wsdirector-core 1.0.3 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d062f547a78c242ffc0b863fc7cd0e9405fc8b4621791ca2bb30f077a6778885
4
- data.tar.gz: c75f03818f180eb0ee202402272189ec23a2d53ad2dd28cc9657971b9abde523
3
+ metadata.gz: e8f7c80b878147f8ceba30cff3c94398e7cf8196794d3b4b857ade3702b8a97f
4
+ data.tar.gz: dc767a46dc089ee5cbe7ff90227ddaa2bb23eee835264a436084dd5cf910e77a
5
5
  SHA512:
6
- metadata.gz: a276cdde656fd94d4e019aa398d1bbce8509e57561bc318e9af681871d3647137f367db714c70eaaeea1b1722c81f19881c6fccb57db123885b4b6c04618ebe7
7
- data.tar.gz: d735cf99e4c64f826ce23cf82bd66fbb2469066c3c660d05e30ed4c31610cff3498ea5d58b98558ce60ef007c34a1717326677f2457ac132a8bb43a7af401bc1
6
+ metadata.gz: c2a1d4aa0e1134344f2e4d94fb132153d90f071e48a541bef57e4ab26bf9d49227a9b646a6e3a226ff86d84995e54297933c9aa755db6374c5a8b107d741d4b8
7
+ data.tar.gz: cd9e6f0d9f2804fca5c3fff3dbccbcd6cc7cc3f1f4eafb9eba7846bf4c8b81cc96246ed1c0fc9be4721267406a97e6bb3e3173d6f7b0b8995f88a30b21dcb4ee
data/CHANGELOG.md CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.1.0 (2024-10-04)
6
+
7
+ - Support `stream_id`, `offset`, and `epoch` fields in Action Cable `receive`. ([@palkan][])
8
+
9
+ - Add `print` option to `receive` action to print the received message. ([@palkan][])
10
+
5
11
  ## 1.0.3 (2023-10-03)
6
12
 
7
13
  - Add `timeout` option to receive to limit the amount of time we wait for the expected message. ([@palkan][])
@@ -94,7 +94,7 @@ module WSDirector
94
94
  "an object including #{obj.inspect}"
95
95
  end
96
96
 
97
- def truncate(*__rest__, &__block__) ; obj.truncate(*__rest__, &__block__); end
97
+ def truncate(*__rest__, &__block__) ; obj.truncate(*__rest__, &__block__); end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :truncate)
98
98
  end
99
99
 
100
100
  # Base protocol describes basic actions
@@ -118,7 +118,7 @@ module WSDirector
118
118
  @client = build_client(*__rest__, &__block__)
119
119
 
120
120
  log(:done) { "Connected" }
121
- end
121
+ end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :init_client)
122
122
 
123
123
  def handle_step(step)
124
124
  type = step.delete("type")
@@ -160,7 +160,7 @@ module WSDirector
160
160
  ordered = step["ordered"]
161
161
  timeout = step.fetch("timeout", 5).to_f
162
162
 
163
- log { "Receive a message in #{timeout}s: #{expected.truncate(100)}" }
163
+ log { "Receive a message in #{timeout}s: #{expected.inspect.truncate(100)}" }
164
164
 
165
165
  start = Time.now.to_f
166
166
  received = nil
@@ -181,12 +181,16 @@ module WSDirector
181
181
  end
182
182
  end
183
183
 
184
+ if step["print"]
185
+ debug({"message" => received})
186
+ end
187
+
184
188
  log(:done) { "Received a message: #{received&.truncate(100)}" }
185
189
  rescue ThreadError, ReceiveTimeoutError
186
190
  if received
187
191
  raise UnmatchedExpectationError, prepare_receive_error(expected, received)
188
192
  else
189
- raise NoMessageError, "Expected to receive #{expected} but nothing has been received"
193
+ raise NoMessageError, "Expected to receive #{expected.inspect} but nothing has been received"
190
194
  end
191
195
  end
192
196
 
@@ -253,7 +257,7 @@ module WSDirector
253
257
 
254
258
  def build_client(*__rest__, &__block__)
255
259
  Client.new(*__rest__, &__block__)
256
- end
260
+ end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :build_client)
257
261
 
258
262
  def prepare_receive_error(expected, received)
259
263
  <<~MSG
@@ -14,14 +14,14 @@ module WSDirector
14
14
  @refs_counter = 3
15
15
  @join_refs_counter = 3
16
16
  @topics_to_join_ref = {}
17
- end
17
+ end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :initialize)
18
18
 
19
19
  def init_client(**options)
20
20
  options[:query] ||= {}
21
21
  # Make sure we use the v2 of the protocol
22
22
  options[:query][:vsn] = "2.0.0"
23
23
 
24
- super(**options)
24
+ super
25
25
  end
26
26
 
27
27
  def join(step)
@@ -5,7 +5,7 @@ module WSDirector
5
5
  # Extend Object through refinements
6
6
  module Formatting
7
7
  refine ::Object do
8
- def truncate(*) ; itself; end
8
+ def truncate(*__rest__) ; itself; end
9
9
  end
10
10
 
11
11
  refine ::String do
@@ -94,7 +94,7 @@ module WSDirector
94
94
  "an object including #{obj.inspect}"
95
95
  end
96
96
 
97
- def truncate(...) ; obj.truncate(...); end
97
+ def truncate(...) ; obj.truncate(...); end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :truncate)
98
98
  end
99
99
 
100
100
  # Base protocol describes basic actions
@@ -118,7 +118,7 @@ module WSDirector
118
118
  @client = build_client(...)
119
119
 
120
120
  log(:done) { "Connected" }
121
- end
121
+ end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :init_client)
122
122
 
123
123
  def handle_step(step)
124
124
  type = step.delete("type")
@@ -160,7 +160,7 @@ module WSDirector
160
160
  ordered = step["ordered"]
161
161
  timeout = step.fetch("timeout", 5).to_f
162
162
 
163
- log { "Receive a message in #{timeout}s: #{expected.truncate(100)}" }
163
+ log { "Receive a message in #{timeout}s: #{expected.inspect.truncate(100)}" }
164
164
 
165
165
  start = Time.now.to_f
166
166
  received = nil
@@ -181,12 +181,16 @@ module WSDirector
181
181
  end
182
182
  end
183
183
 
184
+ if step["print"]
185
+ debug({"message" => received})
186
+ end
187
+
184
188
  log(:done) { "Received a message: #{received&.truncate(100)}" }
185
189
  rescue ThreadError, ReceiveTimeoutError
186
190
  if received
187
191
  raise UnmatchedExpectationError, prepare_receive_error(expected, received)
188
192
  else
189
- raise NoMessageError, "Expected to receive #{expected} but nothing has been received"
193
+ raise NoMessageError, "Expected to receive #{expected.inspect} but nothing has been received"
190
194
  end
191
195
  end
192
196
 
@@ -253,7 +257,7 @@ module WSDirector
253
257
 
254
258
  def build_client(...)
255
259
  Client.new(...)
256
- end
260
+ end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :build_client)
257
261
 
258
262
  def prepare_receive_error(expected, received)
259
263
  <<~MSG
@@ -11,7 +11,7 @@ module WSDirector
11
11
  options[:ignore] ||= [PING_IGNORE]
12
12
  options[:subprotocol] ||= "actioncable-v1-json"
13
13
 
14
- super(**options)
14
+ super
15
15
 
16
16
  receive("data>" => {"type" => "welcome"})
17
17
  log(:done) { "Welcomed" }
@@ -64,7 +64,11 @@ module WSDirector
64
64
  key = step.key?("data") ? "data" : "data>"
65
65
 
66
66
  message = step.fetch(key, {})
67
- super(key => {"identifier" => identifier, "message" => message})
67
+
68
+ # Move all protocol-level fields to data
69
+ step[key] = {"identifier" => identifier, "message" => message}.merge(step.slice("offset", "stream_id", "epoch"))
70
+
71
+ super
68
72
  end
69
73
 
70
74
  def receive_all(step)
@@ -78,7 +82,7 @@ module WSDirector
78
82
 
79
83
  key = msg.key?("data") ? "data" : "data>"
80
84
 
81
- msg[key] = {"identifier" => identifier, "message" => msg[key]}
85
+ msg[key] = {"identifier" => identifier, "message" => msg[key]}.merge(step.slice("offset", "stream_id", "epoch"))
82
86
  end
83
87
 
84
88
  super
@@ -88,7 +92,7 @@ module WSDirector
88
92
 
89
93
  def extract_identifier(step)
90
94
  channel = step.delete("channel")
91
- step.fetch("params", {}).merge(channel: channel).to_json
95
+ (step.delete("params") || {}).merge(channel: channel).to_json
92
96
  end
93
97
  end
94
98
  end
@@ -14,14 +14,14 @@ module WSDirector
14
14
  @refs_counter = 3
15
15
  @join_refs_counter = 3
16
16
  @topics_to_join_ref = {}
17
- end
17
+ end; respond_to?(:ruby2_keywords, true) && (ruby2_keywords :initialize)
18
18
 
19
19
  def init_client(**options)
20
20
  options[:query] ||= {}
21
21
  # Make sure we use the v2 of the protocol
22
22
  options[:query][:vsn] = "2.0.0"
23
23
 
24
- super(**options)
24
+ super
25
25
  end
26
26
 
27
27
  def join(step)
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module WSDirector
4
+ module Ext
5
+ # Extend Object through refinements
6
+ module Formatting
7
+ refine ::Object do
8
+ def truncate(*__rest__) = itself
9
+ end
10
+
11
+ refine ::String do
12
+ def truncate(limit)
13
+ return self if size <= limit
14
+
15
+ "#{self[0..(limit - 3)]}..."
16
+ end
17
+ end
18
+
19
+ refine ::Hash do
20
+ def truncate(limit)
21
+ str = to_json
22
+
23
+ str.truncate(limit)
24
+ end
25
+ end
26
+
27
+ refine ::Float do
28
+ def duration
29
+ if self > 1
30
+ "#{truncate(2)}s"
31
+ else
32
+ "#{(self * 1000).to_i}ms"
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -11,7 +11,7 @@ module WSDirector
11
11
  options[:ignore] ||= [PING_IGNORE]
12
12
  options[:subprotocol] ||= "actioncable-v1-json"
13
13
 
14
- super(**options)
14
+ super
15
15
 
16
16
  receive("data>" => {"type" => "welcome"})
17
17
  log(:done) { "Welcomed" }
@@ -64,7 +64,11 @@ module WSDirector
64
64
  key = step.key?("data") ? "data" : "data>"
65
65
 
66
66
  message = step.fetch(key, {})
67
- super(key => {"identifier" => identifier, "message" => message})
67
+
68
+ # Move all protocol-level fields to data
69
+ step[key] = {"identifier" => identifier, "message" => message}.merge(step.slice("offset", "stream_id", "epoch"))
70
+
71
+ super
68
72
  end
69
73
 
70
74
  def receive_all(step)
@@ -78,7 +82,7 @@ module WSDirector
78
82
 
79
83
  key = msg.key?("data") ? "data" : "data>"
80
84
 
81
- msg[key] = {"identifier" => identifier, "message" => msg[key]}
85
+ msg[key] = {"identifier" => identifier, "message" => msg[key]}.merge(step.slice("offset", "stream_id", "epoch"))
82
86
  end
83
87
 
84
88
  super
@@ -88,7 +92,7 @@ module WSDirector
88
92
 
89
93
  def extract_identifier(step)
90
94
  channel = step.delete("channel")
91
- step.fetch("params", {}).merge(channel: channel).to_json
95
+ (step.delete("params") || {}).merge(channel: channel).to_json
92
96
  end
93
97
  end
94
98
  end
@@ -160,7 +160,7 @@ module WSDirector
160
160
  ordered = step["ordered"]
161
161
  timeout = step.fetch("timeout", 5).to_f
162
162
 
163
- log { "Receive a message in #{timeout}s: #{expected.truncate(100)}" }
163
+ log { "Receive a message in #{timeout}s: #{expected.inspect.truncate(100)}" }
164
164
 
165
165
  start = Time.now.to_f
166
166
  received = nil
@@ -181,12 +181,16 @@ module WSDirector
181
181
  end
182
182
  end
183
183
 
184
+ if step["print"]
185
+ debug({"message" => received})
186
+ end
187
+
184
188
  log(:done) { "Received a message: #{received&.truncate(100)}" }
185
189
  rescue ThreadError, ReceiveTimeoutError
186
190
  if received
187
191
  raise UnmatchedExpectationError, prepare_receive_error(expected, received)
188
192
  else
189
- raise NoMessageError, "Expected to receive #{expected} but nothing has been received"
193
+ raise NoMessageError, "Expected to receive #{expected.inspect} but nothing has been received"
190
194
  end
191
195
  end
192
196
 
@@ -21,7 +21,7 @@ module WSDirector
21
21
  # Make sure we use the v2 of the protocol
22
22
  options[:query][:vsn] = "2.0.0"
23
23
 
24
- super(**options)
24
+ super
25
25
  end
26
26
 
27
27
  def join(step)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WSDirector
4
- VERSION = "1.0.3"
4
+ VERSION = "1.1.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wsdirector-core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.3
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vladimir Dementyev
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2023-10-03 00:00:00.000000000 Z
13
+ date: 2024-10-04 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: websocket-client-simple
@@ -207,6 +207,7 @@ files:
207
207
  - lib/.rbnext/3.1/wsdirector/runner.rb
208
208
  - lib/.rbnext/3.1/wsdirector/scenario_reader.rb
209
209
  - lib/.rbnext/3.1/wsdirector/task.rb
210
+ - lib/.rbnext/3.2/wsdirector/ext/formatting.rb
210
211
  - lib/wsdirector-cli.rb
211
212
  - lib/wsdirector.rb
212
213
  - lib/wsdirector/cli.rb
@@ -245,7 +246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
245
246
  - !ruby/object:Gem::Version
246
247
  version: '0'
247
248
  requirements: []
248
- rubygems_version: 3.4.8
249
+ rubygems_version: 3.5.18
249
250
  signing_key:
250
251
  specification_version: 4
251
252
  summary: Scenario-based WebSocket black-box testing