aixm 0.3.3 → 0.3.4

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/.ruby-version +1 -1
  3. data/.travis.yml +1 -2
  4. data/CHANGELOG.md +20 -0
  5. data/README.md +7 -2
  6. data/aixm.gemspec +2 -3
  7. data/lib/aixm.rb +6 -2
  8. data/lib/aixm/a.rb +151 -0
  9. data/lib/aixm/component/frequency.rb +2 -2
  10. data/lib/aixm/component/geometry.rb +4 -0
  11. data/lib/aixm/component/geometry/point.rb +0 -4
  12. data/lib/aixm/component/helipad.rb +8 -22
  13. data/lib/aixm/component/runway.rb +36 -36
  14. data/lib/aixm/component/surface.rb +121 -0
  15. data/lib/aixm/component/timetable.rb +1 -0
  16. data/lib/aixm/constants.rb +40 -0
  17. data/lib/aixm/d.rb +5 -0
  18. data/lib/aixm/document.rb +2 -2
  19. data/lib/aixm/f.rb +6 -0
  20. data/lib/aixm/feature/address.rb +100 -0
  21. data/lib/aixm/feature/airport.rb +26 -7
  22. data/lib/aixm/feature/airspace.rb +10 -1
  23. data/lib/aixm/feature/navigational_aid.rb +1 -1
  24. data/lib/aixm/feature/navigational_aid/designated_point.rb +20 -5
  25. data/lib/aixm/feature/navigational_aid/dme.rb +2 -2
  26. data/lib/aixm/{component → feature}/service.rb +67 -16
  27. data/lib/aixm/feature/unit.rb +40 -6
  28. data/lib/aixm/refinements.rb +63 -6
  29. data/lib/aixm/shortcuts.rb +12 -4
  30. data/lib/aixm/version.rb +1 -1
  31. data/lib/aixm/xy.rb +6 -1
  32. data/lib/aixm/z.rb +6 -0
  33. data/schemas/ofmx/0/OFMX-DataTypes.xsd +5 -2
  34. data/schemas/ofmx/0/OFMX-Features.xsd +2 -0
  35. data/spec/factory.rb +32 -10
  36. data/spec/lib/aixm/a_spec.rb +203 -0
  37. data/spec/lib/aixm/component/helipad_spec.rb +11 -17
  38. data/spec/lib/aixm/component/runway_spec.rb +46 -32
  39. data/spec/lib/aixm/component/surface_spec.rb +88 -0
  40. data/spec/lib/aixm/d_spec.rb +10 -0
  41. data/spec/lib/aixm/document_spec.rb +104 -32
  42. data/spec/lib/aixm/f_spec.rb +10 -0
  43. data/spec/lib/aixm/feature/address_spec.rb +55 -0
  44. data/spec/lib/aixm/feature/airport_spec.rb +73 -3
  45. data/spec/lib/aixm/feature/navigational_aid/designated_point_spec.rb +43 -6
  46. data/spec/lib/aixm/feature/navigational_aid/dme_spec.rb +2 -2
  47. data/spec/lib/aixm/feature/navigational_aid/marker_spec.rb +2 -2
  48. data/spec/lib/aixm/feature/navigational_aid/ndb_spec.rb +2 -2
  49. data/spec/lib/aixm/feature/navigational_aid/tacan_spec.rb +2 -2
  50. data/spec/lib/aixm/feature/navigational_aid/vor_spec.rb +6 -6
  51. data/spec/lib/aixm/{component → feature}/service_spec.rb +12 -14
  52. data/spec/lib/aixm/feature/unit_spec.rb +7 -4
  53. data/spec/lib/aixm/refinements_spec.rb +100 -15
  54. data/spec/lib/aixm/z_spec.rb +10 -0
  55. metadata +17 -25
  56. data/lib/aixm/h.rb +0 -87
  57. data/spec/lib/aixm/h_spec.rb +0 -113
@@ -71,6 +71,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
71
71
  </xsd:annotation>
72
72
  </xsd:element>
73
73
  </xsd:sequence>
74
+ <xsd:attribute ref="source"/>
74
75
  </xsd:complexType>
75
76
  <xsd:complexType name="AerodromeHeliportAddressUidType">
76
77
  <xsd:annotation>
@@ -4083,6 +4084,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4083
4084
  </xsd:annotation>
4084
4085
  </xsd:element>
4085
4086
  </xsd:sequence>
4087
+ <xsd:attribute ref="source"/>
4086
4088
  </xsd:complexType>
4087
4089
  <xsd:complexType name="IlsUidType">
4088
4090
  <xsd:annotation>
@@ -20,12 +20,22 @@ module AIXM
20
20
  AIXM.f(123.35, :mhz)
21
21
  end
22
22
 
23
- def h
24
- AIXM.h('34L')
23
+ def a
24
+ AIXM.a('34L')
25
25
  end
26
26
 
27
27
  # Components
28
28
 
29
+ def address
30
+ AIXM.address(
31
+ source: 'LF|GEN|0.0 FACTORY|0|0',
32
+ type: :radio_frequency,
33
+ address: "123.35"
34
+ ).tap do |address|
35
+ address.remarks = "A/A (callsign PUJAUT)"
36
+ end
37
+ end
38
+
29
39
  def timetable
30
40
  AIXM.timetable(
31
41
  code: :sunrise_to_sunset
@@ -119,8 +129,9 @@ module AIXM
119
129
  name: 'DESIGNATED POINT NAVAID',
120
130
  xy: AIXM.xy(lat: %q(47°51'33"N), long: %q(007°33'36"E)),
121
131
  z: AIXM.z(500, :qnh),
122
- type: :ICAO
132
+ type: :vfr_reporting_point
123
133
  ).tap do |designated_point|
134
+ designated_point.airport = airport
124
135
  designated_point.timetable = AIXM::H24
125
136
  designated_point.remarks = 'designated point navaid'
126
137
  end
@@ -264,14 +275,14 @@ module AIXM
264
275
  class: :icao
265
276
  ).tap do |unit|
266
277
  unit.airport = airport
267
- unit.remarks = 'A/A FR only'
278
+ unit.remarks = 'FR only'
268
279
  unit.add_service(service)
269
280
  end
270
281
  end
271
282
 
272
283
  def service
273
284
  AIXM.service(
274
- name: "PUJAUT TOWER",
285
+ source: 'LF|GEN|0.0 FACTORY|0|0',
275
286
  type: :approach_control_service
276
287
  ).tap do |service|
277
288
  service.timetable = AIXM::H24
@@ -316,6 +327,7 @@ module AIXM
316
327
  reservation_required.timetable = AIXM::H24
317
328
  reservation_required.remarks = "reservation remarks"
318
329
  end
330
+ airport.add_address(address)
319
331
  end
320
332
  end
321
333
 
@@ -323,18 +335,24 @@ module AIXM
323
335
  AIXM.runway(name: '16L/34R').tap do |runway|
324
336
  runway.length = AIXM.d(650, :m)
325
337
  runway.width = AIXM.d(80, :m)
326
- runway.composition = :graded_earth
338
+ runway.surface.composition = :asphalt
339
+ runway.surface.preparation = :paved
340
+ runway.surface.condition = :good
341
+ runway.surface.pcn = "59/F/A/W/T"
342
+ runway.surface.remarks = "Paved shoulder on 2.5m on each side of the RWY."
327
343
  runway.status = :closed
328
344
  runway.remarks = "Markings eroded"
329
345
  runway.forth.xy = AIXM.xy(lat: %q(44°00'07.63"N), long: %q(004°45'07.81"E))
330
346
  runway.forth.z = AIXM.z(145, :qnh)
331
347
  runway.forth.displaced_threshold = AIXM.xy(lat: %q(44°00'03.54"N), long: %q(004°45'09.30"E))
332
- runway.forth.geographic_orientation = 165
348
+ runway.forth.geographic_orientation = AIXM.a(165)
349
+ runway.forth.vfr_pattern = :left_or_right
333
350
  runway.forth.remarks = "forth remarks"
334
351
  runway.back.xy = AIXM.xy(lat: %q(43°59'25.31"N), long: %q(004°45'23.24"E))
335
- runway.forth.z = AIXM.z(147, :qnh)
352
+ runway.back.z = AIXM.z(147, :qnh)
336
353
  runway.back.displaced_threshold = AIXM.xy(lat: %q(43°59'31.84"N), long: %q(004°45'20.85"E))
337
- runway.back.geographic_orientation = 345
354
+ runway.back.geographic_orientation = AIXM.a(345)
355
+ runway.back.vfr_pattern = :left
338
356
  runway.back.remarks = "back remarks"
339
357
  end
340
358
  end
@@ -345,7 +363,11 @@ module AIXM
345
363
  helipad.z = AIXM.z(141, :qnh)
346
364
  helipad.length = AIXM.d(20, :m)
347
365
  helipad.width = AIXM.d(20, :m)
348
- helipad.composition = :grass
366
+ helipad.surface.composition = :concrete
367
+ helipad.surface.preparation = :paved
368
+ helipad.surface.condition = :fair
369
+ helipad.surface.pcn = "30/F/A/W/U"
370
+ helipad.surface.remarks = "Cracks near the center."
349
371
  helipad.status = :other
350
372
  helipad.remarks = "Authorizaton by AD operator required"
351
373
  end
@@ -0,0 +1,203 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe AIXM::A do
4
+ let :subject_2 do
5
+ AIXM.a('0')
6
+ end
7
+
8
+ let :subject_3 do
9
+ AIXM.a(0)
10
+ end
11
+
12
+ describe :initialize do
13
+ it "fails on invalid values" do
14
+ -> { AIXM.a('foobar') }.must_raise ArgumentError
15
+ end
16
+
17
+ it "parses String as angle with precision=2" do
18
+ AIXM.a('34L').tap do |h|
19
+ h.deg.must_equal 340
20
+ h.precision.must_equal 2
21
+ h.suffix.must_equal :L
22
+ end
23
+ end
24
+
25
+ it "parses Numeric as angle with precision=3" do
26
+ AIXM.a(12).tap do |h|
27
+ h.deg.must_equal 12
28
+ h.precision.must_equal 3
29
+ h.suffix.must_be :nil?
30
+ end
31
+ end
32
+ end
33
+
34
+ describe :to_s do
35
+ context "precision=2" do
36
+ it "rounds and zero-pad deg to length 2 and concats suffix" do
37
+ AIXM.a('05').to_s.must_equal '05'
38
+ AIXM.a('05').tap { |a| a.suffix = :L }.to_s.must_equal '05L'
39
+ AIXM.a('05').tap { |a| a.deg = 0 }.to_s.must_equal '36'
40
+ end
41
+ end
42
+
43
+ context "precition=3" do
44
+ it "rounds and zero-pad deg to length 3" do
45
+ AIXM.a(5).to_s.must_equal '005'
46
+ AIXM.a(5).tap { |a| a.deg = 0 }.to_s.must_equal '000'
47
+ end
48
+ end
49
+ end
50
+
51
+ describe :deg= do
52
+ it "fails on invalid values" do
53
+ [:foobar, '1', -1, 361].wont_be_written_to subject_2, :deg
54
+ [:foobar, '1', -1, 361].wont_be_written_to subject_3, :deg
55
+ end
56
+
57
+ context "precision=2" do
58
+ it "rounds to 10 degree steps" do
59
+ subject_2.tap { |s| s.deg = 0 }.deg.must_equal 0
60
+ subject_2.tap { |s| s.deg = 5 }.deg.must_equal 10
61
+ subject_2.tap { |s| s.deg = 154 }.deg.must_equal 150
62
+ subject_2.tap { |s| s.deg = 359 }.deg.must_equal 0
63
+ subject_2.tap { |s| s.deg = 360 }.deg.must_equal 0
64
+ end
65
+ end
66
+
67
+ context "precision=3" do
68
+ it "accepts 1 degree steps" do
69
+ subject_3.tap { |s| s.deg = 0 }.deg.must_equal 0
70
+ subject_3.tap { |s| s.deg = 5 }.deg.must_equal 5
71
+ subject_3.tap { |s| s.deg = 154 }.deg.must_equal 154
72
+ subject_3.tap { |s| s.deg = 359 }.deg.must_equal 359
73
+ subject_3.tap { |s| s.deg = 360 }.deg.must_equal 0
74
+ end
75
+ end
76
+ end
77
+
78
+ describe :suffix= do
79
+ context "precision=2" do
80
+ it "fails on invalid values" do
81
+ [123, 'r'].wont_be_written_to subject_2, :suffix
82
+ end
83
+
84
+ it "accepts nil value" do
85
+ [nil].must_be_written_to subject_2, :suffix
86
+ end
87
+
88
+ it "symbolizes valid values" do
89
+ subject_2.tap { |s| s.suffix = 'Z' }.suffix.must_equal :Z
90
+ end
91
+ end
92
+
93
+ context "precision=3" do
94
+ it "always fails" do
95
+ -> { subject_3.tap { |s| s.suffix = 'Z' } }.must_raise RuntimeError
96
+ end
97
+ end
98
+ end
99
+
100
+ describe :invert do
101
+ it "must calculate inverse deg correctly" do
102
+ { 0 => 180, 90 => 270, 179 => 359, 180 => 0, 270 => 90, 359 => 179, 360 => 180 }.each do |from, to|
103
+ AIXM.a(from).invert.deg.must_equal to
104
+ end
105
+ end
106
+
107
+ it "must invert left/right suffix" do
108
+ AIXM.a('34L').invert.suffix.must_equal :R
109
+ end
110
+
111
+ it "must leave other suffixes untouched" do
112
+ AIXM.a('35X').invert.suffix.must_equal :X
113
+ end
114
+ end
115
+
116
+ describe :inverse_of? do
117
+ it "must return true for inverse pairs" do
118
+ AIXM.a('34L').inverse_of?(AIXM.a('16R')).must_equal true
119
+ end
120
+
121
+ it "must return false for non-inverse pairs" do
122
+ AIXM.a('34L').inverse_of?(AIXM.a('12L')).must_equal false
123
+ end
124
+ end
125
+
126
+ describe :+ do
127
+ context "precision=2" do
128
+ it "adds degrees as Integer" do
129
+ (subject_2 + 14).must_equal AIXM.a('01')
130
+ (subject_2 + 16).must_equal AIXM.a('02')
131
+ (subject_2 + 370).must_equal AIXM.a('01')
132
+ (AIXM.a('05L') + 20).must_equal AIXM.a('07L')
133
+ end
134
+
135
+ it "adds another angle" do
136
+ (AIXM.a('10') + AIXM.a('08')).must_equal AIXM.a('18')
137
+ end
138
+ end
139
+
140
+ context "precision=3" do
141
+ it "adds degrees as Integer" do
142
+ (subject_3 + 15).must_equal AIXM.a(15)
143
+ (subject_3 + 370).must_equal AIXM.a(10)
144
+ end
145
+ end
146
+ end
147
+
148
+ describe :- do
149
+ context "precision=2" do
150
+ it "subtracts degrees as Integer" do
151
+ (subject_2 - 14).must_equal AIXM.a('35')
152
+ (subject_2 - 16).must_equal AIXM.a('34')
153
+ (AIXM.a('05') - 20).must_equal AIXM.a('03')
154
+ (AIXM.a('05L') - 20).must_equal AIXM.a('03L')
155
+ end
156
+
157
+ it "subtracts another angle" do
158
+ (AIXM.a('10') - AIXM.a('08')).must_equal AIXM.a('02')
159
+ end
160
+ end
161
+
162
+ context "precision=3" do
163
+ it "subtracts degrees as Integer" do
164
+ (subject_3 - 15).must_equal AIXM.a(345)
165
+ (AIXM.a(55) - 20).must_equal AIXM.a(35)
166
+ end
167
+ end
168
+ end
169
+
170
+ describe :== do
171
+ it "recognizes angles with identical deg and suffix as equal" do
172
+ AIXM.a('34L').must_equal AIXM.a('34L')
173
+ end
174
+
175
+ it "recognizes angles with different deg or suffix as unequal" do
176
+ AIXM.a('34L').wont_equal AIXM.a('35L')
177
+ AIXM.a('34L').wont_equal AIXM.a('34R')
178
+ end
179
+
180
+ it "recognizes angles with different precision as unequal" do
181
+ AIXM.a('34').wont_equal AIXM.a(340)
182
+ end
183
+
184
+ it "recognizes objects of different class as unequal" do
185
+ subject_2.wont_equal :oggy
186
+ end
187
+ end
188
+
189
+ describe :hash do
190
+ it "returns an integer" do
191
+ subject_2.hash.must_be_instance_of Integer
192
+ end
193
+
194
+ it "returns different hashes for different precisions" do
195
+ subject_2.hash.wont_equal subject_3.hash
196
+ end
197
+
198
+ it "allows for the use of instances as hash keys" do
199
+ dupe = subject_2.dup
200
+ { subject_2 => true }[dupe].must_equal true
201
+ end
202
+ end
203
+ end
@@ -47,21 +47,6 @@ describe AIXM::Component::Helipad do
47
47
  end
48
48
  end
49
49
 
50
- describe :composition= do
51
- it "fails on invalid values" do
52
- [:foobar, 123].wont_be_written_to subject, :composition
53
- end
54
-
55
- it "accepts nil value" do
56
- [nil].must_be_written_to subject, :composition
57
- end
58
-
59
- it "looks up valid values" do
60
- subject.tap { |s| s.composition = :macadam }.composition.must_equal :macadam
61
- subject.tap { |s| s.composition = :GRADE }.composition.must_equal :graded_earth
62
- end
63
- end
64
-
65
50
  describe :status= do
66
51
  it "fails on invalid values" do
67
52
  [:foobar, 123].wont_be_written_to subject, :status
@@ -100,7 +85,15 @@ describe AIXM::Component::Helipad do
100
85
  <valLen>20</valLen>
101
86
  <valWid>20</valWid>
102
87
  <uomDim>M</uomDim>
103
- <codeComposition>GRASS</codeComposition>
88
+ <codeComposition>CONC</codeComposition>
89
+ <codePreparation>PAVED</codePreparation>
90
+ <codeCondSfc>FAIR</codeCondSfc>
91
+ <valPcnClass>30</valPcnClass>
92
+ <codePcnPavementType>F</codePcnPavementType>
93
+ <codePcnPavementSubgrade>A</codePcnPavementSubgrade>
94
+ <codePcnMaxTirePressure>W</codePcnMaxTirePressure>
95
+ <codePcnEvalMethod>U</codePcnEvalMethod>
96
+ <txtPcnNote>Cracks near the center.</txtPcnNote>
104
97
  <codeSts>OTHER</codeSts>
105
98
  <txtRmk>Authorizaton by AD operator required</txtRmk>
106
99
  </Tla>
@@ -109,7 +102,8 @@ describe AIXM::Component::Helipad do
109
102
 
110
103
  it "builds correct minimal OFMX" do
111
104
  AIXM.ofmx!
112
- subject.z = subject.length = subject.width = subject.composition = subject.status = subject.remarks = nil
105
+ %i(z length width status remarks).each { |a| subject.send(:"#{a}=", nil) }
106
+ %i(composition preparation condition pcn remarks).each { |a| subject.surface.send(:"#{a}=", nil) }
113
107
  subject.to_xml.must_equal <<~END
114
108
  <Tla>
115
109
  <TlaUid>
@@ -7,13 +7,13 @@ describe AIXM::Component::Runway do
7
7
 
8
8
  describe :initialize do
9
9
  it "sets defaults for bidirectional runways" do
10
- subject.forth.name.must_equal AIXM.h('16L')
11
- subject.back.name.must_equal AIXM.h('34R')
10
+ subject.forth.name.must_equal AIXM.a('16L')
11
+ subject.back.name.must_equal AIXM.a('34R')
12
12
  end
13
13
 
14
14
  it "sets defaults for unidirectional runways" do
15
15
  subject = AIXM::Component::Runway.new(name: '30')
16
- subject.forth.name.must_equal AIXM.h('30')
16
+ subject.forth.name.must_equal AIXM.a('30')
17
17
  subject.back.must_be_nil
18
18
  end
19
19
 
@@ -52,21 +52,6 @@ describe AIXM::Component::Runway do
52
52
  end
53
53
  end
54
54
 
55
- describe :composition= do
56
- it "fails on invalid values" do
57
- [:foobar, 123].wont_be_written_to subject, :composition
58
- end
59
-
60
- it "accepts nil value" do
61
- [nil].must_be_written_to subject, :composition
62
- end
63
-
64
- it "looks up valid values" do
65
- subject.tap { |s| s.composition = :macadam }.composition.must_equal :macadam
66
- subject.tap { |s| s.composition = :GRADE }.composition.must_equal :graded_earth
67
- end
68
- end
69
-
70
55
  describe :status= do
71
56
  it "fails on invalid values" do
72
57
  [:foobar, 123].wont_be_written_to subject, :status
@@ -100,7 +85,15 @@ describe AIXM::Component::Runway do
100
85
  <valLen>650</valLen>
101
86
  <valWid>80</valWid>
102
87
  <uomDimRwy>M</uomDimRwy>
103
- <codeComposition>GRADE</codeComposition>
88
+ <codeComposition>ASPH</codeComposition>
89
+ <codePreparation>PAVED</codePreparation>
90
+ <codeCondSfc>GOOD</codeCondSfc>
91
+ <valPcnClass>59</valPcnClass>
92
+ <codePcnPavementType>F</codePcnPavementType>
93
+ <codePcnPavementSubgrade>A</codePcnPavementSubgrade>
94
+ <codePcnMaxTirePressure>W</codePcnMaxTirePressure>
95
+ <codePcnEvalMethod>T</codePcnEvalMethod>
96
+ <txtPcnNote>Paved shoulder on 2.5m on each side of the RWY.</txtPcnNote>
104
97
  <codeSts>CLSD</codeSts>
105
98
  <txtRmk>Markings eroded</txtRmk>
106
99
  </Rwy>
@@ -118,8 +111,9 @@ describe AIXM::Component::Runway do
118
111
  <geoLong>004.75216944E</geoLong>
119
112
  <valTrueBrg>165</valTrueBrg>
120
113
  <valMagBrg>166</valMagBrg>
121
- <valElevTdz>147</valElevTdz>
114
+ <valElevTdz>145</valElevTdz>
122
115
  <uomElevTdz>FT</uomElevTdz>
116
+ <codeVfrPattern>E</codeVfrPattern>
123
117
  <txtRmk>forth remarks</txtRmk>
124
118
  </Rdn>
125
119
  <Rdd>
@@ -154,6 +148,9 @@ describe AIXM::Component::Runway do
154
148
  <geoLong>004.75645556E</geoLong>
155
149
  <valTrueBrg>345</valTrueBrg>
156
150
  <valMagBrg>346</valMagBrg>
151
+ <valElevTdz>147</valElevTdz>
152
+ <uomElevTdz>FT</uomElevTdz>
153
+ <codeVfrPattern>L</codeVfrPattern>
157
154
  <txtRmk>back remarks</txtRmk>
158
155
  </Rdn>
159
156
  <Rdd>
@@ -179,7 +176,8 @@ describe AIXM::Component::Runway do
179
176
 
180
177
  it "builds correct minimal OFMX" do
181
178
  AIXM.ofmx!
182
- %i(length width composition status remarks).each { |a| subject.send(:"#{a}=", nil) }
179
+ %i(length width status remarks).each { |a| subject.send(:"#{a}=", nil) }
180
+ %i(composition preparation condition pcn remarks).each { |a| subject.surface.send(:"#{a}=", nil) }
183
181
  subject.to_xml.must_equal <<~END
184
182
  <Rwy>
185
183
  <RwyUid>
@@ -203,8 +201,9 @@ describe AIXM::Component::Runway do
203
201
  <geoLong>004.75216944E</geoLong>
204
202
  <valTrueBrg>165</valTrueBrg>
205
203
  <valMagBrg>166</valMagBrg>
206
- <valElevTdz>147</valElevTdz>
204
+ <valElevTdz>145</valElevTdz>
207
205
  <uomElevTdz>FT</uomElevTdz>
206
+ <codeVfrPattern>E</codeVfrPattern>
208
207
  <txtRmk>forth remarks</txtRmk>
209
208
  </Rdn>
210
209
  <Rdd>
@@ -239,6 +238,9 @@ describe AIXM::Component::Runway do
239
238
  <geoLong>004.75645556E</geoLong>
240
239
  <valTrueBrg>345</valTrueBrg>
241
240
  <valMagBrg>346</valMagBrg>
241
+ <valElevTdz>147</valElevTdz>
242
+ <uomElevTdz>FT</uomElevTdz>
243
+ <codeVfrPattern>L</codeVfrPattern>
242
244
  <txtRmk>back remarks</txtRmk>
243
245
  </Rdn>
244
246
  <Rdd>
@@ -277,18 +279,14 @@ describe AIXM::Component::Runway::Direction do
277
279
 
278
280
  it "overwrites preset name" do
279
281
  subject.name.to_s.must_equal '16L'
280
- subject.name = AIXM.h('34L')
282
+ subject.name = AIXM.a('34L')
281
283
  subject.name.to_s.must_equal '34L'
282
284
  end
283
285
  end
284
286
 
285
287
  describe :geographic_orientation= do
286
288
  it "fails on invalid values" do
287
- [:foobar, -1, 0, 361].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
289
+ [:foobar, -1, 10].wont_be_written_to subject, :geographic_orientation
292
290
  end
293
291
  end
294
292
 
@@ -320,14 +318,29 @@ describe AIXM::Component::Runway::Direction do
320
318
  end
321
319
  end
322
320
 
321
+ describe :vfr_pattern= do
322
+ it "fails on invalid values" do
323
+ [:foobar, 123].wont_be_written_to subject, :vfr_pattern
324
+ end
325
+
326
+ it "accepts nil value" do
327
+ [nil].must_be_written_to subject, :vfr_pattern
328
+ end
329
+
330
+ it "looks up valid values" do
331
+ subject.tap { |s| s.vfr_pattern = :left }.vfr_pattern.must_equal :left
332
+ subject.tap { |s| s.vfr_pattern = :E }.vfr_pattern.must_equal :left_or_right
333
+ end
334
+ end
335
+
323
336
  describe :remarks= do
324
337
  macro :remarks
325
338
  end
326
339
 
327
340
  describe :magnetic_orientation do
328
341
  it "is calculated correctly" do
329
- subject.geographic_orientation = 16
330
- subject.magnetic_orientation.must_equal 17
342
+ subject.geographic_orientation = AIXM.a(16)
343
+ subject.magnetic_orientation.must_equal AIXM.a(17)
331
344
  end
332
345
  end
333
346
 
@@ -349,8 +362,9 @@ describe AIXM::Component::Runway::Direction do
349
362
  <geoLong>004.75216944E</geoLong>
350
363
  <valTrueBrg>165</valTrueBrg>
351
364
  <valMagBrg>166</valMagBrg>
352
- <valElevTdz>147</valElevTdz>
365
+ <valElevTdz>145</valElevTdz>
353
366
  <uomElevTdz>FT</uomElevTdz>
367
+ <codeVfrPattern>E</codeVfrPattern>
354
368
  <txtRmk>forth remarks</txtRmk>
355
369
  </Rdn>
356
370
  <Rdd>
@@ -376,7 +390,7 @@ describe AIXM::Component::Runway::Direction do
376
390
 
377
391
  it "builds correct minimal OFMX" do
378
392
  AIXM.ofmx!
379
- %i(geographic_orientation z displaced_threshold remarks).each { |a| subject.send(:"#{a}=", nil) }
393
+ %i(geographic_orientation z displaced_threshold vfr_pattern remarks).each { |a| subject.send(:"#{a}=", nil) }
380
394
  subject.to_xml.must_equal <<~END
381
395
  <Rdn>
382
396
  <RdnUid>