wax 0.9.5 → 0.9.7

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.
@@ -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