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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 22e10ab9bc6fe6041bb01667f862f63f50077231
4
- data.tar.gz: 2f04f75361aced6d9c1f8dffaf2f43bd1cef1578
3
+ metadata.gz: 68f26aea2a62fc1c53c4e05094c20c3f36bab95f
4
+ data.tar.gz: cc579e8a2d4b64700339f275abccf89e129661fa
5
5
  SHA512:
6
- metadata.gz: e00cdb8eb532f6b600803134315b47e0be787b897c630b24dff00dbe022e7141099413adb3f41b40979388ab2fe0ee8071a813f591fb5a1be91e9b20f39001da
7
- data.tar.gz: 5a2e2e59c4623d73614d6196960b8e1dfe723201750e84b2f4c4d3b7b1e26eb12ea6abea29b7e902323a3b36fef1ecea1b57b0afa65c972699178582456cfcda
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
@@ -1,3 +1,3 @@
1
1
  module LightOperations
2
- VERSION = '0.1.1'
2
+ VERSION = '1.2.0'
3
3
  end
@@ -1,5 +1,6 @@
1
1
  require 'light_operations/version'
2
2
  require 'light_operations/core'
3
+ require 'light_operations/flow'
3
4
 
4
5
  module LightOperations
5
6
  end
@@ -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', '>= 3.0.2'
22
- spec.add_development_dependency 'bundler', '>= 1.6'
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: 0.1.1
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-04-03 00:00:00.000000000 Z
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.2
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.0.2
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.5
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