aixm 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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