# frozen_string_literal: true
require 'spec_helper'
module Datacite
module Mapping
describe GeoLocation do
attr_reader :warnings
def warnings_including(substring)
warnings.select { |w| w.include?(substring) }
end
def expect_warning(substring, count, include_matches = false)
matches = warnings_including(substring)
found_count = matches.size
msg = "expected #{count} warnings including '#{substring}', found #{found_count}"
msg << ": #{matches}" if include_matches
expect(found_count).to eq(count), msg
end
before(:each) do
@warnings = []
allow(ReadOnlyNodes).to receive(:warn) do |w|
warnings << w
Kernel.warn(w) # for debugging
end
end
describe '#initialize' do
it 'accepts a point' do
point = GeoLocationPoint.new(47.61, -122.33)
loc = GeoLocation.new(point: point)
expect(loc.point).to eq(point)
end
it 'accepts a box' do
box = GeoLocationBox.new(-33.45, -122.33, 47.61, -70.67)
loc = GeoLocation.new(box: box)
expect(loc.box).to eq(box)
end
it 'accepts a place' do
place = 'Ouagadougou'
loc = GeoLocation.new(place: place)
expect(loc.place).to eq(place)
end
it 'accepts a polygon' do
polygon = GeoLocationPolygon.new(points: [
GeoLocationPoint.new(47.61, -122.33),
GeoLocationPoint.new(-33.45, -122.33),
GeoLocationPoint.new(47.61, -70.67),
GeoLocationPoint.new(47.61, -122.33)
])
loc = GeoLocation.new(polygon: polygon)
expect(loc.polygon).to eq(polygon)
end
it 'allows an empty location' do
loc = GeoLocation.new
expect(loc.point).to be_nil
expect(loc.box).to be_nil
expect(loc.place).to be_nil
end
end
describe '#point=' do
it 'sets the point' do
point = GeoLocationPoint.new(47.61, -122.33)
loc = GeoLocation.new
loc.point = point
expect(loc.point).to eq(point)
end
it 'accepts nil' do
loc = GeoLocation.new(point: GeoLocationPoint.new(47.61, -122.33))
loc.point = nil
expect(loc.point).to be_nil
end
end
describe '#box=' do
it 'sets the box' do
box = GeoLocationBox.new(-33.45, -122.33, 47.61, -70.67)
loc = GeoLocation.new
loc.box = box
expect(loc.box).to eq(box)
end
it 'accepts nil' do
loc = GeoLocation.new(box: GeoLocationBox.new(-33.45, -122.33, 47.61, -70.67))
loc.box = nil
expect(loc.box).to be_nil
end
end
describe '#place=' do
it 'sets the place' do
place = 'Ouagadougou'
loc = GeoLocation.new
loc.place = place
expect(loc.place).to eq(place)
end
it 'accepts nil' do
loc = GeoLocation.new(place: 'Ouagadougou')
loc.place = nil
expect(loc.place).to be_nil
end
end
describe '#polygon=' do
it 'sets the polygon' do
polygon = GeoLocationPolygon.new(points: [
GeoLocationPoint.new(47.61, -122.33),
GeoLocationPoint.new(-33.45, -122.33),
GeoLocationPoint.new(47.61, -70.67),
GeoLocationPoint.new(47.61, -122.33)
])
loc = GeoLocation.new
loc.polygon = polygon
expect(loc.polygon).to eq(polygon)
end
end
describe '#load_from_xml' do
it 'parses DC3' do
xml_text = '
Atlantic Ocean
31.233 -67.302
41.090 -71.032 42.893 -68.211
'
loc = GeoLocation.parse_xml(xml_text)
expect(loc.point).to eq(GeoLocationPoint.new(31.233, -67.302))
expect(loc.box).to eq(GeoLocationBox.new(41.09, -71.032, 42.893, -68.211))
expect(loc.place).to eq('Atlantic Ocean')
end
it 'parses DC4' do
xml_text = '
Atlantic Ocean
31.233
-67.302
41.090
-71.032
42.893
-68.211
-67.302
31.233
-71.032
-68.211
41.09
42.893
-67.302
31.233
'
loc = GeoLocation.parse_xml(xml_text)
expect(loc.point).to eq(GeoLocationPoint.new(31.233, -67.302))
expect(loc.box).to eq(GeoLocationBox.new(41.09, -71.032, 42.893, -68.211))
expect(loc.place).to eq('Atlantic Ocean')
actual_polygon = loc.polygon
expected_polygon = GeoLocationPolygon.new(points: [
GeoLocationPoint.new(31.233, -67.302),
GeoLocationPoint.new(-68.211, -71.032),
GeoLocationPoint.new(42.893, 41.09),
GeoLocationPoint.new(31.233, -67.302)
])
expect(actual_polygon).to eq(expected_polygon)
end
it 'trims place-name whitespace' do
xml_text = '
Atlantic Ocean
'
loc = GeoLocation.parse_xml(xml_text)
expect(loc.place).to eq('Atlantic Ocean')
end
end
describe '#save_to_xml' do
attr_reader :loc
before(:each) do
@loc = GeoLocation.new(
point: GeoLocationPoint.new(31.233, -67.302),
box: GeoLocationBox.new(41.09, -71.032, 42.893, -68.211),
place: 'Atlantic Ocean',
polygon: GeoLocationPolygon.new(points: [
GeoLocationPoint.new(-67.302, 31.233),
GeoLocationPoint.new(-71.032, -68.211),
GeoLocationPoint.new(41.09, 42.893),
GeoLocationPoint.new(-67.302, 31.233)
])
)
end
describe 'DC4 mode' do
it 'writes DC4' do
expected_xml = '
Atlantic Ocean
31.233
-67.302
-71.032
-68.211
41.09
42.893
31.233
-67.302
-68.211
-71.032
42.893
41.09
31.233
-67.302
'
actual_xml = loc.save_to_xml
expect(actual_xml).to be_xml(expected_xml)
end
end
describe 'DC3 mapping' do
it 'writes DC3 points and boxes' do
expected_xml = '
31.233 -67.302
41.09 -71.032 42.893 -68.211
Atlantic Ocean
'
actual_xml = loc.save_to_xml(mapping: :datacite_3)
expect(actual_xml).to be_xml(expected_xml)
expect_warning(loc.polygon.to_s, 1)
end
it 'writes DC3 in XSD-defined order: point, box, place' do
actual_xml = loc.save_to_xml(mapping: :datacite_3)
expected_order = %w[geoLocationPoint geoLocationBox geoLocationPlace]
actual_order = actual_xml.children.map(&:name)
expect(actual_order).to eq(expected_order)
end
end
end
end
end
end