hyf

Context-aware query service for Radroots
git clone https://radroots.dev/git/hyf.git
Log | Files | Refs | README | LICENSE

commit 65454d6e9e3e6cad2ee28186283783bc79598b92
parent b57f1d9d9bea7cafac1cb21d8a20729efea5d389
Author: triesap <tyson@radroots.org>
Date:   Thu,  9 Apr 2026 02:55:13 +0000

tests: harden mirrored fixture extraction

- replace the raw substring scan with exact top-level json field parsing
- keep scenario request and expected loading clone-local and structurally checked
- avoid the mojson nested-subvalue edge in fixture helper serialization
- add a regression for descriptions that mention request and expected

Diffstat:
Mtests/fixture_assertions.mojo | 70++++++++++++++++++++++++++++------------------------------------------
Mtests/fixture_loader.mojo | 100+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Mtests/test_hyf.mojo | 47+++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 148 insertions(+), 69 deletions(-)

diff --git a/tests/fixture_assertions.mojo b/tests/fixture_assertions.mojo @@ -2,11 +2,14 @@ from std.testing import assert_equal, assert_true from mojson import Value, dumps, loads -from fixture_loader import load_fixture_scenario_field +from fixture_loader import ( + load_fixture_scenario_expected, + load_fixture_scenario_request, +) def load_scenario_request(relative_path: String) raises -> Value: - return load_fixture_scenario_field(relative_path, "request") + return load_fixture_scenario_request(relative_path) def load_scenario_request_json(relative_path: String) raises -> String: @@ -22,7 +25,7 @@ def status_request_with_invalid_version_json() raises -> String: def assert_matches_scenario_response( actual: Value, relative_path: String ) raises: - var expected = load_fixture_scenario_field(relative_path, "expected") + var expected = load_fixture_scenario_expected(relative_path) if _has_key(expected, "ok"): _assert_json_equal(actual["ok"], expected["ok"]) @@ -110,49 +113,32 @@ def _compact_json(value: Value) raises -> String: if value.is_string(): return dumps(Value(value.string_value())) - if value.is_array() or value.is_object(): - return _minify_json(value.raw_json()) + if value.is_array(): + var result = String("[") + var items = value.array_items() + for index in range(len(items)): + if index > 0: + result += "," + result += _compact_json(items[index]) + result += "]" + return result^ + + if value.is_object(): + var result = String("{") + var first = True + for key in value.object_keys(): + if not first: + result += "," + first = False + result += dumps(Value(String(key))) + result += ":" + result += _compact_json(value[key]) + result += "}" + return result^ return dumps(value) -def _minify_json(raw: String) -> String: - var result = String("") - var in_string = False - var escaped = False - - for byte in raw.as_bytes(): - if escaped: - result += chr(Int(byte)) - escaped = False - continue - - if in_string: - result += chr(Int(byte)) - if byte == UInt8(ord("\\")): - escaped = True - elif byte == UInt8(ord('"')): - in_string = False - continue - - if byte == UInt8(ord('"')): - in_string = True - result += chr(Int(byte)) - continue - - if ( - byte == UInt8(ord(" ")) - or byte == UInt8(ord("\n")) - or byte == UInt8(ord("\t")) - or byte == UInt8(ord("\r")) - ): - continue - - result += chr(Int(byte)) - - return result^ - - def _assert_contains_all(actual: Value, expected_subset: Value) raises: if expected_subset.is_array(): assert_true(actual.is_array()) diff --git a/tests/fixture_loader.mojo b/tests/fixture_loader.mojo @@ -11,12 +11,8 @@ def fixture_manifest_path() raises -> Path: return fixture_root_path() / "manifest.json" -def load_fixture_manifest() raises -> Value: - return loads(fixture_manifest_path().read_text()) - - -def load_fixture_scenario(relative_path: String) raises -> Value: - return loads((fixture_root_path() / String(relative_path)).read_text()) +def load_fixture_json_file(path: Path) raises -> Value: + return loads(path.read_text()) def _skip_whitespace(raw: String, start_index: Int) -> Int: @@ -64,16 +60,11 @@ def _extract_json_value(raw: String, start_index: Int) raises -> String: elif byte == UInt8(ord("}")) or byte == UInt8(ord("]")): depth -= 1 if depth == 0: - return String( - raw[ - byte=start_index : index + 1 - ] - ) + return String(raw[byte=start_index : index + 1]) index += 1 raise Error("unterminated fixture object or array field") if first == UInt8(ord('"')): - var in_string = True var escaped = False var index = start_index + 1 while index < len(data): @@ -82,7 +73,7 @@ def _extract_json_value(raw: String, start_index: Int) raises -> String: escaped = False elif byte == UInt8(ord("\\")): escaped = True - elif byte == UInt8(ord('"')) and in_string: + elif byte == UInt8(ord('"')): return String(raw[byte=start_index : index + 1]) index += 1 raise Error("unterminated fixture string field") @@ -101,20 +92,75 @@ def _extract_json_value(raw: String, start_index: Int) raises -> String: return String(raw[byte=start_index:]) -def load_fixture_scenario_field(relative_path: String, key: String) raises -> Value: - var raw = (fixture_root_path() / String(relative_path)).read_text() - var pattern = "\"" + key + "\"" - var key_index = raw.find(pattern) - if key_index < 0: - raise Error("fixture scenario missing field '" + key + "'") - +def load_fixture_top_level_field_from_path(path: Path, key: String) raises -> Value: + var raw = path.read_text() var data = raw.as_bytes() - var index = key_index + pattern.byte_length() - while index < len(data) and data[index] != UInt8(ord(":")): - index += 1 + var index = _skip_whitespace(raw, 0) + if index >= len(data) or data[index] != UInt8(ord("{")): + raise Error("fixture scenario must be a top-level JSON object") + + index += 1 + while index < len(data): + index = _skip_whitespace(raw, index) + if index >= len(data): + break + + if data[index] == UInt8(ord("}")): + break + + if data[index] != UInt8(ord('"')): + raise Error("fixture scenario object key must be a JSON string") + + var key_json = _extract_json_value(raw, index) + var parsed_key = loads(key_json) + if not parsed_key.is_string(): + raise Error("fixture scenario object key did not parse as a string") + + index += key_json.byte_length() + index = _skip_whitespace(raw, index) + if index >= len(data) or data[index] != UInt8(ord(":")): + raise Error( + "fixture scenario field '" + parsed_key.string_value() + + "' missing colon" + ) + + var value_start = _skip_whitespace(raw, index + 1) + var value_json = _extract_json_value(raw, value_start) + if parsed_key.string_value() == key: + return loads(value_json) + + index = value_start + value_json.byte_length() + index = _skip_whitespace(raw, index) + if index >= len(data): + break + if data[index] == UInt8(ord(",")): + index += 1 + continue + if data[index] == UInt8(ord("}")): + break + raise Error( + "fixture scenario field '" + parsed_key.string_value() + + "' missing delimiter" + ) + + raise Error("fixture scenario missing field '" + key + "'") + + +def load_fixture_manifest() raises -> Value: + return load_fixture_json_file(fixture_manifest_path()) + + +def load_fixture_scenario(relative_path: String) raises -> Value: + return load_fixture_json_file(fixture_root_path() / String(relative_path)) + + +def load_fixture_scenario_request(relative_path: String) raises -> Value: + return load_fixture_top_level_field_from_path( + fixture_root_path() / String(relative_path), "request" + ) - if index >= len(data): - raise Error("fixture scenario field '" + key + "' missing colon") - var value_start = _skip_whitespace(raw, index + 1) - return loads(_extract_json_value(raw, value_start)) +def load_fixture_scenario_expected(relative_path: String) raises -> Value: + return load_fixture_top_level_field_from_path( + fixture_root_path() / String(relative_path), "expected" + ) diff --git a/tests/test_hyf.mojo b/tests/test_hyf.mojo @@ -19,8 +19,12 @@ from fixture_assertions import ( from fixture_loader import ( fixture_manifest_path, + load_fixture_json_file, load_fixture_manifest, load_fixture_scenario, + load_fixture_scenario_expected, + load_fixture_scenario_request, + load_fixture_top_level_field_from_path, ) from hyf_core.backends.selector import ( execute_capability as execute_core_capability, @@ -355,6 +359,49 @@ def test_repo_local_fixture_loader_reads_all_mirrored_scenarios() raises: ) +def test_fixture_loader_reads_top_level_request_and_expected_structurally() raises: + with TemporaryDirectory() as temp_dir: + var scenario_path = Path(temp_dir) / "scenario.json" + scenario_path.write_text( + '{' + + '"fixture_id":"shadowed-top-level-fields",' + + '"description":"this description mentions request and expected before the real fields",' + + '"request":{"version":1,"request_id":"shadow-1","capability":"sys.status","input":{}},' + + '"expected":{"ok":true,"equals":{"output.kind":"status"}}' + + '}' + ) + + var scenario = load_fixture_json_file(scenario_path) + var request = load_fixture_scenario_request("scenarios/status_ok.json") + var expected = load_fixture_scenario_expected("scenarios/status_ok.json") + var temp_request = load_fixture_top_level_field_from_path( + scenario_path, "request" + ) + var temp_expected = load_fixture_top_level_field_from_path( + scenario_path, "expected" + ) + + assert_equal( + scenario["fixture_id"].string_value(), + "shadowed-top-level-fields", + ) + assert_equal( + temp_request["request_id"].string_value(), + "shadow-1", + ) + assert_equal( + temp_request["capability"].string_value(), + "sys.status", + ) + assert_true(temp_expected["ok"].bool_value()) + assert_equal( + temp_expected["equals"]["output.kind"].string_value(), + "status", + ) + assert_equal(request["capability"].string_value(), "sys.status") + assert_true(expected["ok"].bool_value()) + + def test_status_reports_registered_deterministic_ready() raises: var result = _dispatch(load_scenario_request_json("scenarios/status_ok.json")) assert_matches_scenario_response(result, "scenarios/status_ok.json")