Skip to content

Commit e7cf275

Browse files
committed
test: buildability is a fact about the variant
The shared family check assumed that if a member could build a part at all it could build every part it names. A member whose parts each run a file the repository cannot carry may hold some of those files and not others, so a part nobody supplied an image for read as a broken one rather than an absent one. buildable_variants reads it off the member's own catalogue, and is driven against a catalogue written in the test rather than the member's, so the three answers are the same in every repository that carries this file.
1 parent 4bec918 commit e7cf275

2 files changed

Lines changed: 55 additions & 4 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ The NEC uPD77C25 as Nintendo shipped it, running the microcode you supply rather
44

55
[![CI](https://github.com/gufranco/snes-dsp-python/actions/workflows/ci.yml/badge.svg)](https://github.com/gufranco/snes-dsp-python/actions/workflows/ci.yml)
66

7-
**6** parts across **5** microcodes, **0** commands described by hand, **112** exchanges read out of **36** real cartridges compared, **0** failures, **871** tests, **100%** statement and branch coverage, no dependencies
7+
**6** parts across **5** microcodes, **0** commands described by hand, **112** exchanges read out of **36** real cartridges compared, **0** failures, **874** tests, **100%** statement and branch coverage, no dependencies
88

99
```python
1010
from snesdsp import Chip

conformance/family.test.py

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
import tomllib
2525
import types
2626
import unittest
27-
from collections.abc import Iterable
27+
from collections.abc import Iterable, Mapping
2828
from pathlib import Path, PurePosixPath
29-
from typing import Any, Protocol
29+
from typing import Any, ClassVar, Protocol
3030

3131
ROOT = Path(__file__).resolve().parent.parent
3232
sys.path.insert(0, str(ROOT))
@@ -426,6 +426,57 @@ def test_a_running_part_is_not_held(self) -> None:
426426
"""
427427

428428

429+
def buildable_variants(package: Any = None, variants: Any = None) -> list[str]:
430+
"""Every variant that can be constructed on this machine, not merely named.
431+
432+
A member whose parts each run a file the repository cannot carry may hold
433+
some of those files and not others, so whether a part can be built is a fact
434+
about the variant rather than about the member. Reading it off the member's
435+
own `available` keeps that in one place; a member that publishes no such
436+
mapping can build everything it names.
437+
"""
438+
known = VARIANTS if variants is None else variants
439+
asked = getattr(PACKAGE if package is None else package, "available", None)
440+
if not callable(asked):
441+
return sorted(known)
442+
held = asked()
443+
if not isinstance(held, Mapping):
444+
return sorted(known)
445+
return sorted(name for name in known if name in held)
446+
447+
448+
class BuildableVariantTest(unittest.TestCase):
449+
"""That a part nobody supplied a file for is not mistaken for a broken one.
450+
451+
Driven against a catalogue written here rather than the member's own, so the
452+
three answers are the same in every repository that carries this file.
453+
"""
454+
455+
NAMED: ClassVar[dict[str, object]] = {"one": object(), "two": object()}
456+
457+
class Silent:
458+
pass
459+
460+
class Odd:
461+
@staticmethod
462+
def available() -> int:
463+
return 7
464+
465+
class Partial:
466+
@staticmethod
467+
def available() -> dict[str, int]:
468+
return {"two": 1}
469+
470+
def test_a_member_that_publishes_no_catalogue_can_build_everything_it_names(self) -> None:
471+
self.assertEqual(buildable_variants(self.Silent(), self.NAMED), ["one", "two"])
472+
473+
def test_and_so_can_one_whose_catalogue_is_not_a_mapping(self) -> None:
474+
self.assertEqual(buildable_variants(self.Odd(), self.NAMED), ["one", "two"])
475+
476+
def test_a_member_holding_one_file_can_build_that_one(self) -> None:
477+
self.assertEqual(buildable_variants(self.Partial(), self.NAMED), ["two"])
478+
479+
429480
class PublishedSurfaceTest(unittest.TestCase):
430481
"""That everything the standard names is importable from the package itself.
431482
@@ -474,7 +525,7 @@ def test_a_part_is_built_by_Chip_taking_the_model_first(self) -> None: # noqa:
474525

475526
@unittest.skipUnless(A_PART and BUILDABLE, "no part can be built here") # pragma: no cover
476527
def test_and_it_takes_a_model_by_name(self) -> None:
477-
for name in sorted(VARIANTS):
528+
for name in buildable_variants():
478529
self.assertEqual(PACKAGE.Chip(name).model, name, name)
479530

480531
@unittest.skipUnless(A_PART, "not a part in the sense this checks")

0 commit comments

Comments
 (0)