standard-procedure-plumbing 0.4.3 → 0.4.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +504 -0
- data/README.md +39 -0
- data/lib/plumbing/actor/async.rb +1 -1
- data/lib/plumbing/actor/inline.rb +1 -1
- data/lib/plumbing/actor/kernel.rb +11 -0
- data/lib/plumbing/actor/threaded.rb +20 -14
- data/lib/plumbing/actor.rb +1 -1
- data/lib/plumbing/config.rb +2 -2
- data/lib/plumbing/spec/become_matchers.rb +121 -0
- data/lib/plumbing/version.rb +1 -1
- metadata +5 -20
- data/spec/become_equal_to_matcher.rb +0 -26
- data/spec/examples/actor_spec.rb +0 -86
- data/spec/examples/await_spec.rb +0 -43
- data/spec/examples/pipe_spec.rb +0 -145
- data/spec/examples/pipeline_spec.rb +0 -89
- data/spec/examples/rubber_duck_spec.rb +0 -109
- data/spec/plumbing/a_pipe.rb +0 -110
- data/spec/plumbing/actor/transporter_spec.rb +0 -159
- data/spec/plumbing/actor_spec.rb +0 -386
- data/spec/plumbing/custom_filter_spec.rb +0 -29
- data/spec/plumbing/filter_spec.rb +0 -32
- data/spec/plumbing/junction_spec.rb +0 -67
- data/spec/plumbing/pipe_spec.rb +0 -31
- data/spec/plumbing/pipeline_spec.rb +0 -208
- data/spec/plumbing/rubber_duck_spec.rb +0 -74
- data/spec/plumbing_spec.rb +0 -7
- data/spec/spec_helper.rb +0 -16
@@ -1,208 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
require "dry/validation"
|
3
|
-
|
4
|
-
RSpec.describe Plumbing::Pipeline do
|
5
|
-
it "defines a single operation that returns a value based upon the input parameters" do
|
6
|
-
# standard:disable Lint/ConstantDefinitionInBlock
|
7
|
-
class Addition < Plumbing::Pipeline
|
8
|
-
perform :addition
|
9
|
-
|
10
|
-
private
|
11
|
-
|
12
|
-
def addition number
|
13
|
-
number + 1
|
14
|
-
end
|
15
|
-
end
|
16
|
-
# standard:enable Lint/ConstantDefinitionInBlock
|
17
|
-
|
18
|
-
expect(Addition.new.call(5)).to eq 6
|
19
|
-
end
|
20
|
-
|
21
|
-
it "defines a sequence of commands that are executed in order" do
|
22
|
-
# standard:disable Lint/ConstantDefinitionInBlock
|
23
|
-
class Sequence < Plumbing::Pipeline
|
24
|
-
perform :first_step
|
25
|
-
perform :second_step
|
26
|
-
perform :third_step
|
27
|
-
|
28
|
-
private
|
29
|
-
|
30
|
-
def first_step value = []
|
31
|
-
value << "first"
|
32
|
-
end
|
33
|
-
|
34
|
-
def second_step value = []
|
35
|
-
value << "second"
|
36
|
-
end
|
37
|
-
|
38
|
-
def third_step value = []
|
39
|
-
value << "third"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
# standard:enable Lint/ConstantDefinitionInBlock
|
43
|
-
|
44
|
-
expect(Sequence.new.call([])).to eq ["first", "second", "third"]
|
45
|
-
end
|
46
|
-
|
47
|
-
context "embedding an external command" do
|
48
|
-
it "specifies the command with a string" do
|
49
|
-
# standard:disable Lint/ConstantDefinitionInBlock
|
50
|
-
class InnerByName < Plumbing::Pipeline
|
51
|
-
perform :embedded_step
|
52
|
-
|
53
|
-
private
|
54
|
-
|
55
|
-
def embedded_step value = []
|
56
|
-
value << "embedded"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
class OuterByName < Plumbing::Pipeline
|
61
|
-
perform :first_step
|
62
|
-
perform :second_step, using: "InnerByName"
|
63
|
-
perform :third_step
|
64
|
-
|
65
|
-
private
|
66
|
-
|
67
|
-
def first_step value = []
|
68
|
-
value << "first"
|
69
|
-
end
|
70
|
-
|
71
|
-
def third_step value = []
|
72
|
-
value << "third"
|
73
|
-
end
|
74
|
-
end
|
75
|
-
# standard:enable Lint/ConstantDefinitionInBlock
|
76
|
-
|
77
|
-
expect(OuterByName.new.call([])).to eq ["first", "embedded", "third"]
|
78
|
-
end
|
79
|
-
|
80
|
-
it "specifies the command with a class" do
|
81
|
-
# standard:disable Lint/ConstantDefinitionInBlock
|
82
|
-
class InnerByClass < Plumbing::Pipeline
|
83
|
-
perform :embedded_step
|
84
|
-
|
85
|
-
private
|
86
|
-
|
87
|
-
def embedded_step value = []
|
88
|
-
value << "embedded"
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
class OuterByClass < Plumbing::Pipeline
|
93
|
-
perform :first_step
|
94
|
-
perform :second_step, using: InnerByClass
|
95
|
-
perform :third_step
|
96
|
-
|
97
|
-
private
|
98
|
-
|
99
|
-
def first_step value = []
|
100
|
-
value << "first"
|
101
|
-
end
|
102
|
-
|
103
|
-
def third_step value = []
|
104
|
-
value << "third"
|
105
|
-
end
|
106
|
-
end
|
107
|
-
# standard:enable Lint/ConstantDefinitionInBlock
|
108
|
-
|
109
|
-
expect(OuterByClass.new.call([])).to eq ["first", "embedded", "third"]
|
110
|
-
end
|
111
|
-
end
|
112
|
-
|
113
|
-
it "defines an operation that does something but returns the provided input untouched" do
|
114
|
-
# standard:disable Lint/ConstantDefinitionInBlock
|
115
|
-
class Passthrough < Plumbing::Pipeline
|
116
|
-
execute :external_operation
|
117
|
-
|
118
|
-
private
|
119
|
-
|
120
|
-
def external_operation input
|
121
|
-
# SomeApi.do_some_stuff input
|
122
|
-
nil
|
123
|
-
end
|
124
|
-
end
|
125
|
-
# standard:enable Lint/ConstantDefinitionInBlock
|
126
|
-
|
127
|
-
expect(Passthrough.new.call("some parameters")).to eq "some parameters"
|
128
|
-
end
|
129
|
-
|
130
|
-
it "raises a PreConditionError if the input fails the precondition test" do
|
131
|
-
# standard:disable Lint/ConstantDefinitionInBlock
|
132
|
-
class PreConditionCheck < Plumbing::Pipeline
|
133
|
-
pre_condition :has_first_key do |input|
|
134
|
-
input.key?(:first)
|
135
|
-
end
|
136
|
-
|
137
|
-
pre_condition :has_second_key do |input|
|
138
|
-
input.key?(:second)
|
139
|
-
end
|
140
|
-
|
141
|
-
perform :do_something
|
142
|
-
|
143
|
-
private
|
144
|
-
|
145
|
-
def do_something input
|
146
|
-
"#{input[:first]} #{input[:second]}"
|
147
|
-
end
|
148
|
-
end
|
149
|
-
# standard:enable Lint/ConstantDefinitionInBlock
|
150
|
-
|
151
|
-
expect(PreConditionCheck.new.call(first: "First", second: "Second")).to eq "First Second"
|
152
|
-
expect { PreConditionCheck.new.call(first: "First") }.to raise_error(Plumbing::PreConditionError, "has_second_key")
|
153
|
-
end
|
154
|
-
|
155
|
-
it "raises a PreConditionError if the input fails to validate against a Dry::Validation::Contract" do
|
156
|
-
# standard:disable Lint/ConstantDefinitionInBlock
|
157
|
-
class Validated < Plumbing::Pipeline
|
158
|
-
validate_with "Validated::Input"
|
159
|
-
perform :say_hello
|
160
|
-
|
161
|
-
private
|
162
|
-
|
163
|
-
def say_hello input
|
164
|
-
"Hello #{input[:name]} (#{input[:email]})"
|
165
|
-
end
|
166
|
-
|
167
|
-
class Input < Dry::Validation::Contract
|
168
|
-
params do
|
169
|
-
required(:name).filled(:string)
|
170
|
-
required(:email).filled(:string)
|
171
|
-
end
|
172
|
-
rule :email do
|
173
|
-
key.failure("must be a valid email") unless /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i.match? value
|
174
|
-
end
|
175
|
-
end
|
176
|
-
end
|
177
|
-
# standard:enable Lint/ConstantDefinitionInBlock
|
178
|
-
|
179
|
-
expect(Validated.new.call(name: "Alice", email: "alice@example.com")).to eq "Hello Alice (alice@example.com)"
|
180
|
-
expect { Validated.new.call(email: "alice@example.com") }.to raise_error(Plumbing::PreConditionError, {name: ["is missing"]}.to_yaml)
|
181
|
-
expect { Validated.new.call(name: "Bob", email: "bob-has-fat-fingers-and-cant-type") }.to raise_error(Plumbing::PreConditionError, {email: ["must be a valid email"]}.to_yaml)
|
182
|
-
end
|
183
|
-
|
184
|
-
it "raises a PostConditionError if the outputs fail the postcondition test" do
|
185
|
-
# standard:disable Lint/ConstantDefinitionInBlock
|
186
|
-
class PostConditionCheck < Plumbing::Pipeline
|
187
|
-
post_condition :should_be_integer do |result|
|
188
|
-
result.instance_of? Integer
|
189
|
-
end
|
190
|
-
|
191
|
-
post_condition :should_be_greater_than_zero do |result|
|
192
|
-
result > 0
|
193
|
-
end
|
194
|
-
|
195
|
-
perform :do_something
|
196
|
-
|
197
|
-
private
|
198
|
-
|
199
|
-
def do_something value
|
200
|
-
value.to_i
|
201
|
-
end
|
202
|
-
end
|
203
|
-
# standard:enable Lint/ConstantDefinitionInBlock
|
204
|
-
|
205
|
-
expect(PostConditionCheck.new.call("23")).to eq 23
|
206
|
-
expect { PostConditionCheck.new.call("NOT A NUMBER") }.to raise_error(Plumbing::PostConditionError, "should_be_greater_than_zero")
|
207
|
-
end
|
208
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
RSpec.describe Plumbing::RubberDuck do
|
4
|
-
# standard:disable Lint/ConstantDefinitionInBlock
|
5
|
-
class Duck
|
6
|
-
def quack = "Quack"
|
7
|
-
|
8
|
-
def swim(place) = "Swim in #{place}"
|
9
|
-
|
10
|
-
def fly(&block) = "Fly #{block.call}"
|
11
|
-
end
|
12
|
-
# standard:enable Lint/ConstantDefinitionInBlock
|
13
|
-
|
14
|
-
context "defining rubber ducks" do
|
15
|
-
it "verifies that an object matches the RubberDuck type" do
|
16
|
-
@duck_type = described_class.define :quack, :swim, :fly
|
17
|
-
@duck = Duck.new
|
18
|
-
|
19
|
-
expect(@duck_type.verify(@duck)).to eq @duck
|
20
|
-
end
|
21
|
-
|
22
|
-
it "casts the object to a duck type" do
|
23
|
-
@duck_type = described_class.define :quack, :swim, :fly
|
24
|
-
@duck = Duck.new
|
25
|
-
|
26
|
-
@proxy = @duck.as @duck_type
|
27
|
-
|
28
|
-
expect(@proxy).to be_kind_of Plumbing::RubberDuck::Proxy
|
29
|
-
expect(@proxy).to respond_to :quack
|
30
|
-
expect(@proxy.quack).to eq "Quack"
|
31
|
-
expect(@proxy).to respond_to :swim
|
32
|
-
expect(@proxy.swim("the river")).to eq "Swim in the river"
|
33
|
-
expect(@proxy).to respond_to :fly
|
34
|
-
expect(@proxy.fly { "ducky fly" }).to eq "Fly ducky fly"
|
35
|
-
end
|
36
|
-
|
37
|
-
it "does not forward methods that are not part of the duck type" do
|
38
|
-
@duck_type = described_class.define :swim, :fly
|
39
|
-
@duck = Duck.new
|
40
|
-
|
41
|
-
@proxy = @duck.as @duck_type
|
42
|
-
|
43
|
-
expect(@proxy).to_not respond_to :quack
|
44
|
-
end
|
45
|
-
|
46
|
-
it "does not wrap rubber ducks in a proxy" do
|
47
|
-
@duck_type = described_class.define :swim, :fly
|
48
|
-
@duck = Duck.new
|
49
|
-
|
50
|
-
@proxy = @duck.as @duck_type
|
51
|
-
|
52
|
-
expect(@proxy.as(@duck_type)).to eq @proxy
|
53
|
-
end
|
54
|
-
|
55
|
-
it "allows rubber ducks to be expanded and cast to other types" do
|
56
|
-
@quackers = described_class.define :quack
|
57
|
-
@swimming_bird = described_class.define :swim, :fly
|
58
|
-
@duck = Duck.new
|
59
|
-
|
60
|
-
@swimmer = @duck.as @swimming_bird
|
61
|
-
@quacker = @swimmer.as @quackers
|
62
|
-
|
63
|
-
expect(@swimmer).to respond_to :swim
|
64
|
-
expect(@quacker).to respond_to :quack
|
65
|
-
end
|
66
|
-
|
67
|
-
it "raises a TypeError if the object does not respond to the given methods" do
|
68
|
-
@cow_type = described_class.define :moo, :chew
|
69
|
-
@duck = Duck.new
|
70
|
-
|
71
|
-
expect { @cow_type.verify(@duck) }.to raise_error(TypeError)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
data/spec/plumbing_spec.rb
DELETED
data/spec/spec_helper.rb
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "plumbing"
|
4
|
-
require_relative "become_equal_to_matcher"
|
5
|
-
|
6
|
-
RSpec.configure do |config|
|
7
|
-
# Enable flags like --only-failures and --next-failure
|
8
|
-
config.example_status_persistence_file_path = ".rspec_status"
|
9
|
-
|
10
|
-
# Disable RSpec exposing methods globally on `Module` and `main`
|
11
|
-
config.disable_monkey_patching!
|
12
|
-
|
13
|
-
config.expect_with :rspec do |c|
|
14
|
-
c.syntax = :expect
|
15
|
-
end
|
16
|
-
end
|