xml_mini 0.1.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.
- data/.gitignore +18 -0
- data/.rvmrc +1 -0
- data/Gemfile +20 -0
- data/Guardfile +15 -0
- data/LICENSE +22 -0
- data/README.md +31 -0
- data/Rakefile +11 -0
- data/lib/core_ext/array.rb +45 -0
- data/lib/core_ext/blank.rb +112 -0
- data/lib/core_ext/hash.rb +72 -0
- data/lib/xml_mini.rb +160 -0
- data/lib/xml_mini/libxml.rb +63 -0
- data/lib/xml_mini/libxmlsax.rb +84 -0
- data/lib/xml_mini/node_hash.rb +29 -0
- data/lib/xml_mini/nokogiri.rb +64 -0
- data/lib/xml_mini/nokogirisax.rb +81 -0
- data/lib/xml_mini/rexml.rb +126 -0
- data/lib/xml_mini/version.rb +3 -0
- data/test/lib/xml_mini/libxml_engine_test.rb +202 -0
- data/test/lib/xml_mini/libxmlsax_engine_test.rb +193 -0
- data/test/lib/xml_mini/nokogiri_engine_test.rb +215 -0
- data/test/lib/xml_mini/nokogirisax_engine_test.rb +216 -0
- data/test/lib/xml_mini/rexml_engine_test.rb +28 -0
- data/test/lib/xml_mini_test.rb +89 -0
- data/test/test_helper.rb +7 -0
- data/xml_mini.gemspec +17 -0
- metadata +84 -0
@@ -0,0 +1,216 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
# require 'active_support/xml_mini'
|
3
|
+
# require 'active_support/core_ext/hash/conversions'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'nokogiri'
|
7
|
+
rescue LoadError
|
8
|
+
# Skip nokogiri tests
|
9
|
+
else
|
10
|
+
|
11
|
+
class NokogiriSAXEngineTest < MiniTest::Unit::TestCase
|
12
|
+
|
13
|
+
def setup
|
14
|
+
@default_backend = XmlMini.backend
|
15
|
+
XmlMini.backend = 'NokogiriSAX'
|
16
|
+
end
|
17
|
+
|
18
|
+
def teardown
|
19
|
+
XmlMini.backend = @default_backend
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_file_from_minixml
|
23
|
+
hash = Hash.from_minixml(<<-eoxml)
|
24
|
+
<blog>
|
25
|
+
<logo type="file" name="logo.png" content_type="image/png">
|
26
|
+
</logo>
|
27
|
+
</blog>
|
28
|
+
eoxml
|
29
|
+
assert hash.has_key?('blog')
|
30
|
+
assert hash['blog'].has_key?('logo')
|
31
|
+
|
32
|
+
file = hash['blog']['logo']
|
33
|
+
assert_equal 'logo.png', file.original_filename
|
34
|
+
assert_equal 'image/png', file.content_type
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_exception_thrown_on_expansion_attack
|
38
|
+
assert_raises RuntimeError do
|
39
|
+
attack_xml = <<-EOT
|
40
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
41
|
+
<!DOCTYPE member [
|
42
|
+
<!ENTITY a "&b;&b;&b;&b;&b;&b;&b;&b;&b;&b;">
|
43
|
+
<!ENTITY b "&c;&c;&c;&c;&c;&c;&c;&c;&c;&c;">
|
44
|
+
<!ENTITY c "&d;&d;&d;&d;&d;&d;&d;&d;&d;&d;">
|
45
|
+
<!ENTITY d "&e;&e;&e;&e;&e;&e;&e;&e;&e;&e;">
|
46
|
+
<!ENTITY e "&f;&f;&f;&f;&f;&f;&f;&f;&f;&f;">
|
47
|
+
<!ENTITY f "&g;&g;&g;&g;&g;&g;&g;&g;&g;&g;">
|
48
|
+
<!ENTITY g "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
|
49
|
+
]>
|
50
|
+
<member>
|
51
|
+
&a;
|
52
|
+
</member>
|
53
|
+
EOT
|
54
|
+
|
55
|
+
Hash.from_minixml(attack_xml)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def test_setting_nokogiri_as_backend
|
60
|
+
XmlMini.backend = 'Nokogiri'
|
61
|
+
assert_equal XmlMini_Nokogiri, XmlMini.backend
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_blank_returns_empty_hash
|
65
|
+
assert_equal({}, XmlMini.parse(nil))
|
66
|
+
assert_equal({}, XmlMini.parse(''))
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_array_type_makes_an_array
|
70
|
+
assert_equal_rexml(<<-eoxml)
|
71
|
+
<blog>
|
72
|
+
<posts type="array">
|
73
|
+
<post>a post</post>
|
74
|
+
<post>another post</post>
|
75
|
+
</posts>
|
76
|
+
</blog>
|
77
|
+
eoxml
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_one_node_document_as_hash
|
81
|
+
assert_equal_rexml(<<-eoxml)
|
82
|
+
<products/>
|
83
|
+
eoxml
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_one_node_with_attributes_document_as_hash
|
87
|
+
assert_equal_rexml(<<-eoxml)
|
88
|
+
<products foo="bar"/>
|
89
|
+
eoxml
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_products_node_with_book_node_as_hash
|
93
|
+
assert_equal_rexml(<<-eoxml)
|
94
|
+
<products>
|
95
|
+
<book name="awesome" id="12345" />
|
96
|
+
</products>
|
97
|
+
eoxml
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_products_node_with_two_book_nodes_as_hash
|
101
|
+
assert_equal_rexml(<<-eoxml)
|
102
|
+
<products>
|
103
|
+
<book name="awesome" id="12345" />
|
104
|
+
<book name="america" id="67890" />
|
105
|
+
</products>
|
106
|
+
eoxml
|
107
|
+
end
|
108
|
+
|
109
|
+
def test_single_node_with_content_as_hash
|
110
|
+
assert_equal_rexml(<<-eoxml)
|
111
|
+
<products>
|
112
|
+
hello world
|
113
|
+
</products>
|
114
|
+
eoxml
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_children_with_children
|
118
|
+
assert_equal_rexml(<<-eoxml)
|
119
|
+
<root>
|
120
|
+
<products>
|
121
|
+
<book name="america" id="67890" />
|
122
|
+
</products>
|
123
|
+
</root>
|
124
|
+
eoxml
|
125
|
+
end
|
126
|
+
|
127
|
+
def test_children_with_text
|
128
|
+
assert_equal_rexml(<<-eoxml)
|
129
|
+
<root>
|
130
|
+
<products>
|
131
|
+
hello everyone
|
132
|
+
</products>
|
133
|
+
</root>
|
134
|
+
eoxml
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_children_with_non_adjacent_text
|
138
|
+
assert_equal_rexml(<<-eoxml)
|
139
|
+
<root>
|
140
|
+
good
|
141
|
+
<products>
|
142
|
+
hello everyone
|
143
|
+
</products>
|
144
|
+
morning
|
145
|
+
</root>
|
146
|
+
eoxml
|
147
|
+
end
|
148
|
+
|
149
|
+
def test_parse_from_io
|
150
|
+
io = StringIO.new(<<-eoxml)
|
151
|
+
<root>
|
152
|
+
good
|
153
|
+
<products>
|
154
|
+
hello everyone
|
155
|
+
</products>
|
156
|
+
morning
|
157
|
+
</root>
|
158
|
+
eoxml
|
159
|
+
XmlMini.parse(io)
|
160
|
+
end
|
161
|
+
|
162
|
+
def test_children_with_simple_cdata
|
163
|
+
assert_equal_rexml(<<-eoxml)
|
164
|
+
<root>
|
165
|
+
<products>
|
166
|
+
<![CDATA[cdatablock]]>
|
167
|
+
</products>
|
168
|
+
</root>
|
169
|
+
eoxml
|
170
|
+
end
|
171
|
+
|
172
|
+
def test_children_with_multiple_cdata
|
173
|
+
assert_equal_rexml(<<-eoxml)
|
174
|
+
<root>
|
175
|
+
<products>
|
176
|
+
<![CDATA[cdatablock1]]><![CDATA[cdatablock2]]>
|
177
|
+
</products>
|
178
|
+
</root>
|
179
|
+
eoxml
|
180
|
+
end
|
181
|
+
|
182
|
+
def test_children_with_text_and_cdata
|
183
|
+
assert_equal_rexml(<<-eoxml)
|
184
|
+
<root>
|
185
|
+
<products>
|
186
|
+
hello <![CDATA[cdatablock]]>
|
187
|
+
morning
|
188
|
+
</products>
|
189
|
+
</root>
|
190
|
+
eoxml
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_children_with_blank_text
|
194
|
+
assert_equal_rexml(<<-eoxml)
|
195
|
+
<root>
|
196
|
+
<products> </products>
|
197
|
+
</root>
|
198
|
+
eoxml
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_children_with_blank_text_and_attribute
|
202
|
+
assert_equal_rexml(<<-eoxml)
|
203
|
+
<root>
|
204
|
+
<products type="file"> </products>
|
205
|
+
</root>
|
206
|
+
eoxml
|
207
|
+
end
|
208
|
+
|
209
|
+
private
|
210
|
+
def assert_equal_rexml(xml)
|
211
|
+
hash = XmlMini.with_backend('REXML') { XmlMini.parse(xml) }
|
212
|
+
assert_equal(hash, XmlMini.parse(xml))
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'xml_mini/rexml'
|
3
|
+
|
4
|
+
class REXMLEngineTest < MiniTest::Unit::TestCase
|
5
|
+
|
6
|
+
def test_default_is_rexml
|
7
|
+
assert_equal XmlMini_REXML, XmlMini.backend
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_set_rexml_as_backend
|
11
|
+
XmlMini.backend = 'REXML'
|
12
|
+
assert_equal XmlMini_REXML, XmlMini.backend
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_parse_from_io
|
16
|
+
XmlMini.backend = 'REXML'
|
17
|
+
io = StringIO.new(<<-eoxml)
|
18
|
+
<root>
|
19
|
+
good
|
20
|
+
<products>
|
21
|
+
hello everyone
|
22
|
+
</products>
|
23
|
+
morning
|
24
|
+
</root>
|
25
|
+
eoxml
|
26
|
+
XmlMini.parse(io)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
#require 'active_support/builder'
|
3
|
+
|
4
|
+
module XmlMiniTest
|
5
|
+
class RenameKeyTest < MiniTest::Unit::TestCase
|
6
|
+
def test_rename_key_dasherizes_by_default
|
7
|
+
assert_equal "my-key", XmlMini.rename_key("my_key")
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_rename_key_does_nothing_with_dasherize_true
|
11
|
+
assert_equal "my-key", XmlMini.rename_key("my_key", :dasherize => true)
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_rename_key_does_nothing_with_dasherize_false
|
15
|
+
assert_equal "my_key", XmlMini.rename_key("my_key", :dasherize => false)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_rename_key_does_not_dasherize_leading_underscores
|
19
|
+
assert_equal "_id", XmlMini.rename_key("_id")
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_rename_key_with_leading_underscore_dasherizes_interior_underscores
|
23
|
+
assert_equal "_my-key", XmlMini.rename_key("_my_key")
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_rename_key_does_not_dasherize_trailing_underscores
|
27
|
+
assert_equal "id_", XmlMini.rename_key("id_")
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_rename_key_with_trailing_underscore_dasherizes_interior_underscores
|
31
|
+
assert_equal "my-key_", XmlMini.rename_key("my_key_")
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_rename_key_does_not_dasherize_multiple_leading_underscores
|
35
|
+
assert_equal "__id", XmlMini.rename_key("__id")
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_rename_key_does_not_dasherize_multiple_trailing_underscores
|
39
|
+
assert_equal "id__", XmlMini.rename_key("id__")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
class ToTagTest < MiniTest::Unit::TestCase
|
44
|
+
def assert_xml(xml)
|
45
|
+
assert_equal xml, @options[:builder].target!
|
46
|
+
end
|
47
|
+
|
48
|
+
def setup
|
49
|
+
@xml = XmlMini
|
50
|
+
@options = {:skip_instruct => true, :builder => Builder::XmlMarkup.new}
|
51
|
+
end
|
52
|
+
|
53
|
+
# it "#to_tag accepts a callable object and passes options with the builder" do
|
54
|
+
# @xml.to_tag(:some_tag, lambda {|o| o[:builder].br }, @options)
|
55
|
+
# assert_xml "<br/>"
|
56
|
+
# end
|
57
|
+
|
58
|
+
# it "#to_tag accepts a callable object and passes options and tag name" do
|
59
|
+
# @xml.to_tag(:tag, lambda {|o, t| o[:builder].b(t) }, @options)
|
60
|
+
# assert_xml "<b>tag</b>"
|
61
|
+
# end
|
62
|
+
|
63
|
+
# it "#to_tag accepts an object responding to #to_xml and passes the options, where :root is key" do
|
64
|
+
# obj = Object.new
|
65
|
+
# obj.instance_eval do
|
66
|
+
# def to_xml(options) options[:builder].yo(options[:root].to_s) end
|
67
|
+
# end
|
68
|
+
|
69
|
+
# @xml.to_tag(:tag, obj, @options)
|
70
|
+
# assert_xml "<yo>tag</yo>"
|
71
|
+
# end
|
72
|
+
|
73
|
+
# it "#to_tag accepts arbitrary objects responding to #to_str" do
|
74
|
+
# @xml.to_tag(:b, "Howdy", @options)
|
75
|
+
# assert_xml "<b>Howdy</b>"
|
76
|
+
# end
|
77
|
+
|
78
|
+
# it "#to_tag should dasherize the space when passed a string with spaces as a key" do
|
79
|
+
# @xml.to_tag("New York", 33, @options)
|
80
|
+
# assert_xml "<New---York type=\"integer\">33</New---York>"
|
81
|
+
# end
|
82
|
+
|
83
|
+
# it "#to_tag should dasherize the space when passed a symbol with spaces as a key" do
|
84
|
+
# @xml.to_tag(:"New York", 33, @options)
|
85
|
+
# assert_xml "<New---York type=\"integer\">33</New---York>"
|
86
|
+
# end
|
87
|
+
# TODO: test the remaining functions hidden in #to_tag.
|
88
|
+
end
|
89
|
+
end
|
data/test/test_helper.rb
ADDED
data/xml_mini.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/xml_mini/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Michel Pouleijn"]
|
6
|
+
gem.email = ["michel@cttinnovations.com"]
|
7
|
+
gem.description = %q{Extraction of the XML handling code from ActiveSupport }
|
8
|
+
gem.summary = %q{}
|
9
|
+
gem.homepage = "https://github.com/Pouleijn/xml_mini"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "xml_mini"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = XmlMini::VERSION
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xml_mini
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Michel Pouleijn
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-07-21 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: ! 'Extraction of the XML handling code from ActiveSupport '
|
15
|
+
email:
|
16
|
+
- michel@cttinnovations.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- .rvmrc
|
23
|
+
- Gemfile
|
24
|
+
- Guardfile
|
25
|
+
- LICENSE
|
26
|
+
- README.md
|
27
|
+
- Rakefile
|
28
|
+
- lib/core_ext/array.rb
|
29
|
+
- lib/core_ext/blank.rb
|
30
|
+
- lib/core_ext/hash.rb
|
31
|
+
- lib/xml_mini.rb
|
32
|
+
- lib/xml_mini/libxml.rb
|
33
|
+
- lib/xml_mini/libxmlsax.rb
|
34
|
+
- lib/xml_mini/node_hash.rb
|
35
|
+
- lib/xml_mini/nokogiri.rb
|
36
|
+
- lib/xml_mini/nokogirisax.rb
|
37
|
+
- lib/xml_mini/rexml.rb
|
38
|
+
- lib/xml_mini/version.rb
|
39
|
+
- test/lib/xml_mini/libxml_engine_test.rb
|
40
|
+
- test/lib/xml_mini/libxmlsax_engine_test.rb
|
41
|
+
- test/lib/xml_mini/nokogiri_engine_test.rb
|
42
|
+
- test/lib/xml_mini/nokogirisax_engine_test.rb
|
43
|
+
- test/lib/xml_mini/rexml_engine_test.rb
|
44
|
+
- test/lib/xml_mini_test.rb
|
45
|
+
- test/test_helper.rb
|
46
|
+
- xml_mini.gemspec
|
47
|
+
homepage: https://github.com/Pouleijn/xml_mini
|
48
|
+
licenses: []
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options: []
|
51
|
+
require_paths:
|
52
|
+
- lib
|
53
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ! '>='
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: '0'
|
59
|
+
segments:
|
60
|
+
- 0
|
61
|
+
hash: -3385716935177850779
|
62
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ! '>='
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
segments:
|
69
|
+
- 0
|
70
|
+
hash: -3385716935177850779
|
71
|
+
requirements: []
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 1.8.24
|
74
|
+
signing_key:
|
75
|
+
specification_version: 3
|
76
|
+
summary: ''
|
77
|
+
test_files:
|
78
|
+
- test/lib/xml_mini/libxml_engine_test.rb
|
79
|
+
- test/lib/xml_mini/libxmlsax_engine_test.rb
|
80
|
+
- test/lib/xml_mini/nokogiri_engine_test.rb
|
81
|
+
- test/lib/xml_mini/nokogirisax_engine_test.rb
|
82
|
+
- test/lib/xml_mini/rexml_engine_test.rb
|
83
|
+
- test/lib/xml_mini_test.rb
|
84
|
+
- test/test_helper.rb
|