stenotype 0.1.15 → 0.1.16
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 +4 -4
- data/CHANGELOG.md +3 -0
- data/README.md +42 -0
- data/lib/stenotype/adapters/test_adapter.rb +35 -0
- data/lib/stenotype/test/matchers.rb +145 -0
- data/lib/stenotype/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 31a64803c8b2a343a441ce48a26d5b14e5aa55792d718fe2afb236f0589507ca
|
4
|
+
data.tar.gz: 999e4ae1554d49663ac4b8e8cecd94507cde51cfa494c28ebf21fab4240eb41a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a001057b435a76475cb49deb9a73601c2144a3468578d0a68f188ccad85598678a0b5909cd3f32f31b8b04bda42c284b8cb5d54b7423663a79beefb6afcaaf61
|
7
|
+
data.tar.gz: a3f20a7345504675073ad48b48fd3dfb73018bd3d65d1855a28e0224a61a1a9274aaf39bfa483de465b95a82915a616f7c9987986be28a7c3d1f2f1992f3c6d3
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -275,6 +275,48 @@ end
|
|
275
275
|
|
276
276
|
You do not have to manually register the context handler since it happens upon inheriting from `Stenotype::ContextHandlers::Base`
|
277
277
|
|
278
|
+
## Testing
|
279
|
+
|
280
|
+
Stenotype currently supports RSpec integration. To be able to test even emission you can use a predefined matcher by adding the following to spec helper:
|
281
|
+
|
282
|
+
```ruby
|
283
|
+
RSpec.configure do |config|
|
284
|
+
config.around(:each, type: :stenotype_event) do |example|
|
285
|
+
require 'stenotype/adapters/test_adapter'
|
286
|
+
|
287
|
+
config.include Stenotype::Test::Matchers
|
288
|
+
|
289
|
+
RSpec::Mocks.with_temporary_scope do
|
290
|
+
allow(Stenotype.config).to receive(:targets).and_return(Array.wrap(Stenotype::Adapters::TestAdapter.new))
|
291
|
+
example.run
|
292
|
+
allow(Stenotype.config).to receive(:targets).and_call_original
|
293
|
+
end
|
294
|
+
end
|
295
|
+
end
|
296
|
+
```
|
297
|
+
|
298
|
+
After adding the configuration you can use the matchers:
|
299
|
+
```ruby
|
300
|
+
class Example
|
301
|
+
include Stenotype::Emitter
|
302
|
+
|
303
|
+
def trigger
|
304
|
+
emit_event(:user_subscription)
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
RSpec.describe Stenotype::Emitter do
|
309
|
+
describe "POST #create" do
|
310
|
+
subject(:post) { Example.new.trigger }
|
311
|
+
|
312
|
+
it "emits a user_subscription event", type: :stenotype_event do
|
313
|
+
expect { post }.to emit_an_event(:user_subscription).
|
314
|
+
with_arguments_including({ uuid: "abcd" }).
|
315
|
+
exactly(1).times
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
319
|
+
```
|
278
320
|
|
279
321
|
## Development
|
280
322
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Stenotype
|
4
|
+
module Adapters
|
5
|
+
class TestAdapter < Base
|
6
|
+
attr_reader :buffer
|
7
|
+
|
8
|
+
def initialize(*_)
|
9
|
+
@buffer = Array.new
|
10
|
+
super()
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
# @param event_data {Sting} The data to be published
|
15
|
+
# @param additional_attrs {Hash} The list of additional event attributes
|
16
|
+
#
|
17
|
+
def publish(event_data, **additional_attrs)
|
18
|
+
buffer << parse(event_data)
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Clears the buffer
|
23
|
+
#
|
24
|
+
def flush!
|
25
|
+
buffer.clear
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def parse(event_data)
|
31
|
+
JSON.parse(event_data)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
module Stenotype
|
5
|
+
module Test
|
6
|
+
module Matchers
|
7
|
+
extend RSpec::Matchers::DSL
|
8
|
+
|
9
|
+
class DiffSizeMatchesExpectation
|
10
|
+
attr_reader :matching_events, :expected_count
|
11
|
+
|
12
|
+
def initialize(matching_events, expected_count)
|
13
|
+
@matching_events = matching_events
|
14
|
+
@expected_count = expected_count
|
15
|
+
end
|
16
|
+
|
17
|
+
def failure_message
|
18
|
+
"expected to see #{expected_count} event(s) but got #{matching_events.count} event(s)."
|
19
|
+
end
|
20
|
+
|
21
|
+
def matches?
|
22
|
+
matching_events.count == expected_count
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class EventHasExpectedArguments
|
27
|
+
attr_reader :matching_events, :expected_arguments
|
28
|
+
|
29
|
+
def initialize(matching_events, expected_arguments)
|
30
|
+
@matching_events = matching_events
|
31
|
+
@expected_arguments = stringify_keys(expected_arguments)
|
32
|
+
end
|
33
|
+
|
34
|
+
def matches?
|
35
|
+
return false if multiple_events?
|
36
|
+
|
37
|
+
(expected_arguments.to_a - matching_event.to_a).empty?
|
38
|
+
end
|
39
|
+
|
40
|
+
def failure_message
|
41
|
+
if multiple_events?
|
42
|
+
"more than one event with given event name has been emitted. Can not match event arguments"
|
43
|
+
else
|
44
|
+
"expected to see all attributes from #{expected_arguments} to be included in event attributes but got #{matching_event}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def multiple_events?
|
51
|
+
matching_events.size > 1
|
52
|
+
end
|
53
|
+
|
54
|
+
def matching_event
|
55
|
+
matching_events.first
|
56
|
+
end
|
57
|
+
|
58
|
+
def stringify_keys(hash)
|
59
|
+
hash.transform_keys(&:to_s)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
class EventEmitted
|
64
|
+
attr_reader :matching_events, :expected_event_name
|
65
|
+
|
66
|
+
def initialize(matching_events, expected_event_name)
|
67
|
+
@matching_events = matching_events
|
68
|
+
@expected_event_name = expected_event_name
|
69
|
+
end
|
70
|
+
|
71
|
+
def matches?
|
72
|
+
matching_events.any?
|
73
|
+
end
|
74
|
+
|
75
|
+
def failure_message
|
76
|
+
"expected to see a '#{expected_event_name}' event but got nothing"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
matcher :emit_an_event do |expected_event_name, *_|
|
81
|
+
supports_block_expectations
|
82
|
+
|
83
|
+
match do |emitting_event_block|
|
84
|
+
@emitting_event_block = emitting_event_block
|
85
|
+
|
86
|
+
partial_matchers << EventEmitted.new(matching_events, expected_event_name)
|
87
|
+
partial_matchers << EventHasExpectedArguments.new(matching_events, @arguments_should_include) if should_validate_events_count?
|
88
|
+
partial_matchers << DiffSizeMatchesExpectation.new(matching_events, @matching_events_count) if should_validate_attributes?
|
89
|
+
|
90
|
+
return first_failure.nil?
|
91
|
+
end
|
92
|
+
|
93
|
+
chain(:with_arguments_including) { |**args| @arguments_should_include = args }
|
94
|
+
chain(:exactly) { |times| @matching_events_count = times }
|
95
|
+
|
96
|
+
# noop for syntatic sugar
|
97
|
+
chain(:times) {}
|
98
|
+
chain(:time) {}
|
99
|
+
|
100
|
+
def matching_events
|
101
|
+
@matching_events ||= begin
|
102
|
+
buffer_before_emit = stenotype_event_buffer.dup
|
103
|
+
@emitting_event_block.call
|
104
|
+
buffer_after_emit = stenotype_event_buffer.dup
|
105
|
+
|
106
|
+
diff = buffer_after_emit - buffer_before_emit
|
107
|
+
diff.select { |event| event["name"] == expected_event_name.to_s }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def partial_matchers
|
112
|
+
@partial_matchers ||= []
|
113
|
+
end
|
114
|
+
|
115
|
+
def first_failure
|
116
|
+
@first_failure ||= partial_matchers.detect { |matcher| !matcher.matches? }
|
117
|
+
end
|
118
|
+
|
119
|
+
failure_message do
|
120
|
+
return super() unless first_failure
|
121
|
+
|
122
|
+
first_failure.failure_message
|
123
|
+
end
|
124
|
+
|
125
|
+
private
|
126
|
+
|
127
|
+
def should_validate_events_count?
|
128
|
+
@matching_events_count.present?
|
129
|
+
end
|
130
|
+
|
131
|
+
def should_validate_attributes?
|
132
|
+
@arguments_should_include.present?
|
133
|
+
end
|
134
|
+
|
135
|
+
def stenotype_event_buffer
|
136
|
+
stenotype_event_target.buffer
|
137
|
+
end
|
138
|
+
|
139
|
+
def stenotype_event_target
|
140
|
+
Stenotype.config.targets.first
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
data/lib/stenotype/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stenotype
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.16
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Roman Kapitonov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -268,6 +268,7 @@ files:
|
|
268
268
|
- lib/stenotype/adapters/base.rb
|
269
269
|
- lib/stenotype/adapters/google_cloud.rb
|
270
270
|
- lib/stenotype/adapters/stdout_adapter.rb
|
271
|
+
- lib/stenotype/adapters/test_adapter.rb
|
271
272
|
- lib/stenotype/at_exit.rb
|
272
273
|
- lib/stenotype/configuration.rb
|
273
274
|
- lib/stenotype/context_handlers.rb
|
@@ -283,6 +284,7 @@ files:
|
|
283
284
|
- lib/stenotype/frameworks/rails/action_controller.rb
|
284
285
|
- lib/stenotype/frameworks/rails/active_job.rb
|
285
286
|
- lib/stenotype/railtie.rb
|
287
|
+
- lib/stenotype/test/matchers.rb
|
286
288
|
- lib/stenotype/version.rb
|
287
289
|
- stenotype.gemspec
|
288
290
|
homepage: https://github.com/Freshly/stenotype
|