compass_rose 0.1.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bc2d34186d25b9b5f7ba22b34c76527d6bb7d429
4
+ data.tar.gz: 82c63d1a56c9d7c82199a379aac952902e08dbe3
5
+ SHA512:
6
+ metadata.gz: 11f6527ad55c1d692771b12956cc40447d0e4b700e0441fe835a48e39bdc4bc265785d1c66f64da7e1fb16ea26a07f1d611304f84ae9f5189a70b409fdb8db61
7
+ data.tar.gz: 8f654997966a3c9d55e49ed994fe618121b56d803181b73c535aee739d3c67f0333ad1f5f547c38f0addd85a9bea7a8a6bb65a0a3b9475109fcb83aeb351142f
data/.gitignore ADDED
@@ -0,0 +1,33 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+ Gemfile.lock
12
+
13
+ ## Documentation cache and generated files:
14
+ /.yardoc/
15
+ /_yardoc/
16
+ /doc/
17
+ /rdoc/
18
+
19
+ ## Environment normalisation:
20
+ /.bundle/
21
+ /lib/bundler/man/
22
+
23
+ # for a library or gem, you might want to ignore these files since the code is
24
+ # intended to run in multiple environments; otherwise, check them in:
25
+ # Gemfile.lock
26
+ # .ruby-version
27
+ # .ruby-gemset
28
+
29
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
30
+ .rvmrc
31
+
32
+ # misc files
33
+ test.rb
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format Fuubar
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 2.0.0
5
+ - 1.9.3
6
+ - 2.1.1
7
+ notifications:
8
+ email:
9
+ - t+travisci@heckman.io
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ # -*- coding: UTF-8 -*-
2
+ source 'https://rubygems.org'
3
+
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Tim Heckman
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,93 @@
1
+ compass_rose
2
+ =================
3
+
4
+ A tiny gem to convert numerical bearings to their string forms.
5
+
6
+ LICENSE
7
+ -------
8
+ `compass_rose` is released under
9
+ [The MIT License](http://opensource.org/licenses/MIT) The full text of the
10
+ license can be found in the `LICENSE` file. The summary can be found
11
+ [here](https://tldrlegal.com/license/mit-license#summary) courtest of
12
+ tldrlegal.
13
+
14
+ In short, MIT is a permissive license and means you can pretty much do what you
15
+ want with this code as long as the original copyright is included.
16
+
17
+ CONTRIBUTING
18
+ ------------
19
+ Something wrong or you want to submit an improvement? Fork the repo, make your
20
+ changes on a feature branch, write some tests, and submit a pull request. I
21
+ only ask that the commits have useful information and use proper/complete
22
+ sentences.
23
+
24
+ INSTALLATION
25
+ ------------
26
+
27
+ ```shell
28
+ gem install compass_rose
29
+ ```
30
+
31
+ Gemfile
32
+
33
+ ```Ruby
34
+ gem 'compass_rose'
35
+ ```
36
+
37
+ USAGE
38
+ -----
39
+
40
+ ```Ruby
41
+ require 'compass_rose'
42
+ bearing = 232 # directional bearing
43
+ points = 16 # the number of points the compass rose should be divided into
44
+ d = Compass::Rose.direction(bearing, points)
45
+ ```
46
+
47
+ At this point, d would contain the direction. This would be a Hash with the
48
+ following keys:
49
+
50
+ * `full` - full name of the direction, (i.e. `North by east`,
51
+ `North-northeast`, etc.)
52
+ * `abbr` - direction's abbrivation (i.e., `N`, `ESE`, `SWbW`, etc.)
53
+ * `wind_pt` - the traditional wind point (i.e., `Qto Ponente verso Maestro`)
54
+
55
+ Points
56
+ ------
57
+ A compass rose can be cut in to 4 different sizes: 4, 8, 16, 32. This table
58
+ shows which directions are available in the different sizes:
59
+
60
+ | Direction | 4 | 8 | 16 | 32 |
61
+ |:------------------:|:-:|:-:|:--:|:--:|
62
+ | North | X | X | X | X |
63
+ | North by east | | | | X |
64
+ | North-northeast | | | X | X |
65
+ | Northeast by north | | | | X |
66
+ | Northeast | | X | X | X |
67
+ | Northeast by east | | | | X |
68
+ | East-northeast | | | X | X |
69
+ | East by north | | | | X |
70
+ | East | X | X | X | X |
71
+ | East by south | | | | X |
72
+ | East-southeast | | | X | X |
73
+ | Southeast by east | | | | X |
74
+ | Southeast | | X | X | X |
75
+ | Southeast by south | | | | X |
76
+ | South-southeast | | | X | X |
77
+ | South by east | | | | X |
78
+ | South | X | X | X | X |
79
+ | South by west | | | | X |
80
+ | South-southwest | | | X | X |
81
+ | Southwest by south | | | | X |
82
+ | Southwest | | X | X | X |
83
+ | Southwest by west | | | | X |
84
+ | West-southwest | | | X | X |
85
+ | West by south | | | | X |
86
+ | West | X | X | X | X |
87
+ | West by north | | | | X |
88
+ | West-northwest | | | X | X |
89
+ | Northwest by west | | | | X |
90
+ | Northwest | | X | X | X |
91
+ | Northwest by north | | | | X |
92
+ | North-northwest | | | X | X |
93
+ | North by west | | | | X |
data/Rakefile ADDED
@@ -0,0 +1,14 @@
1
+ # -*- coding: UTF-8 -*-
2
+
3
+ require 'rspec/core/rake_task'
4
+ require 'rubocop/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ Rubocop::RakeTask.new(:rubocop) do |t|
9
+ t.patterns =
10
+ %w(compass_rose.gemspec lib/**/*.rb spec/**/*.rb)
11
+ t.fail_on_error = true
12
+ end
13
+
14
+ task default: [:rubocop, :spec]
@@ -0,0 +1,30 @@
1
+ # -*- coding: UTF-8 -*-
2
+ require 'English'
3
+
4
+ $LOAD_PATH.unshift File.expand_path('../lib', __FILE__)
5
+
6
+ require 'compass_rose'
7
+
8
+ Gem::Specification.new do |g|
9
+ g.name = 'compass_rose'
10
+ g.version = Compass::Rose::VERSION
11
+ g.date = Time.now.strftime('%Y-%m-%d')
12
+ g.description = 'Converts bearings in degrees to human-readable names'
13
+ g.summary = 'Bearings to human-readable names'
14
+ g.authors = ['Tim Heckman']
15
+ g.email = 't@heckman.io'
16
+ g.homepage = 'https://github.com/theckman/compass_rose'
17
+ g.license = 'MIT'
18
+
19
+ g.test_files = %x(git ls-files spec/*).split
20
+ g.files = %x(git ls-files).split
21
+
22
+ g.add_development_dependency 'rake', '~>10.1.0'
23
+ g.add_development_dependency 'rspec', '~>2.14.1'
24
+ g.add_development_dependency 'rubocop', '~> 0.19.0'
25
+ g.add_development_dependency 'fuubar', '~> 1.3.2'
26
+ g.add_development_dependency 'simplecov', '~> 0.8.2'
27
+ g.add_development_dependency 'coveralls', '~> 0.7.0'
28
+ g.add_development_dependency 'awesome_print', '~> 1.2.0'
29
+ g.add_development_dependency 'bundler', '>= 1.3'
30
+ end
@@ -0,0 +1,66 @@
1
+ # -*- coding: UTF-8 -*-
2
+
3
+ require 'compass_rose/rose'
4
+ require 'compass_rose/ranges'
5
+
6
+ module CompassRose
7
+ # Direction calculation class
8
+ #
9
+ class Direction
10
+ def self.calculate(bearing, points)
11
+ validate_bearing(bearing)
12
+ validate_points(points)
13
+ p = points_to_sym(points)
14
+ n = find_direction(bearing, CompassRose::RANGES[p])
15
+ CompassRose::ROSE[n]
16
+ end
17
+
18
+ private
19
+
20
+ def self.validate_bearing(bearing)
21
+ if ![Fixnum, Float].include?(bearing.class) ||
22
+ (bearing >= 360 || bearing < 0)
23
+ fail(ArgumentError, 'arg 1 must be a number between 0.00 and 359.99')
24
+ end
25
+ end
26
+
27
+ def self.validate_points(points)
28
+ if points.class != Fixnum ||
29
+ ![4, 8, 16, 32].include?(points)
30
+ fail(ArgumentError, 'arg 2 must be one of: 4, 8, 16, 32')
31
+ end
32
+ end
33
+
34
+ def self.points_to_sym(points)
35
+ m = { 4 => :four, 8 => :eight, 16 => :sixteen, 32 => :thirtytwo }
36
+ m[points]
37
+ end
38
+
39
+ def self.find_direction(bearing, ranges)
40
+ ranges.each do |k, v|
41
+ if v[:low] > v[:high]
42
+ return k if check_north(bearing, v)
43
+ else
44
+ return k if check_else(bearing, v)
45
+ end
46
+ end
47
+ nil
48
+ end
49
+
50
+ def self.check_north(bearing, ranges)
51
+ if bearing >= ranges[:low] || bearing <= ranges[:high]
52
+ true
53
+ else
54
+ false
55
+ end
56
+ end
57
+
58
+ def self.check_else(bearing, ranges)
59
+ if bearing >= ranges[:low] && bearing <= ranges[:high]
60
+ true
61
+ else
62
+ false
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,89 @@
1
+ # -*- coding: UTF-8 -*-
2
+
3
+ # Stuff
4
+ #
5
+ module CompassRose
6
+ # RoseUtils module is used to build the RANGES constant below
7
+ #
8
+ module RoseUtils
9
+ def self.build_rose(rose_map)
10
+ last_bearing = 0.00
11
+ h = hashit(rose_map, last_bearing)
12
+ h
13
+ end
14
+
15
+ def self.hashit(rose_map, last_bearing)
16
+ h = {}
17
+ rose_map[:d].each do |b|
18
+ if last_bearing == 0
19
+ low, high, last_bearing = bearing_zero(rose_map)
20
+ else
21
+ low, high, last_bearing = bearing_nonzero(rose_map, last_bearing)
22
+ end
23
+ h[b] = { low: low, high: high }
24
+ end
25
+ h
26
+ end
27
+
28
+ def self.bearing_zero(rose_map)
29
+ low = format(
30
+ '%.2f', (360.0 - (rose_map[:s] / 2.0)) + 0.01
31
+ ).to_f
32
+ last_bearing = high = format(
33
+ '%.2f', 0.00 + (rose_map[:s] / 2.0)
34
+ ).to_f
35
+ [low, high, last_bearing]
36
+ end
37
+
38
+ def self.bearing_nonzero(rose_map, last_bearing)
39
+ low = format('%.2f', last_bearing + 0.01).to_f
40
+ last_bearing = high = format('%.2f', last_bearing + rose_map[:s]).to_f
41
+ [low, high, last_bearing]
42
+ end
43
+ end
44
+ extend RoseUtils
45
+
46
+ FOUR ||= {
47
+ s: (360 / 4.0),
48
+ d: [:north, :east, :south, :west]
49
+ }
50
+
51
+ EIGHT ||= {
52
+ s: (360 / 8.0),
53
+ d: [
54
+ :north, :northeast, :east, :southeast,
55
+ :south, :southwest, :west, :northwest
56
+ ]
57
+ }
58
+
59
+ SIXTEEN ||= {
60
+ s: (360 / 16.0),
61
+ d: [
62
+ :north, :north_northeast, :northeast, :east_northeast, :east,
63
+ :east_southeast, :southeast, :south_southeast, :south,
64
+ :south_southwest, :southwest, :west_southwest, :west, :west_northwest,
65
+ :northwest, :north_northwest
66
+ ]
67
+ }
68
+
69
+ THIRTYTWO ||= {
70
+ s: (360 / 32.0),
71
+ d: [
72
+ :north, :north_by_east, :north_northeast, :northeast_by_north,
73
+ :northeast, :northeast_by_east, :east_northeast, :east_by_north, :east,
74
+ :east_by_south, :east_southeast, :southeast_by_east, :southeast,
75
+ :southeast_by_south, :south_southeast, :south_by_east, :south,
76
+ :south_by_west, :south_southwest, :southwest_by_south, :southwest,
77
+ :southwest_by_west, :west_southwest, :west_by_south, :west,
78
+ :west_by_north, :west_northwest, :northwest_by_west, :northwest,
79
+ :northwest_by_north, :north_northwest, :north_by_west
80
+ ]
81
+ }
82
+
83
+ RANGES ||= {
84
+ four: RoseUtils.build_rose(FOUR),
85
+ eight: RoseUtils.build_rose(EIGHT),
86
+ sixteen: RoseUtils.build_rose(SIXTEEN),
87
+ thirtytwo: RoseUtils.build_rose(THIRTYTWO)
88
+ }
89
+ end
@@ -0,0 +1,116 @@
1
+ # -*- coding: UTF-8 -*-
2
+
3
+ # Compass Rose
4
+ #
5
+ # Contains the ::ROSE constant which contains all points
6
+ #
7
+ module CompassRose
8
+ # obtained rose data from
9
+ # - https://en.wikipedia.org/wiki/Points_of_the_compass
10
+ #
11
+ ROSE ||= {
12
+ # when only broken in to 4 parts
13
+ north: { full: 'North', abbr: 'N', wind_pt: 'Tramontana' },
14
+ east: { full: 'East', abbr: 'E', wind_pt: 'Levante' },
15
+ south: { full: 'South', abbr: 'S', wind_pt: 'Ostro' },
16
+ west: { full: 'West', abbr: 'W', wind_pt: 'Ponente' },
17
+
18
+ # when broken in to 8 parts
19
+ northeast: { full: 'Northeast', abbr: 'NE', wind_pt: 'Greco' },
20
+ southeast: { full: 'Southeast', abbr: 'SE', wind_pt: 'Scirocco' },
21
+ southwest: { full: 'Southwest', abbr: 'SW', wind_pt: 'Libeccio' },
22
+ northwest: { full: 'Northwest', abbr: 'NW', wind_pt: 'Maestro' },
23
+
24
+ # when broken in to 16 parts
25
+ north_northeast: {
26
+ full: 'North-northeast', abbr: 'NNE', wind_pt: 'Greco-Tramontana'
27
+ },
28
+ east_northeast: {
29
+ full: 'East-northeast', abbr: 'ENE', wind_pt: 'Greco-Levante'
30
+ },
31
+ east_southeast: {
32
+ full: 'East-southeast', abbr: 'ESE', wind_pt: 'Levante-Scirocco'
33
+ }, # Listen up ese...
34
+ south_southeast: {
35
+ full: 'South-southeast', abbr: 'SSE', wind_pt: 'Ostro-Scirocco'
36
+ },
37
+ south_southwest: {
38
+ full: 'South-southwest', abbr: 'SSW', wind_pt: 'Ostro-Libeccio'
39
+ },
40
+ west_southwest: {
41
+ full: 'West-southwest', abbr: 'WSW', wind_pt: 'Ponente-Libeccio'
42
+ },
43
+ west_northwest: {
44
+ full: 'West-northwest', abbr: 'WNW', wind_pt: 'Maestro-Ponente'
45
+ },
46
+ north_northwest: {
47
+ full: 'North-northwest', abbr: 'NNW', wind_pt: 'Maestro-Tramontana'
48
+ },
49
+
50
+ # when broken in to 32 parts
51
+ north_by_east: {
52
+ full: 'North by east', abbr: 'NbE',
53
+ wind_pt: 'Qto Tramontana verso Greco'
54
+ },
55
+ northeast_by_north: {
56
+ full: 'Northeast by north', abbr: 'NEbN',
57
+ wind_pt: 'Qto Greco verso Tramontana'
58
+ },
59
+ northeast_by_east: {
60
+ full: 'Northeast by east', abbr: 'NEbE',
61
+ wind_pt: 'Qto Greco verso Levante'
62
+ },
63
+ east_by_north: {
64
+ full: 'East by north', abbr: 'EbN',
65
+ wind_pt: 'Qto Levante verso Greco'
66
+ },
67
+ east_by_south: {
68
+ full: 'East by south', abbr: 'EbS',
69
+ wind_pt: 'Qto Levante verso Scirocco'
70
+ },
71
+ southeast_by_east: {
72
+ full: 'Southeast by east', abbr: 'SEbE',
73
+ wind_pt: 'Qto Scirocco verso Levante'
74
+ },
75
+ southeast_by_south: {
76
+ full: 'Southeast by south', abbr: 'SEbS',
77
+ wind_pt: 'Qto Scirocco verso Ostro'
78
+ },
79
+ south_by_east: {
80
+ full: 'South by east', abbr: 'SbE',
81
+ wind_pt: 'Qto Ostro verso Scirocco'
82
+ },
83
+ south_by_west: {
84
+ full: 'South by west', abbr: 'SbW',
85
+ wind_pt: 'Qto Ostro verso Libeccio'
86
+ },
87
+ southwest_by_south: {
88
+ full: 'Southwest by south', abbr: 'SWbS',
89
+ wind_pt: 'Qto Libeccio verso Ostro'
90
+ },
91
+ southwest_by_west: {
92
+ full: 'Southwest by west', abbr: 'SWbW',
93
+ wind_pt: 'Qto Libeccio verso Ponente'
94
+ },
95
+ west_by_south: {
96
+ full: 'West by south', abbr: 'WbS',
97
+ wind_pt: 'Qto Ponente verso Libeccio'
98
+ },
99
+ west_by_north: {
100
+ full: 'West by north', abbr: 'WbN',
101
+ wind_pt: 'Qto Ponente verso Maestro'
102
+ },
103
+ northwest_by_west: {
104
+ full: 'Northwest by west', abbr: 'NWbW',
105
+ wind_pt: 'Qto Maestro verso Ponente'
106
+ },
107
+ northwest_by_north: {
108
+ full: 'Northwest by north', abbr: 'NWbN',
109
+ wind_pt: 'Qto Maestro verso Tramontana'
110
+ },
111
+ north_by_west: {
112
+ full: 'North by west', abbr: 'NbW',
113
+ wind_pt: 'Qto Tramontana verso Maestro'
114
+ }
115
+ }
116
+ end
@@ -0,0 +1,38 @@
1
+ # -*- coding: UTF-8 -*-
2
+ # The MIT License (MIT)
3
+
4
+ # Copyright (c) 2014 Tim Heckman
5
+
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # SOFTWARE.
23
+
24
+ require 'compass_rose/direction'
25
+ require 'compass_rose/ranges'
26
+
27
+ # Something
28
+ #
29
+ module Compass
30
+ # Get the direction that your bearing is on the Compass Rose
31
+ #
32
+ class Rose
33
+ VERSION = '0.1.0'
34
+ def self.direction(bearing, num_points)
35
+ CompassRose::Direction.calculate(bearing, num_points)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,282 @@
1
+ # -*- coding: UTF-8 -*-
2
+ require 'spec_helper'
3
+
4
+ describe CompassRose::Direction do
5
+ let(:direction) { described_class }
6
+
7
+ context '#check_else' do
8
+ let(:ranges) { CompassRose::RANGES[:thirtytwo] }
9
+
10
+ it 'should accept no more than two args' do
11
+ expect do
12
+ direction.check_else(nil, nil, nil)
13
+ end.to raise_error ArgumentError
14
+ end
15
+
16
+ it 'should accept no less than two args' do
17
+ expect do
18
+ direction.check_else(nil)
19
+ end.to raise_error ArgumentError
20
+ end
21
+
22
+ it 'should return true if it is within the south range' do
23
+ r = ranges[:south]
24
+ expect(direction.check_else(180, r)).to be_true
25
+ end
26
+
27
+ it 'should return false if it is outside the southern range' do
28
+ r = ranges[:south]
29
+ expect(direction.check_else(0, r)).to be_false
30
+ end
31
+ end
32
+
33
+ context '#check_north' do
34
+ let(:ranges) { CompassRose::RANGES[:thirtytwo] }
35
+
36
+ it 'should accept no more than two args' do
37
+ expect do
38
+ direction.check_north(nil, nil, nil)
39
+ end.to raise_error ArgumentError
40
+ end
41
+
42
+ it 'should accept no less than two args' do
43
+ expect do
44
+ direction.check_north(nil)
45
+ end.to raise_error ArgumentError
46
+ end
47
+
48
+ it 'should return true if it is within the north range' do
49
+ r = ranges[:north]
50
+ expect(direction.check_north(0, r)).to be_true
51
+ end
52
+
53
+ it 'should return false if it is outside the north range' do
54
+ r = ranges[:north]
55
+ expect(direction.check_north(180, r)).to be_false
56
+ end
57
+ end
58
+
59
+ context '#find_direction' do
60
+ let(:ranges) { CompassRose::RANGES[:thirtytwo] }
61
+ let(:fdir) { direction.find_direction(0, ranges) }
62
+
63
+ it 'should accept no more than two args' do
64
+ expect do
65
+ direction.find_direction(nil, nil, nil)
66
+ end.to raise_error ArgumentError
67
+ end
68
+
69
+ it 'should accept no less than two args' do
70
+ expect do
71
+ direction.find_direction(nil)
72
+ end.to raise_error ArgumentError
73
+ end
74
+
75
+ it 'should return a symbol' do
76
+ expect(fdir).to be_an_instance_of Symbol
77
+ end
78
+
79
+ it 'should return the proper direction' do
80
+ expect(direction.find_direction(90, ranges)).to eql :east
81
+ end
82
+ end
83
+
84
+ context '#points_to_sym' do
85
+ it 'should accept no more than one arg' do
86
+ expect do
87
+ direction.points_to_sym(nil, nil)
88
+ end.to raise_error ArgumentError
89
+ end
90
+
91
+ it 'should accept no less than one arg' do
92
+ expect do
93
+ direction.points_to_sym
94
+ end.to raise_error ArgumentError
95
+ end
96
+
97
+ it 'should return a symbol' do
98
+ expect(direction.points_to_sym(4)).to be_an_instance_of Symbol
99
+ end
100
+
101
+ it 'should return :four for 4' do
102
+ expect(direction.points_to_sym(4)).to eql :four
103
+ end
104
+
105
+ it 'should return :eight for 8' do
106
+ expect(direction.points_to_sym(8)).to eql :eight
107
+ end
108
+
109
+ it 'should return :four for 16' do
110
+ expect(direction.points_to_sym(16)).to eql :sixteen
111
+ end
112
+
113
+ it 'should return :four for 32' do
114
+ expect(direction.points_to_sym(32)).to eql :thirtytwo
115
+ end
116
+ end
117
+
118
+ context '#validate_points' do
119
+ let(:vp) { direction.validate_points(4) }
120
+
121
+ it 'should accept no more than one arg' do
122
+ expect do
123
+ direction.validate_points(nil, nil)
124
+ end.to raise_error ArgumentError
125
+ end
126
+
127
+ it 'should accept no less than one arg' do
128
+ expect do
129
+ direction.validate_points
130
+ end.to raise_error ArgumentError
131
+ end
132
+
133
+ it 'should return nil' do
134
+ expect(vp).to be_nil
135
+ end
136
+
137
+ it 'should raise ArgumentError when passed invalid Fixnum' do
138
+ expect do
139
+ direction.validate_points(370)
140
+ end.to raise_error ArgumentError
141
+ end
142
+
143
+ it 'should raise ArgumentError if passed a String' do
144
+ expect do
145
+ direction.validate_points('')
146
+ end.to raise_error ArgumentError
147
+ end
148
+
149
+ it 'should raise ArgumentError if passed nil' do
150
+ expect do
151
+ direction.validate_points(nil)
152
+ end.to raise_error ArgumentError
153
+ end
154
+
155
+ it 'should raise ArgumentError if passed a symbol' do
156
+ expect do
157
+ direction.validate_points(:x)
158
+ end.to raise_error ArgumentError
159
+ end
160
+
161
+ it 'should raise ArgumentError if passed a Float' do
162
+ expect do
163
+ direction.validate_points(0.0)
164
+ end.to raise_error ArgumentError
165
+ end
166
+
167
+ it 'should raise ArgumentError if passed a Array' do
168
+ expect do
169
+ direction.validate_points([])
170
+ end.to raise_error ArgumentError
171
+ end
172
+
173
+ it 'should raise ArgumentError if passed a Hash' do
174
+ expect do
175
+ direction.validate_points({})
176
+ end.to raise_error ArgumentError
177
+ end
178
+ end
179
+
180
+ context '#validate_bearing' do
181
+ let(:vb) { direction.validate_bearing(0) }
182
+
183
+ it 'should accept no more than one arg' do
184
+ expect do
185
+ direction.validate_bearing(nil, nil)
186
+ end.to raise_error ArgumentError
187
+ end
188
+
189
+ it 'should accept no less than one arg' do
190
+ expect do
191
+ direction.validate_bearing
192
+ end.to raise_error ArgumentError
193
+ end
194
+
195
+ it 'should return nil' do
196
+ expect(vb).to be_nil
197
+ end
198
+
199
+ it 'should raise ArgumentError when passed invalid Fixnum' do
200
+ expect do
201
+ direction.validate_bearing(370)
202
+ end.to raise_error ArgumentError
203
+ end
204
+
205
+ it 'should raise ArgumentError if passed a String' do
206
+ expect do
207
+ direction.validate_bearing('')
208
+ end.to raise_error ArgumentError
209
+ end
210
+
211
+ it 'should raise ArgumentError if passed nil' do
212
+ expect do
213
+ direction.validate_bearing(nil)
214
+ end.to raise_error ArgumentError
215
+ end
216
+
217
+ it 'should raise ArgumentError if passed a symbol' do
218
+ expect do
219
+ direction.validate_bearing(:x)
220
+ end.to raise_error ArgumentError
221
+ end
222
+
223
+ it 'should raise ArgumentError if passed a Array' do
224
+ expect do
225
+ direction.validate_bearing([])
226
+ end.to raise_error ArgumentError
227
+ end
228
+
229
+ it 'should raise ArgumentError if passed a Hash' do
230
+ expect do
231
+ direction.validate_bearing({})
232
+ end.to raise_error ArgumentError
233
+ end
234
+ end
235
+
236
+ context '#calculate' do
237
+ let(:c) { direction.calculate(0, 32) }
238
+
239
+ it 'should accept no more than two args' do
240
+ expect do
241
+ direction.calculate(nil, nil, nil)
242
+ end.to raise_error ArgumentError
243
+ end
244
+
245
+ it 'should accept no less than two args' do
246
+ expect do
247
+ direction.calculate(nil)
248
+ end.to raise_error ArgumentError
249
+ end
250
+
251
+ it 'should return a Hash' do
252
+ expect(c).to be_an_instance_of Hash
253
+ end
254
+
255
+ it 'should have the :full key' do
256
+ expect(c.key?(:full)).to be_true
257
+ end
258
+
259
+ it 'should have :full String' do
260
+ expect(c[:full]).to be_an_instance_of String
261
+ expect(c[:full].empty?).to be_false
262
+ end
263
+
264
+ it 'should have the :abbr key' do
265
+ expect(c.key?(:abbr)).to be_true
266
+ end
267
+
268
+ it 'should have :abbr String' do
269
+ expect(c[:abbr]).to be_an_instance_of String
270
+ expect(c[:abbr].empty?).to be_false
271
+ end
272
+
273
+ it 'should have the :wind_pt key' do
274
+ expect(c.key?(:wind_pt)).to be_true
275
+ end
276
+
277
+ it 'should have :wind_pt String' do
278
+ expect(c[:wind_pt]).to be_an_instance_of String
279
+ expect(c[:wind_pt].empty?).to be_false
280
+ end
281
+ end
282
+ end
@@ -0,0 +1,15 @@
1
+ # -*- coding: UTF-8 -*-
2
+
3
+ shared_examples 'CompassRose::Ranges' do
4
+ it ' should be an instance of Hash ' do
5
+ expect(subject).to be_an_instance_of Hash
6
+ end
7
+
8
+ it 'should have the :s key' do
9
+ expect(subject.key?(:s)).to be_true
10
+ end
11
+
12
+ it 'should ha3ve the :d key' do
13
+ expect(subject.key?(:d)).to be_true
14
+ end
15
+ end
@@ -0,0 +1,181 @@
1
+ # -*- coding: UTF-8 -*-
2
+ require 'spec_helper'
3
+ require_relative 'ranges'
4
+
5
+ describe CompassRose::RoseUtils do
6
+ before do
7
+ @lb = 343.12
8
+ @m = CompassRose::THIRTYTWO
9
+ end
10
+
11
+ context '#bearing_nonzero' do
12
+ it 'should take no more than two args' do
13
+ expect do
14
+ CompassRose::RoseUtils.bearing_nonzero(nil, nil, nil)
15
+ end.to raise_error ArgumentError
16
+ end
17
+
18
+ it 'should take no less than two args' do
19
+ expect do
20
+ CompassRose::RoseUtils.bearing_nonzero(nil)
21
+ end.to raise_error ArgumentError
22
+ end
23
+
24
+ it 'should return an Array' do
25
+ b = CompassRose::RoseUtils.bearing_nonzero(@m, @lb)
26
+ expect(b).to be_an_instance_of Array
27
+ end
28
+
29
+ it 'should return the correct values' do
30
+ b = CompassRose::RoseUtils.bearing_nonzero(@m, @lb)
31
+ expect(b[0]).to eql(@lb + 0.01)
32
+ expect(b[1]).to eql(@lb + 11.25)
33
+ expect(b[2]).to eql(@lb + 11.25)
34
+ end
35
+ end
36
+
37
+ context '#bearing_zero' do
38
+
39
+ it 'should take no more one arg' do
40
+ expect do
41
+ CompassRose::RoseUtils.bearing_zero(nil, nil)
42
+ end.to raise_error ArgumentError
43
+ end
44
+
45
+ it 'should take no less than one arg' do
46
+ expect do
47
+ CompassRose::RoseUtils.bearing_zero
48
+ end.to raise_error ArgumentError
49
+ end
50
+
51
+ it 'should return an Array' do
52
+ b = CompassRose::RoseUtils.bearing_zero(@m)
53
+ expect(b).to be_an_instance_of Array
54
+ end
55
+
56
+ it 'should return the correct values' do
57
+ b = CompassRose::RoseUtils.bearing_zero(@m)
58
+ expect(b[0]).to eql 354.38
59
+ expect(b[1]).to eql 5.62
60
+ expect(b[2]).to eql 5.62
61
+ end
62
+ end
63
+
64
+ context '#hashit' do
65
+ let(:hit) { CompassRose::RoseUtils.hashit(@m, 0.00) }
66
+
67
+ it 'should take no more than two args' do
68
+ expect do
69
+ CompassRose::RoseUtils.hashit(nil, nil, nil)
70
+ end.to raise_error ArgumentError
71
+ end
72
+
73
+ it 'should take no less than two args' do
74
+ expect do
75
+ CompassRose::RoseUtils.hashit(nil)
76
+ end.to raise_error ArgumentError
77
+ end
78
+
79
+ it 'should return a Hash' do
80
+ expect(hit).to be_an_instance_of Hash
81
+ end
82
+
83
+ it 'should have each key should be a hash' do
84
+ hit.each do |k, v|
85
+ expect(v).to be_an_instance_of Hash
86
+ end
87
+ end
88
+
89
+ it 'should have the :low key' do
90
+ hit.each do |k, v|
91
+ expect(v.key?(:low)).to be_true
92
+ end
93
+ end
94
+
95
+ it 'should have the :high key' do
96
+ hit.each do |k, v|
97
+ expect(v.key?(:high)).to be_true
98
+ end
99
+ end
100
+ end
101
+
102
+ context '#build_rose' do
103
+ let(:br) { CompassRose::RoseUtils.build_rose(@m) }
104
+
105
+ it 'should take no more than one arg' do
106
+ expect do
107
+ CompassRose::RoseUtils.build_rose(nil, nil)
108
+ end.to raise_error ArgumentError
109
+ end
110
+
111
+ it 'should take no less than one arg' do
112
+ expect do
113
+ CompassRose::RoseUtils.build_rose
114
+ end.to raise_error ArgumentError
115
+ end
116
+
117
+ it 'should return a Hash' do
118
+ expect(br).to be_an_instance_of Hash
119
+ end
120
+ end
121
+ end
122
+
123
+ describe CompassRose::FOUR do
124
+ subject { CompassRose::FOUR }
125
+ it_should_behave_like 'CompassRose::Ranges'
126
+ end
127
+
128
+ describe CompassRose::EIGHT do
129
+ subject { CompassRose::EIGHT }
130
+ it_should_behave_like 'CompassRose::Ranges'
131
+ end
132
+
133
+ describe CompassRose::SIXTEEN do
134
+ subject { CompassRose::SIXTEEN }
135
+ it_should_behave_like 'CompassRose::Ranges'
136
+ end
137
+
138
+ describe CompassRose::THIRTYTWO do
139
+ subject { CompassRose::THIRTYTWO }
140
+ it_should_behave_like 'CompassRose::Ranges'
141
+ end
142
+
143
+ describe CompassRose::RANGES do
144
+ subject { CompassRose::RANGES }
145
+
146
+ it 'should be an instance of Hash' do
147
+ expect(subject).to be_an_instance_of Hash
148
+ end
149
+
150
+ it 'should have the :four key' do
151
+ expect(subject.key?(:four)).to be_true
152
+ end
153
+
154
+ it 'should have a :four key which is a Hash' do
155
+ expect(subject[:four]).to be_an_instance_of Hash
156
+ end
157
+
158
+ it 'should have the :eight key' do
159
+ expect(subject.key?(:eight)).to be_true
160
+ end
161
+
162
+ it 'should have an :eight key which is a Hash' do
163
+ expect(subject[:eight]).to be_an_instance_of Hash
164
+ end
165
+
166
+ it 'should have the :sixteen key' do
167
+ expect(subject.key?(:sixteen)).to be_true
168
+ end
169
+
170
+ it 'should have a :sixteen key which is a Hash' do
171
+ expect(subject[:sixteen]).to be_an_instance_of Hash
172
+ end
173
+
174
+ it 'should have the :thirtytwo key' do
175
+ expect(subject.key?(:thirtytwo)).to be_true
176
+ end
177
+
178
+ it 'should have a :thirtytwo key which is a Hash' do
179
+ expect(subject[:thirtytwo]).to be_an_instance_of Hash
180
+ end
181
+ end
@@ -0,0 +1,41 @@
1
+ # -*- coding: UTF-8 -*-
2
+ require 'spec_helper'
3
+ require 'ap'
4
+
5
+ TRUSTED_KEYS ||= [
6
+ :north, :east, :south, :west, :northeast, :southeast, :southwest, :northwest,
7
+ :north_northeast, :east_northeast, :east_southeast, :south_southeast,
8
+ :south_southwest, :west_southwest, :west_northwest, :north_northwest,
9
+ :north_by_east, :northeast_by_north, :northeast_by_east, :east_by_north,
10
+ :east_by_south, :southeast_by_east, :southeast_by_south, :south_by_east,
11
+ :south_by_west, :southwest_by_south, :southwest_by_west, :west_by_south,
12
+ :west_by_north, :northwest_by_west, :northwest_by_north, :north_by_west
13
+ ]
14
+
15
+ describe CompassRose::ROSE do
16
+ subject { CompassRose::ROSE }
17
+
18
+ it { should be_an_instance_of Hash }
19
+
20
+ TRUSTED_KEYS.each do |k|
21
+ it "should contain the #{k} key" do
22
+ expect(subject.key?(k)).to be_true
23
+ end
24
+
25
+ it "should contain the #{k} Hash" do
26
+ expect(subject[k]).to be_an_instance_of Hash
27
+ end
28
+
29
+ it "should contain the #{k} Hash and it should have the :full key" do
30
+ expect(subject[k].key?(:full)).to be_true
31
+ end
32
+
33
+ it "should contain the #{k} Hash and it should have the :abbr key" do
34
+ expect(subject[k].key?(:abbr)).to be_true
35
+ end
36
+
37
+ it "should contain the #{k} Hash and it should have the :wind_pt key" do
38
+ expect(subject[k].key?(:wind_pt)).to be_true
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,18 @@
1
+ # -*- coding: UTF-8 -*-
2
+ # -*- coding: UTF-8 -*-
3
+ require 'rspec'
4
+ require 'simplecov'
5
+ require 'coveralls'
6
+
7
+ $LOAD_PATH.unshift '.' unless $LOAD_PATH.include?('.')
8
+
9
+ def repo_root
10
+ File.expand_path('../../..', __FILE__)
11
+ end
12
+
13
+ SimpleCov.formatter = Coveralls::SimpleCov::Formatter
14
+ SimpleCov.start do
15
+ add_filter '/spec/'
16
+ end
17
+
18
+ require 'compass_rose'
metadata ADDED
@@ -0,0 +1,177 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: compass_rose
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Tim Heckman
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 10.1.0
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 10.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.14.1
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.14.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: rubocop
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 0.19.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 0.19.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: fuubar
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.3.2
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.3.2
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.8.2
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.8.2
83
+ - !ruby/object:Gem::Dependency
84
+ name: coveralls
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.7.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.7.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: awesome_print
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 1.2.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 1.2.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: bundler
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '1.3'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '1.3'
125
+ description: Converts bearings in degrees to human-readable names
126
+ email: t@heckman.io
127
+ executables: []
128
+ extensions: []
129
+ extra_rdoc_files: []
130
+ files:
131
+ - ".gitignore"
132
+ - ".rspec"
133
+ - ".travis.yml"
134
+ - Gemfile
135
+ - LICENSE
136
+ - README.md
137
+ - Rakefile
138
+ - compass_rose.gemspec
139
+ - lib/compass_rose.rb
140
+ - lib/compass_rose/direction.rb
141
+ - lib/compass_rose/ranges.rb
142
+ - lib/compass_rose/rose.rb
143
+ - spec/compass_rose/direction_spec.rb
144
+ - spec/compass_rose/ranges.rb
145
+ - spec/compass_rose/ranges_spec.rb
146
+ - spec/compass_rose/rose_spec.rb
147
+ - spec/spec_helper.rb
148
+ homepage: https://github.com/theckman/compass_rose
149
+ licenses:
150
+ - MIT
151
+ metadata: {}
152
+ post_install_message:
153
+ rdoc_options: []
154
+ require_paths:
155
+ - lib
156
+ required_ruby_version: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ required_rubygems_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ requirements: []
167
+ rubyforge_project:
168
+ rubygems_version: 2.2.2
169
+ signing_key:
170
+ specification_version: 4
171
+ summary: Bearings to human-readable names
172
+ test_files:
173
+ - spec/compass_rose/direction_spec.rb
174
+ - spec/compass_rose/ranges.rb
175
+ - spec/compass_rose/ranges_spec.rb
176
+ - spec/compass_rose/rose_spec.rb
177
+ - spec/spec_helper.rb