Skip to content

JS: a test spec can opt into the style its own source is written in - #8681

Merged
knutwannheden merged 1 commit into
mainfrom
template.apply-normalises-spliced-argument-style
Aug 27, 2026
Merged

JS: a test spec can opt into the style its own source is written in#8681
knutwannheden merged 1 commit into
mainfrom
template.apply-normalises-spliced-argument-style

Conversation

@knutwannheden

Copy link
Copy Markdown
Contributor

A JS test fixture indented with tabs comes back indented with four spaces from any recipe that formats, so the expectation cannot be written the way the file reads:

before:  function f() {\n\tconst x = 1;\n}
after:   function f() {\n    const x = 1;\n}

This is the documented style resolution — constructor styles, then NamedStyles markers on the source file, then IntelliJ defaults — working as specified. A bare javascript()/typescript() spec carries no style marker, so it lands on the defaults. Instrumenting AutoformatVisitor confirms it: the source file is found, markers:[], useTabCharacter=false, indentSize=4. The style-marker code lives only in the npm() generator, which samples all specs together; a spec standing on its own never reaches it.

Declaring a style was already possible, but only by hand-building a NamedStyles marker and overriding the spec's parser. withDetectedStyle samples the file and attaches what it finds, wired per spec:

spec.rewriteRun({
    ...typescript("function f() {\n\tconst x = 1;\n\treturn x;\n}\n"),
    beforeRecipe: withDetectedStyle
})

Why opt-in

Applying it to every spec was the first version and is wrong. Java is the reference: RewriteTest has no style handling at all, and a test asks for one with spec.parser(JavaParser.fromJavaVersion().styles(...)). That makes the existing JS behaviour symmetric rather than broken — npm() ≈ project parsing and autodetects, a bare spec ≈ a bare Java test and does not. Automatic detection also changes what 9 existing tests are measured against, 8 of them in format.test.ts, which feed deliberately messy input and assert canonical output; autodetecting from that input is self-defeating.

Full detection rather than indentation alone, since an explicit opt-in is a request for the file's style, and no guard against an existing marker, since a caller that asks should get what it asked for.

Tests

One test, a spec opting into its own style keeps the tabs it is written with, pins the whole path — sample, attach, getStyle lookup, formatter. It fails without the beforeRecipe line (tabs become four spaces), so it catches a marker the lookup cannot find as well as a detector that reads the wrong indent. autodetect.test.ts covers the detector's output but never that the marker is consumed. Full JS suite: 1629 passed, 0 failed, no existing test moved.

A spec that formats its output is measured against the built-in defaults,
so a fixture indented with tabs comes back indented with four spaces and
the expectation cannot be written as the file reads. Declaring a style
meant hand-building a NamedStyles marker and overriding the spec's parser.

withDetectedStyle samples the file and attaches what it finds, wired per
spec via beforeRecipe. It stays opt-in to match Java, where RewriteTest
never autodetects and a test asks for a style with
spec.parser(JavaParser.fromJavaVersion().styles(...)). Applying it to
every spec instead would diverge from that and change what 9 existing
tests are measured against, 8 of them in format.test.ts, which feed
deliberately messy input and assert canonical output.
@github-project-automation github-project-automation Bot moved this to In Progress in OpenRewrite Aug 27, 2026
@knutwannheden
knutwannheden merged commit c867f0c into main Aug 27, 2026
1 of 3 checks passed
@knutwannheden
knutwannheden deleted the template.apply-normalises-spliced-argument-style branch August 27, 2026 16:01
@github-project-automation github-project-automation Bot moved this from In Progress to Done in OpenRewrite Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant