keka 0.1.0 → 0.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 +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
|