Skip to content

Pair snapshots via Verify's received map, with a name based fallback - #8

Merged
SimonCropp merged 10 commits into
mainfrom
Better-Unique-support
Jul 22, 2026
Merged

Pair snapshots via Verify's received map, with a name based fallback#8
SimonCropp merged 10 commits into
mainfrom
Better-Unique-support

Conversation

@SimonCropp

@SimonCropp SimonCropp commented Jul 22, 2026

Copy link
Copy Markdown
Member

Accepting a snapshot means moving a .received. file over the .verified. file it belongs to, so the tool has to work out which verified file each received file maps to. It was reconstructing the verified name from the received name, which is not reliable, because the two names legitimately diverge on two independent axes:

  • Runtime uniqueness. A multi targeted project always adds the runtime and version to the received name, while the verified name carries whatever UniqueFor* the test asked for, which may be nothing, the runtime, or the runtime and version.
  • Parameters. IgnoreParameters / IgnoreParametersForVerified / IgnoreConstructorParameters keep parameters in the received name but drop them from the verified name.

Both can apply at once, and neither is a reversible transform:

received  Foo_size=large.DotNet11_0.received.txt
verified  Foo.verified.txt

Read the pairing instead of deriving it

Verify 31.27.0 records which verified file each received file belongs to, into the obj directory of the test project. This adds a reference to Verify.ExceptionParsing and reads those records via ReceivedMaps, so the pairing is exact rather than guessed.

For the records to be found, the working directory has to contain obj, which holds when running from a project or repository root.

The name based fallback, hardened

Records are not always available. They do not exist for snapshots produced by a Verify older than 31.27.0, and they are not found when the working directory does not contain obj, for example when -w points at a snapshot directory below it, or when obj has been removed since the test run. So the name based approach remains as a fallback, and has been reworked.

It previously generated candidate verified names and probed for them. It now enumerates the verified files that actually exist alongside the received file and ranks them by how specifically the received name reduces to each. That is strictly safer, since only files that exist are ever considered, and it additionally handles:

  • the parameter axis, ie. a verified name with trailing parameters dropped
  • #name / #index multi target files, which the previous runtime handling missed
  • .Networking and similar, which the previous StartsWith(".Net") check mistook for a runtime

Matches are delimiter bounded, so Foo can never be paired with FooBar, and every candidate must exist on disk, so a bad guess cannot clobber an unrelated snapshot.

Two cases the fallback still cannot resolve, both only reachable without a record:

  • A brand new snapshot has no verified file to match against, so a runtime suffix cannot be removed.
  • A leading or middle ignored parameter cannot be reconstructed, since the verified name is not a truncation of the received name.

Integration tests

Adds Verify.Terminal.IntegrationTests, which runs real Verify to produce received files and then runs the real SnapshotFinder over them, rather than asserting against hand written names. It is multi targeted on purpose, so it exercises the multi targeting naming.

The suite pins the assumptions this tool makes about Verify's naming, so a future Verify that changes naming fails these tests rather than silently misbehaving. It covers all the sensible uniqueness combinations (plain, UniqueForRuntime, UniqueForRuntimeAndVersion, UniqueForArchitecture, UniqueForOSPlatform, UniqueForAssemblyConfiguration, parameters, ignored parameters), and runs each against both the map and the fallback, asserting both reach the same verified file.

Where the two paths differ, they are asserted as a pair, which is what demonstrates the map's value: WithoutMap_CannotBePlaced next to WithMap_IsPlaced.

Verify's build server detection is forced off in the harness, since no records are written on a build server, which would otherwise make these pass locally and fail on CI.

Also

  • SnapshotFinderTests reworked for the new matching, including cases that must not pair.
  • SnapshotFinder no longer takes IFileSystem, since matching is now done against globbed results.
  • README gains a "How snapshots are paired" section, with a mermaid flowchart of the resolution order, and an explanation of the (rerouted) marker shown by review.

@SimonCropp SimonCropp changed the title Better unique support Pair snapshots via Verify's received map, with a name based fallback Jul 22, 2026
The tool never runs on a build server, so citing that as a reason the
received map is absent was misleading. The cases that actually apply are
a Verify older than 31.27.0, and an obj directory that is not under the
working directory or has been removed since the test run.
@patriksvensson

Copy link
Copy Markdown
Member

Looks good to me!

@SimonCropp
SimonCropp merged commit 10d88a4 into main Jul 22, 2026
2 checks passed
@SimonCropp
SimonCropp deleted the Better-Unique-support branch July 22, 2026 10:31
@SimonCropp SimonCropp added this to the 0.8.0 milestone Jul 22, 2026
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