interactor-strict 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1a672dc50d21ef4b2abc5fb2b15dce9a76215db114b90e6e875f245257022e09
4
+ data.tar.gz: af00d3e146d703307f507db32c7fc285b62b7e5c52cbf9011e33fd4c8b5b016d
5
+ SHA512:
6
+ metadata.gz: 0f5d50fc187bfa3a146df6f6aed6c1171bd6d98f8cd0c5e5ff1cb1bb6f9730849ec35a87ee09853b8d3e6b50d03d86472395ccee04af3f8161a0f4201fedca4a
7
+ data.tar.gz: fdf36277e93030d0da8be725b5d9ec4b1de057ba34c302816f830afac108f02cbd51e30883f7e7caa28ff3f884331db03cb181e2acfb2d5a76057536875d4c88
@@ -0,0 +1,35 @@
1
+ name: Run Tests
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - "master"
7
+ - "v3"
8
+ pull_request:
9
+ branches:
10
+ - '*'
11
+
12
+ jobs:
13
+ spec:
14
+ runs-on: ubuntu-latest
15
+
16
+ strategy:
17
+ matrix:
18
+ ruby_version:
19
+ - "2.7"
20
+ - "3.0"
21
+ - "3.1"
22
+ - "3.2"
23
+ - "head"
24
+
25
+ steps:
26
+ - uses: actions/checkout@v2
27
+
28
+ - name: Set up Ruby
29
+ uses: ruby/setup-ruby@v1
30
+ with:
31
+ ruby-version: ${{ matrix.ruby_version }}
32
+ bundler-cache: true
33
+
34
+ - name: Run Tests
35
+ run: bundle exec rspec
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --order random
3
+ --require spec_helper
data/.standard.yml ADDED
@@ -0,0 +1,4 @@
1
+ ruby_version: 2.3.0
2
+ ignore:
3
+ - 'spec/**/*':
4
+ - Lint/AmbiguousBlockAssociation
data/CHANGELOG.md ADDED
@@ -0,0 +1,53 @@
1
+ ## 3.2.0 / Unreleased
2
+ * [BUGFIX] Raise failures from nested contexts [#170]
3
+
4
+ ## 3.1.2 / 2019-12-29
5
+ * [BUGFIX] Fix Context#fail! on Ruby 2.7
6
+
7
+ ## 3.1.1 / 2018-05-30
8
+
9
+ * [BUGFIX] Allow Context#fail! to accept a hash with string keys
10
+ * [ENHANCEMENT] Many documentation updates
11
+
12
+ ## 3.1.0 / 2014-10-13
13
+
14
+ * [FEATURE] Add around hooks
15
+
16
+ ## 3.0.1 / 2014-09-09
17
+
18
+ * [ENHANCEMENT] Add TomDoc code documentation
19
+
20
+ ## 3.0.0 / 2014-09-07
21
+
22
+ * [FEATURE] Remove "magical" access to the context through the interactor
23
+ * [FEATURE] Manage context values via setters/getters rather than hash access
24
+ * [FEATURE] Change the primary interactor API method from "perform" to "call"
25
+ * [FEATURE] Return the mutated context rather than the interactor instance
26
+ * [FEATURE] Replace interactor setup with before and after hooks
27
+ * [FEATURE] Abort execution immediately upon interactor failure
28
+ * [ENHANCEMENT] Build a suite of realistic integration tests
29
+ * [ENHANCEMENT] Move rollback responsibility into the context
30
+
31
+ ## 2.1.1 / 2014-09-30
32
+
33
+ * [FEATURE] Halt performance if the interactor fails prior
34
+ * [ENHANCEMENT] Add support for Ruby 2.1
35
+
36
+ ## 2.1.0 / 2013-09-05
37
+
38
+ * [FEATURE] Roll back when an interactor within an organizer raises an error
39
+ * [BUGFIX] Ensure that context-deferred methods respect string keys
40
+ * [FEATURE] Respect context initialization from an indifferent access hash
41
+
42
+ ## 2.0.1 / 2013-08-28
43
+
44
+ * [BUGFIX] Allow YAML (de)serialization by fixing interactor allocation
45
+
46
+ ## 2.0.0 / 2013-08-19
47
+
48
+ * [BUGFIX] Fix rollback behavior within nested organizers
49
+ * [BUGFIX] Skip rollback for the failed interactor
50
+
51
+ ## 1.0.0 / 2013-08-17
52
+
53
+ * Initial release!
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,39 @@
1
+ # Contributing to Interactor
2
+
3
+ Interactor is open source and contributions from the community are encouraged!
4
+ No contribution is too small.
5
+
6
+ Please consider:
7
+
8
+ * adding a feature
9
+ * squashing a bug
10
+ * writing [documentation](http://tomdoc.org)
11
+ * reporting an issue
12
+ * fixing a typo
13
+ * correcting [style](https://github.com/styleguide/ruby)
14
+
15
+ ## How do I contribute?
16
+
17
+ For the best chance of having your changes merged, please:
18
+
19
+ 1. [Fork](https://github.com/collectiveidea/interactor/fork) the project.
20
+ 2. [Write](http://en.wikipedia.org/wiki/Test-driven_development) a failing test.
21
+ 3. [Commit](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) changes that fix the tests.
22
+ 4. [Submit](https://github.com/collectiveidea/interactor/pulls) a pull request with *at least* one animated GIF.
23
+ 5. Be patient.
24
+
25
+ ## Bug Reports
26
+
27
+ If you are experiencing unexpected behavior and, after having read Interactor's
28
+ documentation, are convinced this behavior is a bug, please:
29
+
30
+ 1. [Search](https://github.com/collectiveidea/interactor/issues) existing issues.
31
+ 2. Collect enough information to reproduce the issue:
32
+ * Interactor version
33
+ * Ruby version
34
+ * Rails version (if applicable)
35
+ * Specific setup conditions
36
+ * Description of expected behavior
37
+ * Description of actual behavior
38
+ 3. [Submit](https://github.com/collectiveidea/interactor/issues/new) an issue.
39
+ 4. Be patient.
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "standard"
6
+
7
+ group :test do
8
+ gem "codeclimate-test-reporter", require: false
9
+ gem "rspec", "~> 3.7"
10
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,48 @@
1
+ Copyright (c) 2023 Marcelo Jacobus
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ Copyright (c) 2023 Marcelo Jacobus
24
+
25
+ ----------------------------------------------------------------------
26
+ Original License:
27
+ ----------------------------------------------------------------------
28
+
29
+ MIT License
30
+
31
+ Permission is hereby granted, free of charge, to any person obtaining
32
+ a copy of this software and associated documentation files (the
33
+ "Software"), to deal in the Software without restriction, including
34
+ without limitation the rights to use, copy, modify, merge, publish,
35
+ distribute, sublicense, and/or sell copies of the Software, and to
36
+ permit persons to whom the Software is furnished to do so, subject to
37
+ the following conditions:
38
+
39
+ The above copyright notice and this permission notice shall be
40
+ included in all copies or substantial portions of the Software.
41
+
42
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
43
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
44
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
45
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
46
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
47
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
48
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # Interactor::Strict
2
+
3
+ A stricter version of [`Interactor`](https://github.com/collectiveidea/interactor).
4
+
5
+ [![Gem Version](https://img.shields.io/gem/v/interactor-strict.svg)](http://rubygems.org/gems/interactor-strict)
6
+ [![Build Status](https://github.com/mjacobus/interactor-strict/actions/workflows/tests.yml/badge.svg)](https://github.com/mjacobus/interactor-strict/actions/workflows/tests.yml)
7
+ [![Maintainability](https://img.shields.io/codeclimate/maintainability/mjacobus/interactor-strict.svg)](https://codeclimate.com/github/mjacobus/interactor-strict)
8
+ [![Test Coverage](https://img.shields.io/codeclimate/coverage-letter/mjacobus/interactor-strict.svg)](https://codeclimate.com/github/mjacobus/interactor-strict)
9
+ [![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)
10
+
11
+ ## Getting Started
12
+
13
+ Add interactor-strict to your Gemfile and `bundle install`.
14
+
15
+ ```ruby
16
+ gem "interactor-strict"
17
+ ```
18
+
19
+ ## How to use
20
+
21
+ Include the `Interactor` module as well as the `Intractor::Strict`. That will allow you to use keyword arguments. The of keyword arguments is that you may not miss them, as they will be required by the interpreter. Also, you'll not need to document your params in comments, because the method signature will do that for you.
22
+
23
+ ```ruby
24
+ class SomeService
25
+ include Interactor
26
+ include Interactor::Strict # that will allow you to use keywords
27
+
28
+ def call(foo:, bar:, with_default: 'default')
29
+ context.result = [foo, bar, with_default]
30
+ end
31
+ end
32
+
33
+ SomeService.call(foo: "the-foo", bar: "the-bar")
34
+ ```
35
+
36
+ Without the strict interactor module, you would have implemented that service more or less like:
37
+
38
+ ```ruby
39
+ class SomeService
40
+ include Interactor
41
+
42
+ def call
43
+ raise "missing foo" if context.foo.nil?
44
+ raise "missing bar" if context.bar.nil?
45
+ context.result = [context.foo, context.bar, context.with_default || "default"]
46
+ end
47
+ end
48
+
49
+ SomeService.call(foo: "the-foo", bar: "the-bar")
50
+ ```
51
+
52
+ ## Credits
53
+
54
+ This code started as a fork of [mjacobus/interactor](https://github.com/mjacobus/interactor).
55
+
56
+ ## Disclaimer/Opinion
57
+
58
+ The Interactor gem provides a DSL for a very common design of service classes in ruby.
59
+
60
+ I don't particularly support this type of service. I don't like its design because this is not really OOP. `Service.call` is a function attached to a namespace.
61
+
62
+ Also, it imposes on your API/Interface, providing a DSL that brings no real value. You should decide how your services should be designed.
63
+
64
+ However, if you do think Interactor provides a good pattern - or you happen to work in a project that uses this heavily - you are better off with this stricter extension.
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "standard/rake"
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+
7
+ task default: [:spec, :standard]
@@ -0,0 +1,20 @@
1
+ require "English"
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "interactor-strict"
5
+ spec.version = "1.0.0"
6
+
7
+ spec.author = "Marcelo Jacobus"
8
+ spec.email = "marcelo.jacobus@gmail.com"
9
+ spec.description = "Extends the interactor gem"
10
+ spec.summary = "Extends the interactor gem"
11
+ spec.homepage = "https://github.com/mjacobus/interactor-strict"
12
+ spec.license = "MIT"
13
+
14
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
15
+ spec.test_files = spec.files.grep(/^spec/)
16
+
17
+ spec.add_dependency "interactor"
18
+ spec.add_development_dependency "bundler"
19
+ spec.add_development_dependency "rake"
20
+ end
@@ -0,0 +1,40 @@
1
+ require "interactor"
2
+
3
+ module Interactor
4
+ module Strict
5
+ def self.included(base)
6
+ base.class_eval do
7
+ extend ClassMethods
8
+ end
9
+ end
10
+
11
+ def initialize(*args, **kargs)
12
+ unless args.empty?
13
+ raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 0)"
14
+ end
15
+
16
+ @kargs = kargs
17
+ @context = Context.build(*args)
18
+ end
19
+
20
+ def run!
21
+ with_hooks do
22
+ call(**@kargs)
23
+ context.called!(self)
24
+ end
25
+ rescue
26
+ context.rollback!
27
+ raise
28
+ end
29
+
30
+ module ClassMethods
31
+ def call(*args, **kargs)
32
+ new(*args, **kargs).tap(&:run).context
33
+ end
34
+
35
+ def call!(*args, **kargs)
36
+ new(*args, **kargs).tap(&:run!).context
37
+ end
38
+ end
39
+ end
40
+ end