ronin-exploits 1.0.0.beta2 → 1.0.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 +4 -4
- data/.github/workflows/ruby.yml +1 -0
- data/README.md +29 -13
- data/gemspec.yml +10 -8
- data/lib/ronin/exploits/cli/commands/new.rb +1 -1
- data/lib/ronin/exploits/cli/commands/run.rb +55 -5
- data/lib/ronin/exploits/exploit.rb +7 -5
- data/lib/ronin/exploits/lfi.rb +1 -1
- data/lib/ronin/exploits/metadata/arch.rb +1 -1
- data/lib/ronin/exploits/metadata/default_filename.rb +1 -1
- data/lib/ronin/exploits/metadata/default_port.rb +1 -1
- data/lib/ronin/exploits/mixins/file_builder.rb +2 -2
- data/lib/ronin/exploits/mixins/nops.rb +1 -1
- data/lib/ronin/exploits/params/base_url.rb +1 -1
- data/lib/ronin/exploits/version.rb +1 -1
- data/ronin-exploits.gemspec +2 -1
- metadata +24 -129
- data/spec/advisory_spec.rb +0 -71
- data/spec/cli/exploit_command_spec.rb +0 -68
- data/spec/cli/exploit_methods_spec.rb +0 -208
- data/spec/cli/ruby_shell_spec.rb +0 -14
- data/spec/client_side_web_vuln_spec.rb +0 -117
- data/spec/exploit_spec.rb +0 -538
- data/spec/exploits_spec.rb +0 -8
- data/spec/heap_overflow_spec.rb +0 -14
- data/spec/lfi_spec.rb +0 -162
- data/spec/loot/file_spec.rb +0 -131
- data/spec/loot_spec.rb +0 -138
- data/spec/memory_corruption_spec.rb +0 -22
- data/spec/metadata/arch_spec.rb +0 -82
- data/spec/metadata/cookie_param_spec.rb +0 -67
- data/spec/metadata/default_filename_spec.rb +0 -62
- data/spec/metadata/default_port_spec.rb +0 -62
- data/spec/metadata/header_name_spec.rb +0 -67
- data/spec/metadata/os_spec.rb +0 -164
- data/spec/metadata/shouts_spec.rb +0 -100
- data/spec/metadata/url_path_spec.rb +0 -67
- data/spec/metadata/url_query_param_spec.rb +0 -67
- data/spec/mixins/binary_spec.rb +0 -129
- data/spec/mixins/build_dir.rb +0 -66
- data/spec/mixins/file_builder_spec.rb +0 -67
- data/spec/mixins/format_string_spec.rb +0 -44
- data/spec/mixins/has_payload_spec.rb +0 -333
- data/spec/mixins/has_targets_spec.rb +0 -434
- data/spec/mixins/html_spec.rb +0 -772
- data/spec/mixins/http_spec.rb +0 -1227
- data/spec/mixins/loot_spec.rb +0 -20
- data/spec/mixins/nops_spec.rb +0 -165
- data/spec/mixins/remote_tcp_spec.rb +0 -217
- data/spec/mixins/remote_udp_spec.rb +0 -217
- data/spec/mixins/seh_spec.rb +0 -89
- data/spec/mixins/stack_overflow_spec.rb +0 -87
- data/spec/mixins/text_spec.rb +0 -43
- data/spec/open_redirect_spec.rb +0 -71
- data/spec/params/base_url_spec.rb +0 -71
- data/spec/params/bind_host_spec.rb +0 -34
- data/spec/params/bind_port_spec.rb +0 -35
- data/spec/params/filename_spec.rb +0 -77
- data/spec/params/host_spec.rb +0 -34
- data/spec/params/port_spec.rb +0 -77
- data/spec/rfi_spec.rb +0 -107
- data/spec/seh_overflow_spec.rb +0 -18
- data/spec/spec_helper.rb +0 -8
- data/spec/sqli_spec.rb +0 -306
- data/spec/ssti_spec.rb +0 -121
- data/spec/stack_overflow_spec.rb +0 -18
- data/spec/target_spec.rb +0 -92
- data/spec/test_result_spec.rb +0 -32
- data/spec/use_after_free_spec.rb +0 -14
- data/spec/web_spec.rb +0 -12
- data/spec/web_vuln_spec.rb +0 -854
- data/spec/xss_spec.rb +0 -69
data/spec/mixins/html_spec.rb
DELETED
@@ -1,772 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'ronin/exploits/mixins/html'
|
3
|
-
|
4
|
-
require 'ronin/exploits/exploit'
|
5
|
-
|
6
|
-
describe Ronin::Exploits::Mixins::HTML do
|
7
|
-
module TestHTMLMixin
|
8
|
-
class TestExploit < Ronin::Exploits::Exploit
|
9
|
-
include Ronin::Exploits::Mixins::HTML
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
let(:test_exploit) { TestHTMLMixin::TestExploit }
|
14
|
-
subject { test_exploit.new }
|
15
|
-
|
16
|
-
describe "#attr_name" do
|
17
|
-
let(:name) { 'foo' }
|
18
|
-
|
19
|
-
it "must return the name as is" do
|
20
|
-
expect(subject.attr_name(name)).to eq(name)
|
21
|
-
end
|
22
|
-
|
23
|
-
context "when given a Symbol" do
|
24
|
-
let(:name) { :foo }
|
25
|
-
|
26
|
-
it "must return the String version of the Symbol" do
|
27
|
-
expect(subject.attr_name(name)).to eq(name.to_s)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
context "when given `name_case: :lower`" do
|
32
|
-
let(:name) { 'FOO' }
|
33
|
-
|
34
|
-
it "must convert the name to lower-case" do
|
35
|
-
expect(subject.attr_name(name, name_case: :lower)).to eq(name.downcase)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
context "when given `name_case: :upper`" do
|
40
|
-
it "must convert the name to upper-case" do
|
41
|
-
expect(subject.attr_name(name, name_case: :upper)).to eq(name.upcase)
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
context "when given `name_case: :random`" do
|
46
|
-
it "must randomize the case of the name" do
|
47
|
-
expect(subject.attr_name(name, name_case: :random)).to match(
|
48
|
-
/\A(?:Foo|fOo|foO|FOo|FoO|fOO|FOO)\z/
|
49
|
-
)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
describe "#attr" do
|
55
|
-
let(:name) { 'foo' }
|
56
|
-
let(:value) { 'bar' }
|
57
|
-
|
58
|
-
it "must return name=\"value\"" do
|
59
|
-
expect(subject.attr(name,value)).to eq("#{name}=\"#{value}\"")
|
60
|
-
end
|
61
|
-
|
62
|
-
context "when given a Symbol for the name" do
|
63
|
-
let(:name) { :foo }
|
64
|
-
|
65
|
-
it "must accept a Symbol for the name" do
|
66
|
-
expect(subject.attr(name,value)).to eq("#{name}=\"#{value}\"")
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
context "when given a non-String for the value" do
|
71
|
-
let(:value) { 42 }
|
72
|
-
|
73
|
-
it "must accept a non-String for the value" do
|
74
|
-
expect(subject.attr(name,value)).to eq("#{name}=\"#{value}\"")
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
context "when given `name_case: :lower`" do
|
79
|
-
let(:name) { 'FOO' }
|
80
|
-
|
81
|
-
it "must convert the name to lower-case" do
|
82
|
-
expect(subject.attr(name,value, name_case: :lower)).to eq(
|
83
|
-
"#{name.downcase}=\"#{value}\""
|
84
|
-
)
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
context "when given `name_case: :upper`" do
|
89
|
-
it "must convert the name to upper-case" do
|
90
|
-
expect(subject.attr(name,value, name_case: :upper)).to eq(
|
91
|
-
"#{name.upcase}=\"#{value}\""
|
92
|
-
)
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
context "when given `name_case: :random`" do
|
97
|
-
it "must randomize the case of the name" do
|
98
|
-
expect(subject.attr(name,value, name_case: :random)).to match(
|
99
|
-
/\A(?:Foo|fOo|foO|FOo|FoO|fOO|FOO)=\"#{value}\"\z/
|
100
|
-
)
|
101
|
-
end
|
102
|
-
end
|
103
|
-
|
104
|
-
context "when given `quote: double`" do
|
105
|
-
it "must quote the value with double quotes" do
|
106
|
-
expect(subject.attr(name,value, quote: :double)).to eq(
|
107
|
-
"#{name}=\"#{value}\""
|
108
|
-
)
|
109
|
-
end
|
110
|
-
|
111
|
-
context "and when the value contains a double quote" do
|
112
|
-
let(:value) { "bar\"baz" }
|
113
|
-
|
114
|
-
it "must replace any double quotes with "" do
|
115
|
-
expect(subject.attr(name,value)).to eq("#{name}=\"bar"baz\"")
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
context "when given `quote: single`" do
|
121
|
-
it "must quote the value with single quotes" do
|
122
|
-
expect(subject.attr(name,value, quote: :single)).to eq(
|
123
|
-
"#{name}='#{value}'"
|
124
|
-
)
|
125
|
-
end
|
126
|
-
|
127
|
-
context "and when the value contains a single quote" do
|
128
|
-
let(:value) { "bar'baz" }
|
129
|
-
|
130
|
-
it "must replace any double quotes with ';" do
|
131
|
-
expect(subject.attr(name,value, quote: :single)).to eq(
|
132
|
-
"#{name}='bar'baz'"
|
133
|
-
)
|
134
|
-
end
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
context "when given `quote: backtick`" do
|
139
|
-
it "must quote the value with backticks" do
|
140
|
-
expect(subject.attr(name,value, quote: :backtick)).to eq(
|
141
|
-
"#{name}=`#{value}`"
|
142
|
-
)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
context "when given `quote: nil`" do
|
147
|
-
it "must not quote the value" do
|
148
|
-
expect(subject.attr(name,value, quote: nil)).to eq(
|
149
|
-
"#{name}=#{value}"
|
150
|
-
)
|
151
|
-
end
|
152
|
-
|
153
|
-
context "and when the value contains a space" do
|
154
|
-
let(:value) { "bar baz" }
|
155
|
-
|
156
|
-
it "must replace any spaces with &#nbsp;;" do
|
157
|
-
expect(subject.attr(name,value, quote: nil)).to eq(
|
158
|
-
"#{name}=bar baz"
|
159
|
-
)
|
160
|
-
end
|
161
|
-
end
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
describe "#attr_list" do
|
166
|
-
let(:name1) { 'foo' }
|
167
|
-
let(:value1) { 'bar' }
|
168
|
-
let(:name2) { 'baz' }
|
169
|
-
let(:value2) { 'qux' }
|
170
|
-
let(:attrs) { {name1 => value1, name2 => value2} }
|
171
|
-
|
172
|
-
it "must return name=\"value\" ..." do
|
173
|
-
expect(subject.attr_list(attrs)).to eq(
|
174
|
-
"#{name1}=\"#{value1}\" #{name2}=\"#{value2}\""
|
175
|
-
)
|
176
|
-
end
|
177
|
-
|
178
|
-
context "when the attributes have Symbol names" do
|
179
|
-
let(:name1) { :foo }
|
180
|
-
let(:name2) { :baz }
|
181
|
-
|
182
|
-
it "must accept Symbols for attribute names" do
|
183
|
-
expect(subject.attr_list(attrs)).to eq(
|
184
|
-
"#{name1}=\"#{value1}\" #{name2}=\"#{value2}\""
|
185
|
-
)
|
186
|
-
end
|
187
|
-
end
|
188
|
-
|
189
|
-
context "when the attributes contains non-String values" do
|
190
|
-
let(:value1) { 42 }
|
191
|
-
let(:value2) { :qux }
|
192
|
-
|
193
|
-
it "must accept non-Strings for attribute values" do
|
194
|
-
expect(subject.attr_list(attrs)).to eq(
|
195
|
-
"#{name1}=\"#{value1}\" #{name2}=\"#{value2}\""
|
196
|
-
)
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
context "when given `name_case: :lower`" do
|
201
|
-
let(:name1) { 'FOO' }
|
202
|
-
let(:name2) { 'BAZ' }
|
203
|
-
|
204
|
-
it "must convert the attribute names to lower-case" do
|
205
|
-
expect(subject.attr_list(attrs, name_case: :lower)).to eq(
|
206
|
-
"#{name1.downcase}=\"#{value1}\" #{name2.downcase}=\"#{value2}\""
|
207
|
-
)
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
context "when given `name_case: :upper`" do
|
212
|
-
it "must convert the attribute names to upper-case" do
|
213
|
-
expect(subject.attr_list(attrs, name_case: :upper)).to eq(
|
214
|
-
"#{name1.upcase}=\"#{value1}\" #{name2.upcase}=\"#{value2}\""
|
215
|
-
)
|
216
|
-
end
|
217
|
-
end
|
218
|
-
|
219
|
-
context "when given `name_case: :random`" do
|
220
|
-
it "must randomize the case of each attribute name" do
|
221
|
-
expect(subject.attr_list(attrs, name_case: :random)).to match(
|
222
|
-
/\A(?:Foo|fOo|foO|FOo|FoO|fOO|FOO)=\"#{value1}\" (?:Baz|bAz|baZ|BAz|BaZ|bAZ|BAZ)=\"#{value2}\"\z/
|
223
|
-
)
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
context "when given `quote: double`" do
|
228
|
-
it "must quote the attribute values with double quotes" do
|
229
|
-
expect(subject.attr_list(attrs, quote: :double)).to eq(
|
230
|
-
"#{name1}=\"#{value1}\" #{name2}=\"#{value2}\""
|
231
|
-
)
|
232
|
-
end
|
233
|
-
|
234
|
-
context "and when an attribute value contains a double quote" do
|
235
|
-
let(:value1) { "bar\"baz" }
|
236
|
-
|
237
|
-
it "must replace any double quotes with "" do
|
238
|
-
expect(subject.attr_list(attrs)).to eq(
|
239
|
-
"#{name1}=\"bar"baz\" #{name2}=\"#{value2}\""
|
240
|
-
)
|
241
|
-
end
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
context "when given `quote: single`" do
|
246
|
-
it "must quote the attribute values with single quotes" do
|
247
|
-
expect(subject.attr_list(attrs, quote: :single)).to eq(
|
248
|
-
"#{name1}='#{value1}' #{name2}='#{value2}'"
|
249
|
-
)
|
250
|
-
end
|
251
|
-
|
252
|
-
context "and when an attribute value contains a single quote" do
|
253
|
-
let(:value1) { "bar'baz" }
|
254
|
-
|
255
|
-
it "must replace any double quotes with ';" do
|
256
|
-
expect(subject.attr_list(attrs, quote: :single)).to eq(
|
257
|
-
"#{name1}='bar'baz' #{name2}='#{value2}'"
|
258
|
-
)
|
259
|
-
end
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
|
-
context "when given `quote: backtick`" do
|
264
|
-
it "must quote the attribute values with backticks" do
|
265
|
-
expect(subject.attr_list(attrs, quote: :backtick)).to eq(
|
266
|
-
"#{name1}=`#{value1}` #{name2}=`#{value2}`"
|
267
|
-
)
|
268
|
-
end
|
269
|
-
end
|
270
|
-
|
271
|
-
context "when given `quote: nil`" do
|
272
|
-
it "must not quote the attribute values" do
|
273
|
-
expect(subject.attr_list(attrs, quote: nil)).to eq(
|
274
|
-
"#{name1}=#{value1} #{name2}=#{value2}"
|
275
|
-
)
|
276
|
-
end
|
277
|
-
|
278
|
-
context "and when the value contains a space" do
|
279
|
-
let(:value1) { "bar baz" }
|
280
|
-
|
281
|
-
it "must replace any spaces with &#nbsp;;" do
|
282
|
-
expect(subject.attr_list(attrs, quote: nil)).to eq(
|
283
|
-
"#{name1}=bar baz #{name2}=#{value2}"
|
284
|
-
)
|
285
|
-
end
|
286
|
-
end
|
287
|
-
end
|
288
|
-
end
|
289
|
-
|
290
|
-
describe "#tag_name" do
|
291
|
-
let(:name) { 'foo' }
|
292
|
-
|
293
|
-
it "must return the name as is" do
|
294
|
-
expect(subject.tag_name(name)).to eq(name)
|
295
|
-
end
|
296
|
-
|
297
|
-
context "when given a Symbol" do
|
298
|
-
let(:name) { :foo }
|
299
|
-
|
300
|
-
it "must return the String version of the Symbol" do
|
301
|
-
expect(subject.tag_name(name)).to eq(name.to_s)
|
302
|
-
end
|
303
|
-
end
|
304
|
-
|
305
|
-
context "when given `name_case: :lower`" do
|
306
|
-
let(:name) { 'FOO' }
|
307
|
-
|
308
|
-
it "must convert the name to lower-case" do
|
309
|
-
expect(subject.tag_name(name, name_case: :lower)).to eq(name.downcase)
|
310
|
-
end
|
311
|
-
end
|
312
|
-
|
313
|
-
context "when given `name_case: :upper`" do
|
314
|
-
it "must convert the name to upper-case" do
|
315
|
-
expect(subject.tag_name(name, name_case: :upper)).to eq(name.upcase)
|
316
|
-
end
|
317
|
-
end
|
318
|
-
|
319
|
-
context "when given `name_case: :random`" do
|
320
|
-
it "must randomize the case of the name" do
|
321
|
-
expect(subject.tag_name(name, name_case: :random)).to match(
|
322
|
-
/\A(?:Foo|fOo|foO|FOo|FoO|fOO|FOO)\z/
|
323
|
-
)
|
324
|
-
end
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
|
-
describe "#tag" do
|
329
|
-
let(:name) { 'div' }
|
330
|
-
|
331
|
-
context "when no block or the `text:` keyword argument is given" do
|
332
|
-
it "must return <name/>" do
|
333
|
-
expect(subject.tag(name)).to eq("<#{name}/>")
|
334
|
-
end
|
335
|
-
|
336
|
-
context "when given a Symbol" do
|
337
|
-
let(:name) { :div }
|
338
|
-
|
339
|
-
it "must return the String version of the Symbol" do
|
340
|
-
expect(subject.tag(name)).to eq("<#{name}/>")
|
341
|
-
end
|
342
|
-
end
|
343
|
-
|
344
|
-
context "when given `tag_case: :lower`" do
|
345
|
-
let(:name) { 'DIV' }
|
346
|
-
|
347
|
-
it "must convert the name to lower-case" do
|
348
|
-
expect(subject.tag(name, tag_case: :lower)).to eq("<#{name.downcase}/>")
|
349
|
-
end
|
350
|
-
end
|
351
|
-
|
352
|
-
context "when given `tag_case: :upper`" do
|
353
|
-
it "must convert the name to upper-case" do
|
354
|
-
expect(subject.tag(name, tag_case: :upper)).to eq("<#{name.upcase}/>")
|
355
|
-
end
|
356
|
-
end
|
357
|
-
|
358
|
-
context "when given `tag_case: :random`" do
|
359
|
-
it "must randomize the case of the name" do
|
360
|
-
expect(subject.tag(name, tag_case: :random)).to match(
|
361
|
-
/\A<(?:Div|dIv|diV|DIv|DiV|dIV|DIV)\/>\z/
|
362
|
-
)
|
363
|
-
end
|
364
|
-
end
|
365
|
-
|
366
|
-
context "when additional attributes are given" do
|
367
|
-
let(:attr1) { :foo }
|
368
|
-
let(:value1) { 'bar' }
|
369
|
-
let(:attr2) { :baz }
|
370
|
-
let(:value2) { 'qux' }
|
371
|
-
let(:attrs) do
|
372
|
-
{attr1 => value1, attr2 => value2}
|
373
|
-
end
|
374
|
-
|
375
|
-
it "must add an attributes list after the tag name" do
|
376
|
-
expect(subject.tag(name,**attrs)).to eq("<#{name} #{attr1}=\"#{value1}\" #{attr2}=\"#{value2}\"/>")
|
377
|
-
end
|
378
|
-
|
379
|
-
context "when given `attr_case: :lower`" do
|
380
|
-
let(:attr1) { :FOO }
|
381
|
-
let(:attr2) { :BAZ }
|
382
|
-
|
383
|
-
it "must convert the attribute names to lower-case" do
|
384
|
-
expect(subject.tag(name, **attrs, attr_case: :lower)).to eq(
|
385
|
-
"<#{name} #{attr1.downcase}=\"#{value1}\" #{attr2.downcase}=\"#{value2}\"/>"
|
386
|
-
)
|
387
|
-
end
|
388
|
-
end
|
389
|
-
|
390
|
-
context "when given `attr_case: :upper`" do
|
391
|
-
it "must convert the attribute names to upper-case" do
|
392
|
-
expect(subject.tag(name, **attrs, attr_case: :upper)).to eq(
|
393
|
-
"<#{name} #{attr1.upcase}=\"#{value1}\" #{attr2.upcase}=\"#{value2}\"/>"
|
394
|
-
)
|
395
|
-
end
|
396
|
-
end
|
397
|
-
|
398
|
-
context "when given `attr_case: :random`" do
|
399
|
-
it "must randomize the case of each attribute name" do
|
400
|
-
expect(subject.tag(name, **attrs, attr_case: :random)).to match(
|
401
|
-
/\A<#{name} (?:Foo|fOo|foO|FOo|FoO|fOO|FOO)=\"#{value1}\" (?:Baz|bAz|baZ|BAz|BaZ|bAZ|BAZ)=\"#{value2}\"\/>\z/
|
402
|
-
)
|
403
|
-
end
|
404
|
-
end
|
405
|
-
|
406
|
-
context "when given `attr_quote: double`" do
|
407
|
-
it "must quote the attribute values with double quotes" do
|
408
|
-
expect(subject.tag(name, **attrs, attr_quote: :double)).to eq(
|
409
|
-
"<#{name} #{attr1}=\"#{value1}\" #{attr2}=\"#{value2}\"/>"
|
410
|
-
)
|
411
|
-
end
|
412
|
-
|
413
|
-
context "and when an attribute value contains a double quote" do
|
414
|
-
let(:value1) { "bar\"baz" }
|
415
|
-
|
416
|
-
it "must replace any double quotes with "" do
|
417
|
-
expect(subject.tag(name, **attrs)).to eq(
|
418
|
-
"<#{name} #{attr1}=\"bar"baz\" #{attr2}=\"#{value2}\"/>"
|
419
|
-
)
|
420
|
-
end
|
421
|
-
end
|
422
|
-
end
|
423
|
-
|
424
|
-
context "when given `attr_quote: single`" do
|
425
|
-
it "must quote the attribute values with single quotes" do
|
426
|
-
expect(subject.tag(name, **attrs, attr_quote: :single)).to eq(
|
427
|
-
"<#{name} #{attr1}='#{value1}' #{attr2}='#{value2}'/>"
|
428
|
-
)
|
429
|
-
end
|
430
|
-
|
431
|
-
context "and when an attribute value contains a single quote" do
|
432
|
-
let(:value1) { "bar'baz" }
|
433
|
-
|
434
|
-
it "must replace any double quotes with ';" do
|
435
|
-
expect(subject.tag(name, **attrs, attr_quote: :single)).to eq(
|
436
|
-
"<#{name} #{attr1}='bar'baz' #{attr2}='#{value2}'/>"
|
437
|
-
)
|
438
|
-
end
|
439
|
-
end
|
440
|
-
end
|
441
|
-
|
442
|
-
context "when given `attr_quote: :backtick`" do
|
443
|
-
it "must quote the attribute values with backticks" do
|
444
|
-
expect(subject.tag(name, **attrs, attr_quote: :backtick)).to eq(
|
445
|
-
"<#{name} #{attr1}=`#{value1}` #{attr2}=`#{value2}`/>"
|
446
|
-
)
|
447
|
-
end
|
448
|
-
end
|
449
|
-
|
450
|
-
context "when given `attr_quote: nil`" do
|
451
|
-
it "must not quote the attribute values" do
|
452
|
-
expect(subject.tag(name, **attrs, attr_quote: nil)).to eq(
|
453
|
-
"<#{name} #{attr1}=#{value1} #{attr2}=#{value2}/>"
|
454
|
-
)
|
455
|
-
end
|
456
|
-
|
457
|
-
context "and when the value contains a space" do
|
458
|
-
let(:value1) { "bar baz" }
|
459
|
-
|
460
|
-
it "must replace any spaces with &#nbsp;;" do
|
461
|
-
expect(subject.tag(name, **attrs, attr_quote: nil)).to eq(
|
462
|
-
"<#{name} #{attr1}=bar baz #{attr2}=#{value2}/>"
|
463
|
-
)
|
464
|
-
end
|
465
|
-
end
|
466
|
-
end
|
467
|
-
end
|
468
|
-
end
|
469
|
-
|
470
|
-
context "when given the `text:` keyword argument" do
|
471
|
-
let(:inner_text) { 'loren ipsum' }
|
472
|
-
|
473
|
-
it "must return <name>...</name>" do
|
474
|
-
expect(subject.tag(name, text: inner_text)).to eq(
|
475
|
-
"<#{name}>#{inner_text}</#{name}>"
|
476
|
-
)
|
477
|
-
end
|
478
|
-
|
479
|
-
context "when given a Symbol" do
|
480
|
-
let(:name) { :div }
|
481
|
-
|
482
|
-
it "must return the String version of the Symbol" do
|
483
|
-
expect(subject.tag(name, text: inner_text)).to eq(
|
484
|
-
"<#{name}>#{inner_text}</#{name}>"
|
485
|
-
)
|
486
|
-
end
|
487
|
-
end
|
488
|
-
|
489
|
-
context "when given `tag_case: :lower`" do
|
490
|
-
let(:name) { 'DIV' }
|
491
|
-
|
492
|
-
it "must convert the tag names to lower-case" do
|
493
|
-
expect(subject.tag(name, tag_case: :lower, text: inner_text)).to eq(
|
494
|
-
"<#{name.downcase}>#{inner_text}</#{name.downcase}>"
|
495
|
-
)
|
496
|
-
end
|
497
|
-
end
|
498
|
-
|
499
|
-
context "when given `tag_case: :upper`" do
|
500
|
-
it "must convert the tag names to upper-case" do
|
501
|
-
expect(subject.tag(name, tag_case: :upper, text: inner_text)).to eq(
|
502
|
-
"<#{name.upcase}>#{inner_text}</#{name.upcase}>"
|
503
|
-
)
|
504
|
-
end
|
505
|
-
end
|
506
|
-
|
507
|
-
context "when given `tag_case: :random`" do
|
508
|
-
it "must randomize the case of the tag names" do
|
509
|
-
expect(subject.tag(name, tag_case: :random, text: inner_text)).to match(
|
510
|
-
/\A<(?:Div|dIv|diV|DIv|DiV|dIV|DIV)>#{inner_text}<\/(?:Div|dIv|diV|DIv|DiV|dIV|DIV)>\z/
|
511
|
-
)
|
512
|
-
end
|
513
|
-
end
|
514
|
-
|
515
|
-
context "when additional attributes are given" do
|
516
|
-
let(:attr1) { :foo }
|
517
|
-
let(:value1) { 'bar' }
|
518
|
-
let(:attr2) { :baz }
|
519
|
-
let(:value2) { 'qux' }
|
520
|
-
let(:attrs) do
|
521
|
-
{attr1 => value1, attr2 => value2}
|
522
|
-
end
|
523
|
-
|
524
|
-
it "must add an attributes list after the tag name" do
|
525
|
-
expect(subject.tag(name,**attrs, text: inner_text)).to eq(
|
526
|
-
"<#{name} #{attr1}=\"#{value1}\" #{attr2}=\"#{value2}\">#{inner_text}</#{name}>"
|
527
|
-
)
|
528
|
-
end
|
529
|
-
|
530
|
-
context "when given `attr_case: :lower`" do
|
531
|
-
let(:attr1) { :FOO }
|
532
|
-
let(:attr2) { :BAZ }
|
533
|
-
|
534
|
-
it "must convert the attribute names to lower-case" do
|
535
|
-
expect(subject.tag(name, **attrs, attr_case: :lower, text: inner_text)).to eq(
|
536
|
-
"<#{name} #{attr1.downcase}=\"#{value1}\" #{attr2.downcase}=\"#{value2}\">#{inner_text}</#{name}>"
|
537
|
-
)
|
538
|
-
end
|
539
|
-
end
|
540
|
-
|
541
|
-
context "when given `attr_case: :upper`" do
|
542
|
-
it "must convert the attribute names to upper-case" do
|
543
|
-
expect(subject.tag(name, **attrs, attr_case: :upper, text: inner_text)).to eq(
|
544
|
-
"<#{name} #{attr1.upcase}=\"#{value1}\" #{attr2.upcase}=\"#{value2}\">#{inner_text}</#{name}>"
|
545
|
-
)
|
546
|
-
end
|
547
|
-
end
|
548
|
-
|
549
|
-
context "when given `attr_case: :random`" do
|
550
|
-
it "must randomize the case of each attribute name" do
|
551
|
-
expect(subject.tag(name, **attrs, attr_case: :random, text: inner_text)).to match(
|
552
|
-
/\A<#{name} (?:Foo|fOo|foO|FOo|FoO|fOO|FOO)=\"#{value1}\" (?:Baz|bAz|baZ|BAz|BaZ|bAZ|BAZ)=\"#{value2}\">#{inner_text}<\/#{name}>\z/
|
553
|
-
)
|
554
|
-
end
|
555
|
-
end
|
556
|
-
|
557
|
-
context "when given `attr_quote: double`" do
|
558
|
-
it "must quote the attribute values with double quotes" do
|
559
|
-
expect(subject.tag(name, **attrs, attr_quote: :double, text: inner_text)).to eq(
|
560
|
-
"<#{name} #{attr1}=\"#{value1}\" #{attr2}=\"#{value2}\">#{inner_text}</#{name}>"
|
561
|
-
)
|
562
|
-
end
|
563
|
-
|
564
|
-
context "and when an attribute value contains a double quote" do
|
565
|
-
let(:value1) { "bar\"baz" }
|
566
|
-
|
567
|
-
it "must replace any double quotes with "" do
|
568
|
-
expect(subject.tag(name, **attrs, text: inner_text)).to eq(
|
569
|
-
"<#{name} #{attr1}=\"bar"baz\" #{attr2}=\"#{value2}\">#{inner_text}</#{name}>"
|
570
|
-
)
|
571
|
-
end
|
572
|
-
end
|
573
|
-
end
|
574
|
-
|
575
|
-
context "when given `attr_quote: single`" do
|
576
|
-
it "must quote the attribute values with single quotes" do
|
577
|
-
expect(subject.tag(name, **attrs, attr_quote: :single, text: inner_text)).to eq(
|
578
|
-
"<#{name} #{attr1}='#{value1}' #{attr2}='#{value2}'>#{inner_text}</#{name}>"
|
579
|
-
)
|
580
|
-
end
|
581
|
-
|
582
|
-
context "and when an attribute value contains a single quote" do
|
583
|
-
let(:value1) { "bar'baz" }
|
584
|
-
|
585
|
-
it "must replace any double quotes with ';" do
|
586
|
-
expect(subject.tag(name, **attrs, attr_quote: :single, text: inner_text)).to eq(
|
587
|
-
"<#{name} #{attr1}='bar'baz' #{attr2}='#{value2}'>#{inner_text}</#{name}>"
|
588
|
-
)
|
589
|
-
end
|
590
|
-
end
|
591
|
-
end
|
592
|
-
|
593
|
-
context "when given `attr_quote: :backtick`" do
|
594
|
-
it "must quote the attribute values with backticks" do
|
595
|
-
expect(subject.tag(name, **attrs, attr_quote: :backtick, text: inner_text)).to eq(
|
596
|
-
"<#{name} #{attr1}=`#{value1}` #{attr2}=`#{value2}`>#{inner_text}</#{name}>"
|
597
|
-
)
|
598
|
-
end
|
599
|
-
end
|
600
|
-
|
601
|
-
context "when given `attr_quote: nil`" do
|
602
|
-
it "must not quote the attribute values" do
|
603
|
-
expect(subject.tag(name, **attrs, attr_quote: nil, text: inner_text)).to eq(
|
604
|
-
"<#{name} #{attr1}=#{value1} #{attr2}=#{value2}>#{inner_text}</#{name}>"
|
605
|
-
)
|
606
|
-
end
|
607
|
-
|
608
|
-
context "and when the value contains a space" do
|
609
|
-
let(:value1) { "bar baz" }
|
610
|
-
|
611
|
-
it "must replace any spaces with &#nbsp;;" do
|
612
|
-
expect(subject.tag(name, **attrs, attr_quote: nil, text: inner_text)).to eq(
|
613
|
-
"<#{name} #{attr1}=bar baz #{attr2}=#{value2}>#{inner_text}</#{name}>"
|
614
|
-
)
|
615
|
-
end
|
616
|
-
end
|
617
|
-
end
|
618
|
-
end
|
619
|
-
end
|
620
|
-
|
621
|
-
context "when given a block" do
|
622
|
-
let(:inner_html) { '<a href="http://example.com/>link</a>' }
|
623
|
-
|
624
|
-
it "must return <name>...</name>" do
|
625
|
-
expect(subject.tag(name) { inner_html }).to eq(
|
626
|
-
"<#{name}>#{inner_html}</#{name}>"
|
627
|
-
)
|
628
|
-
end
|
629
|
-
|
630
|
-
context "when given a Symbol" do
|
631
|
-
let(:name) { :div }
|
632
|
-
|
633
|
-
it "must return the String version of the Symbol" do
|
634
|
-
expect(subject.tag(name) { inner_html }).to eq(
|
635
|
-
"<#{name}>#{inner_html}</#{name}>"
|
636
|
-
)
|
637
|
-
end
|
638
|
-
end
|
639
|
-
|
640
|
-
context "when given `tag_case: :lower`" do
|
641
|
-
let(:name) { 'DIV' }
|
642
|
-
|
643
|
-
it "must convert the tag names to lower-case" do
|
644
|
-
expect(subject.tag(name, tag_case: :lower) { inner_html }).to eq(
|
645
|
-
"<#{name.downcase}>#{inner_html}</#{name.downcase}>"
|
646
|
-
)
|
647
|
-
end
|
648
|
-
end
|
649
|
-
|
650
|
-
context "when given `tag_case: :upper`" do
|
651
|
-
it "must convert the tag names to upper-case" do
|
652
|
-
expect(subject.tag(name, tag_case: :upper) { inner_html }).to eq(
|
653
|
-
"<#{name.upcase}>#{inner_html}</#{name.upcase}>"
|
654
|
-
)
|
655
|
-
end
|
656
|
-
end
|
657
|
-
|
658
|
-
context "when given `tag_case: :random`" do
|
659
|
-
it "must randomize the case of the tag names" do
|
660
|
-
expect(subject.tag(name, tag_case: :random) { inner_html }).to match(
|
661
|
-
/\A<(?:Div|dIv|diV|DIv|DiV|dIV|DIV)>#{inner_html}<\/(?:Div|dIv|diV|DIv|DiV|dIV|DIV)>\z/
|
662
|
-
)
|
663
|
-
end
|
664
|
-
end
|
665
|
-
|
666
|
-
context "when additional attributes are given" do
|
667
|
-
let(:attr1) { :foo }
|
668
|
-
let(:value1) { 'bar' }
|
669
|
-
let(:attr2) { :baz }
|
670
|
-
let(:value2) { 'qux' }
|
671
|
-
let(:attrs) do
|
672
|
-
{attr1 => value1, attr2 => value2}
|
673
|
-
end
|
674
|
-
|
675
|
-
it "must add an attributes list after the tag name" do
|
676
|
-
expect(subject.tag(name,**attrs) { inner_html }).to eq(
|
677
|
-
"<#{name} #{attr1}=\"#{value1}\" #{attr2}=\"#{value2}\">#{inner_html}</#{name}>"
|
678
|
-
)
|
679
|
-
end
|
680
|
-
|
681
|
-
context "when given `attr_case: :lower`" do
|
682
|
-
let(:attr1) { :FOO }
|
683
|
-
let(:attr2) { :BAZ }
|
684
|
-
|
685
|
-
it "must convert the attribute names to lower-case" do
|
686
|
-
expect(subject.tag(name, **attrs, attr_case: :lower) { inner_html }).to eq(
|
687
|
-
"<#{name} #{attr1.downcase}=\"#{value1}\" #{attr2.downcase}=\"#{value2}\">#{inner_html}</#{name}>"
|
688
|
-
)
|
689
|
-
end
|
690
|
-
end
|
691
|
-
|
692
|
-
context "when given `attr_case: :upper`" do
|
693
|
-
it "must convert the attribute names to upper-case" do
|
694
|
-
expect(subject.tag(name, **attrs, attr_case: :upper) { inner_html }).to eq(
|
695
|
-
"<#{name} #{attr1.upcase}=\"#{value1}\" #{attr2.upcase}=\"#{value2}\">#{inner_html}</#{name}>"
|
696
|
-
)
|
697
|
-
end
|
698
|
-
end
|
699
|
-
|
700
|
-
context "when given `attr_case: :random`" do
|
701
|
-
it "must randomize the case of each attribute name" do
|
702
|
-
expect(subject.tag(name, **attrs, attr_case: :random) { inner_html }).to match(
|
703
|
-
/\A<#{name} (?:Foo|fOo|foO|FOo|FoO|fOO|FOO)=\"#{value1}\" (?:Baz|bAz|baZ|BAz|BaZ|bAZ|BAZ)=\"#{value2}\">#{inner_html}<\/#{name}>\z/
|
704
|
-
)
|
705
|
-
end
|
706
|
-
end
|
707
|
-
|
708
|
-
context "when given `attr_quote: double`" do
|
709
|
-
it "must quote the attribute values with double quotes" do
|
710
|
-
expect(subject.tag(name, **attrs, attr_quote: :double) { inner_html }).to eq(
|
711
|
-
"<#{name} #{attr1}=\"#{value1}\" #{attr2}=\"#{value2}\">#{inner_html}</#{name}>"
|
712
|
-
)
|
713
|
-
end
|
714
|
-
|
715
|
-
context "and when an attribute value contains a double quote" do
|
716
|
-
let(:value1) { "bar\"baz" }
|
717
|
-
|
718
|
-
it "must replace any double quotes with "" do
|
719
|
-
expect(subject.tag(name, **attrs) { inner_html }).to eq(
|
720
|
-
"<#{name} #{attr1}=\"bar"baz\" #{attr2}=\"#{value2}\">#{inner_html}</#{name}>"
|
721
|
-
)
|
722
|
-
end
|
723
|
-
end
|
724
|
-
end
|
725
|
-
|
726
|
-
context "when given `attr_quote: single`" do
|
727
|
-
it "must quote the attribute values with single quotes" do
|
728
|
-
expect(subject.tag(name, **attrs, attr_quote: :single) { inner_html }).to eq(
|
729
|
-
"<#{name} #{attr1}='#{value1}' #{attr2}='#{value2}'>#{inner_html}</#{name}>"
|
730
|
-
)
|
731
|
-
end
|
732
|
-
|
733
|
-
context "and when an attribute value contains a single quote" do
|
734
|
-
let(:value1) { "bar'baz" }
|
735
|
-
|
736
|
-
it "must replace any double quotes with ';" do
|
737
|
-
expect(subject.tag(name, **attrs, attr_quote: :single) { inner_html }).to eq(
|
738
|
-
"<#{name} #{attr1}='bar'baz' #{attr2}='#{value2}'>#{inner_html}</#{name}>"
|
739
|
-
)
|
740
|
-
end
|
741
|
-
end
|
742
|
-
end
|
743
|
-
|
744
|
-
context "when given `attr_quote: :backtick`" do
|
745
|
-
it "must quote the attribute values with backticks" do
|
746
|
-
expect(subject.tag(name, **attrs, attr_quote: :backtick) { inner_html }).to eq(
|
747
|
-
"<#{name} #{attr1}=`#{value1}` #{attr2}=`#{value2}`>#{inner_html}</#{name}>"
|
748
|
-
)
|
749
|
-
end
|
750
|
-
end
|
751
|
-
|
752
|
-
context "when given `attr_quote: nil`" do
|
753
|
-
it "must not quote the attribute values" do
|
754
|
-
expect(subject.tag(name, **attrs, attr_quote: nil) { inner_html }).to eq(
|
755
|
-
"<#{name} #{attr1}=#{value1} #{attr2}=#{value2}>#{inner_html}</#{name}>"
|
756
|
-
)
|
757
|
-
end
|
758
|
-
|
759
|
-
context "and when the value contains a space" do
|
760
|
-
let(:value1) { "bar baz" }
|
761
|
-
|
762
|
-
it "must replace any spaces with &#nbsp;;" do
|
763
|
-
expect(subject.tag(name, **attrs, attr_quote: nil) { inner_html }).to eq(
|
764
|
-
"<#{name} #{attr1}=bar baz #{attr2}=#{value2}>#{inner_html}</#{name}>"
|
765
|
-
)
|
766
|
-
end
|
767
|
-
end
|
768
|
-
end
|
769
|
-
end
|
770
|
-
end
|
771
|
-
end
|
772
|
-
end
|