export_native turns the profile data back into each platform's own
file, for a maintainer there to pick up and use, and none of the ten
exporters had a test. Coverage goes from 0 to 83%.
Writing them found the EmuDeck exporter rejecting its own output: its
export skips placeholder entries, its validate looked for them anyway
and reported the omission as a missing hash. Both sides apply the same
filter now.
The placeholder assertion initially passed for the wrong reason twice
over -- the fixture entry had no hash, so it was dropped as incomplete
rather than as a placeholder, and the assertion then read the name
while the exporters write the path. It is pinned on an unmistakable
destination now, and removing the guard fails two tests.
The requirement parser read core, hashMatchMandatory and note from
each bios element and discarded all three, which reads like a dropped
attribute: hashMatchMandatory decides whether a wrong hash is yellow or
red on Recalbox. It is not lost -- the config parser below captures it
for the YAML -- so these were leftovers, and they cost a look to
confirm that.
Two yaml imports left unused by the move to the shared loader go too.
validate_site reached complexity 43 doing three things at once. The
per-page checks and the link resolution are now separate functions and
the caller keeps only the cross-page duplicate check, which cannot run
until every page has been seen.
The first attempt left the link pass calling a closure that had moved,
and running it against the real site did not catch that: no page there
has a broken link, so the error path never ran. The unit test covering
a deliberately broken fragment did.
_diff_system reached complexity 42, and its hash-based rename fallback
is the part that stands alone: a platform is free to call a file
whatever it likes, so a name matching nothing is not yet a gap, and
counting one file as both missing and extra invents a discrepancy.
That step is now its own function at complexity 31, with the tests it
never had: pairing on any of the three digests, case folding, non-string
values, and the case where two files simply have no hashes and so are
not evidence of anything. diff_truth output is unchanged.
Regenerated with the large-file cache populated, the state CI builds
from: without it ten preserved entries resolve differently and the
counts drift by one file.
SHA1 is the primary key of this collection and there was no
.gitattributes, so git guessed. Git for Windows sets core.autocrlf=true
by default: a clone there rewrites every file git considers text,
meaning the shaders, .ini, .txt and .dat assets under bios/ arrive with
CRLF and a different hash from the one published. Verification then
fails on files nobody touched.
bios/ and data/ are exempt from normalisation, generated artefacts are
pinned to LF so a Windows checkout does not show them modified, and the
rule order is asserted rather than assumed.
A clone group is only visible while both copies are on disk, and the
run then deletes the clone, so writing only what this run saw erased
every mapping an earlier run had recorded. One real run took the map
from 69 entries to 1, and the canonical zips silently stopped answering
to the names they stand in for.
The map is merged now, the 68 lost entries are restored, and the one
whose canonical file is no longer in the collection is dropped.
The cross-reference loop body became its own function, but one exit
stayed a continue and left the module unparseable, which took the whole
test suite down with it. The other ten continues are inside genuine
inner loops and stand.
Output verified identical to the version before the split.
deduplicate reached complexity 50 by mixing the question of which
copies may go with the work of removing them. The decision is now its
own function: same name in two directories is a true duplicate,
different names only collapse as MAME device clones, and anywhere else
each name may be the one some emulator looks for.
Verified against the real collection: both versions plan the same 99
removals.
dedup.py is the only script here that deletes BIOS files and it had no
tests: the sole guard was remembering --dry-run. These cover the
protected directories where two identical copies are both load-bearing,
the canonical choice between a primary and a variant, MAME zip clones
against same-content files that must keep every name, and that a dry
run reports exactly the plan the real run executes.
Disabling the NODEDUP guard fails four of them.
generate_platform_page reached complexity 49, most of it in the block
rendering one collapsible section per system: each file shows a
different set of hashes, sizes and provenance depending on what the
platform declares. That block is now its own function and the caller
sits at 28. All 534 pages identical apart from timestamps.
generate_cross_reference rendered the same relation twice in one
function, once per platform and once per upstream, and reached
complexity 53. Each view is now its own function and the caller is a
pair of calls.
Verified by generating the site with both versions against the same
data: all 533 pages identical apart from timestamps, with a control run
of the same code twice to confirm the comparison had no drift in it.
generate_gap_analysis reached complexity 56. Its problem-files section
is the one that stands alone -- it reads platform_problems and nothing
else -- so it becomes its own function and the caller drops to 43.
The neighbouring sections were tried too and put back: they share
gap_report and the resolved core list, so pulling them out turns a
render pass into an argument-threading exercise for no gain. Verified
by generating the site with both versions against the same data: 529 of
530 pages identical, the odd one a wiki page another run had edited.
verify.py reaches these through a dynamic import and nothing exercised
them, so a signature check that accepted everything would have looked
exactly like one that worked.
Console dumps are personal data and cannot be committed, but the
verifiers only read structure and signatures: the fixtures are built
from the layouts in unique_data.cpp and otp.cpp, signing with a key the
test owns and passing the matching public key in through the keys file.
That covers the region-change detection in SecureInfo_A, the embedded
LFCS in movable.sed, and the OTP path down to the sect233r1 certificate
including the pre-v5 expiry endianness.
crypto_verify goes from 9 to 89 percent. Disabling the OTP hash check
and the movable.sed magic check each fails a test.
The pack integrity tests failed whenever another run was writing
dist/, reporting a corrupt archive when the only fact established was
that somebody else was building. Which test went red depended on how
far along that build was. They skip now, the way validate_schemas
already does.