cml 1.4.2 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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,58 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "CML logic tree solver" do
4
+
5
+ before( :each ) 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
+ <cml:checkboxes label="f t w" only-if="omg">
13
+ <cml:checkbox label="lmao" />
14
+ <cml:checkbox label="rtfm" />
15
+ </cml:checkboxes>
16
+ <cml:radios label="bacon" only-if="omg:[crispy]||w_t_f:[rtfm]++f_t_w:[rtfm]">
17
+ <cml:radio label="tasty" />
18
+ <cml:radio label="too meaty" />
19
+ </cml:radios>
20
+ HTML
21
+
22
+ @dependencies = @p.logic_tree.nodes['bacon'].dependencies_on
23
+ end
24
+
25
+ it "halts with first available answer" do
26
+ nodes_visited = []
27
+ solution = CML::LogicTree::Solver.recurse(@dependencies, 'bacon') do |dependent_name, dependency_name, dependency_desc|
28
+ nodes_visited << dependency_name
29
+ 1.0
30
+ end
31
+ solution.should == 1.0
32
+ nodes_visited.should == ['omg']
33
+ end
34
+
35
+ it "tries each group but cannot find solution" do
36
+ nodes_visited = []
37
+ solution = CML::LogicTree::Solver.recurse(@dependencies, 'bacon') do |dependent_name, dependency_name, dependency_desc|
38
+ nodes_visited << dependency_name
39
+ nil
40
+ end
41
+ solution.should == nil
42
+ nodes_visited.should == ['omg', 'w_t_f']
43
+ end
44
+
45
+ it "provides an array of answers for an AND solution" do
46
+ nodes_visited = []
47
+ solution = CML::LogicTree::Solver.recurse(@dependencies, 'bacon') do |dependent_name, dependency_name, dependency_desc|
48
+ nodes_visited << dependency_name
49
+ case dependency_name
50
+ when 'w_t_f' then 0.1
51
+ when 'f_t_w' then 0.2
52
+ end
53
+ end
54
+ solution.should == [0.1, 0.2]
55
+ nodes_visited.should == ['omg', 'w_t_f', 'f_t_w']
56
+ end
57
+
58
+ end
data/spec/meta_spec.rb CHANGED
@@ -5,7 +5,7 @@ describe "CML.gold" do
5
5
  cml = <<-HTML
6
6
  <cml:text name="nice" />
7
7
  <cml:group>
8
- <cml:group only-if="awesome[1]" class="nice" multiple="true">
8
+ <cml:group only-if="nice" class="nice" multiple="true">
9
9
  <div>
10
10
  <cml:checkboxes label="Checkboxes" aggregation="all">
11
11
  <cml:gold src="awesome_gold" regex="\\.asdf\\." flags="i" no_escape="true" strict="true" />
@@ -20,6 +20,12 @@ describe "CML.gold" do
20
20
  <cml:text label="nuts" gold="true"/>
21
21
  </cml:group>
22
22
  <cml:text name="cool" gold="true" aggregation="agg" />
23
+ <cml:checkbox label="test subset attribute">
24
+ <cml:gold subset="true"/>
25
+ </cml:checkbox>
26
+ <cml:checkbox label="test superset attribute">
27
+ <cml:gold superset="true"/>
28
+ </cml:checkbox>
23
29
  </cml:group>
24
30
  <cml:text label="Hot"/>
25
31
  </cml:group>
@@ -37,7 +43,11 @@ describe "CML.gold" do
37
43
  "sweet"=>"sweetness",
38
44
  "cool_1"=>"cool_1_gold",
39
45
  "_no_way_1_gold_exact"=>true,
40
- "_awesome_gold_regex"=>["\\.asdf\\.", "i", "true"]
46
+ "_awesome_gold_regex"=>["\\.asdf\\.", "i", "true"],
47
+ "_test_subset_attribute_1_gold_strict" => true, # 'subset' attribute should be an alias for 'strict'
48
+ "_test_superset_attribute_1_gold_superset" => true,
49
+ "test_subset_attribute_1"=>"test_subset_attribute_1_gold",
50
+ "test_superset_attribute_1"=>"test_superset_attribute_1_gold"
41
51
  }
42
52
  @p.fields.should == {
43
53
  "checkboxes_1"=>"all",
@@ -3,7 +3,7 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
3
  describe "CML Show Data" do
4
4
 
5
5
  def get_parser(data)
6
- Parser.new(<<-HTML, {:prefix => "unit[data]", :show_data => true, :data => data})
6
+ cml = <<-HTML
7
7
  <cml:text label="The dude abides?" validates="required"/>
8
8
  <cml:textarea label="What do you do for recreation?" name="recreation" />
9
9
  <cml:checkbox label="I need my fucking johnson!" name="johnson_needed" />
@@ -21,8 +21,9 @@ describe "CML Show Data" do
21
21
  <cml:option label="Stayed away from"/>
22
22
  <cml:option label="Approached"/>
23
23
  </cml:select>
24
- <cml:ratings from="Sucked" to="Really tied the room together" label="That rug:"/>​
24
+ <cml:ratings from="Sucked" to="Really tied the room together" label="That rug:"/>
25
25
  HTML
26
+ Parser.new(cml,{:prefix => "unit[data]", :show_data => true, :data => data})
26
27
  end
27
28
 
28
29
  before(:each) do
data/spec/spec_helper.rb CHANGED
@@ -1,26 +1,42 @@
1
1
  $LOAD_PATH.unshift(File.dirname(__FILE__))
2
2
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
3
  require 'cml'
4
- require 'spec'
5
4
  require 'sorta_match'
6
5
  #require 'spec/autorun'
6
+ require 'cgi'
7
7
  include CML
8
8
 
9
- Spec::Runner.configure do |config|
9
+ RSpec.configure do |config|
10
10
 
11
11
  end
12
-
13
- Spec::Matchers.define :sorta_match do |expected|
12
+ RSpec::Matchers.define :sorta_match do |expected|
14
13
  match do |actual|
15
14
  @sm = SortaMatch.new(expected, actual)
16
15
  @sm.matches?
17
16
  end
18
17
 
19
18
  failure_message_for_should do |actual|
20
- "Expected DOM's to sorta match but they had these differences:\n #{@sm.missed.inspect}"
19
+ <<-TEXT
20
+ Expected
21
+ #{@sm.missed.first.inspect}
22
+ but got:
23
+ #{@sm.missed.last.inspect}
24
+ TEXT
21
25
  end
22
26
  end
23
27
 
24
28
  def convert(html)
25
29
  Nokogiri::HTML.fragment(html)
26
- end
30
+ end
31
+
32
+ def html_log( obj )
33
+ puts( obj.inspect.gsub( /[&<>]/ ) do |match|
34
+ case match
35
+ when '&' then '&amp;'
36
+ when '<' then '&lt;'
37
+ when '>' then '&gt;'
38
+ end
39
+ end)
40
+ puts "<hr>"
41
+ end
42
+ alias :h :html_log
@@ -61,7 +61,7 @@ describe "CML Checkboxes" do
61
61
  cml = <<-HTML
62
62
  <cml:checkboxes label="Cool checkboxes">
63
63
  {% for foo in bar %}
64
- <cml:checkbox label="Wanna do it?" value="{{bar}}"/>
64
+ <cml:checkbox label="Wanna do it?" value="{{bar}}" title="additional tooltip info"/>
65
65
  {% endfor %}
66
66
  </cml:checkboxes>
67
67
  HTML
@@ -72,7 +72,7 @@ describe "CML Checkboxes" do
72
72
  <div class="checkboxes cml_field">
73
73
  <h2 class="legend">Cool checkboxes</h2>
74
74
  {% for foo in bar %}
75
- <div class="cml_row"><label class="">
75
+ <div class="cml_row" title="additional tooltip info"><label class="">
76
76
  <input type="checkbox" value="{{bar}}" name="u12345[cool_checkboxes][]" class="cool_checkboxes"/> Wanna do it?
77
77
  </label></div>
78
78
  {% endfor %}
@@ -4,11 +4,11 @@ describe "CML Select" do
4
4
  it "should render group" do
5
5
  cml = <<-HTML
6
6
  <cml:group only-if="awesome[1]" class="nice" multiple="true">
7
- <cml:checkboxes label="Cool checkboxes" name="rad" gold="true">
8
- <cml:checkbox label="Wanna do it?"/>
9
- <cml:checkbox label="Sure?"/>
10
- </cml:checkboxes>
11
- <cml:text label="Something" aggregation="all"/>
7
+ <cml:checkboxes label="Cool checkboxes" name="rad" gold="true">
8
+ <cml:checkbox label="Wanna do it?"/>
9
+ <cml:checkbox label="Sure?"/>
10
+ </cml:checkboxes>
11
+ <cml:text label="Something" aggregation="all"/>
12
12
  <cml:group multiple="true">
13
13
  <div>
14
14
  <cml:text label="nuts"/>
@@ -0,0 +1,404 @@
1
+ require "time"
2
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
3
+
4
+ describe "CML Hours" do
5
+
6
+ it "builds hour select boxes" do
7
+ CML::TimeSelect.build( "x" ).should sorta_match <<-HTML
8
+ <select name="x" class="cml_hours_time"><option value="">Select one:</option>
9
+ <option value="00:00">12:00am</option><option value="00:15">12:15am</option>
10
+ <option value="00:30">12:30am</option><option value="00:45">12:45am</option><option value="01:00">1:00am</option>
11
+ <option value="01:15">1:15am</option><option value="01:30">1:30am</option><option value="01:45">1:45am</option>
12
+ <option value="02:00">2:00am</option><option value="02:15">2:15am</option><option value="02:30">2:30am</option>
13
+ <option value="02:45">2:45am</option><option value="03:00">3:00am</option><option value="03:15">3:15am</option>
14
+ <option value="03:30">3:30am</option><option value="03:45">3:45am</option><option value="04:00">4:00am</option>
15
+ <option value="04:15">4:15am</option><option value="04:30">4:30am</option><option value="04:45">4:45am</option>
16
+ <option value="05:00">5:00am</option><option value="05:15">5:15am</option><option value="05:30">5:30am</option>
17
+ <option value="05:45">5:45am</option><option value="06:00">6:00am</option><option value="06:15">6:15am</option>
18
+ <option value="06:30">6:30am</option><option value="06:45">6:45am</option><option value="07:00">7:00am</option>
19
+ <option value="07:15">7:15am</option><option value="07:30">7:30am</option><option value="07:45">7:45am</option>
20
+ <option value="08:00">8:00am</option><option value="08:15">8:15am</option>
21
+ <option value="08:30">8:30am</option><option value="08:45">8:45am</option><option value="09:00">9:00am</option>
22
+ <option value="09:15">9:15am</option><option value="09:30">9:30am</option><option value="09:45">9:45am</option>
23
+ <option value="10:00">10:00am</option><option value="10:15">10:15am</option><option value="10:30">10:30am</option>
24
+ <option value="10:45">10:45am</option><option value="11:00">11:00am</option><option value="11:15">11:15am</option>
25
+ <option value="11:30">11:30am</option><option value="11:45">11:45am</option><option value="12:00">12:00pm</option>
26
+ <option value="12:15">12:15pm</option><option value="12:30">12:30pm</option><option value="12:45">12:45pm</option>
27
+ <option value="13:00">1:00pm</option><option value="13:15">1:15pm</option><option value="13:30">1:30pm</option>
28
+ <option value="13:45">1:45pm</option><option value="14:00">2:00pm</option><option value="14:15">2:15pm</option>
29
+ <option value="14:30">2:30pm</option><option value="14:45">2:45pm</option><option value="15:00">3:00pm</option>
30
+ <option value="15:15">3:15pm</option><option value="15:30">3:30pm</option><option value="15:45">3:45pm</option>
31
+ <option value="16:00">4:00pm</option><option value="16:15">4:15pm</option><option value="16:30">4:30pm</option>
32
+ <option value="16:45">4:45pm</option><option value="17:00">5:00pm</option><option value="17:15">5:15pm</option>
33
+ <option value="17:30">5:30pm</option><option value="17:45">5:45pm</option><option value="18:00">6:00pm</option>
34
+ <option value="18:15">6:15pm</option><option value="18:30">6:30pm</option><option value="18:45">6:45pm</option>
35
+ <option value="19:00">7:00pm</option><option value="19:15">7:15pm</option><option value="19:30">7:30pm</option>
36
+ <option value="19:45">7:45pm</option><option value="20:00">8:00pm</option><option value="20:15">8:15pm</option>
37
+ <option value="20:30">8:30pm</option><option value="20:45">8:45pm</option><option value="21:00">9:00pm</option>
38
+ <option value="21:15">9:15pm</option><option value="21:30">9:30pm</option><option value="21:45">9:45pm</option>
39
+ <option value="22:00">10:00pm</option><option value="22:15">10:15pm</option><option value="22:30">10:30pm</option>
40
+ <option value="22:45">10:45pm</option><option value="23:00">11:00pm</option><option value="23:15">11:15pm</option>
41
+ <option value="23:30">11:30pm</option><option value="23:45">11:45pm</option></select>
42
+ HTML
43
+
44
+ CML::TimeSelect.build("x", true, :selected => "22:15", :allow_unlisted => true ).should sorta_match <<-HTML
45
+ <select name="x" class="cml_hours_time"><option value="">(Any)</option>
46
+ <option value="not_listed">(Not listed)</option>
47
+ <option value="00:00">12:00am</option><option value="00:15">12:15am</option>
48
+ <option value="00:30">12:30am</option><option value="00:45">12:45am</option><option value="01:00">1:00am</option>
49
+ <option value="01:15">1:15am</option><option value="01:30">1:30am</option><option value="01:45">1:45am</option>
50
+ <option value="02:00">2:00am</option><option value="02:15">2:15am</option><option value="02:30">2:30am</option>
51
+ <option value="02:45">2:45am</option><option value="03:00">3:00am</option><option value="03:15">3:15am</option>
52
+ <option value="03:30">3:30am</option><option value="03:45">3:45am</option><option value="04:00">4:00am</option>
53
+ <option value="04:15">4:15am</option><option value="04:30">4:30am</option><option value="04:45">4:45am</option>
54
+ <option value="05:00">5:00am</option><option value="05:15">5:15am</option><option value="05:30">5:30am</option>
55
+ <option value="05:45">5:45am</option><option value="06:00">6:00am</option><option value="06:15">6:15am</option>
56
+ <option value="06:30">6:30am</option><option value="06:45">6:45am</option><option value="07:00">7:00am</option>
57
+ <option value="07:15">7:15am</option><option value="07:30">7:30am</option><option value="07:45">7:45am</option>
58
+ <option value="08:00">8:00am</option><option value="08:15">8:15am</option>
59
+ <option value="08:30">8:30am</option><option value="08:45">8:45am</option><option value="09:00">9:00am</option>
60
+ <option value="09:15">9:15am</option><option value="09:30">9:30am</option><option value="09:45">9:45am</option>
61
+ <option value="10:00">10:00am</option><option value="10:15">10:15am</option><option value="10:30">10:30am</option>
62
+ <option value="10:45">10:45am</option><option value="11:00">11:00am</option><option value="11:15">11:15am</option>
63
+ <option value="11:30">11:30am</option><option value="11:45">11:45am</option><option value="12:00">12:00pm</option>
64
+ <option value="12:15">12:15pm</option><option value="12:30">12:30pm</option><option value="12:45">12:45pm</option>
65
+ <option value="13:00">1:00pm</option><option value="13:15">1:15pm</option><option value="13:30">1:30pm</option>
66
+ <option value="13:45">1:45pm</option><option value="14:00">2:00pm</option><option value="14:15">2:15pm</option>
67
+ <option value="14:30">2:30pm</option><option value="14:45">2:45pm</option><option value="15:00">3:00pm</option>
68
+ <option value="15:15">3:15pm</option><option value="15:30">3:30pm</option><option value="15:45">3:45pm</option>
69
+ <option value="16:00">4:00pm</option><option value="16:15">4:15pm</option><option value="16:30">4:30pm</option>
70
+ <option value="16:45">4:45pm</option><option value="17:00">5:00pm</option><option value="17:15">5:15pm</option>
71
+ <option value="17:30">5:30pm</option><option value="17:45">5:45pm</option><option value="18:00">6:00pm</option>
72
+ <option value="18:15">6:15pm</option><option value="18:30">6:30pm</option><option value="18:45">6:45pm</option>
73
+ <option value="19:00">7:00pm</option><option value="19:15">7:15pm</option><option value="19:30">7:30pm</option>
74
+ <option value="19:45">7:45pm</option><option value="20:00">8:00pm</option><option value="20:15">8:15pm</option>
75
+ <option value="20:30">8:30pm</option><option value="20:45">8:45pm</option><option value="21:00">9:00pm</option>
76
+ <option value="21:15">9:15pm</option><option value="21:30">9:30pm</option><option value="21:45">9:45pm</option>
77
+ <option value="22:00">10:00pm</option><option selected="selected" value="22:15">10:15pm</option>
78
+ <option value="22:30">10:30pm</option><option value="22:45">10:45pm</option><option value="23:00">11:00pm</option>
79
+ <option value="23:15">11:15pm</option><option value="23:30">11:30pm</option><option value="23:45">11:45pm</option></select>
80
+ HTML
81
+
82
+ CML::TimeSelect.build("x", true, :selected => "not_listed", :allow_unlisted => true ).should sorta_match <<-HTML
83
+ <select name="x" class="cml_hours_time"><option value="">(Any)</option>
84
+ <option value="not_listed" selected="selected">(Not listed)</option>
85
+ <option value="00:00">12:00am</option><option value="00:15">12:15am</option>
86
+ <option value="00:30">12:30am</option><option value="00:45">12:45am</option><option value="01:00">1:00am</option>
87
+ <option value="01:15">1:15am</option><option value="01:30">1:30am</option><option value="01:45">1:45am</option>
88
+ <option value="02:00">2:00am</option><option value="02:15">2:15am</option><option value="02:30">2:30am</option>
89
+ <option value="02:45">2:45am</option><option value="03:00">3:00am</option><option value="03:15">3:15am</option>
90
+ <option value="03:30">3:30am</option><option value="03:45">3:45am</option><option value="04:00">4:00am</option>
91
+ <option value="04:15">4:15am</option><option value="04:30">4:30am</option><option value="04:45">4:45am</option>
92
+ <option value="05:00">5:00am</option><option value="05:15">5:15am</option><option value="05:30">5:30am</option>
93
+ <option value="05:45">5:45am</option><option value="06:00">6:00am</option><option value="06:15">6:15am</option>
94
+ <option value="06:30">6:30am</option><option value="06:45">6:45am</option><option value="07:00">7:00am</option>
95
+ <option value="07:15">7:15am</option><option value="07:30">7:30am</option><option value="07:45">7:45am</option>
96
+ <option value="08:00">8:00am</option><option value="08:15">8:15am</option>
97
+ <option value="08:30">8:30am</option><option value="08:45">8:45am</option><option value="09:00">9:00am</option>
98
+ <option value="09:15">9:15am</option><option value="09:30">9:30am</option><option value="09:45">9:45am</option>
99
+ <option value="10:00">10:00am</option><option value="10:15">10:15am</option><option value="10:30">10:30am</option>
100
+ <option value="10:45">10:45am</option><option value="11:00">11:00am</option><option value="11:15">11:15am</option>
101
+ <option value="11:30">11:30am</option><option value="11:45">11:45am</option><option value="12:00">12:00pm</option>
102
+ <option value="12:15">12:15pm</option><option value="12:30">12:30pm</option><option value="12:45">12:45pm</option>
103
+ <option value="13:00">1:00pm</option><option value="13:15">1:15pm</option><option value="13:30">1:30pm</option>
104
+ <option value="13:45">1:45pm</option><option value="14:00">2:00pm</option><option value="14:15">2:15pm</option>
105
+ <option value="14:30">2:30pm</option><option value="14:45">2:45pm</option><option value="15:00">3:00pm</option>
106
+ <option value="15:15">3:15pm</option><option value="15:30">3:30pm</option><option value="15:45">3:45pm</option>
107
+ <option value="16:00">4:00pm</option><option value="16:15">4:15pm</option><option value="16:30">4:30pm</option>
108
+ <option value="16:45">4:45pm</option><option value="17:00">5:00pm</option><option value="17:15">5:15pm</option>
109
+ <option value="17:30">5:30pm</option><option value="17:45">5:45pm</option><option value="18:00">6:00pm</option>
110
+ <option value="18:15">6:15pm</option><option value="18:30">6:30pm</option><option value="18:45">6:45pm</option>
111
+ <option value="19:00">7:00pm</option><option value="19:15">7:15pm</option><option value="19:30">7:30pm</option>
112
+ <option value="19:45">7:45pm</option><option value="20:00">8:00pm</option><option value="20:15">8:15pm</option>
113
+ <option value="20:30">8:30pm</option><option value="20:45">8:45pm</option><option value="21:00">9:00pm</option>
114
+ <option value="21:15">9:15pm</option><option value="21:30">9:30pm</option><option value="21:45">9:45pm</option>
115
+ <option value="22:00">10:00pm</option><option value="22:15">10:15pm</option>
116
+ <option value="22:30">10:30pm</option><option value="22:45">10:45pm</option><option value="23:00">11:00pm</option>
117
+ <option value="23:15">11:15pm</option><option value="23:30">11:30pm</option><option value="23:45">11:45pm</option></select>
118
+ HTML
119
+ end
120
+
121
+ it "renders" do
122
+ cml = <<-HTML
123
+ <cml:hours label="When are they open?" name="h" />
124
+ HTML
125
+ @p = Parser.new( cml, :prefix => "u1" )
126
+ # puts Parser.escape(@p.to_html).gsub(/\n/,"<br/>")
127
+ # Note: I left off Wednesday through Sunday as `sorta_match` doesn't care
128
+ # and because it's hugely redundant.
129
+ @p.to_html.should sorta_match <<-HTML
130
+ <div class="cml" id="u1">
131
+ <div class="hours matcher:hours cml_field">
132
+ <label class="legend">When are they open?</label>
133
+ <table class="cml_hours cml_row h validates-hours">
134
+ <tr class="cml_hours_mon">
135
+ <td class="cml_hours_day">Monday</td>
136
+ <td class="cml_hours_hours">
137
+ <p class="cml_hours_1">
138
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_mon_open_1]")}</span>
139
+ <span class="cml_hours_to">to</span>
140
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_mon_close_1]")}</span>
141
+ </p>
142
+ <p class="cml_hours_2">
143
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_mon_open_2]")}</span>
144
+ <span class="cml_hours_to">to</span>
145
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_mon_close_2]")}</span>
146
+ </p>
147
+ </td>
148
+ <td class="cml_hours_open_close">
149
+ <p class="cml_hours_openallday">
150
+ <input type="hidden" name="u1[h_mon_openallday]" value="FALSE" />
151
+ <input type="checkbox" name="u1[h_mon_openallday]" id="id_u1_h_mon_openallday" value="TRUE" />
152
+ <label for="id_u1_h_mon_openallday">Open all day</label>
153
+ </p>
154
+ <p class="cml_hours_closedallday">
155
+ <input type="hidden" name="u1[h_mon_closedallday]" value="FALSE" />
156
+ <input type="checkbox" name="u1[h_mon_closedallday]" id="id_u1_h_mon_closedallday" value="TRUE" />
157
+ <label for="id_u1_h_mon_closedallday">Closed all day</label>
158
+ </p>
159
+ </td>
160
+ </tr>
161
+ <tr class="cml_hours_tue">
162
+ <td class="cml_hours_day">Tuesday</td>
163
+ <td class="cml_hours_hours">
164
+ <p class="cml_hours_1">
165
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_tue_open_1]")}</span>
166
+ <span class="cml_hours_to">to</span>
167
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_tue_close_1]")}</span>
168
+ </p>
169
+ <p class="cml_hours_2">
170
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_tue_open_2]")}</span>
171
+ <span class="cml_hours_to">to</span>
172
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_tue_close_2]")}</span>
173
+ </p>
174
+ </td>
175
+ <td class="cml_hours_open_close">
176
+ <p class="cml_hours_openallday">
177
+ <input type="hidden" name="u1[h_tue_openallday]" value="FALSE" />
178
+ <input type="checkbox" name="u1[h_tue_openallday]" id="id_u1_h_tue_openallday" value="TRUE" />
179
+ <label for="id_u1_h_tue_openallday">Open all day</label>
180
+ </p>
181
+ <p class="cml_hours_closedallday">
182
+ <input type="hidden" name="u1[h_tue_closedallday]" value="FALSE" />
183
+ <input type="checkbox" name="u1[h_tue_closedallday]" id="id_u1_h_tue_closedallday" value="TRUE" />
184
+ <label for="id_u1_h_tue_closedallday">Closed all day</label>
185
+ </p>
186
+ </td>
187
+ </tr>
188
+ HTML
189
+ end
190
+
191
+ it "renders with required validator" do
192
+ cml = <<-HTML
193
+ <cml:hours label="When are they open?" name="h" validates="required" />
194
+ HTML
195
+ @p = Parser.new( cml, :prefix => "u1" )
196
+ # puts Parser.escape(@p.to_html).gsub(/\n/,"<br/>")
197
+ # Note: I left off Wednesday through Sunday as `sorta_match` doesn't care
198
+ # and because it's hugely redundant.
199
+ @p.to_html.should sorta_match(<<-HTML)
200
+ <div class="cml" id="u1">
201
+ <div class="hours matcher:hours cml_field">
202
+ <label class="legend">When are they open?</label>
203
+ <table class="cml_hours cml_row h validates-required validates-hours">
204
+ HTML
205
+ end
206
+
207
+ it "renders with allowunlisted=\"true\"" do
208
+ cml = <<-HTML
209
+ <cml:hours label="When are they open?" name="h" allowunlisted="true" />
210
+ HTML
211
+ @p = Parser.new( cml, :prefix => "u1" )
212
+ # puts Parser.escape(@p.to_html).gsub(/\n/,"<br/>")
213
+ @p.to_html.should sorta_match <<-HTML
214
+ <div class="cml" id="u1">
215
+ <div class="hours matcher:hours cml_field">
216
+ <label class="legend">When are they open?</label>
217
+ <table class="cml_hours cml_row h validates-hours">
218
+ <tr class="cml_hours_mon">
219
+ <td class="cml_hours_day">Monday</td>
220
+ <td class="cml_hours_hours">
221
+ <p class="cml_hours_1">
222
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_mon_open_1]", false, :allow_unlisted => true)}</span>
223
+ <span class="cml_hours_to">to</span>
224
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_mon_close_1]", false, :allow_unlisted => true)}</span>
225
+ </p>
226
+ <p class="cml_hours_2">
227
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_mon_open_2]", false, :allow_unlisted => true)}</span>
228
+ <span class="cml_hours_to">to</span>
229
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_mon_close_2]", false, :allow_unlisted => true)}</span>
230
+ </p>
231
+ </td>
232
+ <td class="cml_hours_open_close">
233
+ <p class="cml_hours_openallday">
234
+ <input type="hidden" name="u1[h_mon_openallday]" value="FALSE" />
235
+ <input type="checkbox" name="u1[h_mon_openallday]" id="id_u1_h_mon_openallday" value="TRUE" />
236
+ <label for="id_u1_h_mon_openallday">Open all day</label>
237
+ </p>
238
+ <p class="cml_hours_closedallday">
239
+ <input type="hidden" name="u1[h_mon_closedallday]" value="FALSE" />
240
+ <input type="checkbox" name="u1[h_mon_closedallday]" id="id_u1_h_mon_closedallday" value="TRUE" />
241
+ <label for="id_u1_h_mon_closedallday">Closed all day</label>
242
+ </p>
243
+ </td>
244
+ </tr>
245
+ HTML
246
+ end
247
+
248
+ it "renders gold with no data" do
249
+ cml = <<-HTML
250
+ <cml:hours label="When are they open?" name="h" />
251
+ HTML
252
+ @p = Parser.new( cml, :prefix => "u1", :normalize => true )
253
+ # puts Parser.escape(@p.to_html).gsub(/\n/,"<br/>")
254
+ @p.to_html.should sorta_match <<-HTML
255
+ <div class="cml" id="u1">
256
+ <div class="hours matcher:hours cml_field">
257
+ <label class="legend">When are they open?</label>
258
+ <table class="cml_hours cml_row h_gold validates-hours">
259
+ <tr class="cml_hours_mon">
260
+ <td class="cml_hours_day">Monday</td>
261
+ <td class="cml_hours_hours">
262
+ <p class="cml_hours_1">
263
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_mon_open_1_gold][]", true)}</span>
264
+ <span class="cml_hours_to">to</span>
265
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_mon_close_1_gold][]", true)}</span>
266
+ </p>
267
+ <p class="cml_hours_2">
268
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_mon_open_2_gold][]", true)}</span>
269
+ <span class="cml_hours_to">to</span>
270
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_mon_close_2_gold][]", true)}</span>
271
+ </p>
272
+ </td>
273
+ <td class="cml_hours_open_close">
274
+ <p class="cml_hours_openallday">
275
+ <input type="hidden" name="u1[h_mon_openallday_gold][]" value="FALSE" />
276
+ <input type="checkbox" name="u1[h_mon_openallday_gold][]" id="id_u1_h_mon_openallday_gold" value="TRUE" />
277
+ <label for="id_u1_h_mon_openallday_gold">Open all day</label>
278
+ </p>
279
+ <p class="cml_hours_closedallday">
280
+ <input type="hidden" name="u1[h_mon_closedallday_gold][]" value="FALSE" />
281
+ <input type="checkbox" name="u1[h_mon_closedallday_gold][]" id="id_u1_h_mon_closedallday_gold" value="TRUE" />
282
+ <label for="id_u1_h_mon_closedallday_gold">Closed all day</label>
283
+ </p>
284
+ </td>
285
+ </tr>
286
+ <tr class="cml_hours_tue">
287
+ <td class="cml_hours_day">Tuesday</td>
288
+ <td class="cml_hours_hours">
289
+ <p class="cml_hours_1">
290
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_tue_open_1_gold][]", true)}</span>
291
+ <span class="cml_hours_to">to</span>
292
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_tue_close_1_gold][]", true)}</span>
293
+ </p>
294
+ <p class="cml_hours_2">
295
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_tue_open_2_gold][]", true)}</span>
296
+ <span class="cml_hours_to">to</span>
297
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_tue_close_2_gold][]", true)}</span>
298
+ </p>
299
+ </td>
300
+ <td class="cml_hours_open_close">
301
+ <p class="cml_hours_openallday">
302
+ <input type="hidden" name="u1[h_tue_openallday_gold][]" value="FALSE" />
303
+ <input type="checkbox" name="u1[h_tue_openallday_gold][]" id="id_u1_h_tue_openallday_gold" value="TRUE" />
304
+ <label for="id_u1_h_tue_openallday_gold">Open all day</label>
305
+ </p>
306
+ <p class="cml_hours_closedallday">
307
+ <input type="hidden" name="u1[h_tue_closedallday_gold][]" value="FALSE" />
308
+ <input type="checkbox" name="u1[h_tue_closedallday_gold][]" id="id_u1_h_tue_closedallday_gold" value="TRUE" />
309
+ <label for="id_u1_h_tue_closedallday_gold">Closed all day</label>
310
+ </p>
311
+ </td>
312
+ </tr>
313
+ HTML
314
+ end
315
+
316
+ it "renders gold with data" do
317
+ cml = <<-HTML
318
+ <cml:hours label="When are they open?" name="h" />
319
+ HTML
320
+ data = {
321
+ 'h_mon_openallday_gold' => true,
322
+ 'h_mon_closedallday_gold' => false,
323
+ 'h_mon_open_1_gold' => "0900",
324
+ 'h_mon_close_1_gold' => "1700",
325
+ 'h_mon_open_2_gold' => nil,
326
+ 'h_mon_close_2_gold' => "",
327
+
328
+ 'h_tue_openallday_gold' => ["true"],
329
+ 'h_tue_closedallday_gold' => ["FALSE"],
330
+ 'h_tue_open_1_gold' => ["0900"],
331
+ 'h_tue_close_1_gold' => ["not_listed"],
332
+ 'h_tue_open_2_gold' => ["1300", "1315"],
333
+ 'h_tue_close_2_gold' => ["1700", "1715"],
334
+ }
335
+ @p = Parser.new( cml, :prefix => "u1", :normalize => true, :data => data )
336
+ # puts Parser.escape(@p.to_html).gsub(/\n/,"<br/>")
337
+ @p.to_html.should sorta_match <<-HTML
338
+ <div class="cml" id="u1">
339
+ <div class="hours matcher:hours cml_field">
340
+ <label class="legend">When are they open?</label>
341
+ <table class="cml_hours cml_row h_gold validates-hours">
342
+ <tr class="cml_hours_mon">
343
+ <td class="cml_hours_day">Monday</td>
344
+ <td class="cml_hours_hours">
345
+ <p class="cml_hours_1">
346
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_mon_open_1_gold][]", true, :selected => "0900")}</span>
347
+ <span class="cml_hours_to">to</span>
348
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_mon_close_1_gold][]", true, :selected => "1700")}</span>
349
+ </p>
350
+ <p class="cml_hours_2">
351
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_mon_open_2_gold][]", true)}</span>
352
+ <span class="cml_hours_to">to</span>
353
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_mon_close_2_gold][]", true)}</span>
354
+ </p>
355
+ </td>
356
+ <td class="cml_hours_open_close">
357
+ <p class="cml_hours_openallday">
358
+ <input type="hidden" name="u1[h_mon_openallday_gold][]" value="FALSE" />
359
+ <input type="checkbox" name="u1[h_mon_openallday_gold][]" id="id_u1_h_mon_openallday_gold" value="TRUE" checked="checked" />
360
+ <label for="id_u1_h_mon_openallday_gold">Open all day</label>
361
+ </p>
362
+ <p class="cml_hours_closedallday">
363
+ <input type="hidden" name="u1[h_mon_closedallday_gold][]" value="FALSE" />
364
+ <input type="checkbox" name="u1[h_mon_closedallday_gold][]" id="id_u1_h_mon_closedallday_gold" value="TRUE" />
365
+ <label for="id_u1_h_mon_closedallday_gold">Closed all day</label>
366
+ </p>
367
+ </td>
368
+ </tr>
369
+ <tr class="cml_hours_tue">
370
+ <td class="cml_hours_day">Tuesday</td>
371
+ <td class="cml_hours_hours">
372
+ <p class="cml_hours_1">
373
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_tue_open_1_gold][]", true, :selected => "0900")}</span>
374
+ <span class="cml_hours_to">to</span>
375
+ <span class="cml_hours_selects">#{CML::TimeSelect.build("u1[h_tue_close_1_gold][]", true, :selected => "not_listed")}</span>
376
+ </p>
377
+ <p class="cml_hours_2">
378
+ <span class="cml_hours_selects">
379
+ #{CML::TimeSelect.build("u1[h_tue_open_2_gold][]", true, :selected => "1300")}
380
+ #{CML::TimeSelect.build("u1[h_tue_open_2_gold][]", true, :selected => "1315")}
381
+ </span>
382
+ <span class="cml_hours_to">to</span>
383
+ <span class="cml_hours_selects">
384
+ #{CML::TimeSelect.build("u1[h_tue_close_2_gold][]", true, :selected => "1700")}
385
+ #{CML::TimeSelect.build("u1[h_tue_close_2_gold][]", true, :selected => "1715")}
386
+ </span>
387
+ </p>
388
+ </td>
389
+ <td class="cml_hours_open_close">
390
+ <p class="cml_hours_openallday">
391
+ <input type="hidden" name="u1[h_tue_openallday_gold][]" value="FALSE" />
392
+ <input type="checkbox" name="u1[h_tue_openallday_gold][]" id="id_u1_h_tue_openallday_gold" value="TRUE" checked="checked" />
393
+ <label for="id_u1_h_tue_openallday_gold">Open all day</label>
394
+ </p>
395
+ <p class="cml_hours_closedallday">
396
+ <input type="hidden" name="u1[h_tue_closedallday_gold][]" value="FALSE" />
397
+ <input type="checkbox" name="u1[h_tue_closedallday_gold][]" id="id_u1_h_tue_closedallday_gold" value="TRUE" />
398
+ <label for="id_u1_h_tue_closedallday_gold">Closed all day</label>
399
+ </p>
400
+ </td>
401
+ </tr>
402
+ HTML
403
+ end
404
+ end
@@ -59,7 +59,7 @@ describe "CML Radios" do
59
59
  cml = <<-HTML
60
60
  <cml:radios label="Cool radios">
61
61
  {% for foo in bar %}
62
- <cml:radio label="Wanna do it?" value="{{bar}}"/>
62
+ <cml:radio label="Wanna do it?" value="{{bar}}" title="additional tooltip info"/>
63
63
  {% endfor %}
64
64
  </cml:radios>
65
65
  HTML
@@ -70,7 +70,7 @@ describe "CML Radios" do
70
70
  <div class="radios cml_field">
71
71
  <h2 class="legend">Cool radios</h2>
72
72
  {% for foo in bar %}
73
- <div class="cml_row"><label class="">
73
+ <div class="cml_row" title="additional tooltip info"><label class="">
74
74
  <input type="radio" value="{{bar}}" name="u12345[cool_radios]" class="cool_radios"/> Wanna do it?
75
75
  </label></div>
76
76
  {% endfor %}