aixm 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.ruby-version +1 -1
  4. data/.yardopts +3 -0
  5. data/CHANGELOG.md +34 -14
  6. data/Guardfile +1 -0
  7. data/README.md +64 -257
  8. data/lib/aixm.rb +16 -7
  9. data/lib/aixm/component.rb +6 -0
  10. data/lib/aixm/component/frequency.rb +135 -0
  11. data/lib/aixm/component/geometry.rb +34 -23
  12. data/lib/aixm/component/geometry/arc.rb +37 -22
  13. data/lib/aixm/component/geometry/border.rb +29 -20
  14. data/lib/aixm/component/geometry/circle.rb +39 -22
  15. data/lib/aixm/component/geometry/point.rb +29 -13
  16. data/lib/aixm/component/helipad.rb +154 -0
  17. data/lib/aixm/component/layer.rb +91 -0
  18. data/lib/aixm/component/runway.rb +294 -0
  19. data/lib/aixm/component/service.rb +170 -0
  20. data/lib/aixm/component/timetable.rb +65 -0
  21. data/lib/aixm/component/vertical_limits.rb +65 -29
  22. data/lib/aixm/config.rb +87 -0
  23. data/lib/aixm/document.rb +66 -42
  24. data/lib/aixm/errors.rb +11 -0
  25. data/lib/aixm/f.rb +34 -20
  26. data/lib/aixm/feature.rb +38 -0
  27. data/lib/aixm/feature/airport.rb +473 -0
  28. data/lib/aixm/feature/airspace.rb +145 -92
  29. data/lib/aixm/feature/navigational_aid.rb +94 -0
  30. data/lib/aixm/feature/navigational_aid/designated_point.rb +50 -54
  31. data/lib/aixm/feature/navigational_aid/dme.rb +48 -40
  32. data/lib/aixm/feature/navigational_aid/marker.rb +55 -45
  33. data/lib/aixm/feature/navigational_aid/ndb.rb +54 -50
  34. data/lib/aixm/feature/navigational_aid/tacan.rb +38 -31
  35. data/lib/aixm/feature/navigational_aid/vor.rb +84 -76
  36. data/lib/aixm/feature/organisation.rb +97 -0
  37. data/lib/aixm/feature/unit.rb +152 -0
  38. data/lib/aixm/refinements.rb +132 -47
  39. data/lib/aixm/shortcuts.rb +11 -6
  40. data/lib/aixm/version.rb +1 -1
  41. data/lib/aixm/xy.rb +64 -20
  42. data/lib/aixm/z.rb +51 -22
  43. data/{lib/aixm/schemas → schemas/aixm}/4.5/AIXM-DataTypes.xsd +0 -0
  44. data/{lib/aixm/schemas → schemas/aixm}/4.5/AIXM-Features.xsd +0 -0
  45. data/{lib/aixm/schemas → schemas/aixm}/4.5/AIXM-Snapshot.xsd +0 -0
  46. data/schemas/ofmx/0/OFMX-DataTypes.xsd +5077 -0
  47. data/schemas/ofmx/0/OFMX-Features.xsd +9955 -0
  48. data/schemas/ofmx/0/OFMX-Snapshot.xsd +217 -0
  49. data/spec/factory.rb +209 -33
  50. data/spec/lib/aixm/component/frequency_spec.rb +75 -0
  51. data/spec/lib/aixm/component/geometry/arc_spec.rb +28 -22
  52. data/spec/lib/aixm/component/geometry/border_spec.rb +23 -20
  53. data/spec/lib/aixm/component/geometry/circle_spec.rb +31 -22
  54. data/spec/lib/aixm/component/geometry/point_spec.rb +11 -14
  55. data/spec/lib/aixm/component/geometry_spec.rb +150 -69
  56. data/spec/lib/aixm/component/helipad_spec.rb +136 -0
  57. data/spec/lib/aixm/component/layer_spec.rb +110 -0
  58. data/spec/lib/aixm/component/runway_spec.rb +402 -0
  59. data/spec/lib/aixm/component/service_spec.rb +61 -0
  60. data/spec/lib/aixm/component/timetable_spec.rb +49 -0
  61. data/spec/lib/aixm/component/vertical_limits_spec.rb +39 -20
  62. data/spec/lib/aixm/config_spec.rb +41 -0
  63. data/spec/lib/aixm/document_spec.rb +637 -147
  64. data/spec/lib/aixm/errors_spec.rb +14 -0
  65. data/spec/lib/aixm/f_spec.rb +17 -10
  66. data/spec/lib/aixm/feature/airport_spec.rb +546 -0
  67. data/spec/lib/aixm/feature/airspace_spec.rb +349 -226
  68. data/spec/lib/aixm/feature/navigational_aid/designated_point_spec.rb +47 -36
  69. data/spec/lib/aixm/feature/navigational_aid/dme_spec.rb +61 -36
  70. data/spec/lib/aixm/feature/navigational_aid/marker_spec.rb +61 -113
  71. data/spec/lib/aixm/feature/navigational_aid/ndb_spec.rb +65 -79
  72. data/spec/lib/aixm/feature/navigational_aid/tacan_spec.rb +57 -36
  73. data/spec/lib/aixm/feature/navigational_aid/vor_spec.rb +86 -112
  74. data/spec/lib/aixm/feature/navigational_aid_spec.rb +52 -0
  75. data/spec/lib/aixm/feature/organisation_spec.rb +77 -0
  76. data/spec/lib/aixm/feature/unit_spec.rb +227 -0
  77. data/spec/lib/aixm/feature_spec.rb +58 -0
  78. data/spec/lib/aixm/refinements_spec.rb +187 -178
  79. data/spec/lib/aixm/xy_spec.rb +45 -34
  80. data/spec/lib/aixm/z_spec.rb +19 -21
  81. data/spec/macros/organisation.rb +11 -0
  82. data/spec/macros/remarks.rb +12 -0
  83. data/spec/macros/timetable.rb +11 -0
  84. data/spec/macros/xy.rb +11 -0
  85. data/spec/macros/z_qnh.rb +11 -0
  86. data/spec/spec_helper.rb +26 -0
  87. metadata +60 -19
  88. data/lib/aixm/base.rb +0 -10
  89. data/lib/aixm/component/base.rb +0 -6
  90. data/lib/aixm/component/class_layer.rb +0 -46
  91. data/lib/aixm/component/geometry/base.rb +0 -8
  92. data/lib/aixm/component/schedule.rb +0 -43
  93. data/lib/aixm/feature/base.rb +0 -6
  94. data/lib/aixm/feature/navigational_aid/base.rb +0 -79
  95. data/spec/lib/aixm/component/class_layer_spec.rb +0 -74
  96. data/spec/lib/aixm/component/schedule_spec.rb +0 -33
  97. data/spec/lib/aixm/feature/navigational_aid/base_spec.rb +0 -41
@@ -0,0 +1,136 @@
1
+ require_relative '../../../spec_helper'
2
+
3
+ describe AIXM::Component::Helipad do
4
+ subject do
5
+ AIXM::Factory.airport.helipads.first
6
+ end
7
+
8
+ describe :name= do
9
+ it "fails on invalid values" do
10
+ [nil, :foobar, 123].wont_be_written_to subject, :name
11
+ end
12
+
13
+ it "upcases and transcodes valid values" do
14
+ subject.tap { |s| s.name = 'h1' }.name.must_equal 'H1'
15
+ end
16
+ end
17
+
18
+ describe :xy= do
19
+ macro :xy
20
+
21
+ it "fails on nil value" do
22
+ [nil].wont_be_written_to subject, :xy
23
+ end
24
+ end
25
+
26
+ describe :z= do
27
+ macro :z_qnh
28
+ end
29
+
30
+ describe :length= do
31
+ it "fails on invalid values" do
32
+ [:foobar, 0, -1].wont_be_written_to subject, :length
33
+ end
34
+
35
+ it "accepts nil value" do
36
+ [nil].must_be_written_to subject, :length
37
+ end
38
+
39
+ it "converts valid Numeric values to Integer" do
40
+ subject.tap { |s| s.length = 1000.5 }.length.must_equal 1000
41
+ end
42
+ end
43
+
44
+ describe :width= do
45
+ it "fails on invalid values" do
46
+ [:foobar, 0, -1].wont_be_written_to subject, :width
47
+ end
48
+
49
+ it "accepts nil value" do
50
+ [nil].must_be_written_to subject, :width
51
+ end
52
+
53
+ it "converts valid Numeric values to Integer" do
54
+ subject.tap { |s| s.width = 150.5 }.width.must_equal 150
55
+ end
56
+ end
57
+
58
+ describe :composition= do
59
+ it "fails on invalid values" do
60
+ [:foobar, 123].wont_be_written_to subject, :composition
61
+ end
62
+
63
+ it "accepts nil value" do
64
+ [nil].must_be_written_to subject, :composition
65
+ end
66
+
67
+ it "looks up valid values" do
68
+ subject.tap { |s| s.composition = :macadam }.composition.must_equal :macadam
69
+ subject.tap { |s| s.composition = :GRADE }.composition.must_equal :graded_earth
70
+ end
71
+ end
72
+
73
+ describe :status= do
74
+ it "fails on invalid values" do
75
+ [:foobar, 123].wont_be_written_to subject, :status
76
+ end
77
+
78
+ it "accepts nil value" do
79
+ [nil].must_be_written_to subject, :status
80
+ end
81
+
82
+ it "looks up valid values" do
83
+ subject.tap { |s| s.status = :closed }.status.must_equal :closed
84
+ subject.tap { |s| s.status = :SPOWER }.status.must_equal :secondary_power
85
+ end
86
+ end
87
+
88
+ describe :remarks= do
89
+ macro :remarks
90
+ end
91
+
92
+ describe :xml= do
93
+ it "builds correct complete OFMX" do
94
+ AIXM.ofmx!
95
+ subject.to_xml.must_equal <<~END
96
+ <Tla>
97
+ <TlaUid>
98
+ <AhpUid region="LF">
99
+ <codeId>LFNT</codeId>
100
+ </AhpUid>
101
+ <txtDesig>H1</txtDesig>
102
+ </TlaUid>
103
+ <geoLat>43.99915000N</geoLat>
104
+ <geoLong>004.75154444E</geoLong>
105
+ <codeDatum>WGE</codeDatum>
106
+ <valElev>141</valElev>
107
+ <uomDistVer>FT</uomDistVer>
108
+ <valLen>20</valLen>
109
+ <valWid>20</valWid>
110
+ <uomDim>M</uomDim>
111
+ <codeComposition>GRASS</codeComposition>
112
+ <codeSts>OTHER</codeSts>
113
+ <txtRmk>Authorizaton by AD operator required</txtRmk>
114
+ </Tla>
115
+ END
116
+ end
117
+
118
+ it "builds correct minimal OFMX" do
119
+ AIXM.ofmx!
120
+ subject.z = subject.length = subject.width = subject.composition = subject.status = subject.remarks = nil
121
+ subject.to_xml.must_equal <<~END
122
+ <Tla>
123
+ <TlaUid>
124
+ <AhpUid region="LF">
125
+ <codeId>LFNT</codeId>
126
+ </AhpUid>
127
+ <txtDesig>H1</txtDesig>
128
+ </TlaUid>
129
+ <geoLat>43.99915000N</geoLat>
130
+ <geoLong>004.75154444E</geoLong>
131
+ <codeDatum>WGE</codeDatum>
132
+ </Tla>
133
+ END
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,110 @@
1
+ require_relative '../../../spec_helper'
2
+
3
+ describe AIXM::Component::Layer do
4
+
5
+ context "only required attributes set" do
6
+ subject do
7
+ AIXM.layer(vertical_limits: AIXM::Factory.vertical_limits)
8
+ end
9
+
10
+ describe :initialize do
11
+ it "sets defaults" do
12
+ subject.wont_be :selective?
13
+ end
14
+ end
15
+
16
+ describe :class= do
17
+ it "fails on invalid values" do
18
+ [:X, 'X'].wont_be_written_to subject, :class
19
+ end
20
+
21
+ it "symbolizes and upcases valid values" do
22
+ subject.tap { |s| s.class = 'c' }.class.must_equal :C
23
+ end
24
+ end
25
+
26
+ describe :vertical_limits= do
27
+ it "fails on invalid values" do
28
+ [nil, :foobar, 123].wont_be_written_to subject, :vertical_limits
29
+ end
30
+ end
31
+
32
+ describe :timetable= do
33
+ macro :timetable
34
+ end
35
+
36
+ describe :selective= do
37
+ it "fails on invalid values" do
38
+ [nil, 'N', 0].wont_be_written_to subject, :selective
39
+ end
40
+ end
41
+
42
+ describe :remarks= do
43
+ macro :remarks
44
+ end
45
+
46
+ describe :to_xml do
47
+ it "builds correct OFMX" do
48
+ AIXM.ofmx!
49
+ subject.to_xml.must_equal <<~END
50
+ <codeDistVerUpper>STD</codeDistVerUpper>
51
+ <valDistVerUpper>65</valDistVerUpper>
52
+ <uomDistVerUpper>FL</uomDistVerUpper>
53
+ <codeDistVerLower>STD</codeDistVerLower>
54
+ <valDistVerLower>45</valDistVerLower>
55
+ <uomDistVerLower>FL</uomDistVerLower>
56
+ <codeDistVerMax>ALT</codeDistVerMax>
57
+ <valDistVerMax>6000</valDistVerMax>
58
+ <uomDistVerMax>FT</uomDistVerMax>
59
+ <codeDistVerMnm>HEI</codeDistVerMnm>
60
+ <valDistVerMnm>3000</valDistVerMnm>
61
+ <uomDistVerMnm>FT</uomDistVerMnm>
62
+ <codeSelAvbl>N</codeSelAvbl>
63
+ END
64
+ end
65
+
66
+ it "builds correct AIXM" do
67
+ AIXM.aixm!
68
+ subject.to_xml.wont_match(/<codeSelAvbl>/)
69
+ subject.to_xml.wont_match(/<Att>/)
70
+ subject.to_xml.wont_match(/<txtRmk>/)
71
+ end
72
+ end
73
+ end
74
+
75
+ context "required and optional attributes set" do
76
+ subject do
77
+ AIXM::Factory.layer
78
+ end
79
+
80
+ it "builds correct OFMX" do
81
+ AIXM.ofmx!
82
+ subject.to_xml.must_equal <<~END
83
+ <codeClass>C</codeClass>
84
+ <codeDistVerUpper>STD</codeDistVerUpper>
85
+ <valDistVerUpper>65</valDistVerUpper>
86
+ <uomDistVerUpper>FL</uomDistVerUpper>
87
+ <codeDistVerLower>STD</codeDistVerLower>
88
+ <valDistVerLower>45</valDistVerLower>
89
+ <uomDistVerLower>FL</uomDistVerLower>
90
+ <codeDistVerMax>ALT</codeDistVerMax>
91
+ <valDistVerMax>6000</valDistVerMax>
92
+ <uomDistVerMax>FT</uomDistVerMax>
93
+ <codeDistVerMnm>HEI</codeDistVerMnm>
94
+ <valDistVerMnm>3000</valDistVerMnm>
95
+ <uomDistVerMnm>FT</uomDistVerMnm>
96
+ <Att>
97
+ <codeWorkHr>H24</codeWorkHr>
98
+ </Att>
99
+ <codeSelAvbl>Y</codeSelAvbl>
100
+ <txtRmk>airspace layer</txtRmk>
101
+ END
102
+ end
103
+
104
+ it "builds correct AIXM" do
105
+ AIXM.aixm!
106
+ subject.to_xml.wont_match(/<codeSelAvbl>/)
107
+ end
108
+ end
109
+
110
+ end
@@ -0,0 +1,402 @@
1
+ require_relative '../../../spec_helper'
2
+
3
+ describe AIXM::Component::Runway do
4
+ subject do
5
+ AIXM::Factory.airport.runways.first
6
+ end
7
+
8
+ describe :initialize do
9
+ it "sets defaults for bidirectional runways" do
10
+ subject.forth.name.must_equal '16L'
11
+ subject.back.name.must_equal '34R'
12
+ end
13
+
14
+ it "sets defaults for unidirectional runways" do
15
+ subject = AIXM::Component::Runway.new(name: '30')
16
+ subject.forth.name.must_equal '30'
17
+ subject.back.must_be_nil
18
+ end
19
+ end
20
+
21
+ describe :name= do
22
+ it "fails on invalid values" do
23
+ [nil, :foobar, 123].wont_be_written_to subject, :name
24
+ end
25
+
26
+ it "upcases and transcodes valid values" do
27
+ subject.tap { |s| s.name = '10r/28l' }.name.must_equal '10R/28L'
28
+ end
29
+ end
30
+
31
+ describe :length= do
32
+ it "fails on invalid values" do
33
+ [:foobar, 0, -1].wont_be_written_to subject, :length
34
+ end
35
+
36
+ it "accepts nil value" do
37
+ [nil].must_be_written_to subject, :length
38
+ end
39
+
40
+ it "converts valid values to integer" do
41
+ subject.tap { |s| s.length = 1000.5 }.length.must_equal 1000
42
+ end
43
+ end
44
+
45
+ describe :width= do
46
+ it "fails on invalid values" do
47
+ [:foobar, 0, -1].wont_be_written_to subject, :width
48
+ end
49
+
50
+ it "accepts nil value" do
51
+ [nil].must_be_written_to subject, :width
52
+ end
53
+
54
+ it "converts valid values to integer" do
55
+ subject.tap { |s| s.width = 150.5 }.width.must_equal 150
56
+ end
57
+ end
58
+
59
+ describe :composition= do
60
+ it "fails on invalid values" do
61
+ [:foobar, 123].wont_be_written_to subject, :composition
62
+ end
63
+
64
+ it "accepts nil value" do
65
+ [nil].must_be_written_to subject, :composition
66
+ end
67
+
68
+ it "looks up valid values" do
69
+ subject.tap { |s| s.composition = :macadam }.composition.must_equal :macadam
70
+ subject.tap { |s| s.composition = :GRADE }.composition.must_equal :graded_earth
71
+ end
72
+ end
73
+
74
+ describe :status= do
75
+ it "fails on invalid values" do
76
+ [:foobar, 123].wont_be_written_to subject, :status
77
+ end
78
+
79
+ it "accepts nil value" do
80
+ [nil].must_be_written_to subject, :status
81
+ end
82
+
83
+ it "looks up valid values" do
84
+ subject.tap { |s| s.status = :closed }.status.must_equal :closed
85
+ subject.tap { |s| s.status = :SPOWER }.status.must_equal :secondary_power
86
+ end
87
+ end
88
+
89
+ describe :remarks= do
90
+ macro :remarks
91
+ end
92
+
93
+ describe :xml= do
94
+ it "builds correct complete OFMX" do
95
+ AIXM.ofmx!
96
+ subject.to_xml.must_equal <<~END
97
+ <Rwy>
98
+ <RwyUid>
99
+ <AhpUid region="LF">
100
+ <codeId>LFNT</codeId>
101
+ </AhpUid>
102
+ <txtDesig>16L/34R</txtDesig>
103
+ </RwyUid>
104
+ <valLen>650</valLen>
105
+ <valWid>80</valWid>
106
+ <uomDimRwy>M</uomDimRwy>
107
+ <codeComposition>GRADE</codeComposition>
108
+ <codeSts>CLSD</codeSts>
109
+ <txtRmk>Markings eroded</txtRmk>
110
+ </Rwy>
111
+ <Rdn>
112
+ <RdnUid>
113
+ <RwyUid>
114
+ <AhpUid region="LF">
115
+ <codeId>LFNT</codeId>
116
+ </AhpUid>
117
+ <txtDesig>16L/34R</txtDesig>
118
+ </RwyUid>
119
+ <txtDesig>16L</txtDesig>
120
+ </RdnUid>
121
+ <geoLat>44.00211944N</geoLat>
122
+ <geoLong>004.75216944E</geoLong>
123
+ <valTrueBrg>165</valTrueBrg>
124
+ <valMagBrg>166</valMagBrg>
125
+ <valElevTdz>147</valElevTdz>
126
+ <uomElevTdz>FT</uomElevTdz>
127
+ <txtRmk>forth remarks</txtRmk>
128
+ </Rdn>
129
+ <Rdd>
130
+ <RddUid>
131
+ <RdnUid>
132
+ <RwyUid>
133
+ <AhpUid region="LF">
134
+ <codeId>LFNT</codeId>
135
+ </AhpUid>
136
+ <txtDesig>16L/34R</txtDesig>
137
+ </RwyUid>
138
+ <txtDesig>16L</txtDesig>
139
+ </RdnUid>
140
+ <codeType>DPLM</codeType>
141
+ <codeDayPeriod>A</codeDayPeriod>
142
+ </RddUid>
143
+ <valDist>131</valDist>
144
+ <uomDist>M</uomDist>
145
+ <txtRmk>forth remarks</txtRmk>
146
+ </Rdd>
147
+ <Rdn>
148
+ <RdnUid>
149
+ <RwyUid>
150
+ <AhpUid region="LF">
151
+ <codeId>LFNT</codeId>
152
+ </AhpUid>
153
+ <txtDesig>16L/34R</txtDesig>
154
+ </RwyUid>
155
+ <txtDesig>34R</txtDesig>
156
+ </RdnUid>
157
+ <geoLat>43.99036389N</geoLat>
158
+ <geoLong>004.75645556E</geoLong>
159
+ <valTrueBrg>345</valTrueBrg>
160
+ <valMagBrg>346</valMagBrg>
161
+ <txtRmk>back remarks</txtRmk>
162
+ </Rdn>
163
+ <Rdd>
164
+ <RddUid>
165
+ <RdnUid>
166
+ <RwyUid>
167
+ <AhpUid region="LF">
168
+ <codeId>LFNT</codeId>
169
+ </AhpUid>
170
+ <txtDesig>16L/34R</txtDesig>
171
+ </RwyUid>
172
+ <txtDesig>34R</txtDesig>
173
+ </RdnUid>
174
+ <codeType>DPLM</codeType>
175
+ <codeDayPeriod>A</codeDayPeriod>
176
+ </RddUid>
177
+ <valDist>209</valDist>
178
+ <uomDist>M</uomDist>
179
+ <txtRmk>back remarks</txtRmk>
180
+ </Rdd>
181
+ END
182
+ end
183
+
184
+ it "builds correct minimal OFMX" do
185
+ AIXM.ofmx!
186
+ %i(length width composition status remarks).each { |a| subject.send(:"#{a}=", nil) }
187
+ subject.to_xml.must_equal <<~END
188
+ <Rwy>
189
+ <RwyUid>
190
+ <AhpUid region=\"LF\">
191
+ <codeId>LFNT</codeId>
192
+ </AhpUid>
193
+ <txtDesig>16L/34R</txtDesig>
194
+ </RwyUid>
195
+ </Rwy>
196
+ <Rdn>
197
+ <RdnUid>
198
+ <RwyUid>
199
+ <AhpUid region=\"LF\">
200
+ <codeId>LFNT</codeId>
201
+ </AhpUid>
202
+ <txtDesig>16L/34R</txtDesig>
203
+ </RwyUid>
204
+ <txtDesig>16L</txtDesig>
205
+ </RdnUid>
206
+ <geoLat>44.00211944N</geoLat>
207
+ <geoLong>004.75216944E</geoLong>
208
+ <valTrueBrg>165</valTrueBrg>
209
+ <valMagBrg>166</valMagBrg>
210
+ <valElevTdz>147</valElevTdz>
211
+ <uomElevTdz>FT</uomElevTdz>
212
+ <txtRmk>forth remarks</txtRmk>
213
+ </Rdn>
214
+ <Rdd>
215
+ <RddUid>
216
+ <RdnUid>
217
+ <RwyUid>
218
+ <AhpUid region=\"LF\">
219
+ <codeId>LFNT</codeId>
220
+ </AhpUid>
221
+ <txtDesig>16L/34R</txtDesig>
222
+ </RwyUid>
223
+ <txtDesig>16L</txtDesig>
224
+ </RdnUid>
225
+ <codeType>DPLM</codeType>
226
+ <codeDayPeriod>A</codeDayPeriod>
227
+ </RddUid>
228
+ <valDist>131</valDist>
229
+ <uomDist>M</uomDist>
230
+ <txtRmk>forth remarks</txtRmk>
231
+ </Rdd>
232
+ <Rdn>
233
+ <RdnUid>
234
+ <RwyUid>
235
+ <AhpUid region=\"LF\">
236
+ <codeId>LFNT</codeId>
237
+ </AhpUid>
238
+ <txtDesig>16L/34R</txtDesig>
239
+ </RwyUid>
240
+ <txtDesig>34R</txtDesig>
241
+ </RdnUid>
242
+ <geoLat>43.99036389N</geoLat>
243
+ <geoLong>004.75645556E</geoLong>
244
+ <valTrueBrg>345</valTrueBrg>
245
+ <valMagBrg>346</valMagBrg>
246
+ <txtRmk>back remarks</txtRmk>
247
+ </Rdn>
248
+ <Rdd>
249
+ <RddUid>
250
+ <RdnUid>
251
+ <RwyUid>
252
+ <AhpUid region=\"LF\">
253
+ <codeId>LFNT</codeId>
254
+ </AhpUid>
255
+ <txtDesig>16L/34R</txtDesig>
256
+ </RwyUid>
257
+ <txtDesig>34R</txtDesig>
258
+ </RdnUid>
259
+ <codeType>DPLM</codeType>
260
+ <codeDayPeriod>A</codeDayPeriod>
261
+ </RddUid>
262
+ <valDist>209</valDist>
263
+ <uomDist>M</uomDist>
264
+ <txtRmk>back remarks</txtRmk>
265
+ </Rdd>
266
+ END
267
+ end
268
+ end
269
+
270
+ end
271
+
272
+ describe AIXM::Component::Runway::Direction do
273
+ subject do
274
+ AIXM::Factory.airport.runways.first.forth
275
+ end
276
+
277
+ describe :name= do
278
+ it "overwrites preset name" do
279
+ subject.name.must_equal '16L'
280
+ subject.name = 'x01x'
281
+ subject.name.must_equal 'X01X'
282
+ end
283
+ end
284
+
285
+ describe :geographic_orientation= do
286
+ it "fails on invalid values" do
287
+ [:foobar, -1, 360].wont_be_written_to subject, :geographic_orientation
288
+ end
289
+
290
+ it "converts valid Numeric values to integer" do
291
+ subject.tap { |s| s.geographic_orientation = 100.5 }.geographic_orientation.must_equal 100
292
+ end
293
+ end
294
+
295
+ describe :xy= do
296
+ macro :xy
297
+
298
+ it "fails on nil value" do
299
+ [nil].wont_be_written_to subject, :xy
300
+ end
301
+ end
302
+
303
+ describe :z= do
304
+ macro :z_qnh
305
+
306
+ it "accepts nil value" do
307
+ [nil].must_be_written_to subject, :z
308
+ end
309
+ end
310
+
311
+ describe :displaced_threshold= do
312
+ it "fails on invalid values" do
313
+ [:foobar].wont_be_written_to subject, :displaced_threshold
314
+ end
315
+
316
+ it "converts valid Numeric values to Integer" do
317
+ subject.tap { |s| s.displaced_threshold = 222.0 }.displaced_threshold.must_equal 222
318
+ end
319
+
320
+ it "converts coordinates to distance" do
321
+ subject.xy = AIXM.xy(lat: %q(43°59'54.71"N), long: %q(004°45'28.35"E))
322
+ subject.displaced_threshold = AIXM.xy(lat: %q(43°59'48.47"N), long: %q(004°45'30.62"E))
323
+ subject.displaced_threshold.must_equal 199
324
+ end
325
+ end
326
+
327
+ describe :remarks= do
328
+ macro :remarks
329
+ end
330
+
331
+ describe :magnetic_orientation do
332
+ it "is calculated correctly" do
333
+ subject.geographic_orientation = 16
334
+ subject.magnetic_orientation.must_equal 17
335
+ end
336
+ end
337
+
338
+ describe :xml= do
339
+ it "builds correct complete OFMX" do
340
+ AIXM.ofmx!
341
+ subject.to_xml.must_equal <<~END
342
+ <Rdn>
343
+ <RdnUid>
344
+ <RwyUid>
345
+ <AhpUid region="LF">
346
+ <codeId>LFNT</codeId>
347
+ </AhpUid>
348
+ <txtDesig>16L/34R</txtDesig>
349
+ </RwyUid>
350
+ <txtDesig>16L</txtDesig>
351
+ </RdnUid>
352
+ <geoLat>44.00211944N</geoLat>
353
+ <geoLong>004.75216944E</geoLong>
354
+ <valTrueBrg>165</valTrueBrg>
355
+ <valMagBrg>166</valMagBrg>
356
+ <valElevTdz>147</valElevTdz>
357
+ <uomElevTdz>FT</uomElevTdz>
358
+ <txtRmk>forth remarks</txtRmk>
359
+ </Rdn>
360
+ <Rdd>
361
+ <RddUid>
362
+ <RdnUid>
363
+ <RwyUid>
364
+ <AhpUid region="LF">
365
+ <codeId>LFNT</codeId>
366
+ </AhpUid>
367
+ <txtDesig>16L/34R</txtDesig>
368
+ </RwyUid>
369
+ <txtDesig>16L</txtDesig>
370
+ </RdnUid>
371
+ <codeType>DPLM</codeType>
372
+ <codeDayPeriod>A</codeDayPeriod>
373
+ </RddUid>
374
+ <valDist>131</valDist>
375
+ <uomDist>M</uomDist>
376
+ <txtRmk>forth remarks</txtRmk>
377
+ </Rdd>
378
+ END
379
+ end
380
+
381
+ it "builds correct minimal OFMX" do
382
+ AIXM.ofmx!
383
+ %i(geographic_orientation z displaced_threshold remarks).each { |a| subject.send(:"#{a}=", nil) }
384
+ subject.to_xml.must_equal <<~END
385
+ <Rdn>
386
+ <RdnUid>
387
+ <RwyUid>
388
+ <AhpUid region="LF">
389
+ <codeId>LFNT</codeId>
390
+ </AhpUid>
391
+ <txtDesig>16L/34R</txtDesig>
392
+ </RwyUid>
393
+ <txtDesig>16L</txtDesig>
394
+ </RdnUid>
395
+ <geoLat>44.00211944N</geoLat>
396
+ <geoLong>004.75216944E</geoLong>
397
+ </Rdn>
398
+ END
399
+ end
400
+ end
401
+
402
+ end