opinionated-xml 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,60 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require "nokogiri"
3
+ require "om"
4
+
5
+ describe "OM::XML::Container" do
6
+
7
+ before(:all) do
8
+ class ContainerTest
9
+ include OM::XML::Container
10
+ end
11
+ end
12
+
13
+ before(:each) do
14
+ @container = ContainerTest.from_xml("<foo><bar>1</bar></foo>")
15
+ end
16
+
17
+ it "should automatically include the other modules" do
18
+ pending
19
+ ContainerTest.included_modules.should include(OM::XML::Accessor)
20
+ ContainerTest.included_modules.should include(OM::XML::Schema)
21
+ end
22
+
23
+ it "should add .ng_xml accessor" do
24
+ @container.should respond_to(:ng_xml)
25
+ @container.should respond_to(:ng_xml=)
26
+ end
27
+
28
+ describe "new" do
29
+ it "should populate ng_xml with an instance of Nokogiri::XML::Document" do
30
+ @container.ng_xml.class.should == Nokogiri::XML::Document
31
+ end
32
+ end
33
+
34
+ describe "#from_xml" do
35
+ it "should accept a String, parse it and store it in .ng_xml" do
36
+ Nokogiri::XML::Document.expects(:parse).returns("parsed xml")
37
+ container1 = ContainerTest.from_xml("<foo><bar>1</bar></foo>")
38
+ container1.ng_xml.should == "parsed xml"
39
+ end
40
+ it "should accept a File, parse it and store it in .ng_xml" do
41
+ file = fixture(File.join("mods_articles", "hydrangea_article1.xml"))
42
+ Nokogiri::XML::Document.expects(:parse).returns("parsed xml")
43
+ container1 = ContainerTest.from_xml(file)
44
+ container1.ng_xml.should == "parsed xml"
45
+ end
46
+ it "should accept Nokogiri nodes as input and leave them as-is" do
47
+ parsed_xml = Nokogiri::XML::Document.parse("<foo><bar>1</bar></foo>")
48
+ container1 = ContainerTest.from_xml(parsed_xml)
49
+ container1.ng_xml.should == parsed_xml
50
+ end
51
+ end
52
+
53
+ describe ".to_xml" do
54
+ it "should call .ng_xml.to_xml" do
55
+ @container.ng_xml.expects(:to_xml).returns("ng xml")
56
+ @container.to_xml.should == "ng xml"
57
+ end
58
+ end
59
+
60
+ end
@@ -1,12 +1,14 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require "om"
2
3
 
3
- describe "OpinionatedXml" do
4
+ describe "OM::XML::Properties" do
4
5
 
5
6
  before(:all) do
6
7
  #ModsHelpers.name_("Beethoven, Ludwig van", :date=>"1770-1827", :role=>"creator")
7
- class FakeOxMods < Nokogiri::XML::Document
8
-
9
- include OX
8
+ class FakeOxMods
9
+
10
+ include OM::XML::Container
11
+ include OM::XML::Properties
10
12
 
11
13
  # Could add support for multiple root declarations.
12
14
  # For now, assume that any modsCollections have already been broken up and fed in as individual mods documents
@@ -40,8 +42,8 @@ describe "OpinionatedXml" do
40
42
 
41
43
  class FakeOtherOx < Nokogiri::XML::Document
42
44
 
43
- include OX
44
- extend OX::ClassMethods
45
+ include OM::XML::Properties
46
+ # extend OX::ClassMethods
45
47
 
46
48
  root_property :other, "other", "http://www.foo.com"
47
49
 
@@ -50,7 +52,7 @@ describe "OpinionatedXml" do
50
52
  end
51
53
 
52
54
  before(:each) do
53
- @fixturemods = FakeOxMods.parse( fixture( File.join("CBF_MODS", "ARS0025_016.xml") ) )
55
+ @fixturemods = FakeOxMods.from_xml( fixture( File.join("CBF_MODS", "ARS0025_016.xml") ) )
54
56
  end
55
57
 
56
58
  after(:all) do
@@ -68,7 +70,6 @@ describe "OpinionatedXml" do
68
70
  FakeOxMods.root_property_ref.should == :mods
69
71
  FakeOxMods.root_config.should == {:ref=>:mods, :path=>"mods", :namespace=>"http://www.loc.gov/mods/v3", :attributes=>["id", "version"], :schema=>"http://www.loc.gov/standards/mods/v3/mods-3-2.xsd"}
70
72
  FakeOxMods.ox_namespaces.should == {"oxns"=>"http://www.loc.gov/mods/v3"}
71
- FakeOxMods.schema_url.should == "http://www.loc.gov/standards/mods/v3/mods-3-2.xsd"
72
73
 
73
74
  FakeOtherOx.root_property_ref.should == :other
74
75
  FakeOtherOx.root_config.should == {:namespace=>"http://www.foo.com", :path=>"other", :ref=>:other}
@@ -135,16 +136,16 @@ describe "OpinionatedXml" do
135
136
  describe ".lookup" do
136
137
 
137
138
  it "uses the generated xpath queries" do
138
- @fixturemods.expects(:xpath).with('//oxns:name[@type="personal"]', @fixturemods.ox_namespaces)
139
+ @fixturemods.ng_xml.expects(:xpath).with('//oxns:name[@type="personal"]', @fixturemods.ox_namespaces)
139
140
  @fixturemods.lookup(:person)
140
141
 
141
- @fixturemods.expects(:xpath).with('//oxns:name[@type="personal" and contains(oxns:namePart, "Beethoven, Ludwig van")]', @fixturemods.ox_namespaces)
142
+ @fixturemods.ng_xml.expects(:xpath).with('//oxns:name[@type="personal" and contains(oxns:namePart, "Beethoven, Ludwig van")]', @fixturemods.ox_namespaces)
142
143
  @fixturemods.lookup(:person, "Beethoven, Ludwig van")
143
144
 
144
- @fixturemods.expects(:xpath).with('//oxns:name[@type="personal" and contains(oxns:namePart[@type="date"], "2010")]', @fixturemods.ox_namespaces)
145
+ @fixturemods.ng_xml.expects(:xpath).with('//oxns:name[@type="personal" and contains(oxns:namePart[@type="date"], "2010")]', @fixturemods.ox_namespaces)
145
146
  @fixturemods.lookup(:person, :date=>"2010")
146
147
 
147
- @fixturemods.expects(:xpath).with('//oxns:name[@type="personal" and contains(oxns:role/oxns:roleTerm, "donor")]', @fixturemods.ox_namespaces)
148
+ @fixturemods.ng_xml.expects(:xpath).with('//oxns:name[@type="personal" and contains(oxns:role/oxns:roleTerm, "donor")]', @fixturemods.ox_namespaces)
148
149
  @fixturemods.lookup(:person, :role=>"donor")
149
150
 
150
151
  # @fixturemods.expects(:xpath).with('//oxns:name[@type="personal"]/oxns:namePart[@type="date"]', @fixturemods.ox_namespaces)
@@ -242,59 +243,5 @@ describe "OpinionatedXml" do
242
243
  FakeOxMods.send(:applicable_attributes, ["authority", {:type=>["text","code"]}] ).should == {:type=>"text"}
243
244
  end
244
245
  end
245
-
246
- ## Validation Support
247
- # Some of these tests fail when you don't have an internet connection because the mods schema includes other xsd schemas by URL reference.
248
-
249
- describe "#schema" do
250
- it "should return an instance of Nokogiri::XML::Schema loaded from the schema url -- fails if no internet connection" do
251
- FakeOxMods.schema.should be_kind_of Nokogiri::XML::Schema
252
- end
253
- end
254
-
255
- describe "#validate" do
256
- it "should validate the provided document against the schema provided in class definition -- fails if no internet connection" do
257
- FakeOxMods.schema.expects(:validate).with(@fixturemods).returns([])
258
- FakeOxMods.validate(@fixturemods)
259
- end
260
- end
261
-
262
- describe ".validate" do
263
- it "should rely on class validate method" do
264
- FakeOxMods.expects(:validate).with(@fixturemods)
265
- @fixturemods.validate
266
- end
267
- end
268
-
269
- describe "#schema_file" do
270
- before(:all) do
271
- FakeOxMods.schema_file = nil
272
- end
273
-
274
- after(:all) do
275
- FakeOxMods.schema_file = fixture("mods-3-2.xsd")
276
- end
277
-
278
- it "should lazy load the schema file from the @schema_url" do
279
- FakeOxMods.instance_variable_get(:@schema_file).should be_nil
280
- FakeOxMods.expects(:file_from_url).with(FakeOxMods.schema_url).returns("fake file").once
281
- FakeOxMods.schema_file
282
- FakeOxMods.instance_variable_get(:@schema_file).should == "fake file"
283
- FakeOxMods.schema_file.should == "fake file"
284
- end
285
- end
286
-
287
- describe "#file_from_url" do
288
- it "should retrieve a file from the provided url over HTTP" do
289
- FakeOxMods.send(:file_from_url, "http://google.com")
290
- end
291
- it "should raise an error if the url is invalid" do
292
- lambda {FakeOxMods.send(:file_from_url, "")}.should raise_error(RuntimeError, "Could not retrieve file from . Error: No such file or directory - ")
293
- lambda {FakeOxMods.send(:file_from_url, "foo")}.should raise_error(RuntimeError, "Could not retrieve file from foo. Error: No such file or directory - foo")
294
- end
295
- it "should raise an error if file retrieval fails" do
296
- lambda {FakeOxMods.send(:file_from_url, "http://fedora-commons.org/nonexistent_file")}.should raise_error(RuntimeError, "Could not retrieve file from http://fedora-commons.org/nonexistent_file. Error: 404 Not Found")
297
- end
298
- end
299
246
 
300
247
  end
@@ -0,0 +1,245 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require "om"
3
+
4
+ describe "OM::XML::PropertyValueOperators" do
5
+
6
+ before(:all) do
7
+ #ModsHelpers.name_("Beethoven, Ludwig van", :date=>"1770-1827", :role=>"creator")
8
+ class PropertiesValueOperatorsTest
9
+
10
+ include OM::XML::Container
11
+ include OM::XML::Properties
12
+ include OM::XML::PropertyValueOperators
13
+
14
+ # Could add support for multiple root declarations.
15
+ # For now, assume that any modsCollections have already been broken up and fed in as individual mods documents
16
+ # root :mods_collection, :path=>"modsCollection",
17
+ # :attributes=>[],
18
+ # :subelements => :mods
19
+
20
+ root_property :mods, "mods", "http://www.loc.gov/mods/v3", :attributes=>["id", "version"], :schema=>"http://www.loc.gov/standards/mods/v3/mods-3-2.xsd"
21
+
22
+
23
+ property :name_, :path=>"name",
24
+ :attributes=>[:xlink, :lang, "xml:lang", :script, :transliteration, {:type=>["personal", "enumerated", "corporate"]} ],
25
+ :subelements=>["namePart", "displayForm", "affiliation", :role, "description"],
26
+ :default_content_path => "namePart",
27
+ :convenience_methods => {
28
+ :date => {:path=>"namePart", :attributes=>{:type=>"date"}},
29
+ :family_name => {:path=>"namePart", :attributes=>{:type=>"family"}},
30
+ :given_name => {:path=>"namePart", :attributes=>{:type=>"given"}},
31
+ :terms_of_address => {:path=>"namePart", :attributes=>{:type=>"termsOfAddress"}}
32
+ }
33
+
34
+ property :person, :variant_of=>:name_, :attributes=>{:type=>"personal"}
35
+
36
+ property :role, :path=>"role",
37
+ :parents=>[:name_],
38
+ :attributes=>[ { "type"=>["text", "code"] } , "authority"],
39
+ :default_content_path => "roleTerm"
40
+
41
+
42
+ end
43
+
44
+ end
45
+
46
+ before(:each) do
47
+ @sample = PropertiesValueOperatorsTest.from_xml( fixture( File.join("test_dummy_mods.xml") ) )
48
+ end
49
+
50
+ after(:all) do
51
+ Object.send(:remove_const, :PropertiesValueOperatorsTest)
52
+ end
53
+
54
+ describe ".property_values" do
55
+
56
+ it "should call .lookup and then build an array of values from the returned nodeset (using default_node, etc as nessesary)" do
57
+ lookup_opts = "insert args here"
58
+ mock_node = mock("node")
59
+ mock_node.expects(:text).returns("sample value").times(3)
60
+ mock_nodeset = [mock_node, mock_node, mock_node]
61
+ @sample.expects(:lookup).with(lookup_opts).returns(mock_nodeset)
62
+
63
+ @sample.property_values(lookup_opts).should == ["sample value","sample value","sample value"]
64
+ end
65
+
66
+ end
67
+
68
+ describe ".property_values_append" do
69
+
70
+ it "looks up the parent using :parent_select, uses :child_index to choose the parent node from the result set, uses :template to build the node(s) to be inserted, inserts the :values(s) into the node(s) and adds the node(s) to the parent" do
71
+ @sample.property_values_append(
72
+ :parent_select => [:person, {:given_name=>"Tim", :family_name=>"Berners-Lee"}] ,
73
+ :child_index => :first,
74
+ :template => [:person, :affiliation],
75
+ :values => ["my new value", "another new value"]
76
+ )
77
+ end
78
+
79
+ it "should accept parent_select and template [property_reference, lookup_opts] as argument arrays for generators/lookups" do
80
+ # this appends two affiliation nodes into the first person node whose name is Tim Berners-Lee
81
+ expected_result = '<ns3:name type="personal">
82
+ <ns3:namePart type="family">Berners-Lee</ns3:namePart>
83
+ <ns3:namePart type="given">Tim</ns3:namePart>
84
+ <ns3:role>
85
+ <ns3:roleTerm type="text" authority="marcrelator">creator</ns3:roleTerm>
86
+ <ns3:roleTerm type="code" authority="marcrelator">cre</ns3:roleTerm>
87
+ </ns3:role>
88
+ <ns3:affiliation>my new value</ns3:affiliation><ns3:affiliation>another new value</ns3:affiliation></ns3:name>'
89
+
90
+ @sample.property_values_append(
91
+ :parent_select => [:person, {:given_name=>"Tim", :family_name=>"Berners-Lee"}] ,
92
+ :child_index => :first,
93
+ :template => [:person, :affiliation],
94
+ :values => ["my new value", "another new value"]
95
+ ).to_xml.should == expected_result
96
+
97
+ @sample.lookup(:person, {:given_name=>"Tim", :family_name=>"Berners-Lee"}).first.to_xml.should == expected_result
98
+ end
99
+
100
+ it "should accept symbols as arguments for generators/lookups" do
101
+ # this appends a role of "my role" into the third "person" node in the document
102
+ expected_result = "<ns3:name type=\"personal\">\n <ns3:namePart type=\"family\">Klimt</ns3:namePart>\n <ns3:namePart type=\"given\">Gustav</ns3:namePart>\n <ns3:role>\n <ns3:roleTerm type=\"text\" authority=\"marcrelator\">creator</ns3:roleTerm>\n <ns3:roleTerm type=\"code\" authority=\"marcrelator\">cre</ns3:roleTerm>\n </ns3:role>\n <ns3:role>\n <ns3:roleTerm type=\"text\" authority=\"marcrelator\">visionary</ns3:roleTerm>\n <ns3:roleTerm type=\"code\" authority=\"marcrelator\">vry</ns3:roleTerm>\n </ns3:role>\n <ns3:role type=\"text\"><ns3:roleTerm>my role</ns3:roleTerm></ns3:role></ns3:name>"
103
+
104
+ @sample.property_values_append(
105
+ :parent_select => :person ,
106
+ :child_index => 3,
107
+ :template => :role,
108
+ :values => "my role"
109
+ ).to_xml.should == expected_result
110
+
111
+ @sample.lookup(:person)[3].to_xml.should == expected_result
112
+ end
113
+
114
+ it "should accept parent_select as an (xpath) string and template as a (template) string" do
115
+ # this uses the provided template to add a node into the first node resulting from the xpath '//oxns:name[@type="personal"]'
116
+ expected_result = "<ns3:name type=\"personal\">\n <ns3:namePart type=\"family\">Berners-Lee</ns3:namePart>\n <ns3:namePart type=\"given\">Tim</ns3:namePart>\n <ns3:role>\n <ns3:roleTerm type=\"text\" authority=\"marcrelator\">creator</ns3:roleTerm>\n <ns3:roleTerm type=\"code\" authority=\"marcrelator\">cre</ns3:roleTerm>\n </ns3:role>\n <ns3:role type=\"code\" authority=\"marcrelator\"><ns3:roleTerm>creator</ns3:roleTerm></ns3:role></ns3:name>"
117
+
118
+ @sample.ng_xml.xpath('//oxns:name[@type="personal" and position()=1]/oxns:role', @sample.ox_namespaces).length.should == 1
119
+
120
+ @sample.property_values_append(
121
+ :parent_select =>'//oxns:name[@type="personal"]',
122
+ :child_index => 0,
123
+ :template => 'xml.role { xml.roleTerm( \'#{builder_new_value}\', :type=>\'code\', :authority=>\'marcrelator\') }',
124
+ :values => "founder"
125
+ )
126
+
127
+ @sample.ng_xml.xpath('//oxns:name[@type="personal" and position()=1]/oxns:role', @sample.ox_namespaces).length.should == 2
128
+ @sample.ng_xml.xpath('//oxns:name[@type="personal" and position()=1]/oxns:role[last()]/oxns:roleTerm', @sample.ox_namespaces).first.text.should == "founder"
129
+
130
+ # @sample.lookup(:person).first.to_xml.should == expected_result
131
+ end
132
+
133
+ it "should support more complex mixing & matching" do
134
+ expected_result = "<ns3:name type=\"personal\">\n <ns3:namePart type=\"family\">Jobs</ns3:namePart>\n <ns3:namePart type=\"given\">Steve</ns3:namePart>\n <ns3:namePart type=\"date\">2004</ns3:namePart>\n <ns3:role>\n <ns3:roleTerm type=\"text\" authority=\"marcrelator\">creator</ns3:roleTerm>\n <ns3:roleTerm type=\"code\" authority=\"marcrelator\">cre</ns3:roleTerm>\n </ns3:role>\n <ns3:role type=\"code\" authority=\"marcrelator\"><ns3:roleTerm>foo</ns3:roleTerm></ns3:role></ns3:name>"
135
+
136
+ @sample.ng_xml.xpath('//oxns:name[@type="personal" and position()=2]/oxns:role', @sample.ox_namespaces).length.should == 1
137
+
138
+ @sample.property_values_append(
139
+ :parent_select =>'//oxns:name[@type="personal"]',
140
+ :child_index => 1,
141
+ :template => [ :person, :role, {:attributes=>{"type"=>"code", "authority"=>"marcrelator"}} ],
142
+ :values => "foo"
143
+ )
144
+
145
+ @sample.ng_xml.xpath('//oxns:name[@type="personal" and position()=2]/oxns:role', @sample.ox_namespaces).length.should == 2
146
+ @sample.lookup(:person)[1].search("./oxns:role[last()]/oxns:roleTerm", @sample.ox_namespaces).first.text.should == "foo"
147
+ end
148
+
149
+ it "should raise exception if no node corresponds to the provided :parent_select and :child_index"
150
+
151
+ end
152
+
153
+ describe ".property_value_update" do
154
+
155
+ it "should accept an xpath as :parent_select" do
156
+ sample_xpath = '//oxns:name[@type="personal"]/oxns:role/oxns:roleTerm[@type="text"]'
157
+ @sample.property_value_update(
158
+ :parent_select =>sample_xpath,
159
+ :child_index => 1,
160
+ :value => "donor"
161
+ )
162
+ @sample.ng_xml.xpath(sample_xpath, @sample.ox_namespaces)[1].text.should == "donor"
163
+ end
164
+
165
+ it "if :select is provided, should update the first node provided by that xpath statement" do
166
+ sample_xpath = '//oxns:name[@type="personal" and position()=1]/oxns:namePart[@type="given"]'
167
+ @sample.property_value_update(
168
+ :select =>sample_xpath,
169
+ :value => "Timmeh"
170
+ )
171
+ @sample.ng_xml.xpath(sample_xpath, @sample.ox_namespaces).first.text.should == "Timmeh"
172
+ end
173
+
174
+ it "should replace the existing node if you pass a template and values" do
175
+ pending
176
+ @sample.property_value_update(
177
+ :parent_select =>'//oxns:name[@type="personal"]',
178
+ :child_index => 1,
179
+ :template => [ :person, :role, {:attributes=>{"type"=>"code", "authority"=>"marcrelator"}} ],
180
+ :value => "foo"
181
+ )
182
+ 1.should == 2
183
+ end
184
+ end
185
+
186
+ describe ".property_value_delete" do
187
+ it "should accept an xpath query as :select option" do
188
+ generic_xpath = '//oxns:name[@type="personal" and position()=4]/oxns:role'
189
+ specific_xpath = '//oxns:name[@type="personal" and position()=4]/oxns:role[oxns:roleTerm="visionary"]'
190
+ select_xpath = '//oxns:name[@type="personal" and position()=4]/oxns:role[last()]'
191
+
192
+ # Check that we're starting with 2 roles
193
+ # Check that the specific node we want to delete exists
194
+ @sample.lookup(generic_xpath).length.should == 2
195
+ @sample.lookup(specific_xpath).length.should == 1
196
+
197
+ @sample.property_value_delete(
198
+ :select =>select_xpath
199
+ )
200
+ # Check that we're finishing with 1 role
201
+ @sample.lookup(generic_xpath).length.should == 1
202
+ # Check that the specific node we want to delete no longer exists
203
+ @sample.lookup(specific_xpath).length.should == 0
204
+ end
205
+ it "should accept :parent_select, :parent_index and :child_index options instead of a :select" do
206
+
207
+ generic_xpath = '//oxns:name[@type="personal" and position()=4]/oxns:role/oxns:roleTerm'
208
+ specific_xpath = '//oxns:name[@type="personal" and position()=4]/oxns:role[oxns:roleTerm="visionary"]'
209
+
210
+ # Check that we're starting with 2 roles
211
+ # Check that the specific node we want to delete exists
212
+ @sample.lookup(generic_xpath).length.should == 4
213
+ @sample.lookup(specific_xpath).length.should == 1
214
+
215
+ # this is attempting to delete the last child (in this case roleTerm) from the 3rd role in the document.
216
+ @sample.property_value_delete(
217
+ :parent_select => [:person, :role],
218
+ :parent_index => 3,
219
+ :child_index => :last
220
+ )
221
+
222
+ # Check that we're finishing with 1 role
223
+ @sample.lookup(generic_xpath).length.should == 3
224
+ # Check that the specific node we want to delete no longer exists
225
+ @sample.lookup(specific_xpath).length.should == 1
226
+ end
227
+ it "should work if only :parent_select and :child_index are provided" do
228
+ generic_xpath = '//oxns:name[@type="personal"]/oxns:role'
229
+ # specific_xpath = '//oxns:name[@type="personal"]/oxns:role'
230
+
231
+ # Check that we're starting with 2 roles
232
+ # Check that the specific node we want to delete exists
233
+ @sample.lookup(generic_xpath).length.should == 4
234
+ # @sample.lookup(specific_xpath).length.should == 1
235
+
236
+ @sample.property_value_delete(
237
+ :parent_select => [:person, :role],
238
+ :child_index => 3
239
+ )
240
+ # Check that we're finishing with 1 role
241
+ @sample.lookup(generic_xpath).length.should == 3
242
+ end
243
+ end
244
+
245
+ end
@@ -0,0 +1,78 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
2
+ require "nokogiri"
3
+ require "om"
4
+
5
+ describe "OM::XML::Validation" do
6
+
7
+ before(:all) do
8
+ class ValidationTest
9
+ include OM::XML::Container
10
+ include OM::XML::Validation
11
+ self.schema_url = "http://www.loc.gov/standards/mods/v3/mods-3-2.xsd"
12
+ end
13
+ end
14
+
15
+ before(:each) do
16
+ @sample = ValidationTest.from_xml("<foo><bar>1</bar></foo>")
17
+ end
18
+
19
+ ## Validation Support
20
+ # Some of these tests fail when you don't have an internet connection because the mods schema includes other xsd schemas by URL reference.
21
+
22
+ describe '#schema_url' do
23
+ it "should allow you to set the schema url" do
24
+ ValidationTest.schema_url.should == "http://www.loc.gov/standards/mods/v3/mods-3-2.xsd"
25
+ end
26
+ end
27
+
28
+ describe "#schema" do
29
+ it "should return an instance of Nokogiri::XML::Schema loaded from the schema url -- fails if no internet connection" do
30
+ ValidationTest.schema.should be_kind_of Nokogiri::XML::Schema
31
+ end
32
+ end
33
+
34
+ describe "#validate" do
35
+ it "should validate the provided document against the schema provided in class definition -- fails if no internet connection" do
36
+ ValidationTest.schema.expects(:validate).with(@sample).returns([])
37
+ ValidationTest.validate(@sample)
38
+ end
39
+ end
40
+
41
+ describe ".validate" do
42
+ it "should rely on class validate method" do
43
+ ValidationTest.expects(:validate).with(@sample)
44
+ @sample.validate
45
+ end
46
+ end
47
+
48
+ describe "#schema_file" do
49
+ before(:all) do
50
+ ValidationTest.schema_file = nil
51
+ end
52
+
53
+ after(:all) do
54
+ ValidationTest.schema_file = fixture("mods-3-2.xsd")
55
+ end
56
+
57
+ it "should lazy load the schema file from the @schema_url" do
58
+ ValidationTest.instance_variable_get(:@schema_file).should be_nil
59
+ ValidationTest.expects(:file_from_url).with(ValidationTest.schema_url).returns("fake file").once
60
+ ValidationTest.schema_file
61
+ ValidationTest.instance_variable_get(:@schema_file).should == "fake file"
62
+ ValidationTest.schema_file.should == "fake file"
63
+ end
64
+ end
65
+
66
+ describe "#file_from_url" do
67
+ it "should retrieve a file from the provided url over HTTP" do
68
+ ValidationTest.send(:file_from_url, "http://google.com")
69
+ end
70
+ it "should raise an error if the url is invalid" do
71
+ lambda {ValidationTest.send(:file_from_url, "")}.should raise_error(RuntimeError, "Could not retrieve file from . Error: No such file or directory - ")
72
+ lambda {ValidationTest.send(:file_from_url, "foo")}.should raise_error(RuntimeError, "Could not retrieve file from foo. Error: No such file or directory - foo")
73
+ end
74
+ it "should raise an error if file retrieval fails" do
75
+ lambda {ValidationTest.send(:file_from_url, "http://fedora-commons.org/nonexistent_file")}.should raise_error(RuntimeError, "Could not retrieve file from http://fedora-commons.org/nonexistent_file. Error: 404 Not Found")
76
+ end
77
+ end
78
+ end