ronin-exploits 1.0.0.beta2 → 1.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -0
  3. data/README.md +4 -0
  4. data/gemspec.yml +3 -1
  5. data/lib/ronin/exploits/cli/commands/run.rb +55 -5
  6. data/lib/ronin/exploits/version.rb +1 -1
  7. data/ronin-exploits.gemspec +2 -1
  8. metadata +10 -115
  9. data/spec/advisory_spec.rb +0 -71
  10. data/spec/cli/exploit_command_spec.rb +0 -68
  11. data/spec/cli/exploit_methods_spec.rb +0 -208
  12. data/spec/cli/ruby_shell_spec.rb +0 -14
  13. data/spec/client_side_web_vuln_spec.rb +0 -117
  14. data/spec/exploit_spec.rb +0 -538
  15. data/spec/exploits_spec.rb +0 -8
  16. data/spec/heap_overflow_spec.rb +0 -14
  17. data/spec/lfi_spec.rb +0 -162
  18. data/spec/loot/file_spec.rb +0 -131
  19. data/spec/loot_spec.rb +0 -138
  20. data/spec/memory_corruption_spec.rb +0 -22
  21. data/spec/metadata/arch_spec.rb +0 -82
  22. data/spec/metadata/cookie_param_spec.rb +0 -67
  23. data/spec/metadata/default_filename_spec.rb +0 -62
  24. data/spec/metadata/default_port_spec.rb +0 -62
  25. data/spec/metadata/header_name_spec.rb +0 -67
  26. data/spec/metadata/os_spec.rb +0 -164
  27. data/spec/metadata/shouts_spec.rb +0 -100
  28. data/spec/metadata/url_path_spec.rb +0 -67
  29. data/spec/metadata/url_query_param_spec.rb +0 -67
  30. data/spec/mixins/binary_spec.rb +0 -129
  31. data/spec/mixins/build_dir.rb +0 -66
  32. data/spec/mixins/file_builder_spec.rb +0 -67
  33. data/spec/mixins/format_string_spec.rb +0 -44
  34. data/spec/mixins/has_payload_spec.rb +0 -333
  35. data/spec/mixins/has_targets_spec.rb +0 -434
  36. data/spec/mixins/html_spec.rb +0 -772
  37. data/spec/mixins/http_spec.rb +0 -1227
  38. data/spec/mixins/loot_spec.rb +0 -20
  39. data/spec/mixins/nops_spec.rb +0 -165
  40. data/spec/mixins/remote_tcp_spec.rb +0 -217
  41. data/spec/mixins/remote_udp_spec.rb +0 -217
  42. data/spec/mixins/seh_spec.rb +0 -89
  43. data/spec/mixins/stack_overflow_spec.rb +0 -87
  44. data/spec/mixins/text_spec.rb +0 -43
  45. data/spec/open_redirect_spec.rb +0 -71
  46. data/spec/params/base_url_spec.rb +0 -71
  47. data/spec/params/bind_host_spec.rb +0 -34
  48. data/spec/params/bind_port_spec.rb +0 -35
  49. data/spec/params/filename_spec.rb +0 -77
  50. data/spec/params/host_spec.rb +0 -34
  51. data/spec/params/port_spec.rb +0 -77
  52. data/spec/rfi_spec.rb +0 -107
  53. data/spec/seh_overflow_spec.rb +0 -18
  54. data/spec/spec_helper.rb +0 -8
  55. data/spec/sqli_spec.rb +0 -306
  56. data/spec/ssti_spec.rb +0 -121
  57. data/spec/stack_overflow_spec.rb +0 -18
  58. data/spec/target_spec.rb +0 -92
  59. data/spec/test_result_spec.rb +0 -32
  60. data/spec/use_after_free_spec.rb +0 -14
  61. data/spec/web_spec.rb +0 -12
  62. data/spec/web_vuln_spec.rb +0 -854
  63. data/spec/xss_spec.rb +0 -69
@@ -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 &quot;" do
115
- expect(subject.attr(name,value)).to eq("#{name}=\"bar&quot;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 &#39;;" do
131
- expect(subject.attr(name,value, quote: :single)).to eq(
132
- "#{name}='bar&#39;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&nbsp;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 &quot;" do
238
- expect(subject.attr_list(attrs)).to eq(
239
- "#{name1}=\"bar&quot;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 &#39;;" do
256
- expect(subject.attr_list(attrs, quote: :single)).to eq(
257
- "#{name1}='bar&#39;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&nbsp;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 &quot;" do
417
- expect(subject.tag(name, **attrs)).to eq(
418
- "<#{name} #{attr1}=\"bar&quot;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 &#39;;" do
435
- expect(subject.tag(name, **attrs, attr_quote: :single)).to eq(
436
- "<#{name} #{attr1}='bar&#39;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&nbsp;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 &quot;" do
568
- expect(subject.tag(name, **attrs, text: inner_text)).to eq(
569
- "<#{name} #{attr1}=\"bar&quot;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 &#39;;" do
586
- expect(subject.tag(name, **attrs, attr_quote: :single, text: inner_text)).to eq(
587
- "<#{name} #{attr1}='bar&#39;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&nbsp;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 &quot;" do
719
- expect(subject.tag(name, **attrs) { inner_html }).to eq(
720
- "<#{name} #{attr1}=\"bar&quot;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 &#39;;" do
737
- expect(subject.tag(name, **attrs, attr_quote: :single) { inner_html }).to eq(
738
- "<#{name} #{attr1}='bar&#39;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&nbsp;baz #{attr2}=#{value2}>#{inner_html}</#{name}>"
765
- )
766
- end
767
- end
768
- end
769
- end
770
- end
771
- end
772
- end