bigfleet-builder 2.2.1

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.
@@ -0,0 +1,196 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'test/preload'
5
+ require 'builder/blankslate'
6
+ require 'stringio'
7
+
8
+ # Methods to be introduced into the Object class late.
9
+ module LateObject
10
+ def late_object
11
+ 33
12
+ end
13
+ def LateObject.included(mod)
14
+ # Modules defining an included method should not prevent blank
15
+ # slate erasure!
16
+ end
17
+ end
18
+
19
+ # Methods to be introduced into the Kernel module late.
20
+ module LateKernel
21
+ def late_kernel
22
+ 44
23
+ end
24
+ def LateKernel.included(mod)
25
+ # Modules defining an included method should not prevent blank
26
+ # slate erasure!
27
+ end
28
+ end
29
+
30
+ # Introduce some late methods (both module and direct) into the Kernel
31
+ # module.
32
+ module Kernel
33
+ include LateKernel
34
+
35
+ def late_addition
36
+ 1234
37
+ end
38
+
39
+ def double_late_addition
40
+ 11
41
+ end
42
+
43
+ def double_late_addition
44
+ 22
45
+ end
46
+ end
47
+
48
+
49
+ # Introduce some late methods (both module and direct) into the Object
50
+ # class.
51
+ class Object
52
+ include LateObject
53
+ def another_late_addition
54
+ 4321
55
+ end
56
+ end
57
+
58
+ # Introduce some late methods by inclusion.
59
+ module GlobalModule
60
+ def global_inclusion
61
+ 42
62
+ end
63
+ end
64
+ include GlobalModule
65
+
66
+ def direct_global
67
+ 43
68
+ end
69
+
70
+ ######################################################################
71
+ # Test case for blank slate.
72
+ #
73
+ class TestBlankSlate < Test::Unit::TestCase
74
+ def setup
75
+ @bs = BlankSlate.new
76
+ end
77
+
78
+ def test_undefined_methods_remain_undefined
79
+ assert_raise(NoMethodError) { @bs.no_such_method }
80
+ assert_raise(NoMethodError) { @bs.nil? }
81
+ end
82
+
83
+
84
+ # NOTE: NameError is acceptable because the lack of a '.' means that
85
+ # Ruby can't tell if it is a method or a local variable.
86
+ def test_undefined_methods_remain_undefined_during_instance_eval
87
+ assert_raise(NoMethodError, NameError) do
88
+ @bs.instance_eval do nil? end
89
+ end
90
+ assert_raise(NoMethodError, NameError) do
91
+ @bs.instance_eval do no_such_method end
92
+ end
93
+ end
94
+
95
+ def test_private_methods_are_undefined
96
+ assert_raise(NoMethodError) do
97
+ @bs.puts "HI"
98
+ end
99
+ end
100
+
101
+ def test_targetted_private_methods_are_undefined_during_instance_eval
102
+ assert_raise(NoMethodError, NameError) do
103
+ @bs.instance_eval do self.puts "HI" end
104
+ end
105
+ end
106
+
107
+ def test_untargetted_private_methods_are_defined_during_instance_eval
108
+ oldstdout = $stdout
109
+ $stdout = StringIO.new
110
+ @bs.instance_eval do
111
+ puts "HI"
112
+ end
113
+ ensure
114
+ $stdout = oldstdout
115
+ end
116
+
117
+ def test_methods_added_late_to_kernel_remain_undefined
118
+ assert_equal 1234, nil.late_addition
119
+ assert_raise(NoMethodError) { @bs.late_addition }
120
+ end
121
+
122
+ def test_methods_added_late_to_object_remain_undefined
123
+ assert_equal 4321, nil.another_late_addition
124
+ assert_raise(NoMethodError) { @bs.another_late_addition }
125
+ end
126
+
127
+ def test_methods_added_late_to_global_remain_undefined
128
+ assert_equal 42, global_inclusion
129
+ assert_raise(NoMethodError) { @bs.global_inclusion }
130
+ end
131
+
132
+ def test_preload_method_added
133
+ assert Kernel.k_added_names.include?(:late_addition)
134
+ assert Object.o_added_names.include?(:another_late_addition)
135
+ end
136
+
137
+ def test_method_defined_late_multiple_times_remain_undefined
138
+ assert_equal 22, nil.double_late_addition
139
+ assert_raise(NoMethodError) { @bs.double_late_addition }
140
+ end
141
+
142
+ def test_late_included_module_in_object_is_ok
143
+ assert_equal 33, 1.late_object
144
+ assert_raise(NoMethodError) { @bs.late_object }
145
+ end
146
+
147
+ def test_late_included_module_in_kernel_is_ok
148
+ assert_raise(NoMethodError) { @bs.late_kernel }
149
+ end
150
+
151
+ def test_revealing_previously_hidden_methods_are_callable
152
+ with_to_s = Class.new(BlankSlate) do
153
+ reveal :to_s
154
+ end
155
+ assert_match /^#<.*>$/, with_to_s.new.to_s
156
+ end
157
+
158
+ def test_revealing_previously_hidden_methods_are_callable_with_block
159
+ Object.class_eval <<-EOS
160
+ def given_block(&block)
161
+ block
162
+ end
163
+ EOS
164
+
165
+ with_given_block = Class.new(BlankSlate) do
166
+ reveal :given_block
167
+ end
168
+ assert_not_nil with_given_block.new.given_block {}
169
+ end
170
+
171
+ def test_revealing_a_hidden_method_twice_is_ok
172
+ with_to_s = Class.new(BlankSlate) do
173
+ reveal :to_s
174
+ reveal :to_s
175
+ end
176
+ assert_match /^#<.*>$/, with_to_s.new.to_s
177
+ end
178
+
179
+ def test_revealing_unknown_hidden_method_is_an_error
180
+ assert_raises(RuntimeError) do
181
+ Class.new(BlankSlate) do
182
+ reveal :xyz
183
+ end
184
+ end
185
+ end
186
+
187
+ def test_global_includes_still_work
188
+ assert_nothing_raised do
189
+ assert_equal 42, global_inclusion
190
+ assert_equal 42, Object.new.global_inclusion
191
+ assert_equal 42, "magic number".global_inclusion
192
+ assert_equal 43, direct_global
193
+ end
194
+ end
195
+ end
196
+
@@ -0,0 +1,115 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'test/preload'
5
+ require 'builder'
6
+ require 'builder/css'
7
+
8
+ class TestCSS < Test::Unit::TestCase
9
+ def setup
10
+ @css = Builder::CSS.new
11
+ end
12
+
13
+ def test_create
14
+ assert_not_nil @css
15
+ end
16
+
17
+ def test_no_block
18
+ @css.body
19
+ assert_equal 'body', @css.target!
20
+ end
21
+
22
+ def test_block
23
+ @css.body {
24
+ color 'green'
25
+ }
26
+ assert_equal "body {\n color: green;\n}\n\n", @css.target!
27
+ end
28
+
29
+ def test_id
30
+ @css.id!('nav') { color 'green' }
31
+ assert_equal "#nav {\n color: green;\n}\n\n", @css.target!
32
+ end
33
+
34
+ def test_class
35
+ @css.class!('nav') { color 'green' }
36
+ assert_equal ".nav {\n color: green;\n}\n\n", @css.target!
37
+ end
38
+
39
+ def test_elem_with_id
40
+ @css.div(:id => 'nav') { color 'green' }
41
+ assert_equal "div#nav {\n color: green;\n}\n\n", @css.target!
42
+ end
43
+
44
+ def test_elem_with_class
45
+ @css.div(:class => 'nav') { color 'green' }
46
+ assert_equal "div.nav {\n color: green;\n}\n\n", @css.target!
47
+ end
48
+
49
+ def test_comment
50
+ @css.comment!('foo')
51
+ assert_equal "/* foo */\n", @css.target!
52
+ end
53
+
54
+ def test_selector
55
+ @css.a(:hover) { color 'green' }
56
+ assert_equal "a:hover {\n color: green;\n}\n\n", @css.target!
57
+ end
58
+
59
+ def test_plus
60
+ @css.h1 + @css.span
61
+ assert_equal "h1 + span", @css.target!
62
+ end
63
+
64
+ def test_plus_with_block
65
+ @css.h1 + @css.span { color 'green' }
66
+ assert_equal "h1 + span {\n color: green;\n}\n\n", @css.target!
67
+ end
68
+
69
+ def test_contextual
70
+ @css.h1 >> @css.span
71
+ assert_equal "h1 span", @css.target!
72
+ end
73
+
74
+ def test_contextual_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_child
80
+ @css.h1 > @css.span
81
+ assert_equal "h1 > span", @css.target!
82
+ end
83
+
84
+ def test_child_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_multiple_op
90
+ @css.h1 + @css.span + @css.span
91
+ assert_equal "h1 + span + span", @css.target!
92
+ end
93
+
94
+ def test_all
95
+ @css.h1 | @css.h2 { color 'green' }
96
+ assert_equal "h1 , h2 {\n color: green;\n}\n\n", @css.target!
97
+ end
98
+
99
+ def test_all_with_atts
100
+ @css.h1(:class => 'foo') | @css.h2(:class => 'bar') { color 'green' }
101
+ assert_equal "h1.foo , h2.bar {\n color: green;\n}\n\n", @css.target!
102
+ end
103
+
104
+ def test_multiple_basic
105
+ @css.body { color 'green' }
106
+ @css.h1 { color 'green' }
107
+ assert_equal "body {\n color: green;\n}\n\nh1 {\n color: green;\n}\n\n", @css.target!
108
+ end
109
+
110
+ def test_multiple_ops
111
+ @css.body { color 'green' }
112
+ @css.body > @css.h1 { color 'green' }
113
+ assert_equal "body {\n color: green;\n}\n\nbody > h1 {\n color: green;\n}\n\n", @css.target!
114
+ end
115
+ end
@@ -0,0 +1,133 @@
1
+ class TestEvents < Test::Unit::TestCase
2
+
3
+ class Target
4
+ attr_reader :events
5
+
6
+ def initialize
7
+ @events = []
8
+ end
9
+
10
+ def start_tag(tag, attrs)
11
+ @events << [:start_tag, tag, attrs]
12
+ end
13
+
14
+ def end_tag(tag)
15
+ @events << [:end_tag, tag]
16
+ end
17
+
18
+ def text(string)
19
+ @events << [:text, string]
20
+ end
21
+
22
+ end
23
+
24
+
25
+ def setup
26
+ @target = Target.new
27
+ @xml = Builder::XmlEvents.new(:target=>@target)
28
+ end
29
+
30
+ def test_simple
31
+ @xml.one
32
+ expect [:start_tag, :one, nil]
33
+ expect [:end_tag, :one]
34
+ expect_done
35
+ end
36
+
37
+ def test_nested
38
+ @xml.one { @xml.two }
39
+ expect [:start_tag, :one, nil]
40
+ expect [:start_tag, :two, nil]
41
+ expect [:end_tag, :two]
42
+ expect [:end_tag, :one]
43
+ expect_done
44
+ end
45
+
46
+ def test_text
47
+ @xml.one("a")
48
+ expect [:start_tag, :one, nil]
49
+ expect [:text, "a"]
50
+ expect [:end_tag, :one]
51
+ expect_done
52
+ end
53
+
54
+ def test_special_text
55
+ @xml.one("H&R")
56
+ expect [:start_tag, :one, nil]
57
+ expect [:text, "H&R"]
58
+ expect [:end_tag, :one]
59
+ expect_done
60
+ end
61
+
62
+ def test_text_with_entity
63
+ @xml.one("H&amp;R")
64
+ expect [:start_tag, :one, nil]
65
+ expect [:text, "H&amp;R"]
66
+ expect [:end_tag, :one]
67
+ expect_done
68
+ end
69
+
70
+ def test_attributes
71
+ @xml.a(:b=>"c", :x=>"y")
72
+ expect [:start_tag, :a, {:x => "y", :b => "c"}]
73
+ expect [:end_tag, :a]
74
+ expect_done
75
+ end
76
+
77
+ def test_moderately_complex
78
+ @xml.tag! "address-book" do |x|
79
+ x.entry :id=>"1" do
80
+ x.name {
81
+ x.first "Bill"
82
+ x.last "Smith"
83
+ }
84
+ x.address "Cincinnati"
85
+ end
86
+ x.entry :id=>"2" do
87
+ x.name {
88
+ x.first "John"
89
+ x.last "Doe"
90
+ }
91
+ x.address "Columbus"
92
+ end
93
+ end
94
+ expect [:start_tag, "address-book".intern, nil]
95
+ expect [:start_tag, :entry, {:id => "1"}]
96
+ expect [:start_tag, :name, nil]
97
+ expect [:start_tag, :first, nil]
98
+ expect [:text, "Bill"]
99
+ expect [:end_tag, :first]
100
+ expect [:start_tag, :last, nil]
101
+ expect [:text, "Smith"]
102
+ expect [:end_tag, :last]
103
+ expect [:end_tag, :name]
104
+ expect [:start_tag, :address, nil]
105
+ expect [:text, "Cincinnati"]
106
+ expect [:end_tag, :address]
107
+ expect [:end_tag, :entry]
108
+ expect [:start_tag, :entry, {:id => "2"}]
109
+ expect [:start_tag, :name, nil]
110
+ expect [:start_tag, :first, nil]
111
+ expect [:text, "John"]
112
+ expect [:end_tag, :first]
113
+ expect [:start_tag, :last, nil]
114
+ expect [:text, "Doe"]
115
+ expect [:end_tag, :last]
116
+ expect [:end_tag, :name]
117
+ expect [:start_tag, :address, nil]
118
+ expect [:text, "Columbus"]
119
+ expect [:end_tag, :address]
120
+ expect [:end_tag, :entry]
121
+ expect [:end_tag, "address-book".intern]
122
+ expect_done
123
+ end
124
+
125
+ def expect(value)
126
+ assert_equal value, @target.events.shift
127
+ end
128
+
129
+ def expect_done
130
+ assert_nil @target.events.shift
131
+ end
132
+
133
+ end
@@ -0,0 +1,505 @@
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/xmlmarkup'
17
+
18
+ class TestMarkup < Test::Unit::TestCase
19
+ def setup
20
+ @xml = Builder::XmlMarkup.new
21
+ end
22
+
23
+ def test_create
24
+ assert_not_nil @xml
25
+ end
26
+
27
+ def test_simple
28
+ @xml.simple
29
+ assert_equal "<simple/>", @xml.target!
30
+ end
31
+
32
+ def test_value
33
+ @xml.value("hi")
34
+ assert_equal "<value>hi</value>", @xml.target!
35
+ end
36
+
37
+ def test_nested
38
+ @xml.outer { |x| x.inner("x") }
39
+ assert_equal "<outer><inner>x</inner></outer>", @xml.target!
40
+ end
41
+
42
+ def test_attributes
43
+ @xml.ref(:id => 12)
44
+ assert_equal %{<ref id="12"/>}, @xml.target!
45
+ end
46
+
47
+ def test_string_attributes_are_quoted_by_default
48
+ @xml.ref(:id => "H&R")
49
+ assert_equal %{<ref id="H&amp;R"/>}, @xml.target!
50
+ end
51
+
52
+ def test_symbol_attributes_are_unquoted_by_default
53
+ @xml.ref(:id => :"H&amp;R")
54
+ assert_equal %{<ref id="H&amp;R"/>}, @xml.target!
55
+ end
56
+
57
+ def test_attributes_quoted_can_be_turned_on
58
+ @xml = Builder::XmlMarkup.new
59
+ @xml.ref(:id => "<H&R \"block\">")
60
+ assert_equal %{<ref id="&lt;H&amp;R &quot;block&quot;&gt;"/>}, @xml.target!
61
+ end
62
+
63
+ def test_mixed_attribute_quoting_with_nested_builders
64
+ x = Builder::XmlMarkup.new(:target=>@xml)
65
+ @xml.ref(:id=>:"H&amp;R") {
66
+ x.element(:tag=>"Long&Short")
67
+ }
68
+ assert_equal "<ref id=\"H&amp;R\"><element tag=\"Long&amp;Short\"/></ref>",
69
+ @xml.target!
70
+ end
71
+
72
+ def test_multiple_attributes
73
+ @xml.ref(:id => 12, :name => "bill")
74
+ assert_match %r{^<ref( id="12"| name="bill"){2}/>$}, @xml.target!
75
+ end
76
+
77
+ def test_attributes_with_text
78
+ @xml.a("link", :href=>"http://onestepback.org")
79
+ assert_equal %{<a href="http://onestepback.org">link</a>}, @xml.target!
80
+ end
81
+
82
+ def test_complex
83
+ @xml.body(:bg=>"#ffffff") { |x|
84
+ x.title("T", :style=>"red")
85
+ }
86
+ assert_equal %{<body bg="#ffffff"><title style="red">T</title></body>}, @xml.target!
87
+ end
88
+
89
+ def test_funky_symbol
90
+ @xml.tag!("non-ruby-token", :id=>1) { |x| x.ok }
91
+ assert_equal %{<non-ruby-token id="1"><ok/></non-ruby-token>}, @xml.target!
92
+ end
93
+
94
+ def test_tag_can_handle_private_method
95
+ @xml.tag!("loop", :id=>1) { |x| x.ok }
96
+ assert_equal %{<loop id="1"><ok/></loop>}, @xml.target!
97
+ end
98
+
99
+ def test_no_explicit_marker
100
+ @xml.p { |x| x.b("HI") }
101
+ assert_equal "<p><b>HI</b></p>", @xml.target!
102
+ end
103
+
104
+ def test_reference_local_vars
105
+ n = 3
106
+ @xml.ol { |x| n.times { x.li(n) } }
107
+ assert_equal "<ol><li>3</li><li>3</li><li>3</li></ol>", @xml.target!
108
+ end
109
+
110
+ def test_reference_methods
111
+ @xml.title { |x| x.a { x.b(name) } }
112
+ assert_equal "<title><a><b>bob</b></a></title>", @xml.target!
113
+ end
114
+
115
+ def test_append_text
116
+ @xml.p { |x| x.br; x.text! "HI" }
117
+ assert_equal "<p><br/>HI</p>", @xml.target!
118
+ end
119
+
120
+ def test_ambiguous_markup
121
+ ex = assert_raises(ArgumentError) {
122
+ @xml.h1("data1") { b }
123
+ }
124
+ assert_match /\btext\b/, ex.message
125
+ assert_match /\bblock\b/, ex.message
126
+ end
127
+
128
+ def test_capitalized_method
129
+ @xml.P { |x| x.B("hi"); x.BR(); x.EM { x.text! "world" } }
130
+ assert_equal "<P><B>hi</B><BR/><EM>world</EM></P>", @xml.target!
131
+ end
132
+
133
+ def test_escaping
134
+ @xml.div { |x| x.text! "<hi>"; x.em("H&R Block") }
135
+ assert_equal %{<div>&lt;hi&gt;<em>H&amp;R Block</em></div>}, @xml.target!
136
+ end
137
+
138
+ def test_non_escaping
139
+ @xml.div("ns:xml"=>:"&xml;") { |x| x << "<h&i>"; x.em("H&R Block") }
140
+ assert_equal %{<div ns:xml="&xml;"><h&i><em>H&amp;R Block</em></div>}, @xml.target!
141
+ end
142
+
143
+ def test_return_value
144
+ str = @xml.x("men")
145
+ assert_equal @xml.target!, str
146
+ end
147
+
148
+ def test_stacked_builders
149
+ b = Builder::XmlMarkup.new( :target => @xml )
150
+ b.div { @xml.span { @xml.a("text", :href=>"ref") } }
151
+ assert_equal "<div><span><a href=\"ref\">text</a></span></div>", @xml.target!
152
+ end
153
+
154
+ def name
155
+ "bob"
156
+ end
157
+ end
158
+
159
+ class TestAttributeEscaping < Test::Unit::TestCase
160
+
161
+ def setup
162
+ @xml = Builder::XmlMarkup.new
163
+ end
164
+
165
+ def test_element_gt
166
+ @xml.title('1<2')
167
+ assert_equal '<title>1&lt;2</title>', @xml.target!
168
+ end
169
+
170
+ def test_element_amp
171
+ @xml.title('AT&T')
172
+ assert_equal '<title>AT&amp;T</title>', @xml.target!
173
+ end
174
+
175
+ def test_element_amp2
176
+ @xml.title('&amp;')
177
+ assert_equal '<title>&amp;amp;</title>', @xml.target!
178
+ end
179
+
180
+ def test_attr_less
181
+ @xml.a(:title => '2>1')
182
+ assert_equal '<a title="2&gt;1"/>', @xml.target!
183
+ end
184
+
185
+ def test_attr_amp
186
+ @xml.a(:title => 'AT&T')
187
+ assert_equal '<a title="AT&amp;T"/>', @xml.target!
188
+ end
189
+
190
+ def test_attr_quot
191
+ @xml.a(:title => '"x"')
192
+ assert_equal '<a title="&quot;x&quot;"/>', @xml.target!
193
+ end
194
+
195
+ end
196
+
197
+ class TestNameSpaces < Test::Unit::TestCase
198
+ def setup
199
+ @xml = Builder::XmlMarkup.new(:indent=>2)
200
+ end
201
+
202
+ def test_simple_name_spaces
203
+ @xml.rdf :RDF
204
+ assert_equal "<rdf:RDF/>\n", @xml.target!
205
+ end
206
+
207
+ def test_long
208
+ xml = Builder::XmlMarkup.new(:indent=>2)
209
+ xml.instruct!
210
+ xml.rdf :RDF,
211
+ "xmlns:rdf" => :"&rdf;",
212
+ "xmlns:rdfs" => :"&rdfs;",
213
+ "xmlns:xsd" => :"&xsd;",
214
+ "xmlns:owl" => :"&owl;" do
215
+ xml.owl :Class, :'rdf:ID'=>'Bird' do
216
+ xml.rdfs :label, 'bird'
217
+ xml.rdfs :subClassOf do
218
+ xml.owl :Restriction do
219
+ xml.owl :onProperty, 'rdf:resource'=>'#wingspan'
220
+ xml.owl :maxCardinality,1,'rdf:datatype'=>'&xsd;nonNegativeInteger'
221
+ end
222
+ end
223
+ end
224
+ end
225
+ assert_match /^<\?xml/, xml.target!
226
+ assert_match /\n<rdf:RDF/m, xml.target!
227
+ assert_match /xmlns:rdf="&rdf;"/m, xml.target!
228
+ assert_match /<owl:Restriction>/m, xml.target!
229
+ end
230
+
231
+ end
232
+
233
+ class TestDeclarations < Test::Unit::TestCase
234
+ def setup
235
+ @xml = Builder::XmlMarkup.new(:indent=>2)
236
+ end
237
+
238
+ def test_declare
239
+ @xml.declare! :element
240
+ assert_equal "<!element>\n", @xml.target!
241
+ end
242
+
243
+ def test_bare_arg
244
+ @xml.declare! :element, :arg
245
+ assert_equal"<!element arg>\n", @xml.target!
246
+ end
247
+
248
+ def test_string_arg
249
+ @xml.declare! :element, "string"
250
+ assert_equal"<!element \"string\">\n", @xml.target!
251
+ end
252
+
253
+ def test_mixed_args
254
+ @xml.declare! :element, :x, "y", :z, "-//OASIS//DTD DocBook XML//EN"
255
+ assert_equal "<!element x \"y\" z \"-//OASIS//DTD DocBook XML//EN\">\n", @xml.target!
256
+ end
257
+
258
+ def test_nested_declarations
259
+ @xml = Builder::XmlMarkup.new
260
+ @xml.declare! :DOCTYPE, :chapter do |x|
261
+ x.declare! :ELEMENT, :chapter, "(title,para+)".intern
262
+ end
263
+ assert_equal "<!DOCTYPE chapter [<!ELEMENT chapter (title,para+)>]>", @xml.target!
264
+ end
265
+
266
+ def test_nested_indented_declarations
267
+ @xml.declare! :DOCTYPE, :chapter do |x|
268
+ x.declare! :ELEMENT, :chapter, "(title,para+)".intern
269
+ end
270
+ assert_equal "<!DOCTYPE chapter [\n <!ELEMENT chapter (title,para+)>\n]>\n", @xml.target!
271
+ end
272
+
273
+ def test_complex_declaration
274
+ @xml.declare! :DOCTYPE, :chapter do |x|
275
+ x.declare! :ELEMENT, :chapter, "(title,para+)".intern
276
+ x.declare! :ELEMENT, :title, "(#PCDATA)".intern
277
+ x.declare! :ELEMENT, :para, "(#PCDATA)".intern
278
+ end
279
+ expected = %{<!DOCTYPE chapter [
280
+ <!ELEMENT chapter (title,para+)>
281
+ <!ELEMENT title (#PCDATA)>
282
+ <!ELEMENT para (#PCDATA)>
283
+ ]>
284
+ }
285
+ assert_equal expected, @xml.target!
286
+ end
287
+ end
288
+
289
+
290
+ class TestSpecialMarkup < Test::Unit::TestCase
291
+ def setup
292
+ @xml = Builder::XmlMarkup.new(:indent=>2)
293
+ end
294
+
295
+ def test_comment
296
+ @xml.comment!("COMMENT")
297
+ assert_equal "<!-- COMMENT -->\n", @xml.target!
298
+ end
299
+
300
+ def test_indented_comment
301
+ @xml.p { @xml.comment! "OK" }
302
+ assert_equal "<p>\n <!-- OK -->\n</p>\n", @xml.target!
303
+ end
304
+
305
+ def test_instruct
306
+ @xml.instruct! :abc, :version=>"0.9"
307
+ assert_equal "<?abc version=\"0.9\"?>\n", @xml.target!
308
+ end
309
+
310
+ def test_indented_instruct
311
+ @xml.p { @xml.instruct! :xml }
312
+ assert_match %r{<p>\n <\?xml version="1.0" encoding="UTF-8"\?>\n</p>\n},
313
+ @xml.target!
314
+ end
315
+
316
+ def test_instruct_without_attributes
317
+ @xml.instruct! :zz
318
+ assert_equal "<?zz?>\n", @xml.target!
319
+ end
320
+
321
+ def test_xml_instruct
322
+ @xml.instruct!
323
+ assert_match /^<\?xml version="1.0" encoding="UTF-8"\?>$/, @xml.target!
324
+ end
325
+
326
+ def test_xml_instruct_with_overrides
327
+ @xml.instruct! :xml, :encoding=>"UCS-2"
328
+ assert_match /^<\?xml version="1.0" encoding="UCS-2"\?>$/, @xml.target!
329
+ end
330
+
331
+ def test_xml_instruct_with_standalong
332
+ @xml.instruct! :xml, :encoding=>"UCS-2", :standalone=>"yes"
333
+ assert_match /^<\?xml version="1.0" encoding="UCS-2" standalone="yes"\?>$/, @xml.target!
334
+ end
335
+
336
+ def test_no_blocks
337
+ assert_raises(Builder::IllegalBlockError) do
338
+ @xml.instruct! { |x| x.hi }
339
+ end
340
+ assert_raises(Builder::IllegalBlockError) do
341
+ @xml.comment!(:element) { |x| x.hi }
342
+ end
343
+ end
344
+
345
+ def test_cdata
346
+ @xml.cdata!("TEST")
347
+ assert_equal "<![CDATA[TEST]]>\n", @xml.target!
348
+ end
349
+
350
+ def test_cdata_with_ampersand
351
+ @xml.cdata!("TEST&CHECK")
352
+ assert_equal "<![CDATA[TEST&CHECK]]>\n", @xml.target!
353
+ end
354
+ end
355
+
356
+ class TestIndentedXmlMarkup < Test::Unit::TestCase
357
+ def setup
358
+ @xml = Builder::XmlMarkup.new(:indent=>2)
359
+ end
360
+
361
+ def test_one_level
362
+ @xml.ol { |x| x.li "text" }
363
+ assert_equal "<ol>\n <li>text</li>\n</ol>\n", @xml.target!
364
+ end
365
+
366
+ def test_two_levels
367
+ @xml.p { |x|
368
+ x.ol { x.li "text" }
369
+ x.br
370
+ }
371
+ assert_equal "<p>\n <ol>\n <li>text</li>\n </ol>\n <br/>\n</p>\n", @xml.target!
372
+ end
373
+
374
+ def test_initial_level
375
+ @xml = Builder::XmlMarkup.new(:indent=>2, :margin=>4)
376
+ @xml.name { |x| x.first("Jim") }
377
+ assert_equal " <name>\n <first>Jim</first>\n </name>\n", @xml.target!
378
+ end
379
+
380
+ class TestUtfMarkup < Test::Unit::TestCase
381
+ def setup
382
+ @old_kcode = $KCODE
383
+ end
384
+
385
+ def teardown
386
+ $KCODE = @old_kcode
387
+ end
388
+
389
+ def test_use_entities_if_no_encoding_is_given_and_kcode_is_none
390
+ $KCODE = 'NONE'
391
+ xml = Builder::XmlMarkup.new
392
+ xml.p("\xE2\x80\x99")
393
+ assert_match(%r(<p>&#8217;</p>), xml.target!) #
394
+ end
395
+
396
+ def test_use_entities_if_encoding_is_utf_but_kcode_is_not
397
+ $KCODE = 'NONE'
398
+ xml = Builder::XmlMarkup.new
399
+ xml.instruct!(:xml, :encoding => 'UTF-8')
400
+ xml.p("\xE2\x80\x99")
401
+ assert_match(%r(<p>&#8217;</p>), xml.target!) #
402
+ end
403
+
404
+ def test_use_entities_if_kcode_is_utf_but_encoding_is_something_else
405
+ $KCODE = 'UTF8'
406
+ xml = Builder::XmlMarkup.new
407
+ xml.instruct!(:xml, :encoding => 'UTF-16')
408
+ xml.p("\xE2\x80\x99")
409
+ assert_match(%r(<p>&#8217;</p>), xml.target!) #
410
+ end
411
+
412
+ def test_use_utf8_if_encoding_defaults_and_kcode_is_utf8
413
+ $KCODE = 'UTF8'
414
+ xml = Builder::XmlMarkup.new
415
+ xml.p("\xE2\x80\x99")
416
+ assert_equal "<p>\xE2\x80\x99</p>", xml.target!
417
+ end
418
+
419
+ def test_use_utf8_if_both_encoding_and_kcode_are_utf8
420
+ $KCODE = 'UTF8'
421
+ xml = Builder::XmlMarkup.new
422
+ xml.instruct!(:xml, :encoding => 'UTF-8')
423
+ xml.p("\xE2\x80\x99")
424
+ assert_match(%r(<p>\xE2\x80\x99</p>), xml.target!)
425
+ end
426
+
427
+ def test_use_utf8_if_both_encoding_and_kcode_are_utf8_with_lowercase
428
+ $KCODE = 'UTF8'
429
+ xml = Builder::XmlMarkup.new
430
+ xml.instruct!(:xml, :encoding => 'utf-8')
431
+ xml.p("\xE2\x80\x99")
432
+ assert_match(%r(<p>\xE2\x80\x99</p>), xml.target!)
433
+ end
434
+ end
435
+
436
+ class TestXmlEvents < Test::Unit::TestCase
437
+ def setup
438
+ @handler = EventHandler.new
439
+ @xe = Builder::XmlEvents.new(:target=>@handler)
440
+ end
441
+
442
+ def test_simple
443
+ @xe.p
444
+ assert_equal [:start, :p, nil], @handler.events.shift
445
+ assert_equal [:end, :p], @handler.events.shift
446
+ end
447
+
448
+ def test_text
449
+ @xe.p("HI")
450
+ assert_equal [:start, :p, nil], @handler.events.shift
451
+ assert_equal [:text, "HI"], @handler.events.shift
452
+ assert_equal [:end, :p], @handler.events.shift
453
+ end
454
+
455
+ def test_attributes
456
+ @xe.p("id"=>"2")
457
+ ev = @handler.events.shift
458
+ assert_equal [:start, :p], ev[0,2]
459
+ assert_equal "2", ev[2]['id']
460
+ assert_equal [:end, :p], @handler.events.shift
461
+ end
462
+
463
+ def test_indented
464
+ @xml = Builder::XmlEvents.new(:indent=>2, :target=>@handler)
465
+ @xml.p { |x| x.b("HI") }
466
+ assert_equal [:start, :p, nil], @handler.events.shift
467
+ assert_equal "\n ", pop_text
468
+ assert_equal [:start, :b, nil], @handler.events.shift
469
+ assert_equal "HI", pop_text
470
+ assert_equal [:end, :b], @handler.events.shift
471
+ assert_equal "\n", pop_text
472
+ assert_equal [:end, :p], @handler.events.shift
473
+ end
474
+
475
+ def pop_text
476
+ result = ''
477
+ while ! @handler.events.empty? && @handler.events[0][0] == :text
478
+ result << @handler.events[0][1]
479
+ @handler.events.shift
480
+ end
481
+ result
482
+ end
483
+
484
+ class EventHandler
485
+ attr_reader :events
486
+ def initialize
487
+ @events = []
488
+ end
489
+
490
+ def start_tag(sym, attrs)
491
+ @events << [:start, sym, attrs]
492
+ end
493
+
494
+ def end_tag(sym)
495
+ @events << [:end, sym]
496
+ end
497
+
498
+ def text(txt)
499
+ @events << [:text, txt]
500
+ end
501
+ end
502
+ end
503
+
504
+ end
505
+