nokogiri-happymapper 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/CHANGELOG.md +26 -1
- data/README.md +204 -117
- data/lib/happymapper.rb +318 -343
- data/lib/happymapper/anonymous_mapper.rb +27 -29
- data/lib/happymapper/attribute.rb +7 -5
- data/lib/happymapper/element.rb +19 -24
- data/lib/happymapper/item.rb +18 -20
- data/lib/happymapper/supported_types.rb +20 -19
- data/lib/happymapper/text_node.rb +4 -3
- data/lib/happymapper/version.rb +3 -1
- data/spec/attribute_default_value_spec.rb +14 -15
- data/spec/attributes_spec.rb +14 -15
- data/spec/happymapper/attribute_spec.rb +4 -4
- data/spec/happymapper/element_spec.rb +3 -1
- data/spec/happymapper/item_spec.rb +49 -41
- data/spec/happymapper/text_node_spec.rb +3 -1
- data/spec/happymapper_parse_spec.rb +62 -44
- data/spec/happymapper_spec.rb +270 -263
- data/spec/has_many_empty_array_spec.rb +8 -7
- data/spec/ignay_spec.rb +27 -31
- data/spec/inheritance_spec.rb +30 -24
- data/spec/mixed_namespaces_spec.rb +14 -15
- data/spec/parse_with_object_to_update_spec.rb +37 -38
- data/spec/spec_helper.rb +18 -0
- data/spec/to_xml_spec.rb +64 -63
- data/spec/to_xml_with_namespaces_spec.rb +66 -64
- data/spec/wilcard_tag_name_spec.rb +25 -21
- data/spec/wrap_spec.rb +11 -11
- data/spec/xpath_spec.rb +33 -32
- metadata +33 -5
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
2
4
|
|
3
5
|
module Sheep
|
4
6
|
class Item
|
@@ -16,28 +18,27 @@ module Sheep
|
|
16
18
|
has_many :items, Item, tag: 'item'
|
17
19
|
|
18
20
|
has_many :items_with_a_different_name, Item, tag: 'item'
|
19
|
-
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
23
|
-
describe
|
24
|
+
describe 'emptyness' do
|
24
25
|
let(:xml) do
|
25
|
-
<<-
|
26
|
+
<<-XML
|
26
27
|
<navigator>
|
27
28
|
<items/>
|
28
29
|
</navigator>
|
29
|
-
|
30
|
+
XML
|
30
31
|
end
|
31
32
|
|
32
33
|
let(:navigator) do
|
33
34
|
Sheep::Navigator.parse(xml)
|
34
35
|
end
|
35
36
|
|
36
|
-
it
|
37
|
+
it 'returns an empty array' do
|
37
38
|
expect(navigator.items_with_a_different_name).to be_empty
|
38
39
|
end
|
39
40
|
|
40
|
-
it
|
41
|
+
it 'returns an empty array' do
|
41
42
|
expect(navigator.items).to be_empty
|
42
43
|
end
|
43
44
|
end
|
data/spec/ignay_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
class CatalogTree
|
@@ -10,86 +12,80 @@ class CatalogTree
|
|
10
12
|
|
11
13
|
attribute :code, String
|
12
14
|
|
13
|
-
has_many :nodes, 'CatalogNode', :
|
14
|
-
|
15
|
+
has_many :nodes, 'CatalogNode', tag: 'Node', xpath: '.'
|
15
16
|
end
|
16
17
|
|
17
|
-
|
18
18
|
class CatalogNode
|
19
19
|
include HappyMapper
|
20
20
|
|
21
21
|
tag 'Node'
|
22
22
|
|
23
|
-
attribute :back_office_id, String, :
|
23
|
+
attribute :back_office_id, String, tag: 'vodBackOfficeId'
|
24
24
|
|
25
|
-
has_one :name, String, :
|
25
|
+
has_one :name, String, tag: 'Name'
|
26
26
|
# other important fields
|
27
27
|
|
28
|
-
has_many :translations, 'CatalogNode::Translations', :
|
28
|
+
has_many :translations, 'CatalogNode::Translations', tag: 'Translation', xpath: 'child::*'
|
29
29
|
|
30
30
|
class Translations
|
31
31
|
include HappyMapper
|
32
32
|
tag 'Translation'
|
33
33
|
|
34
|
-
attribute :language, String, :
|
35
|
-
has_one :name, String, :
|
36
|
-
|
34
|
+
attribute :language, String, tag: 'Language'
|
35
|
+
has_one :name, String, tag: 'Name'
|
37
36
|
end
|
38
37
|
|
39
|
-
has_many :nodes, CatalogNode, :
|
40
|
-
|
38
|
+
has_many :nodes, CatalogNode, tag: 'Node', xpath: 'child::*'
|
41
39
|
end
|
42
40
|
|
43
41
|
describe HappyMapper do
|
44
|
-
|
45
|
-
it "should not be nil" do
|
42
|
+
it 'should not be nil' do
|
46
43
|
expect(catalog_tree).not_to be_nil
|
47
44
|
end
|
48
45
|
|
49
|
-
it
|
50
|
-
expect(catalog_tree.code).to eq(
|
46
|
+
it 'should have the attribute code' do
|
47
|
+
expect(catalog_tree.code).to eq('NLD')
|
51
48
|
end
|
52
49
|
|
53
|
-
it
|
50
|
+
it 'should have many nodes' do
|
54
51
|
expect(catalog_tree.nodes).not_to be_empty
|
55
52
|
expect(catalog_tree.nodes.length).to eq(2)
|
56
53
|
end
|
57
54
|
|
58
|
-
context
|
59
|
-
|
60
|
-
|
61
|
-
expect(first_node.name).to eq("Parent 1")
|
55
|
+
context 'first node' do
|
56
|
+
it 'should have a name' do
|
57
|
+
expect(first_node.name).to eq('Parent 1')
|
62
58
|
end
|
63
59
|
|
64
|
-
it
|
60
|
+
it 'should have translations' do
|
65
61
|
expect(first_node.translations.length).to eq(2)
|
66
62
|
|
67
|
-
expect(first_node.translations.first.language).to eq(
|
63
|
+
expect(first_node.translations.first.language).to eq('en-GB')
|
68
64
|
|
69
|
-
expect(first_node.translations.last.name).to eq(
|
65
|
+
expect(first_node.translations.last.name).to eq('Parent 1 de')
|
70
66
|
end
|
71
67
|
|
72
|
-
it
|
68
|
+
it 'should have subnodes' do
|
73
69
|
expect(first_node.nodes).to be_kind_of(Enumerable)
|
74
70
|
expect(first_node.nodes).not_to be_empty
|
75
71
|
expect(first_node.nodes.length).to eq(1)
|
76
72
|
end
|
77
73
|
|
78
|
-
it
|
79
|
-
expect(first_node.nodes.first.name).to eq(
|
74
|
+
it 'first node - first node name' do
|
75
|
+
expect(first_node.nodes.first.name).to eq('First')
|
80
76
|
end
|
81
77
|
|
82
78
|
def first_node
|
83
79
|
@first_node = catalog_tree.nodes.first
|
84
80
|
end
|
85
|
-
|
86
81
|
end
|
87
82
|
|
88
|
-
|
89
|
-
|
83
|
+
def catalog_tree
|
84
|
+
@catalog_tree
|
85
|
+
end
|
90
86
|
|
91
87
|
before(:all) do
|
92
88
|
xml_reference = "#{File.dirname(__FILE__)}/fixtures/inagy.xml"
|
93
|
-
@catalog_tree = CatalogTree.parse(File.read(xml_reference), :
|
89
|
+
@catalog_tree = CatalogTree.parse(File.read(xml_reference), single: true)
|
94
90
|
end
|
95
|
-
end
|
91
|
+
end
|
data/spec/inheritance_spec.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'spec_helper'
|
4
4
|
|
5
|
+
describe 'Using inheritance to share elements and attributes' do
|
5
6
|
class Genetics
|
6
7
|
include HappyMapper
|
7
8
|
content :dna, String
|
@@ -26,9 +27,12 @@ describe "Using inheritance to share elements and attributes" do
|
|
26
27
|
element :genetics, Integer
|
27
28
|
end
|
28
29
|
|
29
|
-
describe
|
30
|
+
describe 'Overwrite' do
|
30
31
|
let(:subject) do
|
31
|
-
xml =
|
32
|
+
xml =
|
33
|
+
'<overwrite love="love" naivety="trusting">' \
|
34
|
+
'<genetics>1001</genetics><immunities>Chicken Pox</immunities>' \
|
35
|
+
'</overwrite>'
|
32
36
|
Overwrite.parse(xml, single: true)
|
33
37
|
end
|
34
38
|
|
@@ -37,9 +41,9 @@ describe "Using inheritance to share elements and attributes" do
|
|
37
41
|
expect(Overwrite.elements.count).to be == Parent.elements.count
|
38
42
|
end
|
39
43
|
|
40
|
-
context
|
44
|
+
context 'when parsing xml' do
|
41
45
|
it 'parses the new overwritten attribut' do
|
42
|
-
expect(subject.love).to be ==
|
46
|
+
expect(subject.love).to be == 'love'
|
43
47
|
end
|
44
48
|
|
45
49
|
it 'parses the new overwritten element' do
|
@@ -47,11 +51,11 @@ describe "Using inheritance to share elements and attributes" do
|
|
47
51
|
end
|
48
52
|
end
|
49
53
|
|
50
|
-
context
|
54
|
+
context 'when saving to xml' do
|
51
55
|
subject do
|
52
56
|
overwrite = Overwrite.new
|
53
57
|
overwrite.genetics = 1
|
54
|
-
overwrite.love =
|
58
|
+
overwrite.love = 'love'
|
55
59
|
Nokogiri::XML(overwrite.to_xml).root
|
56
60
|
end
|
57
61
|
|
@@ -60,48 +64,50 @@ describe "Using inheritance to share elements and attributes" do
|
|
60
64
|
end
|
61
65
|
|
62
66
|
it 'has only 1 love attribute' do
|
63
|
-
expect(subject.xpath('@love').text).to be ==
|
67
|
+
expect(subject.xpath('@love').text).to be == 'love'
|
64
68
|
end
|
65
69
|
end
|
66
70
|
end
|
67
71
|
|
68
|
-
describe
|
72
|
+
describe 'Child', 'a subclass of the Parent' do
|
69
73
|
let(:subject) do
|
70
|
-
xml =
|
74
|
+
xml =
|
75
|
+
'<child love="99" naivety="trusting">' \
|
76
|
+
'<genetics>ABBA</genetics><immunities>Chicken Pox</immunities>' \
|
77
|
+
'</child>'
|
71
78
|
Child.parse(xml)
|
72
79
|
end
|
73
80
|
|
74
|
-
context
|
81
|
+
context 'when parsing xml' do
|
75
82
|
it 'should be possible to deserialize XML into a Child class instance' do
|
76
83
|
expect(subject.love).to eq 99
|
77
|
-
expect(subject.genetics.dna).to eq
|
78
|
-
expect(subject.naivety).to eq
|
84
|
+
expect(subject.genetics.dna).to eq 'ABBA'
|
85
|
+
expect(subject.naivety).to eq 'trusting'
|
79
86
|
expect(subject.immunities.size).to eq(1)
|
80
87
|
end
|
81
88
|
end
|
82
89
|
|
83
|
-
context
|
90
|
+
context 'when saving to xml' do
|
84
91
|
let(:subject) do
|
85
92
|
child = Child.new
|
86
93
|
child.love = 100
|
87
94
|
child.naivety = 'Bright Eyed'
|
88
|
-
child.immunities = [
|
95
|
+
child.immunities = ['Small Pox', 'Chicken Pox', 'Mumps']
|
89
96
|
genetics = Genetics.new
|
90
|
-
genetics.dna =
|
97
|
+
genetics.dna = 'GATTACA'
|
91
98
|
child.genetics = genetics
|
92
99
|
Nokogiri::XML(child.to_xml).root
|
93
100
|
end
|
94
101
|
|
95
|
-
it
|
96
|
-
expect(subject.xpath(
|
97
|
-
expect(subject.xpath(
|
102
|
+
it 'saves both the Child and Parent attributes' do
|
103
|
+
expect(subject.xpath('@naivety').text).to eq 'Bright Eyed'
|
104
|
+
expect(subject.xpath('@love').text).to eq '100'
|
98
105
|
end
|
99
106
|
|
100
|
-
it
|
101
|
-
expect(subject.xpath(
|
102
|
-
expect(subject.xpath(
|
107
|
+
it 'saves both the Child and Parent elements' do
|
108
|
+
expect(subject.xpath('genetics').text).to eq 'GATTACA'
|
109
|
+
expect(subject.xpath('immunities').size).to eq(3)
|
103
110
|
end
|
104
111
|
end
|
105
|
-
|
106
112
|
end
|
107
113
|
end
|
@@ -1,7 +1,8 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'spec_helper'
|
4
4
|
|
5
|
+
describe 'A document with mixed namespaces' do
|
5
6
|
#
|
6
7
|
# Note that the parent element of the xml has the namespacing. The elements
|
7
8
|
# contained within the xml do not share the parent element namespace so a
|
@@ -9,14 +10,14 @@ describe "A document with mixed namespaces" do
|
|
9
10
|
# these child elements.
|
10
11
|
#
|
11
12
|
let(:xml_document) do
|
12
|
-
%
|
13
|
+
%(<prefix:address location='home' xmlns:prefix="http://www.unicornland.com/prefix"
|
13
14
|
xmlns:different="http://www.trollcountry.com/different">
|
14
15
|
<street>Milchstrasse</street>
|
15
16
|
<street>Another Street</street>
|
16
17
|
<housenumber>23</housenumber>
|
17
18
|
<different:postcode>26131</different:postcode>
|
18
19
|
<city>Oldenburg</city>
|
19
|
-
</prefix:address>
|
20
|
+
</prefix:address>)
|
20
21
|
end
|
21
22
|
|
22
23
|
module MixedNamespaces
|
@@ -41,21 +42,19 @@ describe "A document with mixed namespaces" do
|
|
41
42
|
MixedNamespaces::Address.parse(xml_document, single: true)
|
42
43
|
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
expect(address.streets).to eq [ "Milchstrasse", "Another Street" ]
|
45
|
+
it 'has the correct streets' do
|
46
|
+
expect(address.streets).to eq ['Milchstrasse', 'Another Street']
|
47
47
|
end
|
48
48
|
|
49
|
-
it
|
50
|
-
expect(address.house_number).to eq
|
49
|
+
it 'house number' do
|
50
|
+
expect(address.house_number).to eq '23'
|
51
51
|
end
|
52
52
|
|
53
|
-
it
|
54
|
-
expect(address.postcode).to eq
|
53
|
+
it 'postcode' do
|
54
|
+
expect(address.postcode).to eq '26131'
|
55
55
|
end
|
56
56
|
|
57
|
-
it
|
58
|
-
expect(address.city).to eq
|
57
|
+
it 'city' do
|
58
|
+
expect(address.city).to eq 'Oldenburg'
|
59
59
|
end
|
60
|
-
|
61
|
-
end
|
60
|
+
end
|
@@ -1,34 +1,35 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require 'spec_helper'
|
4
4
|
|
5
|
+
describe 'Updating existing objects with .parse and #parse' do
|
5
6
|
let(:subject) { ParseInstanceSpec::Root.parse(parse_instance_initial_xml) }
|
6
7
|
|
7
8
|
let(:parse_instance_initial_xml) do
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
9
|
+
%(<root attr1="initial">
|
10
|
+
<item attr1="initial">
|
11
|
+
<description>initial</description>
|
12
|
+
<subitem attr1="initial">
|
13
|
+
<name>initial</name>
|
14
|
+
</subitem>
|
15
|
+
<subitem attr1="initial">
|
16
|
+
<name>initial</name>
|
17
|
+
</subitem>
|
18
|
+
</item>
|
19
|
+
<item attr1="initial">
|
20
|
+
<description>initial</description>
|
21
|
+
<subitem attr1="initial">
|
22
|
+
<name>initial</name>
|
23
|
+
</subitem>
|
24
|
+
<subitem attr1="initial">
|
25
|
+
<name>initial</name>
|
26
|
+
</subitem>
|
27
|
+
</item>
|
28
|
+
</root>)
|
28
29
|
end
|
29
30
|
|
30
31
|
let(:parse_instance_updated_xml) do
|
31
|
-
%
|
32
|
+
%(<root attr1="updated">
|
32
33
|
<item attr1="updated">
|
33
34
|
<description>updated</description>
|
34
35
|
<subitem attr1="updated">
|
@@ -47,7 +48,7 @@ describe "Updating existing objects with .parse and #parse" do
|
|
47
48
|
<name>updated</name>
|
48
49
|
</subitem>
|
49
50
|
</item>
|
50
|
-
</root>
|
51
|
+
</root>)
|
51
52
|
end
|
52
53
|
|
53
54
|
module ParseInstanceSpec
|
@@ -72,7 +73,7 @@ describe "Updating existing objects with .parse and #parse" do
|
|
72
73
|
end
|
73
74
|
end
|
74
75
|
|
75
|
-
def item_is_correctly_defined(item,value='initial')
|
76
|
+
def item_is_correctly_defined(item, value = 'initial')
|
76
77
|
expect(item.attr1).to eq value
|
77
78
|
expect(item.description).to eq value
|
78
79
|
expect(item.sub_items[0].attr1).to eq value
|
@@ -83,29 +84,27 @@ describe "Updating existing objects with .parse and #parse" do
|
|
83
84
|
|
84
85
|
it 'initial values are correct' do
|
85
86
|
expect(subject.attr1).to eq('initial')
|
86
|
-
item_is_correctly_defined(
|
87
|
-
item_is_correctly_defined(
|
87
|
+
item_is_correctly_defined(subject.items[0])
|
88
|
+
item_is_correctly_defined(subject.items[1])
|
88
89
|
end
|
89
90
|
|
90
|
-
|
91
|
-
describe ".parse", "specifying an existing object to update" do
|
91
|
+
describe '.parse', 'specifying an existing object to update' do
|
92
92
|
it 'all fields are correct' do
|
93
|
-
ParseInstanceSpec::Root.parse(parse_instance_updated_xml, :
|
93
|
+
ParseInstanceSpec::Root.parse(parse_instance_updated_xml, update: subject)
|
94
94
|
expect(subject.attr1).to eq 'updated'
|
95
95
|
|
96
|
-
item_is_correctly_defined(
|
97
|
-
item_is_correctly_defined(
|
96
|
+
item_is_correctly_defined(subject.items[0], 'updated')
|
97
|
+
item_is_correctly_defined(subject.items[1], 'updated')
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
|
-
describe
|
102
|
-
it
|
101
|
+
describe '#parse' do
|
102
|
+
it 'all fields are correct' do
|
103
103
|
subject.parse(parse_instance_updated_xml)
|
104
104
|
expect(subject.attr1).to eq 'updated'
|
105
105
|
|
106
|
-
item_is_correctly_defined(
|
107
|
-
item_is_correctly_defined(
|
106
|
+
item_is_correctly_defined(subject.items[0], 'updated')
|
107
|
+
item_is_correctly_defined(subject.items[1], 'updated')
|
108
108
|
end
|
109
109
|
end
|
110
|
-
|
111
|
-
end
|
110
|
+
end
|