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,300 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
include Arbre::Html
|
3
|
+
|
4
|
+
describe Tag do
|
5
|
+
|
6
|
+
let(:tag) { Arbre::Html::Tag.new }
|
7
|
+
|
8
|
+
######
|
9
|
+
# Building
|
10
|
+
|
11
|
+
it "should use the first argument as content if it is given" do
|
12
|
+
tag.build! "Content"
|
13
|
+
expect(tag.content).to eql('Content')
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should accept attributes" do
|
17
|
+
tag.build! 'id' => 'my-tag'
|
18
|
+
expect(tag.content).to eql('')
|
19
|
+
expect(tag.id).to eql('my-tag')
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should accept content and attributes" do
|
23
|
+
tag.build! "Content", 'id' => 'my-tag'
|
24
|
+
expect(tag.content).to eql('Content')
|
25
|
+
expect(tag.id).to eql('my-tag')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should accept symbolic keyword arguments as attributes as well" do
|
29
|
+
tag.build! "Content", 'id' => 'my-tag', :class => 'custom'
|
30
|
+
expect(tag.content).to eql('Content')
|
31
|
+
expect(tag.id).to eql('my-tag')
|
32
|
+
expect(tag.classes.to_a).to eql(['custom'])
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should require #tag_name to be implemented" do
|
36
|
+
expect{ tag.tag_name }.to raise_error(NotImplementedError)
|
37
|
+
end
|
38
|
+
|
39
|
+
######
|
40
|
+
# DSL
|
41
|
+
|
42
|
+
describe '.tag' do
|
43
|
+
it "should define the method tag_name on the class" do
|
44
|
+
klass = Class.new(Arbre::Html::Tag) { tag :span }
|
45
|
+
expect(klass.new.tag_name).to eql('span')
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should use the same tag name for derived classes" do
|
49
|
+
superclass = Class.new(Arbre::Html::Tag) { tag :span }
|
50
|
+
subclass = Class.new(superclass)
|
51
|
+
expect(subclass.new.tag_name).to eql('span')
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '.id' do
|
56
|
+
it "should add the given ID to the tag" do
|
57
|
+
klass = Class.new(Arbre::Html::Div) { id 'my-div' }
|
58
|
+
expect(klass.new.tag_id).to eql('my-div')
|
59
|
+
expect(klass.new.build!).to be_rendered_as('<div id="my-div"></div>')
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should also add the ID to subclasses" do
|
63
|
+
superclass = Class.new(Arbre::Html::Div) { id 'my-div' }
|
64
|
+
expect(Class.new(superclass).new.tag_id).to eql('my-div')
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should be able to be overridden in the build method" do
|
68
|
+
klass = Class.new(Arbre::Html::Div) do
|
69
|
+
id 'my-div'
|
70
|
+
def build!
|
71
|
+
self.id = 'overridden'
|
72
|
+
super
|
73
|
+
end
|
74
|
+
end
|
75
|
+
expect(klass.new.build!).to be_rendered_as('<div id="overridden"></div>')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe '.classes' do
|
80
|
+
it "should add the given classes to the tag" do
|
81
|
+
klass = Class.new(Arbre::Html::Div) { classes 'time-input' }
|
82
|
+
expect(klass.new.tag_classes).to eql(%w[time-input])
|
83
|
+
expect(klass.new.build!).to be_rendered_as('<div class="time-input"></div>')
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should flatten all given classes and allow space separated classes" do
|
87
|
+
klass = Class.new(Arbre::Html::Div) { classes 'one two', 'three', %w[four five] }
|
88
|
+
expect(klass.new.build!).to be_rendered_as('<div class="one two three four five"></div>')
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should also add the classes to subclasses" do
|
92
|
+
superclass = Class.new(Arbre::Html::Div) { classes 'time-input' }
|
93
|
+
expect(Class.new(superclass).new.tag_classes).to eql(%w[time-input])
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should combine classes with any given to the build! method" do
|
97
|
+
klass = Class.new(Arbre::Html::Div) { classes 'one two' }
|
98
|
+
expect(klass.new.build!(:class => 'three')).to be_rendered_as('<div class="one two three"></div>')
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
######
|
103
|
+
# Attributes
|
104
|
+
|
105
|
+
specify { expect(tag.attributes).to be_a(Attributes) }
|
106
|
+
|
107
|
+
it "should allow setting an attribute through #set_attribute" do
|
108
|
+
tag.set_attribute :style, 'display: none;'
|
109
|
+
tag.set_attribute 'placeholder', '(test)'
|
110
|
+
expect(tag.attributes).to eq('style' => 'display: none;', 'placeholder' => '(test)')
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should allow getting an attribute through #get_attribute" do
|
114
|
+
tag.set_attribute :style, 'display: none;'
|
115
|
+
expect(tag.get_attribute(:style)).to eql('display: none;')
|
116
|
+
expect(tag.get_attribute('style')).to eql('display: none;')
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should allow setting an attribute through an indexer" do
|
120
|
+
tag[:style] = 'display: none;'
|
121
|
+
tag['placeholder'] = '(test)'
|
122
|
+
expect(tag.attributes).to eq('style' => 'display: none;', 'placeholder' => '(test)')
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should allow getting an attribute through an indexer" do
|
126
|
+
tag[:style] = 'display: none;'
|
127
|
+
expect(tag[:style]).to eql('display: none;')
|
128
|
+
expect(tag['style']).to eql('display: none;')
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should check whether an attribute is set through has_attribute?" do
|
132
|
+
tag[:style] = 'display: none;'
|
133
|
+
expect(tag).to have_attribute(:style)
|
134
|
+
expect(tag).to have_attribute('style')
|
135
|
+
expect(tag).not_to have_attribute(:placeholder)
|
136
|
+
end
|
137
|
+
|
138
|
+
describe "attribute accessors" do
|
139
|
+
|
140
|
+
let(:tag_class) do
|
141
|
+
Class.new(Input) do
|
142
|
+
attribute :value
|
143
|
+
attribute :autocomplete, boolean: true
|
144
|
+
end
|
145
|
+
end
|
146
|
+
let(:tag) { tag_class.new }
|
147
|
+
|
148
|
+
it "should allow access to the :value attribute through a method" do
|
149
|
+
tag.value = 'Test'
|
150
|
+
expect(tag[:value]).to eql('Test')
|
151
|
+
|
152
|
+
tag[:value] = 'Test'
|
153
|
+
expect(tag.value).to eql('Test')
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should allow an attribute to be removed if set to nil" do
|
157
|
+
tag[:value] = 'Test'
|
158
|
+
tag.value = nil
|
159
|
+
expect(tag).not_to have_attribute(:value)
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should allow access to the boolean attribute :autocomplete through a method" do
|
163
|
+
tag.autocomplete = true
|
164
|
+
expect(tag.autocomplete).to be_true
|
165
|
+
expect(tag[:autocomplete]).to eql('autocomplete')
|
166
|
+
|
167
|
+
tag.autocomplete = double(:something_trueish)
|
168
|
+
expect(tag.autocomplete).to be_true
|
169
|
+
expect(tag[:autocomplete]).to eql('autocomplete')
|
170
|
+
|
171
|
+
tag.autocomplete = false
|
172
|
+
expect(tag.autocomplete).to be_false
|
173
|
+
expect(tag[:autocomplete]).to be_nil
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should use the value= method when passing in a value attribute to build!" do
|
177
|
+
allow(tag.attributes).to receive(:[]=)
|
178
|
+
|
179
|
+
value1 = double(:value); other1 = double(:other)
|
180
|
+
expect(tag).to receive(:value=).with(value1)
|
181
|
+
expect(tag.attributes).to receive(:[]=).with(:other, other1)
|
182
|
+
tag.build! value: value1, other: other1
|
183
|
+
|
184
|
+
value2 = double(:value); other2 = double(:other)
|
185
|
+
expect(tag).to receive(:value=).with(value2)
|
186
|
+
expect(tag.attributes).to receive(:[]=).with('other', other2)
|
187
|
+
tag.build! 'value' => value2, 'other' => other2
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should not accidentally set the content this way" do
|
191
|
+
content = 'My Content'
|
192
|
+
expect(tag).not_to receive(:content=)
|
193
|
+
tag.build! content: content
|
194
|
+
expect(tag.attributes[:content]).to eql('My Content')
|
195
|
+
end
|
196
|
+
|
197
|
+
it "should not accidentally invoke a helper method" do
|
198
|
+
helpers = double(:value= => nil)
|
199
|
+
allow(tag).to receive(:helpers).and_return(helpers)
|
200
|
+
expect(helpers).not_to receive(:value=)
|
201
|
+
|
202
|
+
tag.build! value: 'My Value'
|
203
|
+
expect(tag.attributes[:value]).to eql('My Value')
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
|
208
|
+
######
|
209
|
+
# ID & classes
|
210
|
+
|
211
|
+
describe '#generate_id' do
|
212
|
+
it "should generate an ID for the tag using its object_id" do
|
213
|
+
tag.generate_id!
|
214
|
+
expect(tag.id).to eql(tag.object_id.to_s)
|
215
|
+
expect(tag[:id]).to eql(tag.object_id.to_s)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe '#classes' do
|
220
|
+
it "should be the same as the :class attribute" do
|
221
|
+
expect(tag.classes).to be(tag[:class])
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
describe '#classes=' do
|
226
|
+
it "should replace the class attribute" do
|
227
|
+
expect(tag.attributes).to receive(:[]=).with(:class, 'one')
|
228
|
+
tag.classes = 'one'
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
describe '#add_class' do
|
233
|
+
it "should add classes" do
|
234
|
+
tag.add_class 'one'
|
235
|
+
expect(tag.classes.to_a).to eql(['one'])
|
236
|
+
tag.add_class 'two three'
|
237
|
+
expect(tag.classes.to_a).to eql(['one', 'two', 'three'])
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
describe '#remove_class' do
|
242
|
+
it "should remove classes" do
|
243
|
+
tag.classes = 'one two three'
|
244
|
+
expect(tag.classes.to_a).to eql(['one', 'two', 'three'])
|
245
|
+
tag.remove_class 'two three'
|
246
|
+
expect(tag.classes.to_a).to eql(['one'])
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
describe '#has_class?' do
|
251
|
+
it "should check whether the given class is present" do
|
252
|
+
tag.classes = 'one two three'
|
253
|
+
expect(tag).to have_class('one')
|
254
|
+
expect(tag).not_to have_class('four')
|
255
|
+
end
|
256
|
+
|
257
|
+
it "should check whether *all* given classes is present" do
|
258
|
+
tag.classes = 'one two three'
|
259
|
+
expect(tag).to have_class('one two')
|
260
|
+
expect(tag).not_to have_class('two four')
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
## Rendering is exemplified in the integration HTML spec.
|
265
|
+
|
266
|
+
######
|
267
|
+
# Inspection
|
268
|
+
|
269
|
+
it "should provide a terse description when using #inspect" do
|
270
|
+
table = Arbre::Html::Table.new
|
271
|
+
expect(table.inspect).to eql('<table>')
|
272
|
+
|
273
|
+
table.id = 'test'
|
274
|
+
expect(table.inspect).to eql('<table#test>')
|
275
|
+
|
276
|
+
table.classes << 'one' << 'two'
|
277
|
+
expect(table.inspect).to eql('<table#test.one.two>')
|
278
|
+
|
279
|
+
table.id = nil
|
280
|
+
expect(table.inspect).to eql('<table.one.two>')
|
281
|
+
|
282
|
+
input = Arbre::Html::Input.new
|
283
|
+
input.type = 'text'
|
284
|
+
expect(input.inspect).to eql('<input[type=text]>')
|
285
|
+
end
|
286
|
+
|
287
|
+
it "should append the class name if this is different from the tag name" do
|
288
|
+
klass = Class.new(Html::Tag) do
|
289
|
+
def tag_name
|
290
|
+
'table'
|
291
|
+
end
|
292
|
+
def self.name
|
293
|
+
'Datagrid'
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
expect(klass.new.inspect).to eql('<table(Datagrid)>')
|
298
|
+
end
|
299
|
+
|
300
|
+
end
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'arbre/rails/layouts'
|
4
|
+
Arbre::Context.send :include, Arbre::Rails::Layouts::ContextMethods
|
5
|
+
|
6
|
+
describe Arbre::Rails::Layouts do
|
7
|
+
|
8
|
+
# Layouts are also integration-specced in integration/rails_spec.rb.
|
9
|
+
let(:controller) { double() }
|
10
|
+
|
11
|
+
before do
|
12
|
+
allow(helpers).to receive(:controller).and_return(controller)
|
13
|
+
allow(helpers).to receive(:request).and_return(double(:xhr? => false))
|
14
|
+
controller.singleton_class.send :include, Arbre::Rails::Layouts::ControllerMethods
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#layout' do
|
18
|
+
|
19
|
+
context "not having specified a document (i.e. a non-Arbre content template)" do
|
20
|
+
it "should use the current legacy document" do
|
21
|
+
legacy_document_class = Class.new(Arbre::Html::Document)
|
22
|
+
expect(Arbre::Rails).to receive(:legacy_document).and_return(legacy_document_class)
|
23
|
+
|
24
|
+
arbre.layout
|
25
|
+
expect(arbre.children.first).to be_a(legacy_document_class)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should run a given layout block on it" do
|
29
|
+
legacy_document_class = Class.new(Arbre::Html::Document)
|
30
|
+
expect(Arbre::Rails).to receive(:legacy_document).and_return(legacy_document_class)
|
31
|
+
|
32
|
+
receiver = nil
|
33
|
+
layout_block = proc { receiver = self }
|
34
|
+
|
35
|
+
arbre.layout &layout_block
|
36
|
+
expect(receiver).to be(arbre.children.first)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "having specified a document but not a content block" do
|
41
|
+
it "should use the document class and arguments" do
|
42
|
+
document_class = Class.new(Arbre::Html::Document)
|
43
|
+
expect_any_instance_of(document_class).to receive(:build!).with(:one, :two)
|
44
|
+
|
45
|
+
arbre.document document_class, :one, :two
|
46
|
+
arbre.layout
|
47
|
+
expect(arbre.children.first).to be_a(document_class)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should run a given layout block on it" do
|
51
|
+
document_class = Class.new(Arbre::Html::Document)
|
52
|
+
|
53
|
+
receiver = nil
|
54
|
+
layout_block = proc { receiver = self }
|
55
|
+
|
56
|
+
arbre.document document_class
|
57
|
+
arbre.layout &layout_block
|
58
|
+
expect(receiver).to be(arbre.children.first)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "having specified a document and a content block" do
|
63
|
+
|
64
|
+
it "should use the document class, arguments and content block" do
|
65
|
+
document_class = Class.new(Arbre::Html::Document)
|
66
|
+
|
67
|
+
called = false
|
68
|
+
block = proc { called = true }
|
69
|
+
expect_any_instance_of(document_class).to receive(:build!).with(:one, :two) do |&blk|
|
70
|
+
blk.call
|
71
|
+
end
|
72
|
+
|
73
|
+
arbre.document document_class, :one, :two, &block
|
74
|
+
arbre.layout
|
75
|
+
expect(arbre.children.first).to be_a(document_class)
|
76
|
+
expect(called).to be_true
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should execute the content block on the document if it was not called from its build! method" do
|
80
|
+
document_class = Class.new(Arbre::Html::Document)
|
81
|
+
|
82
|
+
called = false
|
83
|
+
receiver = nil
|
84
|
+
block = proc { called = true; receiver = self }
|
85
|
+
expect_any_instance_of(document_class).to receive(:build!).with(:one, :two)
|
86
|
+
|
87
|
+
arbre.document document_class, :one, :two, &block
|
88
|
+
arbre.layout
|
89
|
+
expect(arbre.children.first).to be_a(document_class)
|
90
|
+
expect(called).to be_true
|
91
|
+
expect(receiver).to be(arbre.children.first)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should run a given layout block on it, but after the content block" do
|
95
|
+
document_class = Class.new(Arbre::Html::Document)
|
96
|
+
expect_any_instance_of(document_class).to receive(:build!)
|
97
|
+
|
98
|
+
called = []; receivers = []
|
99
|
+
content_block = proc { called << :content; receivers << self }
|
100
|
+
layout_block = proc { called << :layout; receivers << self }
|
101
|
+
|
102
|
+
arbre.document document_class, &content_block
|
103
|
+
arbre.layout &layout_block
|
104
|
+
expect(called).to eql([ :content, :layout ])
|
105
|
+
expect(receivers[0]).to be(arbre.children.first)
|
106
|
+
expect(receivers[1]).to be(arbre.children.first)
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should not call a layout block if this is an AJAX request" do
|
112
|
+
expect(helpers.request).to receive(:xhr?).and_return(true)
|
113
|
+
|
114
|
+
document_class = Class.new(Arbre::Html::Document)
|
115
|
+
|
116
|
+
called = []
|
117
|
+
content_block = proc { called << :content }
|
118
|
+
layout_block = proc { called << :layout }
|
119
|
+
|
120
|
+
arbre.document document_class, &content_block
|
121
|
+
arbre.layout &layout_block
|
122
|
+
expect(called).to eql([ :content ])
|
123
|
+
end
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
include Arbre
|
3
|
+
|
4
|
+
describe TextNode do
|
5
|
+
|
6
|
+
it "should accept only a string in its build method" do
|
7
|
+
node = arbre.append(TextNode, 'Test')
|
8
|
+
expect(node.text).to eql('Test')
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be buildable using :text_node" do
|
12
|
+
node = arbre.text_node('Test')
|
13
|
+
expect(node).to be_a(TextNode)
|
14
|
+
expect(node.text).to eql('Test')
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should be able to be created from a string" do
|
18
|
+
node = TextNode.from_string('Test')
|
19
|
+
expect(node.text).to eql('Test')
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should render its text only" do
|
23
|
+
node = TextNode.new
|
24
|
+
expect(node).to receive(:text).and_return('Test')
|
25
|
+
expect(node.to_s).to eql('Test')
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should always have an empty child collection" do
|
29
|
+
node = TextNode.new
|
30
|
+
expect(node.children).to be_empty
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should be disallowed to add any children" do
|
34
|
+
node = TextNode.new
|
35
|
+
expect{ node.children << Element.new }.to raise_error(NotImplementedError)
|
36
|
+
expect{ node.children.add Element.new }.to raise_error(NotImplementedError)
|
37
|
+
expect{ node.children.concat [ Element.new ] }.to raise_error(NotImplementedError)
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class ExampleController < ActionController::Base
|
2
|
+
|
3
|
+
def show
|
4
|
+
layout = params[:layout] == 'false' ? false : params[:layout]
|
5
|
+
render params[:template], :layout => layout
|
6
|
+
end
|
7
|
+
|
8
|
+
def partial
|
9
|
+
reuse_context = params[:context] != 'false'
|
10
|
+
|
11
|
+
if reuse_context
|
12
|
+
render :partial => 'arbre_partial', locals: { :arbre_context => Arbre::Context.new }
|
13
|
+
else
|
14
|
+
render :partial => 'arbre_partial'
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<p>ERB template.</p>
|
@@ -0,0 +1 @@
|
|
1
|
+
h1 "This is an Arbre template"
|
@@ -0,0 +1,11 @@
|
|
1
|
+
para "Main template: Context Object ID=#{arbre_context.object_id}"
|
2
|
+
|
3
|
+
div id: 'arbre' do
|
4
|
+
partial 'arbre_partial', local1: 'local1'
|
5
|
+
end
|
6
|
+
div id: 'arbre-using-render' do
|
7
|
+
render partial: 'arbre_partial'
|
8
|
+
end
|
9
|
+
div id: 'erb' do
|
10
|
+
partial 'erb_partial'
|
11
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
layout
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'combustion'
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'arbre/rails'
|
6
|
+
|
7
|
+
Combustion.path = 'spec/rails'
|
8
|
+
Combustion.initialize! :action_controller, :action_view do
|
9
|
+
config.middleware.use 'Rack::Lint'
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'rspec/rails'
|
13
|
+
require 'arbre/rails/rspec'
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
|
3
|
+
SimpleCov.start do
|
4
|
+
add_filter '/spec'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'arbre'
|
8
|
+
require 'arbre/rspec'
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
|
12
|
+
config.mock_with :rspec do |config|
|
13
|
+
config.syntax = [ :should, :expect ]
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
19
|
+
# in spec/support/ and its subdirectories.
|
20
|
+
Dir[File.expand_path("../support/**/*.rb", __FILE__)].each {|f| require f}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module ArbreExampleGroup
|
2
|
+
|
3
|
+
def arbre(&block)
|
4
|
+
@context ||= Arbre::Context.new(assigns, helpers)
|
5
|
+
@context.instance_exec &block if block_given?
|
6
|
+
@context
|
7
|
+
end
|
8
|
+
|
9
|
+
def assigns
|
10
|
+
@assigns ||= {}
|
11
|
+
end
|
12
|
+
|
13
|
+
def helpers
|
14
|
+
@helpers ||= {}
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
RSpec.configure { |c| c.include ArbreExampleGroup }
|