diff --git a/gitnexus/test/fixtures/scenario-map-recall/README.md b/gitnexus/test/fixtures/scenario-map-recall/README.md new file mode 100644 index 000000000..d7c0f4809 --- /dev/null +++ b/gitnexus/test/fixtures/scenario-map-recall/README.md @@ -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`. diff --git a/gitnexus/test/fixtures/scenario-map-recall/audit.json b/gitnexus/test/fixtures/scenario-map-recall/audit.json index 9a96d7f82..8844e8872 100644 --- a/gitnexus/test/fixtures/scenario-map-recall/audit.json +++ b/gitnexus/test/fixtures/scenario-map-recall/audit.json @@ -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." }, diff --git a/gitnexus/test/fixtures/scenario-map-recall/retired-type-env.ts b/gitnexus/test/fixtures/scenario-map-recall/retired-type-env.ts new file mode 100644 index 000000000..479d919f5 --- /dev/null +++ b/gitnexus/test/fixtures/scenario-map-recall/retired-type-env.ts @@ -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'); + }); + }); +}); diff --git a/gitnexus/test/unit/type-env.test.ts b/gitnexus/test/unit/type-env.test.ts index fddfdabbb..f396233ca 100644 --- a/gitnexus/test/unit/type-env.test.ts +++ b/gitnexus/test/unit/type-env.test.ts @@ -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'); });