aixm 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d3f7a1a1f47a40725a1f7444d97ca6f11acf3c1805d3d2521d9c79c72494abe5
4
- data.tar.gz: a45d00f0667b808e4e44f5a065392c4d0f6a00fbcd7e085c8bab072288fcdf7b
3
+ metadata.gz: a4e0b32c04cba8526128ce56c60abf4343b7ac8f2e8a3e8252e1046ce3ccbfe3
4
+ data.tar.gz: c88875a5a1921f90a1d4055302469c1608ae610bce5b513c9a3e2d50ed32f842
5
5
  SHA512:
6
- metadata.gz: e58d749b2c1face5c6ec67c1e0f23e5fba2ebca6e3d111cc5075ce561c6c7d6b022585f2cdf0ace8e9320f7b1684385f7ab7bb7c1ca80ecf485afb19e7257cba
7
- data.tar.gz: 5888395288986381ed501d7b7a488729e6be98dc65ed1e77c1bb9522022b95cc7d62f13031272edb86c86a3ce41c301917c30e5cce1e88756d88688b8ca2bd87
6
+ metadata.gz: e0f11994c12259bee9a013b92162ed14f763206855adfb5f0d25fc45807a885da5b330010c1c7768590cd3cca19c260976c68674b0354091b2ef64288a70914e
7
+ data.tar.gz: 800ef3ea1d7e298281454957f3471e06452d9a23a4333c0f978c24590cd9fc140b21948d7588a07a896995731897810bffc317ae610e39822b6e27e51554cb10
data/.travis.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  language: ruby
3
3
  rvm:
4
- - 2.5.0
5
- before_install: gem install bundler -v 1.16.1
4
+ - 2.5.3
5
+ before_install: gem install bundler -v 1.17.1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,12 @@
1
+ ## 0.3.3
2
+
3
+ #### Additions
4
+ * `AIXM::H` (heading)
5
+
6
+ #### Changes
7
+ * Updated OFMX schema URI
8
+ * Added `eql?` and `hash` to `AIXM::XY|Z|D|H|F` to allow for instances of these classes to be used as Hash keys.
9
+
1
10
  ## 0.3.2
2
11
 
3
12
  #### Additions
@@ -106,9 +106,11 @@ module AIXM
106
106
 
107
107
  # @return [String]
108
108
  def inspect
109
- %Q(#<#{self.class} class=#{@klass.inspect}>)
109
+ %Q(#<#{original_class} class=#{@klass.inspect}>)
110
110
  end
111
111
 
112
+ alias_method :original_class, :class
113
+
112
114
  # @!attribute class
113
115
  # @return [Symbol] class of layer (see {CLASSES})
114
116
  def class
@@ -21,7 +21,7 @@ module AIXM
21
21
  # runway.composition = COMPOSITIONS or nil
22
22
  # runway.status = STATUSES or nil
23
23
  # runway.remarks = String or nil
24
- # runway.forth.name = String # preset based on the runway name
24
+ # runway.forth.name = AIXM.h # preset based on the runway name
25
25
  # runway.forth.geographic_orientation = Integer or nil # degrees
26
26
  # runway.forth.xy = AIXM.xy
27
27
  # runway.forth.z = AIXM.z or nil
@@ -31,15 +31,15 @@ module AIXM
31
31
  # @example Bidirectional runway
32
32
  # runway = AIXM.runway(name: '16L/34R')
33
33
  # runway.name # => '16L/34R'
34
- # runway.forth.name = '16L'
34
+ # runway.forth.name.to_s = '16L'
35
35
  # runway.forth.geographic_orientation = 165
36
- # runway.back.name = '34R'
36
+ # runway.back.name.to_s = '34R'
37
37
  # runway.back.geographic_orientation = 345
38
38
  #
39
39
  # @example Unidirectional runway:
40
40
  # runway = AIXM.runway(name: '16L')
41
41
  # runway.name # => '16L'
42
- # runway.forth.name = '16L'
42
+ # runway.forth.name.to_s = '16L'
43
43
  # runway.forth.geographic_orientation = 165
44
44
  # runway.back = nil
45
45
  #
@@ -97,8 +97,9 @@ module AIXM
97
97
  def initialize(name:)
98
98
  self.name = name
99
99
  @name.split('/').tap do |forth, back|
100
- @forth = Direction.new(runway: self, name: forth)
101
- @back = Direction.new(runway: self, name: back) if back
100
+ @forth = Direction.new(runway: self, name: AIXM.h(forth))
101
+ @back = Direction.new(runway: self, name: AIXM.h(back)) if back
102
+ fail(ArgumentError, "invalid name") unless !@back || @back.name.inverse_of?(@forth.name)
102
103
  end
103
104
  end
104
105
 
@@ -183,7 +184,7 @@ module AIXM
183
184
  # @return [AIXM::Component::Runway] runway the runway direction is further describing
184
185
  attr_reader :runway
185
186
 
186
- # @return [String] partial name of runway (e.g. "12" or "16L")
187
+ # @return [AIXM::H] partial name of runway (e.g. "12" or "16L")
187
188
  attr_reader :name
188
189
 
189
190
  # @return [Integer, nil] geographic orientation (true bearing) in degrees
@@ -219,15 +220,15 @@ module AIXM
219
220
  private :runway
220
221
 
221
222
  def name=(value)
222
- fail(ArgumentError, "invalid name") unless value.is_a? String
223
- @name = value.uptrans
223
+ fail(ArgumentError, "invalid name") unless value.is_a? AIXM::H
224
+ @name = value
224
225
  end
225
226
 
226
227
  def geographic_orientation=(value)
227
228
  return @geographic_orientation = nil if value.nil?
228
229
  fail(ArgumentError, "invalid geographic orientation") unless value.is_a? Numeric
229
230
  @geographic_orientation = value.to_i
230
- fail(ArgumentError, "invalid geographic orientation") unless (0..359).include? @geographic_orientation
231
+ fail(ArgumentError, "invalid geographic orientation") unless (1..360).include? @geographic_orientation
231
232
  end
232
233
 
233
234
  def xy=(value)
data/lib/aixm/config.rb CHANGED
@@ -9,7 +9,7 @@ module AIXM
9
9
  },
10
10
  ofmx: {
11
11
  version: '0',
12
- namespace: 'http://openflightmaps.org/schema/0/OFMX-Snapshot.xsd',
12
+ namespace: 'http://schema.openflightmaps.org/0/OFMX-Snapshot.xsd',
13
13
  xsd: Pathname(__dir__).join('..', '..', 'schemas', 'ofmx', '0', 'OFMX-Snapshot.xsd'),
14
14
  root: 'OFMX-Snapshot'
15
15
  }
data/lib/aixm/d.rb CHANGED
@@ -47,10 +47,6 @@ module AIXM
47
47
  fail(ArgumentError, "invalid unit") unless UNITS.has_key? @unit
48
48
  end
49
49
 
50
- def <=>(other)
51
- to_m.dist <=> other.to_m.dist
52
- end
53
-
54
50
  # @!method to_ft
55
51
  # @!method to_km
56
52
  # @!method to_m
@@ -62,5 +58,24 @@ module AIXM
62
58
  self.class.new((dist * UNITS[unit][target_unit]).round(8), target_unit)
63
59
  end
64
60
  end
61
+
62
+ # @see Object#<=>
63
+ # @return [Integer]
64
+ def <=>(other)
65
+ to_m.dist <=> other.to_m.dist
66
+ end
67
+
68
+ # @see Object#==
69
+ # @return [Boolean]
70
+ def ==(other)
71
+ self.class === other && (self <=> other).zero?
72
+ end
73
+ alias_method :eql?, :==
74
+
75
+ # @see Object#hash
76
+ # @return [Integer]
77
+ def hash
78
+ to_s.hash
79
+ end
65
80
  end
66
81
  end
data/lib/aixm/f.rb CHANGED
@@ -40,14 +40,22 @@ module AIXM
40
40
  fail(ArgumentError, "invalid unit") unless UNITS.include? @unit
41
41
  end
42
42
 
43
+ # @return [Boolean] whether this frequency is part of a frequency band
44
+ def between?(lower_freq, upper_freq, unit)
45
+ freq.between?(lower_freq, upper_freq) && self.unit == unit
46
+ end
47
+
48
+ # @see Object#==
43
49
  # @return [Boolean]
44
50
  def ==(other)
45
- other.is_a?(self.class) && freq == other.freq && unit == other.unit
51
+ self.class === other && freq == other.freq && unit == other.unit
46
52
  end
53
+ alias_method :eql?, :==
47
54
 
48
- # @return [Boolean] whether this frequency is part of a frequency band
49
- def between?(lower_freq, upper_freq, unit)
50
- freq.between?(lower_freq, upper_freq) && self.unit == unit
55
+ # @see Object#hash
56
+ # @return [Integer]
57
+ def hash
58
+ to_s.hash
51
59
  end
52
60
 
53
61
  end
data/lib/aixm/feature.rb CHANGED
@@ -19,7 +19,7 @@ module AIXM
19
19
 
20
20
  # @return [Boolean]
21
21
  def ==(other)
22
- other.is_a?(self.class) && self.to_uid == other.to_uid
22
+ self.class === other && self.to_uid == other.to_uid
23
23
  end
24
24
  end
25
25
 
data/lib/aixm/h.rb ADDED
@@ -0,0 +1,87 @@
1
+ using AIXM::Refinements
2
+
3
+ module AIXM
4
+
5
+ # Heading of an aircraft or runway
6
+ #
7
+ # @example
8
+ # AIXM.h(12)
9
+ # AIXM.h('12')
10
+ # AIXM.h('34L')
11
+ # AIXM.h('05X')
12
+ class H
13
+ SUFFIX_INVERSIONS = {
14
+ R: :L,
15
+ L: :R
16
+ }.freeze
17
+
18
+ # @return [Integer] heading
19
+ attr_reader :deg
20
+
21
+ # @return [Symbol, nil] suffix
22
+ attr_reader :suffix
23
+
24
+ def initialize(deg_and_suffix)
25
+ fail(ArgumentError, "invalid heading") unless deg_and_suffix.to_s =~ /\A(\d+)([A-Z]+)?\z/
26
+ self.deg, self.suffix = $1.to_i, $2
27
+ end
28
+
29
+ # @return [String]
30
+ def inspect
31
+ %Q(#<#{self.class} #{to_s}>)
32
+ end
33
+
34
+ # @return [String] human readable representation (e.g. "05" or "34L")
35
+ def to_s
36
+ [('%02d' % deg), suffix].map(&:to_s).join
37
+ end
38
+
39
+ def deg=(value)
40
+ fail(ArgumentError, "invalid deg") unless value.between?(1, 36)
41
+ @deg = value
42
+ end
43
+
44
+ def suffix=(value)
45
+ fail(ArgumentError, "invalid suffix") unless value.nil? || value.to_s =~ /\A[A-Z]+\z/
46
+ @suffix = value&.to_s&.to_sym
47
+ end
48
+
49
+ # Invert a heading by 180 degrees
50
+ #
51
+ # @example
52
+ # AIXM.h('12').invert # => AIXM.h(30)
53
+ # AIXM.h('34L').invert # => AIXM.h(16, 'R')
54
+ # AIXM.h('33X').invert # => AIXM.h(17, 'bravo')
55
+ #
56
+ # @return [AIXM::H] inverted heading
57
+ def invert
58
+ AIXM.h([(((deg + 17) % 36) + 1), SUFFIX_INVERSIONS.fetch(suffix, suffix)].join)
59
+ end
60
+
61
+ # Check whether +other+ heading is the inverse
62
+ #
63
+ # @example
64
+ # AIXM.h('12').inverse_of? AIXM.h('30') # => true
65
+ # AIXM.h('34L').inverse_of? AIXM.h('16R') # => true
66
+ # AIXM.h('16R').inverse_of? AIXM.h('16L') # => false
67
+ #
68
+ # @return [AIXM::H] inverted heading
69
+ def inverse_of?(other)
70
+ invert == other
71
+ end
72
+
73
+ # @see Object#==
74
+ # @return [Boolean]
75
+ def ==(other)
76
+ self.class === other && deg == other.deg && suffix == other.suffix
77
+ end
78
+ alias_method :eql?, :==
79
+
80
+ # @see Object#hash
81
+ # @return [Integer]
82
+ def hash
83
+ to_s.hash
84
+ end
85
+ end
86
+
87
+ end
@@ -33,7 +33,7 @@ module AIXM
33
33
  #
34
34
  # @example
35
35
  # ['foo', :bar, nil, [123]].to_uuid
36
- # # => "f3920098"
36
+ # # => "a68e9aae-81ef-c6f1-d954-2eefe2820c50"
37
37
  #
38
38
  # @note This is a refinement for +Array+
39
39
  # @return [String] UUID version 3
@@ -6,6 +6,7 @@ module AIXM
6
6
  z: Z,
7
7
  d: D,
8
8
  f: F,
9
+ h: H,
9
10
  organisation: Feature::Organisation,
10
11
  unit: Feature::Unit,
11
12
  service: Component::Service,
data/lib/aixm/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module AIXM
2
- VERSION = "0.3.2".freeze
2
+ VERSION = "0.3.3".freeze
3
3
  end
data/lib/aixm/xy.rb CHANGED
@@ -6,12 +6,13 @@ module AIXM
6
6
  #
7
7
  # ===Recognized notations:
8
8
  # * DD - examples: 12.12345678 (north or east), -12.12345678 (south or west)
9
- # * DMS - examples: 11°22'33.44"N, 1112233.44W
9
+ # * DMS - examples: 11°22'33.44"N, 1112233.44W,
10
10
  #
11
11
  # @example All of the below are equivalent
12
+ # AIXM.xy(lat: 11.375955555555556, long: -111.37595555555555)
12
13
  # AIXM.xy(lat: %q(11°22'33.44"), long: %q(-111°22'33.44"))
14
+ # AIXM.xy(lat: %q(11°22'33.44N"), long: %q(111°22'33.44W"))
13
15
  # AIXM.xy(lat: '112233.44N', long: '1112233.44W')
14
- # AIXM.xy(lat: 11.375955555555556, long: -111.37595555555555)
15
16
  #
16
17
  # @see https://github.com/openflightmaps/ofmx/wiki/Coordinates
17
18
  class XY
@@ -63,11 +64,6 @@ module AIXM
63
64
  end
64
65
  end
65
66
 
66
- # @return [Boolean]
67
- def ==(other)
68
- other.is_a?(self.class) && lat == other.lat && long == other.long
69
- end
70
-
71
67
  # @return [AIXM::D] distance as calculated by use of the Haversine formula
72
68
  def distance(other)
73
69
  if self == other
@@ -84,6 +80,19 @@ module AIXM
84
80
  end
85
81
  end
86
82
 
83
+ # @see Object#==
84
+ # @return [Boolean]
85
+ def ==(other)
86
+ self.class === other && lat == other.lat && long == other.long
87
+ end
88
+ alias_method :eql?, :==
89
+
90
+ # @see Object#hash
91
+ # @return [Integer]
92
+ def hash
93
+ to_s.hash
94
+ end
95
+
87
96
  private
88
97
 
89
98
  def float_for(value)
data/lib/aixm/z.rb CHANGED
@@ -46,11 +46,6 @@ module AIXM
46
46
  fail(ArgumentError, "invalid code") unless CODES.include? @code
47
47
  end
48
48
 
49
- # @return [Boolean]
50
- def ==(other)
51
- other.is_a?(self.class) && alt == other.alt && code == other.code
52
- end
53
-
54
49
  # @example
55
50
  # z = AIXM.z(123, :qnh)
56
51
  # z.qnh? # => true
@@ -74,6 +69,19 @@ module AIXM
74
69
  qne? ? :fl : :ft
75
70
  end
76
71
 
72
+ # @see Object#==
73
+ # @return [Boolean]
74
+ def ==(other)
75
+ self.class === other && alt == other.alt && code == other.code
76
+ end
77
+ alias_method :eql?, :==
78
+
79
+ # @see Object#hash
80
+ # @return [Integer]
81
+ def hash
82
+ to_s.hash
83
+ end
84
+
77
85
  end
78
86
 
79
87
  end
data/lib/aixm.rb CHANGED
@@ -16,6 +16,7 @@ require_relative 'aixm/xy'
16
16
  require_relative 'aixm/z'
17
17
  require_relative 'aixm/d'
18
18
  require_relative 'aixm/f'
19
+ require_relative 'aixm/h'
19
20
 
20
21
  require_relative 'aixm/component'
21
22
  require_relative 'aixm/component/service'
data/spec/factory.rb CHANGED
@@ -20,6 +20,10 @@ module AIXM
20
20
  AIXM.f(123.35, :mhz)
21
21
  end
22
22
 
23
+ def h
24
+ AIXM.h('34L')
25
+ end
26
+
23
27
  # Components
24
28
 
25
29
  def timetable
@@ -7,15 +7,19 @@ 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 '16L'
11
- subject.back.name.must_equal '34R'
10
+ subject.forth.name.must_equal AIXM.h('16L')
11
+ subject.back.name.must_equal AIXM.h('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 '30'
16
+ subject.forth.name.must_equal AIXM.h('30')
17
17
  subject.back.must_be_nil
18
18
  end
19
+
20
+ it "fails on non-inverse bidirectional runways" do
21
+ -> { AIXM.runway(name: '16L/14R') }.must_raise ArgumentError
22
+ end
19
23
  end
20
24
 
21
25
  describe :name= do
@@ -267,16 +271,20 @@ describe AIXM::Component::Runway::Direction do
267
271
  end
268
272
 
269
273
  describe :name= do
274
+ it "fails on invalid values" do
275
+ [nil, :foobar, '16R'].wont_be_written_to subject, :name
276
+ end
277
+
270
278
  it "overwrites preset name" do
271
- subject.name.must_equal '16L'
272
- subject.name = 'x01x'
273
- subject.name.must_equal 'X01X'
279
+ subject.name.to_s.must_equal '16L'
280
+ subject.name = AIXM.h('34L')
281
+ subject.name.to_s.must_equal '34L'
274
282
  end
275
283
  end
276
284
 
277
285
  describe :geographic_orientation= do
278
286
  it "fails on invalid values" do
279
- [:foobar, -1, 360].wont_be_written_to subject, :geographic_orientation
287
+ [:foobar, -1, 0, 361].wont_be_written_to subject, :geographic_orientation
280
288
  end
281
289
 
282
290
  it "converts valid Numeric values to integer" do
@@ -25,32 +25,6 @@ describe AIXM::D do
25
25
  end
26
26
  end
27
27
 
28
- describe :<=> do
29
- it "recognizes objects with identical unit and distance as equal" do
30
- a = AIXM.d(123, :m)
31
- b = AIXM.d(123.0, 'M')
32
- a.must_equal b
33
- end
34
-
35
- it "recognizes objects with different units and converted distance as equal" do
36
- a = AIXM.d(123, :m)
37
- b = AIXM.d(403.54330709, 'FT')
38
- a.must_equal b
39
- end
40
-
41
- it "recognizes objects with different units and identical distance as unequal" do
42
- a = AIXM.d(123, :m)
43
- b = AIXM.d(123, :ft)
44
- a.wont_equal b
45
- end
46
-
47
- it "recognizes objects of different class as unequal" do
48
- a = AIXM.d(123, :m)
49
- b = :oggy
50
- a.wont_equal b
51
- end
52
- end
53
-
54
28
  describe :to_ft do
55
29
  it "leaves feet untouched" do
56
30
  subject = AIXM.d(2, :ft)
@@ -127,4 +101,40 @@ describe AIXM::D do
127
101
  end
128
102
  end
129
103
 
104
+ describe :<=> do
105
+ it "recognizes objects with identical unit and distance as equal" do
106
+ a = AIXM.d(123, :m)
107
+ b = AIXM.d(123.0, 'M')
108
+ a.must_equal b
109
+ end
110
+
111
+ it "recognizes objects with different units and converted distance as equal" do
112
+ a = AIXM.d(123, :m)
113
+ b = AIXM.d(403.54330709, 'FT')
114
+ a.must_equal b
115
+ end
116
+
117
+ it "recognizes objects with different units and identical distance as unequal" do
118
+ a = AIXM.d(123, :m)
119
+ b = AIXM.d(123, :ft)
120
+ a.wont_equal b
121
+ end
122
+
123
+ it "recognizes objects of different class as unequal" do
124
+ a = AIXM.d(123, :m)
125
+ b = :oggy
126
+ a.wont_equal b
127
+ end
128
+ end
129
+
130
+ describe :hash do
131
+ it "returns an integer" do
132
+ subject.hash.must_be_instance_of Integer
133
+ end
134
+
135
+ it "allows for the use of instances as hash keys" do
136
+ dupe = subject.dup
137
+ { subject => true }[dupe].must_equal true
138
+ end
139
+ end
130
140
  end
@@ -727,7 +727,7 @@ describe AIXM::Document do
727
727
  it "builds correct OFMX" do
728
728
  subject.to_xml.must_equal <<~"END"
729
729
  <?xml version="1.0" encoding="UTF-8"?>
730
- <OFMX-Snapshot xmlns:xsi="http://openflightmaps.org/schema/0/OFMX-Snapshot.xsd" version="0" origin="rubygem aixm-#{AIXM::VERSION}" region="LF" namespace="00000000-0000-0000-0000-000000000000" created="2018-01-01T12:00:00+01:00" effective="2018-01-01T12:00:00+01:00">
730
+ <OFMX-Snapshot xmlns:xsi="http://schema.openflightmaps.org/0/OFMX-Snapshot.xsd" version="0" origin="rubygem aixm-#{AIXM::VERSION}" region="LF" namespace="00000000-0000-0000-0000-000000000000" created="2018-01-01T12:00:00+01:00" effective="2018-01-01T12:00:00+01:00">
731
731
  <!-- Organisation: FRANCE -->
732
732
  <Org source="LF|GEN|0.0 FACTORY|0|0">
733
733
  <OrgUid>
@@ -25,6 +25,23 @@ describe AIXM::F do
25
25
  end
26
26
  end
27
27
 
28
+ describe :between? do
29
+ subject do
30
+ AIXM.f(100, :mhz)
31
+ end
32
+
33
+ it "detect frequencies within a frequency band" do
34
+ subject.between?(90, 110, :mhz).must_equal true
35
+ subject.between?(90, 100, :mhz).must_equal true
36
+ subject.between?(100.0, 100.1, :mhz).must_equal true
37
+ end
38
+
39
+ it "detect frequencies outside of a frequency band" do
40
+ subject.between?(90, 110, :khz).must_equal false
41
+ subject.between?(90, 95, :mhz).must_equal false
42
+ end
43
+ end
44
+
28
45
  describe :== do
29
46
  it "recognizes objects with identical frequency and unit as equal" do
30
47
  a = AIXM.f(123.0, :mhz)
@@ -45,21 +62,14 @@ describe AIXM::F do
45
62
  end
46
63
  end
47
64
 
48
- describe :between? do
49
- subject do
50
- AIXM.f(100, :mhz)
65
+ describe :hash do
66
+ it "returns an integer" do
67
+ subject.hash.must_be_instance_of Integer
51
68
  end
52
69
 
53
- it "detect frequencies within a frequency band" do
54
- subject.between?(90, 110, :mhz).must_equal true
55
- subject.between?(90, 100, :mhz).must_equal true
56
- subject.between?(100.0, 100.1, :mhz).must_equal true
57
- end
58
-
59
- it "detect frequencies outside of a frequency band" do
60
- subject.between?(90, 110, :khz).must_equal false
61
- subject.between?(90, 95, :mhz).must_equal false
70
+ it "allows for the use of instances as hash keys" do
71
+ dupe = subject.dup
72
+ { subject => true }[dupe].must_equal true
62
73
  end
63
74
  end
64
-
65
75
  end
@@ -0,0 +1,113 @@
1
+ require_relative '../../spec_helper'
2
+
3
+ describe AIXM::H do
4
+ subject do
5
+ AIXM::Factory.h
6
+ end
7
+
8
+ describe :initialize do
9
+ it "fails on invalid values" do
10
+ -> { AIXM.h('foobar') }.must_raise ArgumentError
11
+ end
12
+
13
+ it "parses valid values" do
14
+ AIXM.h('34L').tap do |h|
15
+ h.deg.must_equal 34
16
+ h.suffix.must_equal :L
17
+ end
18
+ AIXM.h(12).tap do |h|
19
+ h.deg.must_equal 12
20
+ h.suffix.must_be :nil?
21
+ end
22
+ end
23
+ end
24
+
25
+ describe :to_s do
26
+ it "pads deg with zero and concats suffix" do
27
+ AIXM.h(5).to_s.must_equal '05'
28
+ AIXM.h('5L').to_s.must_equal '05L'
29
+ AIXM.h('16L').to_s.must_equal '16L'
30
+ end
31
+ end
32
+
33
+ describe :deg= do
34
+ it "fails on invalid values" do
35
+ [:foobar, '1', 0, 37].wont_be_written_to subject, :deg
36
+ end
37
+
38
+ it "accepts valid values" do
39
+ (1..36).to_a.must_be_written_to subject, :deg
40
+ end
41
+ end
42
+
43
+ describe :suffix= do
44
+ it "fails on invalid values" do
45
+ [123, 'r'].wont_be_written_to subject, :suffix
46
+ end
47
+
48
+ it "accepts nil value" do
49
+ [nil].must_be_written_to subject, :suffix
50
+ end
51
+
52
+ it "symbolizes valid values" do
53
+ subject.tap { |s| s.suffix = 'Z' }.suffix.must_equal :Z
54
+ end
55
+ end
56
+
57
+ describe :invert do
58
+ it "must calculate inverse deg correctly" do
59
+ {
60
+ 1 => 19, 2 => 20, 3 => 21, 4 => 22, 5 => 23, 6 => 24, 7 => 25, 8 => 26, 9 => 27,
61
+ 10 => 28, 11 => 29, 12 => 30, 13 => 31, 14 => 32, 15 => 33, 16 => 34, 17 => 35, 18 => 36,
62
+ 19 => 1, 20 => 2, 21 => 3, 22 => 4, 23 => 5, 24 => 6, 25 => 7, 26 => 8, 27 => 9,
63
+ 28 => 10, 29 => 11, 30 => 12, 31 => 13, 32 => 14, 33 => 15, 34 => 16, 35 => 17, 36 => 18
64
+ }.each do |from, to|
65
+ AIXM.h(from).invert.deg.must_equal to
66
+ end
67
+ end
68
+
69
+ it "must invert left/right suffix" do
70
+ AIXM.h('34L').invert.suffix.must_equal :R
71
+ end
72
+
73
+ it "must leave other suffixes untouched" do
74
+ AIXM.h('35X').invert.suffix.must_equal :X
75
+ end
76
+ end
77
+
78
+ describe :inverse_of? do
79
+ it "must return true for inverse pairs" do
80
+ AIXM.h('34L').inverse_of?(AIXM.h('16R')).must_equal true
81
+ end
82
+
83
+ it "must return false for non-inverse pairs" do
84
+ AIXM.h('34L').inverse_of?(AIXM.h('12L')).must_equal false
85
+ end
86
+ end
87
+
88
+ describe :== do
89
+ it "recognizes objects with identical deg and suffix as equal" do
90
+ AIXM.h('34L').must_equal AIXM.h('34L')
91
+ end
92
+
93
+ it "recognizes objects with different deg or suffix as unequal" do
94
+ AIXM.h('34L').wont_equal AIXM.h('35L')
95
+ AIXM.h('34L').wont_equal AIXM.h('34R')
96
+ end
97
+
98
+ it "recognizes objects of different class as unequal" do
99
+ subject.wont_equal :oggy
100
+ end
101
+ end
102
+
103
+ describe :hash do
104
+ it "returns an integer" do
105
+ subject.hash.must_be_instance_of Integer
106
+ end
107
+
108
+ it "allows for the use of instances as hash keys" do
109
+ dupe = subject.dup
110
+ { subject => true }[dupe].must_equal true
111
+ end
112
+ end
113
+ end
@@ -111,6 +111,21 @@ describe AIXM::XY do
111
111
  end
112
112
  end
113
113
 
114
+ describe :distance do
115
+ subject do
116
+ AIXM.xy(lat: %q(44°00'07.63"N), long: %q(004°45'07.81"E))
117
+ end
118
+
119
+ it "calculates the distance between the same point as zero" do
120
+ subject.distance(subject).must_equal AIXM.d(0, :m)
121
+ end
122
+
123
+ it "calculates the distance between two points correctly" do
124
+ other = AIXM.xy(lat: %q(43°59'25.31"N), long: %q(004°45'23.24"E))
125
+ subject.distance(other).must_equal AIXM.d(1351, :m)
126
+ end
127
+ end
128
+
114
129
  describe :== do
115
130
  it "recognizes objects with identical latitude and longitude as equal" do
116
131
  a = AIXM.xy(lat: "112233N", long: "0223344E")
@@ -131,18 +146,14 @@ describe AIXM::XY do
131
146
  end
132
147
  end
133
148
 
134
- describe :distance do
135
- subject do
136
- AIXM.xy(lat: %q(44°00'07.63"N), long: %q(004°45'07.81"E))
137
- end
138
-
139
- it "calculates the distance between the same point as zero" do
140
- subject.distance(subject).must_equal AIXM.d(0, :m)
149
+ describe :hash do
150
+ it "returns an integer" do
151
+ subject.hash.must_be_instance_of Integer
141
152
  end
142
153
 
143
- it "calculates the distance between two points correctly" do
144
- other = AIXM.xy(lat: %q(43°59'25.31"N), long: %q(004°45'23.24"E))
145
- subject.distance(other).must_equal AIXM.d(1351, :m)
154
+ it "allows for the use of instances as hash keys" do
155
+ dupe = subject.dup
156
+ { subject => true }[dupe].must_equal true
146
157
  end
147
158
  end
148
159
  end
@@ -25,26 +25,6 @@ describe AIXM::Z do
25
25
  end
26
26
  end
27
27
 
28
- describe :== do
29
- it "recognizes objects with identical altitude and Q code as equal" do
30
- a = AIXM.z(111, :qnh)
31
- b = AIXM.z(111, :qnh)
32
- a.must_equal b
33
- end
34
-
35
- it "recognizes objects with different altitude or Q code as unequal" do
36
- a = AIXM.z(111, :qnh)
37
- b = AIXM.z(222, :qnh)
38
- a.wont_equal b
39
- end
40
-
41
- it "recognizes objects of different class as unequal" do
42
- a = AIXM.z(111, :qnh)
43
- b = :oggy
44
- a.wont_equal b
45
- end
46
- end
47
-
48
28
  describe :qfe? do
49
29
  it "recognizes same Q code" do
50
30
  AIXM.z(111, :qfe).must_be :qfe?
@@ -70,4 +50,35 @@ describe AIXM::Z do
70
50
  AIXM.z(0, :qne).unit.must_equal :fl
71
51
  end
72
52
  end
53
+
54
+ describe :== do
55
+ it "recognizes objects with identical altitude and Q code as equal" do
56
+ a = AIXM.z(111, :qnh)
57
+ b = AIXM.z(111, :qnh)
58
+ a.must_equal b
59
+ end
60
+
61
+ it "recognizes objects with different altitude or Q code as unequal" do
62
+ a = AIXM.z(111, :qnh)
63
+ b = AIXM.z(222, :qnh)
64
+ a.wont_equal b
65
+ end
66
+
67
+ it "recognizes objects of different class as unequal" do
68
+ a = AIXM.z(111, :qnh)
69
+ b = :oggy
70
+ a.wont_equal b
71
+ end
72
+ end
73
+
74
+ describe :hash do
75
+ it "returns an integer" do
76
+ subject.hash.must_be_instance_of Integer
77
+ end
78
+
79
+ it "allows for the use of instances as hash keys" do
80
+ dupe = subject.dup
81
+ { subject => true }[dupe].must_equal true
82
+ end
83
+ end
73
84
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aixm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Schwyn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-10-30 00:00:00.000000000 Z
11
+ date: 2018-11-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -201,6 +201,7 @@ files:
201
201
  - lib/aixm/feature/obstacle_group.rb
202
202
  - lib/aixm/feature/organisation.rb
203
203
  - lib/aixm/feature/unit.rb
204
+ - lib/aixm/h.rb
204
205
  - lib/aixm/refinements.rb
205
206
  - lib/aixm/shortcuts.rb
206
207
  - lib/aixm/version.rb
@@ -246,6 +247,7 @@ files:
246
247
  - spec/lib/aixm/feature/organisation_spec.rb
247
248
  - spec/lib/aixm/feature/unit_spec.rb
248
249
  - spec/lib/aixm/feature_spec.rb
250
+ - spec/lib/aixm/h_spec.rb
249
251
  - spec/lib/aixm/refinements_spec.rb
250
252
  - spec/lib/aixm/version_spec.rb
251
253
  - spec/lib/aixm/xy_spec.rb
@@ -315,6 +317,7 @@ test_files:
315
317
  - spec/lib/aixm/feature/organisation_spec.rb
316
318
  - spec/lib/aixm/feature/unit_spec.rb
317
319
  - spec/lib/aixm/feature_spec.rb
320
+ - spec/lib/aixm/h_spec.rb
318
321
  - spec/lib/aixm/refinements_spec.rb
319
322
  - spec/lib/aixm/version_spec.rb
320
323
  - spec/lib/aixm/xy_spec.rb