wax 0.9.5 → 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -6,11 +6,25 @@ class Address
6
6
  end
7
7
 
8
8
  def to_xml(wax)
9
- wax.start('address').
10
- child('street', @street).
11
- child('city', @city).
12
- child('state', @state).
13
- child('zip', @zip).
9
+ # Chaining approach
10
+ #wax.start('address').
11
+ # child('street', @street).
12
+ # child('city', @city).
13
+ # child('state', @state).
14
+ # child('zip', @zip).
15
+ # end!
16
+
17
+ # Non-chaining approach
18
+ # Put the current object in a local variable
19
+ # so it can be accessed in the block passed to the write method.
20
+ address = self
21
+ wax.write do
22
+ start 'address'
23
+ child 'street', address.street
24
+ child 'city', address.city
25
+ child 'state', address.state
26
+ child 'zip', address.zip
14
27
  end!
28
+ end
15
29
  end
16
30
  end
data/lib/car.rb CHANGED
@@ -6,10 +6,23 @@ class Car
6
6
  end
7
7
 
8
8
  def to_xml(wax)
9
- wax.start('car').attr('year', @year).
10
- child('make', @make).
11
- child('model', @model).
9
+ # Chaining approach
10
+ #wax.start('car').attr('year', @year).
11
+ # child('make', @make).
12
+ # child('model', @model).
13
+ # end!
14
+
15
+ # Non-chaining approach
16
+ # Put the current object in a local variable
17
+ # so it can be accessed in the block passed to the write method.
18
+ car = self
19
+ wax.write do
20
+ start 'car'
21
+ attr 'year', car.year
22
+ child 'make', car.make
23
+ child 'model', car.model
12
24
  end!
25
+ end
13
26
  end
14
27
  end
15
28
 
@@ -2,15 +2,15 @@ require 'wax'
2
2
 
3
3
  url = "http://www.ociweb.com"
4
4
  WAX.write($stdout, "1.0") do
5
+ xslt "artist.xslt"
6
+ dtd "#{url}/xml/music.dtd"
7
+ start "artist"
8
+ attr "name", "Gardot, Melody"
9
+ namespace nil, "#{url}/music", "#{url}/xml/music.xsd"
10
+ namespace "date", "#{url}/date", "#{url}/xml/date.xsd"
5
11
  comment "This is one of my favorite CDs!"
6
- dtd "#{url}/xml/cd.dtd"
7
- xslt "cd.xslt"
8
12
  start "cd"
9
13
  attr "year", 2008
10
- namespace nil, "#{url}/music", "#{url}/xml/cd.xsd"
11
- namespace "date", "#{url}/date", "#{url}/xml/date.xsd"
12
- start "artist"
13
- attr "name", "Gardot, Melody"
14
14
  child "title", "Worrisome Heart"
15
15
  child "date", "purchaseDate", "4/3/2008"
16
16
  end
@@ -6,13 +6,27 @@ class Person
6
6
  end
7
7
 
8
8
  def to_xml(wax)
9
- wax.start('person').attr('birthdate', @birthdate).child('name', @name)
10
- @address.to_xml(wax)
11
- wax.end!
9
+ # Chaining approach
10
+ #wax.start('person').attr('birthdate', @birthdate).child('name', @name)
11
+ #@address.to_xml(wax)
12
+ #wax.end!
13
+
14
+ # Non-chaining approach
15
+ # Put the current object in a local variable
16
+ # so it can be accessed in the block passed to the write method.
17
+ person = self
18
+ wax.write do
19
+ start 'person'
20
+ attr 'birthdate', person.birthdate
21
+ child 'name', person.name
22
+ person.address.to_xml(self) # self is the WAX object here
23
+ end!
24
+ end
12
25
  end
13
26
  end
14
27
 
15
- if $PROGRAM_NAME == __FILE__ || $PROGRAM_NAME =~ /\/rake/
28
+ if $PROGRAM_NAME == __FILE__
29
+ # || $PROGRAM_NAME =~ /\/rake/
16
30
  require 'address'
17
31
  require 'wax'
18
32
 
@@ -53,7 +53,7 @@ end
53
53
 
54
54
  out 'Without indentation, on a single line:'
55
55
  WAX.write do
56
- set_indent nil
56
+ no_indents_or_crs
57
57
  start 'car'
58
58
  child 'model', 'Prius'
59
59
  end
@@ -155,7 +155,7 @@ out 'Associate an XML Schema:'
155
155
  WAX.write do
156
156
  start 'car'
157
157
  attr 'year', 2008
158
- namespace nil, 'http://www.ociweb.com/cars', 'car.xsd'
158
+ namespace '', 'http://www.ociweb.com/cars', 'car.xsd'
159
159
  child 'model', 'Prius'
160
160
  end
161
161
  # <car year='2008'
@@ -169,7 +169,7 @@ out 'Associate multiple XML Schemas:'
169
169
  WAX.write do
170
170
  start 'car'
171
171
  attr 'year', 2008
172
- namespace nil, 'http://www.ociweb.com/cars', 'car.xsd'
172
+ namespace '', 'http://www.ociweb.com/cars', 'car.xsd'
173
173
  namespace 'm', 'http://www.ociweb.com/model', 'model.xsd'
174
174
  child 'm', 'model', 'Prius'
175
175
  end
data/lib/wax.rb CHANGED
@@ -32,6 +32,11 @@ class WAX
32
32
  # If they are, a RuntimeError is raised.
33
33
  STATES = [:in_prolog, :in_start_tag, :in_element, :after_root]
34
34
 
35
+ NONWINDOWS_CR = "\n"
36
+ WINDOWS_CR = "\r\n"
37
+
38
+ attr_reader :state
39
+
35
40
  # Creates a WAX object, invokes the specified block on it
36
41
  # and calls close on the WAX object.
37
42
  # The writer can be a String file path, an IO object such as a File,
@@ -42,6 +47,11 @@ class WAX
42
47
  wax = WAX.new(writer, version)
43
48
  wax.instance_exec(&proc)
44
49
  wax.close
50
+ wax # return instance so caller can get configuration info. like @cr
51
+ end
52
+
53
+ def write(writer=$stdout, version=nil, &proc)
54
+ instance_eval(&proc)
45
55
  end
46
56
 
47
57
  # Initializes new instances of this class.
@@ -49,6 +59,8 @@ class WAX
49
59
  @attr_on_new_line = false
50
60
  @check_me = true
51
61
  @close_stream = writer != $stdout
62
+ @dtd_specified = false
63
+ @in_commented_start = false
52
64
  @dtd_file_path = nil
53
65
  @entity_defs = []
54
66
  @has_content = @has_indented_content = false
@@ -59,6 +71,8 @@ class WAX
59
71
  @prefixes_stack = []
60
72
  @state = :in_prolog
61
73
  @writer = writer
74
+ @xslt_specified = false
75
+ use_non_windows_cr
62
76
  write_xml_declaration(version)
63
77
  end
64
78
 
@@ -69,9 +83,9 @@ class WAX
69
83
  # to indicate whether the attribute should be written on a new line.
70
84
  def attr(p1, p2, p3=nil, p4=nil)
71
85
  if (p3 == nil)
72
- prefix, name, value, new_line = nil, p1, p2, false
86
+ prefix, name, value, new_line = nil, p1, p2, @attr_on_new_line
73
87
  elsif (p4 == nil)
74
- prefix, name, value, new_line = p1, p2, p3, false
88
+ prefix, name, value, new_line = p1, p2, p3, @attr_on_new_line
75
89
  else
76
90
  prefix, name, value, new_line = p1, p2, p3, p4
77
91
  end
@@ -80,11 +94,11 @@ class WAX
80
94
  bad_state("attr") unless @state == :in_start_tag
81
95
 
82
96
  unless prefix == nil
83
- XMLUtil.verify_nmtoken(prefix)
97
+ XMLUtil.verify_name(prefix)
84
98
  @pending_prefixes << prefix
85
99
  end
86
100
 
87
- XMLUtil.verify_nmtoken(name)
101
+ XMLUtil.verify_name(name)
88
102
  value = XMLUtil.escape(value)
89
103
  end
90
104
 
@@ -168,19 +182,40 @@ class WAX
168
182
  write_indent if @parent_stack.size > 0
169
183
 
170
184
  out "<!-- #{text} -->"
171
- out "\n" if will_indent and @parent_stack.size == 0
185
+ out "#{@cr}" if will_indent and @parent_stack.size == 0
186
+
187
+ self
188
+ end
189
+
190
+ # Writes a commented start tag for a given element name,
191
+ # but doesn't terminate it.
192
+ def commented_start(p1, p2=nil)
193
+ if (p2 == nil)
194
+ # only specified element name
195
+ prefix, name = nil, p1
196
+ else
197
+ # specified element namespace prefix, name and text
198
+ prefix, name = p1, p2
199
+ end
200
+
201
+ @in_commented_start = true
202
+ start(prefix, name)
203
+ @in_commented_start = false
172
204
 
173
205
  self
174
206
  end
175
207
 
176
208
  # Writes a DOCTYPE that associates a DTD with the XML document.
177
209
  def dtd(file_path)
210
+ raise "can't specify more than one DTD" if @dtd_specified
211
+
178
212
  if @check_me
179
213
  bad_state("dtd") unless @state == :in_prolog
180
214
  XMLUtil.verify_uri(file_path)
181
215
  end
182
216
 
183
217
  @dtd_file_path = file_path
218
+ @dtd_specified = true
184
219
  self
185
220
  end
186
221
 
@@ -202,11 +237,17 @@ class WAX
202
237
  # are no longer in scope.
203
238
  @prefixes_stack.pop
204
239
 
240
+ # Check for hypen at beginning of element name
241
+ # which indicates that the commentedStart method was used.
242
+ was_commented_start = name[0] == '-'[0]
243
+
205
244
  if @has_content
206
245
  write_indent if @has_indented_content
207
- out "</#{name}>"
246
+ out '</'
247
+ out was_commented_start ? name[1..-1] : name
248
+ out was_commented_start ? '-->' : '>'
208
249
  else
209
- out "/>"
250
+ out was_commented_start ? '/-->' : '/>'
210
251
  end
211
252
 
212
253
  @has_content = @has_indented_content = true # new setting for parent
@@ -228,6 +269,11 @@ class WAX
228
269
  entity_def(name + " SYSTEM", file_path)
229
270
  end
230
271
 
272
+ # Gets the carriage return characters currently being used.
273
+ def get_cr
274
+ @cr
275
+ end
276
+
231
277
  # Gets the indentation characters being used.
232
278
  def get_indent
233
279
  @indent
@@ -277,7 +323,7 @@ class WAX
277
323
  if @check_me
278
324
  bad_state("namespace") unless @state == :in_start_tag
279
325
 
280
- XMLUtil.verify_nmtoken(prefix) if has_prefix
326
+ XMLUtil.verify_name(prefix) if has_prefix
281
327
  XMLUtil.verify_uri(uri)
282
328
  XMLUtil.verify_uri(schema_path) unless schema_path == nil
283
329
  end
@@ -321,11 +367,26 @@ class WAX
321
367
  text text, true, @check_me
322
368
  end
323
369
 
370
+ # Don't output indent output or write carriage returns.
371
+ # Write out the XML on a single line.
372
+ def no_indents_or_crs
373
+ set_indent nil
374
+ end
375
+
376
+ # Writes the to_s value of an Object to the writer.
377
+ def out(data)
378
+ raise "attempting to out XML after close has been called" unless @writer
379
+ @writer.write(data.to_s)
380
+ end
381
+
324
382
  # Writes a processing instruction.
325
383
  def processing_instruction(target, data)
326
384
  if @check_me
327
385
  bad_state("pi") if @state == :after_root
328
- XMLUtil.verify_nmtoken(target)
386
+
387
+ # Special handling for this processing instruction
388
+ # since starting with "xml" is reserved.
389
+ XMLUtil.verify_name(target) unless target == "xml-stylesheet"
329
390
  end
330
391
 
331
392
  @has_content = @has_indented_content = true
@@ -333,17 +394,17 @@ class WAX
333
394
  write_indent if @parent_stack.size > 0
334
395
 
335
396
  out "<?#{target} #{data}?>"
336
- out("\n") if will_indent and @parent_stack.size == 0
397
+ out("#{@cr}") if will_indent and @parent_stack.size == 0
337
398
 
338
399
  self
339
400
  end
340
401
 
341
402
  # Sets the indentation characters to use.
342
403
  # The only valid values are
343
- # a single tab, one or more spaces, an empty string, or null.
404
+ # a single tab, one or more spaces, an empty string, or nil.
344
405
  # Passing "" causes elements to be output on separate lines,
345
406
  # but not indented.
346
- # Passing null causes all output to be on a single line.
407
+ # Passing nil causes all output to be on a single line.
347
408
  def set_indent(indent)
348
409
  if indent == nil
349
410
  @indent = indent
@@ -355,7 +416,7 @@ class WAX
355
416
  raise ArgumentError, "can't indent a negative number of spaces"
356
417
  end
357
418
 
358
- if count > 4
419
+ if @check_me && count > 4
359
420
  raise ArgumentError, "#{count} is an unreasonable indentation"
360
421
  end
361
422
 
@@ -364,23 +425,27 @@ class WAX
364
425
  return
365
426
 
366
427
  elsif indent.kind_of?(String)
367
- # Note that the parens on the next line are necessary
368
- # because the assignment operator has higher precedence than "or".
369
- valid = (indent == nil or indent.length == 0 or indent == "\t")
370
-
371
- unless valid
372
- # It can only be valid now if every character is a space.
373
- valid = true
374
- for i in 0...indent.length
375
- unless indent[i] == 32 # space
376
- valid = false
377
- break
428
+ if @check_me
429
+ # Note that the parens on the next line are necessary
430
+ # because the assignment operator has higher precedence than "or".
431
+ valid = (indent == nil or indent.length == 0 or indent == "\t")
432
+
433
+ unless valid
434
+ # It can only be valid now if every character is a space.
435
+ valid = true
436
+ for i in 0...indent.length
437
+ unless indent[i] == 32 # space
438
+ valid = false
439
+ break
440
+ end
378
441
  end
379
442
  end
443
+
444
+ if !valid or (indent != nil and indent.length > 4)
445
+ raise ArgumentError, "invalid indent value #{indent}"
446
+ end
380
447
  end
381
448
 
382
- raise ArgumentError, "invalid indent value #{indent}" unless valid
383
-
384
449
  @indent = indent
385
450
 
386
451
  else
@@ -420,10 +485,10 @@ class WAX
420
485
  if @check_me
421
486
  bad_state("start") if @state == :after_root
422
487
  if prefix != nil
423
- XMLUtil.verify_nmtoken(prefix)
488
+ XMLUtil.verify_name(prefix)
424
489
  @pending_prefixes << prefix
425
490
  end
426
- XMLUtil.verify_nmtoken(name)
491
+ XMLUtil.verify_name(name)
427
492
  end
428
493
 
429
494
  # If this is the root element ...
@@ -438,9 +503,15 @@ class WAX
438
503
  has_prefix = prefix != nil and prefix.length > 0
439
504
  qname = has_prefix ? prefix + ':' + name : name
440
505
 
441
- out '<' + qname
442
-
443
- @parent_stack.push(qname)
506
+ if (@in_commented_start)
507
+ out '<!--' + qname
508
+ # Add a "marker" to the element name on the stack
509
+ # so the end method knows to terminate the comment.
510
+ @parent_stack.push('-' + qname)
511
+ else
512
+ out '<' + qname
513
+ @parent_stack.push(qname)
514
+ end
444
515
 
445
516
  # No namespace prefixes have been associated with this element yet.
446
517
  @prefixes_stack.push(nil)
@@ -478,12 +549,26 @@ class WAX
478
549
  text = XMLUtil.escape(text) if escape
479
550
  out text
480
551
  elsif newline
481
- out "\n"
552
+ out "#{@cr}"
482
553
  end
483
554
 
484
555
  self
485
556
  end
486
557
 
558
+ # Uses #{@cr} for carriage returns which is appropriate
559
+ # on every platform except Windows.
560
+ # Note that this is the default.
561
+ def use_non_windows_cr
562
+ @cr = NONWINDOWS_CR
563
+ end
564
+
565
+ # Uses \r#{@cr} for carriage returns which is appropriate
566
+ # only on the Windows platform.
567
+ # Note that this is not the default.
568
+ def use_windows_cr
569
+ @cr = WINDOWS_CR
570
+ end
571
+
487
572
  # Verifies that all the pending namespace prefix are currently in scope.
488
573
  # ArgumentError is raises if any aren't in scope.
489
574
  def verify_prefixes
@@ -502,12 +587,6 @@ class WAX
502
587
  @indent != nil
503
588
  end
504
589
 
505
- # Writes the to_s value of an Object to the writer.
506
- def out(data)
507
- raise "attempting to out XML after close has been called" unless @writer
508
- @writer.write(data.to_s)
509
- end
510
-
511
590
  # Writes a DOCTYPE.
512
591
  def write_doctype(root_element_name)
513
592
  return if @dtd_file_path == nil and @entity_defs.empty?
@@ -519,25 +598,25 @@ class WAX
519
598
  out " ["
520
599
 
521
600
  @entity_defs.each do |entity_def|
522
- out "\n" + @indent if will_indent
601
+ out "#{@cr}" + @indent if will_indent
523
602
  out "<!ENTITY #{entity_def}>"
524
603
  end
525
604
 
526
- out "\n" if will_indent
605
+ out "#{@cr}" if will_indent
527
606
  out ']'
528
607
 
529
608
  @entity_defs.clear
530
609
  end
531
610
 
532
611
  out '>'
533
- out "\n" if will_indent
612
+ out "#{@cr}" if will_indent
534
613
  end
535
614
 
536
615
  # Writes the proper amount of indentation
537
616
  # given the current nesting of elements.
538
617
  def write_indent
539
618
  return unless will_indent
540
- out "\n"
619
+ out "#{@cr}"
541
620
  for i in 0...@parent_stack.size
542
621
  out @indent
543
622
  end
@@ -554,7 +633,7 @@ class WAX
554
633
  @namespace_uri_to_schema_path_map.each_pair do |uri, path|
555
634
  if schema_location.length > 0 # not first pair output
556
635
  if will_indent
557
- schema_location << "\n"
636
+ schema_location << "#{@cr}"
558
637
  for i in 0..@parent_stack.size
559
638
  schema_location << @indent
560
639
  end
@@ -580,20 +659,22 @@ class WAX
580
659
  XMLUtil.verify_version(version) if @check_me
581
660
 
582
661
  out "<?xml version=\"#{version}\" " +
583
- "encoding=\"#{XMLUtil::DEFAULT_ENCODING}\"?>\n"
662
+ "encoding=\"#{XMLUtil::DEFAULT_ENCODING}\"?>#{@cr}"
584
663
  end
585
664
 
586
665
  # Writes an "xml-stylesheet" processing instruction.
587
666
  def xslt(file_path)
667
+ raise "can't specify more than one XSLT" if @xslt_specified
668
+
588
669
  if @check_me
589
670
  bad_state("xslt") unless @state == :in_prolog
590
671
  XMLUtil.verify_uri(file_path)
591
672
  end
592
673
 
593
- @state = :in_prolog
594
-
595
674
  processing_instruction("xml-stylesheet",
596
675
  "type=\"text/xsl\" href=\"#{file_path}\"")
676
+
677
+ @xslt_specified = true
597
678
  end
598
679
 
599
680
  private :bad_state, :is_in_scope_prefix, :terminate_start,
@@ -23,7 +23,113 @@ module XMLUtil
23
23
  # The default encoding used in XML declarations.
24
24
  DEFAULT_ENCODING = "UTF-8"
25
25
 
26
- NMTOKEN_PATTERN = /^[A-Za-z][A-Za-z0-9\-_\.]*$/
26
+ # The following regular expressions
27
+ # were taken from the W3C XML Recommenation:
28
+ BASE_CHAR_PATTERN =
29
+ "[\u0041-\u005A]|[\u0061-\u007A]|[\u00C0-\u00D6]|[\u00D8-\u00F6]|" +
30
+ "[\u00F8-\u00FF]|[\u0100-\u0131]|[\u0134-\u013E]|[\u0141-\u0148]|" +
31
+ "[\u014A-\u017E]|[\u0180-\u01C3]|[\u01CD-\u01F0]|[\u01F4-\u01F5]|" +
32
+ "[\u01FA-\u0217]|[\u0250-\u02A8]|[\u02BB-\u02C1]|\u0386|" +
33
+ "[\u0388-\u038A]|\u038C|[\u038E-\u03A1]|[\u03A3-\u03CE]|" +
34
+ "[\u03D0-\u03D6]|\u03DA|\u03DC|\u03DE|\u03E0|[\u03E2-\u03F3]|" +
35
+ "[\u0401-\u040C]|[\u040E-\u044F]|[\u0451-\u045C]|[\u045E-\u0481]|" +
36
+ "[\u0490-\u04C4]|[\u04C7-\u04C8]|[\u04CB-\u04CC]|[\u04D0-\u04EB]|" +
37
+ "[\u04EE-\u04F5]|[\u04F8-\u04F9]|[\u0531-\u0556]|\u0559|" +
38
+ "[\u0561-\u0586]|[\u05D0-\u05EA]|[\u05F0-\u05F2]|[\u0621-\u063A]|" +
39
+ "[\u0641-\u064A]|[\u0671-\u06B7]|[\u06BA-\u06BE]|[\u06C0-\u06CE]|" +
40
+ "[\u06D0-\u06D3]|\u06D5|[\u06E5-\u06E6]|[\u0905-\u0939]|" +
41
+ "\u093D|[\u0958-\u0961]|[\u0985-\u098C]|[\u098F-\u0990]|" +
42
+ "[\u0993-\u09A8]|[\u09AA-\u09B0]|\u09B2|[\u09B6-\u09B9]|" +
43
+ "[\u09DC-\u09DD]|[\u09DF-\u09E1]|[\u09F0-\u09F1]|[\u0A05-\u0A0A]|" +
44
+ "[\u0A0F-\u0A10]|[\u0A13-\u0A28]|[\u0A2A-\u0A30]|[\u0A32-\u0A33]|" +
45
+ "[\u0A35-\u0A36]|[\u0A38-\u0A39]|[\u0A59-\u0A5C]|\u0A5E|" +
46
+ "[\u0A72-\u0A74]|[\u0A85-\u0A8B]|\u0A8D|[\u0A8F-\u0A91]|" +
47
+ "[\u0A93-\u0AA8]|[\u0AAA-\u0AB0]|[\u0AB2-\u0AB3]|[\u0AB5-\u0AB9]|" +
48
+ "\u0ABD|\u0AE0|[\u0B05-\u0B0C]|[\u0B0F-\u0B10]|[\u0B13-\u0B28]|" +
49
+ "[\u0B2A-\u0B30]|[\u0B32-\u0B33]|[\u0B36-\u0B39]|\u0B3D|" +
50
+ "[\u0B5C-\u0B5D]|[\u0B5F-\u0B61]|[\u0B85-\u0B8A]|[\u0B8E-\u0B90]|" +
51
+ "[\u0B92-\u0B95]|[\u0B99-\u0B9A]|\u0B9C|[\u0B9E-\u0B9F]|" +
52
+ "[\u0BA3-\u0BA4]|[\u0BA8-\u0BAA]|[\u0BAE-\u0BB5]|[\u0BB7-\u0BB9]|" +
53
+ "[\u0C05-\u0C0C]|[\u0C0E-\u0C10]|[\u0C12-\u0C28]|[\u0C2A-\u0C33]|" +
54
+ "[\u0C35-\u0C39]|[\u0C60-\u0C61]|[\u0C85-\u0C8C]|[\u0C8E-\u0C90]|" +
55
+ "[\u0C92-\u0CA8]|[\u0CAA-\u0CB3]|[\u0CB5-\u0CB9]|\u0CDE|" +
56
+ "[\u0CE0-\u0CE1]|[\u0D05-\u0D0C]|[\u0D0E-\u0D10]|[\u0D12-\u0D28]|" +
57
+ "[\u0D2A-\u0D39]|[\u0D60-\u0D61]|[\u0E01-\u0E2E]|\u0E30|" +
58
+ "[\u0E32-\u0E33]|[\u0E40-\u0E45]|[\u0E81-\u0E82]|\u0E84|" +
59
+ "[\u0E87-\u0E88]|\u0E8A|\u0E8D|[\u0E94-\u0E97]|[\u0E99-\u0E9F]|" +
60
+ "[\u0EA1-\u0EA3]|\u0EA5|\u0EA7|[\u0EAA-\u0EAB]|[\u0EAD-\u0EAE]|" +
61
+ "\u0EB0|[\u0EB2-\u0EB3]|\u0EBD|[\u0EC0-\u0EC4]|[\u0F40-\u0F47]|" +
62
+ "[\u0F49-\u0F69]|[\u10A0-\u10C5]|[\u10D0-\u10F6]|\u1100|" +
63
+ "[\u1102-\u1103]|[\u1105-\u1107]|\u1109|[\u110B-\u110C]|" +
64
+ "[\u110E-\u1112]|\u113C|\u113E|\u1140|\u114C|\u114E|\u1150|" +
65
+ "[\u1154-\u1155]|\u1159|[\u115F-\u1161]|\u1163|\u1165|\u1167|" +
66
+ "\u1169|[\u116D-\u116E]|[\u1172-\u1173]|\u1175|\u119E|\u11A8|" +
67
+ "\u11AB|[\u11AE-\u11AF]|[\u11B7-\u11B8]|\u11BA|[\u11BC-\u11C2]|" +
68
+ "\u11EB|\u11F0|\u11F9|[\u1E00-\u1E9B]|[\u1EA0-\u1EF9]|" +
69
+ "[\u1F00-\u1F15]|[\u1F18-\u1F1D]|[\u1F20-\u1F45]|[\u1F48-\u1F4D]|" +
70
+ "[\u1F50-\u1F57]|\u1F59|\u1F5B|\u1F5D|[\u1F5F-\u1F7D]|" +
71
+ "[\u1F80-\u1FB4]|[\u1FB6-\u1FBC]|\u1FBE|[\u1FC2-\u1FC4]|" +
72
+ "[\u1FC6-\u1FCC]|[\u1FD0-\u1FD3]|[\u1FD6-\u1FDB]|[\u1FE0-\u1FEC]|" +
73
+ "[\u1FF2-\u1FF4]|[\u1FF6-\u1FFC]|\u2126|[\u212A-\u212B]|\u212E|" +
74
+ "[\u2180-\u2182]|[\u3041-\u3094]|[\u30A1-\u30FA]|[\u3105-\u312C]|" +
75
+ "[\uAC00-\uD7A3]"
76
+
77
+ COMBINING_CHAR_PATTERN =
78
+ "[\u0300-\u0345]|[\u0360-\u0361]|[\u0483-\u0486]|[\u0591-\u05A1]|" +
79
+ "[\u05A3-\u05B9]|[\u05BB-\u05BD]|\u05BF|[\u05C1-\u05C2]|\u05C4|" +
80
+ "[\u064B-\u0652]|\u0670|[\u06D6-\u06DC]|[\u06DD-\u06DF]|" +
81
+ "[\u06E0-\u06E4]|[\u06E7-\u06E8]|[\u06EA-\u06ED]|[\u0901-\u0903]|" +
82
+ "\u093C|[\u093E-\u094C]|\u094D|[\u0951-\u0954]|[\u0962-\u0963]|" +
83
+ "[\u0981-\u0983]|\u09BC|\u09BE|\u09BF|[\u09C0-\u09C4]|" +
84
+ "[\u09C7-\u09C8]|[\u09CB-\u09CD]|\u09D7|[\u09E2-\u09E3]|\u0A02|" +
85
+ "\u0A3C|\u0A3E|\u0A3F|[\u0A40-\u0A42]|[\u0A47-\u0A48]|" +
86
+ "[\u0A4B-\u0A4D]|[\u0A70-\u0A71]|[\u0A81-\u0A83]|\u0ABC|" +
87
+ "[\u0ABE-\u0AC5]|[\u0AC7-\u0AC9]|[\u0ACB-\u0ACD]|[\u0B01-\u0B03]|" +
88
+ "\u0B3C|[\u0B3E-\u0B43]|[\u0B47-\u0B48]|[\u0B4B-\u0B4D]|" +
89
+ "[\u0B56-\u0B57]|[\u0B82-\u0B83]|[\u0BBE-\u0BC2]|[\u0BC6-\u0BC8]|" +
90
+ "[\u0BCA-\u0BCD]|\u0BD7|[\u0C01-\u0C03]|[\u0C3E-\u0C44]|" +
91
+ "[\u0C46-\u0C48]|[\u0C4A-\u0C4D]|[\u0C55-\u0C56]|[\u0C82-\u0C83]|" +
92
+ "[\u0CBE-\u0CC4]|[\u0CC6-\u0CC8]|[\u0CCA-\u0CCD]|[\u0CD5-\u0CD6]|" +
93
+ "[\u0D02-\u0D03]|[\u0D3E-\u0D43]|[\u0D46-\u0D48]|[\u0D4A-\u0D4D]|" +
94
+ "\u0D57|\u0E31|[\u0E34-\u0E3A]|[\u0E47-\u0E4E]|\u0EB1|" +
95
+ "[\u0EB4-\u0EB9]|[\u0EBB-\u0EBC]|[\u0EC8-\u0ECD]|[\u0F18-\u0F19]|" +
96
+ "\u0F35|\u0F37|\u0F39|\u0F3E|\u0F3F|[\u0F71-\u0F84]|" +
97
+ "[\u0F86-\u0F8B]|[\u0F90-\u0F95]|\u0F97|[\u0F99-\u0FAD]|" +
98
+ "[\u0FB1-\u0FB7]|\u0FB9|[\u20D0-\u20DC]|\u20E1|[\u302A-\u302F]|" +
99
+ "\u3099|\u309A"
100
+
101
+ DIGIT_PATTERN =
102
+ "[\u0030-\u0039]|[\u0660-\u0669]|[\u06F0-\u06F9]|"+
103
+ "[\u0966-\u096F]|[\u09E6-\u09EF]|[\u0A66-\u0A6F]|"+
104
+ "[\u0AE6-\u0AEF]|[\u0B66-\u0B6F]|[\u0BE7-\u0BEF]|"+
105
+ "[\u0C66-\u0C6F]|[\u0CE6-\u0CEF]|[\u0D66-\u0D6F]|"+
106
+ "[\u0E50-\u0E59]|[\u0ED0-\u0ED9]|[\u0F20-\u0F29]"
107
+
108
+ EXTENDER_PATTERN =
109
+ "\u00B7|\u02D0|\u02D1|\u0387|\u0640|\u0E46|\u0EC6|\u3005|" +
110
+ "[\u3031-\u3035]|[\u309D-\u309E]|[\u30FC-\u30FE]"
111
+
112
+ IDEOGRAPHIC_PATTERN = "[\u4E00-\u9FA5]|\u3007|[\u3021-\u3029]"
113
+
114
+ LETTER_PATTERN = BASE_CHAR_PATTERN + "|" + IDEOGRAPHIC_PATTERN
115
+
116
+ NAME_CHAR_PATTERN =
117
+ LETTER_PATTERN + "|" +
118
+ DIGIT_PATTERN + "|" +
119
+ "'.'|'-'|'_'|':'|" +
120
+ COMBINING_CHAR_PATTERN + "|" +
121
+ EXTENDER_PATTERN
122
+
123
+ # Element and attribute names must be name tokens.
124
+ # This is a regular expression used to determine whether a given string
125
+ # is a valid XML "name token" using only Latin characters.
126
+ LATIN_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9\-_\.]*$/
127
+
128
+ # Element and attribute names must be name tokens.
129
+ # This is a regular expression used to determine whether a given string
130
+ # is a valid XML "name token" using any valid Unicode characters.
131
+ FULL_NAME_PATTERN = /^(#{LETTER_PATTERN}|'_')(#{NAME_CHAR_PATTERN})*$/
132
+
27
133
  XMLSCHEMA_INSTANCE_NS = "http://www.w3.org/1999/XMLSchema-instance"
28
134
 
29
135
  # Escapes special characters in XML text.
@@ -57,15 +163,36 @@ module XMLUtil
57
163
  end
58
164
 
59
165
  # Determines whether given text is a name token.
60
- def self.is_nmtoken(text)
166
+ def self.is_name(text)
61
167
  return false if text == nil
62
- (NMTOKEN_PATTERN =~ text) != nil
168
+
169
+ # Names that start with "XML" in any case are reserved.
170
+ return false if text.downcase =~ /$xml/
171
+
172
+ # First attempt to match against the simpler regular expression
173
+ # for names that only use Latin characters
174
+ # because this should be faster and the most common case.
175
+ return true if (LATIN_NAME_PATTERN =~ text) != nil
176
+
177
+ # Since that didn't match, try the full regular expression.
178
+ # Ruby 1.8 doesn't support Unicode in regular expressions!
179
+ # Save this code for Ruby 1.9.
180
+ #matched_full = (FULL_NAME_PATTERN =~ text) != nil
181
+ #puts "#{text} matched full? #{matched_full}"
182
+ #matched_letter = (/^(#{LETTER_PATTERN}|'_')/ =~ text) != nil
183
+ #puts "#{text} matched letter? #{matched_letter}"
184
+
185
+ false
63
186
  end
64
187
 
65
188
  # Determines whether given text is a URI.
66
189
  def self.is_uri(text)
67
- # TODO: Finish this
68
- true
190
+ begin
191
+ uri = URI.parse(text)
192
+ true
193
+ rescue URI::InvalidURIError
194
+ false
195
+ end
69
196
  end
70
197
 
71
198
  # Determines whether given text is a valid XML version.
@@ -83,8 +210,8 @@ module XMLUtil
83
210
 
84
211
  # Verifies that the given text is a valid name token
85
212
  # and raises an ArgumentError if it isn't.
86
- def self.verify_nmtoken(text)
87
- unless is_nmtoken(text)
213
+ def self.verify_name(text)
214
+ unless is_name(text)
88
215
  raise ArgumentError, "\"#{text}\" is an invalid NMTOKEN"
89
216
  end
90
217
  end
@@ -105,4 +232,4 @@ module XMLUtil
105
232
  end
106
233
  end
107
234
 
108
- end
235
+ end
@@ -41,14 +41,25 @@ class WAXTest < Test::Unit::TestCase
41
41
  end
42
42
 
43
43
  def test_attributes
44
- WAX.write do
45
- set_indent nil
44
+ wax = WAX.write do
46
45
  start 'root'
46
+ namespace 'foo', 'http://www.ociweb.com/foo'
47
47
  attr 'a1', 'v1'
48
48
  attr 'a2', 2
49
+ attr 'foo', 'a3', 'bar'
50
+ attr 'foo', 'a4', 'baz', true
49
51
  end
50
52
 
51
- assert_equal '<root a1="v1" a2="2"/>', @sio.string
53
+ cr = wax.get_cr
54
+ xml =
55
+ '<root' + cr +
56
+ ' xmlns:foo="http://www.ociweb.com/foo"' + cr +
57
+ ' a1="v1"' + cr +
58
+ ' a2="2"' + cr +
59
+ ' foo:a3="bar"' + cr +
60
+ ' foo:a4="baz"/>'
61
+
62
+ assert_equal xml, @sio.string
52
63
  end
53
64
 
54
65
  def test_bad_attribute_name
@@ -121,6 +132,15 @@ class WAXTest < Test::Unit::TestCase
121
132
  end
122
133
  end
123
134
 
135
+ def test_bad_dtd_multiple
136
+ assert_raise(RuntimeError) do
137
+ WAX.write do
138
+ dtd "one.dtd"
139
+ dtd "two.dtd" # can't specify two DTDs
140
+ end
141
+ end
142
+ end
143
+
124
144
  def test_bad_element_name
125
145
  assert_raise(ArgumentError) do
126
146
  WAX.write { start "1root" }
@@ -159,6 +179,12 @@ class WAXTest < Test::Unit::TestCase
159
179
  end
160
180
  end
161
181
 
182
+ def test_bad_indent_datatype
183
+ assert_raise(ArgumentError) do
184
+ WAX.write { set_indent Time.now } # invalid type of object
185
+ end
186
+ end
187
+
162
188
  def test_bad_namespace_duplicate_prefix
163
189
  assert_raise(ArgumentError) do
164
190
  # Can't define same namespace prefix more than once in the same scope.
@@ -228,8 +254,17 @@ class WAXTest < Test::Unit::TestCase
228
254
  end
229
255
  end
230
256
 
257
+ def test_bad_xslt_multiple
258
+ assert_raise(RuntimeError) do
259
+ WAX.write do
260
+ xslt "one.xslt"
261
+ xslt "two.xstl" # can't specify two XSLTs
262
+ end
263
+ end
264
+ end
265
+
231
266
  def test_big
232
- WAX.write do
267
+ wax = WAX.write do
233
268
  start "root"
234
269
  nl_text "text #1"
235
270
  child "child1", "text"
@@ -240,69 +275,112 @@ class WAXTest < Test::Unit::TestCase
240
275
  nl_text "text #3"
241
276
  end
242
277
 
243
- xml = "<root>\n" +
244
- " text #1\n" +
245
- " <child1>text</child1>\n" +
246
- " text #2\n" +
247
- " <child2 a1=\"v1\"/>\n" +
248
- " text #3\n" +
278
+ cr = wax.get_cr
279
+ xml = "<root>" + cr +
280
+ " text #1" + cr +
281
+ " <child1>text</child1>" + cr +
282
+ " text #2" + cr +
283
+ " <child2 a1=\"v1\"/>" + cr +
284
+ " text #3" + cr +
249
285
  "</root>"
250
286
 
251
287
  assert_equal xml, @sio.string
252
288
  end
253
289
 
254
290
  def test_blank_line
255
- WAX.write do
291
+ wax = WAX.write do
256
292
  start "root"
257
293
  blank_line
258
294
  end
259
295
 
296
+ cr = wax.get_cr
260
297
  xml =
261
- "<root>\n" +
262
- "\n" +
298
+ "<root>" + cr +
299
+ "" + cr +
263
300
  "</root>"
264
301
  assert_equal xml, @sio.string
265
302
  end
266
303
 
267
304
  def test_cdata
268
- WAX.write do
305
+ wax = WAX.write do
269
306
  start "root"
270
307
  cdata "1<2>3&4'5\"6"
271
308
  end
272
309
 
310
+ cr = wax.get_cr
273
311
  xml =
274
- "<root>\n" +
275
- " <![CDATA[1<2>3&4'5\"6]]>\n" +
312
+ "<root>" + cr +
313
+ " <![CDATA[1<2>3&4'5\"6]]>" + cr +
276
314
  "</root>"
277
315
  assert_equal xml, @sio.string
278
316
  end
279
317
 
280
318
  def test_comment
281
- WAX.write do
319
+ wax = WAX.write do
282
320
  comment "comment #1"
283
321
  comment "comment #2"
284
322
  start "root"
285
323
  comment "comment #3"
286
324
  end
287
325
 
326
+ cr = wax.get_cr
288
327
  xml =
289
- "<!-- comment #1 -->\n" +
290
- "<!-- comment #2 -->\n" +
291
- "<root>\n" +
292
- " <!-- comment #3 -->\n" +
328
+ "<!-- comment #1 -->" + cr +
329
+ "<!-- comment #2 -->" + cr +
330
+ "<root>" + cr +
331
+ " <!-- comment #3 -->" + cr +
293
332
  "</root>"
294
333
 
295
334
  assert_equal xml, @sio.string
296
335
  end
297
336
 
337
+ def test_commented_start
338
+ wax = WAX.write do
339
+ start 'root'
340
+ commented_start 'child'
341
+ child 'grandchild', 'some text'
342
+ end
343
+
344
+ cr = wax.get_cr
345
+ xml =
346
+ "<root>" + cr +
347
+ " <!--child>" + cr +
348
+ " <grandchild>some text</grandchild>" + cr +
349
+ " </child-->" + cr +
350
+ "</root>";
351
+
352
+ assert_equal xml, @sio.string
353
+ end
354
+
355
+ def test_commented_start_with_namespace
356
+ wax = WAX.write do
357
+ start 'root'
358
+ namespace 'foo', 'http://www.ociweb.com/foo'
359
+ commented_start 'foo', 'child'
360
+ child 'grandchild', 'some text'
361
+ end
362
+
363
+ cr = wax.get_cr
364
+ xml =
365
+ '<root' + cr +
366
+ ' xmlns:foo="http://www.ociweb.com/foo">' + cr +
367
+ ' <!--foo:child>' + cr +
368
+ ' <grandchild>some text</grandchild>' + cr +
369
+ ' </foo:child-->' + cr +
370
+ '</root>';
371
+
372
+ assert_equal xml, @sio.string
373
+ end
374
+
298
375
  def test_dtd
299
- WAX.write do
376
+ wax = WAX.write do
300
377
  dtd "http://www.ociweb.com/xml/root.dtd"
301
378
  start "root"
302
379
  end
303
380
 
381
+ cr = wax.get_cr
304
382
  xml =
305
- "<!DOCTYPE root SYSTEM \"http://www.ociweb.com/xml/root.dtd\">\n" +
383
+ "<!DOCTYPE root SYSTEM \"http://www.ociweb.com/xml/root.dtd\">" + cr +
306
384
  "<root/>"
307
385
 
308
386
  assert_equal xml, @sio.string
@@ -310,7 +388,7 @@ class WAXTest < Test::Unit::TestCase
310
388
 
311
389
  def test_empty
312
390
  WAX.write do
313
- set_indent nil
391
+ no_indents_or_crs
314
392
  start "root"
315
393
  end
316
394
 
@@ -319,7 +397,7 @@ class WAXTest < Test::Unit::TestCase
319
397
 
320
398
  def test_entity_def
321
399
  WAX.write do
322
- set_indent nil
400
+ no_indents_or_crs
323
401
  entity_def "name", "value"
324
402
  start "root"
325
403
  end
@@ -330,7 +408,7 @@ class WAXTest < Test::Unit::TestCase
330
408
 
331
409
  def test_external_entity_def
332
410
  WAX.write do
333
- set_indent nil
411
+ no_indents_or_crs
334
412
  external_entity_def "name", "value"
335
413
  start "root"
336
414
  end
@@ -341,7 +419,7 @@ class WAXTest < Test::Unit::TestCase
341
419
 
342
420
  def test_escape
343
421
  WAX.write do
344
- set_indent nil
422
+ no_indents_or_crs
345
423
  start "root"
346
424
  text "abc<def>ghi'jkl\"mno&pqr"
347
425
  end
@@ -353,7 +431,7 @@ class WAXTest < Test::Unit::TestCase
353
431
  def test_extra_end
354
432
  assert_raise(RuntimeError) do
355
433
  WAX.write do
356
- set_indent nil
434
+ no_indents_or_crs
357
435
  start "root"
358
436
  end!
359
437
  end!
@@ -371,7 +449,7 @@ class WAXTest < Test::Unit::TestCase
371
449
  wax.set_indent "\t"
372
450
  assert_equal "\t", wax.get_indent
373
451
 
374
- wax.set_indent nil
452
+ wax.no_indents_or_crs
375
453
  assert_equal nil, wax.get_indent
376
454
 
377
455
  wax.set_indent ""
@@ -379,30 +457,57 @@ class WAXTest < Test::Unit::TestCase
379
457
  end
380
458
 
381
459
  def test_indent_by_num
382
- WAX.write do
460
+ wax = WAX.write do
383
461
  set_indent 2
384
462
  start "root"
385
463
  child "child", "text"
386
464
  end
387
465
 
388
- xml = "<root>\n" + " <child>text</child>\n" + "</root>"
466
+ cr = wax.get_cr
467
+ xml =
468
+ "<root>" + cr +
469
+ " <child>text</child>" + cr +
470
+ "</root>"
389
471
  assert_equal xml, @sio.string
390
472
  end
391
473
 
392
474
  def test_indent_by_string
393
- WAX.write do
394
- set_indent " "
475
+ wax = WAX.write do
476
+ set_indent " " # 1 space
395
477
  start "root"
396
478
  child "child", "text"
397
479
  end
398
480
 
399
- xml = "<root>\n" + " <child>text</child>\n" + "</root>"
481
+ cr = wax.get_cr
482
+ xml =
483
+ "<root>" + cr +
484
+ " <child>text</child>" + cr +
485
+ "</root>"
400
486
  assert_equal xml, @sio.string
401
487
  end
402
488
 
489
+ def test_indent_by_string_weird
490
+ wax = WAX.new
491
+
492
+ # Can set indent to anything if "trust me" is true.
493
+ wax.set_trust_me(true)
494
+ indent = "abc"
495
+ wax.set_indent(indent) # weird indentation characters
496
+ wax.set_trust_me(false)
497
+
498
+ wax.start("root").child("child", "text").close();
499
+
500
+ cr = wax.get_cr
501
+ xml =
502
+ "<root>" + cr +
503
+ indent + "<child>text</child>" + cr +
504
+ "</root>";
505
+ assert_equal xml, @sio.string
506
+ end
507
+
403
508
  def test_namespace
404
509
  WAX.write do
405
- set_indent nil
510
+ no_indents_or_crs
406
511
  start "root"
407
512
  namespace "http://www.ociweb.com/tns1"
408
513
  namespace "tns2", "http://www.ociweb.com/tns2"
@@ -418,7 +523,7 @@ class WAXTest < Test::Unit::TestCase
418
523
 
419
524
  def test_no_indent
420
525
  WAX.write do
421
- set_indent nil
526
+ no_indents_or_crs
422
527
  start "root"
423
528
  child "child", "text"
424
529
  end
@@ -427,6 +532,12 @@ class WAXTest < Test::Unit::TestCase
427
532
  assert_equal xml, @sio.string
428
533
  end
429
534
 
535
+ def test_no_indent_or_crs
536
+ wax = WAX.new
537
+ wax.no_indents_or_crs
538
+ assert_equal nil, wax.get_indent
539
+ end
540
+
430
541
  def test_no_root
431
542
  assert_raise(RuntimeError) do
432
543
  WAX.write {}
@@ -434,21 +545,22 @@ class WAXTest < Test::Unit::TestCase
434
545
  end
435
546
 
436
547
  def test_processing_instruction_in_prologue
437
- WAX.write do
548
+ wax = WAX.write do
438
549
  processing_instruction "xml-stylesheet",
439
550
  "type=\"text/xsl\" href=\"http://www.ociweb.com/foo.xslt\""
440
551
  start "root"
441
552
  end
442
553
 
554
+ cr = wax.get_cr
443
555
  xml =
444
- "<?xml-stylesheet type=\"text/xsl\" href=\"http://www.ociweb.com/foo.xslt\"?>\n" +
556
+ "<?xml-stylesheet type=\"text/xsl\" href=\"http://www.ociweb.com/foo.xslt\"?>" + cr +
445
557
  "<root/>"
446
558
  assert_equal xml, @sio.string
447
559
  end
448
560
 
449
561
  def test_processing_instruction_after_prologue
450
562
  WAX.write do
451
- set_indent nil
563
+ no_indents_or_crs
452
564
  start "root"
453
565
  processing_instruction "target", "data"
454
566
  end
@@ -459,7 +571,7 @@ class WAXTest < Test::Unit::TestCase
459
571
 
460
572
  def test_prefix
461
573
  WAX.write do
462
- set_indent nil
574
+ no_indents_or_crs
463
575
  start "foo", "root"
464
576
  attr "bar", "baz"
465
577
  # Note that the namespace is defined after it is used,
@@ -473,18 +585,19 @@ class WAXTest < Test::Unit::TestCase
473
585
  end
474
586
 
475
587
  def test_schemas_with_indent
476
- WAX.write do
588
+ wax = WAX.write do
477
589
  start "root"
478
590
  namespace nil, "http://www.ociweb.com/tns1", "tns1.xsd"
479
591
  namespace "tns2", "http://www.ociweb.com/tns2", "tns2.xsd"
480
592
  end
481
593
 
482
- xml = "<root\n" +
483
- " xmlns=\"http://www.ociweb.com/tns1\"\n" +
484
- " xmlns:tns2=\"http://www.ociweb.com/tns2\"\n" +
485
- " xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\"\n" +
594
+ cr = wax.get_cr
595
+ xml = "<root" + cr +
596
+ " xmlns=\"http://www.ociweb.com/tns1\"" + cr +
597
+ " xmlns:tns2=\"http://www.ociweb.com/tns2\"" + cr +
598
+ " xmlns:xsi=\"http://www.w3.org/1999/XMLSchema-instance\"" + cr +
486
599
  " xsi:schemaLocation=\"" +
487
- "http://www.ociweb.com/tns1 tns1.xsd\n" +
600
+ "http://www.ociweb.com/tns1 tns1.xsd" + cr +
488
601
  " http://www.ociweb.com/tns2 tns2.xsd" +
489
602
  "\"/>"
490
603
  assert_equal xml, @sio.string
@@ -492,7 +605,7 @@ class WAXTest < Test::Unit::TestCase
492
605
 
493
606
  def test_schemas_without_indent
494
607
  WAX.write do
495
- set_indent nil
608
+ no_indents_or_crs
496
609
  start "root"
497
610
  namespace nil, "http://www.ociweb.com/tns1", "tns1.xsd"
498
611
  namespace "tns2", "http://www.ociweb.com/tns2", "tns2.xsd"
@@ -511,18 +624,22 @@ class WAXTest < Test::Unit::TestCase
511
624
 
512
625
  def test_text
513
626
  WAX.write do
514
- set_indent nil
627
+ no_indents_or_crs
515
628
  start "root"
516
629
  text "text"
517
630
  end
518
631
 
519
- assert_equal "<root>text</root>", @sio.string
632
+ xml = "<root>text</root>"
633
+ assert_equal xml, @sio.string
520
634
  end
521
635
 
522
636
  def test_trust_me_false
523
637
  assert_raise(ArgumentError) do
638
+ this = self
524
639
  WAX.write do
525
640
  set_trust_me false
641
+ this.assert_equal false, is_trust_me
642
+
526
643
  # Since error checking is turned on,
527
644
  # element names must be valid and text is escaped.
528
645
  start "123"
@@ -532,9 +649,13 @@ class WAXTest < Test::Unit::TestCase
532
649
  end
533
650
 
534
651
  def test_trust_me_true
652
+ this = self
535
653
  WAX.write do
536
654
  set_trust_me true
537
- set_indent nil
655
+ this.assert_equal true, is_trust_me
656
+
657
+ no_indents_or_crs
658
+
538
659
  # Since error checking is turned off,
539
660
  # invalid element names and unescaped text are allowed.
540
661
  start "123"
@@ -544,10 +665,36 @@ class WAXTest < Test::Unit::TestCase
544
665
  assert_equal "<123><>&'\"</123>", @sio.string
545
666
  end
546
667
 
668
+ def test_use_non_windows_cr
669
+ wax = WAX.new
670
+ wax.use_non_windows_cr
671
+ assert_equal "\n", wax.get_cr
672
+
673
+ # Most of the other tests verify that
674
+ # this CR is actually used in the output.
675
+ end
676
+
677
+ def test_use_windows_cr
678
+ wax = WAX.write do
679
+ use_windows_cr
680
+ start "root"
681
+ child "child", "text"
682
+ end
683
+
684
+ cr = wax.get_cr
685
+ assert_equal "\r\n", cr
686
+
687
+ xml =
688
+ "<root>" + cr +
689
+ " <child>text</child>" + cr +
690
+ "</root>";
691
+ assert_equal xml, @sio.string
692
+ end
693
+
547
694
  def test_write_file
548
695
  file_path = "temp.xml"
549
696
  WAX.write(file_path) do
550
- set_indent nil
697
+ no_indents_or_crs
551
698
  start "root"
552
699
  text "text"
553
700
  end
@@ -556,14 +703,56 @@ class WAXTest < Test::Unit::TestCase
556
703
  File.delete(file_path)
557
704
  end
558
705
 
706
+ # Tests the instance version of the write method
707
+ # which is convenience for passing to methods
708
+ # that writes parts of the XML.
709
+ def test_write_instance
710
+ require 'address'
711
+ require 'person'
712
+ address = Address.new('123 Some Street', 'Some City', 'MO', 12345)
713
+ person = Person.new('R. Mark Volkmann', '4/16/1961', address)
714
+ wax = WAX.new
715
+ person.to_xml(wax)
716
+ wax.close
717
+
718
+ cr = wax.get_cr
719
+ xml =
720
+ "<person birthdate=\"4/16/1961\">" + cr +
721
+ " <name>R. Mark Volkmann</name>" + cr +
722
+ " <address>" + cr +
723
+ " <street>123 Some Street</street>" + cr +
724
+ " <city>Some City</city>" + cr +
725
+ " <state>MO</state>" + cr +
726
+ " <zip>12345</zip>" + cr +
727
+ " </address>" + cr +
728
+ "</person>"
729
+ assert_equal xml, @sio.string
730
+ end
731
+
559
732
  def test_xml_declaration
560
- WAX.write($stdout, "1.0") do
561
- set_indent nil
733
+ wax = WAX.write($stdout, "1.0") do
734
+ no_indents_or_crs
562
735
  start "root"
563
736
  end
564
737
 
565
- xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root/>"
738
+ cr = wax.get_cr
739
+ xml =
740
+ "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + cr +
741
+ "<root/>"
566
742
  assert_equal xml, @sio.string
567
743
  end
568
-
569
- end
744
+
745
+ def test_xslt
746
+ wax = WAX.write do
747
+ xslt "root.xslt"
748
+ start "root"
749
+ end
750
+
751
+ cr = wax.get_cr
752
+ xml =
753
+ "<?xml-stylesheet type=\"text/xsl\" href=\"root.xslt\"?>" + cr +
754
+ "<root/>"
755
+
756
+ assert_equal xml, @sio.string
757
+ end
758
+ end
@@ -29,9 +29,9 @@ class XMLUtilTest < Test::Unit::TestCase
29
29
  end
30
30
  end
31
31
 
32
- def test_bad_nmtoken
32
+ def test_bad_name
33
33
  assert_raise(ArgumentError) do
34
- XMLUtil.verify_nmtoken("1a")
34
+ XMLUtil.verify_name("1a")
35
35
  end
36
36
  end
37
37
 
@@ -41,11 +41,10 @@ class XMLUtilTest < Test::Unit::TestCase
41
41
  end
42
42
  end
43
43
 
44
- # TODO: Uncomment after is_uri method is implemented.
45
44
  def test_bad_uri
46
- #assert_raise(ArgumentError) do
47
- # XMLUtil.verify_uri(":junk")
48
- #end
45
+ assert_raise(ArgumentError) do
46
+ XMLUtil.verify_uri(":junk")
47
+ end
49
48
  end
50
49
 
51
50
  def test_escape
@@ -65,15 +64,14 @@ class XMLUtilTest < Test::Unit::TestCase
65
64
  assert !XMLUtil.is_comment("one two --")
66
65
  end
67
66
 
68
- def test_is_nmtoken
69
- assert XMLUtil.is_nmtoken("a1")
70
- assert !XMLUtil.is_nmtoken("1a")
67
+ def test_is_name
68
+ assert XMLUtil.is_name("a1")
69
+ assert !XMLUtil.is_name("1a")
71
70
  end
72
71
 
73
- # TODO: Uncomment after is_uri method is implemented.
74
72
  def test_is_uri
75
- #assert XMLUtil.is_uri("http://www.ociweb.com/foo")
76
- #assert !XMLUtil.is_uri(":junk")
73
+ assert XMLUtil.is_uri("http://www.ociweb.com/foo")
74
+ assert !XMLUtil.is_uri(":junk")
77
75
  end
78
76
 
79
77
  def test_is_version
@@ -83,4 +81,4 @@ class XMLUtilTest < Test::Unit::TestCase
83
81
  assert !XMLUtil.is_version("1.3")
84
82
  end
85
83
 
86
- end
84
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wax
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.5
4
+ version: 0.9.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - R. Mark Volkmann
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-09-01 00:00:00 -05:00
12
+ date: 2008-09-15 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies: []
15
15