diff --git a/tests/fixtures/conformance/checkpoint/008_export_checkpoint_json_wrapper_shape.json b/tests/fixtures/conformance/checkpoint/008_export_checkpoint_json_wrapper_shape.json new file mode 100644 index 0000000..869bc6c --- /dev/null +++ b/tests/fixtures/conformance/checkpoint/008_export_checkpoint_json_wrapper_shape.json @@ -0,0 +1,38 @@ +{ + "id": "checkpoint_export_checkpoint_json_wrapper_shape", + "kind": "checkpoint", + "initial_state": { + "premise": null, + "policies": {}, + "version": 2 + }, + "prelude": [ + "set premise concise replies", + "use docker" + ], + "action": { + "fn": "export_checkpoint_json" + }, + "expected": { + "payload_json_parseable": true, + "payload_object": { + "checkpoint_version": 1, + "authoritative_state": { + "premise": "concise replies", + "policies": { + "docker": "use" + }, + "version": 2 + }, + "pending": null + }, + "has_pending_clarification": false, + "state": { + "premise": "concise replies", + "policies": { + "docker": "use" + }, + "version": 2 + } + } +} diff --git a/tests/fixtures/conformance/checkpoint/009_import_checkpoint_json_restores_authoritative_state_no_pending.json b/tests/fixtures/conformance/checkpoint/009_import_checkpoint_json_restores_authoritative_state_no_pending.json new file mode 100644 index 0000000..05e43f1 --- /dev/null +++ b/tests/fixtures/conformance/checkpoint/009_import_checkpoint_json_restores_authoritative_state_no_pending.json @@ -0,0 +1,39 @@ +{ + "id": "checkpoint_import_checkpoint_json_restores_authoritative_state_no_pending", + "kind": "checkpoint", + "initial_state": { + "premise": null, + "policies": {}, + "version": 2 + }, + "action": { + "fn": "import_checkpoint_json", + "payload": "{\"authoritative_state\":{\"policies\":{\"pytest\":\"use\"},\"premise\":\"baseline\",\"version\":2},\"checkpoint_version\":1,\"pending\":null}" + }, + "expected": { + "has_pending_clarification": false, + "state": { + "premise": "baseline", + "policies": { + "pytest": "use" + }, + "version": 2 + }, + "followup": { + "input": "yes", + "decision": { + "kind": "passthrough", + "state": null, + "prompt_to_user": null + }, + "state": { + "premise": "baseline", + "policies": { + "pytest": "use" + }, + "version": 2 + }, + "has_pending_clarification": false + } + } +} diff --git a/tests/fixtures/conformance/checkpoint/010_checkpoint_json_round_trip_state_and_pending_parity.json b/tests/fixtures/conformance/checkpoint/010_checkpoint_json_round_trip_state_and_pending_parity.json new file mode 100644 index 0000000..43b9809 --- /dev/null +++ b/tests/fixtures/conformance/checkpoint/010_checkpoint_json_round_trip_state_and_pending_parity.json @@ -0,0 +1,37 @@ +{ + "id": "checkpoint_checkpoint_json_round_trip_state_and_pending_parity", + "kind": "checkpoint", + "initial_state": { + "premise": null, + "policies": {}, + "version": 2 + }, + "prelude": [ + "use kubectl instead of docker" + ], + "action": { + "fn": "checkpoint_json_round_trip" + }, + "expected": { + "state": { + "premise": null, + "policies": {}, + "version": 2 + }, + "has_pending_clarification": true, + "followup": { + "input": "maybe", + "decision": { + "kind": "clarify", + "state": null, + "prompt_to_user": "Did you mean to use \"kubectl\" instead?" + }, + "state": { + "premise": null, + "policies": {}, + "version": 2 + }, + "has_pending_clarification": true + } + } +} diff --git a/tests/fixtures/conformance/checkpoint/011_pending_clarification_through_checkpoint_json_restore_yes_resolution.json b/tests/fixtures/conformance/checkpoint/011_pending_clarification_through_checkpoint_json_restore_yes_resolution.json new file mode 100644 index 0000000..15a5f55 --- /dev/null +++ b/tests/fixtures/conformance/checkpoint/011_pending_clarification_through_checkpoint_json_restore_yes_resolution.json @@ -0,0 +1,45 @@ +{ + "id": "checkpoint_pending_clarification_through_checkpoint_json_restore_yes_resolution", + "kind": "checkpoint", + "initial_state": { + "premise": null, + "policies": {}, + "version": 2 + }, + "prelude": [ + "use kubectl instead of docker" + ], + "action": { + "fn": "checkpoint_json_round_trip" + }, + "expected": { + "state": { + "premise": null, + "policies": {}, + "version": 2 + }, + "has_pending_clarification": true, + "followup": { + "input": "yes", + "decision": { + "kind": "update", + "state": { + "premise": null, + "policies": { + "kubectl": "use" + }, + "version": 2 + }, + "prompt_to_user": null + }, + "state": { + "premise": null, + "policies": { + "kubectl": "use" + }, + "version": 2 + }, + "has_pending_clarification": false + } + } +} diff --git a/tests/fixtures/conformance/checkpoint/012_import_checkpoint_json_malformed_rejected.json b/tests/fixtures/conformance/checkpoint/012_import_checkpoint_json_malformed_rejected.json new file mode 100644 index 0000000..74a70ac --- /dev/null +++ b/tests/fixtures/conformance/checkpoint/012_import_checkpoint_json_malformed_rejected.json @@ -0,0 +1,25 @@ +{ + "id": "checkpoint_import_checkpoint_json_malformed_rejected", + "kind": "checkpoint", + "initial_state": { + "premise": null, + "policies": {}, + "version": 2 + }, + "action": { + "fn": "import_checkpoint_json", + "payload": "{" + }, + "expected": { + "error": { + "type": "ValueError", + "message_contains": "Invalid JSON payload" + }, + "has_pending_clarification": false, + "state": { + "premise": null, + "policies": {}, + "version": 2 + } + } +} diff --git a/tests/fixtures/conformance/checkpoint/013_import_checkpoint_json_invalid_shape_rejected.json b/tests/fixtures/conformance/checkpoint/013_import_checkpoint_json_invalid_shape_rejected.json new file mode 100644 index 0000000..8f9c0c9 --- /dev/null +++ b/tests/fixtures/conformance/checkpoint/013_import_checkpoint_json_invalid_shape_rejected.json @@ -0,0 +1,25 @@ +{ + "id": "checkpoint_import_checkpoint_json_invalid_shape_rejected", + "kind": "checkpoint", + "initial_state": { + "premise": null, + "policies": {}, + "version": 2 + }, + "action": { + "fn": "import_checkpoint_json", + "payload": "[]" + }, + "expected": { + "error": { + "type": "ValueError", + "message_contains": "Invalid checkpoint payload" + }, + "has_pending_clarification": false, + "state": { + "premise": null, + "policies": {}, + "version": 2 + } + } +} diff --git a/tests/fixtures/conformance/checkpoint/014_import_checkpoint_json_invalid_authoritative_state_rejected.json b/tests/fixtures/conformance/checkpoint/014_import_checkpoint_json_invalid_authoritative_state_rejected.json new file mode 100644 index 0000000..338504c --- /dev/null +++ b/tests/fixtures/conformance/checkpoint/014_import_checkpoint_json_invalid_authoritative_state_rejected.json @@ -0,0 +1,25 @@ +{ + "id": "checkpoint_import_checkpoint_json_invalid_authoritative_state_rejected", + "kind": "checkpoint", + "initial_state": { + "premise": null, + "policies": {}, + "version": 2 + }, + "action": { + "fn": "import_checkpoint_json", + "payload": "{\"checkpoint_version\":1,\"authoritative_state\":{\"premise\":null,\"policies\":[],\"version\":2},\"pending\":null}" + }, + "expected": { + "error": { + "type": "ValueError", + "message_contains": "Invalid state payload" + }, + "has_pending_clarification": false, + "state": { + "premise": null, + "policies": {}, + "version": 2 + } + } +} diff --git a/tests/fixtures/conformance/checkpoint/015_import_checkpoint_json_invalid_payload_is_all_or_nothing.json b/tests/fixtures/conformance/checkpoint/015_import_checkpoint_json_invalid_payload_is_all_or_nothing.json new file mode 100644 index 0000000..67a1da4 --- /dev/null +++ b/tests/fixtures/conformance/checkpoint/015_import_checkpoint_json_invalid_payload_is_all_or_nothing.json @@ -0,0 +1,42 @@ +{ + "id": "checkpoint_import_checkpoint_json_invalid_payload_is_all_or_nothing", + "kind": "checkpoint", + "initial_state": { + "premise": null, + "policies": {}, + "version": 2 + }, + "prelude": [ + "use kubectl instead of docker" + ], + "action": { + "fn": "import_checkpoint_json", + "payload": "{\"checkpoint_version\":1,\"authoritative_state\":{\"premise\":\"new premise\",\"policies\":{\"pytest\":\"use\"},\"version\":2},\"pending\":{\"kind\":\"replacement\",\"replacement\":{\"kind\":\"use_only\",\"new_item\":\"kubectl\",\"old_item\":\"docker\"},\"prompt_to_user\":\"confirm?\"}}" + }, + "expected": { + "error": { + "type": "ValueError", + "message_contains": "Invalid checkpoint payload" + }, + "has_pending_clarification": true, + "state": { + "premise": null, + "policies": {}, + "version": 2 + }, + "followup": { + "input": "maybe", + "decision": { + "kind": "clarify", + "state": null, + "prompt_to_user": "Did you mean to use \"kubectl\" instead?" + }, + "state": { + "premise": null, + "policies": {}, + "version": 2 + }, + "has_pending_clarification": true + } + } +} diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py index 1b65897..92c2577 100644 --- a/tests/test_fixtures.py +++ b/tests/test_fixtures.py @@ -155,6 +155,24 @@ def test_checkpoint_fixtures() -> None: else: with pytest.raises(ValueError, match=error["message_contains"]): engine.import_checkpoint(payload) + elif fn == "export_checkpoint_json": + payload = engine.export_checkpoint_json() + if expected.get("payload_json_parseable"): + parsed = json.loads(payload) + assert parsed == expected["payload_object"], fixture_id + elif fn == "import_checkpoint_json": + payload = action["payload"] + error = expected.get("error") + if error is None: + engine.import_checkpoint_json(payload) + else: + with pytest.raises(ValueError, match=error["message_contains"]): + engine.import_checkpoint_json(payload) + elif fn == "checkpoint_json_round_trip": + payload = engine.export_checkpoint_json() + target = create_engine() + target.import_checkpoint_json(payload) + engine = target else: raise AssertionError(f"Unknown checkpoint action: {fn}")