cml 1.4.2 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/.rspec +1 -0
  2. data/Gemfile +4 -0
  3. data/Gemfile.lock +33 -0
  4. data/README.rdoc +13 -3
  5. data/Rakefile +9 -49
  6. data/cml.gemspec +23 -125
  7. data/lib/cml/converters/jsawesome.rb +3 -3
  8. data/lib/cml/gold.rb +12 -7
  9. data/lib/cml/liquid_filters.rb +4 -0
  10. data/lib/cml/logic.rb +424 -0
  11. data/lib/cml/logic_tree/graph.rb +107 -0
  12. data/lib/cml/logic_tree/solver.rb +43 -0
  13. data/lib/cml/parser.rb +47 -7
  14. data/lib/cml/tag.rb +42 -21
  15. data/lib/cml/tags/checkbox.rb +14 -4
  16. data/lib/cml/tags/checkboxes.rb +4 -0
  17. data/lib/cml/tags/group.rb +4 -0
  18. data/lib/cml/tags/hours.rb +263 -0
  19. data/lib/cml/tags/iterate.rb +4 -0
  20. data/lib/cml/tags/meta.rb +4 -0
  21. data/lib/cml/tags/option.rb +4 -0
  22. data/lib/cml/tags/radio.rb +13 -4
  23. data/lib/cml/tags/radios.rb +4 -0
  24. data/lib/cml/tags/ratings.rb +9 -1
  25. data/lib/cml/tags/search.rb +8 -2
  26. data/lib/cml/tags/select.rb +6 -2
  27. data/lib/cml/tags/taxonomy.rb +148 -0
  28. data/lib/cml/tags/thumb.rb +4 -0
  29. data/lib/cml/tags/unknown.rb +4 -0
  30. data/lib/cml/version.rb +3 -0
  31. data/lib/cml.rb +3 -0
  32. data/spec/converters/jsawesome_spec.rb +0 -9
  33. data/spec/fixtures/logic_broken.cml +5 -0
  34. data/spec/fixtures/logic_circular.cml +5 -0
  35. data/spec/fixtures/logic_grouped.cml +7 -0
  36. data/spec/fixtures/logic_nested.cml +7 -0
  37. data/spec/fixtures/logic_none.cml +7 -0
  38. data/spec/fixtures/logic_not_nested.cml +7 -0
  39. data/spec/liquid_filter_spec.rb +19 -0
  40. data/spec/logic_depends_on_spec.rb +242 -0
  41. data/spec/logic_spec.rb +207 -0
  42. data/spec/logic_tree_graph_spec.rb +465 -0
  43. data/spec/logic_tree_solver_spec.rb +58 -0
  44. data/spec/meta_spec.rb +12 -2
  45. data/spec/show_data_spec.rb +3 -2
  46. data/spec/spec_helper.rb +22 -6
  47. data/spec/tags/checkboxes_spec.rb +2 -2
  48. data/spec/tags/group_spec.rb +5 -5
  49. data/spec/tags/hours_spec.rb +404 -0
  50. data/spec/tags/radios_spec.rb +2 -2
  51. data/spec/tags/ratings_spec.rb +1 -1
  52. data/spec/tags/select_spec.rb +45 -0
  53. data/spec/tags/tag_spec.rb +25 -0
  54. data/spec/tags/taxonomy_spec.rb +112 -0
  55. data/spec/validation_spec.rb +52 -0
  56. metadata +112 -17
  57. data/VERSION +0 -1
@@ -0,0 +1,148 @@
1
+ require 'uri'
2
+
3
+ module CML
4
+ module Tags
5
+ class Taxonomy < Tag
6
+ SIMPLE_OPTIONS = ["root-select", "log-search", "multi-select", "select-all"]
7
+ URL_OPTIONS = ["src", "search-src"]
8
+ ARRAY_OPTIONS = ["top-level", "selectable", "nonselectable"]
9
+
10
+ BareTemplate = <<-HTML.freeze
11
+ {{inputs}}
12
+ {{search_log}}
13
+ <div class="taxonomy_widget_container" {{taxonomy_options}}></div>
14
+ HTML
15
+
16
+ MultiInputTemplate = <<-HTML.freeze
17
+ <div class="taxonomy_choices">
18
+ {{inputs}}
19
+ </div>
20
+ HTML
21
+
22
+ InputTemplate = <<-HTML.freeze
23
+ <div class="cml_row taxonomy_choice">
24
+ <input name="{{name}}" type="{{input_type}}" class="{{classes}}" value="{{value}}" />
25
+ <input name="{{id_name}}" type="{{input_type}}" class="taxonomy_id no_validate" value="{{id_value}}" />
26
+ </div>
27
+ HTML
28
+
29
+ # The actual search logging is done by the taxonomy widget by adding
30
+ # input array fields to this div
31
+ SearchLogTemplate = <<-HTML.freeze
32
+ <div class="cml_row taxonomy_search" data-name="{{search_log_name}}"></div>
33
+ HTML
34
+
35
+ Template = <<-HTML.freeze
36
+ {{label}}
37
+ #{BareTemplate}
38
+ HTML
39
+
40
+ #allow use of the taxonomy tool for browsing without a form input
41
+ def is_field?
42
+ !(@attrs["field"] && @attrs["field"].to_s == "false")
43
+ end
44
+
45
+ def in_logic_graph?
46
+ is_field?
47
+ end
48
+
49
+ def finite_value?
50
+ true
51
+ end
52
+
53
+ def taxonomy_options
54
+ cw_data = {}
55
+
56
+ (SIMPLE_OPTIONS + ARRAY_OPTIONS).each do |opt|
57
+ attr_opt = @attrs[opt]
58
+ cw_data[opt] = attr_opt.to_s if attr_opt
59
+ end
60
+
61
+ URL_OPTIONS.each do |opt|
62
+ attr_opt = @attrs[opt]
63
+ cw_data[opt] = URI.escape(attr_opt.to_s) if attr_opt
64
+ end
65
+
66
+ cw_data.map{|opt_name, opt_value| "data-#{opt_name}=\"#{opt_value}\""}.join(" ")
67
+ end
68
+ memoize :taxonomy_options
69
+
70
+ # Overriden to get the right name prefix/suffix
71
+ def multi_type
72
+ @attrs["multi-select"] ? :list : nil
73
+ end
74
+
75
+ def value
76
+ (@attrs["value"] || (@opts[:data] || {})[name] || "").to_s
77
+ end
78
+
79
+ def id_value
80
+ ( (@opts[:data] || {})[id_name] || "" ).to_s
81
+ end
82
+
83
+ def id_name
84
+ name(false, "id")
85
+ end
86
+
87
+ def search_log_name
88
+ name(true, "search_log")
89
+ end
90
+
91
+ def data
92
+ super.merge({
93
+ "taxonomy_options" => taxonomy_options,
94
+ "value" => value,
95
+ "id_value" => id_value,
96
+ "id_name" => prefix(id_name),
97
+ "search_log_name" => search_log_name,
98
+ "input_type" => "text"
99
+ })
100
+ end
101
+
102
+
103
+ def to_html
104
+ if is_field?
105
+ if @opts[:normalize]
106
+ data_opt = opts[:data] || {}
107
+ seeds = Array(data_opt[@opts[:parser].golds[name(false)]] || data_opt[name(false)])
108
+ # Zip in the id values for taxonomy nodes
109
+ seeds = seeds.zip(data_opt[id_name] || [])
110
+ seeds << nil if seeds.length == 0
111
+
112
+ inputs = seeds.map do |input, p_name|
113
+ Liquid::Template.parse(InputTemplate).render(data.merge({
114
+ "value" => input.to_s,
115
+ "id_value" => p_name.to_s,
116
+ "classes" => classes+(input ? " cml_gold_loaded" : ""),
117
+ "input_type" => "text"
118
+ }))
119
+ end.join("\n")
120
+ search_log = ""
121
+ else
122
+ search_src = @attrs["search-src"].to_s
123
+ log_search = @attrs["log-search"].to_s
124
+ multi_select = @attrs["multi-select"].to_s
125
+
126
+ inputs = Liquid::Template.parse(InputTemplate).render(data)
127
+ inputs = Liquid::Template.parse(MultiInputTemplate).render({"inputs" => inputs}) if !multi_select.empty?
128
+
129
+ if !search_src.empty? && !log_search.empty?
130
+ search_log = Liquid::Template.parse(SearchLogTemplate).render(data)
131
+ else
132
+ search_log = ""
133
+ end
134
+ end
135
+ else
136
+ inputs = ""
137
+ search_log = ""
138
+ end
139
+
140
+ wrapper(Liquid::Template.parse(Template).render(data.merge({
141
+ "inputs" => inputs,
142
+ "search_log" => search_log
143
+ }), [LiquidFilters]))
144
+ end
145
+
146
+ end
147
+ end
148
+ end
@@ -4,6 +4,10 @@ module CML
4
4
  Template = <<-HTML.freeze
5
5
  <img src="http://nodenailer.crowdflower.com/?{{query_string}}" />
6
6
  HTML
7
+
8
+ def in_logic_graph?
9
+ false
10
+ end
7
11
 
8
12
  def validate?
9
13
  false
@@ -4,6 +4,10 @@ module CML
4
4
  Template = <<-HTML.freeze
5
5
  {{content}}
6
6
  HTML
7
+
8
+ def in_logic_graph?
9
+ false
10
+ end
7
11
 
8
12
  def validate?
9
13
  false
@@ -0,0 +1,3 @@
1
+ module CML
2
+ VERSION = "1.5.0"
3
+ end
data/lib/cml.rb CHANGED
@@ -3,6 +3,9 @@ require 'nokogiri'
3
3
  require 'json'
4
4
  require 'liquid'
5
5
 
6
+ require 'cml/logic'
7
+ require 'cml/logic_tree/graph'
8
+ require 'cml/logic_tree/solver'
6
9
  require 'cml/parser'
7
10
  require 'cml/liquid_filters'
8
11
  require 'cml/tag'
@@ -61,15 +61,6 @@ describe "JSAwesome Converter" do
61
61
  @c.convert.should sorta_match(<<-HTML)
62
62
  <cml:textarea label="Street address (eg. 35 W Forth St.)" name="w_forth_st" validates="required" />
63
63
  <cml:text label="City" validates="required" />
64
- <cml:text label="State/Province" name="stateprovince" />
65
64
  HTML
66
-
67
- #For some reason can't get this spec to pass... not worth my time right now.
68
- #<cml:text label="Zip/Postal Code" name="zippostal_code" />
69
- #<cml:text label="Country" validates="required" />
70
- #<cml:textarea label="Any extra company or address information?" name="extra_address_information"/>
71
- #<cml:checkboxes label="Any issues?" name="any_issues">
72
- # <cml:checkbox label="No address could be found even after checking the url or searching the web" name="searching_the_web" />
73
- #</cml:checkboxes>
74
65
  end
75
66
  end
@@ -0,0 +1,5 @@
1
+ <cml:checkboxes label="Do you have a name?" name="do_you_have_a_name" validates="required">
2
+ <cml:checkbox label="Yes" />
3
+ <cml:checkbox label="No" />
4
+ </cml:checkboxes>
5
+ <cml:text label="name" validates="required" only-if="lol:[yes]" />
@@ -0,0 +1,5 @@
1
+ <cml:checkboxes label="Do you have a name?" name="do_you_have_a_name" validates="required" only-if="name">
2
+ <cml:checkbox label="Yes" />
3
+ <cml:checkbox label="No" />
4
+ </cml:checkboxes>
5
+ <cml:text label="name" validates="required" only-if="do_you_have_a_name:[yes]" />
@@ -0,0 +1,7 @@
1
+ <cml:checkboxes label="Do you have a name?" name="do_you_have_a_name" validates="required">
2
+ <cml:checkbox label="Yes" />
3
+ <cml:checkbox label="No" />
4
+ </cml:checkboxes>
5
+ <cml:text label="name" validates="required" only-if="do_you_have_a_name:[yes]" />
6
+ <cml:text label="age" only-if="do_you_have_a_name:[yes]++name:alpha"/>
7
+ <cml:text label="foo" only-if="!age||(do_you_have_a_name:[yes]++name)" />
@@ -0,0 +1,7 @@
1
+ <cml:checkboxes label="Do you have a name?" name="do_you_have_a_name" validates="required">
2
+ <cml:checkbox label="Yes" />
3
+ <cml:checkbox label="No" />
4
+ </cml:checkboxes>
5
+ <cml:text label="name" validates="required" only-if="do_you_have_a_name:[yes]" />
6
+ <cml:text label="age" only-if="do_you_have_a_name:[yes]++name:alpha"/>
7
+ <cml:text label="foo" only-if="!age||do_you_have_a_name" />
@@ -0,0 +1,7 @@
1
+ <cml:checkboxes label="Do you have a name?" name="do_you_have_a_name" validates="required">
2
+ <cml:checkbox label="Yes" />
3
+ <cml:checkbox label="No" />
4
+ </cml:checkboxes>
5
+ <cml:text label="name" validates="required" />
6
+ <cml:text label="age" />
7
+ <cml:text label="foo" only-if="" />
@@ -0,0 +1,7 @@
1
+ <cml:checkboxes label="Do you have a name?" name="do_you_have_a_name" validates="required">
2
+ <cml:checkbox label="Yes" />
3
+ <cml:checkbox label="No" />
4
+ </cml:checkboxes>
5
+ <cml:text label="name" validates="required" only-if="(do_you_have_a_name:[yes])" />
6
+ <cml:text label="age" />
7
+ <cml:text label="foo" only-if="" />
@@ -0,0 +1,19 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "CML Liquid Filters" do
4
+ it "allow random" do
5
+ @p = Liquid::Template.parse(<<-HTML)
6
+ {% capture my_value %}{{ 3 | random }}{% endcapture %}
7
+ {% case my_value %}
8
+ {% when '1' %}
9
+ One
10
+ {% when '2' %}
11
+ Two
12
+ {% when '0' %}
13
+ Zero
14
+ {% endcase %}
15
+ HTML
16
+
17
+ @p.render({}, [LiquidFilters]).should =~ /One|Two|Zero/
18
+ end
19
+ end
@@ -0,0 +1,242 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "CML logic tree dependencies" do
4
+
5
+ it "lists a simple only-if selector" do
6
+ @p = Parser.new(<<-HTML)
7
+ <cml:text label="OMG" />
8
+ <cml:checkboxes label="w t f" only-if="omg">
9
+ <cml:checkbox label="lol" />
10
+ <cml:checkbox label="rtfm" />
11
+ </cml:checkboxes>
12
+ HTML
13
+
14
+ dependent_tag_names = @p.logic_tree.nodes['w_t_f'].depends_on.collect {|n| n.tag.name }
15
+ dependent_tag_names.should == %w{omg}
16
+
17
+ dependencies = @p.logic_tree.nodes['w_t_f'].dependencies_on
18
+ dependencies['||'].should == [{'omg' => [{ :match_key => nil, :is_not => true }]}]
19
+ dependencies['&&'].should be_nil
20
+ end
21
+
22
+ it "lists an only-if 'not' selector" do
23
+ @p = Parser.new(<<-HTML)
24
+ <cml:text label="OMG" />
25
+ <cml:checkboxes label="w t f" only-if="!omg">
26
+ <cml:checkbox label="lol" />
27
+ <cml:checkbox label="rtfm" />
28
+ </cml:checkboxes>
29
+ HTML
30
+ dependent_tag_names = @p.logic_tree.nodes['w_t_f'].depends_on.collect {|n| n.tag.name }
31
+ dependent_tag_names.should == %w{omg}
32
+
33
+ dependencies = @p.logic_tree.nodes['w_t_f'].dependencies_on
34
+ dependencies['||'].should == [{'omg' => [{ :match_key => nil, :is_not => false }]}]
35
+ dependencies['&&'].should be_nil
36
+ end
37
+
38
+ it "lists an only-if 'unchecked' selector for checkboxes" do
39
+ @p = Parser.new(<<-HTML)
40
+ <cml:checkboxes label="w t f">
41
+ <cml:checkbox label="lol" />
42
+ <cml:checkbox label="rtfm" />
43
+ </cml:checkboxes>
44
+ <cml:text label="OMG" only-if="w_t_f:unchecked" />
45
+ HTML
46
+ dependent_tag_names = @p.logic_tree.nodes['omg'].depends_on.collect {|n| n.tag.name }
47
+ dependent_tag_names.should == %w{w_t_f}
48
+
49
+ dependencies = @p.logic_tree.nodes['omg'].dependencies_on
50
+ dependencies['||'].should == [{'w_t_f' => [{ :match_key => 'lol', :is_not => true }, { :match_key => 'rtfm', :is_not => true }]}]
51
+ dependencies['&&'].should be_nil
52
+ end
53
+
54
+ it "lists an only-if 'unchecked' selector for one checkbox" do
55
+ @p = Parser.new(<<-HTML)
56
+ <cml:checkbox label="w t f">
57
+ <cml:text label="OMG" only-if="w_t_f:unchecked" />
58
+ HTML
59
+ dependent_tag_names = @p.logic_tree.nodes['omg'].depends_on.collect {|n| n.tag.name }
60
+ dependent_tag_names.should == %w{w_t_f}
61
+
62
+ dependencies = @p.logic_tree.nodes['omg'].dependencies_on
63
+ dependencies['||'].should == [{'w_t_f' => [{ :match_key => 'true', :is_not => true }]}]
64
+ dependencies['&&'].should be_nil
65
+ end
66
+
67
+ it "lists an only-if 'not unchecked' selector for one checkbox" do
68
+ @p = Parser.new(<<-HTML)
69
+ <cml:checkbox label="w t f">
70
+ <cml:text label="OMG" only-if="!w_t_f:unchecked" />
71
+ HTML
72
+ dependent_tag_names = @p.logic_tree.nodes['omg'].depends_on.collect {|n| n.tag.name }
73
+ dependent_tag_names.should == %w{w_t_f}
74
+
75
+ dependencies = @p.logic_tree.nodes['omg'].dependencies_on
76
+ dependencies['||'].should == [{'w_t_f' => [{ :match_key => 'true', :is_not => false }]}]
77
+ dependencies['&&'].should be_nil
78
+ end
79
+
80
+ it "lists complex only-if '&&' selectors" do
81
+ @p = Parser.new(<<-HTML)
82
+ <cml:text label="OMG" />
83
+ <cml:checkboxes label="w t f" only-if="omg">
84
+ <cml:checkbox label="lol" />
85
+ <cml:checkbox label="rtfm" />
86
+ </cml:checkboxes>
87
+ <cml:radios label="bacon" only-if="omg:[crispy]++w_t_f:[lol]">
88
+ <cml:radio label="tasty" />
89
+ <cml:radio label="too meaty" />
90
+ </cml:radios>
91
+ HTML
92
+ dependent_tag_names = @p.logic_tree.nodes['bacon'].depends_on.collect {|n| n.tag.name }
93
+ dependent_tag_names.should == %w{omg w_t_f}
94
+
95
+ dependencies = @p.logic_tree.nodes['bacon'].dependencies_on
96
+ dependencies['&&'].should be_nil
97
+ dependencies['||'].should == [{
98
+ '&&' => [
99
+ {'omg' => [{ :match_key => 'crispy', :is_not => false }]},
100
+ {'w_t_f' => [{ :match_key => 'lol', :is_not => false }]}
101
+ ]
102
+ }]
103
+ end
104
+
105
+ it "lists complex only-if '||' selectors" do
106
+ @p = Parser.new(<<-HTML)
107
+ <cml:text label="OMG" />
108
+ <cml:checkboxes label="w t f" only-if="omg">
109
+ <cml:checkbox label="lol" />
110
+ <cml:checkbox label="rtfm" />
111
+ </cml:checkboxes>
112
+ <cml:radios label="bacon" only-if="omg:[crispy]||!w_t_f:[lol]">
113
+ <cml:radio label="tasty" />
114
+ <cml:radio label="too meaty" />
115
+ </cml:radios>
116
+ HTML
117
+ dependent_tag_names = @p.logic_tree.nodes['bacon'].depends_on.collect {|n| n.tag.name }
118
+ dependent_tag_names.should == %w{omg w_t_f}
119
+
120
+ dependencies = @p.logic_tree.nodes['bacon'].dependencies_on
121
+ dependencies['&&'].should be_nil
122
+ dependencies['||'].should == [
123
+ {'omg' => [{ :match_key => 'crispy', :is_not => false }]},
124
+ {'w_t_f' => [{ :match_key => 'lol', :is_not => true }]}
125
+ ]
126
+ end
127
+
128
+ it "lists complex nested only-if selectors" do
129
+ @p = Parser.new(<<-HTML)
130
+ <cml:text label="OMG" />
131
+ <cml:checkboxes label="w t f" only-if="omg">
132
+ <cml:checkbox label="lol" />
133
+ <cml:checkbox label="rtfm" />
134
+ </cml:checkboxes>
135
+ <cml:checkboxes label="f t w" only-if="omg">
136
+ <cml:checkbox label="lmao" />
137
+ <cml:checkbox label="rtfm" />
138
+ </cml:checkboxes>
139
+ <cml:radios label="bacon" only-if="omg:[crispy]||(w_t_f:[rtfm]++f_t_w:[rtfm]||f_t_w:[lmao])">
140
+ <cml:radio label="tasty" />
141
+ <cml:radio label="too meaty" />
142
+ </cml:radios>
143
+ HTML
144
+ dependent_tag_names = @p.logic_tree.nodes['bacon'].depends_on.collect {|n| n.tag.name }
145
+ dependent_tag_names.should == %w{omg w_t_f f_t_w}
146
+
147
+ dependencies = @p.logic_tree.nodes['bacon'].dependencies_on
148
+ dependencies['&&'].should be_nil
149
+ dependencies['||'].should == [
150
+ {'omg' => [{ :match_key => 'crispy', :is_not => false }]},
151
+ {"||"=>[
152
+ {'&&' => [
153
+ {'w_t_f' => [{ :match_key => 'rtfm', :is_not => false }]},
154
+ {'f_t_w' => [{ :match_key => 'rtfm', :is_not => false }]}
155
+ ]},
156
+ {'f_t_w' => [{ :match_key => 'lmao', :is_not => false }]}
157
+ ]}
158
+ ]
159
+ end
160
+
161
+ it "is aware of only-if group" do
162
+ @p = Parser.new(<<-HTML)
163
+ <cml:text label="OMG" />
164
+ <cml:group only-if="omg">
165
+ <cml:checkboxes label="w t f">
166
+ <cml:checkbox label="lol" />
167
+ <cml:checkbox label="rtfm" />
168
+ </cml:checkboxes>
169
+ <cml:radios label="bacon">
170
+ <cml:radio label="tasty" />
171
+ <cml:radio label="too meaty" />
172
+ </cml:radios>
173
+ </cml:group>
174
+ HTML
175
+ dependent_tag_names = @p.logic_tree.nodes['w_t_f'].depends_on.collect {|n| n.tag.name }
176
+ dependent_tag_names.should == %w{omg}
177
+ dependent_tag_names = @p.logic_tree.nodes['bacon'].depends_on.collect {|n| n.tag.name }
178
+ dependent_tag_names.should == %w{omg}
179
+
180
+ dependencies = @p.logic_tree.nodes['w_t_f'].dependencies_on
181
+ dependencies['||'].should == [{'omg' => [{ :match_key => nil, :is_not => true }]}]
182
+ dependencies['&&'].should be_nil
183
+
184
+ dependencies = @p.logic_tree.nodes['bacon'].dependencies_on
185
+ dependencies['||'].should == [{'omg' => [{ :match_key => nil, :is_not => true }]}]
186
+ dependencies['&&'].should be_nil
187
+ end
188
+
189
+ it "is aware of nested only-if group" do
190
+ @p = Parser.new(<<-HTML)
191
+ <cml:text label="OMG" />
192
+ <cml:group only-if="omg">
193
+ <cml:checkboxes label="w t f">
194
+ <cml:checkbox label="lol" />
195
+ <cml:checkbox label="rtfm" />
196
+ </cml:checkboxes>
197
+ <cml:group only-if="!w_t_f:[rtfm]">
198
+ <cml:radios label="bacon">
199
+ <cml:radio label="tasty" />
200
+ <cml:radio label="too meaty" />
201
+ </cml:radios>
202
+ </cml:group>
203
+ </cml:group>
204
+ HTML
205
+ dependent_tag_names = @p.logic_tree.nodes['w_t_f'].depends_on.collect {|n| n.tag.name }
206
+ dependent_tag_names.should == %w{omg}
207
+ dependent_tag_names = @p.logic_tree.nodes['bacon'].depends_on.collect {|n| n.tag.name }
208
+ dependent_tag_names.should == %w{omg w_t_f}
209
+
210
+ dependencies = @p.logic_tree.nodes['w_t_f'].dependencies_on
211
+ dependencies['||'].should == [
212
+ {'omg' => [{ :match_key => nil, :is_not => true }]}
213
+ ]
214
+ dependencies['&&'].should be_nil
215
+
216
+ dependencies = @p.logic_tree.nodes['bacon'].dependencies_on
217
+ dependencies['||'].should == [
218
+ {'omg' => [{ :match_key => nil, :is_not => true }]},
219
+ {'w_t_f' => [{ :match_key => 'rtfm', :is_not => true }]}
220
+ ]
221
+ dependencies['&&'].should be_nil
222
+ end
223
+
224
+ it "lists a simple only-if selector with indexed match" do
225
+ @p = Parser.new(<<-HTML)
226
+ <cml:checkboxes label="w t f">
227
+ <cml:checkbox label="lol" />
228
+ <cml:checkbox label="rtfm" />
229
+ </cml:checkboxes>
230
+ <cml:text label="OMG" only-if="w_t_f:[1]" />
231
+ HTML
232
+
233
+ dependent_tag_names = @p.logic_tree.nodes['omg'].depends_on.collect {|n| n.tag.name }
234
+ dependent_tag_names.should == %w{w_t_f}
235
+
236
+ dependencies = @p.logic_tree.nodes['omg'].dependencies_on
237
+ dependencies['||'].should == [
238
+ {'w_t_f' => [{ :match_key => 'rtfm', :is_not => false }]}
239
+ ]
240
+ end
241
+
242
+ end