xsd-populator 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,13 @@
1
+ # loads and runs all tests for the rxsd project
2
+ #
3
+ # Copyright (C) 2010 Mohammed Morsi <movitto@yahoo.com>
4
+ # Licensed under the AGPLv3+ http://www.gnu.org/licenses/agpl.txt
5
+
6
+ require 'rspec'
7
+
8
+ CURRENT_DIR=File.dirname(__FILE__)
9
+ $: << File.expand_path(CURRENT_DIR + "/../lib")
10
+
11
+ require 'xsd_populator'
12
+ require 'byebug'
13
+ require 'nokogiri'
@@ -0,0 +1,44 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+ require 'xsd_explanation_provider'
3
+
4
+ describe XsdExplanationProvider do
5
+ let(:logger){
6
+ logger = Logger.new(STDOUT)
7
+ logger.level = Logger::WARN
8
+ logger
9
+ }
10
+
11
+ let(:populator){
12
+ XsdPopulator.new(:xsd_file => File.expand_path(File.join(File.dirname(__FILE__), 'examples', 'ddex-ern-v36.xsd')), :logger => logger)
13
+ }
14
+
15
+ let(:provider){
16
+ XsdExplanationProvider.new(:data => {:xsd_reader => populator.xsd_reader}, :logger => logger)
17
+ }
18
+
19
+ it "requires an xsd reader" do
20
+ msg = expect{ XsdExplanationProvider.new(:logger => logger).take(:something) }.to raise_error(RuntimeError, 'XsdExplanationProvider needs an xsd reader')
21
+ end
22
+
23
+ it "gives itself for complex elements" do
24
+ expect(provider.take('NewReleaseMessage')).to eq provider
25
+ expect(provider.take(['NewReleaseMessage', 'MessageHeader'])).to eq provider
26
+ end
27
+
28
+ it "gives the element type for simple elements" do
29
+ expect(provider.take(['NewReleaseMessage', 'MessageHeader', 'MessageId'])).to eq 'xs:string'
30
+ end
31
+
32
+ it "gives the attribute type for attributes" do
33
+ expect(provider.take(['NewReleaseMessage', 'MessageHeader', '@LanguageAndScriptCode'])).to eq 'xs:string'
34
+ end
35
+
36
+ it "is the default fallback provider for XsdPopulators without a specified provider" do
37
+ expect(populator.provider.class).to eq XsdExplanationProvider
38
+ xml = populator.populate_element(['NewReleaseMessage', 'MessageHeader', 'MessageSender'])
39
+ # puts xml
40
+ doc = Nokogiri.XML(xml)
41
+ expect(doc.at('/MessageSender/PartyId').text).to eq 'xs:string'
42
+ expect(doc.at('/MessageSender').attributes['LanguageAndScriptCode'].value).to eq 'xs:string'
43
+ end
44
+ end # describe XsdExplanationProvider
@@ -0,0 +1,211 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe XsdPopulator do
4
+ let(:xsd_reader){
5
+ XsdReader::XML.new(:xsd_file => File.expand_path(File.join(File.dirname(__FILE__), 'examples', 'ddex-ern-v36.xsd')))
6
+ }
7
+
8
+ let(:logger){
9
+ logger = Logger.new(STDOUT)
10
+ logger.level = Logger::WARN
11
+ logger
12
+ }
13
+
14
+ let(:populator){
15
+ XsdPopulator.new(:reader => xsd_reader, :logger => logger)
16
+ }
17
+
18
+ describe "#configure" do
19
+ it "lets you change the configuration options at runtime" do
20
+ expect(populator.xsd_reader).to eq xsd_reader
21
+ expect(populator.logger).to eq logger
22
+ expect(populator.options[:relative_provider]).to eq nil
23
+ # save current configuration
24
+ old_options = populator.options.merge(:relative_provider => nil)
25
+ # reconfigure with invalid data
26
+ populator.configure({:reader => :dummy, :logger => :lagger, :relative_provider => :absolutely})
27
+ # some assertion
28
+ expect(populator.xsd_reader).to eq :dummy
29
+ expect(populator.logger).to eq :lagger
30
+ expect(populator.options[:relative_provider]).to eq :absolutely
31
+ # restore configuration
32
+ populator.configure old_options
33
+ # verify
34
+ expect(populator.xsd_reader).to eq xsd_reader
35
+ expect(populator.logger).to eq logger
36
+ expect(populator.options[:relative_provider]).to eq nil
37
+ end
38
+ end
39
+
40
+ describe "#uncache" do
41
+ it "lets you clear the populated_xml cache" do
42
+ # first create a dummy cache, because producing the full XML will take too much time
43
+ populator.instance_variable_set('@populated_xml', :dummy_value)
44
+ # verify the above instance variable is used to cache populaed_xml
45
+ expect(populator.populated_xml).to eq :dummy_value
46
+ # do it!
47
+ populator.uncache
48
+ # verify the cache instance var is clear
49
+ expect(populator.instance_variable_get('@populated_xml')).to eq nil
50
+ end
51
+ end
52
+
53
+ # # TAKES LONG
54
+ # it "should generate xml without data and include comments" do
55
+ # expect(doc.root_node.name).to eq 'NewReleaseMessage'
56
+ # end
57
+
58
+ # # TAKES LONG
59
+ # it "writes to file" do
60
+ # @populator.write_file(File.dirname(__FILE__) + '/examples/ddex-ern-v36.xml')
61
+ # end
62
+
63
+ # TAKES LONG
64
+ # it "it lets you specify a root-level element" do
65
+ # populator = XsdPopulator.new(:xsd_reader => @populator.xsd_reader, :element => 'CatalogListMessage')
66
+ # populator.write_file(File.dirname(__FILE__) + '/examples/ddex-ern-v36-CatalogListMessage2.xml')
67
+ # end
68
+ end
69
+
70
+ describe "XsdPopulator for partial layouts" do
71
+ let(:xsd_reader){
72
+ XsdReader::XML.new(:xsd_file => File.expand_path(File.join(File.dirname(__FILE__), 'examples', 'ddex-ern-v36.xsd')))
73
+ }
74
+
75
+ let(:logger){
76
+ logger = Logger.new(STDOUT)
77
+ logger.level = Logger::WARN
78
+ logger
79
+ }
80
+
81
+ let(:populator){
82
+ XsdPopulator.new({
83
+ :element => ['NewReleaseMessage', 'MessageHeader'],
84
+ :reader=> xsd_reader,
85
+ :logger => logger,
86
+ :strategy => :complete
87
+ })
88
+ }
89
+
90
+ it "lets you specify any specific element as root element at initialization" do
91
+ doc = Nokogiri.XML(populator.populated_xml)
92
+ expect(doc.root.name).to eq 'MessageHeader'
93
+ expect(doc.root.element_children.map(&:name)).to eq ["MessageThreadId", "MessageId", "MessageFileName", "MessageSender", "SentOnBehalfOf", "MessageRecipient", "MessageCreatedDateTime", "MessageAuditTrail", "Comment", "MessageControlType"]
94
+ expect(doc.root.at('MessageSender').at('PartyName').at('FullName').attributes['LanguageAndScriptCode'].value).to eq "xs:string"
95
+ expect(doc.root.at('MessageSender').at('PartyName').at('FullNameAsciiTranscribed').attributes).to eq({})
96
+ end
97
+
98
+ it "lets you specify any specific element to populate" do
99
+ xml = populator.populate_element([:NewReleaseMessage, :MessageHeader, :MessageSender])
100
+ doc = Nokogiri.XML(xml)
101
+ expect(doc.root.name).to eq 'MessageSender'
102
+ expect(doc.root.element_children.map(&:name)).to eq ['PartyId', 'PartyName', 'TradingName']
103
+ end
104
+
105
+ describe ':relative_provider options' do
106
+ class RelativeProviderTester
107
+ include DataProvider::Base
108
+
109
+ provides({
110
+ # for default/full stsack strategy
111
+ ['NewReleaseMessage', 'MessageHeader', 'MessageId'] => 'Full ID',
112
+ # for :relative_provider => true strategies with MessageHeader as root element
113
+ ['MessageHeader', 'MessageId'] => 'Relative Version1',
114
+ # for :relative_provider => true strategies with MessageId as root element
115
+ ['MessageId'] => 'Relative Version2'
116
+ })
117
+ end
118
+
119
+ it "by default uses the full stack for provider ids" do
120
+ populator.configure(:provider => RelativeProviderTester.new)
121
+ expect(Nokogiri.XML(populator.populated_xml).at('/MessageHeader/MessageId').text).to eq 'Full ID'
122
+ expect(Nokogiri.XML(populator.populate_element(['NewReleaseMessage', 'MessageHeader', 'MessageId'])).at('/MessageId').text).to eq 'Full ID'
123
+ end
124
+
125
+ it "uses 'relative' provider ids when the :relative_provider option is true" do
126
+ populator.configure(:provider => RelativeProviderTester.new, :relative_provider => true)
127
+ # MessageHeader is root element
128
+ expect(Nokogiri.XML(populator.populated_xml).at('/MessageHeader/MessageId').text).to eq 'Relative Version1'
129
+ # MessageId is root element
130
+ expect(Nokogiri.XML(populator.populate_element(['NewReleaseMessage', 'MessageHeader', 'MessageId'])).at('/MessageId').text).to eq 'Relative Version2'
131
+ end
132
+ end
133
+
134
+ describe XsdPopulator::ElementNotFoundException do
135
+ it 'is thrown when a specified root element cannot be found' do
136
+ expect{ populator.populate_element('InvalidNode') }.to raise_error(XsdPopulator::ElementNotFoundException)
137
+ pop = XsdPopulator.new(:xsd_reader => xsd_reader, :element => ['NewReleaseMessage', 'Foo'], :logger => logger)
138
+ expect{pop.populated_xml}.to raise_error(XsdPopulator::ElementNotFoundException)
139
+ end
140
+ end
141
+
142
+ describe :strategy do
143
+ class StrategyProvider
144
+ include DataProvider::Base
145
+
146
+ provides({
147
+ ['NewReleaseMessage', 'DealList', 'ReleaseDeal'] => 'Invalid value; ReleaseDeal is a complex node with child-nodes, it should get a DataProvider, not a string',
148
+ ['NewReleaseMessage', 'ReleaseList'] => 'Invalid again',
149
+ ['NewReleaseMessage', 'ResourceList'] => StrategyProvider.new,
150
+ ['NewReleaseMessage', 'WorkList', 'MusicalWork', 'MusicalWorkId'] => lambda{ [StrategyProvider.new] * 3 },
151
+ ['NewReleaseMessage', 'MessageHeader', 'SentOnBehalfOf', '@LanguageAndScriptCode'] => 'UK'
152
+ })
153
+ end
154
+
155
+ let(:populator){
156
+ XsdPopulator.new({
157
+ # :element => ['NewReleaseMessage', 'MessageHeader'], # We're going for 'FULL' render this time
158
+ :reader => xsd_reader,
159
+ :provider => StrategyProvider.new,
160
+ :logger => logger
161
+ })
162
+ }
163
+
164
+ it "defaults to the :smart strategy which doesn't add nodes for which no (valid) data is provided, unless there are providers available for any its offspring nodes" do
165
+ xml = populator.populated_xml
166
+ doc = Nokogiri.XML(xml)
167
+ # There's a provider available for ReleaseDeal, an offspring of DealList, and
168
+ # even though it will return invalid data, it will still cause the DealList node to be created
169
+ expect(doc.search("/NewReleaseMessage/DealList").length).to eq 1
170
+ expect(doc.search("/NewReleaseMessage/DealList/ReleaseDeal").length).to eq 0
171
+ # There is a provider for ReleaseList itself, but it returns invalid data; it will not be created
172
+ expect(doc.search("/NewReleaseMessage/ReleaseList").length).to eq 0
173
+ # There is a provider with valid data (a DataProvider object) for ResourceList, it will be created
174
+ expect(doc.search("/NewReleaseMessage/ResourceList").length).to eq 1
175
+ # There is no data provider for WorkList, but there is for one of it descendents so it's created
176
+ expect(doc.search("/NewReleaseMessage/WorkList").length).to eq 1
177
+ # for MusicalWorkId multiple data providers are provided,
178
+ # so multiple nodes will be created. All of them will be empty though...
179
+ expect(doc.search("/NewReleaseMessage/WorkList/MusicalWork/MusicalWorkId").map{|mw| mw.element_children.length}).to eq [0]*3
180
+ end
181
+
182
+ it "adds empty simple nodes when :strategy is :all_simple_elements" do
183
+ populator.configure(:strategy => :nil_to_empty)
184
+ doc = Nokogiri.XML(xml = populator.populated_xml)
185
+ expect(doc.search("/NewReleaseMessage/DealList").length).to eq 1 # jsut like
186
+ expect(doc.search("/NewReleaseMessage/DealList/ReleaseDeal").length).to eq 0
187
+ expect(doc.search("/NewReleaseMessage/ReleaseList").length).to eq 0
188
+ expect(doc.search("/NewReleaseMessage/ResourceList").length).to eq 1
189
+ expect(doc.search("/NewReleaseMessage/WorkList").length).to eq 1
190
+ expect(doc.search("/NewReleaseMessage/WorkList/MusicalWork/MusicalWorkId").map{|mw| mw.element_children.length}).to eq [4]*3
191
+ end
192
+
193
+ it "builds all the nodes it can find if the :strategy option is set to :complete" do
194
+ populator.configure(:strategy => :complete, :element => ['NewReleaseMessage', 'WorkList'])
195
+ doc = Nokogiri.XML(xml = populator.populated_xml)
196
+ expect(doc.search("/WorkList").length).to eq 1
197
+ expect(doc.search("/WorkList/MusicalWork/MusicalWorkId").map{|n| n.search("./ISWC").length}).to eq [1]*3
198
+ end
199
+
200
+ it "by default doesn't add provider-less attributes" do
201
+ xml = populator.populated_xml
202
+ doc = Nokogiri.XML(xml)
203
+ expect(doc.at("/NewReleaseMessage").attributes['MessageSchemaVersionId'].value).to eq '' # required attribute
204
+ expect(doc.at("/NewReleaseMessage").attributes['ReleaseProfileVersionId']).to eq nil
205
+ expect(doc.at("/NewReleaseMessage").attributes['LanguageAndScriptCode']).to eq nil
206
+ expect(doc.at("/NewReleaseMessage").attributes['LanguageAndScriptCode']).to eq nil
207
+ expect(doc.at("/NewReleaseMessage/MessageHeader").attributes['LanguageAndScriptCode']).to eq nil
208
+ expect(doc.at("/NewReleaseMessage/MessageHeader/SentOnBehalfOf").attributes['LanguageAndScriptCode'].value).to eq 'UK'
209
+ end
210
+ end
211
+ end
@@ -0,0 +1,24 @@
1
+ GEM_NAME="xsd-populator"
2
+ PKG_VERSION='0.1.0'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = GEM_NAME
6
+ s.version = PKG_VERSION
7
+ s.files = `git ls-files`.split($/)
8
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
9
+
10
+ s.add_dependency 'builder', '~> 3.2'
11
+ s.add_dependency 'xsd-reader', '~> 0.1'
12
+ s.add_dependency 'data-provider', '~> 0.1'
13
+ s.add_development_dependency 'nokogiri', '~> 1.6'
14
+ s.add_development_dependency 'rspec', '~> 3.3'
15
+ s.add_development_dependency 'byebug', '~> 5.0'
16
+
17
+ s.author = "Mark van de Korput"
18
+ s.email = "dr.theman@gmail.com"
19
+ s.date = '2015-07-14'
20
+ s.summary = %q{A Ruby gem to build XML data from XSD schemas}
21
+ s.description = %q{A library of Ruby classes for generating XML data from XSD schemas (Data providers)}
22
+ s.homepage = %q{https://github.com/markkorput/xsd-populator}
23
+ s.license = "MIT"
24
+ end
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xsd-populator
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mark van de Korput
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: builder
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: xsd-reader
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: data-provider
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '0.1'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: nokogiri
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.6'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.6'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.3'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.3'
83
+ - !ruby/object:Gem::Dependency
84
+ name: byebug
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '5.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '5.0'
97
+ description: A library of Ruby classes for generating XML data from XSD schemas (Data
98
+ providers)
99
+ email: dr.theman@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - Gemfile
106
+ - Gemfile.lock
107
+ - LICENSE
108
+ - README.md
109
+ - Rakefile
110
+ - lib/ddex_provider.rb
111
+ - lib/xsd_explanation_provider.rb
112
+ - lib/xsd_populator.rb
113
+ - spec/ddex_spec.rb
114
+ - spec/examples/MessageHeader.xml
115
+ - spec/examples/avs.xsd
116
+ - spec/examples/ddex-ern-v36-CatalogListMessage.xml
117
+ - spec/examples/ddex-ern-v36-MessageHeader.xml
118
+ - spec/examples/ddex-ern-v36-NewReleaseMessage.xml
119
+ - spec/examples/ddex-ern-v36.xsd
120
+ - spec/spec_helper.rb
121
+ - spec/xsd_explanation_provider_spec.rb
122
+ - spec/xsd_populator_spec.rb
123
+ - xsd-populator.gemspec
124
+ homepage: https://github.com/markkorput/xsd-populator
125
+ licenses:
126
+ - MIT
127
+ metadata: {}
128
+ post_install_message:
129
+ rdoc_options: []
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ requirements: []
143
+ rubyforge_project:
144
+ rubygems_version: 2.2.2
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: A Ruby gem to build XML data from XSD schemas
148
+ test_files: []