standard-procedure-plumbing 0.3.3 → 0.4.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.
@@ -1,71 +0,0 @@
1
- require_relative "valve/inline"
2
-
3
- module Plumbing
4
- module Valve
5
- def self.included base
6
- base.extend ClassMethods
7
- end
8
-
9
- module ClassMethods
10
- # Create a new valve instance and build a proxy for it using the current mode
11
- # @return [Plumbing::Valve::Base] the proxy for the valve instance
12
- def start(*, **, &)
13
- build_proxy_for(new(*, **, &))
14
- end
15
-
16
- # Define the queries that this valve can answer
17
- # @param names [Array<Symbol>] the names of the queries
18
- def query(*names) = queries.concat(names.map(&:to_sym))
19
-
20
- # List the queries that this valve can answer
21
- def queries = @queries ||= []
22
-
23
- # Define the commands that this valve can execute
24
- # @param names [Array<Symbol>] the names of the commands
25
- def command(*names) = commands.concat(names.map(&:to_sym))
26
-
27
- # List the commands that this valve can execute
28
- def commands = @commands ||= []
29
-
30
- def inherited subclass
31
- subclass.commands.concat commands
32
- subclass.queries.concat queries
33
- end
34
-
35
- private
36
-
37
- def build_proxy_for(target)
38
- proxy_class_for(target.class).new(target)
39
- end
40
-
41
- def proxy_class_for target_class
42
- Plumbing.config.valve_proxy_class_for(target_class) || register_valve_proxy_class_for(target_class)
43
- end
44
-
45
- def proxy_base_class = const_get "Plumbing::Valve::#{Plumbing.config.mode.to_s.capitalize}"
46
-
47
- def register_valve_proxy_class_for target_class
48
- Plumbing.config.register_valve_proxy_class_for(target_class, build_proxy_class)
49
- end
50
-
51
- def build_proxy_class
52
- Class.new(proxy_base_class).tap do |proxy_class|
53
- queries.each do |query|
54
- proxy_class.define_method query do |*args, ignore_result: false, **params, &block|
55
- ignore_result ? tell(query, *args, **params, &block) : ask(query, *args, **params, &block)
56
- end
57
- end
58
-
59
- commands.each do |command|
60
- proxy_class.define_method command do |*args, **params, &block|
61
- tell(command, *args, **params, &block)
62
- nil
63
- rescue
64
- nil
65
- end
66
- end
67
- end
68
- end
69
- end
70
- end
71
- end
@@ -1,171 +0,0 @@
1
- require "spec_helper"
2
-
3
- require_relative "../../lib/plumbing/valve/async"
4
- require_relative "../../lib/plumbing/valve/threaded"
5
- require_relative "../../lib/plumbing/valve/rails"
6
-
7
- RSpec.describe Plumbing::Valve do
8
- # standard:disable Lint/ConstantDefinitionInBlock
9
- class Counter
10
- include Plumbing::Valve
11
- query :name, :count, :am_i_failing?, :slow_query
12
- command "slowly_increment", "raises_error"
13
- attr_reader :name, :count
14
-
15
- def initialize name, initial_value: 0
16
- @name = name
17
- @count = initial_value
18
- end
19
-
20
- def slowly_increment
21
- sleep 0.5
22
- @count += 1
23
- end
24
-
25
- def slow_query
26
- sleep 0.5
27
- @count
28
- end
29
-
30
- def am_i_failing? = raise "I'm a failure"
31
-
32
- def raises_error = raise "I'm an error"
33
- end
34
-
35
- class StepCounter < Counter
36
- query :step_value
37
- attr_reader :step_value
38
-
39
- def initialize name, initial_value: 0, step_value: 5
40
- super(name, initial_value: initial_value)
41
- @step_value = step_value
42
- end
43
-
44
- def slowly_increment
45
- sleep 0.5
46
- @count += @step_value
47
- end
48
-
49
- def failing_query
50
- raise "I'm a failure"
51
- end
52
- end
53
- # standard:enable Lint/ConstantDefinitionInBlock
54
-
55
- it "knows which queries are defined" do
56
- expect(Counter.queries).to eq [:name, :count, :am_i_failing?, :slow_query]
57
- end
58
-
59
- it "knows which commands are defined" do
60
- expect(Counter.commands).to eq [:slowly_increment, :raises_error]
61
- end
62
-
63
- it "raises exceptions from queries" do
64
- @counter = Counter.start "failure"
65
-
66
- expect { @counter.am_i_failing? }.to raise_error "I'm a failure"
67
- end
68
-
69
- it "does not raise exceptions from commands" do
70
- @counter = Counter.start "failure"
71
-
72
- expect { @counter.raises_error }.not_to raise_error
73
- end
74
-
75
- it "raises exceptions from queries" do
76
- @counter = Counter.start "failure"
77
-
78
- expect { @counter.am_i_failing? }.to raise_error "I'm a failure"
79
- end
80
-
81
- it "reuses existing proxy classes" do
82
- @counter = Counter.start "inline counter", initial_value: 100
83
- @proxy_class = @counter.class
84
-
85
- @counter = Counter.start "another inline counter", initial_value: 200
86
- expect(@counter.class).to eq @proxy_class
87
- end
88
-
89
- it "includes commands and queries from the superclass" do
90
- expect(StepCounter.queries).to eq [:name, :count, :am_i_failing?, :slow_query, :step_value]
91
- expect(StepCounter.commands).to eq [:slowly_increment, :raises_error]
92
-
93
- @step_counter = StepCounter.start "step counter", initial_value: 100, step_value: 10
94
-
95
- expect(@step_counter.count).to eq 100
96
- expect(@step_counter.step_value).to eq 10
97
- @step_counter.slowly_increment
98
- expect(@step_counter.count).to eq 110
99
- end
100
-
101
- context "inline" do
102
- around :example do |example|
103
- Plumbing.configure mode: :inline, &example
104
- end
105
-
106
- it "sends all queries immediately" do
107
- @counter = Counter.start "inline counter", initial_value: 100
108
- @time = Time.now
109
-
110
- expect(@counter.name).to eq "inline counter"
111
- expect(@counter.count).to eq 100
112
- expect(Time.now - @time).to be < 0.1
113
-
114
- expect(@counter.slow_query).to eq 100
115
- expect(Time.now - @time).to be > 0.4
116
- end
117
-
118
- it "sends all commands immediately" do
119
- @counter = Counter.start "inline counter", initial_value: 100
120
- @time = Time.now
121
-
122
- @counter.slowly_increment
123
-
124
- expect(@counter.count).to eq 101
125
- expect(Time.now - @time).to be > 0.4
126
- end
127
- end
128
-
129
- [:threaded, :async].each do |mode|
130
- context mode.to_s do
131
- around :example do |example|
132
- Sync do
133
- Plumbing.configure mode: mode, &example
134
- end
135
- end
136
-
137
- it "performs queries in the background and waits for the response" do
138
- @counter = Counter.start "async counter", initial_value: 100
139
- @time = Time.now
140
-
141
- expect(@counter.name).to eq "async counter"
142
- expect(@counter.count).to eq 100
143
- expect(Time.now - @time).to be < 0.1
144
-
145
- expect(@counter.slow_query).to eq 100
146
- expect(Time.now - @time).to be > 0.4
147
- end
148
-
149
- it "performs queries ignoring the response and returning immediately" do
150
- @counter = Counter.start "threaded counter", initial_value: 100
151
- @time = Time.now
152
-
153
- expect(@counter.slow_query(ignore_result: true)).to be_nil
154
-
155
- expect(Time.now - @time).to be < 0.1
156
- end
157
-
158
- it "performs commands in the background and returning immediately" do
159
- @counter = Counter.start "threaded counter", initial_value: 100
160
- @time = Time.now
161
-
162
- @counter.slowly_increment
163
- expect(Time.now - @time).to be < 0.1
164
-
165
- # wait for the threaded task to complete
166
- expect(101).to become_equal_to { @counter.count }
167
- expect(Time.now - @time).to be > 0.4
168
- end
169
- end
170
- end
171
- end