arbre2 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +30 -0
  3. data/.ruby-gemset +1 -0
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +6 -0
  6. data/CHANGELOG.md +75 -0
  7. data/Gemfile +2 -0
  8. data/Gemfile.lock +93 -0
  9. data/LICENSE +20 -0
  10. data/README.md +92 -0
  11. data/Rakefile +7 -0
  12. data/arbre.gemspec +28 -0
  13. data/lib/arbre/child_element_collection.rb +86 -0
  14. data/lib/arbre/container.rb +20 -0
  15. data/lib/arbre/context.rb +83 -0
  16. data/lib/arbre/element/building.rb +151 -0
  17. data/lib/arbre/element.rb +194 -0
  18. data/lib/arbre/element_collection.rb +93 -0
  19. data/lib/arbre/html/attributes.rb +91 -0
  20. data/lib/arbre/html/class_list.rb +53 -0
  21. data/lib/arbre/html/comment.rb +47 -0
  22. data/lib/arbre/html/document.rb +93 -0
  23. data/lib/arbre/html/html_tags.rb +67 -0
  24. data/lib/arbre/html/querying.rb +256 -0
  25. data/lib/arbre/html/tag.rb +317 -0
  26. data/lib/arbre/rails/layouts.rb +126 -0
  27. data/lib/arbre/rails/legacy_document.rb +29 -0
  28. data/lib/arbre/rails/rendering.rb +76 -0
  29. data/lib/arbre/rails/rspec/arbre_support.rb +61 -0
  30. data/lib/arbre/rails/rspec.rb +2 -0
  31. data/lib/arbre/rails/template_handler.rb +32 -0
  32. data/lib/arbre/rails.rb +35 -0
  33. data/lib/arbre/rspec/be_rendered_as_matcher.rb +103 -0
  34. data/lib/arbre/rspec/be_scripted_as_matcher.rb +68 -0
  35. data/lib/arbre/rspec/contain_script_matcher.rb +64 -0
  36. data/lib/arbre/rspec.rb +3 -0
  37. data/lib/arbre/text_node.rb +35 -0
  38. data/lib/arbre/version.rb +3 -0
  39. data/lib/arbre.rb +27 -0
  40. data/spec/arbre/integration/html_document_spec.rb +90 -0
  41. data/spec/arbre/integration/html_spec.rb +283 -0
  42. data/spec/arbre/integration/querying_spec.rb +187 -0
  43. data/spec/arbre/integration/rails_spec.rb +183 -0
  44. data/spec/arbre/rails/rspec/arbre_support_spec.rb +75 -0
  45. data/spec/arbre/rspec/be_rendered_as_matcher_spec.rb +80 -0
  46. data/spec/arbre/rspec/be_scripted_as_matcher_spec.rb +61 -0
  47. data/spec/arbre/rspec/contain_script_matcher_spec.rb +40 -0
  48. data/spec/arbre/support/arbre_example_group.rb +0 -0
  49. data/spec/arbre/unit/child_element_collection_spec.rb +146 -0
  50. data/spec/arbre/unit/container_spec.rb +23 -0
  51. data/spec/arbre/unit/context_spec.rb +95 -0
  52. data/spec/arbre/unit/element/building_spec.rb +300 -0
  53. data/spec/arbre/unit/element_collection_spec.rb +169 -0
  54. data/spec/arbre/unit/element_spec.rb +297 -0
  55. data/spec/arbre/unit/html/attributes_spec.rb +219 -0
  56. data/spec/arbre/unit/html/class_list_spec.rb +109 -0
  57. data/spec/arbre/unit/html/comment_spec.rb +42 -0
  58. data/spec/arbre/unit/html/querying_spec.rb +32 -0
  59. data/spec/arbre/unit/html/tag_spec.rb +300 -0
  60. data/spec/arbre/unit/rails/layouts_spec.rb +127 -0
  61. data/spec/arbre/unit/text_node_spec.rb +40 -0
  62. data/spec/rails/app/controllers/example_controller.rb +18 -0
  63. data/spec/rails/app/views/example/_arbre_partial.html.arb +7 -0
  64. data/spec/rails/app/views/example/_erb_partial.html.erb +1 -0
  65. data/spec/rails/app/views/example/arbre.html.arb +1 -0
  66. data/spec/rails/app/views/example/arbre_partial_result.html.arb +3 -0
  67. data/spec/rails/app/views/example/erb.html.erb +5 -0
  68. data/spec/rails/app/views/example/erb_partial_result.html.arb +3 -0
  69. data/spec/rails/app/views/example/partials.html.arb +11 -0
  70. data/spec/rails/app/views/layouts/empty.html.arb +1 -0
  71. data/spec/rails/app/views/layouts/with_title.html.arb +5 -0
  72. data/spec/rails/config/routes.rb +4 -0
  73. data/spec/rails_spec_helper.rb +13 -0
  74. data/spec/spec_helper.rb +20 -0
  75. data/spec/support/arbre_example_group.rb +19 -0
  76. metadata +254 -0
@@ -0,0 +1,297 @@
1
+ require 'spec_helper'
2
+ include Arbre
3
+
4
+ describe Element do
5
+
6
+ let(:element) { Element.new }
7
+
8
+ ######
9
+ # Context
10
+
11
+ describe '#arbre_context' do
12
+
13
+ it "should be a new one if none was specified" do
14
+ context = Element.new.arbre_context
15
+ expect(context).to be_a(Context)
16
+ end
17
+
18
+ it "should the specified one if one was specified" do
19
+ context = Context.new
20
+ expect(Element.new(context).arbre_context).to be(context)
21
+ end
22
+
23
+ end
24
+
25
+ describe '#assigns' do
26
+
27
+ it "should take assigns from the context" do
28
+ expect(element.arbre_context).to receive(:assigns).and_return(:variable => :value)
29
+ expect(element.assigns).to eql(:variable => :value)
30
+ end
31
+
32
+ end
33
+
34
+ describe '#helpers' do
35
+
36
+ it "should take helpers from the context" do
37
+ helpers = double()
38
+ expect(element.arbre_context).to receive(:helpers).and_return(helpers)
39
+ expect(element.helpers).to be(helpers)
40
+ end
41
+
42
+ end
43
+
44
+ ######
45
+ # Hierarchy
46
+
47
+ describe '#remove!' do
48
+ it "should remove itself from its parent children" do
49
+ element.parent = Element.new
50
+ expect(element.parent.children).to receive(:remove).with(element)
51
+ element.remove!
52
+ end
53
+ end
54
+
55
+ describe '#children' do
56
+
57
+ specify { expect(element.children).to be_a(ChildElementCollection) }
58
+
59
+ it "should be empty by default" do
60
+ expect(element.children).to be_empty
61
+ end
62
+
63
+ end
64
+
65
+ describe '#has_children?' do
66
+ it "should be false if the element has no children" do
67
+ expect(element).not_to have_children
68
+ end
69
+ it "should be true if the element has children" do
70
+ element << Element.new
71
+ expect(element).to have_children
72
+ end
73
+ end
74
+
75
+ describe '#empty?' do
76
+ it "should be true if the element has no children" do
77
+ expect(element).to be_empty
78
+ end
79
+ it "should be false if the element has children" do
80
+ element << Element.new
81
+ expect(element).not_to be_empty
82
+ end
83
+ end
84
+
85
+ describe '#<<' do
86
+
87
+ it "should add a child element" do
88
+ child = Element.new
89
+ element << child
90
+
91
+ expect(element).to have(1).child
92
+ expect(element.children[0]).to be(child)
93
+ end
94
+
95
+ end
96
+
97
+ describe '#orphan?' do
98
+
99
+ it "should be true if the element has no parent" do
100
+ expect(element).to be_orphan
101
+ end
102
+
103
+ it "should be false if the element has a parent" do
104
+ element.parent = Element.new
105
+ expect(element).not_to be_orphan
106
+ end
107
+
108
+ end
109
+
110
+ describe '#ancestors' do
111
+
112
+ specify { expect(element.ancestors).to be_a(ElementCollection) }
113
+
114
+ it "should be empty if the element is an orphan" do
115
+ expect(element.ancestors).to be_empty
116
+ end
117
+
118
+ it "should list all ancestors from near to far" do
119
+ element.parent = Element.new
120
+ element.parent.parent = Element.new
121
+ element.parent.parent.parent = Element.new
122
+ expect(element.ancestors.to_a).to eql([ element.parent, element.parent.parent, element.parent.parent.parent ])
123
+ end
124
+
125
+ end
126
+
127
+ describe '#descendants' do
128
+
129
+ specify { expect(element.descendants).to be_a(ElementCollection) }
130
+
131
+ it "should be empty if the element has no children" do
132
+ expect(element.descendants).to be_empty
133
+ end
134
+
135
+ it "should list all descendants, where each element is appended after its parent" do
136
+ child1, child2, grandchild11, grandchild21, grandchild22 = 5.times.collect { Element.new }
137
+
138
+ element << child1 << child2
139
+ child1 << grandchild11
140
+ child2 << grandchild21 << grandchild22
141
+
142
+ expect(element.descendants).to eq([
143
+ child1, grandchild11,
144
+ child2, grandchild21, grandchild22
145
+ ])
146
+ end
147
+
148
+ end
149
+
150
+ ######
151
+ # Content
152
+
153
+ describe '#content' do
154
+
155
+ it "should be the string output by #children" do
156
+ expect(element.children).to receive(:to_s).and_return('(CONTENT)')
157
+ expect(element.content).to eql('(CONTENT)')
158
+ end
159
+
160
+ end
161
+
162
+ describe '#content=' do
163
+
164
+ it "should clear any children and add a text node with the given string" do
165
+ element << Element.new << Element.new
166
+ element.content = "(CONTENT)"
167
+
168
+ expect(element).to have(1).child
169
+ expect(element.children[0]).to be_a(TextNode)
170
+ expect(element.content).to eql('(CONTENT)')
171
+ end
172
+
173
+ it "should clear any children and add a given element" do
174
+ element << Element.new << Element.new
175
+ child = Element.new
176
+ element.content = child
177
+
178
+ expect(element).to have(1).child
179
+ expect(element.children[0]).to be(child)
180
+ end
181
+
182
+ it "should clear any children and add a given element collection" do
183
+ element << Element.new << Element.new
184
+
185
+ child1 = Element.new
186
+ child2 = Element.new
187
+ children = ElementCollection.new([child1, child2])
188
+ element.content = children
189
+ expect(element.children).to eq([child1, child2])
190
+ end
191
+
192
+ end
193
+
194
+ ######
195
+ # Set operations
196
+
197
+ describe '#+' do
198
+
199
+ it "should wrap itself in a collection and add the other element" do
200
+ element2 = Element.new
201
+
202
+ elements = element + element2
203
+ expect(elements).to be_a(ElementCollection)
204
+ expect(elements).to have(2).items
205
+ expect(elements[0]).to be(element)
206
+ expect(elements[1]).to be(element2)
207
+ end
208
+
209
+ it "should wrap itself in a collection and add the other elements" do
210
+ element2 = Element.new
211
+ element3 = Element.new
212
+
213
+ elements = element + [ element2, element3 ]
214
+ expect(elements).to be_a(ElementCollection)
215
+ expect(elements).to have(3).items
216
+ expect(elements[0]).to be(element)
217
+ expect(elements[1]).to be(element2)
218
+ expect(elements[2]).to be(element3)
219
+ end
220
+
221
+ end
222
+
223
+ ######
224
+ # Building & rendering
225
+
226
+ it "should call any block passed into the #build method with the element as an argument, but not instance-exec'd" do
227
+ receiver = nil
228
+ received_arg = nil
229
+ element.build! { |arg| receiver = self; received_arg = arg }
230
+ expect(received_arg).to be(element)
231
+ expect(receiver).to be(self)
232
+ end
233
+
234
+ it "should render its content by default" do
235
+ expect(element).to receive(:content).and_return('(CONTENT)')
236
+ expect(element.to_s).to eql('(CONTENT)')
237
+ end
238
+
239
+ it "should alias to_s as to_html" do
240
+ expect(element).to receive(:to_s).and_return('(CONTENT)')
241
+ expect(element.to_html).to eql('(CONTENT)')
242
+ end
243
+
244
+ it "should provide a terse description using #inspect" do
245
+ expect(element.inspect).to match(/#<Arbre::Element:0x[0-9a-f]+>/)
246
+ end
247
+
248
+ it "should have an indentation level of 0 by default" do
249
+ expect(element.indent_level).to eql(0)
250
+ end
251
+
252
+ it "should have an indentation level of 1 higher than its parent, if it has a parent" do
253
+ element.parent = Element.new
254
+ expect(element.parent).to receive(:indent_level).and_return(5)
255
+ expect(element.indent_level).to eql(6)
256
+ end
257
+
258
+ ######
259
+ # Helpers & assigns access
260
+
261
+ it "should pass any missing method to a helper method" do
262
+ result = double()
263
+ allow(element).to receive(:helpers).and_return(double(:helpers))
264
+ expect(element.helpers).to receive(:my_helper).and_return(result)
265
+ expect(element.my_helper).to be(result)
266
+ expect{element.my_other_helper}.to raise_error(NoMethodError)
267
+ end
268
+
269
+ it "should actually define the method when it is first found on the helpers" do
270
+ allow(element).to receive(:helpers).and_return(double(:helpers))
271
+ expect(element.helpers).to receive(:my_helper)
272
+ element.my_helper
273
+
274
+ expect(element.method(:my_helper)).not_to be_nil
275
+ end
276
+
277
+ it "should respond to any helper method" do
278
+ result = double()
279
+ allow(element).to receive(:helpers).and_return(double(:helpers))
280
+ allow(element.helpers).to receive(:my_helper).and_return(result)
281
+ expect(element).to respond_to(:my_helper)
282
+ expect(element).not_to respond_to(:my_other_helper)
283
+ end
284
+
285
+ it "should not try a helper method if no helpers were found" do
286
+ expect{ element.my_helper }.to raise_error(NoMethodError)
287
+ end
288
+
289
+ it "should offer any assigns as instance variables when the element is initialized with a context" do
290
+ assigns = { :my_assign => :value }
291
+ context = Context.new(assigns, double(:helpers))
292
+ element = Element.new(context)
293
+
294
+ expect(element.instance_variable_get("@my_assign")).to be(:value)
295
+ end
296
+
297
+ end
@@ -0,0 +1,219 @@
1
+ require 'spec_helper'
2
+ include Arbre::Html
3
+
4
+ describe Attributes do
5
+
6
+ let(:attributes) { Attributes.new }
7
+
8
+ describe 'creation' do
9
+
10
+ it "should be able to be created using Attributes.new without arguments" do
11
+ attributes = Attributes.new
12
+ expect(attributes).to eq({})
13
+ end
14
+
15
+ it "should be able to be created using Attributes.new with a hash of arguments" do
16
+ attributes = Attributes.new(:one => '1')
17
+ expect(attributes).to eq({ 'one' => '1' })
18
+ end
19
+
20
+ it "should be able to be created using Attributes[] just like Hash[]" do
21
+ expect(Hash).to receive(:[]).with(:one, '1').and_return(:one => '1')
22
+ attributes = Attributes[:one, '1']
23
+ expect(attributes).to eq({ 'one' => '1' })
24
+ end
25
+
26
+ end
27
+
28
+ describe 'attribute accessing' do
29
+
30
+ it "should support indifferent access" do
31
+ attributes['one'] = 1
32
+ attributes[:two] = 2
33
+ attributes[3] = 3
34
+
35
+ expect(attributes['one']).to eql('1')
36
+ expect(attributes[:one]).to eql('1')
37
+ expect(attributes['two']).to eql('2')
38
+ expect(attributes[:two]).to eql('2')
39
+ expect(attributes[3]).to eql('3')
40
+ expect(attributes['3']).to eql('3')
41
+ expect(attributes[:'3']).to eql('3')
42
+ end
43
+
44
+ it "should store an attribute as a string key and value" do
45
+ attributes['one'] = 1
46
+ attributes[:two] = 2
47
+ attributes[3] = 3
48
+
49
+ expect(attributes).to eq({ 'one' => '1', 'two' => '2', '3' => '3' })
50
+ end
51
+
52
+ it "should store a 'true' value as the name of the attribute itself" do
53
+ attributes[:checked] = true
54
+ expect(attributes).to eq({ 'checked' => 'checked' })
55
+ end
56
+
57
+ it "should store any value as its string version" do
58
+ attributes[:number] = 5
59
+ expect(attributes).to eq({ 'number' => '5' })
60
+ end
61
+
62
+ it "should remove an attribute that is set to false" do
63
+ attributes = Attributes.new('one' => '1')
64
+ attributes[:one] = false
65
+
66
+ expect(attributes).to be_empty
67
+ end
68
+
69
+ it "should remove an attribute that is set to nil" do
70
+ attributes = Attributes.new('one' => '1')
71
+ attributes[:one] = nil
72
+
73
+ expect(attributes).to be_empty
74
+ end
75
+
76
+ end
77
+
78
+ describe "class attribute" do
79
+
80
+ it "should return a ClassList when the class attribute is accessed" do
81
+ expect(attributes[:class]).to be_a(ClassList)
82
+ expect(attributes[:class]).to be_empty
83
+ expect(attributes['class']).to be_a(ClassList)
84
+ expect(attributes['class']).to be_empty
85
+ end
86
+
87
+ it "should wrap things into a class list when the attribute is set" do
88
+ attributes[:class] = 'one'
89
+ expect(attributes[:class].to_s).to eql('one')
90
+
91
+ attributes[:class] = 'one two'
92
+ expect(attributes[:class].to_s).to eql('one two')
93
+
94
+ attributes[:class] = %[one two]
95
+ expect(attributes[:class].to_s).to eql('one two')
96
+ attributes[:class] << 'three four'
97
+ expect(attributes[:class].to_s).to eql('one two three four')
98
+ end
99
+
100
+ it "should not set the attribute if a nil or empty array is passed" do
101
+ attributes[:class] = nil
102
+ expect(attributes).not_to have_key(:class)
103
+ attributes[:class] = []
104
+ expect(attributes).not_to have_key(:class)
105
+ end
106
+
107
+ end
108
+
109
+ describe '#remove' do
110
+
111
+ it "should remove the attribute with the given name" do
112
+ attributes = Attributes.new(:one => '1')
113
+ attributes.remove 'one'
114
+ expect(attributes).to be_empty
115
+ end
116
+
117
+ it "should remove the attribute with the given name (access indifferent)" do
118
+ attributes = Attributes.new(:one => '1')
119
+ attributes.remove :one
120
+ expect(attributes).to be_empty
121
+ end
122
+
123
+ end
124
+
125
+ describe '#update' do
126
+
127
+ it "should update the attributes hash with new attributes" do
128
+ attributes = Attributes.new(:one => '1', :two => '2')
129
+
130
+ attributes.update 'one' => '2', :three => '3'
131
+ expect(attributes).to eq('one' => '2', 'two' => '2', 'three' => '3')
132
+ end
133
+
134
+ it "should be able to remove attributes by updating them to nil" do
135
+ attributes = Attributes.new(:one => '1', :two => '2')
136
+
137
+ attributes.update 'one' => '2', :two => nil, :three => '3'
138
+ expect(attributes).to eq('one' => '2', 'three' => '3')
139
+ end
140
+
141
+ end
142
+
143
+ describe 'equality' do
144
+
145
+ it "should be equal to any other hash-like construct with the same values" do
146
+ expect(Attributes.new(:one => '1')).to eq(Attributes.new(:one => '1'))
147
+ expect(Attributes.new(:one => '1')).to eq('one' => '1')
148
+ end
149
+
150
+ it "should be eql? only to other attribute hashes with the same values" do
151
+ expect(Attributes.new(:one => '1')).to eql(Attributes.new(:one => '1'))
152
+ expect(Attributes.new(:one => '1')).not_to eql('one' => '1')
153
+ end
154
+
155
+ end
156
+
157
+ describe 'enumeration' do
158
+
159
+ specify { expect(Attributes).to include(Enumerable) }
160
+
161
+ it "should enumerate through all attributes using #each" do
162
+ attributes = Attributes.new(:one => '1', :two => '2')
163
+
164
+ result = []
165
+ attributes.each { |k, v| result << [ k, v] }
166
+ expect(result).to eql([ ['one', '1'], ['two', '2'] ])
167
+ end
168
+
169
+ end
170
+
171
+ describe '#length, #size and #count' do
172
+
173
+ it "should all report the number of the attributes" do
174
+ expect(Attributes.new(:one => '2').length).to eql(1)
175
+ expect(Attributes.new(:one => '2').size).to eql(1)
176
+ expect(Attributes.new(:one => '2').count).to eql(1)
177
+ end
178
+
179
+ end
180
+
181
+ describe '#empty?' do
182
+
183
+ it "should be true if the attribute hash is empty" do
184
+ expect(Attributes.new).to be_empty
185
+ end
186
+
187
+ it "should be false if the attributes array contains elements" do
188
+ expect(Attributes.new(:one => '2')).not_to be_empty
189
+ end
190
+
191
+ end
192
+
193
+ describe '#to_s' do
194
+
195
+ it "should create a format suitable for in HTML tags" do
196
+ attributes = Attributes.new(:href => 'http://www.google.com', :target => :_blank)
197
+ expect(attributes.to_s).to eql('href="http://www.google.com" target="_blank"')
198
+ end
199
+
200
+ it "should escape any HTML entities" do
201
+ attributes = Attributes.new(:dangerous => '<>"')
202
+ expect(attributes.to_s).to eql('dangerous="&lt;&gt;&quot;"')
203
+ end
204
+
205
+ it "should be HTML safe" do
206
+ attributes = Attributes.new(:dangerous => '<>"')
207
+ expect(attributes.to_s).to be_html_safe
208
+ end
209
+
210
+ it "should not render an empty class attribute" do
211
+ attributes = Attributes.new(:class => 'test')
212
+ expect(attributes.to_s).to eql('class="test"')
213
+ attributes[:class] = nil
214
+ expect(attributes.to_s).to eql('')
215
+ end
216
+
217
+ end
218
+
219
+ end
@@ -0,0 +1,109 @@
1
+ require 'spec_helper'
2
+ include Arbre::Html
3
+
4
+ describe ClassList do
5
+
6
+ describe "initializer" do
7
+ it "should be able to be initialized without arguments" do
8
+ list = ClassList.new
9
+ expect(list).to be_empty
10
+ end
11
+
12
+ it "should be able to be initialized with an array of classes" do
13
+ list = ClassList.new(['one', 'two'])
14
+ expect(list.to_a).to eql(['one', 'two'])
15
+ end
16
+
17
+ it "should be able to be initialized with a string containing one class" do
18
+ list = ClassList.new('one')
19
+ expect(list.to_a).to eql(['one'])
20
+ end
21
+
22
+ it "should be able to be initialized with a string containing multiple classes separated by a space" do
23
+ list = ClassList.new('one two')
24
+ expect(list.to_a).to eql(['one', 'two'])
25
+ end
26
+ end
27
+
28
+ describe '#classes' do
29
+ it "should be an alias to itself" do
30
+ list = ClassList.new('one two')
31
+ expect(list.classes).to be(list)
32
+ end
33
+ end
34
+
35
+ describe "#add" do
36
+
37
+ it "should add one class" do
38
+ list = ClassList.new('one')
39
+
40
+ list << 'two' << 'three'
41
+ list.add 'four'
42
+
43
+ expect(list.to_a).to match_array(%w[one two three four])
44
+ end
45
+
46
+ it "should add multiple classes in one string" do
47
+ list = ClassList.new('one')
48
+ list << 'two three'
49
+ list.add 'four five'
50
+ expect(list.to_a).to match_array(%w[one two three four five])
51
+ end
52
+
53
+ it "should add a class using a symbol" do
54
+ list = ClassList.new('one')
55
+ list << :two
56
+ expect(list.to_a).to match_array(%w[one two])
57
+ end
58
+
59
+ end
60
+
61
+ describe '#concat' do
62
+
63
+ it "should append all classes in the given array" do
64
+ list = ClassList.new('one two')
65
+ list.concat [ 'three', 'four five' ]
66
+ expect(list.to_a).to match_array(%w[one two three four five])
67
+ end
68
+
69
+ end
70
+
71
+ describe "#remove" do
72
+
73
+ it "should remove one class" do
74
+ list = ClassList.new('one two')
75
+ list.remove 'one'
76
+ expect(list.to_a).to eql(['two'])
77
+ end
78
+
79
+ it "should add multiple classes in one string" do
80
+ list = ClassList.new('one two three')
81
+ list.remove 'one three'
82
+ expect(list.to_a).to eql(['two'])
83
+ end
84
+
85
+ end
86
+
87
+ describe "equality" do
88
+
89
+ it "should be equal to another ClassList with the same classes" do
90
+ expect(ClassList.new('one two')).to eq(ClassList.new('two one'))
91
+ end
92
+
93
+ it "should be equal to an array with the same classes" do
94
+ expect(ClassList.new('one two')).to eq(['two', 'one'])
95
+ end
96
+
97
+ end
98
+
99
+ describe "#to_s" do
100
+
101
+ it "should output html-ready content" do
102
+ list = ClassList.new('one two three')
103
+ list << 'four'
104
+ expect(list.to_s).to eql('one two three four')
105
+ end
106
+
107
+ end
108
+
109
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+ include Arbre
3
+
4
+ describe Html::Comment do
5
+
6
+ it "should render an empty comment" do
7
+ expect(arbre.comment.to_s).to eql('<!-- -->')
8
+ end
9
+
10
+ it "should render a single-line comment" do
11
+ comment = arbre.comment("This is a comment")
12
+ expect(comment.to_s).to eql('<!-- This is a comment -->')
13
+ end
14
+
15
+ it "should render a multi-line comment" do
16
+ comment = arbre.comment("This is a comment\ncontaining two lines")
17
+ expect(arbre.to_s).to eql(<<-HTML.gsub(/^ {6}/, '').chomp)
18
+ <!--
19
+ This is a comment
20
+ containing two lines
21
+ -->
22
+ HTML
23
+ end
24
+
25
+ it "should use proper indentation" do
26
+ arbre do
27
+ div do
28
+ comment "This is an indented comment\ncontaining two lines"
29
+ end
30
+ end
31
+
32
+ expect(arbre.to_s).to eql(<<-HTML.gsub(/^ {6}/, '').chomp)
33
+ <div>
34
+ <!--
35
+ This is an indented comment
36
+ containing two lines
37
+ -->
38
+ </div>
39
+ HTML
40
+ end
41
+
42
+ end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+ include Arbre
3
+ include Arbre::Html
4
+
5
+ describe Querying do
6
+
7
+ describe '#find and #find_first' do
8
+ it "should use a Query object" do
9
+ element = Element.new
10
+ fieldset = Element.new
11
+
12
+ query = double()
13
+ allow(Query).to receive(:new).with(element).and_return(query)
14
+ allow(query).to receive(:execute).with('fieldset#username').and_return([fieldset])
15
+ expect(element.find('fieldset#username')).to eql([fieldset])
16
+ expect(element.find_first('fieldset#username')).to be(fieldset)
17
+ end
18
+
19
+ it "should fail gracefully" do
20
+ element = Element.new
21
+ query = double()
22
+
23
+ allow(Query).to receive(:new).with(element).and_return(query)
24
+ allow(query).to receive(:execute).with('fieldset#username').and_return([])
25
+ expect(element.find('fieldset#username')).to eql([])
26
+ expect(element.find_first('fieldset#username')).to be_nil
27
+ end
28
+ end
29
+
30
+ # Other methods are integration-specced.
31
+
32
+ end