Module: Ace::Demo::Atoms::DemoYamlParser

Defined in:
lib/ace/demo/atoms/demo_yaml_parser.rb

Constant Summary collapse

ALLOWED_ROOT_KEYS =
%w[description tags settings setup scenes verify teardown].freeze

Class Method Summary collapse

Class Method Details

.parse_file(path) ⇒ Object



13
14
15
16
17
18
# File 'lib/ace/demo/atoms/demo_yaml_parser.rb', line 13

def parse_file(path)
  data = YAML.safe_load_file(path, permitted_classes: [], aliases: false)
  parse_hash(data, source_path: path)
rescue Psych::SyntaxError => e
  raise DemoYamlParseError, "Invalid YAML in #{path}: #{e.message}"
end

.parse_hash(data, source_path: "(inline)") ⇒ Object

Raises:



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/ace/demo/atoms/demo_yaml_parser.rb', line 20

def parse_hash(data, source_path: "(inline)")
  unless data.is_a?(Hash)
    raise DemoYamlParseError, "YAML tape must be a map at root: #{source_path}"
  end

  unknown_keys = data.keys.map(&:to_s) - ALLOWED_ROOT_KEYS
  unless unknown_keys.empty?
    allowed = ALLOWED_ROOT_KEYS.join(", ")
    raise DemoYamlParseError,
      "Unknown top-level keys in #{source_path}: #{unknown_keys.join(", ")}. Allowed: #{allowed}"
  end

  spec = {
    "description" => data["description"]&.to_s,
    "tags" => normalize_tags(data["tags"], source_path: source_path),
    "settings" => normalize_settings(data["settings"], source_path: source_path),
    "setup" => normalize_directives(data["setup"], "setup", source_path: source_path),
    "scenes" => normalize_scenes(data["scenes"], source_path: source_path),
    "verify" => normalize_verify(data["verify"], source_path: source_path),
    "teardown" => normalize_directives(data["teardown"], "teardown", source_path: source_path)
  }

  raise DemoYamlParseError, "Missing or empty scenes section in #{source_path}" if spec["scenes"].empty?

  spec
end