ncs_mdes 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +10 -0
- data/.rvmrc +1 -0
- data/.yardopts +5 -0
- data/CHANGELOG.md +18 -0
- data/Gemfile +9 -0
- data/README.md +59 -0
- data/Rakefile +7 -0
- data/bin/mdes-console +21 -0
- data/documents/1.2/Data_Transmission_Schema_V1.2.xsd +13980 -0
- data/documents/2.0/NCS_Transmission_Schema_2.0.01.02.xml +26918 -0
- data/lib/ncs_navigator/mdes/source_documents.rb +103 -0
- data/lib/ncs_navigator/mdes/specification.rb +86 -0
- data/lib/ncs_navigator/mdes/transmission_table.rb +53 -0
- data/lib/ncs_navigator/mdes/variable.rb +119 -0
- data/lib/ncs_navigator/mdes/variable_type.rb +196 -0
- data/lib/ncs_navigator/mdes/version.rb +5 -0
- data/lib/ncs_navigator/mdes.rb +27 -0
- data/ncs_mdes.gemspec +27 -0
- data/spec/ncs_navigator/mdes/source_documents_spec.rb +95 -0
- data/spec/ncs_navigator/mdes/specification_spec.rb +102 -0
- data/spec/ncs_navigator/mdes/transmission_table_spec.rb +89 -0
- data/spec/ncs_navigator/mdes/variable_spec.rb +216 -0
- data/spec/ncs_navigator/mdes/variable_type_spec.rb +202 -0
- data/spec/ncs_navigator/mdes/version_spec.rb +13 -0
- data/spec/ncs_navigator/mdes_spec.rb +9 -0
- data/spec/spec_helper.rb +45 -0
- metadata +165 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
require File.expand_path("../../../spec_helper.rb", __FILE__)
|
2
|
+
|
3
|
+
module NcsNavigator::Mdes
|
4
|
+
describe SourceDocuments do
|
5
|
+
before do
|
6
|
+
@spec_base, ENV[SourceDocuments::BASE_ENV_VAR] = ENV[SourceDocuments::BASE_ENV_VAR], nil
|
7
|
+
end
|
8
|
+
|
9
|
+
after do
|
10
|
+
ENV[SourceDocuments::BASE_ENV_VAR] = @spec_base
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '#base' do
|
14
|
+
let(:base) { SourceDocuments.new.base }
|
15
|
+
|
16
|
+
it 'defaults to the documents directory in the gem' do
|
17
|
+
base.should == File.expand_path('../../../../documents', __FILE__)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'can be overridden using the NCS_MDES_DOCS_DIR environment variable' do
|
21
|
+
ENV['NCS_MDES_DOCS_DIR'] = '/etc/foo'
|
22
|
+
base.should == '/etc/foo'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#schema' do
|
27
|
+
let(:docs) { SourceDocuments.new }
|
28
|
+
|
29
|
+
before do
|
30
|
+
docs.base = '/baz'
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'absolutizes a relative path against the base' do
|
34
|
+
docs.schema = '1.3/bar.xsd'
|
35
|
+
docs.schema.should == '/baz/1.3/bar.xsd'
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'leaves an absolute path alone' do
|
39
|
+
docs.schema = '/somewhere/particular.xsd'
|
40
|
+
docs.schema.should == '/somewhere/particular.xsd'
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '.get' do
|
45
|
+
describe '1.2' do
|
46
|
+
subject { SourceDocuments.get('1.2') }
|
47
|
+
|
48
|
+
it 'has the correct path for the schema' do
|
49
|
+
subject.schema.should =~ %r{1.2/Data_Transmission_Schema_V1.2.xsd$}
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'is of the specified version' do
|
53
|
+
subject.version.should == '1.2'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '2.0' do
|
58
|
+
subject { SourceDocuments.get('2.0') }
|
59
|
+
|
60
|
+
it 'has the correct path for the schema' do
|
61
|
+
subject.schema.should =~ %r{2.0/NCS_Transmission_Schema_2.0.01.02.xml$}
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'is of the specified version' do
|
65
|
+
subject.version.should == '2.0'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'fails for an unsupported version' do
|
70
|
+
lambda { SourceDocuments.get('1.0') }.
|
71
|
+
should raise_error('MDES 1.0 is not supported by this version of ncs_mdes')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '.xmlns' do
|
76
|
+
subject { SourceDocuments.xmlns }
|
77
|
+
|
78
|
+
it 'includes the XSD namespace' do
|
79
|
+
subject['xs'].should == 'http://www.w3.org/2001/XMLSchema'
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'includes the NCS namespace' do
|
83
|
+
subject['ncs'].should == 'http://www.nationalchildrensstudy.gov'
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'includes the NCS doc namespace' do
|
87
|
+
subject['ncsdoc'].should == 'http://www.nationalchildrensstudy.gov/doc'
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'is available from an instance also' do
|
91
|
+
SourceDocuments.new.xmlns.keys.sort.should == %w(ncs ncsdoc xs)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
module NcsNavigator::Mdes
|
4
|
+
describe Specification do
|
5
|
+
describe '#version' do
|
6
|
+
it 'delegates to the source documents' do
|
7
|
+
Specification.new('1.2').version.should == '1.2'
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe '#initialize' do
|
12
|
+
it 'accepts a string version' do
|
13
|
+
Specification.new('2.0').version.should == '2.0'
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'accepts a SourceDocuments instance' do
|
17
|
+
Specification.new(SourceDocuments.new.tap { |s| s.version = '3.1' }).version.
|
18
|
+
should == '3.1'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#xsd' do
|
23
|
+
it 'is parsed' do
|
24
|
+
Specification.new('1.2', :log => logger).xsd.root.name.should == 'schema'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '#transmission_tables' do
|
29
|
+
it 'is composed of TransmissionTable instances' do
|
30
|
+
Specification.new('2.0', :log => logger).transmission_tables.first.
|
31
|
+
should be_a TransmissionTable
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'in version 1.2' do
|
35
|
+
let!(:tables) { Specification.new('1.2', :log => logger).transmission_tables }
|
36
|
+
|
37
|
+
it 'has 124 tables' do
|
38
|
+
tables.size.should == 124
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'emits no warnings' do
|
42
|
+
logger[:warn].should == []
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'resolves all NCS type references' do
|
46
|
+
tables.collect { |table|
|
47
|
+
table.variables.collect { |v| v.type }.select { |t| t.reference? }
|
48
|
+
}.flatten.collect { |t| t.name }.select { |n| n =~ /^ncs:/ }.should == []
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'in version 2.0' do
|
53
|
+
let!(:tables) { Specification.new('2.0', :log => logger).transmission_tables }
|
54
|
+
|
55
|
+
it 'has 264 tables' do
|
56
|
+
tables.size.should == 264
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'emits no warnings' do
|
60
|
+
logger[:warn].should == []
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'resolves all NCS type references' do
|
64
|
+
tables.collect { |table|
|
65
|
+
table.variables.collect { |v| v.type }.select { |t| t.reference? }
|
66
|
+
}.flatten.collect { |t| t.name }.select { |n| n =~ /^ncs:/ }.should == []
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#types' do
|
72
|
+
it 'is composed of VariableType instances' do
|
73
|
+
Specification.new('2.0', :log => logger).types.first.
|
74
|
+
should be_a VariableType
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'in version 1.2' do
|
78
|
+
let!(:types) { Specification.new('1.2', :log => logger).types }
|
79
|
+
|
80
|
+
it 'has 281 types' do
|
81
|
+
types.size.should == 281
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'emits no warnings' do
|
85
|
+
logger[:warn].size.should == 0
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context 'in version 2.0' do
|
90
|
+
let!(:types) { Specification.new('2.0', :log => logger).types }
|
91
|
+
|
92
|
+
it 'has 423 types' do
|
93
|
+
types.size.should == 423
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'emits no warnings' do
|
97
|
+
logger[:warn].size.should == 0
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
module NcsNavigator::Mdes
|
6
|
+
describe TransmissionTable do
|
7
|
+
describe '.from_element' do
|
8
|
+
let(:element) {
|
9
|
+
Nokogiri::XML(<<-XSD).root.xpath('//xs:element[@name="study_center"]').first
|
10
|
+
<xs:schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:ncs="http://www.nationalchildrensstudy.gov" xmlns:ncsdoc="http://www.nationalchildrensstudy.gov/doc" xmlns:xlink="http://www.w3.org/TR/WD-xlink" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.nationalchildrensstudy.gov" elementFormDefault="unqualified" attributeFormDefault="unqualified">
|
11
|
+
<xs:element name="transmission_tables">
|
12
|
+
<xs:complexType>
|
13
|
+
<xs:sequence>
|
14
|
+
<xs:element name="study_center" minOccurs="0" maxOccurs="unbounded">
|
15
|
+
<xs:complexType>
|
16
|
+
<xs:sequence>
|
17
|
+
<xs:element name="sc_id" ncsdoc:pii="" ncsdoc:status="1" ncsdoc:key_asso="" nillable="false" type="ncs:study_center_cl1"/>
|
18
|
+
<xs:element name="sc_name" ncsdoc:pii="" ncsdoc:status="1" ncsdoc:key_asso="" nillable="true">
|
19
|
+
<xs:simpleType>
|
20
|
+
<xs:restriction base="xs:string">
|
21
|
+
<xs:maxLength value="100"/>
|
22
|
+
</xs:restriction>
|
23
|
+
</xs:simpleType>
|
24
|
+
</xs:element>
|
25
|
+
<xs:element name="comments" ncsdoc:pii="P" ncsdoc:status="1" ncsdoc:key_asso="" nillable="true">
|
26
|
+
<xs:simpleType>
|
27
|
+
<xs:restriction base="xs:string">
|
28
|
+
<xs:maxLength value="8000"/>
|
29
|
+
</xs:restriction>
|
30
|
+
</xs:simpleType>
|
31
|
+
</xs:element>
|
32
|
+
<xs:element name="transaction_type" ncsdoc:pii="" ncsdoc:status="1" ncsdoc:key_asso="" nillable="true">
|
33
|
+
<xs:simpleType>
|
34
|
+
<xs:restriction base="xs:string">
|
35
|
+
<xs:maxLength value="36"/>
|
36
|
+
</xs:restriction>
|
37
|
+
</xs:simpleType>
|
38
|
+
</xs:element>
|
39
|
+
</xs:sequence>
|
40
|
+
</xs:complexType>
|
41
|
+
</xs:element>
|
42
|
+
</xs:sequence>
|
43
|
+
</xs:complexType>
|
44
|
+
</xs:element>
|
45
|
+
</xs:schema>
|
46
|
+
XSD
|
47
|
+
}
|
48
|
+
|
49
|
+
subject { TransmissionTable.from_element(element) }
|
50
|
+
|
51
|
+
it 'has the right name' do
|
52
|
+
subject.name.should == 'study_center'
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'has the right variables' do
|
56
|
+
subject.variables.collect(&:name).
|
57
|
+
should == %w(sc_id sc_name comments transaction_type)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#initialize' do
|
62
|
+
it 'accepts a name' do
|
63
|
+
TransmissionTable.new('study_center').name.should == 'study_center'
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#[]' do
|
68
|
+
subject {
|
69
|
+
TransmissionTable.new('example').tap do |t|
|
70
|
+
t.variables = %w(foo bar baz).collect do |n|
|
71
|
+
Variable.new(n)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
}
|
75
|
+
|
76
|
+
it 'gets a variable' do
|
77
|
+
subject['bar'].should be_a(Variable)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'gets a variable by name' do
|
81
|
+
subject['baz'].name.should == 'baz'
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'is nil for an unknown variable' do
|
85
|
+
subject['quux'].should be_nil
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,216 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
module NcsNavigator::Mdes
|
6
|
+
describe Variable do
|
7
|
+
describe '.from_element' do
|
8
|
+
def variable(s)
|
9
|
+
Variable.from_element(schema_element(s), :log => logger)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:comments) {
|
13
|
+
variable(<<-XSD)
|
14
|
+
<xs:element name="comments" ncsdoc:pii="P" ncsdoc:status="1" ncsdoc:key_asso="" nillable="true">
|
15
|
+
<xs:simpleType>
|
16
|
+
<xs:restriction base="xs:string">
|
17
|
+
<xs:maxLength value="8000"/>
|
18
|
+
</xs:restriction>
|
19
|
+
</xs:simpleType>
|
20
|
+
</xs:element>
|
21
|
+
XSD
|
22
|
+
}
|
23
|
+
|
24
|
+
let(:sc_id) {
|
25
|
+
variable('<xs:element name="sc_id" ncsdoc:pii="" ncsdoc:status="1" ncsdoc:key_asso="" nillable="false" type="ncs:study_center_cl1"/>')
|
26
|
+
}
|
27
|
+
|
28
|
+
it 'has the correct name' do
|
29
|
+
comments.name.should == 'comments'
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#type' do
|
33
|
+
context 'when embedded' do
|
34
|
+
it 'is a VariableType' do
|
35
|
+
comments.type.should be_a VariableType
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'is parsed from the contents' do
|
39
|
+
comments.type.max_length.should == 8000
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'is not a reference' do
|
43
|
+
comments.type.should_not be_reference
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when a named type' do
|
48
|
+
context 'with the XML schema prefix' do
|
49
|
+
let!(:subject) { variable('<xs:element type="xs:decimal"/>') }
|
50
|
+
|
51
|
+
it 'is a VariableType' do
|
52
|
+
subject.type.should be_a VariableType
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'has a matching base type' do
|
56
|
+
subject.type.base_type.should == :decimal
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'is not a reference' do
|
60
|
+
subject.type.should_not be_reference
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'with another prefix' do
|
65
|
+
it 'is a VariableType' do
|
66
|
+
sc_id.type.should be_a VariableType
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'has the name' do
|
70
|
+
sc_id.type.name.should == 'ncs:study_center_cl1'
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'is a reference' do
|
74
|
+
sc_id.type.should be_reference
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'when none present' do
|
80
|
+
let!(:subject) { variable('<xs:element name="bar"/>') }
|
81
|
+
|
82
|
+
it 'is nil' do
|
83
|
+
subject.type.should be_nil
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'warns' do
|
87
|
+
logger[:warn].first.should == 'Could not determine a type for variable "bar" on line 2'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '#required?' do
|
93
|
+
it 'is true when not nillable' do
|
94
|
+
variable('<xs:element nillable="false"/>').should be_required
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'is false when nillable' do
|
98
|
+
comments.should_not be_required
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe '#pii' do
|
103
|
+
it 'is false when blank' do
|
104
|
+
variable('<xs:element ncsdoc:pii=""/>').pii.should == false
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'is true when "Y"' do
|
108
|
+
variable('<xs:element ncsdoc:pii="Y"/>').pii.should == true
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'is :possible when "P"' do
|
112
|
+
variable('<xs:element ncsdoc:pii="P"/>').pii.should == :possible
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'is the literal value when some other value' do
|
116
|
+
variable('<xs:element ncsdoc:pii="7"/>').pii.should == '7'
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'is :unknown when not set' do
|
120
|
+
variable('<xs:element/>').pii.should == :unknown
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe '#status' do
|
125
|
+
it 'is :active for 1' do
|
126
|
+
variable('<xs:element ncsdoc:status="1"/>').status.should == :active
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'is :new for 2' do
|
130
|
+
variable('<xs:element ncsdoc:status="2"/>').status.should == :new
|
131
|
+
end
|
132
|
+
|
133
|
+
it 'is :modified for 3' do
|
134
|
+
variable('<xs:element ncsdoc:status="3"/>').status.should == :modified
|
135
|
+
end
|
136
|
+
|
137
|
+
it 'is :retired for 4' do
|
138
|
+
variable('<xs:element ncsdoc:status="4"/>').status.should == :retired
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'is the literal value for some other value' do
|
142
|
+
variable('<xs:element ncsdoc:status="P4"/>').status.should == 'P4'
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'is nil when not set' do
|
146
|
+
variable('<xs:element/>').status.should be_nil
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe '#resolve_type!' do
|
152
|
+
let(:reference_type) { VariableType.reference('ncs:color_cl3') }
|
153
|
+
let(:actual_type) { VariableType.new('color_cl3') }
|
154
|
+
|
155
|
+
let(:types) { [ actual_type ] }
|
156
|
+
let(:variable) {
|
157
|
+
Variable.new('hair_color').tap { |v| v.type = reference_type }
|
158
|
+
}
|
159
|
+
|
160
|
+
context 'when the type is available' do
|
161
|
+
it 'resolves' do
|
162
|
+
variable.resolve_type!(types)
|
163
|
+
variable.type.should be actual_type
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context 'when the type is not resolvable' do
|
168
|
+
before { variable.resolve_type!([], :log => logger) }
|
169
|
+
|
170
|
+
it 'leaves the reference alone' do
|
171
|
+
variable.type.should be reference_type
|
172
|
+
end
|
173
|
+
|
174
|
+
it 'warns' do
|
175
|
+
logger[:warn].first.should == 'Undefined type ncs:color_cl3 for hair_color.'
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
context 'when the reference is of an unknown namespace' do
|
180
|
+
let(:unknown_kind_of_ref) { VariableType.reference('foo:bar') }
|
181
|
+
|
182
|
+
before {
|
183
|
+
variable.type = unknown_kind_of_ref
|
184
|
+
variable.resolve_type!(types, :log => logger)
|
185
|
+
}
|
186
|
+
|
187
|
+
it 'leaves it in place' do
|
188
|
+
variable.type.should be unknown_kind_of_ref
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'warns' do
|
192
|
+
logger[:warn].first.
|
193
|
+
should == 'Unknown reference namespace in type "foo:bar" for hair_color'
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
context 'when the type is an XML Schema type' do
|
198
|
+
it 'ignores it' do
|
199
|
+
variable.type = VariableType.xml_schema_type('decimal')
|
200
|
+
variable.resolve_type!(types, :log => logger)
|
201
|
+
logger[:warn].should == []
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
context 'when the type is not a reference' do
|
206
|
+
let(:not_a_ref) { VariableType.new('ncs:color_cl3') }
|
207
|
+
|
208
|
+
it 'does nothing' do
|
209
|
+
variable.type = not_a_ref
|
210
|
+
variable.resolve_type!(types)
|
211
|
+
variable.type.should be not_a_ref
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
@@ -0,0 +1,202 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
require 'nokogiri'
|
4
|
+
|
5
|
+
module NcsNavigator::Mdes
|
6
|
+
describe VariableType do
|
7
|
+
describe '.from_xsd_simple_type' do
|
8
|
+
def vtype(body_s, name=nil)
|
9
|
+
VariableType.from_xsd_simple_type(schema_element(<<-XML), :log => logger)
|
10
|
+
<xs:simpleType #{name ? "name='#{name}'" : nil}>
|
11
|
+
#{body_s}
|
12
|
+
</xs:simpleType>
|
13
|
+
XML
|
14
|
+
end
|
15
|
+
|
16
|
+
def vtype_from_string(restriction_body, name=nil)
|
17
|
+
vtype(<<-XML, name)
|
18
|
+
<xs:restriction base="xs:string">
|
19
|
+
#{restriction_body}
|
20
|
+
</xs:restriction>
|
21
|
+
XML
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'with an unsupported restriction base' do
|
25
|
+
let!(:subject) { vtype('<xs:restriction base="xs:int"/>') }
|
26
|
+
|
27
|
+
it 'is nil' do
|
28
|
+
subject.should be_nil
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'logs a warning' do
|
32
|
+
logger[:warn].first.
|
33
|
+
should == 'Unsupported restriction base in simpleType on line 2'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'with an unsupported restriction subelement' do
|
38
|
+
let!(:subject) { vtype_from_string('<xs:color value="red"/>') }
|
39
|
+
|
40
|
+
it 'logs a warning' do
|
41
|
+
logger[:warn].first.should == 'Unsupported restriction element "color" on line 4'
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#name' do
|
46
|
+
it 'is set if there is one' do
|
47
|
+
vtype_from_string(nil, 'foo').name.should == 'foo'
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'is nil if there is not one' do
|
51
|
+
vtype_from_string(nil, nil).name.should be_nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '#max_length' do
|
56
|
+
it 'is set if present' do
|
57
|
+
vtype_from_string('<xs:maxLength value="255"/>').max_length.should == 255
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#min_length' do
|
62
|
+
it 'is set if present' do
|
63
|
+
vtype_from_string('<xs:minLength value="1"/>').min_length.should == 1
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#pattern' do
|
68
|
+
it 'is compiled to a regexp if present' do
|
69
|
+
vtype_from_string('<xs:pattern value="([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])?"/>').
|
70
|
+
pattern.should == /([0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])?/
|
71
|
+
end
|
72
|
+
|
73
|
+
describe 'when malformed' do
|
74
|
+
let!(:subject) { vtype_from_string('<xs:pattern value="(["/>') }
|
75
|
+
|
76
|
+
it 'is nil if present but malformed' do
|
77
|
+
subject.pattern.should be_nil
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'logs a warning' do
|
81
|
+
logger[:warn].first.should == 'Uncompilable pattern "([" in simpleType on line 4'
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe '#base_type' do
|
87
|
+
it 'is :string' do
|
88
|
+
vtype_from_string('<xs:maxLength value="255"/>').base_type.should == :string
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'is not a reference' do
|
93
|
+
vtype_from_string('<xs:maxLength value="255"/>').should_not be_reference
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#code_list' do
|
97
|
+
context 'when there are no enumerated values' do
|
98
|
+
it 'is nil' do
|
99
|
+
vtype_from_string('<xs:maxLength value="255"/>').code_list.should be_nil
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context 'when there are enumerated values' do
|
104
|
+
subject {
|
105
|
+
vtype_from_string(<<-XSD)
|
106
|
+
<xs:enumeration value="1" ncsdoc:label="Retired" ncsdoc:desc="Eq" ncsdoc:global_value="192-1" ncsdoc:master_cl="equipment_action"/>
|
107
|
+
<xs:enumeration value="2" ncsdoc:label="Sent to manufacturer" ncsdoc:desc="Eq" ncsdoc:global_value="192-2" ncsdoc:master_cl="equipment_action"/>
|
108
|
+
<xs:enumeration value="3" ncsdoc:label="Conducting Maintenance on Site" ncsdoc:desc="Eq" ncsdoc:global_value="192-3" ncsdoc:master_cl="equipment_action"/>
|
109
|
+
<xs:enumeration value="-7" ncsdoc:label="Not applicable" ncsdoc:desc="Eq" ncsdoc:global_value="99-7" ncsdoc:master_cl="missing_data"/>
|
110
|
+
<xs:enumeration value="-4" ncsdoc:label="Missing in Error" ncsdoc:desc="Eq" ncsdoc:global_value="99-4" ncsdoc:master_cl="missing_data"/>
|
111
|
+
XSD
|
112
|
+
}
|
113
|
+
|
114
|
+
it 'has an entry for each value' do
|
115
|
+
subject.code_list.collect(&:to_s).should == %w(1 2 3 -7 -4)
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'has the description' do
|
119
|
+
subject.code_list.description.should == "Eq"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe '.reference' do
|
126
|
+
subject { VariableType.reference('ncs:bar') }
|
127
|
+
|
128
|
+
it 'has the right name' do
|
129
|
+
subject.name.should == 'ncs:bar'
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'is a reference' do
|
133
|
+
subject.should be_reference
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe '.xml_schema_type' do
|
138
|
+
subject { VariableType.xml_schema_type('int') }
|
139
|
+
|
140
|
+
it 'has no name' do
|
141
|
+
subject.name.should be_nil
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'has the correct base type' do
|
145
|
+
subject.base_type.should == :int
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'is not a reference' do
|
149
|
+
subject.should_not be_reference
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe VariableType::CodeListEntry do
|
155
|
+
describe '.from_xsd_enumeration' do
|
156
|
+
def code_list_entry(xml_s)
|
157
|
+
VariableType::CodeListEntry.from_xsd_enumeration(schema_element(xml_s), :log => logger)
|
158
|
+
end
|
159
|
+
|
160
|
+
let(:missing) {
|
161
|
+
code_list_entry(<<-XSD)
|
162
|
+
<xs:enumeration value="-4" ncsdoc:label="Missing in Error" ncsdoc:desc="" ncsdoc:global_value="99-4" ncsdoc:master_cl="missing_data"/>
|
163
|
+
XSD
|
164
|
+
}
|
165
|
+
|
166
|
+
describe '#value' do
|
167
|
+
it 'is set' do
|
168
|
+
missing.value.should == "-4"
|
169
|
+
end
|
170
|
+
|
171
|
+
it 'warns when missing' do
|
172
|
+
code_list_entry('<xs:enumeration ncsdoc:label="Foo"/>')
|
173
|
+
logger[:warn].first.should == 'Missing value for code list entry on line 2'
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe "#label" do
|
178
|
+
it 'is set' do
|
179
|
+
missing.label.should == "Missing in Error"
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
describe '#global_value' do
|
184
|
+
it 'is set' do
|
185
|
+
missing.global_value.should == '99-4'
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe '#master_cl' do
|
190
|
+
it 'is set' do
|
191
|
+
missing.master_cl.should == 'missing_data'
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe '#to_s' do
|
197
|
+
it 'is the value' do
|
198
|
+
VariableType::CodeListEntry.new('14').to_s.should == '14'
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|