simple_command 0.0.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e1e044db947afd477d7b8042fbd679fdffbd8a63
4
- data.tar.gz: 021cfb1817dd007895a76184af0db53095c0c9a1
2
+ SHA256:
3
+ metadata.gz: 8847792f86f2c4162d832d2603abfb7f0f40208110ad339484851dfaeeb99cf4
4
+ data.tar.gz: ba9e8c0e1d46fb25d8408f430ba462e14e2ca386e5cd7b4c611d7787523448a0
5
5
  SHA512:
6
- metadata.gz: 0a88837defef4d2cc6f3c7167e0f891f73dd09ff6378a5719df8772e8a4f1bdd7cd22043ca29b3596d9e53d619c9a714d03c2107a27d3746150c8f3d167d2730
7
- data.tar.gz: ea8a66ec330153ba06932837a9795d7931c3741faed743c3ebdaa40e211ffde726a173121a84c6a91c89cca5561308373d04aca9d0a776764ce195d8f75694f2
6
+ metadata.gz: d4fa95128f6e3fcd15419705bf36d56c33b8da0ced34b068940a3ee3fe066feeada465f8257f5076a87f3e237bd0adfd83b377a1d68bf9e81a09240bae5be243
7
+ data.tar.gz: 8cc7cea6c22b3af310b039eee0f041f0ac5c48597d8cc13122771ffdef67a54dcf2ce8f2b77172ad3c6425e5598024d2ef48d95a7562083c94c3d1419348a7e0
data/README.md CHANGED
@@ -1,3 +1,6 @@
1
+ [![Code Climate](https://codeclimate.com/github/nebulab/simple_command/badges/gpa.svg)](https://codeclimate.com/github/nebulab/simple_command)
2
+ [ ![Codeship Status for nebulab/simple_command](https://app.codeship.com/projects/45ce7790-8daf-0132-1412-669677a474c3/status?branch=master)](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(user, password)
37
- @user = user
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.authenticate(@email, @password)
48
+ if user = User.find_by(email: @email)&.authenticate(@password)
45
49
  return user
46
50
  else
47
- errors.add_error(authentication: I18n.t "authenticate_user.failure")
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[:user], session_params[:password])
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[:authentication])
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 )
@@ -2,7 +2,7 @@ module SimpleCommand
2
2
  class NotImplementedError < ::StandardError; end
3
3
 
4
4
  class Errors < Hash
5
- def add_error(key, value)
5
+ def add(key, value, _opts = {})
6
6
  self[key] ||= []
7
7
  self[key] << value
8
8
  self[key].uniq!
@@ -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_error key, value }
13
+ 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
@@ -1,3 +1,3 @@
1
1
  module SimpleCommand
2
- VERSION = '0.0.8'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -5,8 +5,8 @@ module SimpleCommand
5
5
  attr_reader :result
6
6
 
7
7
  module ClassMethods
8
- def call(*args)
9
- new(*args).call
8
+ def call(*args, **kwargs)
9
+ new(*args, **kwargs).call
10
10
  end
11
11
  end
12
12
 
@@ -26,12 +26,15 @@ module SimpleCommand
26
26
  def success?
27
27
  called? && !failure?
28
28
  end
29
+ alias_method :successful?, :success?
29
30
 
30
31
  def failure?
31
32
  called? && errors.any?
32
33
  end
33
34
 
34
35
  def errors
36
+ return super if defined?(super)
37
+
35
38
  @errors ||= Errors.new
36
39
  end
37
40
 
@@ -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', '~> 1.7'
23
- s.add_development_dependency 'rake', '~> 10.0'
22
+ s.add_development_dependency 'bundler'
23
+ s.add_development_dependency 'rake'
24
24
  s.add_development_dependency 'rspec', '~> 3.1'
25
25
  end
@@ -3,9 +3,9 @@ require 'spec_helper'
3
3
  describe SimpleCommand::Errors do
4
4
  let(:errors) { SimpleCommand::Errors.new }
5
5
 
6
- describe '#add_error' do
6
+ describe '#add' do
7
7
  before do
8
- errors.add_error :some_error, 'some error description'
8
+ errors.add :some_error, 'some error description'
9
9
  end
10
10
 
11
11
  it 'adds the error' do
@@ -13,7 +13,7 @@ describe SimpleCommand::Errors do
13
13
  end
14
14
 
15
15
  it 'adds the same error only once' do
16
- errors.add_error :some_error, 'some error description'
16
+ errors.add :some_error, 'some error description'
17
17
  expect(errors[:some_error]).to eq(['some error description'])
18
18
  end
19
19
  end
@@ -35,4 +35,38 @@ describe SimpleCommand::Errors do
35
35
  expect(errors[:another_error]).to eq(errors_list[:another_error])
36
36
  end
37
37
  end
38
+
39
+ describe '#each' do
40
+ let(:errors_list) do
41
+ {
42
+ email: ['taken'],
43
+ password: ['blank', 'too short']
44
+ }
45
+ end
46
+
47
+ before { errors.add_multiple_errors(errors_list) }
48
+
49
+ it 'yields each message for the same key independently' do
50
+ expect { |b| errors.each(&b) }.to yield_control.exactly(3).times
51
+ expect { |b| errors.each(&b) }.to yield_successive_args(
52
+ [:email, 'taken'],
53
+ [:password, 'blank'],
54
+ [:password, 'too short']
55
+ )
56
+ end
57
+ end
58
+
59
+ describe '#full_messages' do
60
+ before do
61
+ errors.add :attr1, 'has an error'
62
+ errors.add :attr2, 'has an error'
63
+ errors.add :attr2, 'has two errors'
64
+ end
65
+
66
+ it "returrns the full messages array" do
67
+ expect(errors.full_messages).to eq ["Attr1 has an error", "Attr2 has an error", "Attr2 has two errors"]
68
+ end
69
+
70
+ end
71
+
38
72
  end
@@ -40,7 +40,7 @@ describe SimpleCommand do
40
40
  end
41
41
 
42
42
  it 'is false if something went wrong' do
43
- command.errors.add_error(:some_error, 'some message')
43
+ command.errors.add(:some_error, 'some message')
44
44
  expect(command.call.success?).to be_falsy
45
45
  end
46
46
 
@@ -69,7 +69,7 @@ describe SimpleCommand do
69
69
  end
70
70
 
71
71
  it 'is true if something went wrong' do
72
- command.errors.add_error(:some_error, 'some message')
72
+ command.errors.add(:some_error, 'some message')
73
73
  expect(command.call.failure?).to be_truthy
74
74
  end
75
75
 
@@ -93,7 +93,7 @@ describe SimpleCommand do
93
93
 
94
94
  context 'with errors' do
95
95
  before do
96
- command.errors.add_error(:some_error, 'some message')
96
+ command.errors.add(:some_error, 'some message')
97
97
  end
98
98
 
99
99
  it 'has a key with error message' do
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.8
4
+ version: 0.2.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: 2015-01-19 00:00:00.000000000 Z
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: '1.7'
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: '1.7'
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: '10.0'
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: '10.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -80,7 +80,7 @@ homepage: http://github.com/nebulab/simple_command
80
80
  licenses:
81
81
  - MIT
82
82
  metadata: {}
83
- post_install_message:
83
+ post_install_message:
84
84
  rdoc_options: []
85
85
  require_paths:
86
86
  - lib
@@ -95,9 +95,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  requirements: []
98
- rubyforge_project:
99
- rubygems_version: 2.4.5
100
- signing_key:
98
+ rubygems_version: 3.2.20
99
+ signing_key:
101
100
  specification_version: 4
102
101
  summary: Easy way to build and manage commands (service objects)
103
102
  test_files: