test: remove duplicate nullable helper cases (#3782)

Retain all 82 recall-audit pairs by preserving the removed callbacks as static fixtures. Keep seven unique type-env inputs and the frozen mutation oracle unchanged.

Co-authored-by: Gergo Magyar <gergomagyar0@gmail.com>
This commit is contained in:
Gergő Magyar 2026-10-31 04:40:03 +00:00 • committed by GitHub
parent 3f36a86518
commit 7af4a274e1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 83 additions and 60 deletions

View file

@ -0,0 +1,15 @@
# Recall audit sources
`audit.json` records manually reviewed positive pairs and distinct scenarios from
PR #3686. The runtime detector still decides whether retrieved candidates are duplicates.
`retired-type-env.ts` preserves 12 pure `stripNullable` callbacks removed from
`test/unit/type-env.test.ts` after the full detector run on PR #3743 confirmed their
duplicates in `test/unit/shared-type-extractors.test.ts`. The callbacks and suite titles
were copied from commit `bd9586e008c6a2dbcd2f15598a3a20c3f2f44f03`; only the import's
relative path changed. These cases have no hooks or mocks.
The `.ts` suffix keeps this source fixture out of Vitest's `*.test.ts` discovery.
`recall-audit.test.ts` explicitly parses it, keeping all 82 positive audit pairs
while the ordinary test suite executes each of these 12 scenarios once.
The seven other `stripNullable` cases remain in `type-env.test.ts`.

View file

@ -382,73 +382,73 @@
},
{
"a": "test/unit/shared-type-extractors.test.ts#stripNullable > strips \"| null\": User | null \u2192 User",
"b": "test/unit/type-env.test.ts#buildTypeEnv > stripNullable > strips User | null \u2192 User",
"b": "test/fixtures/scenario-map-recall/retired-type-env.ts#buildTypeEnv > stripNullable > strips User | null \u2192 User",
"category": "pure-helper",
"basis": "Same production function, literal inputs and expected values; source callbacks are identical. No enclosing hooks change the input."
},
{
"a": "test/unit/shared-type-extractors.test.ts#stripNullable > strips \"| undefined\": User | undefined \u2192 User",
"b": "test/unit/type-env.test.ts#buildTypeEnv > stripNullable > strips User | undefined \u2192 User",
"b": "test/fixtures/scenario-map-recall/retired-type-env.ts#buildTypeEnv > stripNullable > strips User | undefined \u2192 User",
"category": "pure-helper",
"basis": "Same production function, literal inputs and expected values; source callbacks are identical. No enclosing hooks change the input."
},
{
"a": "test/unit/shared-type-extractors.test.ts#stripNullable > strips both \"| null | undefined\": User | null | undefined \u2192 User",
"b": "test/unit/type-env.test.ts#buildTypeEnv > stripNullable > strips User | null | undefined \u2192 User",
"b": "test/fixtures/scenario-map-recall/retired-type-env.ts#buildTypeEnv > stripNullable > strips User | null | undefined \u2192 User",
"category": "pure-helper",
"basis": "Same production function, literal inputs and expected values; source callbacks are identical. No enclosing hooks change the input."
},
{
"a": "test/unit/shared-type-extractors.test.ts#stripNullable > strips nullable suffix: User? \u2192 User",
"b": "test/unit/type-env.test.ts#buildTypeEnv > stripNullable > strips User? \u2192 User",
"b": "test/fixtures/scenario-map-recall/retired-type-env.ts#buildTypeEnv > stripNullable > strips User? \u2192 User",
"category": "pure-helper",
"basis": "Same production function, literal inputs and expected values; source callbacks are identical. No enclosing hooks change the input."
},
{
"a": "test/unit/shared-type-extractors.test.ts#stripNullable > returns undefined for genuine union: User | Repo",
"b": "test/unit/type-env.test.ts#buildTypeEnv > stripNullable > refuses genuine union User | Repo \u2192 undefined",
"b": "test/fixtures/scenario-map-recall/retired-type-env.ts#buildTypeEnv > stripNullable > refuses genuine union User | Repo \u2192 undefined",
"category": "pure-helper",
"basis": "Same production function, literal inputs and expected values; source callbacks are identical. No enclosing hooks change the input."
},
{
"a": "test/unit/shared-type-extractors.test.ts#stripNullable > returns undefined for bare \"null\"",
"b": "test/unit/type-env.test.ts#buildTypeEnv > stripNullable > returns undefined for null alone",
"b": "test/fixtures/scenario-map-recall/retired-type-env.ts#buildTypeEnv > stripNullable > returns undefined for null alone",
"category": "pure-helper",
"basis": "Same production function, literal inputs and expected values; source callbacks are identical. No enclosing hooks change the input."
},
{
"a": "test/unit/shared-type-extractors.test.ts#stripNullable > returns undefined for bare \"undefined\"",
"b": "test/unit/type-env.test.ts#buildTypeEnv > stripNullable > returns undefined for undefined alone",
"b": "test/fixtures/scenario-map-recall/retired-type-env.ts#buildTypeEnv > stripNullable > returns undefined for undefined alone",
"category": "pure-helper",
"basis": "Same production function, literal inputs and expected values; source callbacks are identical. No enclosing hooks change the input."
},
{
"a": "test/unit/shared-type-extractors.test.ts#stripNullable > returns undefined for bare \"None\"",
"b": "test/unit/type-env.test.ts#buildTypeEnv > stripNullable > returns undefined for None alone",
"b": "test/fixtures/scenario-map-recall/retired-type-env.ts#buildTypeEnv > stripNullable > returns undefined for None alone",
"category": "pure-helper",
"basis": "Same production function, literal inputs and expected values; source callbacks are identical. No enclosing hooks change the input."
},
{
"a": "test/unit/shared-type-extractors.test.ts#stripNullable > returns undefined for bare \"nil\"",
"b": "test/unit/type-env.test.ts#buildTypeEnv > stripNullable > returns undefined for nil alone",
"b": "test/fixtures/scenario-map-recall/retired-type-env.ts#buildTypeEnv > stripNullable > returns undefined for nil alone",
"category": "pure-helper",
"basis": "Same production function, literal inputs and expected values; source callbacks are identical. No enclosing hooks change the input."
},
{
"a": "test/unit/shared-type-extractors.test.ts#stripNullable > returns undefined for bare \"void\"",
"b": "test/unit/type-env.test.ts#buildTypeEnv > stripNullable > returns undefined for void alone",
"b": "test/fixtures/scenario-map-recall/retired-type-env.ts#buildTypeEnv > stripNullable > returns undefined for void alone",
"category": "pure-helper",
"basis": "Same production function, literal inputs and expected values; source callbacks are identical. No enclosing hooks change the input."
},
{
"a": "test/unit/shared-type-extractors.test.ts#stripNullable > returns undefined for empty string",
"b": "test/unit/type-env.test.ts#buildTypeEnv > stripNullable > returns undefined for empty string",
"b": "test/fixtures/scenario-map-recall/retired-type-env.ts#buildTypeEnv > stripNullable > returns undefined for empty string",
"category": "pure-helper",
"basis": "Same production function, literal inputs and expected values; source callbacks are identical. No enclosing hooks change the input."
},
{
"a": "test/unit/shared-type-extractors.test.ts#stripNullable > returns the type name unchanged when no nullable markers: User \u2192 User",
"b": "test/unit/type-env.test.ts#buildTypeEnv > stripNullable > passes through User unchanged",
"b": "test/fixtures/scenario-map-recall/retired-type-env.ts#buildTypeEnv > stripNullable > passes through User unchanged",
"category": "pure-helper",
"basis": "Same production function, literal inputs and expected values; source callbacks are identical. No enclosing hooks change the input."
},

View file

@ -0,0 +1,56 @@
// Static input for recall-audit.test.ts; excluded from Vitest discovery by its .ts suffix.
// Preserves the 12 duplicate callbacks removed from type-env.test.ts (see README.md).
import { describe, expect, it } from 'vitest';
import { stripNullable } from '../../../src/core/ingestion/type-extractors/shared.js';
describe('buildTypeEnv', () => {
describe('stripNullable', () => {
it('strips User | null → User', () => {
expect(stripNullable('User | null')).toBe('User');
});
it('strips User | undefined → User', () => {
expect(stripNullable('User | undefined')).toBe('User');
});
it('strips User | null | undefined → User', () => {
expect(stripNullable('User | null | undefined')).toBe('User');
});
it('strips User? → User', () => {
expect(stripNullable('User?')).toBe('User');
});
it('refuses genuine union User | Repo → undefined', () => {
expect(stripNullable('User | Repo')).toBeUndefined();
});
it('returns undefined for null alone', () => {
expect(stripNullable('null')).toBeUndefined();
});
it('returns undefined for undefined alone', () => {
expect(stripNullable('undefined')).toBeUndefined();
});
it('returns undefined for None alone', () => {
expect(stripNullable('None')).toBeUndefined();
});
it('returns undefined for nil alone', () => {
expect(stripNullable('nil')).toBeUndefined();
});
it('returns undefined for void alone', () => {
expect(stripNullable('void')).toBeUndefined();
});
it('returns undefined for empty string', () => {
expect(stripNullable('')).toBeUndefined();
});
it('passes through User unchanged', () => {
expect(stripNullable('User')).toBe('User');
});
});
});

View file

@ -3224,38 +3224,6 @@ svc = App::Models::Service.new
});
describe('stripNullable', () => {
it('strips User | null → User', () => {
expect(stripNullable('User | null')).toBe('User');
});
it('strips User | undefined → User', () => {
expect(stripNullable('User | undefined')).toBe('User');
});
it('strips User | null | undefined → User', () => {
expect(stripNullable('User | null | undefined')).toBe('User');
});
it('strips User? → User', () => {
expect(stripNullable('User?')).toBe('User');
});
it('passes through User unchanged', () => {
expect(stripNullable('User')).toBe('User');
});
it('refuses genuine union User | Repo → undefined', () => {
expect(stripNullable('User | Repo')).toBeUndefined();
});
it('returns undefined for null alone', () => {
expect(stripNullable('null')).toBeUndefined();
});
it('returns undefined for empty string', () => {
expect(stripNullable('')).toBeUndefined();
});
it('strips User | void → User', () => {
expect(stripNullable('User | void')).toBe('User');
});
@ -3272,22 +3240,6 @@ svc = App::Models::Service.new
expect(stripNullable('User | void | nil')).toBe('User');
});
it('returns undefined for None alone', () => {
expect(stripNullable('None')).toBeUndefined();
});
it('returns undefined for nil alone', () => {
expect(stripNullable('nil')).toBeUndefined();
});
it('returns undefined for void alone', () => {
expect(stripNullable('void')).toBeUndefined();
});
it('returns undefined for undefined alone', () => {
expect(stripNullable('undefined')).toBeUndefined();
});
it('strips nullable suffix with spaces: User ? → User', () => {
expect(stripNullable(' User? ')).toBe('User');
});