compass_rose 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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