builder 2.1.2 → 3.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.
- data/CHANGES +5 -1
- data/README +20 -1
- data/README.rdoc +232 -0
- data/Rakefile +62 -29
- data/TAGS +55364 -0
- data/doc/releases/builder-2.1.1.rdoc +0 -0
- data/lib/blankslate.rb +3 -7
- data/lib/builder/blankslate.rb +6 -3
- data/lib/builder/xchar.rb +108 -26
- data/lib/builder/xmlbase.rb +40 -19
- data/lib/builder/xmlmarkup.rb +29 -23
- data/test/performance.rb +10 -0
- data/test/preload.rb +10 -0
- data/test/{testblankslate.rb → test_blankslate.rb} +42 -0
- data/test/test_cssbuilder.rb +125 -0
- data/test/{testeventbuilder.rb → test_eventbuilder.rb} +17 -0
- data/test/{testmarkupbuilder.rb → test_markupbuilder.rb} +100 -3
- data/test/test_namecollision.rb +39 -0
- data/test/test_xchar.rb +43 -3
- metadata +77 -48
- data/scripts/publish.rb +0 -17
data/test/preload.rb
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
#--
|
4
|
+
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
|
5
|
+
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
|
6
|
+
# All rights reserved.
|
7
|
+
|
8
|
+
# Permission is granted for use, copying, modification, distribution,
|
9
|
+
# and distribution of modified versions of this work as long as the
|
10
|
+
# above copyright notice is included.
|
11
|
+
#++
|
12
|
+
|
3
13
|
# We are defining method_added in Kernel and Object so that when
|
4
14
|
# BlankSlate overrides them later, we can verify that it correctly
|
5
15
|
# calls the older hooks.
|
@@ -1,5 +1,15 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
#--
|
4
|
+
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
|
5
|
+
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
|
6
|
+
# All rights reserved.
|
7
|
+
|
8
|
+
# Permission is granted for use, copying, modification, distribution,
|
9
|
+
# and distribution of modified versions of this work as long as the
|
10
|
+
# above copyright notice is included.
|
11
|
+
#++
|
12
|
+
|
3
13
|
require 'test/unit'
|
4
14
|
require 'test/preload'
|
5
15
|
require 'builder/blankslate'
|
@@ -71,6 +81,13 @@ end
|
|
71
81
|
# Test case for blank slate.
|
72
82
|
#
|
73
83
|
class TestBlankSlate < Test::Unit::TestCase
|
84
|
+
if Object::const_defined?(:BasicObject)
|
85
|
+
def self.suite
|
86
|
+
# skip tests if :BasicObject is present
|
87
|
+
Test::Unit::TestSuite.new(name)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
74
91
|
def setup
|
75
92
|
@bs = BlankSlate.new
|
76
93
|
end
|
@@ -155,6 +172,19 @@ class TestBlankSlate < Test::Unit::TestCase
|
|
155
172
|
assert_match /^#<.*>$/, with_to_s.new.to_s
|
156
173
|
end
|
157
174
|
|
175
|
+
def test_revealing_previously_hidden_methods_are_callable_with_block
|
176
|
+
Object.class_eval <<-EOS
|
177
|
+
def given_block(&block)
|
178
|
+
block
|
179
|
+
end
|
180
|
+
EOS
|
181
|
+
|
182
|
+
with_given_block = Class.new(BlankSlate) do
|
183
|
+
reveal :given_block
|
184
|
+
end
|
185
|
+
assert_not_nil with_given_block.new.given_block {}
|
186
|
+
end
|
187
|
+
|
158
188
|
def test_revealing_a_hidden_method_twice_is_ok
|
159
189
|
with_to_s = Class.new(BlankSlate) do
|
160
190
|
reveal :to_s
|
@@ -179,5 +209,17 @@ class TestBlankSlate < Test::Unit::TestCase
|
|
179
209
|
assert_equal 43, direct_global
|
180
210
|
end
|
181
211
|
end
|
212
|
+
|
213
|
+
def test_reveal_should_not_bind_to_an_instance
|
214
|
+
with_object_id = Class.new(BlankSlate) do
|
215
|
+
reveal(:object_id)
|
216
|
+
end
|
217
|
+
|
218
|
+
obj1 = with_object_id.new
|
219
|
+
obj2 = with_object_id.new
|
220
|
+
|
221
|
+
assert obj1.object_id != obj2.object_id,
|
222
|
+
"Revealed methods should not be bound to a particular instance"
|
223
|
+
end
|
182
224
|
end
|
183
225
|
|
@@ -0,0 +1,125 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
|
5
|
+
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
|
6
|
+
# All rights reserved.
|
7
|
+
|
8
|
+
# Permission is granted for use, copying, modification, distribution,
|
9
|
+
# and distribution of modified versions of this work as long as the
|
10
|
+
# above copyright notice is included.
|
11
|
+
#++
|
12
|
+
|
13
|
+
require 'test/unit'
|
14
|
+
require 'test/preload'
|
15
|
+
require 'builder'
|
16
|
+
require 'builder/css'
|
17
|
+
|
18
|
+
class TestCSS < Test::Unit::TestCase
|
19
|
+
def setup
|
20
|
+
@css = Builder::CSS.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_create
|
24
|
+
assert_not_nil @css
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_no_block
|
28
|
+
@css.body
|
29
|
+
assert_equal 'body', @css.target!
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_block
|
33
|
+
@css.body {
|
34
|
+
color 'green'
|
35
|
+
}
|
36
|
+
assert_equal "body {\n color: green;\n}\n\n", @css.target!
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_id
|
40
|
+
@css.id!('nav') { color 'green' }
|
41
|
+
assert_equal "#nav {\n color: green;\n}\n\n", @css.target!
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_class
|
45
|
+
@css.class!('nav') { color 'green' }
|
46
|
+
assert_equal ".nav {\n color: green;\n}\n\n", @css.target!
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_elem_with_id
|
50
|
+
@css.div(:id => 'nav') { color 'green' }
|
51
|
+
assert_equal "div#nav {\n color: green;\n}\n\n", @css.target!
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_elem_with_class
|
55
|
+
@css.div(:class => 'nav') { color 'green' }
|
56
|
+
assert_equal "div.nav {\n color: green;\n}\n\n", @css.target!
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_comment
|
60
|
+
@css.comment!('foo')
|
61
|
+
assert_equal "/* foo */\n", @css.target!
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_selector
|
65
|
+
@css.a(:hover) { color 'green' }
|
66
|
+
assert_equal "a:hover {\n color: green;\n}\n\n", @css.target!
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_plus
|
70
|
+
@css.h1 + @css.span
|
71
|
+
assert_equal "h1 + span", @css.target!
|
72
|
+
end
|
73
|
+
|
74
|
+
def test_plus_with_block
|
75
|
+
@css.h1 + @css.span { color 'green' }
|
76
|
+
assert_equal "h1 + span {\n color: green;\n}\n\n", @css.target!
|
77
|
+
end
|
78
|
+
|
79
|
+
def test_contextual
|
80
|
+
@css.h1 >> @css.span
|
81
|
+
assert_equal "h1 span", @css.target!
|
82
|
+
end
|
83
|
+
|
84
|
+
def test_contextual_with_block
|
85
|
+
@css.h1 >> @css.span { color 'green' }
|
86
|
+
assert_equal "h1 span {\n color: green;\n}\n\n", @css.target!
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_child
|
90
|
+
@css.h1 > @css.span
|
91
|
+
assert_equal "h1 > span", @css.target!
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_child_with_block
|
95
|
+
@css.h1 > @css.span { color 'green' }
|
96
|
+
assert_equal "h1 > span {\n color: green;\n}\n\n", @css.target!
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_multiple_op
|
100
|
+
@css.h1 + @css.span + @css.span
|
101
|
+
assert_equal "h1 + span + span", @css.target!
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_all
|
105
|
+
@css.h1 | @css.h2 { color 'green' }
|
106
|
+
assert_equal "h1 , h2 {\n color: green;\n}\n\n", @css.target!
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_all_with_atts
|
110
|
+
@css.h1(:class => 'foo') | @css.h2(:class => 'bar') { color 'green' }
|
111
|
+
assert_equal "h1.foo , h2.bar {\n color: green;\n}\n\n", @css.target!
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_multiple_basic
|
115
|
+
@css.body { color 'green' }
|
116
|
+
@css.h1 { color 'green' }
|
117
|
+
assert_equal "body {\n color: green;\n}\n\nh1 {\n color: green;\n}\n\n", @css.target!
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_multiple_ops
|
121
|
+
@css.body { color 'green' }
|
122
|
+
@css.body > @css.h1 { color 'green' }
|
123
|
+
assert_equal "body {\n color: green;\n}\n\nbody > h1 {\n color: green;\n}\n\n", @css.target!
|
124
|
+
end
|
125
|
+
end
|
@@ -1,3 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
|
5
|
+
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
|
6
|
+
# All rights reserved.
|
7
|
+
|
8
|
+
# Permission is granted for use, copying, modification, distribution,
|
9
|
+
# and distribution of modified versions of this work as long as the
|
10
|
+
# above copyright notice is included.
|
11
|
+
#++
|
12
|
+
|
13
|
+
require 'test/unit'
|
14
|
+
require 'test/preload'
|
15
|
+
require 'builder'
|
16
|
+
require 'builder/xmlevents'
|
17
|
+
|
1
18
|
class TestEvents < Test::Unit::TestCase
|
2
19
|
|
3
20
|
class Target
|
@@ -118,7 +118,7 @@ class TestMarkup < Test::Unit::TestCase
|
|
118
118
|
end
|
119
119
|
|
120
120
|
def test_ambiguous_markup
|
121
|
-
ex =
|
121
|
+
ex = assert_raise(ArgumentError) {
|
122
122
|
@xml.h1("data1") { b }
|
123
123
|
}
|
124
124
|
assert_match /\btext\b/, ex.message
|
@@ -228,6 +228,22 @@ class TestNameSpaces < Test::Unit::TestCase
|
|
228
228
|
assert_match /<owl:Restriction>/m, xml.target!
|
229
229
|
end
|
230
230
|
|
231
|
+
def test_ensure
|
232
|
+
xml = Builder::XmlMarkup.new
|
233
|
+
xml.html do
|
234
|
+
xml.body do
|
235
|
+
begin
|
236
|
+
xml.p do
|
237
|
+
raise Exception.new('boom')
|
238
|
+
end
|
239
|
+
rescue Exception => e
|
240
|
+
xml.pre e
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
assert_match %r{<p>}, xml.target!
|
245
|
+
assert_match %r{</p>}, xml.target!
|
246
|
+
end
|
231
247
|
end
|
232
248
|
|
233
249
|
class TestDeclarations < Test::Unit::TestCase
|
@@ -334,10 +350,10 @@ class TestSpecialMarkup < Test::Unit::TestCase
|
|
334
350
|
end
|
335
351
|
|
336
352
|
def test_no_blocks
|
337
|
-
|
353
|
+
assert_raise(Builder::IllegalBlockError) do
|
338
354
|
@xml.instruct! { |x| x.hi }
|
339
355
|
end
|
340
|
-
|
356
|
+
assert_raise(Builder::IllegalBlockError) do
|
341
357
|
@xml.comment!(:element) { |x| x.hi }
|
342
358
|
end
|
343
359
|
end
|
@@ -377,6 +393,87 @@ class TestIndentedXmlMarkup < Test::Unit::TestCase
|
|
377
393
|
assert_equal " <name>\n <first>Jim</first>\n </name>\n", @xml.target!
|
378
394
|
end
|
379
395
|
|
396
|
+
class TestUtfMarkup < Test::Unit::TestCase
|
397
|
+
if ! String.method_defined?(:encode)
|
398
|
+
def setup
|
399
|
+
@old_kcode = $KCODE
|
400
|
+
end
|
401
|
+
|
402
|
+
def teardown
|
403
|
+
$KCODE = @old_kcode
|
404
|
+
end
|
405
|
+
|
406
|
+
def test_use_entities_if_no_encoding_is_given_and_kcode_is_none
|
407
|
+
$KCODE = 'NONE'
|
408
|
+
xml = Builder::XmlMarkup.new
|
409
|
+
xml.p("\xE2\x80\x99")
|
410
|
+
assert_match(%r(<p>’</p>), xml.target!) #
|
411
|
+
end
|
412
|
+
|
413
|
+
def test_use_entities_if_encoding_is_utf_but_kcode_is_not
|
414
|
+
$KCODE = 'NONE'
|
415
|
+
xml = Builder::XmlMarkup.new
|
416
|
+
xml.instruct!(:xml, :encoding => 'UTF-8')
|
417
|
+
xml.p("\xE2\x80\x99")
|
418
|
+
assert_match(%r(<p>’</p>), xml.target!) #
|
419
|
+
end
|
420
|
+
else
|
421
|
+
# change in behavior. As there is no $KCODE anymore, the default
|
422
|
+
# moves from "does not understand utf-8" to "supports utf-8".
|
423
|
+
|
424
|
+
def test_use_entities_if_no_encoding_is_given_and_kcode_is_none
|
425
|
+
xml = Builder::XmlMarkup.new
|
426
|
+
xml.p("\xE2\x80\x99")
|
427
|
+
assert_match("<p>\u2019</p>", xml.target!) #
|
428
|
+
end
|
429
|
+
|
430
|
+
def test_use_entities_if_encoding_is_utf_but_kcode_is_not
|
431
|
+
xml = Builder::XmlMarkup.new
|
432
|
+
xml.instruct!(:xml, :encoding => 'UTF-8')
|
433
|
+
xml.p("\xE2\x80\x99")
|
434
|
+
assert_match("<p>\u2019</p>", xml.target!) #
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
def encode string, encoding
|
439
|
+
if !String.method_defined?(:encode)
|
440
|
+
$KCODE = encoding
|
441
|
+
string
|
442
|
+
elsif encoding == 'UTF8'
|
443
|
+
string.force_encoding('UTF-8')
|
444
|
+
else
|
445
|
+
string
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
def test_use_entities_if_kcode_is_utf_but_encoding_is_something_else
|
450
|
+
xml = Builder::XmlMarkup.new
|
451
|
+
xml.instruct!(:xml, :encoding => 'UTF-16')
|
452
|
+
xml.p(encode("\xE2\x80\x99", 'UTF8'))
|
453
|
+
assert_match(%r(<p>’</p>), xml.target!) #
|
454
|
+
end
|
455
|
+
|
456
|
+
def test_use_utf8_if_encoding_defaults_and_kcode_is_utf8
|
457
|
+
xml = Builder::XmlMarkup.new
|
458
|
+
xml.p(encode("\xE2\x80\x99",'UTF8'))
|
459
|
+
assert_equal encode("<p>\xE2\x80\x99</p>",'UTF8'), xml.target!
|
460
|
+
end
|
461
|
+
|
462
|
+
def test_use_utf8_if_both_encoding_and_kcode_are_utf8
|
463
|
+
xml = Builder::XmlMarkup.new
|
464
|
+
xml.instruct!(:xml, :encoding => 'UTF-8')
|
465
|
+
xml.p(encode("\xE2\x80\x99",'UTF8'))
|
466
|
+
assert_match encode("<p>\xE2\x80\x99</p>",'UTF8'), xml.target!
|
467
|
+
end
|
468
|
+
|
469
|
+
def test_use_utf8_if_both_encoding_and_kcode_are_utf8_with_lowercase
|
470
|
+
xml = Builder::XmlMarkup.new
|
471
|
+
xml.instruct!(:xml, :encoding => 'utf-8')
|
472
|
+
xml.p(encode("\xE2\x80\x99",'UTF8'))
|
473
|
+
assert_match encode("<p>\xE2\x80\x99</p>",'UTF8'), xml.target!
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
380
477
|
class TestXmlEvents < Test::Unit::TestCase
|
381
478
|
def setup
|
382
479
|
@handler = EventHandler.new
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#--
|
4
|
+
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
|
5
|
+
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
|
6
|
+
# All rights reserved.
|
7
|
+
|
8
|
+
# Permission is granted for use, copying, modification, distribution,
|
9
|
+
# and distribution of modified versions of this work as long as the
|
10
|
+
# above copyright notice is included.
|
11
|
+
#++
|
12
|
+
|
13
|
+
require 'test/unit'
|
14
|
+
require 'builder/xchar'
|
15
|
+
|
16
|
+
class TestNameCollisions < Test::Unit::TestCase
|
17
|
+
module Collide
|
18
|
+
def xchr
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_no_collision
|
23
|
+
assert_nothing_raised do
|
24
|
+
Builder.check_for_name_collision(Collide, :not_defined)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_collision
|
29
|
+
assert_raise RuntimeError do
|
30
|
+
Builder.check_for_name_collision(Collide, "xchr")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_collision_with_symbol
|
35
|
+
assert_raise RuntimeError do
|
36
|
+
Builder.check_for_name_collision(Collide, :xchr)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/test/test_xchar.rb
CHANGED
@@ -1,9 +1,42 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
+
#--
|
4
|
+
# Portions copyright 2004 by Jim Weirich (jim@weirichhouse.org).
|
5
|
+
# Portions copyright 2005 by Sam Ruby (rubys@intertwingly.net).
|
6
|
+
# All rights reserved.
|
7
|
+
|
8
|
+
# Permission is granted for use, copying, modification, distribution,
|
9
|
+
# and distribution of modified versions of this work as long as the
|
10
|
+
# above copyright notice is included.
|
11
|
+
#++
|
12
|
+
|
13
|
+
#!/usr/bin/env ruby
|
14
|
+
|
3
15
|
require 'test/unit'
|
4
16
|
require 'builder/xchar'
|
5
17
|
|
18
|
+
if String.method_defined?(:encode)
|
19
|
+
class String
|
20
|
+
ENCODING_BINARY = Encoding.find('BINARY')
|
21
|
+
|
22
|
+
# shim method for testing purposes
|
23
|
+
def to_xs(escape=true)
|
24
|
+
raise NameError.new('to_xs') unless caller[0].index(__FILE__)
|
25
|
+
|
26
|
+
result = Builder::XChar.encode(self)
|
27
|
+
if escape
|
28
|
+
result.gsub(/[^\u0000-\u007F]/) {|c| "&##{c.ord};"}
|
29
|
+
else
|
30
|
+
# really only useful for testing purposes
|
31
|
+
result.force_encoding(ENCODING_BINARY)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
6
37
|
class TestXmlEscaping < Test::Unit::TestCase
|
38
|
+
REPLACEMENT_CHAR = Builder::XChar::REPLACEMENT_CHAR.to_xs
|
39
|
+
|
7
40
|
def test_ascii
|
8
41
|
assert_equal 'abc', 'abc'.to_xs
|
9
42
|
end
|
@@ -15,9 +48,9 @@ class TestXmlEscaping < Test::Unit::TestCase
|
|
15
48
|
end
|
16
49
|
|
17
50
|
def test_invalid
|
18
|
-
assert_equal
|
19
|
-
assert_equal
|
20
|
-
assert_equal
|
51
|
+
assert_equal REPLACEMENT_CHAR, "\x00".to_xs # null
|
52
|
+
assert_equal REPLACEMENT_CHAR, "\x0C".to_xs # form feed
|
53
|
+
assert_equal REPLACEMENT_CHAR, "\xEF\xBF\xBF".to_xs # U+FFFF
|
21
54
|
end
|
22
55
|
|
23
56
|
def test_iso_8859_1
|
@@ -34,4 +67,11 @@ class TestXmlEscaping < Test::Unit::TestCase
|
|
34
67
|
assert_equal '’', "\xE2\x80\x99".to_xs # right single quote
|
35
68
|
assert_equal '©', "\xC2\xA9".to_xs # copy
|
36
69
|
end
|
70
|
+
|
71
|
+
def test_utf8_verbatim
|
72
|
+
assert_equal "\xE2\x80\x99", "\xE2\x80\x99".to_xs(false) # right single quote
|
73
|
+
assert_equal "\xC2\xA9", "\xC2\xA9".to_xs(false) # copy
|
74
|
+
assert_equal "\xC2\xA9&\xC2\xA9",
|
75
|
+
"\xC2\xA9&\xC2\xA9".to_xs(false) # copy with ampersand
|
76
|
+
end
|
37
77
|
end
|