arbre2 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,183 @@
|
|
1
|
+
require 'rails_spec_helper'
|
2
|
+
|
3
|
+
describe Arbre::Rails, :type => :request do
|
4
|
+
|
5
|
+
# Describes Rails integration. Refer to spec/rails/example_app for an example application.
|
6
|
+
# The application offers one controller action mapped to the root path, which can take
|
7
|
+
# the name of a template and/or a layout to render.
|
8
|
+
|
9
|
+
let(:body) { response.body }
|
10
|
+
|
11
|
+
######
|
12
|
+
# Content / layout
|
13
|
+
|
14
|
+
it "should render an ERB template without a layout" do
|
15
|
+
get '/', :template => 'erb', :layout => false
|
16
|
+
expect(body).to be_rendered_as('<h1>This is an ERB template</h1>', escape: false)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should render an Arbre template without a layout" do
|
20
|
+
get '/', :template => 'arbre', :layout => false
|
21
|
+
expect(body).to be_rendered_as('<h1>This is an Arbre template</h1>', escape: false)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should render an ERB template with an empty Arbre layout" do
|
25
|
+
get '/', :template => 'erb', :layout => 'empty'
|
26
|
+
expect(body).to be_rendered_as(<<-HTML, escape: false)
|
27
|
+
<!DOCTYPE html>
|
28
|
+
|
29
|
+
<html>
|
30
|
+
<head>
|
31
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
32
|
+
<meta http-equiv="Author" content="Me" />
|
33
|
+
</head>
|
34
|
+
<body>
|
35
|
+
<h1>This is an ERB template</h1>
|
36
|
+
</body>
|
37
|
+
</html>
|
38
|
+
HTML
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should render an ERB template with an Arbre layout that sets a title" do
|
42
|
+
get '/', :template => 'erb', :layout => 'with_title'
|
43
|
+
expect(body).to be_rendered_as(<<-HTML, escape: false)
|
44
|
+
<!DOCTYPE html>
|
45
|
+
|
46
|
+
<html>
|
47
|
+
<head>
|
48
|
+
<title>Application Title</title>
|
49
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
50
|
+
<meta http-equiv="Author" content="Me" />
|
51
|
+
</head>
|
52
|
+
<body>
|
53
|
+
<h1>This is an ERB template</h1>
|
54
|
+
</body>
|
55
|
+
</html>
|
56
|
+
HTML
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should allow the legacy document class to be overridden" do
|
60
|
+
Arbre::Rails.legacy_document = Class.new(Arbre::Html::Document) do
|
61
|
+
def build!
|
62
|
+
super
|
63
|
+
|
64
|
+
head do
|
65
|
+
text_node helpers.content_for(:head)
|
66
|
+
text_node helpers.content_for(:styles)
|
67
|
+
end
|
68
|
+
body do
|
69
|
+
div id: 'content-container' do
|
70
|
+
text_node helpers.content_for(:layout)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
get '/', :template => 'erb', :layout => 'empty'
|
77
|
+
expect(body).to be_rendered_as(<<-HTML, escape: false)
|
78
|
+
<!DOCTYPE html>
|
79
|
+
|
80
|
+
<html>
|
81
|
+
<head>
|
82
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
83
|
+
<meta http-equiv="Author" content="Me" />
|
84
|
+
</head>
|
85
|
+
<body>
|
86
|
+
<div id="content-container">
|
87
|
+
<h1>This is an ERB template</h1>
|
88
|
+
</div>
|
89
|
+
</body>
|
90
|
+
</html>
|
91
|
+
HTML
|
92
|
+
|
93
|
+
Arbre::Rails.legacy_document = nil
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should render an Arbre template with an empty Arbre layout" do
|
97
|
+
get '/', :template => 'arbre', :layout => 'empty'
|
98
|
+
expect(body).to be_rendered_as(<<-HTML, escape: false)
|
99
|
+
<!DOCTYPE html>
|
100
|
+
|
101
|
+
<html>
|
102
|
+
<head>
|
103
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
104
|
+
</head>
|
105
|
+
<body>
|
106
|
+
<h1>This is an Arbre template</h1>
|
107
|
+
</body>
|
108
|
+
</html>
|
109
|
+
HTML
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should render an Arbre template with an Arbre layout that sets a title" do
|
113
|
+
get '/', :template => 'arbre', :layout => 'with_title'
|
114
|
+
expect(body).to be_rendered_as(<<-HTML, escape: false)
|
115
|
+
<!DOCTYPE html>
|
116
|
+
|
117
|
+
<html>
|
118
|
+
<head>
|
119
|
+
<title>Application Title</title>
|
120
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
121
|
+
</head>
|
122
|
+
<body>
|
123
|
+
<h1>This is an Arbre template</h1>
|
124
|
+
</body>
|
125
|
+
</html>
|
126
|
+
HTML
|
127
|
+
end
|
128
|
+
|
129
|
+
######
|
130
|
+
# Partial / sub-template rendering
|
131
|
+
|
132
|
+
it "should re-use a context when using method `partial' and the partial is also Arbre" do
|
133
|
+
get '/', :template => 'partials', :layout => false
|
134
|
+
|
135
|
+
expect(body).to be_rendered_as(%r[
|
136
|
+
<p>Main template: Context Object ID=(\d+)</p>
|
137
|
+
<div id="arbre">
|
138
|
+
<p>Partial: Local1=local1, Context Object ID=(\d+)</p>
|
139
|
+
<p>Paragraph 2</p>
|
140
|
+
</div>
|
141
|
+
<div id="arbre-using-render">
|
142
|
+
<p>Partial: Context Object ID=(\d+)</p>
|
143
|
+
<p>Paragraph 2</p>
|
144
|
+
</div>
|
145
|
+
<div id="erb">
|
146
|
+
<p>ERB template.</p>
|
147
|
+
</div>
|
148
|
+
]x, escape: false)
|
149
|
+
|
150
|
+
# Make sure that the context is re-used between the first two, but not in the case of 'render'.
|
151
|
+
(ctx1_id,_), (ctx2_id,_), (ctx3_id,_) = body.scan(/Context Object ID=(\d+)/)
|
152
|
+
expect(ctx1_id).to eql(ctx2_id)
|
153
|
+
expect(ctx1_id).not_to eql(ctx3_id)
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should return an empty string if an Arbre context is re-used" do
|
157
|
+
get '/partial', :context => true
|
158
|
+
expect(body).to be_rendered_as('', escape: false)
|
159
|
+
end
|
160
|
+
|
161
|
+
it "should not return an empty string if an Arbre context is not re-used" do
|
162
|
+
get '/partial', :context => false
|
163
|
+
expect(body).to be_rendered_as(%r[^<p>Partial: Context Object ID=(\d+)</p>], escape: false)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should handle an Arbre template without converting the template to a string" do
|
167
|
+
get '/', :template => 'arbre_partial_result', :layout => false
|
168
|
+
expect(body).to be_rendered_as(%r[
|
169
|
+
<p>Partial: Context Object ID=(\d+)</p>
|
170
|
+
<p>Paragraph 2</p>
|
171
|
+
<p>The previous element is a Arbre::Html::P</p>
|
172
|
+
]x, escape: false)
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should wrap any other partial in a TextNode" do
|
176
|
+
get '/', :template => 'erb_partial_result', :layout => false
|
177
|
+
expect(body).to be_rendered_as(%r[
|
178
|
+
<p>ERB template.</p>
|
179
|
+
<p>The previous element is a Arbre::TextNode</p>
|
180
|
+
]x, escape: false)
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'rails_spec_helper'
|
2
|
+
|
3
|
+
describe Arbre::Rails::RSpec::ArbreSupport, arbre: true do
|
4
|
+
|
5
|
+
let(:example) { self }
|
6
|
+
subject { example }
|
7
|
+
|
8
|
+
describe '#arbre_context' do
|
9
|
+
let(:assigns) { double(:assigns) }
|
10
|
+
let(:helpers) { double(:helpers) }
|
11
|
+
|
12
|
+
it "should build and memoize an Arbre context" do
|
13
|
+
context = double(:context)
|
14
|
+
expect(Arbre::Context).to receive(:new).once.with(assigns, helpers).and_return(context)
|
15
|
+
expect(example.arbre_context).to be(context)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should be aliased as #arbre" do
|
19
|
+
context = double(:context)
|
20
|
+
expect(Arbre::Context).to receive(:new).once.with(assigns, helpers).and_return(context)
|
21
|
+
expect(example.arbre_context).to be(context)
|
22
|
+
expect(example.arbre).to be(context)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
its(:assigns) { should eql({}) }
|
27
|
+
|
28
|
+
describe '#helpers' do
|
29
|
+
it "should build and memoize helpers" do
|
30
|
+
helpers = double(:helpers)
|
31
|
+
expect(example).to receive(:build_helpers).once.and_return(helpers)
|
32
|
+
expect(example.helpers).to be(helpers)
|
33
|
+
expect(example.helpers).to be(helpers)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#build_helpers' do
|
38
|
+
let(:helpers) { example.build_helpers }
|
39
|
+
|
40
|
+
specify { expect(helpers).to be_a(ActionView::Base) }
|
41
|
+
specify { expect(helpers.controller).to be(controller) }
|
42
|
+
specify { expect(helpers.request).to be(request) }
|
43
|
+
|
44
|
+
it "should mock an asset_path helper" do
|
45
|
+
expect(helpers.asset_path('test')).to eql('/assets/test')
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should include any ApplicationController helpers if an ApplicationController exists" do
|
49
|
+
if defined?(::ApplicationController)
|
50
|
+
prev_app_controller = ::ApplicationController
|
51
|
+
Object.send :remove_const, :ApplicationController
|
52
|
+
end
|
53
|
+
::ApplicationController = Class.new(ActionController::Base)
|
54
|
+
app_helpers = Module.new do
|
55
|
+
def my_method; 'result' end
|
56
|
+
end
|
57
|
+
expect(::ApplicationController).to receive(:_helpers).and_return(app_helpers)
|
58
|
+
|
59
|
+
expect(helpers.my_method).to eql('result')
|
60
|
+
Object.send :remove_const, :ApplicationController
|
61
|
+
::ApplicationController = prev_app_controller if prev_app_controller
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
describe '#controller' do
|
67
|
+
specify { expect(example.controller).to be_a(ActionController::Base) }
|
68
|
+
specify { expect(example.controller.request).to be(example.request) }
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#request' do
|
72
|
+
specify { expect(example.request).to be_a(ActionDispatch::Request) }
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Arbre::RSpec::BeRenderedAsMatcher do
|
4
|
+
|
5
|
+
it "should fail if the actual was nil" do
|
6
|
+
expect{ expect(nil).to be_rendered_as('<html/>') }
|
7
|
+
.to raise_error(RSpec::Expectations::ExpectationNotMetError, <<-STR.gsub(/^\s{8}/, ''))
|
8
|
+
expected that element of type NilClass would be rendered differently:
|
9
|
+
expected: <html/> (String)
|
10
|
+
got: nil
|
11
|
+
STR
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should fail if the actual's string version was not the same" do
|
15
|
+
expect{ expect(double(:to_s => '<html></html>'.html_safe)).to be_rendered_as('<html/>') }
|
16
|
+
.to raise_error(RSpec::Expectations::ExpectationNotMetError, <<-STR.gsub(/^\s{8}/, ''))
|
17
|
+
expected that element of type RSpec::Mocks::Mock would be rendered differently:
|
18
|
+
expected: <html/> (String)
|
19
|
+
got: <html></html>
|
20
|
+
STR
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should fail if the actual's string version did not match the regular expression" do
|
24
|
+
expect{ expect(double(:to_s => '<html></html>'.html_safe)).to be_rendered_as(/regular* expression{1,2}/) }
|
25
|
+
.to raise_error(RSpec::Expectations::ExpectationNotMetError, <<-STR.gsub(/^\s{8}/, ''))
|
26
|
+
expected that element of type RSpec::Mocks::Mock would be rendered differently:
|
27
|
+
expected: /regular* expression{1,2}/ (Regexp)
|
28
|
+
got: <html></html>
|
29
|
+
STR
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should fail if the actual's string was not HTML-safed" do
|
33
|
+
expect{ expect(double(:to_s => '<html></html>')).to be_rendered_as('<html></html>') }
|
34
|
+
.to raise_error(RSpec::Expectations::ExpectationNotMetError, <<-STR.gsub(/^\s{8}/, ''))
|
35
|
+
expected that element of type RSpec::Mocks::Mock would be rendered differently:
|
36
|
+
expected: <html></html> (String)
|
37
|
+
got: <html></html>
|
38
|
+
STR
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should pass if the actual's string version did match the given string" do
|
42
|
+
expect{ expect('<html></html>'.html_safe).to be_rendered_as('<html></html>') }
|
43
|
+
.not_to raise_error
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should pass if the actual's string version did match the given regular expression" do
|
47
|
+
expect{ expect('<html></html>'.html_safe).to be_rendered_as(/<html>.*?<\/html>/) }
|
48
|
+
.not_to raise_error
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should pass if the actual's string version did match the given string, where whitespace is ignored" do
|
52
|
+
expect{ expect('<html> </html>'.html_safe).to be_rendered_as('<html></html>') }
|
53
|
+
.not_to raise_error
|
54
|
+
expect{ expect("<html>\n</html>\n".html_safe).to be_rendered_as('<html> </html>') }
|
55
|
+
.not_to raise_error
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should pass if the actual's string version did match the given regular expression, where whitespace is ignored" do
|
59
|
+
expect{ expect('<html> </html>'.html_safe).to be_rendered_as(/<html>.*?<\/html>/) }
|
60
|
+
.not_to raise_error
|
61
|
+
expect{ expect("<html>\n</html>\n".html_safe).to be_rendered_as(/<html.*> <\/html>/) }
|
62
|
+
.not_to raise_error
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should pass if the actual's string version did match the given string, where attribute order is ignored" do
|
66
|
+
expect{ expect('<html lang="en" data-something="two"></html>'.html_safe).to be_rendered_as('<html data-something="two" lang="en"></html>') }
|
67
|
+
.not_to raise_error
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should pass if the actual's string version did match the given regex, where attribute order is ignored" do
|
71
|
+
expect{ expect('<html lang="en" data-something="two"></html>'.html_safe).to be_rendered_as(/<html data-something="two" lang="en">.*<\/html>/) }
|
72
|
+
.not_to raise_error
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should pass if the actual's string version matched the given string, where placeholders were used" do
|
76
|
+
expect{ expect('<html><body></body></html>'.html_safe).to be_rendered_as('<html>(...)</html>') }
|
77
|
+
.not_to raise_error
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Arbre::RSpec::BeScriptedAsMatcher do
|
4
|
+
|
5
|
+
it "should fail if the actual's content was not the same" do
|
6
|
+
expect{ expect(double(:content => 'alert("test");')).to be_scripted_as('alert("something else");') }
|
7
|
+
.to raise_error(RSpec::Expectations::ExpectationNotMetError, <<-STR.gsub(/^\s{8}/, ''))
|
8
|
+
expected that element of type RSpec::Mocks::Mock would be scripted differently:
|
9
|
+
expected: alert("something else"); (String)
|
10
|
+
got: alert("test");
|
11
|
+
STR
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should fail if the actual's content did not match the regular expression" do
|
15
|
+
expect{ expect(double(:content => 'alert("test");')).to be_scripted_as(/regular* expression{1,2}/) }
|
16
|
+
.to raise_error(RSpec::Expectations::ExpectationNotMetError, <<-STR.gsub(/^\s{8}/, ''))
|
17
|
+
expected that element of type RSpec::Mocks::Mock would be scripted differently:
|
18
|
+
expected: /regular* expression{1,2}/ (Regexp)
|
19
|
+
got: alert("test");
|
20
|
+
STR
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should pass if the actual's content did match the given string" do
|
24
|
+
expect{ expect(double(:content => 'alert("test");')).to be_scripted_as('alert("test");') }
|
25
|
+
.not_to raise_error
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should pass if the actual's content did match the given regular expression" do
|
29
|
+
expect{ expect(double(:content => 'alert("test");')).to be_scripted_as(/alert\("\w+"\);/) }
|
30
|
+
.not_to raise_error
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should pass if the actual's content did match the given string, where whitespace is ignored" do
|
34
|
+
expect{ expect(double(:content => ' alert("test"); ')).to be_scripted_as('alert("test");') }
|
35
|
+
.not_to raise_error
|
36
|
+
expect{ expect(double(:content => "alert(\"test\");\n")).to be_scripted_as(' alert("test"); ') }
|
37
|
+
.not_to raise_error
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should fail if the whitespace difference was significant" do
|
41
|
+
expect{ expect(double(:content => 'alert("test " );')).to be_scripted_as('alert("test");') }
|
42
|
+
.to raise_error(RSpec::Expectations::ExpectationNotMetError, <<-STR.gsub(/^\s{8}/, ''))
|
43
|
+
expected that element of type RSpec::Mocks::Mock would be scripted differently:
|
44
|
+
expected: alert("test"); (String)
|
45
|
+
got: alert("test " );
|
46
|
+
STR
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should pass if the actual's content did match the given regular expression, where whitespace is ignored" do
|
50
|
+
expect{ expect(double(:content => ' alert("test"); ')).to be_scripted_as(/alert\("\w+"\);/) }
|
51
|
+
.not_to raise_error
|
52
|
+
expect{ expect(double(:content => "alert(\"test\");\n")).to be_scripted_as(/ alert\("\w+"\); /) }
|
53
|
+
.not_to raise_error
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should pass if the actual's content matched the given string, where placeholders were used" do
|
57
|
+
expect{ expect(double(:content => 'var a=1; alert("test");')).to be_scripted_as('(...)alert("test");') }
|
58
|
+
.not_to raise_error
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Arbre::RSpec::ContainScriptMatcher do
|
4
|
+
|
5
|
+
it "should fail if the actual's content did not contain the given script" do
|
6
|
+
expect{ expect(double(:to_s => '<script type="javascript">alert("test");</script>')).to contain_script('alert("something else");') }
|
7
|
+
.to raise_error(RSpec::Expectations::ExpectationNotMetError, <<-STR.gsub(/^\s{8}/, ''))
|
8
|
+
expected that element of type RSpec::Mocks::Mock contained script:
|
9
|
+
expected: alert("something else"); (String)
|
10
|
+
got: <script type="javascript">alert("test");</script>
|
11
|
+
STR
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should pass if the actual's content did match the given string" do
|
15
|
+
expect{ expect(double(:to_s => '<script type="javascript">alert("test");</script>')).to contain_script('alert("test");') }
|
16
|
+
.not_to raise_error
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should pass if the actual's content contained given string" do
|
20
|
+
expect{ expect(double(:to_s => '<body><script type="javascript">var a = 1; alert("test");</script></body>')).to contain_script('alert("test");') }
|
21
|
+
.not_to raise_error
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should pass if the actual's content did match the given string, where whitespace is ignored" do
|
25
|
+
expect{ expect(double(:to_s => '<script type="javascript"> alert("test"); </script>')).to contain_script('alert("test");') }
|
26
|
+
.not_to raise_error
|
27
|
+
expect{ expect(double(:to_s => "<script type=\"javascript\">alert(\"test\");\n</script>")).to contain_script(' alert("test"); ') }
|
28
|
+
.not_to raise_error
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should fail if the whitespace difference was significant" do
|
32
|
+
expect{ expect(double(:to_s => '<script type="javascript">alert("test " );</script>')).to contain_script('alert("test");') }
|
33
|
+
.to raise_error(RSpec::Expectations::ExpectationNotMetError, <<-STR.gsub(/^\s{8}/, ''))
|
34
|
+
expected that element of type RSpec::Mocks::Mock contained script:
|
35
|
+
expected: alert("test"); (String)
|
36
|
+
got: <script type="javascript">alert("test " );</script>
|
37
|
+
STR
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
File without changes
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
include Arbre
|
3
|
+
|
4
|
+
describe ChildElementCollection do
|
5
|
+
|
6
|
+
specify { expect(ChildElementCollection).to be < ElementCollection }
|
7
|
+
|
8
|
+
let(:parent) { Element.new }
|
9
|
+
let(:collection) { ChildElementCollection.new(parent) }
|
10
|
+
|
11
|
+
let(:element) { Element.new }
|
12
|
+
let(:element1) { Element.new }
|
13
|
+
let(:element2) { Element.new }
|
14
|
+
let(:element3) { Element.new }
|
15
|
+
|
16
|
+
######
|
17
|
+
# Parent
|
18
|
+
|
19
|
+
it "should store its parent" do
|
20
|
+
expect(collection.parent).to be(parent)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should only be eql? to another collection if the parent is the same" do
|
24
|
+
collection1 = ChildElementCollection.new(parent)
|
25
|
+
collection1 << element1
|
26
|
+
|
27
|
+
collection2 = ChildElementCollection.new(parent)
|
28
|
+
collection2 << element1
|
29
|
+
expect(collection1).to eql(collection2)
|
30
|
+
|
31
|
+
collection2 = ChildElementCollection.new(Element.new)
|
32
|
+
collection2 << element1
|
33
|
+
expect(collection1).not_to eql(collection2)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should set the parent to each child element that is added to the collection" do
|
37
|
+
collection << element1
|
38
|
+
expect(element1.parent).to be(parent)
|
39
|
+
|
40
|
+
collection = ChildElementCollection.new(parent)
|
41
|
+
collection.insert_at 0, element2
|
42
|
+
expect(element2.parent).to be(parent)
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should remove any element that is added to the collection from its existing parent" do
|
46
|
+
expect(element1).to receive(:remove!)
|
47
|
+
expect(element2).to receive(:remove!)
|
48
|
+
|
49
|
+
collection << element1
|
50
|
+
collection.insert_at 0, element2
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should unset the parent from each child element that is removed from the collection" do
|
54
|
+
collection << element
|
55
|
+
collection.remove element
|
56
|
+
expect(element.parent).to be_nil
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should not add or set the parent of the same element twice" do
|
60
|
+
expect(element).to receive(:parent=).once.with(parent)
|
61
|
+
collection << element << element
|
62
|
+
expect(collection).to have(1).item
|
63
|
+
|
64
|
+
collection = ChildElementCollection.new(parent)
|
65
|
+
expect(element).to receive(:parent=).once.with(parent)
|
66
|
+
collection << element
|
67
|
+
collection.insert_at 0, element
|
68
|
+
expect(collection).to have(1).item
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should not unset the parent if the given element was not part of the collection" do
|
72
|
+
element.parent = Element.new
|
73
|
+
collection.remove element
|
74
|
+
expect(element.parent).not_to be_nil
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should not the parents of all elements if #clear is used" do
|
78
|
+
collection << element1 << element2
|
79
|
+
|
80
|
+
expect(element1.parent).not_to be_nil
|
81
|
+
expect(element2.parent).not_to be_nil
|
82
|
+
collection.clear
|
83
|
+
expect(element1.parent).to be_nil
|
84
|
+
expect(element2.parent).to be_nil
|
85
|
+
end
|
86
|
+
|
87
|
+
######
|
88
|
+
# Inserting
|
89
|
+
|
90
|
+
describe '#insert_at' do
|
91
|
+
it "should insert the element at the given index" do
|
92
|
+
collection << element1 << element3
|
93
|
+
collection.insert_at 1, element2
|
94
|
+
|
95
|
+
expect(collection).to eq([element1, element2, element3])
|
96
|
+
end
|
97
|
+
|
98
|
+
it "should move, and not duplicate, an element that already existed in the collection" do
|
99
|
+
collection << element1 << element3 << element2
|
100
|
+
collection.insert_at 1, element2
|
101
|
+
expect(collection).to eq([element1, element2, element3])
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should be able to move an element towards the back" do
|
105
|
+
collection << element2 << element1 << element3
|
106
|
+
collection.insert_at 2, element2
|
107
|
+
expect(collection).to eq([element1, element2, element3])
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
describe '#insert_after' do
|
113
|
+
it "should insert the element after the other element" do
|
114
|
+
collection << element1
|
115
|
+
collection.insert_after element1, element3
|
116
|
+
collection.insert_after element1, element2
|
117
|
+
|
118
|
+
expect(collection).to eq([element1, element2, element3])
|
119
|
+
end
|
120
|
+
|
121
|
+
it "should raise an error if the given reference element did not exist in the collection" do
|
122
|
+
collection << element1
|
123
|
+
expect(element2).to receive(:to_s).and_return('element2')
|
124
|
+
expect { collection.insert_after element2, element3 }.to \
|
125
|
+
raise_error(ArgumentError, 'existing element element2 not found')
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
describe '#insert_before' do
|
130
|
+
it "should insert the element after the other element" do
|
131
|
+
collection << element3
|
132
|
+
collection.insert_before element3, element1
|
133
|
+
collection.insert_before element3, element2
|
134
|
+
|
135
|
+
expect(collection).to eq([element1, element2, element3])
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should raise an error if the given reference element did not exist in the collection" do
|
139
|
+
collection << element1
|
140
|
+
expect(element2).to receive(:to_s).and_return('element2')
|
141
|
+
expect { collection.insert_before element2, element3 }.to \
|
142
|
+
raise_error(ArgumentError, 'existing element element2 not found')
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
include Arbre
|
3
|
+
|
4
|
+
describe Container do
|
5
|
+
|
6
|
+
it "should render its content" do
|
7
|
+
container = Container.new
|
8
|
+
expect(container).to receive(:content).and_return('(CONTENT)')
|
9
|
+
expect(container.to_s).to eql('(CONTENT)')
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should have an indentation level of 0 by default" do
|
13
|
+
expect(Container.new.indent_level).to eql(0)
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should have the same indentation level as its parent" do
|
17
|
+
container = Container.new
|
18
|
+
container.parent = Element.new
|
19
|
+
expect(container.parent).to receive(:indent_level).and_return(5)
|
20
|
+
expect(container.indent_level).to eql(5)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|