diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..57771ec --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,49 @@ +Style/StringLiterals: + EnforcedStyle: double_quotes + +Style/FrozenStringLiteralComment: + Enabled: false + +# Allow some style changes in specs +Metrics/ModuleLength: + Exclude: + - spec/**/* +Metrics/BlockLength: + Exclude: + - spec/**/* +Style/BlockDelimiters: + Exclude: + - spec/**/* +Style/RescueModifier: + Exclude: + - spec/**/* +Metrics/MethodLength: + Exclude: + - spec/interactor/hooks_spec.rb +Style/IndentArray: + Exclude: + - spec/integration_spec.rb + - spec/interactor/hooks_spec.rb + +# Allow nice tree-like comments in specs +Style/AsciiComments: + Exclude: + - spec/integration_spec.rb + +# Here inconsistent indentation helps to understand +# tree nature of callbacks. +Style/AlignArray: + Exclude: + - spec/integration_spec.rb + +# This could be removed if throws are used instead of +# raising Failure in #fail! +Lint/HandleExceptions: + Exclude: + - lib/interactor.rb + +Style/EmptyMethod: + Enabled: false + +AllCops: + TargetRubyVersion: 2.0 diff --git a/.travis.yml b/.travis.yml index 2c3a874..2c72fad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,6 +15,7 @@ language: ruby matrix: allow_failures: - rvm: ruby-head + - rvm: "2.0" notifications: webhooks: on_start: always @@ -27,5 +28,5 @@ rvm: - "2.3.3" - "2.4.0" - ruby-head -script: bundle exec rspec +script: bundle exec rake sudo: false diff --git a/Gemfile b/Gemfile index b5be352..d309077 100644 --- a/Gemfile +++ b/Gemfile @@ -5,4 +5,5 @@ gemspec group :test do gem "codeclimate-test-reporter", require: false gem "rspec", "~> 3.2" + gem "rubocop", "~> 0.47.1" end diff --git a/Rakefile b/Rakefile index c92b11e..f0f5d6c 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,8 @@ require "bundler/gem_tasks" require "rspec/core/rake_task" +require "rubocop/rake_task" RSpec::Core::RakeTask.new(:spec) +RuboCop::RakeTask.new(:rubocop) -task default: :spec +task default: [:spec, :rubocop] diff --git a/interactor.gemspec b/interactor.gemspec index 12715cb..b8a4524 100644 --- a/interactor.gemspec +++ b/interactor.gemspec @@ -1,4 +1,5 @@ # encoding: utf-8 +require "English" Gem::Specification.new do |spec| spec.name = "interactor" @@ -6,14 +7,17 @@ Gem::Specification.new do |spec| spec.author = "Collective Idea" spec.email = "info@collectiveidea.com" - spec.description = "Interactor provides a common interface for performing complex user interactions." + spec.description = "Interactor provides a common interface for performing " \ + "complex user interactions." spec.summary = "Simple interactor implementation" spec.homepage = "https://github.com/collectiveidea/interactor" spec.license = "MIT" - spec.files = `git ls-files`.split($/) + spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR) spec.test_files = spec.files.grep(/^spec/) + spec.required_ruby_version = ">= 2.0" + spec.add_development_dependency "bundler", "~> 1.9" spec.add_development_dependency "rake", "~> 10.4" end diff --git a/lib/interactor/context.rb b/lib/interactor/context.rb index 030ef20..cb269d2 100644 --- a/lib/interactor/context.rb +++ b/lib/interactor/context.rb @@ -53,7 +53,7 @@ class Context < OpenStruct # # Returns the Interactor::Context. def self.build(context = {}) - self === context ? context : new(context) + context.is_a?(Context) ? context : new(context) end # Public: Whether the Interactor::Context is successful. By default, a new diff --git a/lib/interactor/hooks.rb b/lib/interactor/hooks.rb index d82e7a5..7ae4d00 100644 --- a/lib/interactor/hooks.rb +++ b/lib/interactor/hooks.rb @@ -219,9 +219,9 @@ def with_hooks # # Returns nothing. def run_around_hooks(&block) - self.class.around_hooks.reverse.inject(block) { |chain, hook| + self.class.around_hooks.reverse.inject(block) do |chain, hook| proc { run_hook(hook, chain) } - }.call + end.call end # Internal: Run before hooks. diff --git a/spec/integration_spec.rb b/spec/integration_spec.rb index 436f6b2..045fc0c 100644 --- a/spec/integration_spec.rb +++ b/spec/integration_spec.rb @@ -2,6 +2,11 @@ def build_interactor(&block) interactor = Class.new.send(:include, Interactor) interactor.class_eval(&block) if block + interactor.class_eval do + def unexpected_error! + raise "foo" + end + end interactor end @@ -9,6 +14,11 @@ def build_organizer(options = {}, &block) organizer = Class.new.send(:include, Interactor::Organizer) organizer.organize(options[:organize]) if options[:organize] organizer.class_eval(&block) if block + organizer.class_eval do + def unexpected_error! + raise "foo" + end + end organizer end @@ -25,7 +35,8 @@ def build_organizer(options = {}, &block) # └─ interactor5 let(:organizer) { - build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do + interactors = [organizer2, interactor3, organizer4, interactor5] + build_organizer(organize: interactors) do around do |interactor| context.steps << :around_before interactor.call @@ -315,7 +326,8 @@ def rollback context "when an around hook fails early" do let(:organizer) { - build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do + interactors = [organizer2, interactor3, organizer4, interactor5] + build_organizer(organize: interactors) do around do |interactor| context.fail! context.steps << :around_before @@ -345,9 +357,10 @@ def rollback context "when an around hook errors early" do let(:organizer) { - build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do + interactors = [organizer2, interactor3, organizer4, interactor5] + build_organizer(organize: interactors) do around do |interactor| - raise "foo" + unexpected_error! context.steps << :around_before interactor.call context.steps << :around_after @@ -381,7 +394,8 @@ def rollback context "when a before hook fails" do let(:organizer) { - build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do + interactors = [organizer2, interactor3, organizer4, interactor5] + build_organizer(organize: interactors) do around do |interactor| context.steps << :around_before interactor.call @@ -412,7 +426,8 @@ def rollback context "when a before hook errors" do let(:organizer) { - build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do + interactors = [organizer2, interactor3, organizer4, interactor5] + build_organizer(organize: interactors) do around do |interactor| context.steps << :around_before interactor.call @@ -420,7 +435,7 @@ def rollback end before do - raise "foo" + unexpected_error! context.steps << :before end @@ -449,7 +464,8 @@ def rollback context "when an after hook fails" do let(:organizer) { - build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do + interactors = [organizer2, interactor3, organizer4, interactor5] + build_organizer(organize: interactors) do around do |interactor| context.steps << :around_before interactor.call @@ -500,7 +516,8 @@ def rollback context "when an after hook errors" do let(:organizer) { - build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do + interactors = [organizer2, interactor3, organizer4, interactor5] + build_organizer(organize: interactors) do around do |interactor| context.steps << :around_before interactor.call @@ -512,7 +529,7 @@ def rollback end after do - raise "foo" + unexpected_error! context.steps << :after end end @@ -557,7 +574,8 @@ def rollback context "when an around hook fails late" do let(:organizer) { - build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do + interactors = [organizer2, interactor3, organizer4, interactor5] + build_organizer(organize: interactors) do around do |interactor| context.steps << :around_before interactor.call @@ -609,11 +627,12 @@ def rollback context "when an around hook errors late" do let(:organizer) { - build_organizer(organize: [organizer2, interactor3, organizer4, interactor5]) do + interactors = [organizer2, interactor3, organizer4, interactor5] + build_organizer(organize: interactors) do around do |interactor| context.steps << :around_before interactor.call - raise "foo" + unexpected_error! context.steps << :around_after end @@ -716,7 +735,7 @@ def rollback let(:interactor3) { build_interactor do around do |interactor| - raise "foo" + unexpected_error! context.steps << :around_before3 interactor.call context.steps << :around_after3 @@ -823,7 +842,7 @@ def rollback end before do - raise "foo" + unexpected_error! context.steps << :before3 end @@ -933,7 +952,7 @@ def rollback end def call - raise "foo" + unexpected_error! context.steps << :call3 end @@ -1032,7 +1051,7 @@ def rollback end after do - raise "foo" + unexpected_error! context.steps << :after3 end @@ -1128,7 +1147,7 @@ def rollback around do |interactor| context.steps << :around_before3 interactor.call - raise "foo" + unexpected_error! context.steps << :around_after3 end @@ -1233,7 +1252,7 @@ def rollback let(:interactor4b) { build_interactor do around do |interactor| - raise "foo" + unexpected_error! context.steps << :around_before4b interactor.call context.steps << :around_after4b @@ -1350,7 +1369,7 @@ def rollback end before do - raise "foo" + unexpected_error! context.steps << :before4b end @@ -1470,7 +1489,7 @@ def rollback end def call - raise "foo" + unexpected_error! context.steps << :call4b end @@ -1579,7 +1598,7 @@ def rollback end after do - raise "foo" + unexpected_error! context.steps << :after4b end @@ -1685,7 +1704,7 @@ def rollback around do |interactor| context.steps << :around_before4b interactor.call - raise "foo" + unexpected_error! context.steps << :around_after4b end diff --git a/spec/support/lint.rb b/spec/support/lint.rb index bfbc97c..73346e5 100644 --- a/spec/support/lint.rb +++ b/spec/support/lint.rb @@ -43,7 +43,8 @@ let(:context) { double(:context) } it "initializes a context" do - expect(Interactor::Context).to receive(:build).once.with(foo: "bar") { context } + expect(Interactor::Context).to receive(:build) + .once.with(foo: "bar") { context } instance = interactor.new(foo: "bar")