tilia-xml 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
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,156 @@
1
+ require 'test_helper'
2
+ require 'stringio'
3
+
4
+ module Tilia
5
+ module Xml
6
+ class ServiceTest < Minitest::Test
7
+ def setup
8
+ @util = Service.new
9
+ end
10
+
11
+ def test_get_reader
12
+ elems = { '{http://sabre.io/ns}test' => 'Test!' }
13
+
14
+ @util.element_map = elems
15
+
16
+ reader = @util.reader
17
+ assert_instance_of(Reader, reader)
18
+ assert_equal(elems, reader.element_map)
19
+ end
20
+
21
+ def test_get_writer
22
+ ns = { 'http://sabre.io/ns' => 's' }
23
+
24
+ @util.namespace_map = ns
25
+ writer = @util.writer
26
+
27
+ assert_instance_of(Writer, writer)
28
+ assert_equal(ns, writer.namespace_map)
29
+ end
30
+
31
+ def test_parse
32
+ xml = <<XML
33
+ <root xmlns="http://sabre.io/ns">
34
+ <child>value</child>
35
+ </root>
36
+ XML
37
+ root_element = ''
38
+ result = @util.parse(xml, nil, root_element)
39
+ assert_equal('{http://sabre.io/ns}root', root_element)
40
+
41
+ expected = [
42
+ {
43
+ 'name' => '{http://sabre.io/ns}child',
44
+ 'value' => 'value',
45
+ 'attributes' => {}
46
+ }
47
+ ]
48
+
49
+ assert_equal(expected, result)
50
+ end
51
+
52
+ def test_parse_stream
53
+ xml = <<XML
54
+ <root xmlns="http://sabre.io/ns">
55
+ <child>value</child>
56
+ </root>
57
+ XML
58
+ stream = StringIO.new
59
+ stream.write xml
60
+ stream.rewind
61
+
62
+ root_element = ''
63
+ result = @util.parse(stream, nil, root_element)
64
+ assert_equal('{http://sabre.io/ns}root', root_element)
65
+
66
+ expected = [
67
+ {
68
+ 'name' => '{http://sabre.io/ns}child',
69
+ 'value' => 'value',
70
+ 'attributes' => {}
71
+ }
72
+ ]
73
+
74
+ assert_equal(expected, result)
75
+ end
76
+
77
+ def test_expect
78
+ xml = <<XML
79
+ <root xmlns="http://sabre.io/ns">
80
+ <child>value</child>
81
+ </root>
82
+ XML
83
+ result = @util.expect('{http://sabre.io/ns}root', xml)
84
+
85
+ expected = [
86
+ {
87
+ 'name' => '{http://sabre.io/ns}child',
88
+ 'value' => 'value',
89
+ 'attributes' => {}
90
+ }
91
+ ]
92
+
93
+ assert_equal(expected, result)
94
+ end
95
+
96
+ def test_expect_stream
97
+ xml = <<XML
98
+ <root xmlns="http://sabre.io/ns">
99
+ <child>value</child>
100
+ </root>
101
+ XML
102
+
103
+ stream = StringIO.new
104
+ stream.write xml
105
+ stream.rewind
106
+
107
+ result = @util.expect('{http://sabre.io/ns}root', xml)
108
+
109
+ expected = [
110
+ {
111
+ 'name' => '{http://sabre.io/ns}child',
112
+ 'value' => 'value',
113
+ 'attributes' => {}
114
+ }
115
+ ]
116
+
117
+ assert_equal(expected, result)
118
+ end
119
+
120
+ def test_expect_wrong
121
+ xml = <<XML
122
+ <root xmlns="http://sabre.io/ns">
123
+ <child>value</child>
124
+ </root>
125
+ XML
126
+ assert_raises(ParseException) { @util.expect('{http://sabre.io/ns}error', xml) }
127
+ end
128
+
129
+ def test_write
130
+ @util.namespace_map = { 'http://sabre.io/ns' => 's' }
131
+ result = @util.write(
132
+ '{http://sabre.io/ns}root',
133
+ '{http://sabre.io/ns}child' => 'value'
134
+ )
135
+
136
+ expected = <<XML
137
+ <?xml version="1.0"?>
138
+ <s:root xmlns:s="http://sabre.io/ns">
139
+ <s:child>value</s:child>
140
+ </s:root>
141
+ XML
142
+ assert_equal(expected, result)
143
+ end
144
+
145
+ def test_parse_clark_notation
146
+ expected = ['http://sabredav.org/ns', 'elem']
147
+ result = Service.parse_clark_notation('{http://sabredav.org/ns}elem')
148
+ assert_equal(expected, result)
149
+ end
150
+
151
+ def test_parse_clark_notation_fail
152
+ assert_raises(ArgumentError) { Service.parse_clark_notation('http://sabredav.org/ns}elem') }
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,260 @@
1
+ require 'test_helper'
2
+ require 'stringio'
3
+
4
+ module Tilia
5
+ module Xml
6
+ class WriterTest < Minitest::Test
7
+ def setup
8
+ @writer = Tilia::Xml::Writer.new
9
+ @writer.namespace_map = { 'http://sabredav.org/ns' => 's' }
10
+ @writer.open_memory
11
+ @writer.set_indent(true)
12
+ @writer.start_document
13
+ end
14
+
15
+ def compare(input, output)
16
+ @writer.write(input)
17
+ assert_equal(output, @writer.output_memory)
18
+ end
19
+
20
+ # rubocop:disable Style/ClosingParenthesisIndentation
21
+ # Rubocop has a problem with the closing parenthesis of the long compare()
22
+ # statements, but IMO that's the best way.
23
+ def test_simple
24
+ compare(
25
+ { '{http://sabredav.org/ns}root' => 'text' },
26
+ <<HI
27
+ <?xml version="1.0"?>
28
+ <s:root xmlns:s="http://sabredav.org/ns">text</s:root>
29
+ HI
30
+ )
31
+ end
32
+
33
+ def test_simple_quotes
34
+ compare({ '{http://sabredav.org/ns}root' => '"text"' }, <<HI
35
+ <?xml version="1.0"?>
36
+ <s:root xmlns:s="http://sabredav.org/ns">&quot;text&quot;</s:root>
37
+ HI
38
+ )
39
+ end
40
+
41
+ def test_simple_attributes
42
+ compare(
43
+ {
44
+ '{http://sabredav.org/ns}root' => {
45
+ 'value' => 'text',
46
+ 'attributes' => {
47
+ 'attr1' => 'attribute value'
48
+ }
49
+ }
50
+ }, <<HI
51
+ <?xml version="1.0"?>
52
+ <s:root xmlns:s="http://sabredav.org/ns" attr1="attribute value">text</s:root>
53
+ HI
54
+ )
55
+ end
56
+
57
+ def test_mixed_syntax
58
+ compare(
59
+ {
60
+ '{http://sabredav.org/ns}root' => {
61
+ 'single' => 'value',
62
+ 'multiple' => [
63
+ {
64
+ 'name' => 'foo',
65
+ 'value' => 'bar'
66
+ },
67
+ {
68
+ 'name' => 'foo',
69
+ 'value' => 'foobar'
70
+ }
71
+ ],
72
+ 'attributes' => {
73
+ 'value' => nil,
74
+ 'attributes' => {
75
+ 'foo' => 'bar'
76
+ }
77
+ },
78
+ 'verbose' => { # RUBY
79
+ # 'name' => 'verbose', # RUBY
80
+ 'value' => 'syntax',
81
+ 'attributes' => {
82
+ 'foo' => 'bar'
83
+ }
84
+ }
85
+ }
86
+ }, <<HI
87
+ <?xml version="1.0"?>
88
+ <s:root xmlns:s="http://sabredav.org/ns">
89
+ <single>value</single>
90
+ <multiple>
91
+ <foo>bar</foo>
92
+ <foo>foobar</foo>
93
+ </multiple>
94
+ <attributes foo="bar"/>
95
+ <verbose foo="bar">syntax</verbose>
96
+ </s:root>
97
+ HI
98
+ )
99
+ end
100
+
101
+ def test_null
102
+ compare({ '{http://sabredav.org/ns}root' => nil }, <<HI
103
+ <?xml version="1.0"?>
104
+ <s:root xmlns:s="http://sabredav.org/ns"/>
105
+ HI
106
+ )
107
+ end
108
+
109
+ def test_array_format2
110
+ compare(
111
+ {
112
+ '{http://sabredav.org/ns}root' => [
113
+ {
114
+ 'name' => '{http://sabredav.org/ns}elem1',
115
+ 'value' => 'text',
116
+ 'attributes' => {
117
+ 'attr1' => 'attribute value'
118
+ }
119
+ }
120
+ ]
121
+ }, <<HI
122
+ <?xml version="1.0"?>
123
+ <s:root xmlns:s="http://sabredav.org/ns">
124
+ <s:elem1 attr1="attribute value">text</s:elem1>
125
+ </s:root>
126
+ HI
127
+ )
128
+ end
129
+
130
+ def test_custom_namespace
131
+ compare(
132
+ {
133
+ '{http://sabredav.org/ns}root' => {
134
+ '{urn:foo}elem1' => 'bar'
135
+ }
136
+ }, <<HI
137
+ <?xml version="1.0"?>
138
+ <s:root xmlns:s="http://sabredav.org/ns">
139
+ <x1:elem1 xmlns:x1="urn:foo">bar</x1:elem1>
140
+ </s:root>
141
+ HI
142
+ )
143
+ end
144
+
145
+ def test_empty_namespace
146
+ # Empty namespaces are allowed, so we should support this.
147
+ compare({ '{http://sabredav.org/ns}root' => { '{}elem1' => 'bar' } }, <<HI
148
+ <?xml version="1.0"?>
149
+ <s:root xmlns:s="http://sabredav.org/ns">
150
+ <elem1 xmlns="">bar</elem1>
151
+ </s:root>
152
+ HI
153
+ )
154
+ end
155
+
156
+ def test_attributes
157
+ compare(
158
+ {
159
+ '{http://sabredav.org/ns}root' => [
160
+ {
161
+ 'name' => '{http://sabredav.org/ns}elem1',
162
+ 'value' => 'text',
163
+ 'attributes' => {
164
+ 'attr1' => 'val1',
165
+ '{http://sabredav.org/ns}attr2' => 'val2',
166
+ '{urn:foo}attr3' => 'val3'
167
+ }
168
+ }
169
+ ]
170
+ }, <<HI
171
+ <?xml version="1.0"?>
172
+ <s:root xmlns:s="http://sabredav.org/ns">
173
+ <s:elem1 attr1="val1" s:attr2="val2" x1:attr3="val3" xmlns:x1="urn:foo">text</s:elem1>
174
+ </s:root>
175
+ HI
176
+ )
177
+ end
178
+
179
+ def test_invalid_format
180
+ assert_raises(ArgumentError) do
181
+ compare(
182
+ {
183
+ '{http://sabredav.org/ns}root' => [
184
+ { 'incorrect' => '0', 'keynames' => 1 }
185
+ ]
186
+ },
187
+ ''
188
+ )
189
+ end
190
+ end
191
+
192
+ def test_base_element
193
+ compare({ '{http://sabredav.org/ns}root' => Tilia::Xml::Element::Base.new('hello') }, <<HI
194
+ <?xml version="1.0"?>
195
+ <s:root xmlns:s="http://sabredav.org/ns">hello</s:root>
196
+ HI
197
+ )
198
+ end
199
+
200
+ def test_element_obj
201
+ compare({ '{http://sabredav.org/ns}root' => Tilia::Xml::Element::Mock.new }, <<HI
202
+ <?xml version="1.0"?>
203
+ <s:root xmlns:s="http://sabredav.org/ns">
204
+ <s:elem1>hiiii!</s:elem1>
205
+ </s:root>
206
+ HI
207
+ )
208
+ end
209
+
210
+ def test_empty_namespace_prefix
211
+ @writer.namespace_map['http://sabredav.org/ns'] = nil
212
+ compare({ '{http://sabredav.org/ns}root' => Tilia::Xml::Element::Mock.new }, <<HI
213
+ <?xml version="1.0"?>
214
+ <root xmlns="http://sabredav.org/ns">
215
+ <elem1>hiiii!</elem1>
216
+ </root>
217
+ HI
218
+ )
219
+ end
220
+
221
+ def test_write_element
222
+ @writer.write_element('{http://sabredav.org/ns}foo', 'content')
223
+
224
+ output = <<HI
225
+ <?xml version="1.0"?>
226
+ <s:foo xmlns:s="http://sabredav.org/ns">content</s:foo>
227
+ HI
228
+ assert_equal(output, @writer.output_memory)
229
+ end
230
+
231
+ def test_write_element_complex
232
+ @writer.write_element('{http://sabredav.org/ns}foo', Tilia::Xml::Element::KeyValue.new('{http://sabredav.org/ns}bar' => 'test'))
233
+
234
+ output = <<HI
235
+ <?xml version="1.0"?>
236
+ <s:foo xmlns:s="http://sabredav.org/ns">
237
+ <s:bar>test</s:bar>
238
+ </s:foo>
239
+ HI
240
+ assert_equal(output, @writer.output_memory)
241
+ end
242
+
243
+ def test_write_bad_object
244
+ assert_raises(ArgumentError) { @writer.write(Class.new) }
245
+ end
246
+
247
+ def test_start_element_simple
248
+ @writer.start_element('foo')
249
+ @writer.end_element
250
+
251
+ output = <<HI
252
+ <?xml version="1.0"?>
253
+ <foo xmlns:s="http://sabredav.org/ns"/>
254
+ HI
255
+ assert_equal(output, @writer.output_memory)
256
+ end
257
+ # rubocop:enable Style/ClosingParenthesisIndentation
258
+ end
259
+ end
260
+ end
data/tilia-xml.gemspec ADDED
@@ -0,0 +1,15 @@
1
+ require File.join(File.dirname(__FILE__), 'lib', 'tilia', 'xml', 'version')
2
+ Gem::Specification.new do |s|
3
+ s.name = 'tilia-xml'
4
+ s.version = Tilia::Xml::Version::VERSION
5
+ s.licenses = ['BSD-3-Clause']
6
+ s.summary = 'Port of the sabre-xml library to ruby.'
7
+ s.description = "Port of the sabre-xml library to ruby.\n\nThe Tilia XML parser is the only XML library that you may not hate."
8
+ s.author = 'Jakob Sack'
9
+ s.email = 'tilia@jakobsack.de'
10
+ s.files = `git ls-files`.split("\n")
11
+ s.homepage = 'https://github.com/tilia/tilia-xml'
12
+ s.add_runtime_dependency 'activesupport', '~> 4.2'
13
+ s.add_runtime_dependency 'libxml-ruby', '~> 2.8'
14
+ s.add_runtime_dependency 'tilia-uri', '~> 1.0'
15
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tilia-xml
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.0
5
+ platform: ruby
6
+ authors:
7
+ - Jakob Sack
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-12-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '4.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '4.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: libxml-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.8'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.8'
41
+ - !ruby/object:Gem::Dependency
42
+ name: tilia-uri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ description: |-
56
+ Port of the sabre-xml library to ruby.
57
+
58
+ The Tilia XML parser is the only XML library that you may not hate.
59
+ email: tilia@jakobsack.de
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - ".gitignore"
65
+ - ".rubocop.yml"
66
+ - ".simplecov"
67
+ - ".travis.yml"
68
+ - CHANGELOG.sabre.md
69
+ - CONTRIBUTING.md
70
+ - Gemfile
71
+ - Gemfile.lock
72
+ - LICENSE
73
+ - LICENSE.sabre
74
+ - README.md
75
+ - Rakefile
76
+ - lib/tilia/xml.rb
77
+ - lib/tilia/xml/context_stack_trait.rb
78
+ - lib/tilia/xml/element.rb
79
+ - lib/tilia/xml/element/base.rb
80
+ - lib/tilia/xml/element/cdata.rb
81
+ - lib/tilia/xml/element/elements.rb
82
+ - lib/tilia/xml/element/key_value.rb
83
+ - lib/tilia/xml/element/uri.rb
84
+ - lib/tilia/xml/element/xml_fragment.rb
85
+ - lib/tilia/xml/lib_xml_exception.rb
86
+ - lib/tilia/xml/parse_exception.rb
87
+ - lib/tilia/xml/reader.rb
88
+ - lib/tilia/xml/service.rb
89
+ - lib/tilia/xml/version.rb
90
+ - lib/tilia/xml/writer.rb
91
+ - lib/tilia/xml/xml_deserializable.rb
92
+ - lib/tilia/xml/xml_serializable.rb
93
+ - test/test_helper.rb
94
+ - test/xml/context_stack_test.rb
95
+ - test/xml/element/cdata_test.rb
96
+ - test/xml/element/eater.rb
97
+ - test/xml/element/elements_test.rb
98
+ - test/xml/element/key_value_test.rb
99
+ - test/xml/element/mock.rb
100
+ - test/xml/element/uri_test.rb
101
+ - test/xml/element/xml_fragment_test.rb
102
+ - test/xml/infite_loop_test.rb
103
+ - test/xml/reader_test.rb
104
+ - test/xml/service_test.rb
105
+ - test/xml/writer_test.rb
106
+ - tilia-xml.gemspec
107
+ homepage: https://github.com/tilia/tilia-xml
108
+ licenses:
109
+ - BSD-3-Clause
110
+ metadata: {}
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ requirements: []
126
+ rubyforge_project:
127
+ rubygems_version: 2.2.5
128
+ signing_key:
129
+ specification_version: 4
130
+ summary: Port of the sabre-xml library to ruby.
131
+ test_files: []
132
+ has_rdoc: