sdl4r 0.9.6 → 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.
- data/CHANGELOG +49 -2
- data/Rakefile +35 -5
- data/TODO +29 -3
- data/doc/classes/SDL4R.html +386 -674
- data/doc/classes/SDL4R/Parser.html +183 -307
- data/doc/classes/SDL4R/ParserTest.html +357 -0
- data/doc/classes/SDL4R/SDL4RTest.html +532 -0
- data/doc/classes/SDL4R/SDLTest.html +77 -0
- data/doc/classes/SDL4R/SdlBinary.html +180 -295
- data/doc/classes/SDL4R/SdlParseError.html +105 -180
- data/doc/classes/SDL4R/SdlTimeSpan.html +628 -939
- data/doc/classes/SDL4R/Tag.html +1236 -2036
- data/doc/classes/SDL4R/TagTest.html +292 -0
- data/doc/created.rid +1 -1
- data/doc/files/CHANGELOG.html +183 -184
- data/doc/files/LICENSE.html +496 -755
- data/doc/files/README.html +399 -623
- data/doc/files/lib/sdl4r/parser/reader_rb.html +53 -106
- data/doc/files/lib/sdl4r/parser/time_span_with_zone_rb.html +53 -106
- data/doc/files/lib/sdl4r/parser/token_rb.html +53 -106
- data/doc/files/lib/sdl4r/parser/tokenizer_rb.html +53 -106
- data/doc/files/lib/sdl4r/parser_rb.html +60 -112
- data/doc/files/lib/sdl4r/sdl4r_rb.html +62 -114
- data/doc/files/lib/sdl4r/sdl_binary_rb.html +53 -106
- data/doc/files/lib/sdl4r/sdl_parse_error_rb.html +53 -106
- data/doc/files/lib/sdl4r/sdl_time_span_rb.html +53 -106
- data/doc/files/lib/sdl4r/tag_rb.html +62 -114
- data/doc/files/lib/sdl4r_rb.html +53 -106
- data/doc/files/test/sdl4r/parser_test_rb.html +63 -0
- data/doc/files/test/sdl4r/sdl4r_test_rb.html +66 -0
- data/doc/files/test/sdl4r/sdl_test_rb.html +63 -0
- data/doc/files/test/sdl4r/tag_test_rb.html +63 -0
- data/doc/fr_class_index.html +19 -32
- data/doc/fr_file_index.html +37 -40
- data/doc/fr_method_index.html +4707 -114
- data/doc/index.html +14 -23
- data/doc/rdoc-style.css +323 -203
- data/lib/sdl4r/parser/reader.rb +26 -19
- data/lib/sdl4r/parser/token.rb +3 -3
- data/lib/sdl4r/parser/tokenizer.rb +93 -98
- data/lib/sdl4r/sdl_parse_error.rb +2 -2
- data/lib/sdl4r/tag.rb +127 -73
- data/test/sdl4r/parser_test.rb +109 -11
- data/test/sdl4r/tag_test.rb +73 -4
- metadata +15 -12
@@ -36,10 +36,10 @@ module SDL4R
|
|
36
36
|
def initialize(description, line_no, position, line = nil)
|
37
37
|
super(
|
38
38
|
"#{description} Line " + ((line_no.nil? or line_no < 0)? "unknown" : line_no.to_s) +
|
39
|
-
", Position " + ((position.nil? or position < 0)? "unknown" : position.to_s) +
|
39
|
+
", Position " + ((position.nil? or position < 0)? "unknown" : position.to_s) + $/ +
|
40
40
|
(line ? line + (position ? " " * (position - 1) : "") + "^" : ""))
|
41
41
|
|
42
|
-
@
|
42
|
+
@line = line_no
|
43
43
|
@position = position
|
44
44
|
end
|
45
45
|
|
data/lib/sdl4r/tag.rb
CHANGED
@@ -87,7 +87,18 @@ module SDL4R
|
|
87
87
|
# orange quantity=2
|
88
88
|
# }
|
89
89
|
#
|
90
|
-
#
|
90
|
+
# If you provide a block that takes an argument, you will write the same example, as follows:
|
91
|
+
#
|
92
|
+
# tag = Tag.new("fruit") do |t|
|
93
|
+
# t.add_value 2
|
94
|
+
# t.new_child("orange") do
|
95
|
+
# set_attribute("quantity", 2)
|
96
|
+
# end
|
97
|
+
# end
|
98
|
+
#
|
99
|
+
# In this case, the current context is not the new Tag anymore but the context of your code.
|
100
|
+
#
|
101
|
+
# === Raises
|
91
102
|
# ArgumentError if the name is not a legal SDL identifier
|
92
103
|
# (see SDL4R#validate_identifier) or the namespace is non-blank
|
93
104
|
# and is not a legal SDL identifier.
|
@@ -113,7 +124,13 @@ module SDL4R
|
|
113
124
|
# The default namespace is represented by an empty string.
|
114
125
|
@attributesByNamespace = {}
|
115
126
|
|
116
|
-
|
127
|
+
if block_given?
|
128
|
+
if block.arity > 0
|
129
|
+
block[self]
|
130
|
+
else
|
131
|
+
instance_eval(&block)
|
132
|
+
end
|
133
|
+
end
|
117
134
|
end
|
118
135
|
|
119
136
|
# Creates a new child tag.
|
@@ -125,7 +142,15 @@ module SDL4R
|
|
125
142
|
# end
|
126
143
|
# end
|
127
144
|
#
|
128
|
-
# The context of execution of the given block is the child instance
|
145
|
+
# The context of execution of the given block is the child instance.
|
146
|
+
# If you provide a block that takes a parameter (see below), the context is the context of your
|
147
|
+
# code:
|
148
|
+
#
|
149
|
+
# car = Tag.new("car") do |child|
|
150
|
+
# child.new_child("wheels") do |grandchild|
|
151
|
+
# grandchild << 4
|
152
|
+
# end
|
153
|
+
# end
|
129
154
|
#
|
130
155
|
# Returns the created child Tag.
|
131
156
|
#
|
@@ -135,7 +160,7 @@ module SDL4R
|
|
135
160
|
|
136
161
|
# Add a child to this Tag.
|
137
162
|
#
|
138
|
-
#
|
163
|
+
# _child_:: The child to add
|
139
164
|
#
|
140
165
|
# Returns the added child.
|
141
166
|
#
|
@@ -146,9 +171,9 @@ module SDL4R
|
|
146
171
|
|
147
172
|
# Adds the given object as a child if it is a +Tag+, as an attribute if it is a Hash
|
148
173
|
# {key => value} (supports namespaces), or as a value otherwise.
|
149
|
-
# If it is an
|
150
|
-
# elements is itself an
|
151
|
-
# via this operator (see the examples below)
|
174
|
+
# If it is an Enumerable (e.g. Array), each of its elements is added to this Tag via this
|
175
|
+
# operator. If any of its elements is itself an Enumerable, then an anonymous tag is created and
|
176
|
+
# the Enumerable is passed to it via this operator (see the examples below).
|
152
177
|
#
|
153
178
|
# tag << Tag.new("child")
|
154
179
|
# tag << 123 # new integer value
|
@@ -162,9 +187,13 @@ module SDL4R
|
|
162
187
|
# # 4 5 6
|
163
188
|
# # }
|
164
189
|
#
|
190
|
+
# Of course, despite the fact that String is an Enumerable, it is considered as the type of
|
191
|
+
# values.
|
192
|
+
#
|
165
193
|
# Returns +self+.
|
166
194
|
#
|
167
|
-
# Use other accessors for a stricter and less
|
195
|
+
# Use other accessors (#add_child, #add_value, #attributes, etc) for a stricter and less
|
196
|
+
# "magical" behavior.
|
168
197
|
#
|
169
198
|
def <<(o)
|
170
199
|
if o.is_a?(Tag)
|
@@ -175,9 +204,11 @@ module SDL4R
|
|
175
204
|
namespace ||= ""
|
176
205
|
set_attribute(namespace, key, value)
|
177
206
|
}
|
178
|
-
elsif o.is_a?
|
207
|
+
elsif o.is_a? String
|
208
|
+
add_value(o)
|
209
|
+
elsif o.is_a? Enumerable
|
179
210
|
o.each { |item|
|
180
|
-
if item.is_a?
|
211
|
+
if item.is_a? Enumerable and not item.is_a? String
|
181
212
|
anonymous = new_child("content")
|
182
213
|
anonymous << item
|
183
214
|
else
|
@@ -192,7 +223,7 @@ module SDL4R
|
|
192
223
|
|
193
224
|
# Remove a child from this Tag
|
194
225
|
#
|
195
|
-
#
|
226
|
+
# _child_:: the child to remove
|
196
227
|
#
|
197
228
|
# Returns true if the child exists and is removed
|
198
229
|
#
|
@@ -208,14 +239,14 @@ module SDL4R
|
|
208
239
|
end
|
209
240
|
|
210
241
|
#
|
211
|
-
# A convenience method that sets the first value in the value list.
|
212
|
-
#
|
242
|
+
# A convenience method that sets the first value in the value list.
|
243
|
+
# See # #add_value for legal types.
|
213
244
|
#
|
214
|
-
#
|
245
|
+
# _value_:: The value to be set.
|
215
246
|
#
|
216
247
|
# === Raises
|
217
248
|
#
|
218
|
-
#
|
249
|
+
# _ArgumentError_:: if the value is not a legal SDL type
|
219
250
|
#
|
220
251
|
def value=(value)
|
221
252
|
@values[0] = SDL4R.coerce_or_fail(value)
|
@@ -245,9 +276,9 @@ module SDL4R
|
|
245
276
|
#
|
246
277
|
# Returns an Array of the children Tags of this Tag or enumerates them.
|
247
278
|
#
|
248
|
-
#
|
249
|
-
#
|
250
|
-
#
|
279
|
+
# _recursive_:: if true children and all descendants will be returned. False by default.
|
280
|
+
# _name_:: if not nil, only children having this name will be returned. Nil by default.
|
281
|
+
# _namespace_:: use nil for all namespaces and "" for the default one. Nil by default.
|
251
282
|
#
|
252
283
|
# tag.children # => array of the children
|
253
284
|
# tag.children(true) { |descendant| ... }
|
@@ -283,7 +314,7 @@ module SDL4R
|
|
283
314
|
# more than one value, all the values will be added as an array. If the child
|
284
315
|
# has no value, +nil+ will be added. The search is not recursive.
|
285
316
|
#
|
286
|
-
#
|
317
|
+
# _name_:: if nil, all children are considered (nil by default).
|
287
318
|
def children_values(name = nil)
|
288
319
|
children_values = []
|
289
320
|
each_child(false, name) { |child|
|
@@ -305,7 +336,7 @@ module SDL4R
|
|
305
336
|
#
|
306
337
|
# Get the first child with the given name, optionally using a recursive search.
|
307
338
|
#
|
308
|
-
#
|
339
|
+
# _name_:: the name of the child Tag. If +nil+, the first child is returned (+nil+ if there are
|
309
340
|
# no children at all).
|
310
341
|
#
|
311
342
|
# Returns the first child tag having the given name or +nil+ if no such child exists
|
@@ -325,7 +356,7 @@ module SDL4R
|
|
325
356
|
|
326
357
|
# Indicates whether the child Tag of given name exists.
|
327
358
|
#
|
328
|
-
#
|
359
|
+
# _name_:: name of the searched child Tag
|
329
360
|
#
|
330
361
|
def has_child?(name)
|
331
362
|
!child(name).nil?
|
@@ -340,9 +371,9 @@ module SDL4R
|
|
340
371
|
# Enumerates the children +Tag+s of this Tag and calls the given block
|
341
372
|
# providing it the child as parameter.
|
342
373
|
#
|
343
|
-
#
|
344
|
-
#
|
345
|
-
#
|
374
|
+
# _recursive_:: if true, enumerate grand-children, etc, recursively
|
375
|
+
# _namespace_:: if not nil, indicates the namespace of the children to enumerate
|
376
|
+
# _name_:: if not nil, indicates the name of the children to enumerate
|
346
377
|
#
|
347
378
|
def each_child(recursive = false, namespace = nil, name = :DEFAULT, &block)
|
348
379
|
if name == :DEFAULT
|
@@ -402,7 +433,7 @@ module SDL4R
|
|
402
433
|
|
403
434
|
# Adds a value to this Tag. See SDL4R#coerce_or_fail to know about the allowable types.
|
404
435
|
#
|
405
|
-
#
|
436
|
+
# _v_:: The value to add
|
406
437
|
#
|
407
438
|
# Raises an +ArgumentError+ if the value is not a legal SDL type
|
408
439
|
#
|
@@ -419,7 +450,7 @@ module SDL4R
|
|
419
450
|
|
420
451
|
# Removes the first occurence of the specified value from this Tag.
|
421
452
|
#
|
422
|
-
#
|
453
|
+
# _v_:: The value to remove
|
423
454
|
#
|
424
455
|
# Returns true If the value exists and is removed
|
425
456
|
#
|
@@ -453,12 +484,11 @@ module SDL4R
|
|
453
484
|
end
|
454
485
|
end
|
455
486
|
|
456
|
-
# Set the values for this tag. See
|
457
|
-
# value types.
|
487
|
+
# Set the values for this tag. See #add_value for legal value types.
|
458
488
|
#
|
459
|
-
#
|
460
|
-
#
|
461
|
-
#
|
489
|
+
# _values_:: The new values
|
490
|
+
#
|
491
|
+
# Raises an +ArgumentError+ if the collection contains any values which are not legal SDL types.
|
462
492
|
#
|
463
493
|
def values=(someValues)
|
464
494
|
@values.clear()
|
@@ -473,17 +503,15 @@ module SDL4R
|
|
473
503
|
# set_attribute(namespace, key, value)
|
474
504
|
#
|
475
505
|
# Set an attribute in the given namespace for this tag. The allowable
|
476
|
-
# attribute value types are the same as those allowed for
|
477
|
-
# {@link #addValue(Object)}
|
478
|
-
#
|
479
|
-
# +namespace+:: The namespace for this attribute
|
480
|
-
# +key+:: The attribute key
|
481
|
-
# +value+:: The attribute value
|
506
|
+
# attribute value types are the same as those allowed for #add_value.
|
482
507
|
#
|
483
|
-
#
|
484
|
-
#
|
485
|
-
#
|
486
|
-
#
|
508
|
+
# _namespace_:: The namespace for this attribute
|
509
|
+
# _key_:: The attribute key
|
510
|
+
# _value_:: The attribute value
|
511
|
+
#
|
512
|
+
# Raises +ArgumentError+ if the key is not a legal SDL identifier (see
|
513
|
+
# SDL4R#validate_identifier), or the namespace is non-blank and is not a legal SDL identifier,
|
514
|
+
# or thevalue is not a legal SDL type
|
487
515
|
#
|
488
516
|
def set_attribute(namespace, key, value = :default)
|
489
517
|
if value == :default
|
@@ -549,7 +577,7 @@ module SDL4R
|
|
549
577
|
# p "#{namespace}:#{key} = #{value}"
|
550
578
|
# end
|
551
579
|
#
|
552
|
-
#
|
580
|
+
# _namespace_::
|
553
581
|
# namespace of the returned attributes. If nil, all attributes are returned with
|
554
582
|
# qualified names (e.g. "meat:color"). If "", attributes of the default namespace are returned.
|
555
583
|
#
|
@@ -579,8 +607,8 @@ module SDL4R
|
|
579
607
|
#
|
580
608
|
# Removes the attribute, whose name and namespace are specified.
|
581
609
|
#
|
582
|
-
#
|
583
|
-
#
|
610
|
+
# _key_:: name of the removed atribute
|
611
|
+
# _namespace_:: namespace of the removed attribute (equal to "", default namespace, by default)
|
584
612
|
#
|
585
613
|
# Returns the value of the removed attribute or +nil+ if it didn't exist.
|
586
614
|
#
|
@@ -627,12 +655,11 @@ module SDL4R
|
|
627
655
|
# previous attributes of the specified +namespace+ are removed.
|
628
656
|
# See #set_attribute for allowable attribute value types.
|
629
657
|
#
|
630
|
-
#
|
631
|
-
#
|
658
|
+
# _attributes_:: a Hash where keys are attribute keys
|
659
|
+
# _namespace_:: "" (default namespace) by default
|
632
660
|
#
|
633
|
-
# Raises an +ArgumentError+ if any key in the map is not a legal SDL
|
634
|
-
#
|
635
|
-
# is not a legal SDL type.
|
661
|
+
# Raises an +ArgumentError+ if any key in the map is not a legal SDL identifier
|
662
|
+
# (see SDL4R#validate_identifier), or any value is not a legal SDL type.
|
636
663
|
#
|
637
664
|
def set_attributes(namespace, attribute_hash = nil)
|
638
665
|
if attribute_hash.nil?
|
@@ -655,7 +682,7 @@ module SDL4R
|
|
655
682
|
# Sets all the attributes of the default namespace for this Tag in one
|
656
683
|
# operation.
|
657
684
|
#
|
658
|
-
# See #set_attributes
|
685
|
+
# See #set_attributes.
|
659
686
|
#
|
660
687
|
def attributes=(attribute_hash)
|
661
688
|
set_attributes(attribute_hash)
|
@@ -663,9 +690,9 @@ module SDL4R
|
|
663
690
|
|
664
691
|
# Sets the name of this Tag.
|
665
692
|
#
|
666
|
-
# Raises +ArgumentError+ if the name is not a legal SDL
|
667
|
-
#
|
668
|
-
|
693
|
+
# Raises +ArgumentError+ if the name is not a legal SDL identifier
|
694
|
+
# (see SDL4R#validate_identifier).
|
695
|
+
#
|
669
696
|
def name=(a_name)
|
670
697
|
a_name = a_name.to_s
|
671
698
|
SDL4R.validate_identifier(a_name)
|
@@ -675,8 +702,8 @@ module SDL4R
|
|
675
702
|
# The namespace to set. +nil+ will be coerced to the empty string.
|
676
703
|
#
|
677
704
|
# Raises +ArgumentError+ if the namespace is non-blank and is not
|
678
|
-
#
|
679
|
-
|
705
|
+
# a legal SDL identifier (see SDL4R#validate_identifier)
|
706
|
+
#
|
680
707
|
def namespace=(a_namespace)
|
681
708
|
a_namespace = a_namespace.to_s
|
682
709
|
SDL4R.validate_identifier(a_namespace) unless a_namespace.empty?
|
@@ -725,7 +752,7 @@ module SDL4R
|
|
725
752
|
# Write this tag out to the given IO or StringIO or String (optionally clipping the root.)
|
726
753
|
# Returns +output+.
|
727
754
|
#
|
728
|
-
#
|
755
|
+
# _output_:: an IO or StringIO or a String to write to
|
729
756
|
# +include_root+:: if true this tag will be written out as the root element, if false only the
|
730
757
|
# children will be written. False by default.
|
731
758
|
#
|
@@ -756,10 +783,9 @@ module SDL4R
|
|
756
783
|
output
|
757
784
|
end
|
758
785
|
|
759
|
-
#
|
760
786
|
# Get a String representation of this SDL Tag. This method returns a
|
761
787
|
# complete description of the Tag's state using SDL (i.e. the output can
|
762
|
-
# be parsed by
|
788
|
+
# be parsed by #read)
|
763
789
|
#
|
764
790
|
# Returns A string representation of this tag using SDL
|
765
791
|
#
|
@@ -767,8 +793,7 @@ module SDL4R
|
|
767
793
|
to_string
|
768
794
|
end
|
769
795
|
|
770
|
-
#
|
771
|
-
# +linePrefix+:: A prefix to insert before every line.
|
796
|
+
# _linePrefix_:: A prefix to insert before every line.
|
772
797
|
# Returns A string representation of this tag using SDL
|
773
798
|
#
|
774
799
|
# TODO: break up long lines using the backslash
|
@@ -825,8 +850,8 @@ module SDL4R
|
|
825
850
|
|
826
851
|
# Returns a string representation of the children tags.
|
827
852
|
#
|
828
|
-
#
|
829
|
-
#
|
853
|
+
# _linePrefix_:: A prefix to insert before every line.
|
854
|
+
# _s_:: a String that receives the string representation
|
830
855
|
#
|
831
856
|
# TODO: break up long lines using the backslash
|
832
857
|
#
|
@@ -857,19 +882,45 @@ module SDL4R
|
|
857
882
|
|
858
883
|
# Returns a string containing an XML representation of this tag. Values
|
859
884
|
# will be represented using _val0, _val1, etc.
|
860
|
-
#
|
861
|
-
# +line_prefix+:: A prefix to insert before every line.
|
862
|
-
# +uri_by_namespace+:: a Hash giving the URIs for the namespaces. Nil to ignore this.
|
863
885
|
#
|
864
|
-
|
865
|
-
|
866
|
-
|
886
|
+
# _options_:: a hash of the options
|
887
|
+
#
|
888
|
+
# === options:
|
889
|
+
#
|
890
|
+
# [:line_prefix] a text prefixing each line (default: "")
|
891
|
+
# [:uri_by_namespace] a Hash giving the URIs for the namespaces
|
892
|
+
# [:indent] text specifying one indentation (default: "\t")
|
893
|
+
# [:eol] end of line expression (default: "\n")
|
894
|
+
# [:omit_null_attributes]
|
895
|
+
# if true, null/nil attributes are not exported (default: false). Otherwise, they are exported
|
896
|
+
# as follows:
|
897
|
+
# tag attr="null"
|
898
|
+
#
|
899
|
+
def to_xml_string(options = {})
|
900
|
+
options = {
|
901
|
+
:uri_by_namespace => nil,
|
902
|
+
:indent => "\t",
|
903
|
+
:line_prefix => "",
|
904
|
+
:eol => "\n",
|
905
|
+
:omit_null_attributes => false
|
906
|
+
}.merge(options)
|
907
|
+
_to_xml_string(options[:line_prefix], options)
|
908
|
+
end
|
909
|
+
|
910
|
+
protected
|
911
|
+
|
912
|
+
# Implementation of #to_xml_string but without the extra-treatment on parameters for default
|
913
|
+
# values.
|
914
|
+
def _to_xml_string(line_prefix, options)
|
915
|
+
eol = options[:eol]
|
916
|
+
|
867
917
|
s = ""
|
868
918
|
s << line_prefix << ?<
|
869
919
|
s << "#{namespace}:" unless namespace.empty?
|
870
920
|
s << name
|
871
921
|
|
872
922
|
# output namespace declarations
|
923
|
+
uri_by_namespace = options[:uri_by_namespace]
|
873
924
|
if uri_by_namespace
|
874
925
|
uri_by_namespace.each_pair do |namespace, uri|
|
875
926
|
if namespace
|
@@ -891,19 +942,22 @@ module SDL4R
|
|
891
942
|
|
892
943
|
# output attributes
|
893
944
|
if has_attribute?
|
945
|
+
omit_null_attributes = options[:omit_null_attributes]
|
894
946
|
attributes do |attribute_namespace, attribute_name, attribute_value|
|
895
|
-
|
896
|
-
|
897
|
-
|
947
|
+
unless omit_null_attributes and attribute_value.nil?
|
948
|
+
s << " "
|
949
|
+
s << "#{attribute_namespace}:" unless attribute_namespace.empty?
|
950
|
+
s << attribute_name << "=\"" << SDL4R.format(attribute_value, false) << ?"
|
951
|
+
end
|
898
952
|
end
|
899
953
|
end
|
900
954
|
|
901
955
|
if @children.empty?
|
902
956
|
s << "/>"
|
903
957
|
else
|
904
|
-
s << "
|
958
|
+
s << ">" << eol
|
905
959
|
@children.each do |child|
|
906
|
-
s << child.
|
960
|
+
s << child._to_xml_string(line_prefix + options[:indent], options) << eol
|
907
961
|
end
|
908
962
|
|
909
963
|
s << line_prefix << "</"
|
data/test/sdl4r/parser_test.rb
CHANGED
@@ -86,12 +86,12 @@ module SDL4R
|
|
86
86
|
assert_equal("d`e`f", values[1], "values[1]")
|
87
87
|
assert_equal("g\"h\"i", values[2], "values[2]")
|
88
88
|
assert_equal("j\\k+l", values[3], "values[3]")
|
89
|
-
assert_equal("m\\\nn\\\n \t o\
|
89
|
+
assert_equal("m\\\nn\\\n \t o\r", values[4], "values[4]")
|
90
90
|
end
|
91
91
|
|
92
92
|
def test_tag_with_base64_values
|
93
93
|
tag1 = parse_one_tag1(
|
94
|
-
<<
|
94
|
+
<<EOS
|
95
95
|
tag1 [V2VsY29tZSB0byB0aGUgY3J1ZWwgd29ybGQu] [
|
96
96
|
SG9wZSB5
|
97
97
|
b3UnbGwg
|
@@ -99,7 +99,7 @@ tag1 [V2VsY29tZSB0byB0aGUgY3J1ZWwgd29ybGQu] [
|
|
99
99
|
b3VyIHdh
|
100
100
|
eS4=
|
101
101
|
]
|
102
|
-
|
102
|
+
EOS
|
103
103
|
)
|
104
104
|
assert_not_nil(tag1, "tag1")
|
105
105
|
values = tag1.values
|
@@ -117,6 +117,11 @@ EOF
|
|
117
117
|
attributes = tag1.attributes
|
118
118
|
assert_equal(1, attributes.size, "attribute count")
|
119
119
|
assert_equal(99, attributes["attr1"], "attr1")
|
120
|
+
|
121
|
+
# check the parsing with line continuations
|
122
|
+
tag1 = parse_one_tag1("tag1\\\nattr1=\\\n99")
|
123
|
+
assert_not_nil(tag1, "tag1")
|
124
|
+
assert_equal(99, tag1.attribute("attr1"), "attr1")
|
120
125
|
end
|
121
126
|
|
122
127
|
def test_tag_with_attributes
|
@@ -208,6 +213,16 @@ EOF
|
|
208
213
|
assert_equal(BigDecimal("171.8"), values[9])
|
209
214
|
assert_equal(BigDecimal("1.920"), values[10])
|
210
215
|
assert_equal(BigDecimal("12345678901234567890"), values[11])
|
216
|
+
|
217
|
+
assert_raise SdlParseError do
|
218
|
+
parse_one_tag1("tag1 123.2.2")
|
219
|
+
end
|
220
|
+
assert_raise SdlParseError do
|
221
|
+
parse_one_tag1("tag1 123.2e")
|
222
|
+
end
|
223
|
+
assert_raise SdlParseError do
|
224
|
+
parse_one_tag1("tag1 +-123.2")
|
225
|
+
end
|
211
226
|
end
|
212
227
|
|
213
228
|
def test_booleans
|
@@ -230,7 +245,7 @@ EOF
|
|
230
245
|
def test_comments
|
231
246
|
root = Tag.new("root")
|
232
247
|
root.read(
|
233
|
-
<<
|
248
|
+
<<EOS
|
234
249
|
tag1 123
|
235
250
|
#tag2 456
|
236
251
|
tag3 789
|
@@ -241,7 +256,7 @@ tag7 901
|
|
241
256
|
/*tag8 234
|
242
257
|
tag9 567*/
|
243
258
|
tag10 890
|
244
|
-
|
259
|
+
EOS
|
245
260
|
)
|
246
261
|
children = root.children
|
247
262
|
assert_equal(5, children.size, "children count")
|
@@ -259,7 +274,7 @@ EOF
|
|
259
274
|
|
260
275
|
def test_double_quote_strings
|
261
276
|
root = SDL4R::read(
|
262
|
-
<<
|
277
|
+
<<EOS
|
263
278
|
tag1 "cheese and cherry jam"
|
264
279
|
tag2 "cheese and \\
|
265
280
|
cherry jam"
|
@@ -271,7 +286,7 @@ tag5 "Even my dog wouldn't\\thave\\tit!"
|
|
271
286
|
tag6 "\\"\\t\\r\\n\\\\"
|
272
287
|
tag7 equation="is not x=y*z" color="blue \\
|
273
288
|
and yellow"
|
274
|
-
|
289
|
+
EOS
|
275
290
|
)
|
276
291
|
|
277
292
|
assert_equal "cheese and cherry jam", root.child("tag1").value, "double-quote string"
|
@@ -288,8 +303,32 @@ EOF
|
|
288
303
|
assert_equal "blue and yellow", root.child("tag7").attribute("color")
|
289
304
|
end
|
290
305
|
|
306
|
+
def test_characters
|
307
|
+
root = SDL4R::read "tag1 ' ' 'a' '\\\\' '\\t' '\\n' '\\r'"
|
308
|
+
assert_equal [" ", "a", "\\", "\t", "\n", "\r"], root.child("tag1").values
|
309
|
+
|
310
|
+
assert_raise SdlParseError do
|
311
|
+
SDL4R::read "tag1 '"
|
312
|
+
end
|
313
|
+
assert_raise SdlParseError do
|
314
|
+
SDL4R::read "tag1 'a"
|
315
|
+
end
|
316
|
+
assert_raise SdlParseError do
|
317
|
+
SDL4R::read "tag1 'abc'"
|
318
|
+
end
|
319
|
+
assert_raise SdlParseError do
|
320
|
+
SDL4R::read "tag1 ''"
|
321
|
+
end
|
322
|
+
assert_raise SdlParseError do
|
323
|
+
SDL4R::read "tag1 '\\'"
|
324
|
+
end
|
325
|
+
assert_raise SdlParseError do
|
326
|
+
SDL4R::read "tag1 '\\"
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
291
330
|
def test_backquote_strings
|
292
|
-
root = SDL4R::read <<
|
331
|
+
root = SDL4R::read <<EOS
|
293
332
|
winfile `c:\\directory\\myfile.xls`
|
294
333
|
talk `I said "something"`
|
295
334
|
xml `
|
@@ -298,7 +337,7 @@ xml `
|
|
298
337
|
</product>
|
299
338
|
`
|
300
339
|
regex `\\w+\\.suite\\(\\)`
|
301
|
-
|
340
|
+
EOS
|
302
341
|
|
303
342
|
assert_equal "c:\\directory\\myfile.xls", root.child("winfile").value
|
304
343
|
assert_equal 'I said "something"', root.child("talk").value
|
@@ -308,7 +347,7 @@ EOF
|
|
308
347
|
end
|
309
348
|
|
310
349
|
def test_sub_tags
|
311
|
-
root = SDL4R::read <<
|
350
|
+
root = SDL4R::read <<EOS
|
312
351
|
wax {
|
313
352
|
}
|
314
353
|
steack {
|
@@ -322,7 +361,7 @@ steack {
|
|
322
361
|
}
|
323
362
|
}
|
324
363
|
peanut.butter
|
325
|
-
|
364
|
+
EOS
|
326
365
|
|
327
366
|
expected = Tag.new("root") do
|
328
367
|
new_child("wax")
|
@@ -341,8 +380,67 @@ EOF
|
|
341
380
|
assert_equal expected, root
|
342
381
|
end
|
343
382
|
|
383
|
+
def test_parse_error
|
384
|
+
# WARNING: the line and col of an error is not accurate science. The goal here is to point to
|
385
|
+
# coordinates that are useful to the user.
|
386
|
+
# Exampe for a string litteral that spans over several line, some errors could be point to
|
387
|
+
# the start or to the end without too much ambiguity.
|
388
|
+
# Consequently, feel free to change the coordinates, if a change in the implementation
|
389
|
+
# modifies the x/y of the error and they still make sense.
|
390
|
+
assert_error_xy "=", 1, 1
|
391
|
+
assert_error_xy "tag1 xyz", 1, 6
|
392
|
+
assert_error_xy "tag1 \\\nxyz", 2, 1
|
393
|
+
assert_error_xy "tag1 \\\n xyz", 2, 4
|
394
|
+
|
395
|
+
source = <<EOS
|
396
|
+
-- my comment
|
397
|
+
=
|
398
|
+
EOS
|
399
|
+
assert_error_xy source, 2, 1
|
400
|
+
|
401
|
+
source = <<EOS
|
402
|
+
murder_plot 123 \\
|
403
|
+
weight=456 \\
|
404
|
+
* \\
|
405
|
+
length=789
|
406
|
+
EOS
|
407
|
+
assert_error_xy source, 3, 6
|
408
|
+
|
409
|
+
assert_error_xy 'tag1 "text\\"', 1, 13
|
410
|
+
|
411
|
+
source = <<EOS
|
412
|
+
murder_plot "abcd\\
|
413
|
+
efghij\\
|
414
|
+
kl\\
|
415
|
+
mnopq
|
416
|
+
EOS
|
417
|
+
assert_error_xy source, 4, 13
|
418
|
+
end
|
419
|
+
|
344
420
|
private
|
345
421
|
|
422
|
+
def assert_error_xy source, expected_line, expected_pos
|
423
|
+
error = get_parse_error_or_fail source
|
424
|
+
begin
|
425
|
+
assert_equal expected_line, error.line, "line"
|
426
|
+
assert_equal expected_pos, error.position, "position"
|
427
|
+
rescue
|
428
|
+
puts "Expected error: #{error}"
|
429
|
+
puts error.backtrace
|
430
|
+
raise $!
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
def get_parse_error_or_fail source
|
435
|
+
begin
|
436
|
+
SDL4R::read source
|
437
|
+
|
438
|
+
rescue
|
439
|
+
return $! if $!.is_a? SdlParseError
|
440
|
+
raise AssertionFailedError, "was expecting a SdlParseError"
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
346
444
|
# Creates and returns a DateTime where an unspecified +zone_offset+ means 'the local zone
|
347
445
|
# offset' (contrarily to DateTime#civil())
|
348
446
|
def local_civil_date(year, month, day, hour = 0, min = 0, sec = 0, zone_offset = nil)
|