arbre2 2.1.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.
- checksums.yaml +7 -0
- data/.gitignore +30 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +75 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +93 -0
- data/LICENSE +20 -0
- data/README.md +92 -0
- data/Rakefile +7 -0
- data/arbre.gemspec +28 -0
- data/lib/arbre/child_element_collection.rb +86 -0
- data/lib/arbre/container.rb +20 -0
- data/lib/arbre/context.rb +83 -0
- data/lib/arbre/element/building.rb +151 -0
- data/lib/arbre/element.rb +194 -0
- data/lib/arbre/element_collection.rb +93 -0
- data/lib/arbre/html/attributes.rb +91 -0
- data/lib/arbre/html/class_list.rb +53 -0
- data/lib/arbre/html/comment.rb +47 -0
- data/lib/arbre/html/document.rb +93 -0
- data/lib/arbre/html/html_tags.rb +67 -0
- data/lib/arbre/html/querying.rb +256 -0
- data/lib/arbre/html/tag.rb +317 -0
- data/lib/arbre/rails/layouts.rb +126 -0
- data/lib/arbre/rails/legacy_document.rb +29 -0
- data/lib/arbre/rails/rendering.rb +76 -0
- data/lib/arbre/rails/rspec/arbre_support.rb +61 -0
- data/lib/arbre/rails/rspec.rb +2 -0
- data/lib/arbre/rails/template_handler.rb +32 -0
- data/lib/arbre/rails.rb +35 -0
- data/lib/arbre/rspec/be_rendered_as_matcher.rb +103 -0
- data/lib/arbre/rspec/be_scripted_as_matcher.rb +68 -0
- data/lib/arbre/rspec/contain_script_matcher.rb +64 -0
- data/lib/arbre/rspec.rb +3 -0
- data/lib/arbre/text_node.rb +35 -0
- data/lib/arbre/version.rb +3 -0
- data/lib/arbre.rb +27 -0
- data/spec/arbre/integration/html_document_spec.rb +90 -0
- data/spec/arbre/integration/html_spec.rb +283 -0
- data/spec/arbre/integration/querying_spec.rb +187 -0
- data/spec/arbre/integration/rails_spec.rb +183 -0
- data/spec/arbre/rails/rspec/arbre_support_spec.rb +75 -0
- data/spec/arbre/rspec/be_rendered_as_matcher_spec.rb +80 -0
- data/spec/arbre/rspec/be_scripted_as_matcher_spec.rb +61 -0
- data/spec/arbre/rspec/contain_script_matcher_spec.rb +40 -0
- data/spec/arbre/support/arbre_example_group.rb +0 -0
- data/spec/arbre/unit/child_element_collection_spec.rb +146 -0
- data/spec/arbre/unit/container_spec.rb +23 -0
- data/spec/arbre/unit/context_spec.rb +95 -0
- data/spec/arbre/unit/element/building_spec.rb +300 -0
- data/spec/arbre/unit/element_collection_spec.rb +169 -0
- data/spec/arbre/unit/element_spec.rb +297 -0
- data/spec/arbre/unit/html/attributes_spec.rb +219 -0
- data/spec/arbre/unit/html/class_list_spec.rb +109 -0
- data/spec/arbre/unit/html/comment_spec.rb +42 -0
- data/spec/arbre/unit/html/querying_spec.rb +32 -0
- data/spec/arbre/unit/html/tag_spec.rb +300 -0
- data/spec/arbre/unit/rails/layouts_spec.rb +127 -0
- data/spec/arbre/unit/text_node_spec.rb +40 -0
- data/spec/rails/app/controllers/example_controller.rb +18 -0
- data/spec/rails/app/views/example/_arbre_partial.html.arb +7 -0
- data/spec/rails/app/views/example/_erb_partial.html.erb +1 -0
- data/spec/rails/app/views/example/arbre.html.arb +1 -0
- data/spec/rails/app/views/example/arbre_partial_result.html.arb +3 -0
- data/spec/rails/app/views/example/erb.html.erb +5 -0
- data/spec/rails/app/views/example/erb_partial_result.html.arb +3 -0
- data/spec/rails/app/views/example/partials.html.arb +11 -0
- data/spec/rails/app/views/layouts/empty.html.arb +1 -0
- data/spec/rails/app/views/layouts/with_title.html.arb +5 -0
- data/spec/rails/config/routes.rb +4 -0
- data/spec/rails_spec_helper.rb +13 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/support/arbre_example_group.rb +19 -0
- 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="<>""')
|
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
|