Skip to content

test(formatted): add regression tests for quoting scalar values - #266

Merged
stevebeattie merged 1 commit into
chainguard-dev:mainfrom
stevebeattie:test-quote-scalars
Oct 2, 2026
Merged

stevebeattie merged 1 commit into
chainguard-dev:mainfrom
stevebeattie:test-quote-scalars

Conversation

@stevebeattie

Copy link
Copy Markdown
Member

Summary

This adds TestQuoteScalars, a table-driven regression test for how quote
expressions (--quote / quote: in .yam.yaml) handle each kind of YAML
scalar. Only tests change; formatter behavior stays the same.

yaml.v3 already does the right thing here. When a scalar on a quote path isn't
explicitly tagged, it drops the implicit tag and writes the value
double-quoted with its original text, so 5.12, 42, 0x1F, .inf, true
and 2024-01-01 all become strings with no type coercion in yam. Until now
only a single float fixture (testdata/format/quotes.yaml) covered quoting,
and it didn't check other types, explicit tags, or the decoded type. That's
how #125 came to propose a fix that wasn't needed.

What's covered

Each row checks three things: the exact formatted text, the decoded value
(so a change that keeps the text but changes the type fails), and that
formatting the output a second time changes nothing.

  • Implicit scalars become quoted strings with their text unchanged:
    float, int, hex and octal ints, .inf, .NaN, exponent floats, 1_000,
    true, timestamps, and block literals.
  • Strings: plain strings, YAML 1.1 bool words (yes), single-quoted
    strings, and already double-quoted strings (left unchanged).
  • Explicit tags are kept: !!float 5.12 becomes !!float "5.12", and
    the same for !!int, !!bool and !!str. Quoting should never override
    a type the author wrote out.
  • Things that stay attached: anchors and line comments on quoted values.
    Nulls stay null.
  • Paths: several quote expressions all apply; .v[] quotes every
    sequence item; .v[1] quotes only that item.
  • Paths that don't match leave values unchanged: a sibling key, a
    same-depth path under a different parent (the mistake in the yam --quotes doesn't work for floats (and probably others) #100 repro),
    a deeper path, and a path to a sequence rather than its items.

The block-literal row deliberately pins today's behavior: quoting a |
scalar flattens it to one escaped line. A comment on the row says so.

Verification

  • go test ./... and go test -race ./pkg/yam/formatted pass on main.
  • With quotes: Fix quotes on ints and floats #125's encoder change applied, exactly two rows fail
    (!!float "5.12" → !!str "5.12", !!int "42" → !!str "42").
  • I broke the code on purpose in several other ways, and each one fails
    the row written for it. Before this test, the first five passed the
    entire repo suite:
    • path matching that compares only the last key
    • applying only the first or only the last quote expression
    • quoting nulls into "null"
    • dropping line comments from quoted values
    • losing explicit tags (|= changed to =)
    • skipping quoting for strings
  • gofmt -l . is clean. golangci-lint run --new-from-rev=origin/main
    reports 0 issues.

Related: #100, #125

🤖 Generated with Claude Code

Add TestQuoteScalars, a table test covering how quote expressions
treat each scalar type. yaml.v3 already double-quotes non-string
scalars on quote paths while keeping their original text, so ints,
floats, hex/octal ints, .inf/.NaN, bools, and timestamps all become
strings without any type coercion in yam. Until now only a single
float fixture (testdata/format/quotes.yaml) covered quoting.

Explicitly tagged values (!!float 5.12) keep their tag and gain
quotes (!!float "5.12"), so quoting never overrides a type the author
spelled out. These rows fail if non-string tags are rewritten to !!str,
as proposed in chainguard-dev#125.

Also covers plain and already-quoted strings, YAML 1.1 bool words,
anchored scalars, line comments, nulls, block literals, multiple quote
expressions, any-index and specific-index sequence paths, and paths
that should not match: a sibling key, a same-depth path under a
different parent (the repro in chainguard-dev#100), a deeper path, and a path to a
sequence rather than its items.

Each row checks the formatted text, that the decoded value has the
expected type, and that formatting the output again changes nothing.

To test: go test ./pkg/yam/formatted -run TestQuoteScalars -v

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@stevebeattie
stevebeattie merged commit 41bc5da into chainguard-dev:main Oct 2, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants