light_operations 0.1.1 → 1.2.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 +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
|