simple_command 0.0.9 → 1.0.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.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +23 -0
- data/README.md +51 -7
- data/lib/simple_command/errors.rb +19 -1
- data/lib/simple_command/utils.rb +14 -0
- data/lib/simple_command/version.rb +1 -1
- data/lib/simple_command.rb +6 -2
- data/simple_command.gemspec +2 -2
- data/spec/simple_command/errors_spec.rb +52 -6
- metadata +16 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 709a8e79d062fc2df30ceb2515a4996dac770a1a06b26cfedef243b560fa86d4
|
4
|
+
data.tar.gz: 6b30945ca6b05353376bb3636f42c501d7c349ded063adc98706628ced2ecc03
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e9a41d79fe67caa53d69c54d690958f62eae87ef54c8e966360854adb4b1716580446255ccf5767a35aaea9f45ac53c1d20b0686b5ff30cd715ac37074d5d8c
|
7
|
+
data.tar.gz: 5ac692c46307b7f034658608b8217e5a367587b91760ca7f38aebb8cca3612eae9b29f3069ddb896b6ffbadd8b12f600609ebcc6b38c2f06f395358c9dc5655b
|
@@ -0,0 +1,23 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
|
10
|
+
strategy:
|
11
|
+
fail-fast: false
|
12
|
+
matrix:
|
13
|
+
ruby: ["2.7", "3.0", "3.1", ruby-head, jruby-9.3, jruby-head]
|
14
|
+
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v2
|
17
|
+
- name: Set up Ruby
|
18
|
+
uses: ruby/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
bundler-cache: true # 'bundle install' and cache gems
|
21
|
+
ruby-version: ${{ matrix.ruby }}
|
22
|
+
- name: Run tests
|
23
|
+
run: bundle exec rake
|
data/README.md
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
[](https://codeclimate.com/github/nebulab/simple_command)
|
2
|
+
[ ](https://app.codeship.com/projects/60741)
|
3
|
+
|
1
4
|
# SimpleCommand
|
2
5
|
|
3
6
|
A simple, standardized way to build and use _Service Objects_ (aka _Commands_) in Ruby
|
@@ -31,34 +34,46 @@ Here's a basic example of a command that authenticates a user
|
|
31
34
|
class AuthenticateUser
|
32
35
|
# put SimpleCommand before the class' ancestors chain
|
33
36
|
prepend SimpleCommand
|
37
|
+
include ActiveModel::Validations
|
34
38
|
|
35
39
|
# optional, initialize the command with some arguments
|
36
|
-
def initialize(
|
37
|
-
@
|
40
|
+
def initialize(email, password)
|
41
|
+
@email = email
|
38
42
|
@password = password
|
39
43
|
end
|
40
44
|
|
41
45
|
# mandatory: define a #call method. its return value will be available
|
42
46
|
# through #result
|
43
47
|
def call
|
44
|
-
if user = User.
|
48
|
+
if user = User.find_by(email: @email)&.authenticate(@password)
|
45
49
|
return user
|
46
50
|
else
|
47
|
-
errors.add(
|
51
|
+
errors.add(:base, :failure)
|
48
52
|
end
|
49
53
|
nil
|
50
54
|
end
|
51
55
|
end
|
52
56
|
```
|
53
57
|
|
58
|
+
in your locale file
|
59
|
+
```yaml
|
60
|
+
# config/locales/en.yml
|
61
|
+
en:
|
62
|
+
activemodel:
|
63
|
+
errors:
|
64
|
+
models:
|
65
|
+
authenticate_user:
|
66
|
+
failure: Wrong email or password
|
67
|
+
```
|
68
|
+
|
54
69
|
Then, in your controller:
|
55
70
|
|
56
71
|
```ruby
|
57
72
|
class SessionsController < ApplicationController
|
58
73
|
def create
|
59
74
|
# initialize and execute the command
|
60
|
-
# NOTE: `.call` is a shortcut for `.new(args).call
|
61
|
-
command = AuthenticateUser.call(session_params[:
|
75
|
+
# NOTE: `.call` is a shortcut for `.new(args).call`
|
76
|
+
command = AuthenticateUser.call(session_params[:email], session_params[:password])
|
62
77
|
|
63
78
|
# check command outcome
|
64
79
|
if command.success?
|
@@ -66,7 +81,7 @@ class SessionsController < ApplicationController
|
|
66
81
|
session[:user_token] = command.result.secret_token
|
67
82
|
redirect_to root_path
|
68
83
|
else
|
69
|
-
flash.now[:alert] = t(command.errors
|
84
|
+
flash.now[:alert] = t(command.errors.full_messages.to_sentence)
|
70
85
|
render :new
|
71
86
|
end
|
72
87
|
end
|
@@ -79,6 +94,35 @@ class SessionsController < ApplicationController
|
|
79
94
|
end
|
80
95
|
```
|
81
96
|
|
97
|
+
## Test with Rspec
|
98
|
+
Make the spec file `spec/commands/authenticate_user_spec.rb` like:
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
describe AuthenticateUser do
|
102
|
+
subject(:context) { described_class.call(username, password) }
|
103
|
+
|
104
|
+
describe '.call' do
|
105
|
+
context 'when the context is successful' do
|
106
|
+
let(:username) { 'correct_user' }
|
107
|
+
let(:password) { 'correct_password' }
|
108
|
+
|
109
|
+
it 'succeeds' do
|
110
|
+
expect(context).to be_success
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'when the context is not successful' do
|
115
|
+
let(:username) { 'wrong_user' }
|
116
|
+
let(:password) { 'wrong_password' }
|
117
|
+
|
118
|
+
it 'fails' do
|
119
|
+
expect(context).to be_failure
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
```
|
125
|
+
|
82
126
|
## Contributing
|
83
127
|
|
84
128
|
1. Fork it ( https://github.com/nebulab/simple_command/fork )
|
@@ -10,8 +10,26 @@ module SimpleCommand
|
|
10
10
|
|
11
11
|
def add_multiple_errors(errors_hash)
|
12
12
|
errors_hash.each do |key, values|
|
13
|
-
values.each { |value| add key, value }
|
13
|
+
SimpleCommand::Utils.array_wrap(values).each { |value| add key, value }
|
14
14
|
end
|
15
15
|
end
|
16
|
+
|
17
|
+
def each
|
18
|
+
each_key do |field|
|
19
|
+
self[field].each { |message| yield field, message }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def full_messages
|
24
|
+
map { |attribute, message| full_message(attribute, message) }
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def full_message(attribute, message)
|
29
|
+
return message if attribute == :base
|
30
|
+
attr_name = attribute.to_s.tr('.', '_').capitalize
|
31
|
+
"%s %s" % [attr_name, message]
|
32
|
+
end
|
33
|
+
|
16
34
|
end
|
17
35
|
end
|
data/lib/simple_command.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
require 'simple_command/version'
|
2
|
+
require 'simple_command/utils'
|
2
3
|
require 'simple_command/errors'
|
3
4
|
|
4
5
|
module SimpleCommand
|
5
6
|
attr_reader :result
|
6
7
|
|
7
8
|
module ClassMethods
|
8
|
-
def call(*args)
|
9
|
-
new(*args).call
|
9
|
+
def call(*args, **kwargs)
|
10
|
+
new(*args, **kwargs).call
|
10
11
|
end
|
11
12
|
end
|
12
13
|
|
@@ -26,12 +27,15 @@ module SimpleCommand
|
|
26
27
|
def success?
|
27
28
|
called? && !failure?
|
28
29
|
end
|
30
|
+
alias_method :successful?, :success?
|
29
31
|
|
30
32
|
def failure?
|
31
33
|
called? && errors.any?
|
32
34
|
end
|
33
35
|
|
34
36
|
def errors
|
37
|
+
return super if defined?(super)
|
38
|
+
|
35
39
|
@errors ||= Errors.new
|
36
40
|
end
|
37
41
|
|
data/simple_command.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.test_files = s.files.grep(/^(test|spec|features)\//)
|
20
20
|
s.require_paths = ['lib']
|
21
21
|
|
22
|
-
s.add_development_dependency 'bundler'
|
23
|
-
s.add_development_dependency 'rake'
|
22
|
+
s.add_development_dependency 'bundler'
|
23
|
+
s.add_development_dependency 'rake'
|
24
24
|
s.add_development_dependency 'rspec', '~> 3.1'
|
25
25
|
end
|
@@ -19,20 +19,66 @@ describe SimpleCommand::Errors do
|
|
19
19
|
end
|
20
20
|
|
21
21
|
describe '#add_multiple_errors' do
|
22
|
-
|
23
|
-
{
|
22
|
+
it 'populates itself with the added errors' do
|
23
|
+
errors_list = {
|
24
24
|
some_error: ['some error description'],
|
25
25
|
another_error: ['another error description']
|
26
26
|
}
|
27
|
-
end
|
28
27
|
|
29
|
-
before do
|
30
28
|
errors.add_multiple_errors errors_list
|
31
|
-
end
|
32
29
|
|
33
|
-
it 'populates itself with the added errors' do
|
34
30
|
expect(errors[:some_error]).to eq(errors_list[:some_error])
|
35
31
|
expect(errors[:another_error]).to eq(errors_list[:another_error])
|
36
32
|
end
|
33
|
+
|
34
|
+
it 'copies errors from another SimpleCommand::Errors object' do
|
35
|
+
command_errors = SimpleCommand::Errors.new
|
36
|
+
command_errors.add :some_error, "was found"
|
37
|
+
command_errors.add :some_error, "happened again"
|
38
|
+
|
39
|
+
errors.add_multiple_errors command_errors
|
40
|
+
|
41
|
+
expect(errors[:some_error]).to eq(["was found", "happened again"])
|
42
|
+
end
|
43
|
+
|
44
|
+
it "ignores nil values" do
|
45
|
+
errors.add_multiple_errors({:foo => nil})
|
46
|
+
|
47
|
+
expect(errors[:foo]).to eq nil
|
48
|
+
end
|
37
49
|
end
|
50
|
+
|
51
|
+
describe '#each' do
|
52
|
+
let(:errors_list) do
|
53
|
+
{
|
54
|
+
email: ['taken'],
|
55
|
+
password: ['blank', 'too short']
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
before { errors.add_multiple_errors(errors_list) }
|
60
|
+
|
61
|
+
it 'yields each message for the same key independently' do
|
62
|
+
expect { |b| errors.each(&b) }.to yield_control.exactly(3).times
|
63
|
+
expect { |b| errors.each(&b) }.to yield_successive_args(
|
64
|
+
[:email, 'taken'],
|
65
|
+
[:password, 'blank'],
|
66
|
+
[:password, 'too short']
|
67
|
+
)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
describe '#full_messages' do
|
72
|
+
before do
|
73
|
+
errors.add :attr1, 'has an error'
|
74
|
+
errors.add :attr2, 'has an error'
|
75
|
+
errors.add :attr2, 'has two errors'
|
76
|
+
end
|
77
|
+
|
78
|
+
it "returrns the full messages array" do
|
79
|
+
expect(errors.full_messages).to eq ["Attr1 has an error", "Attr2 has an error", "Attr2 has two errors"]
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
38
84
|
end
|
metadata
CHANGED
@@ -1,43 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple_command
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrea Pavoni
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,6 +59,7 @@ executables: []
|
|
59
59
|
extensions: []
|
60
60
|
extra_rdoc_files: []
|
61
61
|
files:
|
62
|
+
- ".github/workflows/ci.yml"
|
62
63
|
- ".gitignore"
|
63
64
|
- ".rspec"
|
64
65
|
- ".rubocop.yml"
|
@@ -69,6 +70,7 @@ files:
|
|
69
70
|
- Rakefile
|
70
71
|
- lib/simple_command.rb
|
71
72
|
- lib/simple_command/errors.rb
|
73
|
+
- lib/simple_command/utils.rb
|
72
74
|
- lib/simple_command/version.rb
|
73
75
|
- simple_command.gemspec
|
74
76
|
- spec/factories/missed_call_command.rb
|
@@ -80,7 +82,7 @@ homepage: http://github.com/nebulab/simple_command
|
|
80
82
|
licenses:
|
81
83
|
- MIT
|
82
84
|
metadata: {}
|
83
|
-
post_install_message:
|
85
|
+
post_install_message:
|
84
86
|
rdoc_options: []
|
85
87
|
require_paths:
|
86
88
|
- lib
|
@@ -95,9 +97,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
95
97
|
- !ruby/object:Gem::Version
|
96
98
|
version: '0'
|
97
99
|
requirements: []
|
98
|
-
|
99
|
-
|
100
|
-
signing_key:
|
100
|
+
rubygems_version: 3.2.20
|
101
|
+
signing_key:
|
101
102
|
specification_version: 4
|
102
103
|
summary: Easy way to build and manage commands (service objects)
|
103
104
|
test_files:
|