Skip to content

Error on conflicting global test directives; fix tests with duplicate directives - #64200

Open
Ryan Cavanaugh (RyanCavanaugh) with Copilot wants to merge 3 commits into
mainfrom
copilot/fix-invalid-test-directive
Open

Error on conflicting global test directives; fix tests with duplicate directives#64200
Ryan Cavanaugh (RyanCavanaugh) with Copilot wants to merge 3 commits into
mainfrom
copilot/fix-invalid-test-directive

Conversation

Copilot AI commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

The Go test harness silently allowed a global test directive (e.g. @target) to be repeated with a conflicting value—the later value silently won, hiding authoring mistakes. useStrictLikePrologueString01.ts had @target: commonjs immediately followed by @target: es5, es2015, which almost certainly should have been @module: commonjs, but the harness swallowed the error instead of flagging it.

Harness

  • test_case_parser.go: enabled the (previously disabled/commented-out) check so ParseTestFilesAndSymlinksWithOptions now panics when a global directive is set twice with different values, instead of silently keeping the last one.

Test fixes

Ran the full compiler test suite against the new check to find every existing test that would now trip it (3 total):

  • useStrictLikePrologueString01.ts: @target: commonjs@module: commonjs; updated .js baseline for the now-active CommonJS emit.
  • es5-yieldFunctionObjectLiterals.ts: removed stray leftover @lib: es5,es2015.promise (overridden by @lib: es2015, likely copy-pasted from an async-function test).
  • bundlerImportTsExtensions.ts: removed stray duplicate @outDir: dist (overridden by @outDir: out).

No other baseline changes were needed beyond useStrictLikePrologueString01.

@typescript-automation typescript-automation Bot added For Uncommitted Bug PR for untriaged, rejected, closed or missing bug For Milestone Bug PRs that fix a bug with a specific milestone and removed For Uncommitted Bug PR for untriaged, rejected, closed or missing bug labels Sep 8, 2026
Copilot AI linked an issue Sep 8, 2026 that may be closed by this pull request
1 task
Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com>
@typescript-automation typescript-automation Bot added For Uncommitted Bug PR for untriaged, rejected, closed or missing bug and removed For Milestone Bug PRs that fix a bug with a specific milestone labels Sep 8, 2026
Copilot AI changed the title [WIP] Fix incorrect test directive in useStrictLikePrologueString01 Error on conflicting global test directives; fix tests with duplicate directives Sep 8, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot good start but also check that the specified flag value is also legal (barring known back-compat things like module: amd). e.g. You should be able to detect module: commojs or target: es212 as errors

Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com>

Copilot AI commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Copilot good start but also check that the specified flag value is also legal (barring known back-compat things like module: amd). e.g. You should be able to detect module: commojs or `target: es...

Added value legality validation in 3ef8a99 (see commit "Validate legal values for known enum/boolean global test directives"). It checks enum/boolean compiler-option directives (e.g. @target, @module) against their real legal values and panics on typos like @module: commojs or @target: es212. @module: amd and similar still pass since they're legal enum values, just unsupported at runtime (a separate, existing concern handled by SkipUnsupportedCompilerOptions).

The check is gated to compiler/transpile test parsing only (new ParseTestFilesOptions.ValidateOptionValues flag) — the fourslash test parser and parser fuzzer intentionally parse arbitrary/legacy content and shouldn't be subject to it. Running it against the full test suite also caught a couple of real test files using trailing-semicolon values (e.g. @declaration: true;), which I accounted for by stripping the trailing ; before validation.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The parser has unresolved validation behavior and lacks focused regression coverage.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Rejects conflicting global test directives and fixes affected compiler fixtures.

Changes:

  • Adds duplicate-directive detection and option-value validation.
  • Corrects or removes three conflicting directives.
  • Updates the CommonJS emit baseline.

Review findings:

  • Moderate (2 votes): Remove the unrelated value-validation behavior or document and test it explicitly.
  • Moderate (1 vote): Reject empty enum/boolean selectors rather than silently accepting them.
  • Nit (2 votes): Add focused tests covering conflicting and identical duplicate directives.
File summaries
File Description
tsc/testdata/tests/cases/conformance/moduleResolution/bundler/bundlerImportTsExtensions.ts Removes the duplicate outDir directive.
tsc/testdata/tests/cases/compiler/useStrictLikePrologueString01.ts Corrects target to module.
tsc/testdata/tests/cases/compiler/es5-yieldFunctionObjectLiterals.ts Removes the conflicting lib directive.
tsc/testdata/baselines/reference/compiler/useStrictLikePrologueString01(target=es2015).js Updates the CommonJS emit baseline.
tsc/internal/testrunner/test_case_parser.go Adds duplicate-directive and option-value validation.
Review details

Suppressed comments (1)

tsc/internal/testrunner/test_case_parser.go:200

  • The conflict check compares raw directive text even though the harness normalizes it later. For example, @declaration: true; and @declaration: true are semantically identical (trailing semicolons are supported in existing tests), as are es5,es2015 and es5, es2015, but this now panics for both pairs. Please compare canonicalized option values here, or reject every duplicate consistently rather than labeling formatting differences as conflicts.
					if existingValue, ok := globalOptions[metaDataName]; ok && existingValue != metaDataValue {
						panic(fmt.Sprintf("Duplicate global option '%s': %q conflicts with previously set value %q", metaDataName, metaDataValue, existingValue))
  • Files reviewed: 5/5 changed files
  • Comments generated: 3
  • Review effort level: Balanced

func(filename string, content string, fileOptions map[string]string) (*testUnit, error) {
return &testUnit{content: content, name: filename}, nil
},
ParseTestFilesOptions{ValidateOptionValues: true},
Comment on lines +348 to +356
for token := range strings.SplitSeq(value, ",") {
token = strings.TrimSpace(token)
if token == "" || token == "*" || strings.HasPrefix(token, "-") || strings.HasPrefix(token, "!") {
continue
}
if !isValid(token) {
panic(fmt.Sprintf("Illegal value %q for global option '%s'; expected one of: %s", token, name, strings.Join(legalValues(), ", ")))
}
}
Comment on lines 199 to +200
if existingValue, ok := globalOptions[metaDataName]; ok && existingValue != metaDataValue {
// !!! This would break existing baseline tests
// panic("Duplicate global option: " + metaDataName)
panic(fmt.Sprintf("Duplicate global option '%s': %q conflicts with previously set value %q", metaDataName, metaDataValue, existingValue))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

For Uncommitted Bug PR for untriaged, rejected, closed or missing bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Perhaps there is an incorrect test directive in useStrictLikePrologueString01

3 participants