From 2d328a014ff2515eddea51b303d0e5ab2793faca Mon Sep 17 00:00:00 2001 From: Martin Spickermann Date: Mon, 25 Dec 2023 18:21:32 +0100 Subject: [PATCH] Switch from Rubocop to Standard (#14) --- .github/workflows/CI.yml | 12 +-- .rubocop.yml | 24 ------ .ruby-style.yml | 15 ---- .standard-rspec.yml | 2 + .standard.yml | 7 ++ CHANGELOG.md | 6 +- Gemfile | 17 ++-- README.md | 2 +- Rakefile | 9 +-- deep_hash_transformer.gemspec | 28 +++---- lib/deep_hash_transformer.rb | 22 ++--- lib/deep_hash_transformer/blank.rb | 8 +- .../collection_operation.rb | 2 +- .../element_operation.rb | 6 +- lib/deep_hash_transformer/version.rb | 2 +- spec/deep_hash_transformer/blank_spec.rb | 6 +- .../collection_operation_spec.rb | 10 +-- .../element_operation_spec.rb | 18 ++--- spec/deep_hash_transformer_spec.rb | 80 +++++++++---------- spec/spec_helper.rb | 22 ++--- 20 files changed, 135 insertions(+), 163 deletions(-) delete mode 100644 .rubocop.yml delete mode 100644 .ruby-style.yml create mode 100644 .standard-rspec.yml create mode 100644 .standard.yml diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 5d2757b..bbd048b 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -12,7 +12,7 @@ jobs: strategy: matrix: - ruby: [3.3.0-preview1, 3.2.2, 3.1.4, 3.0.5, 2.7.7, 2.6.10, 2.5.9] + ruby: [3.3.0, 3.2.2, 3.1.4, 3.0.6] name: CI Ruby ${{ matrix.ruby }} steps: @@ -26,18 +26,18 @@ jobs: run: bundle install - name: RSpec run: bundle exec rspec - - name: Rubocop - run: bundle exec rubocop + - name: Standard + run: bundle exec standardrb - name: Coveralls - if: ${{ matrix.ruby == '3.2.2' }} + if: ${{ matrix.ruby == '3.3.0' }} continue-on-error: true uses: coverallsapp/github-action@master with: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Code Climate - if: ${{ matrix.ruby == '3.2.2' }} + if: ${{ matrix.ruby == '3.3.0' }} continue-on-error: true - uses: paambaati/codeclimate-action@v4.0.0 + uses: paambaati/codeclimate-action@v5.0.0 env: CC_TEST_REPORTER_ID: ${{ secrets.CODE_CLIMATE_TOKEN }} with: diff --git a/.rubocop.yml b/.rubocop.yml deleted file mode 100644 index 83364ff..0000000 --- a/.rubocop.yml +++ /dev/null @@ -1,24 +0,0 @@ -inherit_from: - '.ruby-style.yml' -require: - - 'rubocop-rake' - - 'rubocop-rspec' - - 'rubocop-performance' - -Lint/RaiseException: - Enabled: true - -Lint/StructNewOverride: - Enabled: true - -RSpec/LeakyConstantDeclaration: - Enabled: false - -Style/HashEachMethods: - Enabled: true - -Style/HashTransformKeys: - Enabled: true - -Style/HashTransformValues: - Enabled: true diff --git a/.ruby-style.yml b/.ruby-style.yml deleted file mode 100644 index d62e1d4..0000000 --- a/.ruby-style.yml +++ /dev/null @@ -1,15 +0,0 @@ -AllCops: - NewCops: enable - TargetRubyVersion: 2.5 - -# personal preferences -Layout/LineLength: - Max: 99 - -Style/Documentation: - Enabled: false - -# gem specific configurations -Metrics/BlockLength: - Exclude: - - 'spec/**/*_spec.rb' # because RSpec's DSL encourages lengthly blocks diff --git a/.standard-rspec.yml b/.standard-rspec.yml new file mode 100644 index 0000000..c8e5453 --- /dev/null +++ b/.standard-rspec.yml @@ -0,0 +1,2 @@ +require: + - rubocop-rspec diff --git a/.standard.yml b/.standard.yml new file mode 100644 index 0000000..12ba421 --- /dev/null +++ b/.standard.yml @@ -0,0 +1,7 @@ +ruby_version: 3.0 + +plugins: + - standard-performance + +extend_config: + - .standard-rspec.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index f22b1f3..5ec1913 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,8 @@ -*Unreleased* +*2.2.1 (December 25, 2023)* + +* Ensure Ruby 3.3 compability +* Stop testing against Ruby < 3.0 +* Switch from Rubocop to Standard *2.2.0 (May 17, 2023)* diff --git a/Gemfile b/Gemfile index 39ed7c4..5954d64 100644 --- a/Gemfile +++ b/Gemfile @@ -1,12 +1,11 @@ # frozen_string_literal: true -source 'https://rubygems.org' +source "https://rubygems.org" -gem 'rake' -gem 'rspec' -gem 'rubocop' -gem 'rubocop-performance' -gem 'rubocop-rake' -gem 'rubocop-rspec' -gem 'simplecov' -gem 'simplecov-lcov' +gem "rake" +gem "rspec" +gem "rubocop-rspec" +gem "simplecov" +gem "simplecov-lcov" +gem "standard" +gem "standard-performance" diff --git a/README.md b/README.md index 332fe2d..d4719c9 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/spicke 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit your changes (`git commit -am 'Add some feature'`) 4. Push to the branch (`git push origin my-new-feature`) -5. Create a new pull request +5. Create a new pull request. ## License diff --git a/Rakefile b/Rakefile index eb88d47..cb74b42 100644 --- a/Rakefile +++ b/Rakefile @@ -1,12 +1,11 @@ # frozen_string_literal: true -require 'bundler/gem_tasks' -require 'rspec/core/rake_task' -require 'rubocop/rake_task' +require "bundler/gem_tasks" +require "rspec/core/rake_task" +require "standard/rake" RSpec::Core::RakeTask.new(:spec) do |t| t.verbose = false end -RuboCop::RakeTask.new(:rubocop) -task default: %i[spec rubocop] +task default: %i[spec standard] diff --git a/deep_hash_transformer.gemspec b/deep_hash_transformer.gemspec index fd6eefb..7f7ffe2 100644 --- a/deep_hash_transformer.gemspec +++ b/deep_hash_transformer.gemspec @@ -1,27 +1,27 @@ # frozen_string_literal: true -lib = File.expand_path('lib', __dir__) +lib = File.expand_path("lib", __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) -require 'deep_hash_transformer/version' +require "deep_hash_transformer/version" Gem::Specification.new do |spec| - spec.authors = ['Martin Spickermann'] - spec.email = ['spickermann@gmail.com'] - spec.homepage = 'https://github.com/spickermann/deep_hash_transformer' - spec.license = 'MIT' + spec.authors = ["Martin Spickermann"] + spec.email = ["spickermann@gmail.com"] + spec.homepage = "https://github.com/spickermann/deep_hash_transformer" + spec.license = "MIT" - spec.name = 'deep_hash_transformer' - spec.version = DeepHashTransformer::VERSION + spec.name = "deep_hash_transformer" + spec.version = DeepHashTransformer::VERSION - spec.summary = 'Transforms deeply nested hash structure' - spec.description = <<-DESCRIPTION + spec.summary = "Transforms deeply nested hash structure" + spec.description = <<-DESCRIPTION DeepHashTransformer helps to transform keys in deeply nested hash structures DESCRIPTION - spec.files = Dir['CHANGELOG', 'MIT-LICENSE', 'README', 'lib/**/*', 'spec/**/*'] + spec.files = Dir["CHANGELOG", "MIT-LICENSE", "README", "lib/**/*", "spec/**/*"] - spec.require_paths = ['lib'] - spec.required_ruby_version = '>= 2.5.0' + spec.require_paths = ["lib"] + spec.required_ruby_version = ">= 3.0.0" - spec.metadata['rubygems_mfa_required'] = 'true' + spec.metadata["rubygems_mfa_required"] = "true" end diff --git a/lib/deep_hash_transformer.rb b/lib/deep_hash_transformer.rb index b8f866e..7dbd2e8 100644 --- a/lib/deep_hash_transformer.rb +++ b/lib/deep_hash_transformer.rb @@ -1,8 +1,8 @@ # frozen_string_literal: true -require 'deep_hash_transformer/collection_operation' -require 'deep_hash_transformer/element_operation' -require 'deep_hash_transformer/version' +require "deep_hash_transformer/collection_operation" +require "deep_hash_transformer/element_operation" +require "deep_hash_transformer/version" class DeepHashTransformer ELEMENT_OPS = %i[ @@ -31,7 +31,7 @@ def tr(*ops) unknown_transformations = ops.map(&:to_s) - OPS.map(&:to_s) if unknown_transformations.any? raise( - ArgumentError, "unknown transformation(s): #{unknown_transformations.join(',')}" + ArgumentError, "unknown transformation(s): #{unknown_transformations.join(",")}" ) end @@ -54,13 +54,13 @@ def transform_collection(collection, ops) def transform_value(value, ops) collection = case value - when Array - value.map { |e| transform_value(e, ops) } - when Hash - value.map { |k, v| [transform_key(k, ops), transform_value(v, ops)] }.to_h - else - value - end + when Array + value.map { |e| transform_value(e, ops) } + when Hash + value.map { |k, v| [transform_key(k, ops), transform_value(v, ops)] }.to_h + else + value + end transform_collection(collection, ops) end diff --git a/lib/deep_hash_transformer/blank.rb b/lib/deep_hash_transformer/blank.rb index db3ddc5..c8271d3 100644 --- a/lib/deep_hash_transformer/blank.rb +++ b/lib/deep_hash_transformer/blank.rb @@ -2,7 +2,7 @@ class DeepHashTransformer class Blank - BLANK_STRING = /\A[[:space:]]*\z/.freeze + BLANK_STRING = /\A[[:space:]]*\z/ def self.call(value) new(value).blank? @@ -13,10 +13,10 @@ def initialize(value) end def blank? - return true unless value - return value.blank? if value.respond_to?(:blank?) + return true unless value + return value.blank? if value.respond_to?(:blank?) return BLANK_STRING.match?(value) if value.is_a?(String) - return value.empty? if value.respond_to?(:empty?) + return value.empty? if value.respond_to?(:empty?) false end diff --git a/lib/deep_hash_transformer/collection_operation.rb b/lib/deep_hash_transformer/collection_operation.rb index e703c12..7d08bb0 100644 --- a/lib/deep_hash_transformer/collection_operation.rb +++ b/lib/deep_hash_transformer/collection_operation.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -require_relative 'blank' +require_relative "blank" class DeepHashTransformer module CollectionOperation diff --git a/lib/deep_hash_transformer/element_operation.rb b/lib/deep_hash_transformer/element_operation.rb index 4edcce7..51fbe8a 100644 --- a/lib/deep_hash_transformer/element_operation.rb +++ b/lib/deep_hash_transformer/element_operation.rb @@ -10,7 +10,7 @@ def camel_case(val) def dasherize(val) stringify(val) - .tr('_', '-') + .tr("_", "-") end def identity(val) @@ -34,14 +34,14 @@ def symbolize(val) def underscore(val) stringify(val) - .tr('-', '_') + .tr("-", "_") end def snake_case(val) stringify(val) .gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2') .gsub(/([a-z\d])([A-Z])/, '\1_\2') - .tr('-', '_') + .tr("-", "_") .downcase end end diff --git a/lib/deep_hash_transformer/version.rb b/lib/deep_hash_transformer/version.rb index 0838b4e..8e5cd8d 100644 --- a/lib/deep_hash_transformer/version.rb +++ b/lib/deep_hash_transformer/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true class DeepHashTransformer - VERSION = '2.2.0' + VERSION = "2.2.1" end diff --git a/spec/deep_hash_transformer/blank_spec.rb b/spec/deep_hash_transformer/blank_spec.rb index aef9711..979881c 100644 --- a/spec/deep_hash_transformer/blank_spec.rb +++ b/spec/deep_hash_transformer/blank_spec.rb @@ -1,11 +1,11 @@ # frozen_string_literal: true RSpec.describe DeepHashTransformer::Blank do - describe '.call' do + describe ".call" do subject { described_class.call(value) } - presents = [true, 1, 0, 'any', [nil], { A: nil }] - blanks = [nil, false, '', ' ', [], {}] + presents = [true, 1, 0, "any", [nil], {A: nil}] + blanks = [nil, false, "", " ", [], {}] presents.each do |value| context "with #{value.inspect}" do diff --git a/spec/deep_hash_transformer/collection_operation_spec.rb b/spec/deep_hash_transformer/collection_operation_spec.rb index 4830e4e..79b05c9 100644 --- a/spec/deep_hash_transformer/collection_operation_spec.rb +++ b/spec/deep_hash_transformer/collection_operation_spec.rb @@ -2,28 +2,28 @@ RSpec.describe DeepHashTransformer::CollectionOperation do examples = [ - { a: 'b' }, { a: nil }, { a: ' ' }, [:foo], ['', nil] + {a: "b"}, {a: nil}, {a: " "}, [:foo], ["", nil] ] subject do examples.map { |value| described_class.public_send(method, value) } end - describe '.compact' do + describe ".compact" do let(:method) { :compact } expected_output = [ - { a: 'b' }, {}, { a: ' ' }, [:foo], [''] + {a: "b"}, {}, {a: " "}, [:foo], [""] ] it { is_expected.to eq(expected_output) } end - describe '.compact_blank' do + describe ".compact_blank" do let(:method) { :compact_blank } expected_output = [ - { a: 'b' }, {}, {}, [:foo], [] + {a: "b"}, {}, {}, [:foo], [] ] it { is_expected.to eq(expected_output) } diff --git a/spec/deep_hash_transformer/element_operation_spec.rb b/spec/deep_hash_transformer/element_operation_spec.rb index 8e4825d..01362bb 100644 --- a/spec/deep_hash_transformer/element_operation_spec.rb +++ b/spec/deep_hash_transformer/element_operation_spec.rb @@ -2,7 +2,7 @@ RSpec.describe DeepHashTransformer::ElementOperation do examples = [ - :symbol, 'string', 'camelCase', 'dashed-key', 'PascalCase', 'under_scored' + :symbol, "string", "camelCase", "dashed-key", "PascalCase", "under_scored" ] subject do @@ -11,14 +11,14 @@ # rubocop:disable Layout/HashAlignment, Style/SymbolArray, Style/WordArray expected_output = { - camel_case: ['symbol', 'string', 'camelCase', 'dashedKey', 'pascalCase', 'underScored'], - dasherize: ['symbol', 'string', 'camelCase', 'dashed-key', 'PascalCase', 'under-scored'], - identity: [:symbol, 'string', 'camelCase', 'dashed-key', 'PascalCase', 'under_scored'], - pascal_case: ['Symbol', 'String', 'CamelCase', 'DashedKey', 'PascalCase', 'UnderScored'], - snake_case: ['symbol', 'string', 'camel_case', 'dashed_key', 'pascal_case', 'under_scored'], - stringify: ['symbol', 'string', 'camelCase', 'dashed-key', 'PascalCase', 'under_scored'], - symbolize: [:symbol, :string, :camelCase, :'dashed-key', :PascalCase, :under_scored], - underscore: ['symbol', 'string', 'camelCase', 'dashed_key', 'PascalCase', 'under_scored'] + camel_case: ["symbol", "string", "camelCase", "dashedKey", "pascalCase", "underScored"], + dasherize: ["symbol", "string", "camelCase", "dashed-key", "PascalCase", "under-scored"], + identity: [:symbol, "string", "camelCase", "dashed-key", "PascalCase", "under_scored"], + pascal_case: ["Symbol", "String", "CamelCase", "DashedKey", "PascalCase", "UnderScored"], + snake_case: ["symbol", "string", "camel_case", "dashed_key", "pascal_case", "under_scored"], + stringify: ["symbol", "string", "camelCase", "dashed-key", "PascalCase", "under_scored"], + symbolize: [:symbol, :string, :camelCase, :"dashed-key", :PascalCase, :under_scored], + underscore: ["symbol", "string", "camelCase", "dashed_key", "PascalCase", "under_scored"] } # rubocop:enable Layout/HashAlignment, Style/SymbolArray, Style/WordArray diff --git a/spec/deep_hash_transformer_spec.rb b/spec/deep_hash_transformer_spec.rb index d6b71f0..b4d8e9b 100644 --- a/spec/deep_hash_transformer_spec.rb +++ b/spec/deep_hash_transformer_spec.rb @@ -3,9 +3,9 @@ RSpec.describe DeepHashTransformer do subject(:operation) { described_class.new(example) } - let(:example) { { foo: 'bar' } } + let(:example) { {foo: "bar"} } - describe 'autogenerated methods' do + describe "autogenerated methods" do DeepHashTransformer::ELEMENT_OPS.each do |method| describe ".#{method}" do it "delegates to `Operation.#{method}`" do @@ -19,37 +19,37 @@ end end - describe '#tr' do - context 'with `:snake_case, :symbolize`' do + describe "#tr" do + context "with `:snake_case, :symbolize`" do subject { super().tr(:snake_case, :symbolize) } - let(:example) { { 'FooBar' => 'baz' } } + let(:example) { {"FooBar" => "baz"} } - it { is_expected.to eq(foo_bar: 'baz') } + it { is_expected.to eq(foo_bar: "baz") } end - context 'with an unknown transformation' do + context "with an unknown transformation" do subject(:unknown_ops) { operation.tr(:unknown) } - it 'raise an exception' do + it "raise an exception" do expect { unknown_ops }.to raise_error(ArgumentError, /unknown/) end end - context 'with a complex, nested example' do + context "with a complex, nested example" do subject { super().tr(:camel_case, :symbolize) } let(:example) do { Integer => 123, - :symbol => { foo_bar: 'bar' }, - 'string' => { 'foo_bar' => 123 }, - 'nested-array' => [ + :symbol => {foo_bar: "bar"}, + "string" => {"foo_bar" => 123}, + "nested-array" => [ { - 'camelCased' => 'camelCased', - 'dashed-key' => 'dashed-key', - 'PascalCased' => 'PascalCased', - 'under_scored' => 'under_scored' + "camelCased" => "camelCased", + "dashed-key" => "dashed-key", + "PascalCased" => "PascalCased", + "under_scored" => "under_scored" } ] } @@ -58,71 +58,71 @@ it do # rubocop:disable RSpec/ExampleLength is_expected.to eq( # rubocop:disable RSpec/ImplicitSubject Integer => 123, - :symbol => { fooBar: 'bar' }, - :string => { fooBar: 123 }, + :symbol => {fooBar: "bar"}, + :string => {fooBar: 123}, :nestedArray => [ { - camelCased: 'camelCased', - dashedKey: 'dashed-key', - pascalCased: 'PascalCased', - underScored: 'under_scored' + camelCased: "camelCased", + dashedKey: "dashed-key", + pascalCased: "PascalCased", + underScored: "under_scored" } ] ) end end - context 'with nil values' do + context "with nil values" do subject { super().tr(:compact, :stringify) } let(:example) do - { a: { b: ['', nil, :value], c: '', d: nil, e: true, f: false, g: 123, h: [''] } } + {a: {b: ["", nil, :value], c: "", d: nil, e: true, f: false, g: 123, h: [""]}} end it do # rubocop:disable RSpec/ExampleLength is_expected.to eq( # rubocop:disable RSpec/ImplicitSubject - 'a' => { - 'b' => ['', :value], - 'c' => '', - 'e' => true, - 'f' => false, - 'g' => 123, - 'h' => [''] + "a" => { + "b" => ["", :value], + "c" => "", + "e" => true, + "f" => false, + "g" => 123, + "h" => [""] } ) end end - context 'with blank values' do + context "with blank values" do subject { super().tr(:compact_blank, :stringify) } let(:example) do - { a: { b: ['', nil, :value], c: '', d: nil, e: true, f: false, g: 123, h: [''] } } + {a: {b: ["", nil, :value], c: "", d: nil, e: true, f: false, g: 123, h: [""]}} end it do # rubocop:disable RSpec/ExampleLength is_expected.to eq( # rubocop:disable RSpec/ImplicitSubject - 'a' => { - 'b' => [:value], - 'e' => true, - 'g' => 123 + "a" => { + "b" => [:value], + "e" => true, + "g" => 123 } ) end end - context 'with deeply nested blank values' do + context "with deeply nested blank values" do subject { super().tr(:compact_blank) } let(:example) do - { a: { b: [nil, { c: nil }] } } + {a: {b: [nil, {c: nil}]}} end it { is_expected.to eq({}) } end end - it 'has a version number' do + it "has a version number" do expect(DeepHashTransformer::VERSION).not_to be_nil end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 35c8078..7d918a0 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,21 +1,21 @@ # frozen_string_literal: true -require 'bundler/setup' -require 'deep_hash_transformer' -require 'deep_hash_transformer/blank' -require 'deep_hash_transformer/collection_operation' -require 'deep_hash_transformer/element_operation' +require "bundler/setup" +require "deep_hash_transformer" +require "deep_hash_transformer/blank" +require "deep_hash_transformer/collection_operation" +require "deep_hash_transformer/element_operation" -require 'simplecov' +require "simplecov" SimpleCov.start do - if ENV['CI'] - require 'simplecov_json_formatter' - require 'simplecov-lcov' + if ENV["CI"] + require "simplecov_json_formatter" + require "simplecov-lcov" SimpleCov::Formatter::LcovFormatter.config do |c| c.report_with_single_file = true - c.single_report_path = 'coverage/lcov.info' + c.single_report_path = "coverage/lcov.info" end formatter SimpleCov::Formatter::MultiFormatter.new [ @@ -28,7 +28,7 @@ RSpec.configure do |config| # Enable flags like --only-failures and --next-failure - config.example_status_persistence_file_path = '.rspec_status' + config.example_status_persistence_file_path = ".rspec_status" config.expect_with :rspec do |c| c.syntax = :expect