call_sheet 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/Gemfile.lock +4 -1
- data/README.md +23 -21
- data/lib/call_sheet/dsl.rb +0 -2
- data/lib/call_sheet/result_matcher.rb +40 -0
- data/lib/call_sheet/step.rb +5 -6
- data/lib/call_sheet/step_adapters/base.rb +0 -2
- data/lib/call_sheet/step_adapters/map.rb +1 -1
- data/lib/call_sheet/step_adapters/tee.rb +1 -1
- data/lib/call_sheet/step_adapters/try.rb +2 -2
- data/lib/call_sheet/step_failure.rb +3 -1
- data/lib/call_sheet/transaction.rb +7 -4
- data/lib/call_sheet/version.rb +1 -1
- data/lib/call_sheet.rb +1 -1
- data/spec/examples.txt +21 -19
- data/spec/integration/call_sheet_spec.rb +63 -32
- data/spec/integration/passing_step_arguments_spec.rb +1 -1
- data/spec/integration/publishing_step_events_spec.rb +1 -3
- data/spec/spec_helper.rb +3 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bb1702c17a58664dd0fe67c3e785151da951b418
|
4
|
+
data.tar.gz: 9fe07911b83cd2b03f46e4067423322bb61a1cd4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ed94e027073aec6f2ca2d7a3a7e5323463caab088536266fe55b1b41c0bc0b88db1b277cd60f7e5ebbd7799a06965aca1dc250276f3fd91fd57858f60f80b93e
|
7
|
+
data.tar.gz: 37253ade71ab026981f3064d9bc2a77ac5a64fe3cb870096fa01c6bba6c871796cd19a4e0f5d71d69f36695c02a884be027c9c7870dd3d8847c709d0e501c442
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
call_sheet (0.
|
4
|
+
call_sheet (0.2.0)
|
5
5
|
deterministic (>= 0.15.3)
|
6
|
+
kleisli
|
6
7
|
wisper (>= 1.6.0)
|
7
8
|
|
8
9
|
GEM
|
@@ -15,6 +16,7 @@ GEM
|
|
15
16
|
diff-lcs (1.2.5)
|
16
17
|
docile (1.1.5)
|
17
18
|
json (1.8.3)
|
19
|
+
kleisli (0.2.6)
|
18
20
|
parser (2.2.3.0)
|
19
21
|
ast (>= 1.1, < 3.0)
|
20
22
|
powerpack (0.1.1)
|
@@ -54,6 +56,7 @@ PLATFORMS
|
|
54
56
|
DEPENDENCIES
|
55
57
|
bundler (~> 1.10)
|
56
58
|
call_sheet!
|
59
|
+
kleisli
|
57
60
|
rake (~> 10.4.2)
|
58
61
|
rspec (~> 3.3.0)
|
59
62
|
rubocop (~> 0.34.2)
|
data/README.md
CHANGED
@@ -25,7 +25,7 @@ Call Sheet is based on the following ideas, drawn mostly from [Transflow](http:/
|
|
25
25
|
|
26
26
|
Requiring a business transaction's steps to exist as independent operations directly addressable voa a container means that they can be tested in isolation and easily reused throughout your application. Following from this, keeping the business transaction to a series of high-level, declarative steps ensures that it's easy to understand at a glance.
|
27
27
|
|
28
|
-
The output of each step is wrapped in a [
|
28
|
+
The output of each step is wrapped in a [Kleisli](https://github.com/txus/kleisli) `Either` object (`Right` for success or `Left` for failure). This allows the steps to be chained together and ensures that processing stops in the case of a failure. Returning an `Either` from the overall transaction also allows for error handling to remain a primary concern without it getting in the way of tidy, straightforward operation logic. Wrapping the step output also means that you can work with a wide variety of operations within your application – they don’t need to return an `Either` already.
|
29
29
|
|
30
30
|
## Usage
|
31
31
|
|
@@ -33,10 +33,10 @@ All you need to use Call Sheet is a container of operations that respond to `#ca
|
|
33
33
|
|
34
34
|
Each operation is integrated into your business transaction through one of the following step adapters:
|
35
35
|
|
36
|
-
* `map` – any output is considered successful and returned as `
|
37
|
-
* `try` – the operation may raise an exception in an error case. This is caught and returned as `
|
38
|
-
* `tee` – the operation interacts with some external system and has no meaningful output. The original input is passed through and returned as `
|
39
|
-
* `raw` or `step` – the operation already returns its own `
|
36
|
+
* `map` – any output is considered successful and returned as `Right(output)`
|
37
|
+
* `try` – the operation may raise an exception in an error case. This is caught and returned as `Left(exception)`. The output is otherwise returned as `Right(output)`.
|
38
|
+
* `tee` – the operation interacts with some external system and has no meaningful output. The original input is passed through and returned as `Right(input)`.
|
39
|
+
* `raw` or `step` – the operation already returns its own `Either` object, and needs no special handling.
|
40
40
|
|
41
41
|
```ruby
|
42
42
|
DB = []
|
@@ -54,31 +54,33 @@ save_user = CallSheet(container: container) do
|
|
54
54
|
end
|
55
55
|
|
56
56
|
save_user.call("name" => "Jane", "email" => "jane@doe.com")
|
57
|
-
# =>
|
57
|
+
# => Right({:name=>"Jane", :email=>"jane@doe.com"})
|
58
58
|
|
59
59
|
DB
|
60
60
|
# => [{:name=>"Jane", :email=>"jane@doe.com"}]
|
61
61
|
```
|
62
62
|
|
63
|
-
Each transaction returns a `
|
63
|
+
Each transaction returns a result value wrapped in a `Left` or `Right` object. You can handle these different results (including errors arising from particular steps) with a match block:
|
64
64
|
|
65
65
|
```ruby
|
66
|
-
save_user.call(name: "Jane", email: "jane@doe.com")
|
67
|
-
|
66
|
+
save_user.call(name: "Jane", email: "jane@doe.com") do |m|
|
67
|
+
m.success do
|
68
68
|
puts "Succeeded!"
|
69
69
|
end
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
70
|
+
|
71
|
+
m.failure do |f|
|
72
|
+
f.on :validate do |errors|
|
73
|
+
# In a more realistic example, you’d loop through a list of messages in `errors`.
|
74
|
+
puts "Couldn’t save this user. Please provide an email address."
|
75
|
+
end
|
76
|
+
|
77
|
+
f.otherwise do |error|
|
78
|
+
puts "Couldn’t save this user."
|
79
|
+
end
|
76
80
|
end
|
77
81
|
end
|
78
82
|
```
|
79
83
|
|
80
|
-
You can use guard expressions like `where { f == :step_name }` in the failure matches to catch failures that arise from particular steps in your transaction.
|
81
|
-
|
82
84
|
### Passing additional step arguments
|
83
85
|
|
84
86
|
Additional arguments for step operations can be passed at the time of calling your transaction. Provide these arguments as an array, and they’ll be [splatted](https://endofline.wordpress.com/2011/01/21/the-strange-ruby-splat/) into the front of the operation’s arguments. This means that transactions can effectively support operations with any sort of `#call(*args, input)` interface.
|
@@ -100,10 +102,10 @@ end
|
|
100
102
|
|
101
103
|
input = {"name" => "Jane", "email" => "jane@doe.com"}
|
102
104
|
save_user.call(input, validate: ["doe.com"])
|
103
|
-
# =>
|
105
|
+
# => Right({:name=>"Jane", :email=>"jane@doe.com"})
|
104
106
|
|
105
107
|
save_user.call(input, validate: ["smith.com"])
|
106
|
-
# =>
|
108
|
+
# => Left("not allowed")
|
107
109
|
```
|
108
110
|
|
109
111
|
### Subscribing to step notifications
|
@@ -149,7 +151,7 @@ save_user = CallSheet(container: large_whole_app_container) do
|
|
149
151
|
end
|
150
152
|
```
|
151
153
|
|
152
|
-
A `raw` step can
|
154
|
+
A `raw` step (also aliased as `step`) can be used if the operation in your container already returns an `Either` and therefore doesn’t need any special handling.
|
153
155
|
|
154
156
|
## Installation
|
155
157
|
|
@@ -169,7 +171,7 @@ Bug reports and pull requests are welcome on [GitHub](http://github.com/icelab/c
|
|
169
171
|
|
170
172
|
Call Sheet is developed and maintained by [Icelab](http://icelab.com.au/).
|
171
173
|
|
172
|
-
Call Sheet’s error handling is based on Scott Wlaschin’s [Railway Oriented Programming](http://fsharpforfunandprofit.com/rop/), found via Zohaib Rauf’s [Railway Oriented Programming in Elixir](http://zohaib.me/railway-programming-pattern-in-elixir/) blog post. Call Sheet’s behavior as a business transaction library draws heavy inspiration from Piotr Solnica’s [Transflow](http://github.com/solnic/transflow) and Gilbert B Garza’s [Solid Use Case](https://github.com/mindeavor/solid_use_case).
|
174
|
+
Call Sheet’s error handling is based on Scott Wlaschin’s [Railway Oriented Programming](http://fsharpforfunandprofit.com/rop/), found via Zohaib Rauf’s [Railway Oriented Programming in Elixir](http://zohaib.me/railway-programming-pattern-in-elixir/) blog post. Call Sheet’s behavior as a business transaction library draws heavy inspiration from Piotr Solnica’s [Transflow](http://github.com/solnic/transflow) and Gilbert B Garza’s [Solid Use Case](https://github.com/mindeavor/solid_use_case). Josep M. Bach’s [Kleisli](https://github.com/txus/kleisli) gem makes functional programming patterns in Ruby accessible and fun. Thank you all!
|
173
175
|
|
174
176
|
## License
|
175
177
|
|
data/lib/call_sheet/dsl.rb
CHANGED
@@ -0,0 +1,40 @@
|
|
1
|
+
module CallSheet
|
2
|
+
class ResultMatcher
|
3
|
+
attr_reader :result
|
4
|
+
attr_reader :value
|
5
|
+
|
6
|
+
def initialize(result)
|
7
|
+
@result = result
|
8
|
+
@value = result.value
|
9
|
+
end
|
10
|
+
|
11
|
+
def success(&block)
|
12
|
+
block.call value if result.is_a?(Kleisli::Either::Right)
|
13
|
+
end
|
14
|
+
|
15
|
+
def failure(&block)
|
16
|
+
block.call FailureMatcher.new(result) if result.is_a?(Kleisli::Either::Left)
|
17
|
+
end
|
18
|
+
|
19
|
+
class FailureMatcher
|
20
|
+
attr_reader :result
|
21
|
+
attr_reader :value
|
22
|
+
|
23
|
+
def initialize(result)
|
24
|
+
@result = result
|
25
|
+
@value = result.value
|
26
|
+
end
|
27
|
+
|
28
|
+
def on(step_name, &block)
|
29
|
+
if value.__step_name == step_name
|
30
|
+
@matched = true
|
31
|
+
block.call value
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def otherwise(&block)
|
36
|
+
block.call value unless @matched
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/call_sheet/step.rb
CHANGED
@@ -4,7 +4,6 @@ require "call_sheet/step_failure"
|
|
4
4
|
module CallSheet
|
5
5
|
# @api private
|
6
6
|
class Step
|
7
|
-
include Deterministic::Prelude::Result
|
8
7
|
include Wisper::Publisher
|
9
8
|
|
10
9
|
attr_reader :step_name
|
@@ -22,15 +21,15 @@ module CallSheet
|
|
22
21
|
end
|
23
22
|
|
24
23
|
def call(input)
|
25
|
-
args = (call_args << input)
|
24
|
+
args = (call_args.dup << input)
|
26
25
|
result = operation.call(*args)
|
27
26
|
|
28
|
-
result.
|
27
|
+
result.fmap { |value|
|
29
28
|
broadcast :"#{step_name}_success", value
|
30
|
-
|
31
|
-
}.
|
29
|
+
value
|
30
|
+
}.or { |value|
|
32
31
|
broadcast :"#{step_name}_failure", *args, value
|
33
|
-
|
32
|
+
Left(StepFailure.new(step_name, value))
|
34
33
|
}
|
35
34
|
end
|
36
35
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module CallSheet
|
2
2
|
class StepFailure < BasicObject
|
3
|
+
attr_reader :__step_name
|
4
|
+
|
3
5
|
def initialize(step_name, object)
|
4
6
|
@__step_name = step_name
|
5
7
|
@__object = object
|
@@ -10,7 +12,7 @@ module CallSheet
|
|
10
12
|
end
|
11
13
|
|
12
14
|
def ==(other)
|
13
|
-
@
|
15
|
+
@__object == other
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
@@ -1,7 +1,7 @@
|
|
1
|
+
require "call_sheet/result_matcher"
|
2
|
+
|
1
3
|
module CallSheet
|
2
4
|
class Transaction
|
3
|
-
include Deterministic::Prelude::Result
|
4
|
-
|
5
5
|
# @api private
|
6
6
|
attr_reader :steps
|
7
7
|
private :steps
|
@@ -12,12 +12,15 @@ module CallSheet
|
|
12
12
|
end
|
13
13
|
|
14
14
|
# @api public
|
15
|
-
def call(input, options = {})
|
15
|
+
def call(input, options = {}, &block)
|
16
16
|
assert_valid_options(options)
|
17
17
|
assert_options_satisfy_step_arity(options)
|
18
18
|
|
19
19
|
steps = steps_with_options_applied(options)
|
20
|
-
steps.inject(
|
20
|
+
result = steps.inject(Right(input), :>>)
|
21
|
+
|
22
|
+
block.call ResultMatcher.new(result) if block
|
23
|
+
result
|
21
24
|
end
|
22
25
|
alias_method :[], :call
|
23
26
|
|
data/lib/call_sheet/version.rb
CHANGED
data/lib/call_sheet.rb
CHANGED
data/spec/examples.txt
CHANGED
@@ -1,21 +1,23 @@
|
|
1
1
|
example_id | status | run_time |
|
2
2
|
-------------------------------------------------------- | ------ | --------------- |
|
3
|
-
./spec/integration/call_sheet_spec.rb[1:1:1] | passed | 0.
|
4
|
-
./spec/integration/call_sheet_spec.rb[1:1:2] | passed | 0.
|
5
|
-
./spec/integration/call_sheet_spec.rb[1:1:3] | passed | 0.
|
6
|
-
./spec/integration/call_sheet_spec.rb[1:1:4] | passed | 0.
|
7
|
-
./spec/integration/call_sheet_spec.rb[1:
|
8
|
-
./spec/integration/call_sheet_spec.rb[1:2:
|
9
|
-
./spec/integration/call_sheet_spec.rb[1:2:
|
10
|
-
./spec/integration/call_sheet_spec.rb[1:2:
|
11
|
-
./spec/integration/call_sheet_spec.rb[1:2:
|
12
|
-
./spec/integration/call_sheet_spec.rb[1:
|
13
|
-
./spec/integration/call_sheet_spec.rb[1:
|
14
|
-
./spec/integration/call_sheet_spec.rb[1:3:
|
15
|
-
./spec/integration/
|
16
|
-
./spec/integration/
|
17
|
-
./spec/integration/passing_step_arguments_spec.rb[1:
|
18
|
-
./spec/integration/
|
19
|
-
./spec/integration/
|
20
|
-
./spec/integration/publishing_step_events_spec.rb[1:
|
21
|
-
./spec/integration/publishing_step_events_spec.rb[1:
|
3
|
+
./spec/integration/call_sheet_spec.rb[1:1:1] | passed | 0.00147 seconds |
|
4
|
+
./spec/integration/call_sheet_spec.rb[1:1:2] | passed | 0.00103 seconds |
|
5
|
+
./spec/integration/call_sheet_spec.rb[1:1:3] | passed | 0.00032 seconds |
|
6
|
+
./spec/integration/call_sheet_spec.rb[1:1:4] | passed | 0.00108 seconds |
|
7
|
+
./spec/integration/call_sheet_spec.rb[1:1:5] | passed | 0.00043 seconds |
|
8
|
+
./spec/integration/call_sheet_spec.rb[1:2:1] | passed | 0.00224 seconds |
|
9
|
+
./spec/integration/call_sheet_spec.rb[1:2:2] | passed | 0.00028 seconds |
|
10
|
+
./spec/integration/call_sheet_spec.rb[1:2:3] | passed | 0.0007 seconds |
|
11
|
+
./spec/integration/call_sheet_spec.rb[1:2:4] | passed | 0.00027 seconds |
|
12
|
+
./spec/integration/call_sheet_spec.rb[1:2:5] | passed | 0.00025 seconds |
|
13
|
+
./spec/integration/call_sheet_spec.rb[1:2:6] | passed | 0.00048 seconds |
|
14
|
+
./spec/integration/call_sheet_spec.rb[1:3:1] | passed | 0.00035 seconds |
|
15
|
+
./spec/integration/call_sheet_spec.rb[1:3:2] | passed | 0.00018 seconds |
|
16
|
+
./spec/integration/call_sheet_spec.rb[1:3:3] | passed | 0.0003 seconds |
|
17
|
+
./spec/integration/passing_step_arguments_spec.rb[1:1:1] | passed | 0.00023 seconds |
|
18
|
+
./spec/integration/passing_step_arguments_spec.rb[1:2:1] | passed | 0.00039 seconds |
|
19
|
+
./spec/integration/passing_step_arguments_spec.rb[1:3:1] | passed | 0.00137 seconds |
|
20
|
+
./spec/integration/publishing_step_events_spec.rb[1:1:1] | passed | 0.00055 seconds |
|
21
|
+
./spec/integration/publishing_step_events_spec.rb[1:1:2] | passed | 0.00052 seconds |
|
22
|
+
./spec/integration/publishing_step_events_spec.rb[1:2:1] | passed | 0.0004 seconds |
|
23
|
+
./spec/integration/publishing_step_events_spec.rb[1:2:2] | passed | 0.0016 seconds |
|
@@ -1,6 +1,4 @@
|
|
1
1
|
RSpec.describe CallSheet do
|
2
|
-
include Deterministic::Prelude::Result
|
3
|
-
|
4
2
|
let(:call_sheet) {
|
5
3
|
CallSheet(container: container) do
|
6
4
|
map :process
|
@@ -13,7 +11,7 @@ RSpec.describe CallSheet do
|
|
13
11
|
let(:container) {
|
14
12
|
{
|
15
13
|
process: -> input { {name: input["name"], email: input["email"]} },
|
16
|
-
verify: -> input {
|
14
|
+
verify: -> input { Right(input) },
|
17
15
|
validate: -> input { input[:email].nil? ? raise(Test::NotValidError, "email required") : input },
|
18
16
|
persist: -> input { Test::DB << input and true }
|
19
17
|
}
|
@@ -26,87 +24,120 @@ RSpec.describe CallSheet do
|
|
26
24
|
|
27
25
|
context "successful" do
|
28
26
|
let(:input) { {"name" => "Jane", "email" => "jane@doe.com"} }
|
29
|
-
let(:run_call_sheet) { call_sheet.call(input) }
|
30
27
|
|
31
28
|
it "calls the operations" do
|
32
|
-
|
29
|
+
call_sheet.call(input)
|
33
30
|
expect(Test::DB).to include(name: "Jane", email: "jane@doe.com")
|
34
31
|
end
|
35
32
|
|
36
33
|
it "returns a success" do
|
37
|
-
expect(
|
34
|
+
expect(call_sheet.call(input)).to be_a Kleisli::Either::Right
|
38
35
|
end
|
39
36
|
|
40
37
|
it "wraps the result of the final operation" do
|
41
|
-
expect(
|
38
|
+
expect(call_sheet.call(input).value).to eq(name: "Jane", email: "jane@doe.com")
|
39
|
+
end
|
40
|
+
|
41
|
+
it "can be called multiple times to the same effect" do
|
42
|
+
call_sheet.call(input)
|
43
|
+
call_sheet.call(input)
|
44
|
+
|
45
|
+
expect(Test::DB[0]).to eq(name: "Jane", email: "jane@doe.com")
|
46
|
+
expect(Test::DB[1]).to eq(name: "Jane", email: "jane@doe.com")
|
42
47
|
end
|
43
48
|
|
44
|
-
it "supports
|
45
|
-
|
46
|
-
|
47
|
-
|
49
|
+
it "supports matching on success" do
|
50
|
+
results = []
|
51
|
+
|
52
|
+
call_sheet.call(input) do |m|
|
53
|
+
m.success do |value|
|
54
|
+
results << "success for #{value[:email]}"
|
55
|
+
end
|
48
56
|
end
|
49
57
|
|
50
|
-
expect(
|
58
|
+
expect(results.first).to eq "success for jane@doe.com"
|
51
59
|
end
|
52
60
|
end
|
53
61
|
|
54
62
|
context "failed in a try step" do
|
55
63
|
let(:input) { {"name" => "Jane"} }
|
56
|
-
let(:run_call_sheet) { call_sheet.call(input) }
|
57
64
|
|
58
65
|
it "does not run subsequent operations" do
|
59
|
-
|
66
|
+
call_sheet.call(input)
|
60
67
|
expect(Test::DB).to be_empty
|
61
68
|
end
|
62
69
|
|
63
70
|
it "returns a failure" do
|
64
|
-
expect(
|
71
|
+
expect(call_sheet.call(input)).to be_a Kleisli::Either::Left
|
65
72
|
end
|
66
73
|
|
67
74
|
it "wraps the result of the failing operation" do
|
68
|
-
expect(
|
75
|
+
expect(call_sheet.call(input).value).to be_a Test::NotValidError
|
69
76
|
end
|
70
77
|
|
71
|
-
it "supports
|
72
|
-
|
73
|
-
|
74
|
-
|
78
|
+
it "supports matching on failure" do
|
79
|
+
results = []
|
80
|
+
|
81
|
+
call_sheet.call(input) do |m|
|
82
|
+
m.failure do |f|
|
83
|
+
results << "Failed: #{f.value}"
|
84
|
+
end
|
75
85
|
end
|
76
86
|
|
77
|
-
expect(
|
87
|
+
expect(results.first).to eq "Failed: email required"
|
78
88
|
end
|
79
89
|
|
80
|
-
it "supports
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
90
|
+
it "supports matching on specific step failures" do
|
91
|
+
results = []
|
92
|
+
|
93
|
+
call_sheet.call(input) do |m|
|
94
|
+
m.failure do |f|
|
95
|
+
f.on :validate do |v|
|
96
|
+
results << "Validation failure: #{v}"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
expect(results.first).to eq "Validation failure: email required"
|
102
|
+
end
|
103
|
+
|
104
|
+
it "supports matching on un-named step failures" do
|
105
|
+
results = []
|
106
|
+
|
107
|
+
call_sheet.call(input) do |m|
|
108
|
+
m.failure do |f|
|
109
|
+
f.on :some_other_step do |v|
|
110
|
+
results << "Some other step failure"
|
111
|
+
end
|
112
|
+
|
113
|
+
f.otherwise do |v|
|
114
|
+
results << "Catch-all failure: #{v}"
|
115
|
+
end
|
116
|
+
end
|
85
117
|
end
|
86
118
|
|
87
|
-
expect(
|
119
|
+
expect(results.first).to eq "Catch-all failure: email required"
|
88
120
|
end
|
89
121
|
end
|
90
122
|
|
91
123
|
context "failed in a raw step" do
|
92
124
|
let(:input) { {"name" => "Jane", "email" => "jane@doe.com"} }
|
93
|
-
let(:run_call_sheet) { call_sheet.call(input) }
|
94
125
|
|
95
126
|
before do
|
96
|
-
container[:verify] = -> input {
|
127
|
+
container[:verify] = -> input { Left("raw failure") }
|
97
128
|
end
|
98
129
|
|
99
130
|
it "does not run subsequent operations" do
|
100
|
-
|
131
|
+
call_sheet.call(input)
|
101
132
|
expect(Test::DB).to be_empty
|
102
133
|
end
|
103
134
|
|
104
135
|
it "returns a failure" do
|
105
|
-
expect(
|
136
|
+
expect(call_sheet.call(input)).to be_a Kleisli::Either::Left
|
106
137
|
end
|
107
138
|
|
108
139
|
it "returns the failing value from the operation" do
|
109
|
-
expect(
|
140
|
+
expect(call_sheet.call(input).value).to eq "raw failure"
|
110
141
|
end
|
111
142
|
end
|
112
143
|
end
|
@@ -28,7 +28,7 @@ RSpec.describe "Passing additional arguments to step operations" do
|
|
28
28
|
let(:step_options) { {validate: ["doe.com"]} }
|
29
29
|
|
30
30
|
it "passes the arguments and calls the operations successfully" do
|
31
|
-
expect(run_call_sheet).to
|
31
|
+
expect(run_call_sheet).to be_a Kleisli::Either::Right
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -1,6 +1,4 @@
|
|
1
1
|
RSpec.describe "publishing step events" do
|
2
|
-
include Deterministic::Prelude::Result
|
3
|
-
|
4
2
|
let(:call_sheet) {
|
5
3
|
CallSheet(container: container) do
|
6
4
|
map :process
|
@@ -12,7 +10,7 @@ RSpec.describe "publishing step events" do
|
|
12
10
|
let(:container) {
|
13
11
|
{
|
14
12
|
process: -> input { {name: input["name"]} },
|
15
|
-
verify: -> input { input[:name].to_s != "" ?
|
13
|
+
verify: -> input { input[:name].to_s != "" ? Right(input) : Left("no name") },
|
16
14
|
persist: -> input { Test::DB << input and true }
|
17
15
|
}
|
18
16
|
}
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: call_sheet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Riley
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-11-
|
11
|
+
date: 2015-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: deterministic
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.15.3
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: kleisli
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: wisper
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -136,6 +150,7 @@ files:
|
|
136
150
|
- Rakefile
|
137
151
|
- lib/call_sheet.rb
|
138
152
|
- lib/call_sheet/dsl.rb
|
153
|
+
- lib/call_sheet/result_matcher.rb
|
139
154
|
- lib/call_sheet/step.rb
|
140
155
|
- lib/call_sheet/step_adapters.rb
|
141
156
|
- lib/call_sheet/step_adapters/base.rb
|