diff --git a/src/erc7730/main.py b/src/erc7730/main.py index 13c04979..1eb3050d 100644 --- a/src/erc7730/main.py +++ b/src/erc7730/main.py @@ -75,19 +75,35 @@ def _any_v2_descriptor(paths: list[Path]) -> bool: short_help="Print ERC-7730 descriptor JSON schema.", help=""" Print ERC-7730 descriptor JSON schema. + + The schema is generated from the model this tool validates against, so it is the one + `erc7730 lint` enforces. Pass --v2 for the v2 model. """, ) def command_schema( model_type: Annotated[ERC7730ModelType, Argument(help="The descriptor form ")] = ERC7730ModelType.INPUT, + v2: Annotated[bool, Option("--v2", help="Print the schema of the v2 model")] = False, ) -> None: descriptor_type: type[Model] - match model_type: - case ERC7730ModelType.INPUT: - descriptor_type = InputERC7730Descriptor - case ERC7730ModelType.RESOLVED: - descriptor_type = ResolvedERC7730Descriptor - case _: - assert_never(model_type) + if v2: + from erc7730.model.input.v2.descriptor import InputERC7730Descriptor as InputERC7730DescriptorV2 + from erc7730.model.resolved.v2.descriptor import ResolvedERC7730Descriptor as ResolvedERC7730DescriptorV2 + + match model_type: + case ERC7730ModelType.INPUT: + descriptor_type = InputERC7730DescriptorV2 + case ERC7730ModelType.RESOLVED: + descriptor_type = ResolvedERC7730DescriptorV2 + case _: + assert_never(model_type) + else: + match model_type: + case ERC7730ModelType.INPUT: + descriptor_type = InputERC7730Descriptor + case ERC7730ModelType.RESOLVED: + descriptor_type = ResolvedERC7730Descriptor + case _: + assert_never(model_type) builtins.print(json.dumps(descriptor_type.model_json_schema(by_alias=True), indent=4)) diff --git a/tests/test_main.py b/tests/test_main.py index fac9e546..046823dd 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -34,6 +34,27 @@ def test_schema(model_type: ERC7730ModelType) -> None: assert json.loads(out) is not None +@pytest.mark.parametrize("model_type", list(ERC7730ModelType)) +def test_schema_v2(model_type: ERC7730ModelType) -> None: + result = runner.invoke(app, ["schema", model_type, "--v2"]) + out = "".join(result.stdout.splitlines()) + assert result.exit_code == 0 + assert json.loads(out) is not None + + +def test_schema_v2_reaches_the_v2_model() -> None: + """Exit code 0 only proves a schema was printed, not which model it came from. + + `mustMatch` is a v2 visibility rule and `excluded` a v1 field, so each name appears + in exactly one of the two schemas. + """ + v1 = "".join(runner.invoke(app, ["schema", ERC7730ModelType.INPUT]).stdout.splitlines()) + v2 = "".join(runner.invoke(app, ["schema", ERC7730ModelType.INPUT, "--v2"]).stdout.splitlines()) + + assert "excluded" in v1 and "mustMatch" not in v1 + assert "mustMatch" in v2 and "excluded" not in v2 + + def test_list() -> None: result = runner.invoke(app, ["list", str(ERC7730_REGISTRY_ROOT)]) out = "".join(result.stdout.splitlines())