The upstream package-url/vers-spec conformance suite is thin and uneven: 491 npm native-parse cases but 1 npm containment case, 977 maven comparison cases but 0 maven native-parse cases, 1 gem case total, and zero data for cargo, composer, cpan, dart/pub, deb, golang, hackage, hex, rpm, semver. Passing it doesn't prove much beyond "can parse the URI format".
Rather than wait on upstream, add a testdata/local/tests/ directory in the same JSON schema, run it through the existing conformance runner, and fill it by harvesting fixtures from each ecosystem's own reference implementation (node-semver, pypa/packaging, composer/semver, pub_semver, rubygems, dpkg, rpm, dtolnay/semver, maven-artifact). The harvested JSON is committed so go test needs nothing but Go.
Infrastructure
Seed local data from existing tests
Harvester
Harvest: comparison tests (upstream has zero for all of these)
Harvest: native-range tests
Harvest: generated containment tests
Follow-up
The upstream
package-url/vers-specconformance suite is thin and uneven: 491 npm native-parse cases but 1 npm containment case, 977 maven comparison cases but 0 maven native-parse cases, 1 gem case total, and zero data for cargo, composer, cpan, dart/pub, deb, golang, hackage, hex, rpm, semver. Passing it doesn't prove much beyond "can parse the URI format".Rather than wait on upstream, add a
testdata/local/tests/directory in the same JSON schema, run it through the existing conformance runner, and fill it by harvesting fixtures from each ecosystem's own reference implementation (node-semver, pypa/packaging, composer/semver, pub_semver, rubygems, dpkg, rpm, dtolnay/semver, maven-artifact). The harvested JSON is committed sogo testneeds nothing but Go.Infrastructure
conformance_test.gotofilepath.Glob("testdata/*/tests/*_<type>_test.json")instead of enumerating filenames, so bothtestdata/vers-spec/tests/andtestdata/local/tests/are picked up and new upstream files run automatically after a submodule bumpvers_canonical_parse_test.json(currently exists upstream but isn't run)testdata/local/skip.jsonmapping{filename: [{description, reason}]}for known intentional divergences, checked before each subtest witht.Skip(reason)Seed local data from existing tests
testdata/local/tests/composer_range_from_native_test.jsonfromcomposer_pub_test.gotablestestdata/local/tests/composer_version_cmp_test.jsontestdata/local/tests/pub_range_from_native_test.jsontestdata/local/tests/pub_version_cmp_test.jsoncomposer_pub_test.godown to error-path cases once the JSON covers the happy pathsHarvester
tools/harvest/main.go(invoked viago run ./tools/harvest, kept out of the library build) that shallow-clones reference repos, extracts assertion tables, and writestestdata/local/tests/*.jsonwith source repo + commit SHA recorded in a top-level$commentfieldMakefiletargetharvestthat runs itHarvest: comparison tests (upstream has zero for all of these)
npm/node-semver/test/fixtures/{comparisons,equality}.jspypa/packaging/tests/test_version.pyrubygems/rubygems/test/rubygems/test_gem_version.rbcomposer/semver/tests/ComparatorTest.phpdart-lang/tools/pkgs/pub_semver/test/version_test.dartdtolnay/semver/tests/dpkg/lib/dpkg/t/t-version.crpm-software-management/rpm/tests/rpmvercmp.atgolang.org/x/mod/semvertest dataHarvest: native-range tests
node-semver/test/fixtures/{range-include,range-exclude}.js(upstream has 1 case)pypa/packaging/tests/test_specifiers.py(upstream has 3 cases)rubygems/test_gem_requirement.rb(upstream has 1 case)composer/semver/tests/VersionParserTest.phpdata providerspub_semver/test/version_range_test.dartandversion_constraint_test.dartdtolnay/semver/tests/test_version_req.rsmaven-artifactVersionRangeTest.java(upstream has 0 native cases)Harvest: generated containment tests
npx semver,python -c 'import packaging.specifiers...',php -r,dart run,ruby -e 'Gem::Requirement...') to record the expected answer; skip a scheme with a warning if its runtime isn't on PATHFollow-up
ParseandParseNative(the Rubyversgem caps at 2048 chars / 64 constraints; this library currently has no bound)testdata/local/has meaningful coverage, open an upstream PR topackage-url/vers-specwith the generated files and a link to the harvester; don't block on it landing