diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 36c20bf..b5ce036 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - ruby-version: ['3.0', '3.1', '3.2', '3.3', 'head'] + ruby-version: ['3.1', '3.2', '3.3', 'head'] steps: - uses: actions/checkout@v3 diff --git a/.rubocop.yml b/.rubocop.yml index ca0210b..9f48e6c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -5,201 +5,39 @@ require: AllCops: NewCops: enable -Layout/ArgumentAlignment: - Enabled: true - EnforcedStyle: with_fixed_indentation - -Layout/ParameterAlignment: - Enabled: true - EnforcedStyle: with_fixed_indentation - -Layout/CaseIndentation: - Enabled: false - -Layout/ElseAlignment: - Enabled: false - -Layout/EmptyLinesAroundBlockBody: +Gemspec/RequiredRubyVersion: Enabled: false Layout/EndAlignment: Enabled: true EnforcedStyleAlignWith: start_of_line -Layout/FirstArrayElementIndentation: - Enabled: true - EnforcedStyle: consistent - -Layout/FirstHashElementIndentation: - Enabled: true - EnforcedStyle: consistent - -Layout/LineLength: - Enabled: false - -Layout/MultilineHashBraceLayout: - Enabled: true - EnforcedStyle: symmetrical - -Layout/MultilineMethodCallIndentation: - Enabled: true - EnforcedStyle: indented - -Layout/MultilineOperationIndentation: - Enabled: true - EnforcedStyle: indented - -Layout/RescueEnsureAlignment: - Enabled: false - Layout/SpaceInsideHashLiteralBraces: Enabled: true EnforcedStyle: no_space -Layout/SpaceInLambdaLiteral: - Enabled: true - EnforcedStyle: require_space - -Layout/TrailingWhitespace: - Enabled: false - -Lint/AmbiguousBlockAssociation: - Enabled: false - -Lint/AssignmentInCondition: - Enabled: false - -Lint/SuppressedException: - Enabled: true - -Lint/ShadowingOuterLocalVariable: - Enabled: false - -Lint/RedundantSplatExpansion: - Enabled: false - -Metrics/AbcSize: - Enabled: false - -Metrics/BlockLength: - CountComments: false - Enabled: true - Max: 100 - Metrics/ClassLength: Enabled: false -Metrics/CyclomaticComplexity: - Enabled: true - Max: 10 - Metrics/MethodLength: Enabled: false -Metrics/ModuleLength: - Enabled: false - Metrics/PerceivedComplexity: Enabled: true Max: 10 -Naming/AccessorMethodName: - Enabled: true - -Naming/FileName: - Enabled: false - Naming/MethodParameterName: Enabled: false -Naming/PredicateName: - Enabled: true - -Naming/VariableNumber: - Enabled: false - -RSpec/AnyInstance: - Enabled: false - -RSpec/DescribeClass: - Enabled: true - -RSpec/DescribedClass: - Enabled: false - RSpec/ExampleLength: Enabled: true Max: 25 -RSpec/HookArgument: - Enabled: false - -RSpec/ImplicitSubject: - Enabled: false - -RSpec/LetSetup: - Enabled: false - -RSpec/MessageSpies: - Enabled: false - RSpec/MultipleExpectations: Enabled: false -RSpec/NestedGroups: - Enabled: true - Max: 5 - -RSpec/NotToNot: - Enabled: true - EnforcedStyle: to_not - -RSpec/VerifiedDoubleReference: - Enabled: false - -Security/YAMLLoad: - Enabled: true - -Style/Alias: - Enabled: false - -Style/ClassAndModuleChildren: - Enabled: false - Style/Documentation: Enabled: false -Style/EmptyMethod: - Enabled: true - EnforcedStyle: expanded - -Style/FormatStringToken: - Enabled: false - -Style/GuardClause: - Enabled: false - Style/FrozenStringLiteralComment: Enabled: false - -Style/Lambda: - Enabled: false - -Style/NumericPredicate: - Enabled: false - -Style/PerlBackrefs: - Enabled: false - -Style/RedundantBegin: - Enabled: false - -Style/RescueModifier: - Enabled: false - -Style/SafeNavigation: - Enabled: false - -Style/SymbolArray: - Enabled: true - EnforcedStyle: brackets diff --git a/.ruby-version b/.ruby-version index be94e6f..15a2799 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.2.2 +3.3.0 diff --git a/Guardfile b/Guardfile index 0096933..12009ce 100644 --- a/Guardfile +++ b/Guardfile @@ -1,37 +1,3 @@ -# A sample Guardfile -# More info at https://github.com/guard/guard#readme - -## Uncomment and set this to only include directories you want to watch -# directories %w(app lib config test spec features) - -## Uncomment to clear the screen before every task -# clearing :on - -## Guard internally checks for changes in the Guardfile and exits. -## If you want Guard to automatically start up again, run guard in a -## shell loop, e.g.: -## -## $ while bundle exec guard; do echo "Restarting Guard..."; done -## -## Note: if you are using the `directories` clause above and you are not -## watching the project directory ('.'), then you will want to move -## the Guardfile to a watched dir and symlink it back, e.g. -# -# $ mkdir config -# $ mv Guardfile config/ -# $ ln -s config/Guardfile . -# -# and, you'll have to watch "config/Guardfile" instead of "Guardfile" - -# Note: The cmd option is now required due to the increasing number of ways -# rspec may be run, below are examples of the most common uses. -# * bundler: 'bundle exec rspec' -# * bundler binstubs: 'bin/rspec' -# * spring: 'bin/rspec' (This will use spring if running and you have -# installed the spring binstubs per the docs) -# * zeus: 'zeus rspec' (requires the server to be started separately) -# * 'just' rspec: 'rspec' - guard :rspec, cmd: 'bundle exec rspec' do require 'guard/rspec/dsl' dsl = Guard::RSpec::Dsl.new(self) diff --git a/LICENSE b/LICENSE index a97cf07..468d928 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015-2023 Keith Morrison +Copyright (c) 2015-2024 Keith Morrison Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the diff --git a/README.md b/README.md index 6e4b504..e4e3268 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ A Ruby library for working with compass points. Compass Point is compatible with the following versions of Ruby: -* MRI Ruby 3.0.x, 3.1.x, 3.2.x, and 3.3.x +* MRI Ruby 3.1.x, 3.2.x, and 3.3.x ## Installation @@ -68,7 +68,7 @@ example: ## License -Copyright (c) 2015-2023 Keith Morrison <> +Copyright (c) 2015-2024 Keith Morrison <> Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/compass_point.gemspec b/compass_point.gemspec index 75e005f..3f8cb49 100644 --- a/compass_point.gemspec +++ b/compass_point.gemspec @@ -17,6 +17,6 @@ Gem::Specification.new do |s| s.files = Dir['LICENSE', 'README.md', '{lib,spec}/**/*.rb', 'compass_points.gemspec'] s.require_paths = ['lib'] - s.required_ruby_version = '>= 3.0.0' + s.required_ruby_version = '>= 3.1.0' s.metadata['rubygems_mfa_required'] = 'true' end diff --git a/lib/compass_point.rb b/lib/compass_point.rb index e419d40..fa5ff5d 100644 --- a/lib/compass_point.rb +++ b/lib/compass_point.rb @@ -1,7 +1,7 @@ class CompassPoint - VERSION = '2.0.1'.freeze + VERSION = '3.0.0'.freeze - COMPASS_BEARING_REGEX = /(n|s)\s(\d{1,3}).?\s(e|w)/.freeze + COMPASS_BEARING_REGEX = /(n|s)\s(\d{1,3}).?\s(e|w)/ POINTS = { n: {min: 354.38, mid: 0.0, max: 5.62, name: 'North'}, @@ -41,9 +41,9 @@ class CompassPoint class << self def azimuth(s) input = normalize_input(s) - if point = find_point(input) + if (point = find_point(input)) point[:mid] - elsif match = input.match(COMPASS_BEARING_REGEX) + elsif (match = input.match(COMPASS_BEARING_REGEX)) azimuth_from_match(match) end end @@ -96,15 +96,13 @@ def azimuth_from_match(match) 180 end - adjust = match[2].to_i - operation = if (match[1] == 'n' && match[3] == 'w') || (match[1] == 's' && match[3] == 'e') :- else :+ end - base.send(operation, adjust) + base.send(operation, match[2].to_i) end def generate_compass_quadrant_bearing(b) diff --git a/spec/compass_point_spec.rb b/spec/compass_point_spec.rb index d188dc9..5cc591d 100644 --- a/spec/compass_point_spec.rb +++ b/spec/compass_point_spec.rb @@ -3,88 +3,87 @@ describe CompassPoint do describe '.azimuth' do it 'returns mid point in degrees' do - expect(CompassPoint.azimuth('N')).to eq 0.0 - expect(CompassPoint.azimuth(:nw)).to eq 315.0 - expect(CompassPoint.azimuth('sbw')).to eq 191.25 - expect(CompassPoint.azimuth('X')).to be_nil - expect(CompassPoint.azimuth('Northeast by east')).to eq 56.25 - expect(CompassPoint.azimuth('N 27° E')).to eq 27 - expect(CompassPoint.azimuth('S 77° E')).to eq 103 - expect(CompassPoint.azimuth('S 2° E')).to eq 178 - expect(CompassPoint.azimuth('N 77° W')).to eq 283 - expect(CompassPoint.azimuth('N 20 W')).to eq 340 - expect(CompassPoint.azimuth('S 30° W')).to eq 210 + expect(described_class.azimuth('N')).to eq 0.0 + expect(described_class.azimuth(:nw)).to eq 315.0 + expect(described_class.azimuth('sbw')).to eq 191.25 + expect(described_class.azimuth('X')).to be_nil + expect(described_class.azimuth('Northeast by east')).to eq 56.25 + expect(described_class.azimuth('N 27° E')).to eq 27 + expect(described_class.azimuth('S 77° E')).to eq 103 + expect(described_class.azimuth('S 2° E')).to eq 178 + expect(described_class.azimuth('N 77° W')).to eq 283 + expect(described_class.azimuth('N 20 W')).to eq 340 + expect(described_class.azimuth('S 30° W')).to eq 210 end end describe '.back_azimuth' do it 'returns opposite of azimuth' do - expect(CompassPoint.back_azimuth('N')).to eq 180.0 - expect(CompassPoint.back_azimuth(:nw)).to eq 135.0 - expect(CompassPoint.back_azimuth('sbw')).to eq 11.25 - expect(CompassPoint.back_azimuth('X')).to be_nil - expect(CompassPoint.back_azimuth('Northeast by east')).to eq 236.25 - expect(CompassPoint.back_azimuth('N 27° E')).to eq 207 - expect(CompassPoint.back_azimuth('S 77° E')).to eq 283 - expect(CompassPoint.back_azimuth('S 2° E')).to eq 358 - expect(CompassPoint.back_azimuth('N 77° W')).to eq 103 - expect(CompassPoint.back_azimuth('N 20 W')).to eq 160 - expect(CompassPoint.back_azimuth('S 30° W')).to eq 30 + expect(described_class.back_azimuth('N')).to eq 180.0 + expect(described_class.back_azimuth(:nw)).to eq 135.0 + expect(described_class.back_azimuth('sbw')).to eq 11.25 + expect(described_class.back_azimuth('X')).to be_nil + expect(described_class.back_azimuth('Northeast by east')).to eq 236.25 + expect(described_class.back_azimuth('N 27° E')).to eq 207 + expect(described_class.back_azimuth('S 77° E')).to eq 283 + expect(described_class.back_azimuth('S 2° E')).to eq 358 + expect(described_class.back_azimuth('N 77° W')).to eq 103 + expect(described_class.back_azimuth('N 20 W')).to eq 160 + expect(described_class.back_azimuth('S 30° W')).to eq 30 end end describe '.min' do it 'returns min point in degrees' do - expect(CompassPoint.min('N')).to eq 354.38 - expect(CompassPoint.min(:nw)).to eq 309.38 - expect(CompassPoint.min('sbw')).to eq 185.63 - expect(CompassPoint.min('X')).to be_nil - expect(CompassPoint.min('Northeast by east')).to eq 50.63 + expect(described_class.min('N')).to eq 354.38 + expect(described_class.min(:nw)).to eq 309.38 + expect(described_class.min('sbw')).to eq 185.63 + expect(described_class.min('X')).to be_nil + expect(described_class.min('Northeast by east')).to eq 50.63 end end describe '.max' do it 'returns max point in degrees' do - expect(CompassPoint.max('N')).to eq 5.62 - expect(CompassPoint.max(:nw)).to eq 320.62 - expect(CompassPoint.max('sbw')).to eq 196.87 - expect(CompassPoint.max('X')).to be_nil - expect(CompassPoint.max('Northeast by east')).to eq 61.87 + expect(described_class.max('N')).to eq 5.62 + expect(described_class.max(:nw)).to eq 320.62 + expect(described_class.max('sbw')).to eq 196.87 + expect(described_class.max('X')).to be_nil + expect(described_class.max('Northeast by east')).to eq 61.87 end end describe '.min_max' do it 'returns [min, max]' do - expect(CompassPoint.min_max('N')).to eq [354.38, 5.62] - expect(CompassPoint.min_max(:nw)).to eq [309.38, 320.62] - expect(CompassPoint.min_max('sbw')).to eq [185.63, 196.87] - expect(CompassPoint.min_max('X')).to be_nil - expect(CompassPoint.min_max('Northeast by east')).to eq [50.63, 61.87] + expect(described_class.min_max('N')).to eq [354.38, 5.62] + expect(described_class.min_max(:nw)).to eq [309.38, 320.62] + expect(described_class.min_max('sbw')).to eq [185.63, 196.87] + expect(described_class.min_max('X')).to be_nil + expect(described_class.min_max('Northeast by east')).to eq [50.63, 61.87] end end describe '.name' do it 'returns the points full name' do - expect(CompassPoint.name('nnw')).to eq 'North northwest' + expect(described_class.name('nnw')).to eq 'North northwest' end end describe '.compass_quadrant_bearing' do it 'is' do - expect(CompassPoint.compass_quadrant_bearing(0)).to eq 'N' - expect(CompassPoint.compass_quadrant_bearing(27)).to eq 'N 27° E' - expect(CompassPoint.compass_quadrant_bearing(27.4)).to eq 'N 27° E' - expect(CompassPoint.compass_quadrant_bearing(27.7)).to eq 'N 28° E' - expect(CompassPoint.compass_quadrant_bearing(90)).to eq 'E' - expect(CompassPoint.compass_quadrant_bearing(103)).to eq 'S 77° E' - expect(CompassPoint.compass_quadrant_bearing(178)).to eq 'S 2° E' - expect(CompassPoint.compass_quadrant_bearing(180)).to eq 'S' - expect(CompassPoint.compass_quadrant_bearing(210)).to eq 'S 30° W' - expect(CompassPoint.compass_quadrant_bearing(270)).to eq 'W' - expect(CompassPoint.compass_quadrant_bearing(283)).to eq 'N 77° W' - expect(CompassPoint.compass_quadrant_bearing(340)).to eq 'N 20° W' - expect(CompassPoint.compass_quadrant_bearing(360)).to eq 'N' + expect(described_class.compass_quadrant_bearing(0)).to eq 'N' + expect(described_class.compass_quadrant_bearing(27)).to eq 'N 27° E' + expect(described_class.compass_quadrant_bearing(27.4)).to eq 'N 27° E' + expect(described_class.compass_quadrant_bearing(27.7)).to eq 'N 28° E' + expect(described_class.compass_quadrant_bearing(90)).to eq 'E' + expect(described_class.compass_quadrant_bearing(103)).to eq 'S 77° E' + expect(described_class.compass_quadrant_bearing(178)).to eq 'S 2° E' + expect(described_class.compass_quadrant_bearing(180)).to eq 'S' + expect(described_class.compass_quadrant_bearing(210)).to eq 'S 30° W' + expect(described_class.compass_quadrant_bearing(270)).to eq 'W' + expect(described_class.compass_quadrant_bearing(283)).to eq 'N 77° W' + expect(described_class.compass_quadrant_bearing(340)).to eq 'N 20° W' + expect(described_class.compass_quadrant_bearing(360)).to eq 'N' end end - end