Module: Rtml::Rules::DomValidation

Included in:
Rtml::ReverseEngineering::Simulator, RtmlExampleGroup, String
Defined in:
lib/rtml/rules/dom_validation.rb

Instance Method Summary collapse

Instance Method Details

#validate_tml(doc) ⇒ Object

Validates that the TML produced by the given string or Rtml::Document is well-formed and syntactically valid



3
4
5
6
7
8
9
# File 'lib/rtml/rules/dom_validation.rb', line 3

def validate_tml(doc)
  if doc.kind_of?(String) || doc.kind_of?(Symbol)
    tag = Hpricot::XML(doc.respond_to?(:to_tml) ? doc.to_tml : doc).root
  else tag = doc
  end
  validate_tml_tag(tag)
end

#validate_tml_dom(tag, structure) ⇒ Object

Validates that the TML produced by the specified tag matches the overall structure. Structure can be a symbol, an array of symbols, or a hash of symbols and arrays of symbols. Only tag names are matched. The tag may contain additional tags, so this method should be used to check that the tag contains *at least* the given structure, and not to check for *at most* the given structure.

Example:

validate_tml_dom("<tml><screen id='init'><next uri='#main' /><display> . . . </display></screen></tml>",
                 :tml => { :screen => [ :next, :display ] }) #=> true


19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/rtml/rules/dom_validation.rb', line 19

def validate_tml_dom(tag, structure)
  structure = ignore_root_tag(structure)
  tag = root_hpricot_tag(tag)

  matches = []
  case structure
    when String, Symbol then matches.concat validate_tml_dom_with_string(tag, structure)
    when Array          then matches.concat validate_tml_dom_with_array(tag, structure)
    when Hash           then matches.concat validate_tml_dom_with_hash(tag, structure)
    else raise ArgumentError, "Expected a String, Symbol, Array or Hash argument", caller
  end

  matches
end

#validate_tml_tag(tag, parent_options = {}) ⇒ Object

Validates that the TML produced by the specified tag is syntactically valid. Does not check its parent.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/rtml/rules/dom_validation.rb', line 35

def validate_tml_tag(tag, parent_options = {})
  tag = root_hpricot_tag(tag)
  tag_name = tag.name
  tag_rules = rules.tag_rules(tag_name) # contains :name, :minimum, :maximum, :children, :order
  tracker = {}

  validate_tag_exists(tag_name)

  # add to parent_options for tracking, to match against minimum after children have been validated
  parent_options[tag_name] = parent_options[tag_name].to_i + 1

  if tag.children
    assert_children_in_order(tag)
    tag.children.each do |child|
      next unless child.kind_of?(Hpricot::Elem)
      assert_element_allowed(tag, child)
      validate_tml_tag(child, tracker)
    end

    # assert each child >= minimum (&& <= maximum unless maximum == 0)
    tag_rules.children.each do |child_name|
      count = tracker[child_name] || 0
      minimum = rules.tag(tag_name).minimum(child_name)
      maximum = rules.tag(tag_name).maximum(child_name)
      raise Rtml::Errors::RulesViolationError, "Too few '#{child_name}' tags within parent '#{tag_name}'" unless count >= minimum
      raise Rtml::Errors::RulesViolationError, "Too many '#{child_name}' tags within parent '#{tag_name}'" unless maximum == 0 || count <= maximum
    end
  end
end