From 20e9be19349d0bead26fb6cad68e3b5da7fcc448 Mon Sep 17 00:00:00 2001 From: Peter Goldstein Date: Mon, 13 Feb 2023 21:22:03 -0500 Subject: [PATCH] Enable new cops by default. Add in recommended rubocop libraries. Address or allowlist lints. --- .github/workflows/lint.yml | 1 - .rubocop.yml | 5 +++ .rubocop_todo.yml | 36 ++++++++++++++++++++- CHANGELOG.md | 1 + Gemfile | 2 ++ lib/ruby-enum/errors/base.rb | 2 +- ruby-enum.gemspec | 1 + spec/ruby-enum/enum_spec.rb | 62 +++++++++++++++++++++++++----------- 8 files changed, 88 insertions(+), 22 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 1d5f094..9ffe62f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -9,7 +9,6 @@ jobs: uses: actions/checkout@v3 - name: Set up Ruby uses: ruby/setup-ruby@v1 - with: with: ruby-version: 2.7 bundler-cache: true diff --git a/.rubocop.yml b/.rubocop.yml index 1336681..b55a7df 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,10 @@ +require: + - rubocop-rake + - rubocop-rspec + AllCops: TargetRubyVersion: 2.7 + NewCops: enable Exclude: - vendor/**/* diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 0f8a86b..641b22e 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2023-02-13 20:38:06 UTC using RuboCop version 1.45.1. +# on 2023-02-14 01:34:25 UTC using RuboCop version 1.45.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -28,6 +28,40 @@ Naming/MethodParameterName: Exclude: - 'lib/ruby-enum/enum.rb' +# Offense count: 3 +# Configuration parameters: CountAsOne. +RSpec/ExampleLength: + Max: 11 + +# Offense count: 2 +# Configuration parameters: Include, CustomTransform, IgnoreMethods, SpecSuffixOnly. +# Include: **/*_spec*rb*, **/spec/**/* +RSpec/FilePath: + Exclude: + - 'spec/ruby-enum/enum_spec.rb' + - 'spec/ruby-enum/version_spec.rb' + +# Offense count: 4 +RSpec/LeakyConstantDeclaration: + Exclude: + - 'spec/ruby-enum/enum_spec.rb' + +# Offense count: 6 +RSpec/MultipleExpectations: + Max: 11 + +# Offense count: 18 +# Configuration parameters: EnforcedStyle, IgnoreSharedExamples. +# SupportedStyles: always, named_only +RSpec/NamedSubject: + Exclude: + - 'spec/ruby-enum/enum_spec.rb' + +# Offense count: 1 +# Configuration parameters: AllowedGroups. +RSpec/NestedGroups: + Max: 4 + # Offense count: 4 # Configuration parameters: AllowedConstants. Style/Documentation: diff --git a/CHANGELOG.md b/CHANGELOG.md index b72ed02..3c810f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### 0.9.1 (Next) +* [#40](https://github.com/dblock/ruby-enum/pull/39): Enable new Rubocop cops and address/allowlist lints - [@petergoldstein](https://github.com/petergoldstein). * [#39](https://github.com/dblock/ruby-enum/pull/39): Require Ruby >= 2.7 - [@petergoldstein](https://github.com/petergoldstein). * [#38](https://github.com/dblock/ruby-enum/pull/38): Ensure Ruby >= 2.3 - [@ojab](https://github.com/ojab). * Your contribution here. diff --git a/Gemfile b/Gemfile index 341e2d3..dc4319a 100644 --- a/Gemfile +++ b/Gemfile @@ -12,6 +12,8 @@ group :development, :test do gem 'danger-toc', '0.2.0' gem 'rspec', '~> 3.0' gem 'rubocop', '~> 1.0' + gem 'rubocop-rake' + gem 'rubocop-rspec' end group :test do diff --git a/lib/ruby-enum/errors/base.rb b/lib/ruby-enum/errors/base.rb index dc6822f..c1fd922 100644 --- a/lib/ruby-enum/errors/base.rb +++ b/lib/ruby-enum/errors/base.rb @@ -22,7 +22,7 @@ def compose_message(key, attributes = {}) @summary = create_summary(key, attributes) @resolution = create_resolution(key, attributes) - "\nProblem:\n #{@problem}"\ + "\nProblem:\n #{@problem}" \ "\nSummary:\n #{@summary}" + "\nResolution:\n #{@resolution}" end diff --git a/ruby-enum.gemspec b/ruby-enum.gemspec index 31aeaca..46fe6e0 100644 --- a/ruby-enum.gemspec +++ b/ruby-enum.gemspec @@ -17,4 +17,5 @@ Gem::Specification.new do |s| s.licenses = ['MIT'] s.summary = 'Enum-like behavior for Ruby.' s.add_dependency 'i18n' + s.metadata['rubygems_mfa_required'] = 'true' end diff --git a/spec/ruby-enum/enum_spec.rb b/spec/ruby-enum/enum_spec.rb index 6a7e560..9ef7c9e 100644 --- a/spec/ruby-enum/enum_spec.rb +++ b/spec/ruby-enum/enum_spec.rb @@ -22,10 +22,12 @@ class SecondSubclass < FirstSubclass expect(Colors::RED).to eq 'red' expect(Colors::GREEN).to eq 'green' end + it 'raises UninitializedConstantError on an invalid constant' do expect { Colors::ANYTHING }.to raise_error Ruby::Enum::Errors::UninitializedConstantError, /The constant Colors::ANYTHING has not been defined./ end - context '#each' do + + describe '#each' do it 'iterates over constants' do keys = [] enum_keys = [] @@ -40,7 +42,8 @@ class SecondSubclass < FirstSubclass expect(enum_values).to eq %w[red green] end end - context '#map' do + + describe '#map' do it 'maps constants' do key_key_values = Colors.map do |key, enum| [key, enum.key, enum.value] @@ -50,87 +53,104 @@ class SecondSubclass < FirstSubclass expect(key_key_values[1]).to eq [:GREEN, :GREEN, 'green'] end end - context '#parse' do + + describe '#parse' do it 'parses exact value' do expect(Colors.parse('red')).to eq(Colors::RED) end + it 'is case-insensitive' do expect(Colors.parse('ReD')).to eq(Colors::RED) end + it 'returns nil for a null value' do expect(Colors.parse(nil)).to be_nil end + it 'returns nil for an invalid value' do expect(Colors.parse('invalid')).to be_nil end end - context '#key?' do + + describe '#key?' do it 'returns true for valid keys accessed directly' do Colors.keys.each do |key| # rubocop:disable Style/HashEachMethods - expect(Colors.key?(key)).to eq(true) + expect(Colors.key?(key)).to be(true) end end + it 'returns true for valid keys accessed via each_keys' do Colors.each_key do |key| - expect(Colors.key?(key)).to eq(true) + expect(Colors.key?(key)).to be(true) end end + it 'returns false for invalid keys' do - expect(Colors.key?(:NOT_A_KEY)).to eq(false) + expect(Colors.key?(:NOT_A_KEY)).to be(false) end end - context '#value' do + + describe '#value' do it 'returns string values for keys' do Colors.each do |key, enum| expect(Colors.value(key)).to eq(enum.value) end end + it 'returns nil for an invalid key' do expect(Colors.value(:NOT_A_KEY)).to be_nil end end - context '#value?' do + + describe '#value?' do it 'returns true for valid values accessed directly' do Colors.values.each do |value| # rubocop:disable Style/HashEachMethods - expect(Colors.value?(value)).to eq(true) + expect(Colors.value?(value)).to be(true) end end + it 'returns true for valid values accessed via each_value' do Colors.each_value do |value| - expect(Colors.value?(value)).to eq(true) + expect(Colors.value?(value)).to be(true) end end + it 'returns false for invalid values' do - expect(Colors.value?('I am not a value')).to eq(false) + expect(Colors.value?('I am not a value')).to be(false) end end - context '#key' do + + describe '#key' do it 'returns enum instances for values' do Colors.each do |_, enum| expect(Colors.key(enum.value)).to eq(enum.key) end end + it 'returns nil for an invalid value' do expect(Colors.key('invalid')).to be_nil end end - context '#keys' do + + describe '#keys' do it 'returns keys' do expect(Colors.keys).to eq(%i[RED GREEN]) end end - context '#values' do + + describe '#values' do it 'returns values' do expect(Colors.values).to eq(%w[red green]) end end - context '#to_h' do + + describe '#to_h' do it 'returns a hash of key:values' do expect(Colors.to_h).to eq(RED: 'red', GREEN: 'green') end end - context 'on duplicate keys' do + context 'when a duplicate key is used' do it 'raises DuplicateKeyError' do expect do Colors.class_eval do @@ -140,7 +160,7 @@ class SecondSubclass < FirstSubclass end end - context 'on duplicate values' do + context 'when a duplicate value is used' do it 'raises a DuplicateValueError' do expect do Colors.class_eval do @@ -176,11 +196,14 @@ class EmptyEnums it 'contains its own enums' do expect(FirstSubclass::ORANGE).to eq 'orange' end + it 'parent class should not have enums defined in child classes' do expect { Colors::ORANGE }.to raise_error Ruby::Enum::Errors::UninitializedConstantError end - context 'Given a 2 level depth subclass' do + + context 'when defining a 2 level depth subclass' do subject { SecondSubclass } + it 'contains its own enums and all the enums defined in the parent classes' do expect(subject::RED).to eq 'red' expect(subject::GREEN).to eq 'green' @@ -227,6 +250,7 @@ class States define :undefined end subject { States } + it 'behaves like an enum' do expect(subject.created).to eq 'Created' expect(subject.published).to eq 'Published'