ruby-avm-library 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/.autotest +5 -0
  2. data/.gitignore +5 -0
  3. data/.rspec +5 -0
  4. data/Gemfile +14 -0
  5. data/README.md +56 -0
  6. data/Rakefile +2 -0
  7. data/autotest/discover.rb +2 -0
  8. data/bin/avm2avm +7 -0
  9. data/lib/avm/cli.rb +18 -0
  10. data/lib/avm/contact.rb +40 -0
  11. data/lib/avm/controlled_vocabulary.rb +23 -0
  12. data/lib/avm/coordinate_frame.rb +10 -0
  13. data/lib/avm/coordinate_system_projection.rb +10 -0
  14. data/lib/avm/creator.rb +123 -0
  15. data/lib/avm/image.rb +355 -0
  16. data/lib/avm/image_quality.rb +10 -0
  17. data/lib/avm/image_type.rb +10 -0
  18. data/lib/avm/node.rb +28 -0
  19. data/lib/avm/observation.rb +76 -0
  20. data/lib/avm/spatial_quality.rb +10 -0
  21. data/lib/avm/xmp.rb +157 -0
  22. data/lib/ruby-avm-library.rb +7 -0
  23. data/lib/ruby-avm-library/version.rb +7 -0
  24. data/reek.watchr +12 -0
  25. data/ruby-avm-library.gemspec +27 -0
  26. data/spec/avm/cli_spec.rb +0 -0
  27. data/spec/avm/contact_spec.rb +93 -0
  28. data/spec/avm/creator_spec.rb +268 -0
  29. data/spec/avm/image_spec.rb +350 -0
  30. data/spec/avm/observation_spec.rb +191 -0
  31. data/spec/avm/xmp_spec.rb +154 -0
  32. data/spec/quick_fix_formatter.rb +26 -0
  33. data/spec/sample_files/creator/no_creator.xmp +14 -0
  34. data/spec/sample_files/creator/one_creator.xmp +28 -0
  35. data/spec/sample_files/creator/two_creators.xmp +26 -0
  36. data/spec/sample_files/image/both.xmp +101 -0
  37. data/spec/sample_files/image/light_years.xmp +96 -0
  38. data/spec/sample_files/image/nothing.xmp +18 -0
  39. data/spec/sample_files/image/redshift.xmp +101 -0
  40. data/spec/sample_files/image/single_value_light_years.xmp +96 -0
  41. data/spec/sample_files/observation/none.xmp +5 -0
  42. data/spec/sample_files/observation/one.xmp +17 -0
  43. data/spec/sample_files/observation/two.xmp +17 -0
  44. data/spec/spec_helper.rb +3 -0
  45. metadata +184 -0
@@ -0,0 +1,268 @@
1
+ require 'spec_helper'
2
+ require 'avm/image'
3
+ require 'avm/creator'
4
+
5
+ describe AVM::Creator do
6
+ let(:image) { AVM::Image.new }
7
+ let(:creator) { image.creator }
8
+
9
+ let(:name) { 'Space Telescope Science Institute' }
10
+ let(:url) { 'http://www.stsci.edu/' }
11
+ let(:rights) { 'Public Domain' }
12
+
13
+ subject { creator }
14
+
15
+ def self.can_read_properties
16
+ its(:name) { should == name }
17
+ its(:url) { should == url }
18
+ its(:rights) { should == rights }
19
+ end
20
+
21
+ describe '#merge!' do
22
+ before { creator.merge!(:name => name, :url => url, :rights => rights) }
23
+
24
+ can_read_properties
25
+ end
26
+
27
+ describe 'setters' do
28
+ before {
29
+ creator.name = name
30
+ creator.url = url
31
+ creator.rights = rights
32
+ }
33
+
34
+ can_read_properties
35
+ end
36
+
37
+ describe 'primary contact passthrough' do
38
+ context 'no contacts' do
39
+ its(:address) { should be_nil }
40
+ end
41
+
42
+ context 'one contact, must be primary' do
43
+ let(:first_contact) { AVM::Contact.new(
44
+ :name => 'zz bill',
45
+ :address => first_contact_address,
46
+ :city => first_contact_address,
47
+ :state => first_contact_address,
48
+ :postal_code => first_contact_address,
49
+ :country => first_contact_address
50
+ ) }
51
+ let(:first_contact_address) { 'first contact' }
52
+
53
+ before { creator.contacts << first_contact }
54
+
55
+ fields = [ :address, :city, :state, :province, :postal_code, :zip, :country ]
56
+ fields.each { |field| its(field) { should == first_contact_address } }
57
+
58
+ specify { creator.to_a.should == [
59
+ first_contact.to_h
60
+ ] }
61
+
62
+ context 'two contacts' do
63
+ let(:second_contact) { AVM::Contact.new(
64
+ :name => 'aa bill',
65
+ :address => second_contact_address,
66
+ :city => second_contact_address,
67
+ :state => second_contact_address,
68
+ :postal_code => second_contact_address,
69
+ :country => second_contact_address
70
+ ) }
71
+ let(:second_contact_address) { 'second contact' }
72
+
73
+ before { creator.contacts << second_contact }
74
+
75
+ context 'no primary, first alphabetical is primary' do
76
+ subject { second_contact }
77
+
78
+ fields.each { |field| its(field) { should == second_contact_address } }
79
+
80
+ specify { creator.to_a.should == [
81
+ second_contact.to_h, first_contact.to_h
82
+ ] }
83
+ end
84
+
85
+ context 'one is primary, use it' do
86
+ before { first_contact.primary = true }
87
+
88
+ fields.each { |field| its(field) { should == first_contact_address } }
89
+
90
+ specify { creator.to_a.should == [
91
+ first_contact.to_h, second_contact.to_h
92
+ ] }
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ describe '#create_contact' do
99
+ let(:first_name) { 'John' }
100
+ let(:first_contact) { creator.create_contact(:name => first_name) }
101
+
102
+ subject { creator.primary_contact }
103
+ before { first_contact }
104
+
105
+ its(:name) { should == first_name }
106
+ end
107
+
108
+ describe '#from_xml' do
109
+ let(:document) { image.to_xml }
110
+ let(:image) { AVM::Image.from_xml(File.read(file_path)) }
111
+
112
+ subject { image }
113
+
114
+ context 'no creator' do
115
+ let(:file_path) { 'spec/sample_files/creator/no_creator.xmp' }
116
+
117
+ its('creator.length') { should == 0 }
118
+ end
119
+
120
+ context 'one creator' do
121
+ let(:file_path) { 'spec/sample_files/creator/one_creator.xmp' }
122
+
123
+ its('creator.length') { should == 1 }
124
+
125
+ def self.field_checks
126
+ its(:name) { should == name }
127
+ its(:address) { should == address }
128
+ its(:city) { should == city }
129
+ its(:state) { should == state }
130
+ its(:zip) { should == zip }
131
+ its(:country) { should == country }
132
+ its(:email) { should == email }
133
+ its(:telephone) { should == telephone }
134
+ end
135
+
136
+ let(:name) { 'John Bintz' }
137
+ let(:email) { 'bintz@stsci.edu' }
138
+ let(:telephone) { '800-555-1234' }
139
+ let(:address) { '3700 San Martin Drive' }
140
+ let(:city) { 'Baltimore' }
141
+ let(:state) { 'Maryland' }
142
+ let(:zip) { '21218' }
143
+ let(:country) { 'USA' }
144
+
145
+ context 'creator one' do
146
+ subject { image.creator[0] }
147
+
148
+ field_checks
149
+
150
+ it { should be_primary }
151
+ end
152
+
153
+ context 'two creators' do
154
+ let(:file_path) { 'spec/sample_files/creator/two_creators.xmp' }
155
+
156
+ its('creator.length') { should == 2 }
157
+
158
+ context 'first creator' do
159
+ subject { image.creator[0] }
160
+
161
+ field_checks
162
+
163
+ it { should be_primary }
164
+ end
165
+
166
+ context 'second creator' do
167
+ subject { image.creator[1] }
168
+
169
+ field_checks
170
+
171
+ it { should_not be_primary }
172
+
173
+ let(:name) { 'Aohn Bintz' }
174
+ let(:email) { 'aohn@stsci.edu' }
175
+ let(:telephone) { '800-555-2345' }
176
+ let(:address) { '3700 San Martin Drive' }
177
+ let(:city) { 'Baltimore' }
178
+ let(:state) { 'Maryland' }
179
+ let(:zip) { '21218' }
180
+ let(:country) { 'USA' }
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ describe 'contact name node' do
187
+ let(:first_name) { 'John' }
188
+ let(:second_name) { 'Zohn' }
189
+
190
+ let(:first_contact) { creator.create_contact(first_contact_options) }
191
+ let(:second_contact) { creator.create_contact(second_contact_options) }
192
+
193
+ let(:first_contact_options) { { :name => first_name } }
194
+ let(:second_contact_options) { { :name => second_name } }
195
+
196
+ subject { image.to_xml.search('//dc:creator/rdf:Seq/rdf:li').collect { |node| node.text } }
197
+
198
+ context 'no contacts' do
199
+ it { should == [] }
200
+ end
201
+
202
+ context 'one contact' do
203
+ before { first_contact }
204
+
205
+ it { should == [ first_name ] }
206
+ end
207
+
208
+ context 'second contact' do
209
+ before { second_contact ; first_contact }
210
+
211
+ it { should == [ first_name, second_name ] }
212
+ end
213
+
214
+ describe 'everything else uses primary' do
215
+ let(:fields) { [ :address, :city, :state, :zip, :country ] }
216
+
217
+ def other_fields(what)
218
+ Hash[fields.zip(Array.new(fields.length, what))]
219
+ end
220
+
221
+ let(:first_contact_options) { { :name => first_name }.merge(other_fields('one')) }
222
+ let(:second_contact_options) { { :name => second_name }.merge(other_fields('two')) }
223
+
224
+ before { second_contact ; first_contact }
225
+
226
+ specify {
227
+ %w{CiAdrExtadr CiAdrCity CiAdrRegion CiAdrPcode CiAdrCtry}.each do |element_name|
228
+ image.to_xml.at_xpath("//Iptc4xmpCore:#{element_name}").text.should == 'one'
229
+ end
230
+ }
231
+ end
232
+
233
+ describe 'contact emails, telephones' do
234
+ let(:first_email) { 'bintz@stsci.edu' }
235
+ let(:second_email) { 'bintz-2@stsci.edu' }
236
+
237
+ let(:first_phone) { '123-456-7890' }
238
+ let(:second_phone) { '234-567-8901' }
239
+
240
+ let(:first_contact_options) { { :name => first_name, :email => first_email, :telephone => first_phone } }
241
+ let(:second_contact_options) { { :name => second_name, :email => second_email, :telephone => second_phone } }
242
+
243
+ let(:contact_info) { image.to_xml.search('//Iptc4xmpCore:CreatorContactInfo') }
244
+
245
+ let(:telephone_text) { contact_info.at_xpath('./Iptc4xmpCore:CiTelWork').text }
246
+ let(:email_text) { contact_info.at_xpath('./Iptc4xmpCore:CiEmailWork').text }
247
+
248
+ context 'no contacts' do
249
+ specify { expect { telephone_text }.to raise_error }
250
+ specify { expect { email_text }.to raise_error }
251
+ end
252
+
253
+ context 'one contact' do
254
+ before { first_contact }
255
+
256
+ specify { telephone_text.should == first_phone }
257
+ specify { email_text.should == first_email }
258
+ end
259
+
260
+ context 'two contacts' do
261
+ before { first_contact ; second_contact }
262
+
263
+ specify { telephone_text.should == [ first_phone, second_phone ] * ',' }
264
+ specify { email_text.should == [ first_email, second_email ] * ',' }
265
+ end
266
+ end
267
+ end
268
+ end
@@ -0,0 +1,350 @@
1
+ require 'spec_helper'
2
+ require 'avm/image'
3
+
4
+ describe AVM::Image do
5
+ let(:image) { self.class.describes.new(options) }
6
+ let(:options) { {} }
7
+
8
+ subject { image }
9
+
10
+ let(:title) { 'My title' }
11
+ let(:headline) { 'Headline' }
12
+ let(:description) { 'Description' }
13
+ let(:distance_notes) { 'Distance Notes' }
14
+ let(:spectral_notes) { 'Spectral Notes' }
15
+ let(:reference_url) { 'Reference URL' }
16
+ let(:credit) { 'Credit' }
17
+ let(:date) { '2010-01-01' }
18
+ let(:id) { 'ID' }
19
+ let(:type) { 'Observation' }
20
+ let(:image_quality) { 'Good' }
21
+ let(:redshift) { 'Redshift' }
22
+ let(:light_years) { 'Light years' }
23
+
24
+ let(:subject_names) { [ 'Name one', 'Name two' ] }
25
+ let(:categories) { [ 'Category one', 'Category two' ] }
26
+
27
+ let(:coordinate_frame) { 'ICRS' }
28
+ let(:equinox) { '100' }
29
+ let(:reference_value) { [ 100, 50 ] }
30
+ let(:reference_dimension) { [ 200, 150 ] }
31
+ let(:reference_pixel) { [ 25, 15 ] }
32
+ let(:spatial_scale) { [ 40, 35 ] }
33
+ let(:spatial_rotation) { 10.0 }
34
+ let(:coordinate_system_projection) { 'TAN' }
35
+ let(:spatial_quality) { 'Full' }
36
+ let(:spatial_notes) { 'Spatial Notes' }
37
+ let(:fits_header) { 'FITS header' }
38
+ let(:spatial_cd_matrix) { [ 1, 2, 3, 4 ] }
39
+
40
+ let(:publisher) { 'Publisher' }
41
+ let(:publisher_id) { 'Publisher ID' }
42
+ let(:resource_id) { 'Resource ID' }
43
+ let(:resource_url) { 'Resource URL' }
44
+ let(:related_resources) { [ 'Resource 1', 'Resource 2' ] }
45
+ let(:metadata_date) { '2010-01-05' }
46
+ let(:metadata_version) { '1.2' }
47
+
48
+ def self.with_all_options
49
+ let(:options) { {
50
+ :title => title,
51
+ :headline => headline,
52
+ :description => description,
53
+ :distance_notes => distance_notes,
54
+ :spectral_notes => spectral_notes,
55
+ :reference_url => reference_url,
56
+ :credit => credit,
57
+ :date => date,
58
+ :id => id,
59
+ :type => type,
60
+ :quality => image_quality,
61
+ :redshift => redshift,
62
+ :light_years => light_years,
63
+ :coordinate_frame => coordinate_frame,
64
+ :equinox => equinox,
65
+ :reference_value => reference_value,
66
+ :reference_dimension => reference_dimension,
67
+ :reference_pixel => reference_pixel,
68
+ :spatial_scale => spatial_scale,
69
+ :spatial_rotation => spatial_rotation,
70
+ :coordinate_system_projection => coordinate_system_projection,
71
+ :spatial_quality => spatial_quality,
72
+ :spatial_notes => spatial_notes,
73
+ :fits_header => fits_header,
74
+ :spatial_cd_matrix => spatial_cd_matrix,
75
+ :publisher => publisher,
76
+ :publisher_id => publisher_id,
77
+ :resource_id => resource_id,
78
+ :resource_url => resource_url,
79
+ :related_resources => related_resources,
80
+ :metadata_date => metadata_date,
81
+ :metadata_version => metadata_version,
82
+ :subject_names => subject_names,
83
+ :categories => categories
84
+ } }
85
+ end
86
+
87
+ let(:avm_image_type) { eval("AVM::ImageType::#{type}") }
88
+ let(:avm_image_quality) { eval("AVM::ImageQuality::#{image_quality}") }
89
+ let(:avm_coordinate_frame) { eval("AVM::CoordinateFrame::#{coordinate_frame}") }
90
+ let(:avm_coordinate_system_projection) { eval("AVM::CoordinateSystemProjection::#{coordinate_system_projection}") }
91
+ let(:avm_spatial_quality) { eval("AVM::SpatialQuality::#{spatial_quality}") }
92
+
93
+ def self.has_most_options
94
+ its(:creator) { should be_a_kind_of(AVM::Creator) }
95
+ its(:title) { should == title }
96
+ its(:headline) { should == headline }
97
+ its(:description) { should == description }
98
+ its(:distance_notes) { should == distance_notes }
99
+ its(:spectral_notes) { should == spectral_notes }
100
+ its(:reference_url) { should == reference_url }
101
+ its(:credit) { should == credit }
102
+ its(:date) { should == Time.parse(date) }
103
+ its(:id) { should == id }
104
+ its(:image_type) { should be_a_kind_of avm_image_type }
105
+ its(:image_quality) { should be_a_kind_of avm_image_quality }
106
+
107
+ its(:coordinate_frame) { should be_a_kind_of avm_coordinate_frame }
108
+ its(:equinox) { should == equinox }
109
+ its(:reference_value) { should == reference_value }
110
+ its(:reference_dimension) { should == reference_dimension }
111
+ its(:reference_pixel) { should == reference_pixel }
112
+ its(:spatial_scale) { should == spatial_scale }
113
+ its(:spatial_rotation) { should == spatial_rotation }
114
+ its(:coordinate_system_projection) { should be_a_kind_of avm_coordinate_system_projection }
115
+ its(:spatial_quality) { should be_a_kind_of avm_spatial_quality }
116
+ its(:spatial_notes) { should == spatial_notes }
117
+ its(:fits_header) { should == fits_header }
118
+ its(:spatial_cd_matrix) { should == spatial_cd_matrix }
119
+
120
+ its(:publisher) { should == publisher }
121
+ its(:publisher_id) { should == publisher_id }
122
+ its(:resource_id) { should == resource_id }
123
+ its(:resource_url) { should == resource_url }
124
+ its(:related_resources) { should == related_resources }
125
+ its(:metadata_date) { should == Time.parse(metadata_date) }
126
+ its(:metadata_version) { should == metadata_version }
127
+
128
+ its(:subject_names) { should == subject_names }
129
+ its(:categories) { should == categories }
130
+
131
+ it { should be_valid }
132
+ end
133
+
134
+ describe '#initialize' do
135
+ with_all_options
136
+
137
+ it { should be_a_kind_of(AVM::Image) }
138
+
139
+ has_most_options
140
+
141
+ its(:to_h) { should == {
142
+ :title => title,
143
+ :headline => headline,
144
+ :description => description,
145
+ :distance_notes => distance_notes,
146
+ :spectral_notes => spectral_notes,
147
+ :reference_url => reference_url,
148
+ :credit => credit,
149
+ :date => Time.parse(date),
150
+ :id => id,
151
+ :image_type => avm_image_type.new,
152
+ :image_quality => avm_image_quality.new,
153
+ :coordinate_frame => avm_coordinate_frame.new,
154
+ :equinox => equinox,
155
+ :reference_value => reference_value,
156
+ :reference_dimension => reference_dimension,
157
+ :reference_pixel => reference_pixel,
158
+ :spatial_scale => spatial_scale,
159
+ :spatial_rotation => spatial_rotation,
160
+ :coordinate_system_projection => avm_coordinate_system_projection.new,
161
+ :spatial_quality => avm_spatial_quality.new,
162
+ :spatial_notes => spatial_notes,
163
+ :fits_header => fits_header,
164
+ :spatial_cd_matrix => spatial_cd_matrix,
165
+ :distance => [ light_years, redshift ],
166
+ :creator => [],
167
+ :publisher => publisher,
168
+ :publisher_id => publisher_id,
169
+ :resource_id => resource_id,
170
+ :resource_url => resource_url,
171
+ :related_resources => related_resources,
172
+ :metadata_date => Time.parse(metadata_date),
173
+ :metadata_version => metadata_version,
174
+ :subject_names => subject_names,
175
+ :categories => categories,
176
+ :observations => []
177
+ } }
178
+
179
+ its(:distance) { should == [ light_years, redshift ] }
180
+ end
181
+
182
+ describe 'not valid' do
183
+ let(:image) { AVM::Image.new }
184
+
185
+ it { should_not be_valid }
186
+ end
187
+
188
+ describe '.from_xml' do
189
+ let!(:image) { AVM::Image.from_xml(File.read(file_path)) }
190
+
191
+ subject { image }
192
+
193
+ context "nothing in it" do
194
+ let(:file_path) { 'spec/sample_files/image/nothing.xmp' }
195
+
196
+ [ :title, :headline, :description, :distance_notes,
197
+ :spectral_notes, :reference_url, :credit, :date,
198
+ :id, :image_type, :image_quality, :redshift,
199
+ :light_years, :coordinate_frame, :equinox, :reference_value,
200
+ :reference_dimension, :reference_pixel, :spatial_scale,
201
+ :spatial_rotation, :coordinate_system_projection, :spatial_quality, :spatial_notes,
202
+ :fits_header, :spatial_cd_matrix, :subject_names, :categories
203
+ ].each do |field|
204
+ its(field) { should be_nil }
205
+ end
206
+
207
+ it { should_not be_valid }
208
+ end
209
+
210
+ context "image in it" do
211
+ context 'distance as a single value, assume light years' do
212
+ let(:file_path) { 'spec/sample_files/image/single_value_light_years.xmp' }
213
+
214
+ has_most_options
215
+
216
+ its(:redshift) { should be_nil }
217
+ its(:light_years) { should == light_years }
218
+ end
219
+
220
+ context "distance in light years" do
221
+ let(:file_path) { 'spec/sample_files/image/light_years.xmp' }
222
+
223
+ has_most_options
224
+
225
+ its(:redshift) { should be_nil }
226
+ its(:light_years) { should == light_years }
227
+ end
228
+
229
+ context "distaince in redshift" do
230
+ let(:file_path) { 'spec/sample_files/image/redshift.xmp' }
231
+
232
+ has_most_options
233
+
234
+ its(:light_years) { should be_nil }
235
+ its(:redshift) { should == redshift }
236
+ end
237
+
238
+ context "distance in both" do
239
+ let(:file_path) { 'spec/sample_files/image/both.xmp' }
240
+
241
+ has_most_options
242
+
243
+ its(:light_years) { should == light_years }
244
+ its(:redshift) { should == redshift }
245
+ end
246
+ end
247
+ end
248
+
249
+ describe '#to_xml' do
250
+ let(:xml) { image.to_xml }
251
+
252
+ let(:dublin_core) { xml.at_xpath('//rdf:Description[@rdf:about="Dublin Core"]') }
253
+ let(:photoshop) { xml.at_xpath('//rdf:Description[@rdf:about="Photoshop"]') }
254
+ let(:avm) { xml.at_xpath('//rdf:Description[@rdf:about="AVM"]') }
255
+
256
+ context 'nothing in it' do
257
+ it "should have basic tags" do
258
+ xml.at_xpath('//rdf:RDF').should_not be_nil
259
+ xml.search('//rdf:RDF/rdf:Description').should_not be_empty
260
+ photoshop.at_xpath('./photoshop:DateCreated').should_not be_nil
261
+ end
262
+ end
263
+
264
+ context 'with basics' do
265
+ with_all_options
266
+
267
+ def xpath_text(which, xpath)
268
+ which.at_xpath(xpath).text
269
+ end
270
+
271
+ def xpath_list(which, xpath, search = './/rdf:li')
272
+ which.at_xpath(xpath).search(search).collect(&:text)
273
+ end
274
+
275
+ it "should have the image info tags" do
276
+ xpath_text(dublin_core, './dc:title/rdf:Alt/rdf:li').should == title
277
+ xpath_text(photoshop, './photoshop:Headline').should == headline
278
+ xpath_text(dublin_core, './dc:description/rdf:Alt/rdf:li').should == description
279
+
280
+ xpath_text(avm, './avm:Distance.Notes').should == distance_notes
281
+ xpath_text(avm, './avm:Spectral.Notes').should == spectral_notes
282
+ xpath_text(avm, './avm:ReferenceURL').should == reference_url
283
+ xpath_text(photoshop, './photoshop:Credit').should == credit
284
+ xpath_text(photoshop, './photoshop:DateCreated').should == date
285
+ xpath_text(avm, './avm:ID').should == id
286
+ xpath_text(avm, './avm:Type').should == type
287
+ xpath_text(avm, './avm:Image.ProductQuality').should == image_quality
288
+ end
289
+
290
+ it "should have the spatial tags" do
291
+ xpath_text(avm, './avm:Spatial.CoordinateFrame').should == coordinate_frame
292
+ xpath_text(avm, './avm:Spatial.Equinox').should == equinox
293
+ xpath_list(avm, './avm:Spatial.ReferenceValue').should == reference_value.collect { |v| v.to_f.to_s }
294
+ xpath_list(avm, './avm:Spatial.ReferenceDimension').should == reference_dimension.collect { |v| v.to_f.to_s }
295
+ xpath_list(avm, './avm:Spatial.ReferencePixel').should == reference_pixel.collect { |v| v.to_f.to_s }
296
+ xpath_list(avm, './avm:Spatial.Scale').should == spatial_scale.collect { |v| v.to_f.to_s }
297
+ xpath_text(avm, './avm:Spatial.CoordsystemProjection').should == coordinate_system_projection
298
+ xpath_text(avm, './avm:Spatial.Quality').should == spatial_quality
299
+ xpath_text(avm, './avm:Spatial.Notes').should == spatial_notes
300
+ xpath_text(avm, './avm:Spatial.FITSheader').should == fits_header
301
+ xpath_list(avm, './avm:Spatial.CDMatrix').should == spatial_cd_matrix.collect { |v| v.to_f.to_s }
302
+ end
303
+
304
+ it "should have the publisher tags" do
305
+ xpath_text(avm, './avm:Publisher').should == publisher
306
+ xpath_text(avm, './avm:PublisherID').should == publisher_id
307
+ xpath_text(avm, './avm:ResourceID').should == resource_id
308
+ xpath_text(avm, './avm:ResourceURL').should == resource_url
309
+ xpath_list(avm, './avm:RelatedResources', './rdf:Bag/rdf:li').should == related_resources
310
+ xpath_text(avm, './avm:MetadataDate').should == metadata_date
311
+ xpath_text(avm, './avm:MetadataVersion').should == metadata_version
312
+ end
313
+
314
+ context "distance" do
315
+ context "no distances" do
316
+ let(:redshift) { nil }
317
+ let(:light_years) { nil }
318
+
319
+ it("should have no distances") { avm.at_xpath('./avm:Distance').should be_nil }
320
+ end
321
+
322
+ context "redshift only" do
323
+ let(:light_years) { nil }
324
+
325
+ it "should have redshift only" do
326
+ avm.at_xpath('./avm:Distance/rdf:Seq/rdf:li[1]').text.should == '-'
327
+ avm.at_xpath('./avm:Distance/rdf:Seq/rdf:li[2]').text.should == redshift
328
+ end
329
+ end
330
+
331
+ context "light years only" do
332
+ let(:redshift) { nil }
333
+
334
+ it "should should have light years but not redshift" do
335
+ avm.at_xpath('./avm:Distance/rdf:Seq/rdf:li[1]').text.should == light_years
336
+ avm.at_xpath('./avm:Distance/rdf:Seq/rdf:li[2]').should be_nil
337
+ end
338
+ end
339
+
340
+ context "redshift and light years" do
341
+ it "should have both light years and redshift" do
342
+ avm.at_xpath('./avm:Distance/rdf:Seq/rdf:li[1]').text.should == light_years
343
+ avm.at_xpath('./avm:Distance/rdf:Seq/rdf:li[2]').text.should == redshift
344
+ end
345
+ end
346
+ end
347
+ end
348
+ end
349
+ end
350
+