keka 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.circleci/config.yml +17 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +13 -13
- data/README.md +54 -17
- data/lib/keka.rb +29 -57
- data/lib/keka/context.rb +43 -0
- data/lib/keka/exceptions.rb +9 -0
- data/lib/keka/result.rb +17 -0
- data/lib/keka/version.rb +1 -1
- metadata +9 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 441fd2d2712b2ea5b6a15076088de3a1617945f0683251addd7e0be5f5077b9e
|
4
|
+
data.tar.gz: 3d7cf921207b9000a838197669af05d619aadc1252b420d48d74771266dfbccf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 447a280a18b005007788861863dce8b2dc647100add773615a1f5e2ae1a1151020f3955b0486da070a8995e32b7c9b168f5da5adf652b8fb8cb535e1e6b1b151
|
7
|
+
data.tar.gz: 7514d83dd424338c51254855275b4031d45ba34a4814104130a2549aad7e0676327e288edfb1422b08a899d0528ffc48a93f8822a574f17d6af346a749ab57a3
|
@@ -0,0 +1,17 @@
|
|
1
|
+
version: 2
|
2
|
+
jobs:
|
3
|
+
build:
|
4
|
+
docker:
|
5
|
+
- image: circleci/ruby:2.5.3
|
6
|
+
working_directory: ~/repo
|
7
|
+
environment:
|
8
|
+
BUNDLER_VERSION: 1.17.3
|
9
|
+
steps:
|
10
|
+
- checkout
|
11
|
+
- run: gem install bundler:1.17.3
|
12
|
+
- run:
|
13
|
+
name: install dependencies
|
14
|
+
command: bundle install --jobs=4 --retry=3 --path vendor/bundle
|
15
|
+
- run:
|
16
|
+
name: run specs
|
17
|
+
command: bundle exec rspec
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.5.3
|
data/CHANGELOG.md
ADDED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
keka (0.
|
4
|
+
keka (0.2.0)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
@@ -13,19 +13,19 @@ GEM
|
|
13
13
|
coderay (~> 1.1.0)
|
14
14
|
method_source (~> 0.9.0)
|
15
15
|
rake (10.5.0)
|
16
|
-
rspec (3.
|
17
|
-
rspec-core (~> 3.
|
18
|
-
rspec-expectations (~> 3.
|
19
|
-
rspec-mocks (~> 3.
|
20
|
-
rspec-core (3.
|
21
|
-
rspec-support (~> 3.
|
22
|
-
rspec-expectations (3.
|
16
|
+
rspec (3.9.0)
|
17
|
+
rspec-core (~> 3.9.0)
|
18
|
+
rspec-expectations (~> 3.9.0)
|
19
|
+
rspec-mocks (~> 3.9.0)
|
20
|
+
rspec-core (3.9.1)
|
21
|
+
rspec-support (~> 3.9.1)
|
22
|
+
rspec-expectations (3.9.0)
|
23
23
|
diff-lcs (>= 1.2.0, < 2.0)
|
24
|
-
rspec-support (~> 3.
|
25
|
-
rspec-mocks (3.
|
24
|
+
rspec-support (~> 3.9.0)
|
25
|
+
rspec-mocks (3.9.1)
|
26
26
|
diff-lcs (>= 1.2.0, < 2.0)
|
27
|
-
rspec-support (~> 3.
|
28
|
-
rspec-support (3.
|
27
|
+
rspec-support (~> 3.9.0)
|
28
|
+
rspec-support (3.9.2)
|
29
29
|
|
30
30
|
PLATFORMS
|
31
31
|
ruby
|
@@ -38,4 +38,4 @@ DEPENDENCIES
|
|
38
38
|
rspec (~> 3.7)
|
39
39
|
|
40
40
|
BUNDLED WITH
|
41
|
-
1.
|
41
|
+
1.17.3
|
data/README.md
CHANGED
@@ -4,44 +4,34 @@ Keka (Japanese for 'result') is a wrapper that represents the result of a partic
|
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
7
|
-
Add this line to your application's Gemfile:
|
8
|
-
|
9
7
|
```ruby
|
10
8
|
gem 'keka'
|
11
9
|
```
|
12
10
|
|
13
|
-
And then execute:
|
14
|
-
|
15
|
-
$ bundle
|
16
|
-
|
17
|
-
Or install it yourself as:
|
18
|
-
|
19
|
-
$ gem install keka
|
20
|
-
|
21
11
|
## Usage
|
22
12
|
|
23
13
|
Below is an example of how the various methods can come together.
|
24
14
|
|
25
15
|
```ruby
|
26
16
|
class Order
|
27
|
-
def refund
|
17
|
+
def refund(cancel_delivery = true)
|
28
18
|
Keka.run do
|
29
19
|
# returns an err keka with provided msg if !refundable?
|
30
20
|
Keka.err_unless!(refundable?, 'Payment is no longer refundable.')
|
31
21
|
# returns an err keka with provided msg if !refund!
|
32
|
-
Keka.err_unless!(refund
|
22
|
+
Keka.err_unless!(payment.refund, 'Refund failed. Please try again')
|
33
23
|
# execute statements if nothing 'return' from above
|
34
24
|
do_something_else
|
35
|
-
# if cancel_delivery
|
36
|
-
# => returns an err keka with provided msg if !
|
37
|
-
Keka.err_unless!(
|
25
|
+
# if cancel_delivery
|
26
|
+
# => returns an err keka with provided msg if !remove_delivery_assignment
|
27
|
+
Keka.err_unless!(remove_delivery_assignment, 'Refunded but failed to remove delivery.') if cancel_delivery
|
38
28
|
# returns an ok keka if nothing 'return' from above
|
39
29
|
end
|
40
30
|
end
|
41
31
|
|
42
32
|
private
|
43
33
|
|
44
|
-
def
|
34
|
+
def remove_delivery_assignment
|
45
35
|
Keka.run do
|
46
36
|
# returns an ok keka if already_removed?
|
47
37
|
Keka.ok_if! already_removed?
|
@@ -64,9 +54,56 @@ class SomeController
|
|
64
54
|
end
|
65
55
|
```
|
66
56
|
|
67
|
-
Of course, you can also use `.err_unless!`,
|
57
|
+
Of course, you can also use `.err_unless!`, `.err_if!`, and `.ok_if!` outside
|
68
58
|
of the `Keka.run` block.
|
69
59
|
|
60
|
+
### Handle Exceptions
|
61
|
+
|
62
|
+
Before version 0.2.0, handling exceptions in `.run` block is a bit tricky. You might do something like this
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
def validate_purchase(item_ids)
|
66
|
+
Keka.run do
|
67
|
+
Item.find(item_ids)
|
68
|
+
rescue ActiveRecord::RecordNotFound
|
69
|
+
Keka.err_if! true, 'Some item is unavailable'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
```
|
73
|
+
|
74
|
+
After version 0.2.0, you can simply
|
75
|
+
```ruby
|
76
|
+
# * Returns ok result if no exception is raised.
|
77
|
+
# * Returns err result if ActiveRecord::RecordNotFound is raised, with msg set
|
78
|
+
# to 'Some item is unavailable'.
|
79
|
+
# * Raises if any other non-keka exception is thrown.
|
80
|
+
def validate_purchase(item_ids)
|
81
|
+
Keka.rescue_with(ActiveRecord::RecordNotFound, 'Some item is unavailable')
|
82
|
+
.run { Item.find(item_ids) }
|
83
|
+
end
|
84
|
+
```
|
85
|
+
|
86
|
+
You can also chain `.rescue_with`
|
87
|
+
```ruby
|
88
|
+
def validate_purchase(store_id, new_item_payload)
|
89
|
+
Keka.rescue_with(ActiveRecord::RecordNotFound, 'Some item is unavailable')
|
90
|
+
.rescue_with(ActiveRecord::RecordInvalid, 'Invalid payload')
|
91
|
+
.run do
|
92
|
+
store = Store.find(store_id)
|
93
|
+
store.items.create!(new_item_payload)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
98
|
+
Note, by design, `.rescue_with` only rescues from descendants of StandardError. This will **NOT** work.
|
99
|
+
```ruby
|
100
|
+
def invalid_example
|
101
|
+
# The .rescue_with does NOTHING here. This method will raise a NoMemoryError exception.
|
102
|
+
Keka.rescue_with(NoMemoryError, 'oops')
|
103
|
+
.run { raise NoMemoryError.new }
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
70
107
|
## Development
|
71
108
|
|
72
109
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/keka.rb
CHANGED
@@ -1,72 +1,44 @@
|
|
1
1
|
require 'keka/version'
|
2
|
+
require 'keka/exceptions'
|
3
|
+
require 'keka/result'
|
4
|
+
require 'keka/context'
|
2
5
|
|
3
6
|
module Keka
|
7
|
+
class << self
|
8
|
+
include Context::Originable
|
4
9
|
|
5
|
-
|
6
|
-
|
7
|
-
def initialize(keka)
|
8
|
-
@keka = keka
|
9
|
-
super
|
10
|
+
def err_if!(evaluator, msg = nil)
|
11
|
+
raise Halt.new(err(msg)) if (evaluator.respond_to?(:ok?) ? evaluator.ok? : evaluator)
|
10
12
|
end
|
11
|
-
end
|
12
|
-
|
13
|
-
class Base
|
14
|
-
attr_accessor :msg
|
15
13
|
|
16
|
-
def
|
17
|
-
|
18
|
-
|
14
|
+
def err_unless!(evaluator, msg = nil)
|
15
|
+
if evaluator.is_a? self::Result
|
16
|
+
return if evaluator.ok?
|
17
|
+
evaluator.msg = msg if msg
|
18
|
+
raise Halt.new(evaluator)
|
19
|
+
else
|
20
|
+
raise Halt.new(err(msg)) unless evaluator
|
21
|
+
end
|
19
22
|
end
|
20
23
|
|
21
|
-
def
|
22
|
-
|
24
|
+
def ok_if!(evaluator, msg = nil)
|
25
|
+
if evaluator.is_a? self::Result
|
26
|
+
return unless evaluator.ok?
|
27
|
+
evaluator.msg = msg if msg
|
28
|
+
raise Halt.new(evaluator)
|
29
|
+
else
|
30
|
+
raise Halt.new(ok(msg)) if evaluator
|
31
|
+
end
|
23
32
|
end
|
24
33
|
|
25
|
-
private
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
def self.err_if!(evaluator, msg = nil)
|
30
|
-
raise Halt.new(err(msg)) if (evaluator.respond_to?(:ok?) ? evaluator.ok? : evaluator)
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.err_unless!(evaluator, msg = nil)
|
34
|
-
if evaluator.is_a? self::Base
|
35
|
-
return if evaluator.ok?
|
36
|
-
evaluator.msg = msg if msg
|
37
|
-
raise Halt.new(evaluator)
|
38
|
-
else
|
39
|
-
raise Halt.new(err(msg)) unless evaluator
|
34
|
+
# private (maybe)
|
35
|
+
def ok(msg = nil)
|
36
|
+
Result.new(true, msg)
|
40
37
|
end
|
41
|
-
end
|
42
38
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
evaluator.msg = msg if msg
|
47
|
-
raise Halt.new(evaluator)
|
48
|
-
else
|
49
|
-
raise Halt.new(ok(msg)) if evaluator
|
39
|
+
# private (maybe)
|
40
|
+
def err(msg = nil)
|
41
|
+
Result.new(false, msg)
|
50
42
|
end
|
51
43
|
end
|
52
|
-
|
53
|
-
def self.run
|
54
|
-
raise 'Block required!' unless block_given?
|
55
|
-
yield
|
56
|
-
ok
|
57
|
-
rescue Halt => e
|
58
|
-
e.keka
|
59
|
-
end
|
60
|
-
|
61
|
-
|
62
|
-
# private (maybe)
|
63
|
-
def self.ok(msg = nil)
|
64
|
-
Base.new(true, msg)
|
65
|
-
end
|
66
|
-
|
67
|
-
# private (maybe)
|
68
|
-
def self.err(msg = nil)
|
69
|
-
Base.new(false, msg)
|
70
|
-
end
|
71
|
-
|
72
44
|
end
|
data/lib/keka/context.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
module Keka
|
2
|
+
class Context
|
3
|
+
|
4
|
+
module Originable
|
5
|
+
def rescue_with(err_class, err_msg = nil)
|
6
|
+
Context.new.rescue_with(err_class, err_msg)
|
7
|
+
end
|
8
|
+
|
9
|
+
def run(&block)
|
10
|
+
Context.new.run(&block)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@opts = {
|
16
|
+
rescue_exceptions: []
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def rescue_with(err_class, err_msg = nil)
|
21
|
+
opts[:rescue_exceptions] << {
|
22
|
+
klass: err_class,
|
23
|
+
msg: err_msg
|
24
|
+
}
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
def run
|
29
|
+
raise 'Block required!' unless block_given?
|
30
|
+
yield
|
31
|
+
Keka.ok
|
32
|
+
rescue Keka::Halt => e
|
33
|
+
e.result
|
34
|
+
rescue StandardError => e
|
35
|
+
raise unless matched = opts[:rescue_exceptions].detect { |setting| e.is_a?(setting[:klass]) }
|
36
|
+
Keka.err(matched[:msg])
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
attr_reader :opts
|
41
|
+
|
42
|
+
end
|
43
|
+
end
|
data/lib/keka/result.rb
ADDED
data/lib/keka/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: keka
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- zino
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -74,9 +74,11 @@ extensions: []
|
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
76
|
- ".DS_Store"
|
77
|
+
- ".circleci/config.yml"
|
77
78
|
- ".gitignore"
|
78
79
|
- ".rspec"
|
79
|
-
- ".
|
80
|
+
- ".ruby-version"
|
81
|
+
- CHANGELOG.md
|
80
82
|
- Gemfile
|
81
83
|
- Gemfile.lock
|
82
84
|
- LICENSE.txt
|
@@ -86,6 +88,9 @@ files:
|
|
86
88
|
- bin/setup
|
87
89
|
- keka.gemspec
|
88
90
|
- lib/keka.rb
|
91
|
+
- lib/keka/context.rb
|
92
|
+
- lib/keka/exceptions.rb
|
93
|
+
- lib/keka/result.rb
|
89
94
|
- lib/keka/version.rb
|
90
95
|
homepage: https://github.com/zinosama/keka
|
91
96
|
licenses:
|
@@ -107,8 +112,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
107
112
|
- !ruby/object:Gem::Version
|
108
113
|
version: '0'
|
109
114
|
requirements: []
|
110
|
-
|
111
|
-
rubygems_version: 2.6.14
|
115
|
+
rubygems_version: 3.0.2
|
112
116
|
signing_key:
|
113
117
|
specification_version: 4
|
114
118
|
summary: Better handle short-circuit logic, result state, and return message
|