cucumber-messages 0.0.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.
- checksums.yaml +7 -0
- data/README.md +3 -0
- data/VERSION +1 -0
- data/lib/cucumber/messages/id_generator.rb +24 -0
- data/lib/cucumber/messages/message/deserialization.rb +37 -0
- data/lib/cucumber/messages/message/serialization.rb +70 -0
- data/lib/cucumber/messages/message/utils.rb +45 -0
- data/lib/cucumber/messages/message.rb +11 -0
- data/lib/cucumber/messages/ndjson_to_message_enumerator.rb +21 -0
- data/lib/cucumber/messages/time_conversion.rb +33 -0
- data/lib/cucumber/messages.deserializers.rb +1208 -0
- data/lib/cucumber/messages.dtos.rb +1782 -0
- data/lib/cucumber/messages.rb +10 -0
- metadata +136 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fae43985a14dd510cdad40de4e15f44d41a25d2cc5872eb8ce95b486995ddf9e
|
4
|
+
data.tar.gz: 3bd925db18e60f98b718ebd017e328dcc2938c8022b526bf4d3e057ae1ecb39a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 120be88738c8374cd69723b9e4b2a33664f8f802cf72af92a46b6dfef12c9520b85c0e853861102bad57948f5f019d7cff50e5565833e91b2a136e7f3ae7a30d
|
7
|
+
data.tar.gz: ba5ccba6194a142270aadb05e5db76728a1dc57f1fe1617fd25d593f069761b4da0c95b06030da83051b7e932d2bd2e1d3050a144c44dbae5fef5ada0a4fae4d
|
data/README.md
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module Messages
|
5
|
+
module IdGenerator
|
6
|
+
class Incrementing
|
7
|
+
def initialize
|
8
|
+
@index = -1
|
9
|
+
end
|
10
|
+
|
11
|
+
def new_id
|
12
|
+
@index += 1
|
13
|
+
@index.to_s
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class UUID
|
18
|
+
def new_id
|
19
|
+
SecureRandom.uuid
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'cucumber/messages/message/utils'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Cucumber
|
5
|
+
module Messages
|
6
|
+
class Message
|
7
|
+
include Cucumber::Messages::Message::Utils
|
8
|
+
|
9
|
+
module Deserialization
|
10
|
+
def self.included(other)
|
11
|
+
other.extend(ClassMethods)
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
##
|
16
|
+
# Returns a new Message - or messages into an array - deserialized from the given json document.
|
17
|
+
# CamelCased keys are properly converted to snake_cased attributes in the process
|
18
|
+
#
|
19
|
+
# Cucumber::Messages::Duration.from_json('{"seconds":1,"nanos":42}') # => #<Cucumber::Messages::Duration:0x00007efda134c290 @seconds=1, @nanos=42>
|
20
|
+
# Cucumber::Messages::PickleTag.from_json('{"name":"foo","astNodeId":"abc-def"}') # => #<Cucumber::Messages::PickleTag:0x00007efda138cdb8 @name="foo", @ast_node_id="abc-def">
|
21
|
+
#
|
22
|
+
# It is recursive so embedded messages are also processed.
|
23
|
+
#
|
24
|
+
# json_string = { location: { line: 2 }, text: "comment" }.to_json
|
25
|
+
# Cucumber::Messages::Comment.from_json(json_string) # => #<Cucumber::Messages::Comment:0x00007efda6abf888 @location=#<Cucumber::Messages::Location:0x00007efda6abf978 @line=2, @column=nil>, @text="comment">
|
26
|
+
#
|
27
|
+
# json_string = { uri: 'file:///...', comments: [{text: 'text comment'}, {text: 'another comment'}]}.to_json
|
28
|
+
# Cucumber::Messages::GherkinDocument.from_json(json_string) # => #<Cucumber::Messages::GherkinDocument:0x00007efda11e6a90 ... @comments=[#<Cucumber::Messages::Comment:0x00007efda11e6e50 ..., #<Cucumber::Messages::Comment:0x00007efda11e6b58 ...>]>
|
29
|
+
##
|
30
|
+
def from_json(json_string)
|
31
|
+
from_h(JSON.parse(json_string, { symbolize_names: true }))
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'cucumber/messages/message/utils'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module Cucumber
|
5
|
+
module Messages
|
6
|
+
class Message
|
7
|
+
include Cucumber::Messages::Message::Utils
|
8
|
+
|
9
|
+
module Serialization
|
10
|
+
##
|
11
|
+
# Returns a new Hash formed from the message attributes
|
12
|
+
# If +camelize:+ keyword parameter is set to true, then keys will be camelized
|
13
|
+
# If +reject_nil_values:+ keyword parameter is set to true, resulting hash won't include nil values
|
14
|
+
#
|
15
|
+
# Cucumber::Messages::Duration.new(seconds: 1, nanos: 42).to_h # => { seconds: 1, nanos: 42 }
|
16
|
+
# Cucumber::Messages::PickleTag.new(name: 'foo', ast_node_id: 'abc-def').to_h(camelize: true) # => { name: 'foo', astNodeId: 'abc-def' }
|
17
|
+
# Cucumber::Messages::PickleTag.new(name: 'foo', ast_node_id: nil).to_h(reject_nil_values: true) # => { name: 'foo' }
|
18
|
+
#
|
19
|
+
# It is recursive so embedded messages are also processed
|
20
|
+
#
|
21
|
+
# location = Cucumber::Messages::Location.new(line: 2)
|
22
|
+
# Cucumber::Messages::Comment.new(location: location, text: 'comment').to_h # => { location: { line: 2, :column: nil }, text: "comment" }
|
23
|
+
##
|
24
|
+
def to_h(camelize: false, reject_nil_values: false)
|
25
|
+
resulting_hash = self.instance_variables.map do |variable_name|
|
26
|
+
h_key = variable_name[1..-1]
|
27
|
+
h_key = Cucumber::Messages::Message.camelize(h_key) if camelize
|
28
|
+
|
29
|
+
h_value = prepare_value(
|
30
|
+
self.instance_variable_get(variable_name),
|
31
|
+
camelize: camelize,
|
32
|
+
reject_nil_values: reject_nil_values
|
33
|
+
)
|
34
|
+
|
35
|
+
[ h_key.to_sym, h_value ]
|
36
|
+
end.to_h
|
37
|
+
|
38
|
+
resulting_hash.reject! { |_, value| value.nil? } if reject_nil_values
|
39
|
+
resulting_hash
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Generates a JSON document from the message.
|
44
|
+
# Keys are camelized during the process. Null values are not part of the json document.
|
45
|
+
#
|
46
|
+
# Cucumber::Messages::Duration.new(seconds: 1, nanos: 42).to_json # => '{"seconds":1,"nanos":42}'
|
47
|
+
# Cucumber::Messages::PickleTag.new(name: 'foo', ast_node_id: 'abc-def').to_json # => '{"name":"foo","astNodeId":"abc-def"}'
|
48
|
+
# Cucumber::Messages::PickleTag.new(name: 'foo', ast_node_id: nil).to_json # => '{"name":"foo"}'
|
49
|
+
#
|
50
|
+
# As #to_h, the method is recursive
|
51
|
+
#
|
52
|
+
# location = Cucumber::Messages::Location.new(line: 2)
|
53
|
+
# Cucumber::Messages::Comment.new(location: location, text: 'comment').to_json # => '{"location":{"line":2,"column":null},"text":"comment"}'
|
54
|
+
##
|
55
|
+
def to_json
|
56
|
+
to_h(camelize: true, reject_nil_values: true).to_json
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def prepare_value(value, camelize:, reject_nil_values:)
|
62
|
+
return value.to_h(camelize: camelize, reject_nil_values: reject_nil_values) if value.is_a?(Cucumber::Messages::Message)
|
63
|
+
return value.map { |v| prepare_value(v, camelize: camelize, reject_nil_values: reject_nil_values) } if value.is_a?(Array)
|
64
|
+
|
65
|
+
value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module Messages
|
3
|
+
class Message
|
4
|
+
module Utils
|
5
|
+
def self.included(other)
|
6
|
+
other.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
##
|
11
|
+
# Makes an underscored, lowercase form from the expression in the string.
|
12
|
+
#
|
13
|
+
# underscore('GherkinDocument') # => "gherkin_document"
|
14
|
+
#
|
15
|
+
# This is a simplified version of the Ruby on Rails implementation
|
16
|
+
# https://github.com/rails/rails/blob/v6.1.3.2/activesupport/lib/active_support/inflector/methods.rb#L92
|
17
|
+
##
|
18
|
+
def underscore(term)
|
19
|
+
return term unless /[A-Z-]/.match?(term)
|
20
|
+
|
21
|
+
word = term.gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
|
22
|
+
word.gsub!(/([a-z\d])([A-Z])/, '\1_\2')
|
23
|
+
word.tr!("-", "_")
|
24
|
+
word.downcase!
|
25
|
+
word
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# Converts strings to UpperCamelCase.
|
30
|
+
#
|
31
|
+
# camelize('gherkin_document') # => "GherkinDocument"
|
32
|
+
#
|
33
|
+
# This is a simplified version of the Ruby on Rails implementation
|
34
|
+
# https://github.com/rails/rails/blob/v6.1.3.2/activesupport/lib/active_support/inflector/methods.rb#L69
|
35
|
+
##
|
36
|
+
def camelize(term)
|
37
|
+
camelized = term.to_s
|
38
|
+
camelized.gsub!(/(?:_|(\/))([a-z\d]*)/i) { "#{$1}#{$2.capitalize}" }
|
39
|
+
camelized
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'cucumber/messages/message/deserialization'
|
2
|
+
require 'cucumber/messages/message/serialization'
|
3
|
+
|
4
|
+
module Cucumber
|
5
|
+
module Messages
|
6
|
+
class Message
|
7
|
+
include Cucumber::Messages::Message::Deserialization
|
8
|
+
include Cucumber::Messages::Message::Serialization
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'cucumber/messages.deserializers'
|
2
|
+
|
3
|
+
module Cucumber
|
4
|
+
module Messages
|
5
|
+
class NdjsonToMessageEnumerator < Enumerator
|
6
|
+
def initialize(io)
|
7
|
+
super() do |yielder|
|
8
|
+
io.each_line do |line|
|
9
|
+
next if line.strip.empty?
|
10
|
+
begin
|
11
|
+
m = Envelope.from_json(line)
|
12
|
+
rescue => e
|
13
|
+
raise "Not JSON: #{line.strip}"
|
14
|
+
end
|
15
|
+
yielder.yield(m)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Cucumber
|
2
|
+
module Messages
|
3
|
+
module TimeConversion
|
4
|
+
NANOSECONDS_PER_SECOND = 1000000000
|
5
|
+
|
6
|
+
def time_to_timestamp(time)
|
7
|
+
{
|
8
|
+
'seconds' => time.to_i,
|
9
|
+
'nanos' => time.nsec
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
def timestamp_to_time(timestamp)
|
14
|
+
Time.at(timestamp['seconds'] + timestamp['nanos'].to_f / NANOSECONDS_PER_SECOND)
|
15
|
+
end
|
16
|
+
|
17
|
+
def seconds_to_duration(seconds_float)
|
18
|
+
seconds, second_modulus = seconds_float.divmod(1)
|
19
|
+
nanos = second_modulus * NANOSECONDS_PER_SECOND
|
20
|
+
{
|
21
|
+
'seconds' => seconds,
|
22
|
+
'nanos' => nanos.to_i
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def duration_to_seconds(duration)
|
27
|
+
seconds_part = duration['seconds']
|
28
|
+
nanos_part = duration['nanos'].to_f / NANOSECONDS_PER_SECOND
|
29
|
+
seconds_part + nanos_part
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|