require File.expand_path('../../../spec_helper', __FILE__)
require 'nokogiri'
module NcsNavigator::Mdes
describe VariableType do
describe '.from_xsd_simple_type' do
def vtype(body_s, name=nil)
VariableType.from_xsd_simple_type(schema_element(<<-XML), :log => logger)
#{body_s}
XML
end
def vtype_from_string(restriction_body, name=nil)
vtype(<<-XML, name)
#{restriction_body}
XML
end
describe 'with an unsupported restriction base' do
let!(:subject) { vtype('') }
it 'is nil' do
subject.should be_nil
end
it 'logs a warning' do
logger[:warn].first.
should == 'Unsupported restriction base in simpleType on line 2'
end
end
describe 'with an unsupported restriction subelement' do
let!(:subject) { vtype_from_string('') }
it 'logs a warning' do
logger[:warn].first.should == 'Unsupported restriction element "color" on line 4'
end
end
describe '#name' do
it 'is set if there is one' do
vtype_from_string(nil, 'foo').name.should == 'foo'
end
it 'is nil if there is not one' do
vtype_from_string(nil, nil).name.should be_nil
end
end
describe '#max_length' do
it 'is set if present' do
vtype_from_string('').max_length.should == 255
end
end
describe '#min_length' do
it 'is set if present' do
vtype_from_string('').min_length.should == 1
end
end
describe '#pattern' do
it 'is compiled to a regexp if present' do
vtype_from_string('').
pattern.should == /^([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])?$/
end
describe 'when malformed' do
let!(:subject) { vtype_from_string('') }
it 'is nil if present but malformed' do
subject.pattern.should be_nil
end
it 'logs a warning' do
logger[:warn].first.should == 'Uncompilable pattern "([" in simpleType on line 4'
end
end
end
describe '#base_type' do
it 'is :string' do
vtype_from_string('').base_type.should == :string
end
end
it 'is not a reference' do
vtype_from_string('').should_not be_reference
end
describe '#code_list' do
context 'when there are no enumerated values' do
it 'is nil' do
vtype_from_string('').code_list.should be_nil
end
end
context 'when there are enumerated values' do
subject {
vtype_from_string(<<-XSD)
XSD
}
it 'has an entry for each value' do
subject.code_list.collect(&:to_s).should == %w(1 2 3 -7 -4)
end
it 'has the description' do
subject.code_list.description.should == "Eq"
end
end
end
end
describe '.reference' do
subject { VariableType.reference('ncs:bar') }
it 'has the right name' do
subject.name.should == 'ncs:bar'
end
it 'is a reference' do
subject.should be_reference
end
end
describe '.xml_schema_type' do
subject { VariableType.xml_schema_type('int') }
it 'has no name' do
subject.name.should be_nil
end
it 'has the correct base type' do
subject.base_type.should == :int
end
it 'is not a reference' do
subject.should_not be_reference
end
end
describe '#diff' do
let(:a) { VariableType.new('A') }
let(:aprime) { VariableType.new('A') }
let(:diff) { a.diff(aprime) }
let(:strict_diff) { a.diff(aprime, :strict => true) }
it 'reports nothing when they are the same' do
diff.should be_nil
end
describe 'name' do
it 'reports a difference' do
a.diff(VariableType.new('B'))[:name].should be_a_value_diff('A', 'B')
end
end
describe 'base_type' do
it 'reports a difference' do
a.base_type = :int
aprime.base_type = :decimal
diff[:base_type].should be_a_value_diff(:int, :decimal)
end
end
describe 'pattern' do
it 'reports a difference' do
a.pattern = /^(0-9){4}$/
aprime.pattern = /^(0-9){5}$/
diff[:pattern].should be_a_value_diff(/^(0-9){4}$/, /^(0-9){5}$/)
end
end
describe 'max_length' do
it 'reports a difference' do
a.max_length = nil
aprime.max_length = 18
diff[:max_length].should be_a_value_diff(nil, 18)
end
end
describe 'min_length' do
it 'reports a difference' do
a.min_length = 1
aprime.min_length = nil
diff[:min_length].should be_a_value_diff(1, nil)
end
end
describe 'code_list' do
let(:cl) { CodeList.new }
let(:clprime) { CodeList.new }
def cle(value, label)
CodeListEntry.new(value).tap { |e| e.label = label }
end
let(:e_one) { cle( '1', 'Hand grenades')}
let(:e_five) { cle( '5', 'Horseshoes') }
let(:e_other) { cle('-5', 'Other') }
let(:e_other_prime) { cle( '5', 'Other') }
describe 'when only the left has a code list' do
before do
a.code_list = cl
cl << e_one << e_other
end
it 'reports all entries as left only by value' do
strict_diff[:code_list_by_value].left_only.should == %w(1 -5)
end
it 'reports all entries as left only by label' do
strict_diff[:code_list_by_label].left_only.should == ['Hand grenades', 'Other']
end
end
describe 'when only the right has a code list' do
before do
aprime.code_list = clprime
clprime << e_five << e_other
end
it 'reports all entries as right only by value' do
strict_diff[:code_list_by_value].right_only.should == %w(5 -5)
end
it 'reports all entries as right only by label' do
strict_diff[:code_list_by_label].right_only.should == ['Horseshoes', 'Other']
end
end
describe 'when both have code lists' do
before do
a.code_list = cl
aprime.code_list = clprime
end
describe 'and they are the same' do
before do
cl << e_one << e_five
clprime << e_one << e_five
end
it 'reports no differences' do
strict_diff.should be_nil
end
end
describe 'and they differ by values only' do
before do
cl << e_other << e_one
clprime << e_one << e_other_prime
end
it 'reports the entry difference in the by-label attribute' do
strict_diff[:code_list_by_label]['Other'][:value].
should be_a_value_diff('-5', '5')
end
it 'reports extra entries in the by-value attribute' do
strict_diff[:code_list_by_value].left_only.should == ['-5']
strict_diff[:code_list_by_value].right_only.should == ['5']
end
end
describe 'and they differ by labels only' do
before do
cl << e_one << e_five
clprime << e_one << e_other_prime
end
it 'reports the entry difference in the by-value attribute' do
strict_diff[:code_list_by_value]['5'][:label].
should be_a_value_diff('Horseshoes', 'Other')
end
it 'reports extra entries in the by-label attribute' do
strict_diff[:code_list_by_label].left_only.should == ['Horseshoes']
strict_diff[:code_list_by_label].right_only.should == ['Other']
end
end
describe 'and the differ by whitespace, punctuation and case in the labels only' do
let(:weird_left) { ' foUR! ' }
let(:weird_right) { 'FOUR#' }
before do
cl << e_one << cle('4', weird_left)
clprime << e_one << cle('4', weird_right)
end
describe 'with a strict diff' do
it 'reports the entry difference in the by-value attribute' do
strict_diff[:code_list_by_value]['4'][:label].
should be_a_value_diff(weird_left, weird_right)
end
it 'reports extra entries in the by-label attribute' do
strict_diff[:code_list_by_label].left_only.should == [weird_left]
strict_diff[:code_list_by_label].right_only.should == [weird_right]
end
end
describe 'with a loose diff' do
it 'reports no by-value differences' do
diff.should be_nil
end
it 'reports no by-label differences' do
diff.should be_nil
end
end
end
end
end
end
end
end