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,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,7 @@
1
+ if defined?(local1)
2
+ para "Partial: Local1=#{local1}, Context Object ID=#{arbre_context.object_id}"
3
+ para "Paragraph 2"
4
+ else
5
+ para "Partial: Context Object ID=#{arbre_context.object_id}"
6
+ para "Paragraph 2"
7
+ end
@@ -0,0 +1 @@
1
+ <p>ERB template.</p>
@@ -0,0 +1 @@
1
+ h1 "This is an Arbre template"
@@ -0,0 +1,3 @@
1
+ render :partial => 'arbre_partial'
2
+
3
+ para "The previous element is a #{current_element.children.first.class}"
@@ -0,0 +1,5 @@
1
+ <% content_for(:head) do %>
2
+ <meta http-equiv="Author" content="Me" />
3
+ <% end %>
4
+
5
+ <h1>This is an ERB template</h1>
@@ -0,0 +1,3 @@
1
+ render :partial => 'erb_partial'
2
+
3
+ para "The previous element is a #{current_element.children.first.class}"
@@ -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,5 @@
1
+ layout do
2
+
3
+ self.title = "Application Title"
4
+
5
+ end
@@ -0,0 +1,4 @@
1
+ Combustion::Application.routes.draw do
2
+ get '/' => 'example#show'
3
+ get '/partial' => 'example#partial'
4
+ end
@@ -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'
@@ -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 }