standard-procedure-plumbing 0.4.4 → 0.4.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  require_relative "custom_filter"
2
2
  module Plumbing
3
3
  # A pipe that filters events from a source pipe
4
- class Filter < CustomFilter
4
+ class Pipe::Filter < Pipe::CustomFilter
5
5
  # Chain this pipe to the source pipe
6
6
  # @param source [Plumbing::Observable] the source from which to receive and filter events
7
7
  # @param &accepts [Block] a block that returns a boolean value - true to accept the event, false to reject it
@@ -14,9 +14,10 @@ module Plumbing
14
14
 
15
15
  protected
16
16
 
17
- def received(event)
18
- return nil unless @accepts.call event
19
- dispatch event
17
+ def received(event_name, data)
18
+ safely do
19
+ notify event_name, **data if @accepts.call(event_name, data)
20
+ end
20
21
  end
21
22
  end
22
23
  end
@@ -1,6 +1,6 @@
1
1
  module Plumbing
2
2
  # A pipe that filters events from a source pipe
3
- class Junction < Pipe
3
+ class Pipe::Junction < Pipe
4
4
  # Chain multiple sources to this pipe
5
5
  # @param sources [Array<Plumbing::Observable>] the sources which will be joined and relayed
6
6
  def initialize *sources
@@ -11,9 +11,9 @@ module Plumbing
11
11
  private
12
12
 
13
13
  def add source
14
- source.as(Observable).add_observer do |event|
14
+ source.as(Observable).add_observer do |event_name, **data|
15
15
  safely do
16
- dispatch event
16
+ notify event_name, **data
17
17
  end
18
18
  end
19
19
  end
data/lib/plumbing/pipe.rb CHANGED
@@ -3,21 +3,19 @@ module Plumbing
3
3
  class Pipe
4
4
  include Plumbing::Actor
5
5
 
6
- async :notify, :<<, :remove_observer, :add_observer, :is_observer?, :shutdown
6
+ async :notify, :remove_observer, :add_observer, :is_observer?, :shutdown
7
7
 
8
- # Push an event into the pipe
9
- # @param event [Plumbing::Event] the event to push into the pipe
10
- def << event
11
- raise Plumbing::InvalidEvent.new event unless event.is_a? Plumbing::Event
12
- dispatch event
13
- end
14
-
15
- # A shortcut to creating and then pushing an event
16
- # @param event_type [String] representing the type of event this is
8
+ # Notify observers about an event
9
+ # @param event_name [String] representing the type of event this is
17
10
  # @param data [Hash] representing the event-specific data to be passed to the observers
18
- def notify event_type, data = nil
19
- Event.new(type: event_type, data: data).tap do |event|
20
- self << event
11
+ def notify event_name, **data
12
+ Plumbing.config.logger.debug { "-> #{self.class}#notify #{event_name}" }
13
+ observers.each do |observer|
14
+ Plumbing.config.logger.debug { "===> #{self.class}#dispatch #{event_name}(#{data}) to #{observer}" }
15
+ observer.call event_name, data
16
+ rescue => ex
17
+ Plumbing.config.logger.error { "!!!! #{self.class}#dispatch #{event_name} => #{ex}" }
18
+ ex
21
19
  end
22
20
  end
23
21
 
@@ -52,23 +50,14 @@ module Plumbing
52
50
  stop
53
51
  end
54
52
 
55
- protected
56
-
57
- # Dispatch an event to all observers
58
- # @param event [Plumbing::Event]
59
- # Enumerates all observers and `calls` them with this event
60
- # Discards any errors raised by the observer so that all observers will be successfully notified
61
- def dispatch event
62
- observers.each do |observer|
63
- observer.call event
64
- rescue => ex
65
- puts ex
66
- ex
67
- end
68
- end
53
+ private
69
54
 
70
55
  def observers
71
56
  @observers ||= []
72
57
  end
58
+
59
+ require_relative "pipe/filter"
60
+ require_relative "pipe/junction"
61
+
73
62
  end
74
63
  end
@@ -0,0 +1,121 @@
1
+ require "rspec/expectations"
2
+
3
+ # Custom matcher that repeatedly evaluates the block until it matches the expected value or the timeout has elapsed
4
+ #
5
+ # This allows asynchronous operations to be tested in a synchronous manner with a timeout
6
+ #
7
+ # Example:
8
+ # expect{ subject.greeting }.to become "Hello Alice"
9
+ #
10
+ RSpec::Matchers.define :become do |expected|
11
+ match do |block|
12
+ wait_for do
13
+ (@result = block.call) == expected
14
+ end
15
+ true
16
+ rescue Timeout::Error
17
+ false
18
+ end
19
+
20
+ def supports_block_expectations? = true
21
+
22
+ failure_message do |expected|
23
+ "expected #{expected} but, after timeout, the result was #{@result}"
24
+ end
25
+ end
26
+
27
+ # Custom matcher that repeatedly evaluates the block until it becomes true or the timeout has elapsed
28
+ #
29
+ # This allows asynchronous operations to be tested in a synchronous manner with a timeout
30
+ #
31
+ # Example:
32
+ # expect { @object.valid? }.to become_true
33
+ #
34
+ RSpec::Matchers.define :become_true do
35
+ match do |block|
36
+ wait_for do
37
+ block.call == true
38
+ end
39
+ true
40
+ rescue Timeout::Error
41
+ false
42
+ end
43
+
44
+ def supports_block_expectations? = true
45
+
46
+ failure_message do |expected|
47
+ "expected true but timeout expired"
48
+ end
49
+ end
50
+
51
+ # Custom matcher that repeatedly evaluates the block until it becomes truthy or the timeout has elapsed
52
+ #
53
+ # This allows asynchronous operations to be tested in a synchronous manner with a timeout
54
+ #
55
+ # Example:
56
+ # expect { @object.message }.to become_truthy
57
+ #
58
+ RSpec::Matchers.define :become_truthy do
59
+ match do |block|
60
+ wait_for do
61
+ block.call
62
+ end
63
+ true
64
+ rescue Timeout::Error
65
+ false
66
+ end
67
+
68
+ def supports_block_expectations? = true
69
+
70
+ failure_message do |expected|
71
+ "expected truthy value but timeout expired"
72
+ end
73
+ end
74
+
75
+ # Custom matcher that repeatedly evaluates the block until it becomes false or the timeout has elapsed
76
+ #
77
+ # This allows asynchronous operations to be tested in a synchronous manner with a timeout
78
+ #
79
+ # Example:
80
+ # expect { @object.in_progress? }.to become_false
81
+ #
82
+ RSpec::Matchers.define :become_false do
83
+ match do |block|
84
+ wait_for do
85
+ block.call == false
86
+ end
87
+ true
88
+ rescue Timeout::Error
89
+ false
90
+ end
91
+
92
+ def supports_block_expectations? = true
93
+
94
+ failure_message do |expected|
95
+ "expected false but timeout expired"
96
+ end
97
+ end
98
+
99
+ # Custom matcher that repeatedly evaluates the block until it becomes falsey or the timeout has elapsed
100
+ #
101
+ # This allows asynchronous operations to be tested in a synchronous manner with a timeout
102
+ #
103
+ # Example:
104
+ # expect { @object.background_task }.to become_falsey
105
+ #
106
+ RSpec::Matchers.define :become_falsey do
107
+ match do |block|
108
+ wait_for do
109
+ !block.call
110
+ end
111
+ true
112
+ rescue Timeout::Error
113
+ false
114
+ end
115
+
116
+ def supports_block_expectations? = true
117
+
118
+ failure_message do |expected|
119
+ "expected falsey but timeout expired"
120
+ end
121
+ end
@@ -0,0 +1,14 @@
1
+ module Plumbing
2
+ module Spec
3
+ def self.modes(inline: true, async: true, threaded: true, &)
4
+ Plumbing.configure(mode: :inline, &) if inline
5
+ Sync { Plumbing.configure(mode: :async, &) } if async
6
+ Plumbing.configure(mode: thread_mode, &) if threaded
7
+ end
8
+
9
+ def self.thread_mode
10
+ defined?(::Rails) ? :threaded_rails : :threaded
11
+ end
12
+ private_class_method :thread_mode
13
+ end
14
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Plumbing
4
- VERSION = "0.4.4"
4
+ VERSION = "0.4.6"
5
5
  end
data/lib/plumbing.rb CHANGED
@@ -6,10 +6,7 @@ module Plumbing
6
6
  require_relative "plumbing/rubber_duck"
7
7
  require_relative "plumbing/types"
8
8
  require_relative "plumbing/error"
9
- require_relative "plumbing/event"
10
9
  require_relative "plumbing/pipe"
11
- require_relative "plumbing/filter"
12
- require_relative "plumbing/junction"
13
10
  require_relative "plumbing/pipeline"
14
11
  require_relative "plumbing/version"
15
12
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: standard-procedure-plumbing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rahoul Baruah
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-09-18 00:00:00.000000000 Z
11
+ date: 2024-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: globalid
@@ -31,6 +31,7 @@ executables: []
31
31
  extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
+ - LICENSE
34
35
  - README.md
35
36
  - Rakefile
36
37
  - lib/plumbing.rb
@@ -42,12 +43,11 @@ files:
42
43
  - lib/plumbing/actor/threaded.rb
43
44
  - lib/plumbing/actor/transporter.rb
44
45
  - lib/plumbing/config.rb
45
- - lib/plumbing/custom_filter.rb
46
46
  - lib/plumbing/error.rb
47
- - lib/plumbing/event.rb
48
- - lib/plumbing/filter.rb
49
- - lib/plumbing/junction.rb
50
47
  - lib/plumbing/pipe.rb
48
+ - lib/plumbing/pipe/custom_filter.rb
49
+ - lib/plumbing/pipe/filter.rb
50
+ - lib/plumbing/pipe/junction.rb
51
51
  - lib/plumbing/pipeline.rb
52
52
  - lib/plumbing/pipeline/contracts.rb
53
53
  - lib/plumbing/pipeline/operations.rb
@@ -55,7 +55,8 @@ files:
55
55
  - lib/plumbing/rubber_duck/module.rb
56
56
  - lib/plumbing/rubber_duck/object.rb
57
57
  - lib/plumbing/rubber_duck/proxy.rb
58
- - lib/plumbing/spec/become_equal_to_matcher.rb
58
+ - lib/plumbing/spec/become_matchers.rb
59
+ - lib/plumbing/spec/modes.rb
59
60
  - lib/plumbing/types.rb
60
61
  - lib/plumbing/version.rb
61
62
  homepage: https://github.com/standard-procedure/plumbing
@@ -1,4 +0,0 @@
1
- module Plumbing
2
- # An immutable data structure representing an Event
3
- Event = Data.define :type, :data
4
- end
@@ -1,23 +0,0 @@
1
- require "rspec/expectations"
2
-
3
- # Custom matcher that repeatedly evaluates the block until it matches the expected value or 5 seconds have elapsed
4
- #
5
- # This allows asynchronous operations to be tested in a synchronous manner with a timeout
6
- #
7
- # Example:
8
- # expect("Hello").to become_equal_to { subject.greeting }
9
- #
10
- RSpec::Matchers.define :become_equal_to do
11
- match do |expected|
12
- wait_for do
13
- block_arg.call == expected
14
- end
15
- true
16
- rescue Timeout::Error
17
- false
18
- end
19
-
20
- failure_message do |expected|
21
- "expected block to return #{expected} but was #{@result} after timeout expired"
22
- end
23
- end