activeinteractor 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +59 -1
  3. data/README.md +20 -5
  4. data/lib/active_interactor.rb +1 -0
  5. data/lib/active_interactor/config.rb +1 -1
  6. data/lib/active_interactor/context/attributes.rb +56 -11
  7. data/lib/active_interactor/context/base.rb +1 -0
  8. data/lib/active_interactor/context/errors.rb +47 -0
  9. data/lib/active_interactor/context/loader.rb +1 -1
  10. data/lib/active_interactor/context/status.rb +12 -19
  11. data/lib/active_interactor/interactor/context.rb +2 -1
  12. data/lib/active_interactor/interactor/perform.rb +5 -1
  13. data/lib/active_interactor/models.rb +13 -28
  14. data/lib/active_interactor/organizer/interactor_interface.rb +25 -8
  15. data/lib/active_interactor/organizer/interactor_interface_collection.rb +1 -0
  16. data/lib/active_interactor/organizer/perform.rb +11 -2
  17. data/lib/active_interactor/rails/orm/dynamoid.rb +5 -0
  18. data/lib/active_interactor/rails/orm/mongoid.rb +5 -0
  19. data/lib/active_interactor/version.rb +1 -1
  20. data/lib/rails/generators/templates/organizer.erb +2 -2
  21. data/spec/active_interactor/base_spec.rb +33 -0
  22. data/spec/active_interactor/context/base_spec.rb +44 -1
  23. data/spec/active_interactor/organizer/interactor_interface_spec.rb +74 -2
  24. data/spec/integration/a_basic_organizer_spec.rb +53 -1
  25. data/spec/integration/active_record_integration_spec.rb +8 -342
  26. data/spec/integration/an_organizer_with_failing_nested_organizer_spec.rb +47 -0
  27. data/spec/integration/an_organizer_with_options_callbacks_spec.rb +63 -0
  28. data/spec/spec_helper.rb +18 -8
  29. data/spec/support/shared_examples/a_class_that_extends_active_interactor_models_example.rb +81 -0
  30. metadata +40 -41
  31. data/spec/support/coverage.rb +0 -4
  32. data/spec/support/coverage/reporters.rb +0 -11
  33. data/spec/support/coverage/reporters/codacy.rb +0 -39
  34. data/spec/support/coverage/reporters/simple_cov.rb +0 -54
  35. data/spec/support/coverage/runner.rb +0 -66
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe 'An organizer with failing nested organizer', type: :integration do
6
+ let!(:parent_interactor1) { build_interactor('TestParentInteractor1') }
7
+ let!(:parent_interactor2) { build_interactor('TestParentInteractor2') }
8
+ let!(:child_interactor1) { build_interactor('TestChildInteractor1') }
9
+ let!(:child_interactor2) do
10
+ build_interactor('TestChildInteractor2') do
11
+ def perform
12
+ context.fail!
13
+ end
14
+ end
15
+ end
16
+
17
+ let!(:child_interactor_class) do
18
+ build_organizer('TestChildOrganizer') do
19
+ organize TestChildInteractor1, TestChildInteractor2
20
+ end
21
+ end
22
+
23
+ let(:parent_interactor_class) do
24
+ build_organizer('TestParentOrganizer') do
25
+ organize TestParentInteractor1, TestChildOrganizer, TestParentInteractor2
26
+ end
27
+ end
28
+
29
+ describe '.perform' do
30
+ subject { parent_interactor_class.perform }
31
+
32
+ before do
33
+ expect_any_instance_of(child_interactor_class).to receive(:perform).exactly(:once).and_call_original
34
+ expect_any_instance_of(child_interactor1).to receive(:perform).exactly(:once).and_call_original
35
+ expect_any_instance_of(child_interactor2).to receive(:perform).exactly(:once).and_call_original
36
+ expect_any_instance_of(child_interactor2).to receive(:rollback).exactly(:once).and_call_original
37
+ expect_any_instance_of(child_interactor1).to receive(:rollback).exactly(:once).and_call_original
38
+ expect_any_instance_of(parent_interactor1).to receive(:rollback).exactly(:once).and_call_original
39
+ expect_any_instance_of(parent_interactor2).not_to receive(:perform).exactly(:once).and_call_original
40
+ expect_any_instance_of(parent_interactor2).not_to receive(:rollback).exactly(:once).and_call_original
41
+ end
42
+
43
+ it { is_expected.to be_a parent_interactor_class.context_class }
44
+
45
+ it { is_expected.to be_failure }
46
+ end
47
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe 'An organizer with options callbacks', type: :integration do
6
+ let!(:interactor1) do
7
+ build_interactor('TestInteractor1') do
8
+ def perform
9
+ context.step = 3 if context.step == 2
10
+ context.step = 6 if context.step == 5
11
+ end
12
+ end
13
+ end
14
+
15
+ let(:interactor_class) do
16
+ build_organizer do
17
+ organize do
18
+ add TestInteractor1, before: :test_before_method, after: :test_after_method
19
+ add TestInteractor1, before: lambda {
20
+ context.step = 5 if context.step == 4
21
+ }, after: lambda {
22
+ context.step = 7 if context.step == 6
23
+ }
24
+ end
25
+
26
+ private
27
+
28
+ def test_before_method
29
+ context.step = 2 if context.step == 1
30
+ end
31
+
32
+ def test_after_method
33
+ context.step = 4 if context.step == 3
34
+ end
35
+ end
36
+ end
37
+
38
+ include_examples 'a class with interactor methods'
39
+ include_examples 'a class with interactor callback methods'
40
+ include_examples 'a class with interactor context methods'
41
+ include_examples 'a class with organizer callback methods'
42
+
43
+ describe '.perform' do
44
+ subject { interactor_class.perform(step: 1) }
45
+
46
+ it { is_expected.to be_a interactor_class.context_class }
47
+ it 'is expected to receive #test_before_method once' do
48
+ expect_any_instance_of(interactor_class).to receive(:test_before_method)
49
+ .exactly(:once)
50
+ subject
51
+ end
52
+
53
+ it 'is expected to receive #test_after_method once' do
54
+ expect_any_instance_of(interactor_class).to receive(:test_after_method)
55
+ .exactly(:once)
56
+ subject
57
+ end
58
+
59
+ it 'runs callbacks in sequence' do
60
+ expect(subject.step).to eq(7)
61
+ end
62
+ end
63
+ end
@@ -1,13 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'support/coverage'
4
-
5
- Spec::Coverage::Runner.start do
6
- add_formatter :simple_cov_html
7
- add_formatter :codacy
8
- track '/lib/**/*.rb'
9
- filter '/spec/'
10
- filter '/lib/rails/**'
3
+ begin
4
+ require 'simplecov'
5
+ require 'simplecov-lcov'
6
+
7
+ SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true
8
+
9
+ SimpleCov.start do
10
+ enable_coverage :branch
11
+ add_filter '/spec/'
12
+ add_filter '/lib/rails/**/*.rb'
13
+ track_files '/lib/**/*.rb'
14
+ formatter SimpleCov::Formatter::MultiFormatter.new([
15
+ SimpleCov::Formatter::HTMLFormatter,
16
+ SimpleCov::Formatter::LcovFormatter
17
+ ])
18
+ end
19
+ rescue LoadError
20
+ puts 'Skipping coverage...'
11
21
  end
12
22
 
13
23
  require 'bundler/setup'
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.shared_examples 'A class that extends ActiveInteractor::Models' do
4
+ it { expect(model_class).to respond_to :attribute }
5
+ it { expect(model_class).to respond_to :attributes }
6
+
7
+ describe 'as an instance' do
8
+ subject { model_class.new }
9
+
10
+ it { is_expected.to respond_to :attributes }
11
+ it { is_expected.to respond_to :called! }
12
+ it { is_expected.to respond_to :fail! }
13
+ it { is_expected.to respond_to :fail? }
14
+ it { is_expected.to respond_to :failure? }
15
+ it { is_expected.to respond_to :merge! }
16
+ it { is_expected.to respond_to :rollback! }
17
+ it { is_expected.to respond_to :success? }
18
+ it { is_expected.to respond_to :successful? }
19
+ end
20
+
21
+ describe '.new' do
22
+ subject { model_class.new(attributes) }
23
+
24
+ describe 'with arguments {:foo => "foo"}' do
25
+ let(:attributes) { { foo: 'foo' } }
26
+
27
+ it { is_expected.to have_attributes(foo: 'foo') }
28
+ end
29
+
30
+ describe 'with arguments {:bar => "bar"}' do
31
+ let(:attributes) { model_class.new(bar: 'bar') }
32
+
33
+ it { expect { subject }.to raise_error(ActiveModel::UnknownAttributeError) }
34
+ end
35
+
36
+ describe 'with arguments <#ModelClass foo="foo">' do
37
+ let(:other_instance) { model_class.new(foo: 'foo') }
38
+ let(:attributes) { other_instance }
39
+
40
+ it { is_expected.to have_attributes(foo: 'foo') }
41
+
42
+ context 'with argument instance having @_failed eq to true' do
43
+ before { other_instance.instance_variable_set('@_failed', true) }
44
+
45
+ it { is_expected.to be_failure }
46
+ end
47
+
48
+ context 'with argument instance having @_called eq to ["foo"]' do
49
+ before { other_instance.instance_variable_set('@_called', %w[foo]) }
50
+
51
+ it 'is expected to have instance variable @_called eq to ["foo"]' do
52
+ expect(subject.instance_variable_get('@_called')).to eq %w[foo]
53
+ end
54
+ end
55
+
56
+ context 'with argument instance having @_rolled_back eq to true' do
57
+ before { other_instance.instance_variable_set('@_rolled_back', true) }
58
+
59
+ it 'is expected to have instance variable @_rolled_back eq to true' do
60
+ expect(subject.instance_variable_get('@_rolled_back')).to eq true
61
+ end
62
+ end
63
+ end
64
+
65
+ describe 'with arguments <#OtherClass bar="bar">' do
66
+ let(:attributes) { model_class.new(other_instance) }
67
+ let!(:other_class) do
68
+ build_class('OtherClass') do
69
+ include ActiveModel::Attributes
70
+ include ActiveModel::Model
71
+ extend ActiveInteractor::Models
72
+ acts_as_context
73
+ attribute :bar
74
+ end
75
+ end
76
+ let(:other_instance) { other_class.new(bar: 'bar') }
77
+
78
+ it { expect { subject }.to raise_error(ActiveModel::UnknownAttributeError) }
79
+ end
80
+ end
81
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activeinteractor
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Allen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-01-28 00:00:00.000000000 Z
11
+ date: 2020-10-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -111,6 +111,7 @@ files:
111
111
  - lib/active_interactor/configurable.rb
112
112
  - lib/active_interactor/context/attributes.rb
113
113
  - lib/active_interactor/context/base.rb
114
+ - lib/active_interactor/context/errors.rb
114
115
  - lib/active_interactor/context/loader.rb
115
116
  - lib/active_interactor/context/status.rb
116
117
  - lib/active_interactor/error.rb
@@ -127,6 +128,8 @@ files:
127
128
  - lib/active_interactor/organizer/perform.rb
128
129
  - lib/active_interactor/rails.rb
129
130
  - lib/active_interactor/rails/orm/active_record.rb
131
+ - lib/active_interactor/rails/orm/dynamoid.rb
132
+ - lib/active_interactor/rails/orm/mongoid.rb
130
133
  - lib/active_interactor/rails/railtie.rb
131
134
  - lib/active_interactor/version.rb
132
135
  - lib/rails/generators/active_interactor.rb
@@ -185,13 +188,11 @@ files:
185
188
  - spec/integration/an_organizer_with_around_each_callbacks_spec.rb
186
189
  - spec/integration/an_organizer_with_before_each_callbacks_spec.rb
187
190
  - spec/integration/an_organizer_with_conditionally_organized_interactors_spec.rb
191
+ - spec/integration/an_organizer_with_failing_nested_organizer_spec.rb
192
+ - spec/integration/an_organizer_with_options_callbacks_spec.rb
188
193
  - spec/spec_helper.rb
189
- - spec/support/coverage.rb
190
- - spec/support/coverage/reporters.rb
191
- - spec/support/coverage/reporters/codacy.rb
192
- - spec/support/coverage/reporters/simple_cov.rb
193
- - spec/support/coverage/runner.rb
194
194
  - spec/support/helpers/factories.rb
195
+ - spec/support/shared_examples/a_class_that_extends_active_interactor_models_example.rb
195
196
  - spec/support/shared_examples/a_class_with_interactor_callback_methods_example.rb
196
197
  - spec/support/shared_examples/a_class_with_interactor_context_methods_example.rb
197
198
  - spec/support/shared_examples/a_class_with_interactor_methods_example.rb
@@ -202,10 +203,10 @@ licenses:
202
203
  - MIT
203
204
  metadata:
204
205
  bug_tracker_uri: https://github.com/aaronmallen/activeinteractor/issues
205
- changelog_uri: https://github.com/aaronmallen/activeinteractor/blob/v1.0.1/CHANGELOG.md
206
- documentation_uri: https://www.rubydoc.info/gems/activeinteractor/1.0.1
206
+ changelog_uri: https://github.com/aaronmallen/activeinteractor/blob/v1.1.0/CHANGELOG.md
207
+ documentation_uri: https://www.rubydoc.info/gems/activeinteractor/1.1.0
207
208
  hompage_uri: https://github.com/aaronmallen/activeinteractor
208
- source_code_uri: https://github.com/aaronmallen/activeinteractor/tree/v1.0.1
209
+ source_code_uri: https://github.com/aaronmallen/activeinteractor/tree/v1.1.0
209
210
  wiki_uri: https://github.com/aaronmallen/activeinteractor/wiki
210
211
  post_install_message:
211
212
  rdoc_options: []
@@ -227,45 +228,43 @@ signing_key:
227
228
  specification_version: 4
228
229
  summary: Ruby interactors with ActiveModel::Validations
229
230
  test_files:
230
- - spec/active_interactor_spec.rb
231
- - spec/integration/a_failing_interactor_spec.rb
232
- - spec/integration/active_record_integration_spec.rb
231
+ - spec/support/shared_examples/a_class_that_extends_active_interactor_models_example.rb
232
+ - spec/support/shared_examples/a_class_with_interactor_methods_example.rb
233
+ - spec/support/shared_examples/a_class_with_interactor_context_methods_example.rb
234
+ - spec/support/shared_examples/a_class_with_organizer_callback_methods_example.rb
235
+ - spec/support/shared_examples/a_class_with_interactor_callback_methods_example.rb
236
+ - spec/support/spec_helpers.rb
237
+ - spec/support/helpers/factories.rb
238
+ - spec/integration/an_organizer_with_options_callbacks_spec.rb
239
+ - spec/integration/an_interactor_with_validations_on_calling_spec.rb
240
+ - spec/integration/an_organizer_with_failing_nested_organizer_spec.rb
241
+ - spec/integration/a_basic_interactor_spec.rb
242
+ - spec/integration/a_basic_organizer_spec.rb
243
+ - spec/integration/an_organizer_with_conditionally_organized_interactors_spec.rb
244
+ - spec/integration/an_interactor_with_validations_spec.rb
245
+ - spec/integration/an_interactor_with_an_existing_context_class_spec.rb
246
+ - spec/integration/an_organizer_with_around_each_callbacks_spec.rb
233
247
  - spec/integration/an_interactor_with_validations_on_called_spec.rb
234
248
  - spec/integration/an_interactor_with_around_perform_callbacks_spec.rb
235
249
  - spec/integration/an_interactor_with_before_rollback_callbacks_spec.rb
236
- - spec/integration/a_basic_organizer_spec.rb
250
+ - spec/integration/an_interactor_with_before_perform_callbacks_spec.rb
237
251
  - spec/integration/an_interactor_with_around_rollback_callbacks_spec.rb
252
+ - spec/integration/an_interactor_with_after_perform_callbacks_spec.rb
253
+ - spec/integration/an_interactor_with_after_context_validation_callbacks_spec.rb
238
254
  - spec/integration/an_organizer_with_after_each_callbacks_spec.rb
255
+ - spec/integration/active_record_integration_spec.rb
256
+ - spec/integration/a_failing_interactor_spec.rb
257
+ - spec/integration/an_organizer_with_before_each_callbacks_spec.rb
239
258
  - spec/integration/an_organizer_performing_in_parallel_spec.rb
240
- - spec/integration/an_interactor_with_an_existing_context_class_spec.rb
241
259
  - spec/integration/an_interactor_with_after_rollback_callbacks_spec.rb
242
- - spec/integration/an_interactor_with_validations_spec.rb
243
- - spec/integration/a_basic_interactor_spec.rb
244
- - spec/integration/an_interactor_with_validations_on_calling_spec.rb
245
- - spec/integration/an_interactor_with_before_perform_callbacks_spec.rb
246
- - spec/integration/an_organizer_with_before_each_callbacks_spec.rb
247
- - spec/integration/an_organizer_with_conditionally_organized_interactors_spec.rb
248
- - spec/integration/an_organizer_with_around_each_callbacks_spec.rb
249
- - spec/integration/an_interactor_with_after_context_validation_callbacks_spec.rb
250
- - spec/integration/an_interactor_with_after_perform_callbacks_spec.rb
251
- - spec/support/spec_helpers.rb
252
- - spec/support/coverage/reporters.rb
253
- - spec/support/coverage/reporters/codacy.rb
254
- - spec/support/coverage/reporters/simple_cov.rb
255
- - spec/support/coverage/runner.rb
256
- - spec/support/shared_examples/a_class_with_organizer_callback_methods_example.rb
257
- - spec/support/shared_examples/a_class_with_interactor_callback_methods_example.rb
258
- - spec/support/shared_examples/a_class_with_interactor_methods_example.rb
259
- - spec/support/shared_examples/a_class_with_interactor_context_methods_example.rb
260
- - spec/support/helpers/factories.rb
261
- - spec/support/coverage.rb
262
- - spec/spec_helper.rb
260
+ - spec/active_interactor/interactor/worker_spec.rb
261
+ - spec/active_interactor/interactor/perform/options_spec.rb
263
262
  - spec/active_interactor/context/base_spec.rb
264
- - spec/active_interactor/base_spec.rb
265
263
  - spec/active_interactor/config_spec.rb
264
+ - spec/active_interactor/error_spec.rb
265
+ - spec/active_interactor/base_spec.rb
266
+ - spec/active_interactor/organizer/interactor_interface_collection_spec.rb
266
267
  - spec/active_interactor/organizer/base_spec.rb
267
268
  - spec/active_interactor/organizer/interactor_interface_spec.rb
268
- - spec/active_interactor/organizer/interactor_interface_collection_spec.rb
269
- - spec/active_interactor/interactor/worker_spec.rb
270
- - spec/active_interactor/interactor/perform/options_spec.rb
271
- - spec/active_interactor/error_spec.rb
269
+ - spec/spec_helper.rb
270
+ - spec/active_interactor_spec.rb
@@ -1,4 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'coverage/reporters'
4
- require_relative 'coverage/runner'
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Spec
4
- module Coverage
5
- module Reporters
6
- EMPTY_LOAD_RESULT = [{}, [], []].freeze
7
- end
8
- end
9
- end
10
-
11
- Dir[File.expand_path('reporters/*.rb', __dir__)].sort.each { |file| require file }
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Spec
4
- module Coverage
5
- module Reporters
6
- module Codacy
7
- class << self
8
- def load
9
- return EMPTY_LOAD_RESULT unless load_dependencies
10
-
11
- [formatters, initialize_steps, run_steps]
12
- end
13
-
14
- private
15
-
16
- def load_dependencies
17
- require 'codacy-coverage'
18
- true
19
- rescue LoadError
20
- puts 'Skipping Codacy Coverage reporting...'
21
- false
22
- end
23
-
24
- def formatters
25
- { codacy: ::Codacy::Formatter }
26
- end
27
-
28
- def initialize_steps
29
- []
30
- end
31
-
32
- def run_steps
33
- []
34
- end
35
- end
36
- end
37
- end
38
- end
39
- end
@@ -1,54 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Spec
4
- module Coverage
5
- module Reporters
6
- module SimpleCov
7
- class << self
8
- def load
9
- return EMPTY_LOAD_RESULT unless load_dependencies
10
-
11
- [formatters, initialize_steps, run_steps]
12
- end
13
-
14
- private
15
-
16
- def load_dependencies
17
- require 'simplecov'
18
- true
19
- rescue LoadError
20
- puts 'Skipping SimpleCov reporting...'
21
- false
22
- end
23
-
24
- def formatters
25
- { simple_cov_html: ::SimpleCov::Formatter::HTMLFormatter }
26
- end
27
-
28
- def initialize_steps
29
- [setup_formatters]
30
- end
31
-
32
- def run_steps
33
- [start_simplecov]
34
- end
35
-
36
- def setup_formatters
37
- lambda do |runner|
38
- ::SimpleCov.formatter = ::SimpleCov::Formatter::MultiFormatter.new(runner.formatters)
39
- end
40
- end
41
-
42
- def start_simplecov
43
- lambda do |runner|
44
- ::SimpleCov.start do
45
- runner.tracked_files.each { |f| track_files f }
46
- runner.filtered_files.each { |f| add_filter f }
47
- end
48
- end
49
- end
50
- end
51
- end
52
- end
53
- end
54
- end