xsd-populator 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f2eda4c1222169e40bd22cd1ec39960cefd5a38b
4
- data.tar.gz: 41bc1605eaa36e836aacfbae731f34752c1ece56
3
+ metadata.gz: 9ebc1e85e1cd52ecfb538ab4b7a19d4519246ed6
4
+ data.tar.gz: 3507861603505bebe389482309a9d8bb8b91573a
5
5
  SHA512:
6
- metadata.gz: 269167d81605c0f996e2bba757b59dcf71f77e65b08c1c27f162b6d061b7945302e1052368fb71be19b20ae906b2b7507c964c7af0f3e6448f34982bc5b4f167
7
- data.tar.gz: 7c13c2ddfb4ec11213427ab6bf7d91a91c5ac725062f13ab4c27f20f19ec99af2a4581f7c3059058808bb59f9e71ad6eb8f8d9ea5528d118e3fc54e7ec7e0d48
6
+ metadata.gz: dd3ed398300a5cd61bdbd28991ec285ba5edb1c27aff7e85e779f0aec49905679d5de18eeb3f2bc16a82361489052d35d1e3dbe3c73e529c36aeb28f2d0f964b
7
+ data.tar.gz: 1c9bd6860e771cc7de54246aa39117330226c1d676b2170e4bf46b468576c33a51ed32725bf4e728e85d77548926e204bab18e88e1a6cfd81776d9557bc19e96
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 1.9.3
5
+ bundler_args: --without test
data/Gemfile CHANGED
@@ -2,5 +2,6 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'xsd-reader', :path => '/srv/xsd-reader'
6
- gem 'data-provider', :path => '/srv/data-provider'
5
+ group :test do
6
+ gem 'byebug'
7
+ end
@@ -6,18 +6,6 @@ PATH
6
6
  data-provider (~> 0.2)
7
7
  xsd-reader (~> 0.2)
8
8
 
9
- PATH
10
- remote: /srv/data-provider
11
- specs:
12
- data-provider (0.2.0)
13
-
14
- PATH
15
- remote: /srv/xsd-reader
16
- specs:
17
- xsd-reader (0.2.0)
18
- nokogiri (~> 1.6)
19
- rest-client (~> 1.8)
20
-
21
9
  GEM
22
10
  remote: https://rubygems.org/
23
11
  specs:
@@ -25,16 +13,18 @@ GEM
25
13
  byebug (5.0.0)
26
14
  columnize (= 0.9.0)
27
15
  columnize (0.9.0)
16
+ data-provider (0.2.0)
28
17
  diff-lcs (1.2.5)
29
- domain_name (0.5.24)
18
+ domain_name (0.5.25)
30
19
  unf (>= 0.0.5, < 1.0.0)
31
20
  http-cookie (1.0.2)
32
21
  domain_name (~> 0.5)
33
- mime-types (2.6.1)
22
+ mime-types (2.6.2)
34
23
  mini_portile (0.6.2)
35
- netrc (0.10.3)
24
+ netrc (0.11.0)
36
25
  nokogiri (1.6.6.2)
37
26
  mini_portile (~> 0.6.0)
27
+ rake (10.1.0)
38
28
  rest-client (1.8.0)
39
29
  http-cookie (>= 1.0.2, < 2.0)
40
30
  mime-types (>= 1.16, < 3.0)
@@ -55,17 +45,19 @@ GEM
55
45
  unf (0.1.4)
56
46
  unf_ext
57
47
  unf_ext (0.0.7.1)
48
+ xsd-reader (0.2.0)
49
+ nokogiri (~> 1.6)
50
+ rest-client (~> 1.8)
58
51
 
59
52
  PLATFORMS
60
53
  ruby
61
54
 
62
55
  DEPENDENCIES
63
- byebug (~> 5.0)
64
- data-provider!
56
+ byebug
65
57
  nokogiri (~> 1.6)
58
+ rake (~> 10.1)
66
59
  rspec (~> 3.3)
67
60
  xsd-populator!
68
- xsd-reader!
69
61
 
70
62
  BUNDLED WITH
71
63
  1.10.5
data/README.md CHANGED
@@ -1,2 +1,69 @@
1
1
  # xsd-populator
2
- A Ruby gem to produce XML data from XSD schemas
2
+ A Ruby gem to produce XML data from XSD schemas and DataProvider objects.
3
+
4
+ See the data-provider gem: [https://github.com/markkorput/data-provider](https://github.com/markkorput/data-provider)
5
+
6
+ [![Build Status](https://travis-ci.org/markkorput/xsd-populator.svg)](https://travis-ci.org/markkorput/xsd-populator)
7
+
8
+
9
+
10
+ ## Installation
11
+
12
+
13
+ Rubygems:
14
+
15
+ ```
16
+ gem install xsd-populator
17
+ ```
18
+
19
+ Bundler:
20
+
21
+ ```ruby
22
+ gem 'xsd-populator'
23
+ ````
24
+
25
+ ## Examples
26
+
27
+ Load xsd
28
+ ```ruby
29
+ require 'xsd_populator'
30
+ reader = XsdPopulator.new(:xsd => 'ddex-ern-v36.xsd')
31
+ reader.populated_xml # => XML-string
32
+ ```
33
+
34
+ Not that in this minimal implementation, no custom data provider is given to the populator, causing it to use the default internal 'XsdExplanationProvider', which produces explanatory XML.
35
+
36
+ For this [elaborate example XSD](https://github.com/markkorput/xsd-populator/blob/master/spec/examples/ddex-ern-v36.xsd), this would produce [this xml](https://github.com/markkorput/xsd-populator/blob/master/spec/examples/ddex-ern-v36-NewReleaseMessage.xml)
37
+
38
+
39
+ ### Using actual custom data providers
40
+
41
+ In practice, you'd implement a custom DataProvider class (see the [data-provider gem](https://github.com/markkorput/data-provider)) and pass it into the XsdPopulator.
42
+
43
+ ```ruby
44
+ require 'xsd_populator'
45
+
46
+ data_provider = CustomDataProvider.new(:some => 'data')
47
+ reader = XsdPopulator.new(:xsd => 'ddex-ern-v36.xsd', :provider => data_provider)
48
+ reader.populated_xml # => XML-string
49
+ ```
50
+
51
+ ### Producing specific parts of an XML structure
52
+
53
+ In case you want to produce only a specific part of an XML hierarchy, you can specify an element when initializing the populator object:
54
+
55
+ ```ruby
56
+ reader = XsdPopulator.new(:xsd => 'ddex-ern-v36.xsd', :element => ['NewReleaseMessage', 'MessageHeader'])
57
+ reader.populated_xml # => XML-string containing only the part
58
+ ```
59
+
60
+ The :element option takes an array-value representing an element's XPath (in this case that XPath is /NewReleaseMessage/MessageHeader). The specified element become(s) the root-element(s) in the produced XML.
61
+
62
+ This example would produce [this XML](https://github.com/markkorput/xsd-populator/blob/master/spec/examples/ddex-ern-v36-MessageHeader.xml)
63
+
64
+
65
+
66
+
67
+
68
+
69
+
@@ -0,0 +1,53 @@
1
+ class XsdPopulator
2
+ class Informer
3
+ attr_reader :options
4
+
5
+ def initialize(_opts = {})
6
+ @options = _opts || {}
7
+ end
8
+
9
+ def skip?
10
+ options[:skip] == true
11
+ end
12
+
13
+ def self.skip
14
+ self.new(:skip => true)
15
+ end
16
+
17
+ def attributes
18
+ options[:attributes] || {}
19
+ end
20
+
21
+ def attributes?
22
+ self.options.keys.include?(:attributes)
23
+ end
24
+
25
+ def self.attributes(attrs)
26
+ self.new(:attributes => attrs)
27
+ end
28
+
29
+ def namespace
30
+ options[:namespace]
31
+ end
32
+
33
+ def namespace?
34
+ options.keys.include?(:namespace)
35
+ end
36
+
37
+ def self.namespace(ns)
38
+ self.new(:namespace => ns)
39
+ end
40
+
41
+ def content
42
+ options[:content]
43
+ end
44
+
45
+ def content?
46
+ self.options.keys.include?(:content)
47
+ end
48
+
49
+ def self.content(content)
50
+ self.new(:content => content)
51
+ end
52
+ end # class Informer
53
+ end # module XsdPopulator
@@ -2,33 +2,13 @@ require 'bundler/setup'
2
2
  require 'builder'
3
3
  require 'xsd_reader'
4
4
  require 'xsd_explanation_provider'
5
+ require 'informer'
5
6
 
6
7
  class XsdPopulator
7
8
 
8
9
  class ElementNotFoundException < Exception
9
10
  end
10
11
 
11
- class Informer
12
- attr_reader :options
13
-
14
- def initialize(_opts = {})
15
- @options = _opts || {}
16
- end
17
-
18
- def skip?
19
- options[:skip] == true
20
- end
21
-
22
- def attributes
23
- options[:attributes] || {}
24
- end
25
-
26
- def namespace
27
- options[:namespace]
28
- end
29
- end # class Informer
30
-
31
-
32
12
  attr_reader :options
33
13
 
34
14
  def initialize(_opts = {})
@@ -77,7 +57,11 @@ class XsdPopulator
77
57
  end
78
58
 
79
59
  def populate_element(element_specifier = nil)
80
- element_specifier.nil? ? populated_xml : populate_xml(element_specifier)
60
+ element_specifier.nil? ? populated_xml : populate_xml(:element_specifier => element_specifier)
61
+ end
62
+
63
+ def populate(opts = {})
64
+ populate_xml(opts.merge(:element_specifier => opts.delete(:element)))
81
65
  end
82
66
 
83
67
  def write_file(path)
@@ -91,22 +75,42 @@ class XsdPopulator
91
75
 
92
76
  private
93
77
 
94
- def populate_xml(element_specifier = nil)
95
- if (root_el = root_xsd_element(element_specifier)).nil?
78
+ def populate_xml(opts = {})
79
+ # supported opts:
80
+ # :element_specifier
81
+ # :builder
82
+
83
+ if (root_el = root_xsd_element(opts[:element_specifier])).nil?
96
84
  logger.warn "Couldn't find element definition, aborting"
97
85
  return nil
98
86
  end
99
87
 
100
- xml = Builder::XmlMarkup.new(:indent => 2)
101
- xml.instruct!
102
-
103
- stack = options[:relative_provider] == true ? [] : [element_specifier || options[:element]].flatten.compact
88
+ stack = options[:relative_provider] == true ? [] : [opts[:element_specifier] || options[:element]].flatten.compact
104
89
  stack.pop
105
- build_element(xml, root_el, self.provider, stack)
90
+
91
+ if (xml = opts[:builder]).nil?
92
+ xml = Builder::XmlMarkup.new(:indent => 2)
93
+ xml.instruct!
94
+ end
95
+
96
+ build_element(xml, root_el, start_provider(root_el, stack), stack)
106
97
 
107
98
  return xml.target!
108
99
  end
109
100
 
101
+ def start_provider(el, stack)
102
+ p = self.provider
103
+
104
+ 1.upto(stack.length) do |cnt|
105
+ new_p = p.try_take(stack[0, cnt])
106
+ if new_p.respond_to?(:try_take)
107
+ p = new_p
108
+ end
109
+ end
110
+
111
+ return p
112
+ end
113
+
110
114
  def stack_recursion_count(stack = [])
111
115
  stack.select{|el| el == stack.last}.length - 1
112
116
  end
@@ -152,12 +156,28 @@ class XsdPopulator
152
156
  else
153
157
  attributes_data_hash ||= attributes_data_hash_for(element, provider, stack)
154
158
  attributes_hash = attributes_hash_for_index(attributes_data_hash, idx)
155
- attributes_hash = node_content.attributes.merge(attributes_hash) if node_content.is_a?(Informer) && node_content.attributes.length > 0
159
+
160
+ if node_content.is_a?(Informer) && node_content.attributes?
161
+ informer_attributes = node_content.attributes.keys.inject({}) do |result, key|
162
+ if (informer = node_content.attributes[key]).is_a?(Informer)
163
+ if informer.skip?
164
+ result
165
+ else
166
+ result.merge(key => informer.content)
167
+ end
168
+ else
169
+ result.merge(key => informer)
170
+ end
171
+ end
172
+
173
+ attributes_hash.merge!(informer_attributes)
174
+ end
156
175
  end
157
176
 
158
177
  # simple node; name, value, attributes
159
178
  if !element.child_elements?
160
- xml.tag!(element.name, node_content, attributes_hash)
179
+ cont = node_content.is_a?(Informer) && node_content.content? ? node_content.content : node_content
180
+ xml.tag!(element.name, cont, attributes_hash)
161
181
  next
162
182
  end
163
183
 
@@ -323,6 +343,7 @@ class XsdPopulator
323
343
  def add_attribute?(attribute, provider, stack = [], opts = {})
324
344
  return true if attribute.required?
325
345
  content = opts[:content] || provider.try_take(stack + ["@#{attribute.name}"])
346
+ return false if content.is_a?(Informer) and content.skip?
326
347
  return (!content.nil?) || add_empty_attributes?
327
348
  end
328
349
  end # class XsdPopulator
@@ -0,0 +1,162 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe XsdPopulator::Informer do
4
+ class InformProvider
5
+ include DataProvider::Base
6
+
7
+ provides({
8
+ ['NewReleaseMessage', 'MessageHeader'] => XsdPopulator::Informer.new(:skip => true),
9
+ ['NewReleaseMessage', 'MessageHeader', 'MessageId'] => 123,
10
+ ['NewReleaseMessage', 'ResourceList', '@LanguageAndScriptCode'] => XsdPopulator::Informer.skip,
11
+ ['NewReleaseMessage', 'ResourceList', 'SoundRecording', 'SoundRecordingType'] => XsdPopulator::Informer.content('SuperMegaBox'),
12
+ ['NewReleaseMessage', 'ResourceList', 'SoundRecording', 'ReferenceTitle', 'TitleText'] => XsdPopulator::Informer.new(:content => 'SuperSmashHitsDeluxe', :attibutes => {'LanguageAndScriptCode' => XsdPopulator::Informer.skip})
13
+
14
+ })
15
+ end
16
+
17
+ let(:xsd_reader){
18
+ XsdReader::XML.new(:xsd_file => File.expand_path(File.join(File.dirname(__FILE__), 'examples', 'ddex-ern-v36.xsd')))
19
+ }
20
+
21
+ let(:logger){
22
+ logger = Logger.new(STDOUT)
23
+ logger.level = Logger::WARN
24
+ logger
25
+ }
26
+
27
+ let(:populator){
28
+ XsdPopulator.new({
29
+ :reader=> xsd_reader,
30
+ :logger => logger,
31
+ :provider => InformProvider.new
32
+ })
33
+ }
34
+
35
+ describe "#skip?" do
36
+ it "specifies if the skip flag is enabled" do
37
+ expect(XsdPopulator::Informer.new(:skip => true).skip?).to eq true
38
+ expect(XsdPopulator::Informer.new(:skip => false).skip?).to eq false
39
+ end
40
+
41
+ it "is false by default" do
42
+ expect(XsdPopulator::Informer.new.skip?).to eq false
43
+ end
44
+ end
45
+
46
+ describe "#attributes?" do
47
+ it "tells if attributes were explicitly specified" do
48
+ expect(XsdPopulator::Informer.new(:attributes => {}).attributes?).to eq true
49
+ expect(XsdPopulator::Informer.new(:attributes => nil).attributes?).to eq true
50
+ expect(XsdPopulator::Informer.new(:attrs => {}).attributes?).to eq false
51
+ end
52
+
53
+ it "is false by default" do
54
+ expect(XsdPopulator::Informer.new.attributes?).to eq false
55
+ end
56
+ end
57
+
58
+ describe "#content?" do
59
+ it "tells if the informer was explicitly given content" do
60
+ expect(XsdPopulator::Informer.new(:content => {}).content?).to eq true
61
+ expect(XsdPopulator::Informer.new(:content => 'Something').content?).to eq true
62
+ expect(XsdPopulator::Informer.new(:content => nil).content?).to eq true
63
+ end
64
+
65
+ it "is false by default" do
66
+ expect(XsdPopulator::Informer.new(:attributes => {}).content?).to eq false
67
+ expect(XsdPopulator::Informer.new.content?).to eq false
68
+ end
69
+ end
70
+
71
+ describe "#namespace?" do
72
+ it "tells if namespace information was explicitly specified" do
73
+ expect(XsdPopulator::Informer.new(:namespace => {}).namespace?).to eq true
74
+ expect(XsdPopulator::Informer.new(:namespace => 'Something').namespace?).to eq true
75
+ expect(XsdPopulator::Informer.new(:namespace => nil).namespace?).to eq true
76
+ end
77
+
78
+ it "is false by default" do
79
+ expect(XsdPopulator::Informer.new(:attributes => {}).namespace?).to eq false
80
+ expect(XsdPopulator::Informer.new.namespace?).to eq false
81
+ end
82
+ end
83
+
84
+ describe ":skip" do
85
+ it "informs the populator to skip an element" do
86
+ expect(Nokogiri.XML(populator.populated_xml).at('/NewReleaseMessage/MessageHeader')).to eq nil
87
+ end
88
+
89
+ it "informs the populator to skip an attribute" do
90
+ expect(Nokogiri.XML(populator.populated_xml).at('/NewReleaseMessage/ResourceList').attributes['Namespace']).to eq nil
91
+ end
92
+
93
+ it "informs the populator to skip an attribute" do
94
+ expect(Nokogiri.XML(populator.populated_xml).at('/NewReleaseMessage/ResourceList/SoundRecording/ReferenceTitle/TitleText').attributes['LanguageAndScriptCode']).to eq nil
95
+ end
96
+ end
97
+
98
+ describe ":attributes" do
99
+ it "informs the populator to explicitly add a set of attributes to an element" do
100
+ provider_class = Class.new(Object) do
101
+ include DataProvider::Base
102
+
103
+ provider ['NewReleaseMessage', '@MessageSchemaVersionId']{ '2010/ern-main/32' }
104
+
105
+ provider ['NewReleaseMessage']{
106
+ XsdPopulator::Informer.new(:attributes => {
107
+ 'xmlns:ern' => 'http://ddex.net/xml/2010/ern-main/32',
108
+ 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
109
+ 'xsi:schemaLocation' => 'http://ddex.net/xml/2010/ern-main/32 http://ddex.net/xml/2010/ern-main/32/ern-main.xsd'
110
+ })
111
+ }
112
+
113
+ provides(['NewReleaseMessage', 'MessageHeader', 'MessageId'] => 123)
114
+ end
115
+
116
+ populator = XsdPopulator.new({
117
+ :reader=> xsd_reader,
118
+ :logger => logger,
119
+ :provider => provider_class.new
120
+ })
121
+
122
+ el = Nokogiri.XML(populator.populated_xml).at('NewReleaseMessage')
123
+ expect(el.attributes['schemaLocation'].value).to eq 'http://ddex.net/xml/2010/ern-main/32 http://ddex.net/xml/2010/ern-main/32/ern-main.xsd'
124
+ expect(el.attributes['MessageSchemaVersionId'].value).to eq '2010/ern-main/32'
125
+ expect(el.attributes.keys.length).to eq 2
126
+
127
+ expect(el.namespace_definitions.map{|nsdef| [nsdef.prefix, nsdef.href]}.sort).to eq([
128
+ ['ern', 'http://ddex.net/xml/2010/ern-main/32'],
129
+ ['xsi', 'http://www.w3.org/2001/XMLSchema-instance']
130
+ ])
131
+ end
132
+ end
133
+
134
+ describe ":namespace" do
135
+ it "informs the populator to prefix a node with a namespace" do
136
+ provider_class = Class.new(Object) do
137
+ include DataProvider::Base
138
+
139
+ provider ['NewReleaseMessage']{ XsdPopulator::Informer.new(:namespace => 'ern') }
140
+ provides(['NewReleaseMessage', 'MessageHeader', 'MessageId'] => 123)
141
+ end
142
+
143
+ populator = XsdPopulator.new({
144
+ :reader=> xsd_reader,
145
+ :logger => logger,
146
+ :provider => provider_class.new
147
+ })
148
+
149
+ expect(Nokogiri.XML(populator.populated_xml).root.name).to eq 'ern:NewReleaseMessage'
150
+ end
151
+ end
152
+
153
+ describe ":content" do
154
+ it "informs the populator to use the specified content for the element" do
155
+ expect(Nokogiri.XML(populator.populated_xml).at('/NewReleaseMessage/ResourceList/SoundRecording/SoundRecordingType').text).to eq 'SuperMegaBox'
156
+ end
157
+
158
+ it "informs the populator to skip an attribute" do
159
+ expect(Nokogiri.XML(populator.populated_xml).at('/NewReleaseMessage/ResourceList/SoundRecording/ReferenceTitle/TitleText').text).to eq 'SuperSmashHitsDeluxe'
160
+ end
161
+ end
162
+ end
@@ -4,10 +4,22 @@
4
4
  # Licensed under the AGPLv3+ http://www.gnu.org/licenses/agpl.txt
5
5
 
6
6
  require 'rspec'
7
+ require 'nokogiri'
8
+ require 'logger'
9
+
10
+ begin
11
+ require 'byebug'
12
+ rescue LoadError => e
13
+ Logger.new(STDOUT).warn("Could not load byebug, continuing without it")
14
+ end
15
+
16
+ def spec_logger
17
+ @spec_logger_cache ||= Logger.new(STDOUT).tap do |logr|
18
+ logr.level = Logger::WARN
19
+ end
20
+ end
7
21
 
8
22
  CURRENT_DIR=File.dirname(__FILE__)
9
23
  $: << File.expand_path(CURRENT_DIR + "/../lib")
10
24
 
11
25
  require 'xsd_populator'
12
- require 'byebug'
13
- require 'nokogiri'
@@ -102,7 +102,7 @@ describe "XsdPopulator for partial layouts" do
102
102
  expect(doc.root.element_children.map(&:name)).to eq ['PartyId', 'PartyName', 'TradingName']
103
103
  end
104
104
 
105
- describe ':relative_provider options' do
105
+ describe ':relative_provider option' do
106
106
  class RelativeProviderTester
107
107
  include DataProvider::Base
108
108
 
@@ -245,86 +245,59 @@ describe "XsdPopulator for partial layouts" do
245
245
  expect(doc.search('/SoundRecordingDetailsByTerritory/Title').map{|node| node.attributes['TitleType'].value}).to eq ['typeA', 'typeB']
246
246
  end
247
247
  end
248
- end
249
-
250
- describe XsdPopulator::Informer do
251
- class InformProvider
252
- include DataProvider::Base
253
-
254
- provides(['NewReleaseMessage', 'MessageHeader'] => XsdPopulator::Informer.new(:skip => true))
255
- provides(['NewReleaseMessage', 'MessageHeader', 'MessageId'] => 123)
256
- end
257
248
 
258
- let(:xsd_reader){
259
- XsdReader::XML.new(:xsd_file => File.expand_path(File.join(File.dirname(__FILE__), 'examples', 'ddex-ern-v36.xsd')))
260
- }
261
-
262
- let(:logger){
263
- logger = Logger.new(STDOUT)
264
- logger.level = Logger::WARN
265
- logger
266
- }
249
+ describe ':builder option' do
250
+ let(:builder){
251
+ b = Builder::XmlMarkup.new(:indent => 2)
252
+ b.instruct!
253
+ b
254
+ }
267
255
 
268
- let(:populator){
269
- XsdPopulator.new({
270
- :reader=> xsd_reader,
271
- :logger => logger,
272
- :provider => InformProvider.new
273
- })
274
- }
256
+ it 'lets you populate XML into an existing builder instance' do
257
+ # create two levels of arbitrary xml nodes
258
+ builder.genericRootNode do |xml|
259
+ xml.genericSubNode do |xml|
260
+ # insert the DDEX MessageSender (with nested content) inside our generic XML
261
+ populator.populate(:builder => xml, :element => ['NewReleaseMessage', 'MessageHeader', 'MessageSender'])
262
+ end
263
+ end
275
264
 
276
- it "informs the populator to skip an element" do
277
- expect(Nokogiri.XML(populator.populated_xml).at('/NewReleaseMessage/MessageHeader')).to eq nil
265
+ # verify our generic XML layout contains the MessageSender part of the DDEX xml
266
+ xml_string = builder.target!
267
+ doc = Nokogiri.XML(xml_string)
268
+ expect(doc.search('//genericRootNode/genericSubNode/MessageSender/PartyName/FullName').length).to eq 1
269
+ end
278
270
  end
279
271
 
280
- it "informs the populator to explicitly add a set of attributes to an element" do
281
- provider_class = Class.new(Object) do
272
+ describe "full stack traversal" do
273
+ class FullStackProvider
282
274
  include DataProvider::Base
283
275
 
284
- provider ['NewReleaseMessage', '@MessageSchemaVersionId']{ '2010/ern-main/32' }
285
-
286
- provider ['NewReleaseMessage']{
287
- XsdPopulator::Informer.new(:attributes => {
288
- 'xmlns:ern' => 'http://ddex.net/xml/2010/ern-main/32',
289
- 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
290
- 'xsi:schemaLocation' => 'http://ddex.net/xml/2010/ern-main/32 http://ddex.net/xml/2010/ern-main/32/ern-main.xsd'
291
- })
292
- }
276
+ provider ['NewReleaseMessage'] do
277
+ self.add_data!(:party_id => 'NewReleaseID__')
278
+ end
293
279
 
294
- provides(['NewReleaseMessage', 'MessageHeader', 'MessageId'] => 123)
280
+ provider ['NewReleaseMessage', 'MessageHeader', 'MessageId'] do
281
+ self.get_data(:party_id) || 'ID-Missing'
282
+ end
295
283
  end
296
284
 
297
- populator = XsdPopulator.new({
298
- :reader=> xsd_reader,
299
- :logger => logger,
300
- :provider => provider_class.new
301
- })
302
-
303
- el = Nokogiri.XML(populator.populated_xml).at('NewReleaseMessage')
304
- expect(el.attributes['schemaLocation'].value).to eq 'http://ddex.net/xml/2010/ern-main/32 http://ddex.net/xml/2010/ern-main/32/ern-main.xsd'
305
- expect(el.attributes['MessageSchemaVersionId'].value).to eq '2010/ern-main/32'
306
- expect(el.attributes.keys.length).to eq 2
307
-
308
- expect(el.namespace_definitions.map{|nsdef| [nsdef.prefix, nsdef.href]}.sort).to eq([
309
- ['ern', 'http://ddex.net/xml/2010/ern-main/32'],
310
- ['xsi', 'http://www.w3.org/2001/XMLSchema-instance']
311
- ])
312
- end
285
+ let(:populator){
286
+ XsdPopulator.new({
287
+ :element => ['NewReleaseMessage', 'MessageHeader'],
288
+ :reader=> xsd_reader,
289
+ :logger => logger,
290
+ :strategy => :complete,
291
+ :provider => FullStackProvider.new
292
+ })
293
+ }
313
294
 
314
- it "informs the populator to prefix a node with a namespace" do
315
- provider_class = Class.new(Object) do
316
- include DataProvider::Base
295
+ let(:doc){
296
+ Nokogiri.XML(populator.populated_xml)
297
+ }
317
298
 
318
- provider ['NewReleaseMessage']{ XsdPopulator::Informer.new(:namespace => 'ern') }
319
- provides(['NewReleaseMessage', 'MessageHeader', 'MessageId'] => 123)
299
+ it "executes the data providers for the omitted parent elements" do
300
+ expect(doc.at('/MessageHeader/MessageId').inner_text).to eq 'NewReleaseID__'
320
301
  end
321
-
322
- populator = XsdPopulator.new({
323
- :reader=> xsd_reader,
324
- :logger => logger,
325
- :provider => provider_class.new
326
- })
327
-
328
- expect(Nokogiri.XML(populator.populated_xml).root.name).to eq 'ern:NewReleaseMessage'
329
302
  end
330
303
  end
@@ -1,19 +1,20 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "xsd-populator"
3
- s.version = '0.2.0'
3
+ s.version = '0.2.1'
4
+ s.date = '2016-01-23'
4
5
  s.files = `git ls-files`.split($/)
5
6
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
6
7
 
7
8
  s.add_dependency 'builder', '~> 3.2'
8
9
  s.add_dependency 'xsd-reader', '~> 0.2'
9
10
  s.add_dependency 'data-provider', '~> 0.2'
11
+ s.add_development_dependency 'rake', '~> 10.1'
10
12
  s.add_development_dependency 'nokogiri', '~> 1.6'
11
13
  s.add_development_dependency 'rspec', '~> 3.3'
12
- s.add_development_dependency 'byebug', '~> 5.0'
13
14
 
14
15
  s.author = "Mark van de Korput"
15
16
  s.email = "dr.theman@gmail.com"
16
- s.date = '2015-08-27'
17
+
17
18
  s.summary = %q{A Ruby gem to build XML data from XSD schemas}
18
19
  s.description = s.summary
19
20
  s.homepage = %q{https://github.com/markkorput/xsd-populator}
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xsd-populator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mark van de Korput
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-27 00:00:00.000000000 Z
11
+ date: 2016-01-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: builder
@@ -53,47 +53,47 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0.2'
55
55
  - !ruby/object:Gem::Dependency
56
- name: nokogiri
56
+ name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '1.6'
61
+ version: '10.1'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '1.6'
68
+ version: '10.1'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rspec
70
+ name: nokogiri
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '3.3'
75
+ version: '1.6'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '3.3'
82
+ version: '1.6'
83
83
  - !ruby/object:Gem::Dependency
84
- name: byebug
84
+ name: rspec
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - "~>"
88
88
  - !ruby/object:Gem::Version
89
- version: '5.0'
89
+ version: '3.3'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
- version: '5.0'
96
+ version: '3.3'
97
97
  description: A Ruby gem to build XML data from XSD schemas
98
98
  email: dr.theman@gmail.com
99
99
  executables: []
@@ -101,12 +101,14 @@ extensions: []
101
101
  extra_rdoc_files: []
102
102
  files:
103
103
  - ".gitignore"
104
+ - ".travis.yml"
104
105
  - Gemfile
105
106
  - Gemfile.lock
106
107
  - LICENSE
107
108
  - README.md
108
109
  - Rakefile
109
110
  - lib/ddex_provider.rb
111
+ - lib/informer.rb
110
112
  - lib/xsd_explanation_provider.rb
111
113
  - lib/xsd_populator.rb
112
114
  - spec/ddex_spec.rb
@@ -116,6 +118,7 @@ files:
116
118
  - spec/examples/ddex-ern-v36-MessageHeader.xml
117
119
  - spec/examples/ddex-ern-v36-NewReleaseMessage.xml
118
120
  - spec/examples/ddex-ern-v36.xsd
121
+ - spec/informer_spec.rb
119
122
  - spec/spec_helper.rb
120
123
  - spec/xsd_explanation_provider_spec.rb
121
124
  - spec/xsd_populator_spec.rb