arbo 1.2.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/.github/workflows/ci.yaml +21 -0
- data/.github/workflows/daily.yaml +23 -0
- data/.gitignore +11 -0
- data/CHANGELOG.md +95 -0
- data/CONTRIBUTING.md +3 -0
- data/Gemfile +17 -0
- data/LICENSE +20 -0
- data/README.md +29 -0
- data/Rakefile +18 -0
- data/arbo.gemspec +25 -0
- data/docs/Gemfile +2 -0
- data/docs/_config.yml +7 -0
- data/docs/_includes/footer.html +8 -0
- data/docs/_includes/google-analytics.html +16 -0
- data/docs/_includes/head.html +7 -0
- data/docs/_includes/toc.html +12 -0
- data/docs/_includes/top-menu.html +8 -0
- data/docs/_layouts/default.html +21 -0
- data/docs/index.md +106 -0
- data/docs/stylesheets/main.css +1152 -0
- data/lib/arbo/component.rb +22 -0
- data/lib/arbo/context.rb +118 -0
- data/lib/arbo/element/builder_methods.rb +83 -0
- data/lib/arbo/element/proxy.rb +28 -0
- data/lib/arbo/element.rb +225 -0
- data/lib/arbo/element_collection.rb +31 -0
- data/lib/arbo/html/attributes.rb +41 -0
- data/lib/arbo/html/class_list.rb +28 -0
- data/lib/arbo/html/document.rb +31 -0
- data/lib/arbo/html/html5_elements.rb +47 -0
- data/lib/arbo/html/tag.rb +220 -0
- data/lib/arbo/html/text_node.rb +43 -0
- data/lib/arbo/rails/forms.rb +101 -0
- data/lib/arbo/rails/rendering.rb +17 -0
- data/lib/arbo/rails/template_handler.rb +35 -0
- data/lib/arbo/rails.rb +5 -0
- data/lib/arbo/version.rb +3 -0
- data/lib/arbo.rb +21 -0
- data/spec/arbo/integration/html_spec.rb +307 -0
- data/spec/arbo/unit/component_spec.rb +54 -0
- data/spec/arbo/unit/context_spec.rb +35 -0
- data/spec/arbo/unit/element_finder_methods_spec.rb +116 -0
- data/spec/arbo/unit/element_spec.rb +272 -0
- data/spec/arbo/unit/html/class_list_spec.rb +16 -0
- data/spec/arbo/unit/html/tag_attributes_spec.rb +104 -0
- data/spec/arbo/unit/html/tag_spec.rb +124 -0
- data/spec/arbo/unit/html/text_node_spec.rb +5 -0
- data/spec/rails/integration/forms_spec.rb +117 -0
- data/spec/rails/integration/rendering_spec.rb +98 -0
- data/spec/rails/rails_spec_helper.rb +46 -0
- data/spec/rails/stub_app/config/database.yml +3 -0
- data/spec/rails/stub_app/config/routes.rb +3 -0
- data/spec/rails/stub_app/db/schema.rb +3 -0
- data/spec/rails/stub_app/log/.gitignore +1 -0
- data/spec/rails/stub_app/public/favicon.ico +0 -0
- data/spec/rails/support/mock_person.rb +15 -0
- data/spec/rails/templates/arbo/_partial.arb +1 -0
- data/spec/rails/templates/arbo/_partial_with_assignment.arb +1 -0
- data/spec/rails/templates/arbo/empty.arb +0 -0
- data/spec/rails/templates/arbo/page_with_arb_partial_and_assignment.arb +3 -0
- data/spec/rails/templates/arbo/page_with_assignment.arb +1 -0
- data/spec/rails/templates/arbo/page_with_erb_partial.arb +3 -0
- data/spec/rails/templates/arbo/page_with_helpers.arb +7 -0
- data/spec/rails/templates/arbo/page_with_partial.arb +3 -0
- data/spec/rails/templates/arbo/simple_page.arb +8 -0
- data/spec/rails/templates/erb/_partial.erb +1 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/support/bundle.rb +4 -0
- metadata +169 -0
@@ -0,0 +1,272 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'timeout'
|
3
|
+
|
4
|
+
describe Arbo::Element do
|
5
|
+
|
6
|
+
let(:element){ Arbo::Element.new }
|
7
|
+
|
8
|
+
context "when initialized" do
|
9
|
+
|
10
|
+
it "should have no children" do
|
11
|
+
expect(element.children).to be_empty
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should have no parent" do
|
15
|
+
expect(element.parent).to be_nil
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should respond to the HTML builder methods" do
|
19
|
+
expect(element).to respond_to(:span)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should have a set of local assigns" do
|
23
|
+
context = Arbo::Context.new hello: "World"
|
24
|
+
element = Arbo::Element.new(context)
|
25
|
+
expect(element.assigns[:hello]).to eq("World")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should have an empty hash with no local assigns" do
|
29
|
+
expect(element.assigns).to eq({})
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "passing in a helper object" do
|
35
|
+
|
36
|
+
let(:helper) do
|
37
|
+
Class.new do
|
38
|
+
def helper_method
|
39
|
+
"helper method"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
let(:element){ Arbo::Element.new(Arbo::Context.new(nil, helper.new)) }
|
45
|
+
|
46
|
+
it "should call methods on the helper object and return TextNode objects" do
|
47
|
+
expect(element.helper_method).to eq("helper method")
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should raise a NoMethodError if not found" do
|
51
|
+
expect {
|
52
|
+
element.a_method_that_doesnt_exist
|
53
|
+
}.to raise_error(NoMethodError)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "passing in assigns" do
|
59
|
+
let(:post){ double }
|
60
|
+
let(:assigns){ {post: post} }
|
61
|
+
|
62
|
+
it "should be accessible via a method call" do
|
63
|
+
element = Arbo::Element.new(Arbo::Context.new(assigns))
|
64
|
+
expect(element.post).to eq(post)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
it "to_a.flatten should not infinitely recurse" do
|
70
|
+
Timeout.timeout(1) do
|
71
|
+
element.to_a.flatten
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "adding a child" do
|
76
|
+
|
77
|
+
let(:child){ Arbo::Element.new }
|
78
|
+
|
79
|
+
before do
|
80
|
+
element.add_child child
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should add the child to the parent" do
|
84
|
+
expect(element.children.first).to eq(child)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should set the parent of the child" do
|
88
|
+
expect(child.parent).to eq(element)
|
89
|
+
end
|
90
|
+
|
91
|
+
context "when the child is nil" do
|
92
|
+
|
93
|
+
let(:child){ nil }
|
94
|
+
|
95
|
+
it "should not add the child" do
|
96
|
+
expect(element.children).to be_empty
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
context "when the child is a string" do
|
102
|
+
|
103
|
+
let(:child){ "Hello World" }
|
104
|
+
|
105
|
+
it "should add as a TextNode" do
|
106
|
+
expect(element.children.first).to be_instance_of(Arbo::HTML::TextNode)
|
107
|
+
expect(element.children.first.to_s).to eq("Hello World")
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe "setting the content" do
|
114
|
+
|
115
|
+
context "when a string" do
|
116
|
+
|
117
|
+
before do
|
118
|
+
element.add_child "Hello World"
|
119
|
+
element.content = "Goodbye"
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should clear the existing children" do
|
123
|
+
expect(element.children.size).to eq(1)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should add the string as a child" do
|
127
|
+
expect(element.children.first.to_s).to eq("Goodbye")
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should html escape the string" do
|
131
|
+
string = "Goodbye <br />"
|
132
|
+
element.content = string
|
133
|
+
expect(element.content.to_s).to eq("Goodbye <br />")
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context "when an element" do
|
138
|
+
let(:content_element){ Arbo::Element.new }
|
139
|
+
|
140
|
+
before do
|
141
|
+
element.content = content_element
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should set the content tag" do
|
145
|
+
expect(element.children.first).to eq(content_element)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "should set the tags parent" do
|
149
|
+
expect(content_element.parent).to eq(element)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context "when an array of tags" do
|
154
|
+
let(:first){ Arbo::Element.new }
|
155
|
+
let(:second){ Arbo::Element.new }
|
156
|
+
|
157
|
+
before do
|
158
|
+
element.content = [first, second]
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should set the content tag" do
|
162
|
+
expect(element.children.first).to eq(first)
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should set the tags parent" do
|
166
|
+
expect(element.children.first.parent).to eq(element)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
|
172
|
+
describe "rendering to html" do
|
173
|
+
|
174
|
+
before { @separator = $, }
|
175
|
+
after { $, = @separator }
|
176
|
+
let(:collection){ element + "hello world" }
|
177
|
+
|
178
|
+
it "should render the children collection" do
|
179
|
+
expect(element.children).to receive(:to_s).and_return("content")
|
180
|
+
expect(element.to_s).to eq("content")
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should render collection when is set the default separator" do
|
184
|
+
$, = "_"
|
185
|
+
expect(collection.to_s).to eq("hello world")
|
186
|
+
end
|
187
|
+
|
188
|
+
it "should render collection when is not set the default separator" do
|
189
|
+
expect(collection.to_s).to eq("hello world")
|
190
|
+
end
|
191
|
+
|
192
|
+
end
|
193
|
+
|
194
|
+
describe "adding elements together" do
|
195
|
+
|
196
|
+
context "when both elements are tags" do
|
197
|
+
let(:first){ Arbo::Element.new }
|
198
|
+
let(:second){ Arbo::Element.new }
|
199
|
+
let(:collection){ first + second }
|
200
|
+
|
201
|
+
it "should return an instance of Collection" do
|
202
|
+
expect(collection).to be_an_instance_of(Arbo::ElementCollection)
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should return the elements in the collection" do
|
206
|
+
expect(collection.size).to eq(2)
|
207
|
+
expect(collection.first).to eq(first)
|
208
|
+
expect(collection[1]).to eq(second)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
context "when the left is a collection and the right is a tag" do
|
213
|
+
let(:first){ Arbo::Element.new }
|
214
|
+
let(:second){ Arbo::Element.new }
|
215
|
+
let(:third){ Arbo::Element.new }
|
216
|
+
let(:collection){ Arbo::ElementCollection.new([first, second]) + third}
|
217
|
+
|
218
|
+
it "should return an instance of Collection" do
|
219
|
+
expect(collection).to be_an_instance_of(Arbo::ElementCollection)
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should return the elements in the collection flattened" do
|
223
|
+
expect(collection.size).to eq(3)
|
224
|
+
expect(collection[0]).to eq(first)
|
225
|
+
expect(collection[1]).to eq(second)
|
226
|
+
expect(collection[2]).to eq(third)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
context "when the right is a collection and the left is a tag" do
|
231
|
+
let(:first){ Arbo::Element.new }
|
232
|
+
let(:second){ Arbo::Element.new }
|
233
|
+
let(:third){ Arbo::Element.new }
|
234
|
+
let(:collection){ first + Arbo::ElementCollection.new([second,third]) }
|
235
|
+
|
236
|
+
it "should return an instance of Collection" do
|
237
|
+
expect(collection).to be_an_instance_of(Arbo::ElementCollection)
|
238
|
+
end
|
239
|
+
|
240
|
+
it "should return the elements in the collection flattened" do
|
241
|
+
expect(collection.size).to eq(3)
|
242
|
+
expect(collection[0]).to eq(first)
|
243
|
+
expect(collection[1]).to eq(second)
|
244
|
+
expect(collection[2]).to eq(third)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
context "when the left is a tag and the right is a string" do
|
249
|
+
let(:element){ Arbo::Element.new }
|
250
|
+
let(:collection){ element + "Hello World"}
|
251
|
+
|
252
|
+
it "should return an instance of Collection" do
|
253
|
+
expect(collection).to be_an_instance_of(Arbo::ElementCollection)
|
254
|
+
end
|
255
|
+
|
256
|
+
it "should return the elements in the collection" do
|
257
|
+
expect(collection.size).to eq(2)
|
258
|
+
expect(collection[0]).to eq(element)
|
259
|
+
expect(collection[1]).to be_an_instance_of(Arbo::HTML::TextNode)
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
context "when the left is a string and the right is a tag" do
|
264
|
+
let(:collection){ "hello World" + Arbo::Element.new}
|
265
|
+
|
266
|
+
it "should return a string" do
|
267
|
+
expect(collection.strip.chomp).to eq("hello World")
|
268
|
+
end
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Arbo::HTML::ClassList do
|
4
|
+
|
5
|
+
describe ".build_from_string" do
|
6
|
+
|
7
|
+
it "should build a new list from a string of classes" do
|
8
|
+
list = Arbo::HTML::ClassList.build_from_string("first second")
|
9
|
+
expect(list.size).to eq(2)
|
10
|
+
|
11
|
+
expect(list).to match_array(%w{first second})
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Arbo::HTML::Tag, "Attributes" do
|
4
|
+
|
5
|
+
let(:tag){ Arbo::HTML::Tag.new }
|
6
|
+
|
7
|
+
describe "attributes" do
|
8
|
+
|
9
|
+
before { tag.build id: "my_id" }
|
10
|
+
|
11
|
+
it "should have an attributes hash" do
|
12
|
+
expect(tag.attributes).to eq({id: "my_id"})
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#to_s" do
|
16
|
+
it "should render the attributes to html" do
|
17
|
+
expect(tag.to_s).to eq "<tag id=\"my_id\"></tag>\n"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "shouldn't render attributes that are empty" do
|
21
|
+
tag.class_list # initializes an empty ClassList
|
22
|
+
tag.set_attribute :foo, ''
|
23
|
+
tag.set_attribute :bar, nil
|
24
|
+
|
25
|
+
expect(tag.to_s).to eq "<tag id=\"my_id\"></tag>\n"
|
26
|
+
end
|
27
|
+
|
28
|
+
context "with hyphenated attributes" do
|
29
|
+
before { tag.build id: "my_id", "data-method" => "get", "data-remote" => true }
|
30
|
+
|
31
|
+
it "should render the attributes to html" do
|
32
|
+
expect(tag.to_s).to eq "<tag id=\"my_id\" data-method=\"get\" data-remote=\"true\"></tag>\n"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when there is a nested attribute" do
|
37
|
+
before { tag.build id: "my_id", data: { action: 'some_action' } }
|
38
|
+
|
39
|
+
it "should flatten the attributes when rendering to html" do
|
40
|
+
expect(tag.to_s).to eq "<tag id=\"my_id\" data-action=\"some_action\"></tag>\n"
|
41
|
+
end
|
42
|
+
|
43
|
+
it "shouldn't render attributes that are empty" do
|
44
|
+
tag.class_list # initializes an empty ClassList
|
45
|
+
tag.set_attribute :foo, { bar: '' }
|
46
|
+
tag.set_attribute :bar, { baz: nil }
|
47
|
+
|
48
|
+
expect(tag.to_s).to eq "<tag id=\"my_id\" data-action=\"some_action\"></tag>\n"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "when there is a deeply nested attribute" do
|
53
|
+
before { tag.build id: "my_id", foo: { bar: { baz: 'foozle' } } }
|
54
|
+
|
55
|
+
it "should flatten the attributes when rendering to html" do
|
56
|
+
expect(tag.to_s).to eq "<tag id=\"my_id\" foo-bar-baz=\"foozle\"></tag>\n"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when there are multiple nested attributes" do
|
61
|
+
before { tag.build id: "my_id", foo: { bar: 'foozle1', baz: 'foozle2' } }
|
62
|
+
|
63
|
+
it "should flatten the attributes when rendering to html" do
|
64
|
+
expect(tag.to_s).to eq "<tag id=\"my_id\" foo-bar=\"foozle1\" foo-baz=\"foozle2\"></tag>\n"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should get an attribute value" do
|
70
|
+
expect(tag.attr(:id)).to eq("my_id")
|
71
|
+
end
|
72
|
+
|
73
|
+
describe "#has_attribute?" do
|
74
|
+
context "when the attribute exists" do
|
75
|
+
it "should return true" do
|
76
|
+
expect(tag.has_attribute?(:id)).to eq(true)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context "when the attribute does not exist" do
|
81
|
+
it "should return false" do
|
82
|
+
expect(tag.has_attribute?(:class)).to eq(false)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
it "should remove an attribute" do
|
88
|
+
expect(tag.attributes).to eq({id: "my_id"})
|
89
|
+
expect(tag.remove_attribute(:id)).to eq("my_id")
|
90
|
+
expect(tag.attributes).to eq({})
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "rendering attributes" do
|
95
|
+
it "should html safe the attribute values" do
|
96
|
+
tag.set_attribute(:class, '">bad things!')
|
97
|
+
expect(tag.to_s).to eq "<tag class=\"">bad things!\"></tag>\n"
|
98
|
+
end
|
99
|
+
it "should should escape the attribute names" do
|
100
|
+
tag.set_attribute(">bad", "things")
|
101
|
+
expect(tag.to_s).to eq "<tag >bad=\"things\"></tag>\n"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Arbo::HTML::Tag do
|
4
|
+
|
5
|
+
let(:tag){ Arbo::HTML::Tag.new }
|
6
|
+
|
7
|
+
describe "building a new tag" do
|
8
|
+
before { tag.build "Hello World", id: "my_id" }
|
9
|
+
|
10
|
+
it "should set the contents to a string" do
|
11
|
+
expect(tag.content).to eq("Hello World")
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should set the hash of options to the attributes" do
|
15
|
+
expect(tag.attributes).to eq({ id: "my_id" })
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "creating a tag 'for' an object" do
|
20
|
+
let(:model_name){ double(singular: "resource_class")}
|
21
|
+
let(:resource_class){ double(model_name: model_name) }
|
22
|
+
let(:resource){ double(class: resource_class, to_key: ['5'])}
|
23
|
+
|
24
|
+
before do
|
25
|
+
tag.build for: resource
|
26
|
+
end
|
27
|
+
it "should set the id to the type and id" do
|
28
|
+
expect(tag.id).to eq("resource_class_5")
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should add a class name" do
|
32
|
+
expect(tag.class_list).to include("resource_class")
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
describe "for an object that doesn't have a model_name" do
|
37
|
+
let(:resource_class){ double(name: 'ResourceClass') }
|
38
|
+
|
39
|
+
before do
|
40
|
+
tag.build for: resource
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should set the id to the type and id" do
|
44
|
+
expect(tag.id).to eq("resource_class_5")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should add a class name" do
|
48
|
+
expect(tag.class_list).to include("resource_class")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "with a default_id_for_prefix" do
|
53
|
+
|
54
|
+
let(:tag) do
|
55
|
+
Class.new(Arbo::HTML::Tag) do
|
56
|
+
def default_id_for_prefix
|
57
|
+
"a_prefix"
|
58
|
+
end
|
59
|
+
end.new
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should set the id to the type and id" do
|
63
|
+
expect(tag.id).to eq("a_prefix_resource_class_5")
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "creating a tag with a for attribute" do
|
70
|
+
it "sets the `for` attribute when a string is given" do
|
71
|
+
tag.build for: "email"
|
72
|
+
expect(tag.attributes[:for]).to eq "email"
|
73
|
+
end
|
74
|
+
|
75
|
+
it "sets the `for` attribute when a symbol is given" do
|
76
|
+
tag.build for: :email
|
77
|
+
expect(tag.attributes[:for]).to eq :email
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "css class names" do
|
82
|
+
|
83
|
+
it "should add a class" do
|
84
|
+
tag.add_class "hello_world"
|
85
|
+
expect(tag.class_names).to eq("hello_world")
|
86
|
+
end
|
87
|
+
|
88
|
+
it "should remove_class" do
|
89
|
+
tag.add_class "hello_world"
|
90
|
+
expect(tag.class_names).to eq("hello_world")
|
91
|
+
tag.remove_class "hello_world"
|
92
|
+
expect(tag.class_names).to eq("")
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should not add a class if it already exists" do
|
96
|
+
tag.add_class "hello_world"
|
97
|
+
tag.add_class "hello_world"
|
98
|
+
expect(tag.class_names).to eq("hello_world")
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should seperate classes with space" do
|
102
|
+
tag.add_class "hello world"
|
103
|
+
expect(tag.class_list.size).to eq(2)
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should create a class list from a string" do
|
107
|
+
tag = Arbo::HTML::Tag.new
|
108
|
+
tag.build(class: "first-class")
|
109
|
+
tag.add_class "second-class"
|
110
|
+
expect(tag.class_list.size).to eq(2)
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "#render_in" do
|
116
|
+
before { tag.build "Hello World", id: "my_id" }
|
117
|
+
|
118
|
+
it "renders tag" do
|
119
|
+
html = tag.render_in(Arbo::Context.new)
|
120
|
+
|
121
|
+
expect(html).to eq "<tag id=\"my_id\">Hello World</tag>\n"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'rails/rails_spec_helper'
|
2
|
+
|
3
|
+
describe "Building forms" do
|
4
|
+
|
5
|
+
let(:assigns){ {} }
|
6
|
+
let(:helpers){ mock_action_view }
|
7
|
+
let(:html) { form.to_s }
|
8
|
+
let(:output_buffer) { form.render_in(form) }
|
9
|
+
|
10
|
+
describe "building a simple form for" do
|
11
|
+
|
12
|
+
let(:form) do
|
13
|
+
arbo do
|
14
|
+
form_for MockPerson.new, url: "/" do |f|
|
15
|
+
f.label :name
|
16
|
+
f.text_field :name
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should build a form" do
|
22
|
+
expect(html).to have_selector("form")
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should include the hidden authenticity token" do
|
26
|
+
expect(html).to have_selector('input[type="hidden"][name="authenticity_token"][value="AUTH_TOKEN"]', visible: :hidden)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should create a label" do
|
30
|
+
expect(html).to have_selector("form label[for=mock_person_name]")
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should create a text field" do
|
34
|
+
expect(html).to have_selector("form input[type=text]")
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should render equally with each strategy" do
|
38
|
+
expect(output_buffer).to eq html
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "building a form with fields for" do
|
43
|
+
|
44
|
+
let(:form) do
|
45
|
+
arbo do
|
46
|
+
form_for MockPerson.new, url: "/" do |f|
|
47
|
+
f.label :name
|
48
|
+
f.text_field :name
|
49
|
+
f.fields_for :permission do |pf|
|
50
|
+
pf.label :admin
|
51
|
+
pf.check_box :admin
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should render nested label" do
|
58
|
+
expect(html).to have_selector("form label[for=mock_person_permission_admin]", text: "Admin")
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should render nested label" do
|
62
|
+
expect(html).to have_selector("form input[type=checkbox][name='mock_person[permission][admin]']")
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should not render a div for the proxy" do
|
66
|
+
expect(html).not_to have_selector("form div.fields_for_proxy")
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should render equally with each strategy" do
|
70
|
+
expect(output_buffer).to eq html
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "forms with other elements" do
|
76
|
+
let(:form) do
|
77
|
+
arbo do
|
78
|
+
form_for MockPerson.new, url: "/" do |f|
|
79
|
+
|
80
|
+
div do
|
81
|
+
f.label :name
|
82
|
+
f.text_field :name
|
83
|
+
end
|
84
|
+
|
85
|
+
para do
|
86
|
+
f.label :name
|
87
|
+
f.text_field :name
|
88
|
+
end
|
89
|
+
|
90
|
+
div class: "permissions" do
|
91
|
+
f.fields_for :permission do |pf|
|
92
|
+
div class: "permissions_label" do
|
93
|
+
pf.label :admin
|
94
|
+
end
|
95
|
+
pf.check_box :admin
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should correctly nest elements" do
|
104
|
+
expect(html).to have_selector("form > p > label")
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should correnctly nest elements within fields for" do
|
108
|
+
expect(html).to have_selector("form > div.permissions > div.permissions_label label")
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should render equally with each strategy" do
|
112
|
+
expect(output_buffer).to eq html
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
end
|