light_operations 0.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +106 -0
- data/lib/light_operations/flow.rb +33 -0
- data/lib/light_operations/version.rb +1 -1
- data/lib/light_operations.rb +1 -0
- data/light_operations.gemspec +5 -2
- data/spec/lib/flow_spec.rb +204 -0
- metadata +54 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68f26aea2a62fc1c53c4e05094c20c3f36bab95f
|
4
|
+
data.tar.gz: cc579e8a2d4b64700339f275abccf89e129661fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 097e63174c71d528b9d00a24e70dd67d115b1baaedd039a225d30c5c5df9aea21270765ea992a6f16d79e955e091414543e8de3c7d27af0c255fdb3f1591701f
|
7
|
+
data.tar.gz: 1c3a955b4f7e2f3d1505a7038e41c4619b5cd332ffe52d06f677c4dd7baf36a0b6e93b268a35cf48c54873ccc8421a54465206163e239c37466fb9fc8a03357b
|
data/README.md
CHANGED
@@ -24,6 +24,8 @@ Or install it yourself as:
|
|
24
24
|
|
25
25
|
$ gem install light_operations
|
26
26
|
|
27
|
+
**Important latest version of gem > 1.2.x works only with ruby 2.x**
|
28
|
+
|
27
29
|
## How it works
|
28
30
|
|
29
31
|
Basicly this is a Container for buissnes logic.
|
@@ -502,6 +504,110 @@ When operation status is most importent we can simply use `#success?` or `#fail?
|
|
502
504
|
|
503
505
|
Errors are available by `#errors` after operation is executed
|
504
506
|
|
507
|
+
### Whats new in 1.2.x
|
508
|
+
New module LightOperations::Flow which gives very simple and easy way to create operation per action in controller (tested on rails).
|
509
|
+
|
510
|
+
#### How it works:
|
511
|
+
|
512
|
+
include module in controller like this
|
513
|
+
```ruby
|
514
|
+
class AccountsController < VersionController
|
515
|
+
include LightOperations::Flow
|
516
|
+
operation :accounts, namespace: Operations, actions: [:create, :show]
|
517
|
+
def render_create(op)
|
518
|
+
render text: op.subject
|
519
|
+
end
|
520
|
+
|
521
|
+
def render_fail_create(op)
|
522
|
+
render text: op.errors # or if you want to show form use 'op.subject'
|
523
|
+
end
|
524
|
+
end
|
525
|
+
```
|
526
|
+
|
527
|
+
Now create operation class for account creation (components/operations/accounts/create.rb):
|
528
|
+
|
529
|
+
```ruby
|
530
|
+
module Operations
|
531
|
+
module Accounts
|
532
|
+
class Create < LightOperations::Core
|
533
|
+
rescue_from ActiveRecord::RecordInvalid, with: :invalid_record_handler
|
534
|
+
|
535
|
+
def execute(params:)
|
536
|
+
Account.create!(params.require(:account))
|
537
|
+
end
|
538
|
+
|
539
|
+
private
|
540
|
+
|
541
|
+
def invalid_record_handler(ex)
|
542
|
+
fail!(ex.record.errors)
|
543
|
+
end
|
544
|
+
end
|
545
|
+
end
|
546
|
+
end
|
547
|
+
```
|
548
|
+
|
549
|
+
add into `application.rb`
|
550
|
+
|
551
|
+
```ruby
|
552
|
+
config.autoload_paths += %W(
|
553
|
+
#{config.root}/app/components
|
554
|
+
)
|
555
|
+
```
|
556
|
+
|
557
|
+
But it is not all :D (operation params gives you a lot more)
|
558
|
+
|
559
|
+
```ruby
|
560
|
+
class AccountsController < VersionController
|
561
|
+
include LightOperations::Flow
|
562
|
+
operation(
|
563
|
+
:accounts, # top level namespace
|
564
|
+
namespace: Operations, # Base namespace by default is Kernel
|
565
|
+
actions: [:create, :show], # those are operations executed by router
|
566
|
+
default_view: nil, # By changing this option you can have one method for render all successful operations for all actions.
|
567
|
+
view_prefix: 'render_', # By changing this you can have #view_create instead of #render_create
|
568
|
+
default_fail_view: nil, # By changing this option you can have one method for render all failed operations for all actions.
|
569
|
+
fail_view_prefix: 'render_fail_' # By changing this you can have #view_fail_create instead of #render_fail_create
|
570
|
+
end
|
571
|
+
```
|
572
|
+
|
573
|
+
This simple module should give you power to create something like this:
|
574
|
+
|
575
|
+
```ruby
|
576
|
+
module Api
|
577
|
+
module V1
|
578
|
+
class AccountsController < VersionController
|
579
|
+
include LightOperations::Flow
|
580
|
+
skip_before_action :authorize, only: [:create, :password_reset]
|
581
|
+
operation :accounts,
|
582
|
+
namespace: Operations,
|
583
|
+
actions: [:create, :update, :show, :destroy, :password_reset],
|
584
|
+
default_fail_view: :render_error
|
585
|
+
|
586
|
+
private
|
587
|
+
|
588
|
+
def render_operation_error(op)
|
589
|
+
render json: op.errors, status: 422 # you can have status in operation if you want
|
590
|
+
end
|
591
|
+
|
592
|
+
def render_account(op)
|
593
|
+
render json: AccountOwnerSerializer.new(op.account), status: op.status
|
594
|
+
end
|
595
|
+
|
596
|
+
def render_no_content(_op)
|
597
|
+
render nothing: true, status: :no_content
|
598
|
+
end
|
599
|
+
|
600
|
+
alias_method :render_update, :render_account
|
601
|
+
alias_method :render_create, :render_account
|
602
|
+
alias_method :render_password_reset, :render_no_content
|
603
|
+
alias_method :render_destroy, :render_no_content
|
604
|
+
end
|
605
|
+
end
|
606
|
+
end
|
607
|
+
|
608
|
+
|
609
|
+
```
|
610
|
+
|
505
611
|
## Contributing
|
506
612
|
|
507
613
|
1. Fork it ( https://github.com/[my-github-username]/light_operations/fork )
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module LightOperations
|
2
|
+
module Flow
|
3
|
+
def self.included(base)
|
4
|
+
base.send(:extend, ClassMethods)
|
5
|
+
end
|
6
|
+
|
7
|
+
attr_reader :operation_opts, :operation_dependencies
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def operation(operation_name, namespace: Kernel, actions: [], default_view: nil, view_prefix: 'render_', default_fail_view: nil, fail_view_prefix: 'render_fail_')
|
11
|
+
actions.each do |action_name|
|
12
|
+
operation_method = "#{action_name}_op"
|
13
|
+
|
14
|
+
define_method(action_name.to_s) do
|
15
|
+
send(operation_method).run((operation_opts || {}).merge(params: params))
|
16
|
+
end
|
17
|
+
|
18
|
+
define_method(operation_method) do
|
19
|
+
success_view = default_view || "#{view_prefix}#{action_name}".to_sym
|
20
|
+
fail_view = default_fail_view || "#{fail_view_prefix}#{action_name}".to_sym
|
21
|
+
const = operation_name.to_s.titleize.delete(' ')
|
22
|
+
action = action_name.to_s.titleize.delete(' ')
|
23
|
+
namespace.const_get(const).const_get(action)
|
24
|
+
.new(operation_dependencies)
|
25
|
+
.bind_with(self)
|
26
|
+
.on_success(success_view)
|
27
|
+
.on_fail(fail_view)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/light_operations.rb
CHANGED
data/light_operations.gemspec
CHANGED
@@ -18,11 +18,14 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_runtime_dependency 'activesupport', '
|
22
|
-
spec.add_development_dependency '
|
21
|
+
spec.add_runtime_dependency 'activesupport', '~> 3.0'
|
22
|
+
spec.add_development_dependency 'rails', '~> 3.2'
|
23
|
+
spec.add_development_dependency 'test-unit', '~> 3.0'
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
23
25
|
spec.add_development_dependency 'rake', '~> 10.4'
|
24
26
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
25
27
|
spec.add_development_dependency 'guard', '~> 2.12'
|
28
|
+
spec.add_development_dependency 'rspec-rails', '~> 3.0'
|
26
29
|
spec.add_development_dependency 'guard-rspec', '~> 4.5'
|
27
30
|
spec.add_development_dependency 'guard-rubocop', '~> 1.2'
|
28
31
|
spec.add_development_dependency 'coveralls', '~> 0.7'
|
@@ -0,0 +1,204 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'action_controller/railtie'
|
3
|
+
require 'action_view/railtie'
|
4
|
+
require 'rspec/rails'
|
5
|
+
require 'rspec/autorun'
|
6
|
+
|
7
|
+
|
8
|
+
describe 'LightOperations::Flow', type: :controller do
|
9
|
+
RailsApp = Class.new(Rails::Application)
|
10
|
+
RailsApp.config.secret_key_base = '5308dcbbb7dea1b44e3d1d55ea7656f9'
|
11
|
+
RailsApp.config.eager_load = false
|
12
|
+
RailsApp.config.root = File.dirname(__FILE__)
|
13
|
+
RailsApp.config.generators { |g| g.test_framework :rspec }
|
14
|
+
RailsApp.routes.draw do
|
15
|
+
resources :accounts, only: [:create, :show, :update]
|
16
|
+
end
|
17
|
+
|
18
|
+
module TestOperations
|
19
|
+
module Accounts
|
20
|
+
class Create < LightOperations::Core
|
21
|
+
def execute(params:)
|
22
|
+
params[:correct] ? 'Create OK' : fail!('Create Fail')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class Show < LightOperations::Core
|
27
|
+
def execute(params:)
|
28
|
+
params[:correct] ? 'Show OK' : fail!('Show Fail')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class Update < LightOperations::Core
|
33
|
+
attr_reader :status
|
34
|
+
AccessDeny = Class.new(StandardError)
|
35
|
+
rescue_from AccessDeny, with: :access_deny_handler
|
36
|
+
|
37
|
+
def execute(params:, current_user: {})
|
38
|
+
@status = 200
|
39
|
+
fail AccessDeny unless current_user[:id].to_i == 1
|
40
|
+
params[:correct] ? 'Update OK' : fail_with_status!(text: 'Update Fail')
|
41
|
+
end
|
42
|
+
|
43
|
+
def fail_with_status!(text:, code: 422)
|
44
|
+
@status = code
|
45
|
+
fail!(text)
|
46
|
+
end
|
47
|
+
|
48
|
+
def access_deny_handler
|
49
|
+
fail_with_status!(text: 'Update access deny', code: 401)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
context 'default use of flow' do
|
55
|
+
controller(RailsApp::ActionController::Base) do
|
56
|
+
include Rails.application.routes.url_helpers
|
57
|
+
include LightOperations::Flow
|
58
|
+
operation :accounts, namespace: TestOperations, actions: [:create]
|
59
|
+
|
60
|
+
def render_create(op)
|
61
|
+
render text: op.subject
|
62
|
+
end
|
63
|
+
|
64
|
+
def render_fail_create(op)
|
65
|
+
render text: op.subject
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
it '#render_create as success' do
|
71
|
+
post :create, correct: true
|
72
|
+
expect(response.body).to eq('Create OK')
|
73
|
+
end
|
74
|
+
|
75
|
+
it '#render_fail_create as fail' do
|
76
|
+
post :create, {}
|
77
|
+
expect(response.body).to eq('Create Fail')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context 'flow with #view_prefix and #fail_view_prefix' do
|
82
|
+
controller(RailsApp::ActionController::Base) do
|
83
|
+
include Rails.application.routes.url_helpers
|
84
|
+
include LightOperations::Flow
|
85
|
+
operation :accounts, namespace: TestOperations, actions: [:create], view_prefix: 'view_', fail_view_prefix: 'fail_view_'
|
86
|
+
|
87
|
+
def view_create(op)
|
88
|
+
render text: op.subject
|
89
|
+
end
|
90
|
+
|
91
|
+
def fail_view_create(op)
|
92
|
+
render text: op.subject
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
it '#view_create as success' do
|
98
|
+
post :create, correct: true
|
99
|
+
expect(response.body).to eq('Create OK')
|
100
|
+
end
|
101
|
+
|
102
|
+
it '#fail_view_create as fail' do
|
103
|
+
post :create, {}
|
104
|
+
expect(response.body).to eq('Create Fail')
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'flow with #view_prefix and #fail_view_prefix as one' do
|
109
|
+
controller(RailsApp::ActionController::Base) do
|
110
|
+
include Rails.application.routes.url_helpers
|
111
|
+
include LightOperations::Flow
|
112
|
+
operation :accounts, namespace: TestOperations, actions: [:create], view_prefix: 'render_', fail_view_prefix: 'render_'
|
113
|
+
|
114
|
+
def render_create(op)
|
115
|
+
status = op.success? ? 200 : 404
|
116
|
+
render text: op.subject, status: status
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
it '#render_create as success' do
|
122
|
+
post :create, correct: true
|
123
|
+
expect(response.body).to eq('Create OK')
|
124
|
+
expect(response.code).to eq('200')
|
125
|
+
end
|
126
|
+
|
127
|
+
it '#render_create as fail' do
|
128
|
+
post :create, {}
|
129
|
+
expect(response.body).to eq('Create Fail')
|
130
|
+
expect(response.code).to eq('404')
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context 'flow with #default_view and #default_fail_view' do
|
135
|
+
controller(RailsApp::ActionController::Base) do
|
136
|
+
include Rails.application.routes.url_helpers
|
137
|
+
include LightOperations::Flow
|
138
|
+
operation :accounts, namespace: TestOperations, actions: [:create, :show], default_view: :render_view, default_fail_view: :render_fail_view
|
139
|
+
|
140
|
+
def render_view(op)
|
141
|
+
render text: op.subject
|
142
|
+
end
|
143
|
+
|
144
|
+
def render_fail_view(op)
|
145
|
+
render text: op.subject, status: 422
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
|
150
|
+
it '#render_view as success' do
|
151
|
+
post :create, correct: true
|
152
|
+
expect(response.body).to eq('Create OK')
|
153
|
+
expect(response.code).to eq('200')
|
154
|
+
get :show, id: 1, correct: true
|
155
|
+
expect(response.body).to eq('Show OK')
|
156
|
+
expect(response.code).to eq('200')
|
157
|
+
end
|
158
|
+
|
159
|
+
it '#render_fail_view as fail' do
|
160
|
+
post :create, {}
|
161
|
+
expect(response.body).to eq('Create Fail')
|
162
|
+
expect(response.code).to eq('422')
|
163
|
+
get :show, id: 1
|
164
|
+
expect(response.body).to eq('Show Fail')
|
165
|
+
expect(response.code).to eq('422')
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context 'flow with advance customization' do
|
170
|
+
controller(RailsApp::ActionController::Base) do
|
171
|
+
include Rails.application.routes.url_helpers
|
172
|
+
include LightOperations::Flow
|
173
|
+
operation :accounts, namespace: TestOperations, actions: [:update], default_view: :render_view, default_fail_view: :render_error
|
174
|
+
|
175
|
+
def render_view(op)
|
176
|
+
render text: op.subject, status: op.status
|
177
|
+
end
|
178
|
+
|
179
|
+
def render_error(op)
|
180
|
+
render text: op.errors, status: op.status
|
181
|
+
end
|
182
|
+
|
183
|
+
def operation_opts
|
184
|
+
{ current_user: { id: params[:id] } }
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
it '#render_view as success' do
|
190
|
+
post :update, correct: true, id: 1
|
191
|
+
expect(response.body).to eq('Update OK')
|
192
|
+
expect(response.code).to eq('200')
|
193
|
+
end
|
194
|
+
|
195
|
+
it '#render_fail_view as fail' do
|
196
|
+
post :update, id: 1
|
197
|
+
expect(response.body).to eq('Update Fail')
|
198
|
+
expect(response.code).to eq('422')
|
199
|
+
post :update, id: 2
|
200
|
+
expect(response.body).to eq('Update access deny')
|
201
|
+
expect(response.code).to eq('401')
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
metadata
CHANGED
@@ -1,41 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: light_operations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pawel Niemczyk
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 3.0
|
19
|
+
version: '3.0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rails
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.2'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
25
39
|
- !ruby/object:Gem::Version
|
26
|
-
version: 3.
|
40
|
+
version: '3.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: test-unit
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: bundler
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|
30
58
|
requirements:
|
31
|
-
- - "
|
59
|
+
- - "~>"
|
32
60
|
- !ruby/object:Gem::Version
|
33
61
|
version: '1.6'
|
34
62
|
type: :development
|
35
63
|
prerelease: false
|
36
64
|
version_requirements: !ruby/object:Gem::Requirement
|
37
65
|
requirements:
|
38
|
-
- - "
|
66
|
+
- - "~>"
|
39
67
|
- !ruby/object:Gem::Version
|
40
68
|
version: '1.6'
|
41
69
|
- !ruby/object:Gem::Dependency
|
@@ -80,6 +108,20 @@ dependencies:
|
|
80
108
|
- - "~>"
|
81
109
|
- !ruby/object:Gem::Version
|
82
110
|
version: '2.12'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec-rails
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '3.0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '3.0'
|
83
125
|
- !ruby/object:Gem::Dependency
|
84
126
|
name: guard-rspec
|
85
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -154,9 +196,11 @@ files:
|
|
154
196
|
- Rakefile
|
155
197
|
- lib/light_operations.rb
|
156
198
|
- lib/light_operations/core.rb
|
199
|
+
- lib/light_operations/flow.rb
|
157
200
|
- lib/light_operations/version.rb
|
158
201
|
- light_operations.gemspec
|
159
202
|
- spec/lib/core_spec.rb
|
203
|
+
- spec/lib/flow_spec.rb
|
160
204
|
- spec/spec_helper.rb
|
161
205
|
homepage: https://github.com/pniemczyk/light_operations
|
162
206
|
licenses:
|
@@ -178,10 +222,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
178
222
|
version: '0'
|
179
223
|
requirements: []
|
180
224
|
rubyforge_project:
|
181
|
-
rubygems_version: 2.4.
|
225
|
+
rubygems_version: 2.4.6
|
182
226
|
signing_key:
|
183
227
|
specification_version: 4
|
184
228
|
summary: Light operations
|
185
229
|
test_files:
|
186
230
|
- spec/lib/core_spec.rb
|
231
|
+
- spec/lib/flow_spec.rb
|
187
232
|
- spec/spec_helper.rb
|