tilia-xml 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rubocop.yml +32 -0
  4. data/.simplecov +4 -0
  5. data/.travis.yml +3 -0
  6. data/CHANGELOG.sabre.md +167 -0
  7. data/CONTRIBUTING.md +25 -0
  8. data/Gemfile +15 -0
  9. data/Gemfile.lock +56 -0
  10. data/LICENSE +27 -0
  11. data/LICENSE.sabre +27 -0
  12. data/README.md +30 -0
  13. data/Rakefile +17 -0
  14. data/lib/tilia/xml/context_stack_trait.rb +99 -0
  15. data/lib/tilia/xml/element/base.rb +73 -0
  16. data/lib/tilia/xml/element/cdata.rb +53 -0
  17. data/lib/tilia/xml/element/elements.rb +109 -0
  18. data/lib/tilia/xml/element/key_value.rb +110 -0
  19. data/lib/tilia/xml/element/uri.rb +98 -0
  20. data/lib/tilia/xml/element/xml_fragment.rb +128 -0
  21. data/lib/tilia/xml/element.rb +22 -0
  22. data/lib/tilia/xml/lib_xml_exception.rb +9 -0
  23. data/lib/tilia/xml/parse_exception.rb +7 -0
  24. data/lib/tilia/xml/reader.rb +240 -0
  25. data/lib/tilia/xml/service.rb +151 -0
  26. data/lib/tilia/xml/version.rb +9 -0
  27. data/lib/tilia/xml/writer.rb +261 -0
  28. data/lib/tilia/xml/xml_deserializable.rb +29 -0
  29. data/lib/tilia/xml/xml_serializable.rb +27 -0
  30. data/lib/tilia/xml.rb +23 -0
  31. data/test/test_helper.rb +4 -0
  32. data/test/xml/context_stack_test.rb +40 -0
  33. data/test/xml/element/cdata_test.rb +37 -0
  34. data/test/xml/element/eater.rb +60 -0
  35. data/test/xml/element/elements_test.rb +113 -0
  36. data/test/xml/element/key_value_test.rb +187 -0
  37. data/test/xml/element/mock.rb +52 -0
  38. data/test/xml/element/uri_test.rb +55 -0
  39. data/test/xml/element/xml_fragment_test.rb +121 -0
  40. data/test/xml/infite_loop_test.rb +47 -0
  41. data/test/xml/reader_test.rb +407 -0
  42. data/test/xml/service_test.rb +156 -0
  43. data/test/xml/writer_test.rb +260 -0
  44. data/tilia-xml.gemspec +15 -0
  45. metadata +132 -0
@@ -0,0 +1,121 @@
1
+ require 'test_helper'
2
+
3
+ module Tilia
4
+ module Xml
5
+ class XmlFragmentTest < Minitest::Test
6
+ # Data provider for serialize and deserialize tests.
7
+ #
8
+ # Returns three items per test:
9
+ #
10
+ # 1. Input data for the reader.
11
+ # 2. Expected output for XmlFragment deserializer
12
+ # 3. Expected output after serializing that value again.
13
+ #
14
+ # If 3 is not set, use 1 for 3.
15
+ #
16
+ # @return [Array]
17
+ def xml_provider
18
+ [
19
+ [
20
+ 'hello',
21
+ 'hello'
22
+ ],
23
+ [
24
+ '<element>hello</element>',
25
+ '<element xmlns="http://sabredav.org/ns">hello</element>'
26
+ ],
27
+ [
28
+ '<element foo="bar">hello</element>',
29
+ '<element xmlns="http://sabredav.org/ns" foo="bar">hello</element>'
30
+ ],
31
+ [
32
+ '<element x1:foo="bar" xmlns:x1="http://example.org/ns">hello</element>',
33
+ '<element xmlns:x1="http://example.org/ns" xmlns="http://sabredav.org/ns" x1:foo="bar">hello</element>'
34
+ ],
35
+ [
36
+ '<element xmlns="http://example.org/ns">hello</element>',
37
+ '<element xmlns="http://example.org/ns">hello</element>',
38
+ '<x1:element xmlns:x1="http://example.org/ns">hello</x1:element>'
39
+ ],
40
+ [
41
+ '<element xmlns:foo="http://example.org/ns">hello</element>',
42
+ '<element xmlns:foo="http://example.org/ns" xmlns="http://sabredav.org/ns">hello</element>',
43
+ '<element>hello</element>'
44
+ ],
45
+ [
46
+ '<foo:element xmlns:foo="http://example.org/ns">hello</foo:element>',
47
+ '<foo:element xmlns:foo="http://example.org/ns">hello</foo:element>',
48
+ '<x1:element xmlns:x1="http://example.org/ns">hello</x1:element>'
49
+ ],
50
+ [
51
+ '<foo:element xmlns:foo="http://example.org/ns"><child>hello</child></foo:element>',
52
+ '<foo:element xmlns:foo="http://example.org/ns" xmlns="http://sabredav.org/ns"><child>hello</child></foo:element>',
53
+ '<x1:element xmlns:x1="http://example.org/ns"><child>hello</child></x1:element>'
54
+ ],
55
+ [
56
+ '<foo:element xmlns:foo="http://example.org/ns"><child/></foo:element>',
57
+ '<foo:element xmlns:foo="http://example.org/ns" xmlns="http://sabredav.org/ns"><child/></foo:element>',
58
+ '<x1:element xmlns:x1="http://example.org/ns"><child/></x1:element>'
59
+ ],
60
+ [
61
+ '<foo:element xmlns:foo="http://example.org/ns"><child a="b"/></foo:element>',
62
+ '<foo:element xmlns:foo="http://example.org/ns" xmlns="http://sabredav.org/ns"><child a="b"/></foo:element>',
63
+ '<x1:element xmlns:x1="http://example.org/ns"><child a="b"/></x1:element>'
64
+ ]
65
+ ]
66
+ end
67
+
68
+ def test_deserialize
69
+ xml_provider.each do |data|
70
+ (input, expected) = data
71
+ input = <<BLA
72
+ <?xml version="1.0"?>
73
+ <root xmlns="http://sabredav.org/ns">
74
+ <fragment>#{input}</fragment>
75
+ </root>
76
+ BLA
77
+ reader = Tilia::Xml::Reader.new
78
+ reader.element_map = { '{http://sabredav.org/ns}fragment' => Tilia::Xml::Element::XmlFragment }
79
+ reader.xml(input)
80
+ output = reader.parse
81
+
82
+ result = {
83
+ 'name' => '{http://sabredav.org/ns}root',
84
+ 'value' => [
85
+ {
86
+ 'name' => '{http://sabredav.org/ns}fragment',
87
+ 'value' => Tilia::Xml::Element::XmlFragment.new(expected),
88
+ 'attributes' => {}
89
+ }
90
+ ],
91
+ 'attributes' => {}
92
+ }
93
+ assert_equal(result, output)
94
+ end
95
+ end
96
+
97
+ def test_serialize
98
+ xml_provider.each do |data|
99
+ (expected_fallback, input, expected) = data
100
+
101
+ expected = expected_fallback if expected.nil?
102
+
103
+ writer = Tilia::Xml::Writer.new
104
+ writer.namespace_map = { 'http://sabredav.org/ns' => nil }
105
+ writer.open_memory
106
+ writer.start_document
107
+ writer.write('{http://sabredav.org/ns}root' => { '{http://sabredav.org/ns}fragment' => Tilia::Xml::Element::XmlFragment.new(input) })
108
+ output = writer.output_memory
109
+
110
+ result = <<XML
111
+ <?xml version="1.0"?>
112
+ <root xmlns="http://sabredav.org/ns"><fragment>#{expected}</fragment></root>
113
+ XML
114
+ result.chomp!
115
+
116
+ assert_equal(result, output)
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,47 @@
1
+ require 'test_helper'
2
+
3
+ module Tilia
4
+ module Xml
5
+ class InfiteLoopTest < Minitest::Test
6
+ # This particular xml body caused the parser to go into an infinite loop.
7
+ # Need to know why.
8
+ def test_deserialize
9
+ body = <<XML
10
+ <?xml version="1.0"?>
11
+ <d:propertyupdate xmlns:d="DAV:" xmlns:s="http://sabredav.org/NS/test">
12
+ <d:set><d:prop></d:prop></d:set>
13
+ <d:set><d:prop></d:prop></d:set>
14
+ </d:propertyupdate>
15
+ XML
16
+ reader = Reader.new
17
+ reader.element_map = { '{DAV:}set' => Element::KeyValue }
18
+ reader.xml(body)
19
+
20
+ output = reader.parse
21
+
22
+ expected = {
23
+ 'name' => '{DAV:}propertyupdate',
24
+ 'value' => [
25
+ {
26
+ 'name' => '{DAV:}set',
27
+ 'value' => {
28
+ '{DAV:}prop' => nil
29
+ },
30
+ 'attributes' => {}
31
+ },
32
+ {
33
+ 'name' => '{DAV:}set',
34
+ 'value' => {
35
+ '{DAV:}prop' => nil
36
+ },
37
+ 'attributes' => {}
38
+ }
39
+ ],
40
+ 'attributes' => {}
41
+ }
42
+
43
+ assert_equal(expected, output)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,407 @@
1
+ require 'test_helper'
2
+ require 'xml/element/mock'
3
+ require 'xml/element/eater'
4
+
5
+ module Tilia
6
+ module Xml
7
+ class ReaderTest < Minitest::Test
8
+ def setup
9
+ @reader = Reader.new
10
+ end
11
+
12
+ def test_should_load_clark
13
+ input = <<BLA
14
+ <?xml version="1.0"?>
15
+ <root xmlns="http://sabredav.org/ns" />
16
+ BLA
17
+ @reader.xml(input)
18
+ @reader.next
19
+ assert_equal('{http://sabredav.org/ns}root', @reader.clark)
20
+ end
21
+
22
+ def test_should_get_clark_without_ns
23
+ input = <<BLA
24
+ <?xml version="1.0"?>
25
+ <root />
26
+ BLA
27
+ @reader.xml(input)
28
+ @reader.next
29
+ assert_equal('{}root', @reader.clark)
30
+ end
31
+
32
+ def test_should_load_clark_on_an_element
33
+ input = <<BLA
34
+ <?xml version="1.0"?>
35
+ <root />
36
+ BLA
37
+ @reader.xml(input)
38
+ assert_nil(@reader.clark)
39
+ end
40
+
41
+ def test_should_parse_a_simple_xml_file
42
+ input = <<BLA
43
+ <?xml version="1.0"?>
44
+ <root xmlns="http://sabredav.org/ns">
45
+ <elem1 attr="val" />
46
+ <elem2>
47
+ <elem3>Hi!</elem3>
48
+ </elem2>
49
+ </root>
50
+ BLA
51
+ @reader.xml(input)
52
+ output = @reader.parse
53
+
54
+ expected = {
55
+ 'name' => '{http://sabredav.org/ns}root',
56
+ 'value' => [
57
+ {
58
+ 'name' => '{http://sabredav.org/ns}elem1',
59
+ 'value' => nil,
60
+ 'attributes' => {
61
+ 'attr' => 'val'
62
+ }
63
+ },
64
+ {
65
+ 'name' => '{http://sabredav.org/ns}elem2',
66
+ 'value' => [
67
+ {
68
+ 'name' => '{http://sabredav.org/ns}elem3',
69
+ 'value' => 'Hi!',
70
+ 'attributes' => {}
71
+ }
72
+ ],
73
+ 'attributes' => {}
74
+ }
75
+ ],
76
+ 'attributes' => {}
77
+ }
78
+
79
+ assert_equal(expected, output)
80
+ end
81
+
82
+ def test_should_work_with_cdata
83
+ input = <<BLA
84
+ <?xml version="1.0"?>
85
+ <root xmlns="http://sabredav.org/ns">
86
+ <foo><![CDATA[bar]]></foo>
87
+ </root>
88
+ BLA
89
+ @reader.xml(input)
90
+ output = @reader.parse
91
+
92
+ expected = {
93
+ 'name' => '{http://sabredav.org/ns}root',
94
+ 'value' => [
95
+ {
96
+ 'name' => '{http://sabredav.org/ns}foo',
97
+ 'value' => 'bar',
98
+ 'attributes' => {}
99
+ }
100
+ ],
101
+ 'attributes' => {}
102
+ }
103
+
104
+ assert_equal(expected, output)
105
+ end
106
+
107
+ def test_should_read_simple_namespaced_attributes
108
+ input = <<BLA
109
+ <?xml version="1.0"?>
110
+ <root xmlns="http://sabredav.org/ns" xmlns:foo="urn:foo">
111
+ <elem1 foo:attr="val" />
112
+ </root>
113
+ BLA
114
+ @reader.xml(input)
115
+ output = @reader.parse
116
+
117
+ expected = {
118
+ 'name' => '{http://sabredav.org/ns}root',
119
+ 'value' => [
120
+ {
121
+ 'name' => '{http://sabredav.org/ns}elem1',
122
+ 'value' => nil,
123
+ 'attributes' => {
124
+ '{urn:foo}attr' => 'val'
125
+ }
126
+ }
127
+ ],
128
+ 'attributes' => {}
129
+ }
130
+
131
+ assert_equal(expected, output)
132
+ end
133
+
134
+ def test_should_read_mapped_elements
135
+ input = <<BLA
136
+ <?xml version="1.0"?>
137
+ <root xmlns="http://sabredav.org/ns">
138
+ <elem1 />
139
+ </root>
140
+ BLA
141
+ @reader.element_map = {
142
+ '{http://sabredav.org/ns}elem1' => Element::Mock
143
+ }
144
+ @reader.xml(input)
145
+ output = @reader.parse
146
+
147
+ expected = {
148
+ 'name' => '{http://sabredav.org/ns}root',
149
+ 'value' => [
150
+ {
151
+ 'name' => '{http://sabredav.org/ns}elem1',
152
+ 'value' => 'foobar',
153
+ 'attributes' => {}
154
+ }
155
+ ],
156
+ 'attributes' => {}
157
+ }
158
+
159
+ assert_equal(expected, output)
160
+ end
161
+
162
+ def test_should_activate_mapped_element_callbacks
163
+ input = <<BLA
164
+ <?xml version="1.0"?>
165
+ <root xmlns="http://sabredav.org/ns">
166
+ <elem1 />
167
+ </root>
168
+ BLA
169
+ @reader.element_map = {
170
+ '{http://sabredav.org/ns}elem1' => lambda do |reader|
171
+ reader.next
172
+ 'foobar'
173
+ end
174
+ }
175
+ @reader.xml(input)
176
+ output = @reader.parse
177
+
178
+ expected = {
179
+ 'name' => '{http://sabredav.org/ns}root',
180
+ 'value' => [
181
+ {
182
+ 'name' => '{http://sabredav.org/ns}elem1',
183
+ 'value' => 'foobar',
184
+ 'attributes' => {}
185
+ }
186
+ ],
187
+ 'attributes' => {}
188
+ }
189
+
190
+ assert_equal(expected, output)
191
+ end
192
+
193
+ def test_should_read_text
194
+ input = <<BLA
195
+ <?xml version="1.0"?>
196
+ <root xmlns="http://sabredav.org/ns">
197
+ <elem1>
198
+ <elem2>hello </elem2>
199
+ <elem2>world</elem2>
200
+ </elem1>
201
+ </root>
202
+ BLA
203
+ @reader.element_map = {
204
+ '{http://sabredav.org/ns}elem1' => ->(reader) { reader.read_text }
205
+ }
206
+ @reader.xml(input)
207
+ output = @reader.parse
208
+
209
+ expected = {
210
+ 'name' => '{http://sabredav.org/ns}root',
211
+ 'value' => [
212
+ {
213
+ 'name' => '{http://sabredav.org/ns}elem1',
214
+ 'value' => 'hello world',
215
+ 'attributes' => {}
216
+ }
217
+ ],
218
+ 'attributes' => {}
219
+ }
220
+
221
+ assert_equal(expected, output)
222
+ end
223
+
224
+ def test_should_raise_exceptions
225
+ input = <<BLA
226
+ <?xml version="1.0"?>
227
+ <root xmlns="http://sabredav.org/ns">
228
+ BLA
229
+ @reader.element_map = {
230
+ '{http://sabredav.org/ns}elem1' => Element::Mock
231
+ }
232
+ @reader.xml(input)
233
+
234
+ assert_raises(LibXmlException) { @reader.parse }
235
+ end
236
+
237
+ def test_should_handle_broken_parser
238
+ input = <<BLA
239
+ <?xml version="1.0"?>
240
+ <root xmlns="http://sabredav.org/ns">
241
+ <elem1 />
242
+ </root>
243
+ BLA
244
+ @reader.element_map = {
245
+ '{http://sabredav.org/ns}elem1' => Element::Eater
246
+ }
247
+ @reader.xml(input)
248
+ assert_raises(ParseException) { @reader.parse }
249
+ end
250
+
251
+ def test_should_handle_invalid_xml
252
+ input = <<BLA
253
+ <test>
254
+ <hello>
255
+ </hello>
256
+ </sffsdf>
257
+ BLA
258
+ @reader.xml(input)
259
+ assert_raises(LibXmlException) { @reader.parse }
260
+ end
261
+
262
+ def test_should_handle_invalid_xml_2
263
+ input = <<BLA
264
+ <?xml version="1.0" encoding="UTF-8"?>
265
+ <definitions>
266
+ <collaboration>
267
+ <participant id="sid-A33D08EB-A2DE-448F-86FE-A2B62E98818" name="Company" processRef="sid-A0A6A196-3C9A-4C69-88F6-7ED7DDFDD264">
268
+ <extensionElements>
269
+ <signavio:signavioMetaData metaKey="bgcolor" />
270
+ ""Administrative w">
271
+ <extensionElements>
272
+ <signavio:signavioMetaData metaKey="bgcolor" metaValue=""/>
273
+ </extensionElements>
274
+ </lan
275
+ BLA
276
+ @reader.xml(input)
277
+ assert_raises(LibXmlException) { @reader.parse }
278
+ end
279
+
280
+ def test_should_parse_an_inner_tree
281
+ input = <<BLA
282
+ <?xml version="1.0"?>
283
+ <root xmlns="http://sabredav.org/ns">
284
+ <elem1>
285
+ <elem1 />
286
+ </elem1>
287
+ </root>
288
+ BLA
289
+ @reader.element_map = {
290
+ '{http://sabredav.org/ns}elem1' => lambda do |reader|
291
+ inner_tree = reader.parse_inner_tree(
292
+ '{http://sabredav.org/ns}elem1' => lambda do |lambda_reader|
293
+ lambda_reader.next
294
+ 'foobar'
295
+ end
296
+ )
297
+ inner_tree
298
+ end
299
+ }
300
+ @reader.xml(input)
301
+ output = @reader.parse
302
+
303
+ expected = {
304
+ 'name' => '{http://sabredav.org/ns}root',
305
+ 'value' => [
306
+ {
307
+ 'name' => '{http://sabredav.org/ns}elem1',
308
+ 'value' => [
309
+ {
310
+ 'name' => '{http://sabredav.org/ns}elem1',
311
+ 'value' => 'foobar',
312
+ 'attributes' => {}
313
+ }
314
+ ],
315
+ 'attributes' => {}
316
+ }
317
+ ],
318
+ 'attributes' => {}
319
+ }
320
+
321
+ assert_equal(expected, output)
322
+ end
323
+
324
+ def test_should_use_parse_get_elements
325
+ input = <<BLA
326
+ <?xml version="1.0"?>
327
+ <root xmlns="http://sabredav.org/ns">
328
+ <elem1>
329
+ <elem1 />
330
+ </elem1>
331
+ </root>
332
+ BLA
333
+ @reader.element_map = {
334
+ '{http://sabredav.org/ns}elem1' => lambda do |reader|
335
+ inner_tree = reader.parse_get_elements(
336
+ '{http://sabredav.org/ns}elem1' => lambda do |lambda_reader|
337
+ lambda_reader.next
338
+ 'foobar'
339
+ end
340
+ )
341
+ inner_tree
342
+ end
343
+ }
344
+ @reader.xml(input)
345
+ output = @reader.parse
346
+
347
+ expected = {
348
+ 'name' => '{http://sabredav.org/ns}root',
349
+ 'value' => [
350
+ {
351
+ 'name' => '{http://sabredav.org/ns}elem1',
352
+ 'value' => [
353
+ {
354
+ 'name' => '{http://sabredav.org/ns}elem1',
355
+ 'value' => 'foobar',
356
+ 'attributes' => {}
357
+ }
358
+ ],
359
+ 'attributes' => {}
360
+ }
361
+ ],
362
+ 'attributes' => {}
363
+ }
364
+
365
+ assert_equal(expected, output)
366
+ end
367
+
368
+ def test_should_work_with_no_elements
369
+ input = <<BLA
370
+ <?xml version="1.0"?>
371
+ <root xmlns="http://sabredav.org/ns">
372
+ <elem1>
373
+ hi
374
+ </elem1>
375
+ </root>
376
+ BLA
377
+ @reader.element_map = {
378
+ '{http://sabredav.org/ns}elem1' => lambda do |reader|
379
+ inner_tree = reader.parse_get_elements(
380
+ '{http://sabredav.org/ns}elem1' => lambda do |lambda_reader|
381
+ lambda_reader.next
382
+ 'foobar'
383
+ end
384
+ )
385
+ inner_tree
386
+ end
387
+ }
388
+ @reader.xml(input)
389
+ output = @reader.parse
390
+
391
+ expected = {
392
+ 'name' => '{http://sabredav.org/ns}root',
393
+ 'value' => [
394
+ {
395
+ 'name' => '{http://sabredav.org/ns}elem1',
396
+ 'value' => [],
397
+ 'attributes' => {}
398
+ }
399
+ ],
400
+ 'attributes' => {}
401
+ }
402
+
403
+ assert_equal(expected, output)
404
+ end
405
+ end
406
+ end
407
+ end