Files
settled-reach/client/tests/test_yaml_parser.gd
T
jpmschweitzerandClaude Opus 4.6 4eb54a6f7a fix(client): resolve all gdlint warnings — zero warnings policy
Fix 354 gdlint warnings across 65 files: 194 class-definitions-order
(reorder declarations), 138 max-line-length (split long lines),
22 code issues (unused args, no-else-return, naming). Update .gdlintrc
to exclude addons/ and raise max-public-methods for test files.
No logic changes — declaration order, whitespace, and naming only.

Ticket: #783

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 09:59:56 +02:00

263 lines
9.3 KiB
GDScript

## YamlParser unit tests (#560).
## Verifies parse() (nested, typed) and parse_flat() (dotted keys, string values).
## Covers: maps, nested maps, arrays of dicts, type conversion, comments,
## quoted strings, empty input, edge cases.
##
## D-030: fixture-based, server-free, no subprocess required.
class_name TestYamlParser
extends GdUnitTestSuite
# -- parse(): basic key-value pairs -------------------------------------------
func test_parse_simple_key_value() -> void:
var result := YamlParser.parse("key: value")
assert_that(result["key"]).is_equal("value")
func test_parse_quoted_string() -> void:
var result := YamlParser.parse('key: "hello world"')
assert_that(result["key"]).is_equal("hello world")
func test_parse_empty_quoted_string() -> void:
var result := YamlParser.parse('key: ""')
assert_that(result["key"]).is_equal("")
func test_parse_integer_value() -> void:
var result := YamlParser.parse("count: 42")
assert_that(result["count"]).is_equal(42)
assert_that(typeof(result["count"])).is_equal(TYPE_INT)
func test_parse_negative_integer() -> void:
var result := YamlParser.parse("offset: -3")
assert_that(result["offset"]).is_equal(-3)
func test_parse_float_value() -> void:
var result := YamlParser.parse("radius: 2.5")
assert_that(typeof(result["radius"])).is_equal(TYPE_FLOAT)
assert_float(result["radius"]).is_equal_approx(2.5, 0.001)
func test_parse_boolean_true() -> void:
var result := YamlParser.parse("enabled: true")
assert_that(result["enabled"]).is_equal(true)
assert_that(typeof(result["enabled"])).is_equal(TYPE_BOOL)
func test_parse_boolean_false() -> void:
var result := YamlParser.parse("enabled: false")
assert_that(result["enabled"]).is_equal(false)
func test_parse_empty_input() -> void:
var result := YamlParser.parse("")
assert_that(result.size()).is_equal(0)
func test_parse_only_comments() -> void:
var result := YamlParser.parse("# comment\n# another")
assert_that(result.size()).is_equal(0)
func test_parse_inline_comment_stripped() -> void:
var result := YamlParser.parse("room_id: test # this is a comment")
assert_that(result["room_id"]).is_equal("test")
func test_parse_quoted_value_with_hash() -> void:
## Quoted strings preserve literal # characters.
var result := YamlParser.parse('color: "#e0e8ff"')
assert_that(result["color"]).is_equal("#e0e8ff")
func test_parse_value_with_colon() -> void:
var result := YamlParser.parse('time: "12:30"')
assert_that(result["time"]).is_equal("12:30")
# -- parse(): nested maps -----------------------------------------------------
func test_parse_nested_map() -> void:
var yaml := "section:\n key: value"
var result := YamlParser.parse(yaml)
assert_that(result.has("section")).is_true()
assert_that(result["section"] is Dictionary).is_true()
assert_that(result["section"]["key"]).is_equal("value")
func test_parse_deeply_nested() -> void:
var yaml := "a:\n b:\n c: deep"
var result := YamlParser.parse(yaml)
assert_that(result["a"]["b"]["c"]).is_equal("deep")
func test_parse_multiple_sections() -> void:
var yaml := "hud:\n mode: Mode\ninteraction:\n talk: Talk"
var result := YamlParser.parse(yaml)
assert_that(result["hud"]["mode"]).is_equal("Mode")
assert_that(result["interaction"]["talk"]).is_equal("Talk")
func test_parse_multiple_keys_per_section() -> void:
var yaml := "hud:\n a: 1\n b: 2\n c: 3"
var result := YamlParser.parse(yaml)
assert_that(result["hud"]["a"]).is_equal(1)
assert_that(result["hud"]["b"]).is_equal(2)
assert_that(result["hud"]["c"]).is_equal(3)
func test_parse_sibling_subsections() -> void:
var yaml := "states:\n a:\n x: 1\n b:\n x: 2"
var result := YamlParser.parse(yaml)
assert_that(result["states"]["a"]["x"]).is_equal(1)
assert_that(result["states"]["b"]["x"]).is_equal(2)
func test_parse_section_with_trailing_comment() -> void:
## "section: # comment" should be treated as a section header.
var yaml := "section: # comment\n key: value"
var result := YamlParser.parse(yaml)
assert_that(result["section"]["key"]).is_equal("value")
# -- parse(): arrays of dicts -------------------------------------------------
func test_parse_single_array_item() -> void:
var yaml := "conditions:\n - id: test-1\n type: near\n x: 10"
var result := YamlParser.parse(yaml)
assert_that(result.has("conditions")).is_true()
assert_that(result["conditions"] is Array).is_true()
assert_that(result["conditions"].size()).is_equal(1)
assert_that(result["conditions"][0]["id"]).is_equal("test-1")
assert_that(result["conditions"][0]["type"]).is_equal("near")
assert_that(result["conditions"][0]["x"]).is_equal(10)
func test_parse_multiple_array_items() -> void:
var yaml := "conditions:\n - id: a\n x: 1\n - id: b\n x: 2"
var result := YamlParser.parse(yaml)
assert_that(result["conditions"].size()).is_equal(2)
assert_that(result["conditions"][0]["id"]).is_equal("a")
assert_that(result["conditions"][1]["id"]).is_equal("b")
func test_parse_array_items_with_blank_lines() -> void:
var yaml := "conditions:\n - id: a\n x: 1\n\n - id: b\n x: 2"
var result := YamlParser.parse(yaml)
assert_that(result["conditions"].size()).is_equal(2)
func test_parse_top_level_plus_array() -> void:
## Checklist format: top-level key-value pairs followed by a conditions array.
var yaml := "room_id: warehouse\nconditions:\n - id: c1\n type: near\n x: 5"
var result := YamlParser.parse(yaml)
assert_that(result["room_id"]).is_equal("warehouse")
assert_that(result["conditions"].size()).is_equal(1)
assert_that(result["conditions"][0]["id"]).is_equal("c1")
func test_parse_array_typed_values() -> void:
var yaml := "items:\n - id: t\n x: 42\n radius: 2.5\n active: true"
var result := YamlParser.parse(yaml)
var item: Dictionary = result["items"][0]
assert_that(item["x"]).is_equal(42)
assert_that(typeof(item["radius"])).is_equal(TYPE_FLOAT)
assert_that(item["active"]).is_equal(true)
# -- parse_flat(): dotted keys -------------------------------------------------
func test_flat_simple() -> void:
var yaml := "section:\n key: value"
var result := YamlParser.parse_flat(yaml)
assert_that(result.has("section.key")).is_true()
assert_that(result["section.key"]).is_equal("value")
func test_flat_deeply_nested() -> void:
var yaml := "a:\n b:\n c: deep"
var result := YamlParser.parse_flat(yaml)
assert_that(result["a.b.c"]).is_equal("deep")
func test_flat_multiple_sections() -> void:
var yaml := "hud:\n mode: Mode\ninteraction:\n talk: Talk"
var result := YamlParser.parse_flat(yaml)
assert_that(result["hud.mode"]).is_equal("Mode")
assert_that(result["interaction.talk"]).is_equal("Talk")
func test_flat_values_are_strings() -> void:
## parse_flat returns all values as strings, unlike parse() which returns typed.
var yaml := "section:\n count: 42\n rate: 0.9\n active: true"
var result := YamlParser.parse_flat(yaml)
assert_that(result["section.count"]).is_equal("42")
assert_that(result["section.rate"]).is_equal("0.9")
assert_that(result["section.active"]).is_equal("true")
func test_flat_quoted_value() -> void:
var yaml := 'section:\n key: "hello world"'
var result := YamlParser.parse_flat(yaml)
assert_that(result["section.key"]).is_equal("hello world")
func test_flat_inline_comment() -> void:
var yaml := "hud:\n mode: Standard # default"
var result := YamlParser.parse_flat(yaml)
assert_that(result["hud.mode"]).is_equal("Standard")
func test_flat_empty_quoted_value() -> void:
var yaml := 'hud:\n prefix: "" # No prefix'
var result := YamlParser.parse_flat(yaml)
assert_that(result.has("hud.prefix")).is_true()
assert_that(result["hud.prefix"]).is_equal("")
func test_flat_skips_arrays() -> void:
## Arrays have no dotted-key representation — they are skipped in flat output.
var yaml := "room_id: test\nconditions:\n - id: c1\n x: 5"
var result := YamlParser.parse_flat(yaml)
assert_that(result.has("room_id")).is_true()
# No dotted keys for array contents
assert_that(result.has("conditions")).is_false()
assert_that(result.has("conditions.0")).is_false()
func test_flat_empty_input() -> void:
var result := YamlParser.parse_flat("")
assert_that(result.size()).is_equal(0)
# -- Dialogue theme format (regression) ----------------------------------------
func test_dialogue_theme_format() -> void:
## dialogue-theme.yaml has top-level values and one nested map (npc_colors).
var yaml := "player_color: \"#e0e8ff\"\nnpc_colors:\n 0: \"#4a9ebb\"\n 1: \"#6bc9a6\"\npassive_opacity: 0.9"
var flat := YamlParser.parse_flat(yaml)
assert_that(flat["player_color"]).is_equal("#e0e8ff")
assert_that(flat["npc_colors.0"]).is_equal("#4a9ebb")
assert_that(flat["npc_colors.1"]).is_equal("#6bc9a6")
assert_that(flat["passive_opacity"]).is_equal("0.9")
# -- Checklist format (regression) ---------------------------------------------
func test_checklist_format() -> void:
## checklist.yaml: top-level kv + conditions array with typed values.
var yaml := ("room_id: inventory_warehouse\nconditions:\n - id: test-1\n" +
" condition_type: player_near\n x: 10\n y: 20\n radius: 3.0")
var result := YamlParser.parse(yaml)
assert_that(result["room_id"]).is_equal("inventory_warehouse")
var cond: Dictionary = result["conditions"][0]
assert_that(cond["id"]).is_equal("test-1")
assert_that(cond["condition_type"]).is_equal("player_near")
assert_that(cond["x"]).is_equal(10)
assert_that(cond["y"]).is_equal(20)
assert_that(typeof(cond["radius"])).is_equal(TYPE_FLOAT)