evt-messaging-fixtures 0.0.0.0 → 1.1.1.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 +4 -4
- data/lib/messaging/fixtures.rb +9 -2
- data/lib/messaging/fixtures/controls.rb +10 -0
- data/lib/messaging/fixtures/controls/entity.rb +76 -0
- data/lib/messaging/fixtures/controls/event.rb +89 -0
- data/lib/messaging/fixtures/controls/handler.rb +81 -0
- data/lib/messaging/fixtures/controls/id.rb +7 -0
- data/lib/messaging/fixtures/controls/message.rb +79 -0
- data/lib/messaging/fixtures/controls/metadata.rb +69 -0
- data/lib/messaging/fixtures/controls/sequence.rb +11 -0
- data/lib/messaging/fixtures/controls/store.rb +28 -0
- data/lib/messaging/fixtures/controls/time.rb +7 -0
- data/lib/messaging/fixtures/defaults.rb +15 -0
- data/lib/messaging/fixtures/follows.rb +57 -0
- data/lib/messaging/fixtures/handler.rb +121 -0
- data/lib/messaging/fixtures/message.rb +124 -0
- data/lib/messaging/fixtures/metadata.rb +92 -0
- data/lib/messaging/fixtures/writer.rb +101 -0
- metadata +23 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d6ce7dc5f801ca051e1bcf74b12705a0bcbd05ae5375895371705fb9820453c
|
4
|
+
data.tar.gz: ba8c30bf0a8778c1347ba1db178e43ad0d61af603ea6b0d5c3ed4d489df1e5c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 727bec07b3c9e53b7868439477828257302a726bbb87a4f189301aab8d407f1424dea403403a4e0fd2083bcb8717a8b2ba5233c134f50b6a859c2589cad45702
|
7
|
+
data.tar.gz: 396b221225b28855d488095201fda8372591d67cfeb93698844930074c716d1a42ca9ad836a1714f0a67067c6782ad85a0385ca122cf86eac3a14cc9c80d28e0
|
data/lib/messaging/fixtures.rb
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
-
require '
|
1
|
+
require 'schema/fixtures'
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'entity_store'
|
4
|
+
|
5
|
+
require 'messaging/fixtures/defaults'
|
6
|
+
require 'messaging/fixtures/follows'
|
7
|
+
require 'messaging/fixtures/metadata'
|
8
|
+
require 'messaging/fixtures/message'
|
9
|
+
require 'messaging/fixtures/writer'
|
10
|
+
require 'messaging/fixtures/handler'
|
@@ -1 +1,11 @@
|
|
1
1
|
require 'messaging/controls'
|
2
|
+
|
3
|
+
require 'messaging/fixtures/controls/id'
|
4
|
+
require 'messaging/fixtures/controls/time'
|
5
|
+
require 'messaging/fixtures/controls/metadata'
|
6
|
+
require 'messaging/fixtures/controls/message'
|
7
|
+
require 'messaging/fixtures/controls/event'
|
8
|
+
require 'messaging/fixtures/controls/sequence'
|
9
|
+
require 'messaging/fixtures/controls/entity'
|
10
|
+
require 'messaging/fixtures/controls/store'
|
11
|
+
require 'messaging/fixtures/controls/handler'
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module Messaging
|
2
|
+
module Fixtures
|
3
|
+
module Controls
|
4
|
+
module Entity
|
5
|
+
class Example
|
6
|
+
include Schema::DataStructure
|
7
|
+
|
8
|
+
attribute :id, String
|
9
|
+
attribute :alternate_condition, Boolean, default: false
|
10
|
+
attribute :sequence, Integer
|
11
|
+
|
12
|
+
alias :alternate_condition? :alternate_condition
|
13
|
+
|
14
|
+
def processed?(message_sequence)
|
15
|
+
return false if sequence.nil?
|
16
|
+
|
17
|
+
message_sequence <= sequence
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.example(sequence: nil)
|
22
|
+
sequence ||= self.sequence
|
23
|
+
|
24
|
+
some_entity = Example.build
|
25
|
+
|
26
|
+
some_entity.id = id
|
27
|
+
some_entity.sequence = sequence
|
28
|
+
|
29
|
+
some_entity
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.id
|
33
|
+
ID.example(increment: id_increment)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.id_increment
|
37
|
+
11
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.amount
|
41
|
+
1
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.sequence
|
45
|
+
Event.sequence
|
46
|
+
end
|
47
|
+
|
48
|
+
module New
|
49
|
+
def self.example
|
50
|
+
Entity::Example.new
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
module Identified
|
55
|
+
def self.example
|
56
|
+
example = New.example
|
57
|
+
|
58
|
+
example.id = Entity.id
|
59
|
+
|
60
|
+
example
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
module Sequenced
|
65
|
+
def self.example
|
66
|
+
example = Identified.example
|
67
|
+
|
68
|
+
example.sequence = Entity.sequence
|
69
|
+
|
70
|
+
example
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module Messaging
|
2
|
+
module Fixtures
|
3
|
+
module Controls
|
4
|
+
module Event
|
5
|
+
def self.example
|
6
|
+
output = Output.new
|
7
|
+
|
8
|
+
output.example_id = example_id
|
9
|
+
output.amount = amount
|
10
|
+
output.time = time
|
11
|
+
output.processed_time = processed_time
|
12
|
+
output.sequence = sequence
|
13
|
+
|
14
|
+
output.metadata = metadata
|
15
|
+
|
16
|
+
output
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.example_id
|
20
|
+
Entity.id
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.amount
|
24
|
+
1
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.time
|
28
|
+
Time::Effective.example
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.processed_time
|
32
|
+
Time::Processed.example
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.sequence
|
36
|
+
Message::Metadata.global_position + 1
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.metadata
|
40
|
+
Metadata.example
|
41
|
+
end
|
42
|
+
|
43
|
+
module Metadata
|
44
|
+
def self.example
|
45
|
+
metadata = Messaging::Message::Metadata.new
|
46
|
+
|
47
|
+
metadata.causation_message_stream_name = causation_message_stream_name
|
48
|
+
metadata.causation_message_position = causation_message_position
|
49
|
+
metadata.causation_message_global_position = causation_message_global_position
|
50
|
+
|
51
|
+
metadata
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.causation_message_stream_name
|
55
|
+
Message::Metadata.stream_name
|
56
|
+
end
|
57
|
+
|
58
|
+
def self.causation_message_position
|
59
|
+
Message::Metadata.position
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.causation_message_global_position
|
63
|
+
Message::Metadata.global_position
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class Output
|
68
|
+
include Messaging::Message
|
69
|
+
|
70
|
+
attribute :example_id, String
|
71
|
+
attribute :amount, Integer
|
72
|
+
attribute :time, String
|
73
|
+
attribute :processed_time, String
|
74
|
+
attribute :sequence, Integer
|
75
|
+
end
|
76
|
+
|
77
|
+
class AlternateOutput
|
78
|
+
include Messaging::Message
|
79
|
+
|
80
|
+
attribute :example_id, String
|
81
|
+
attribute :amount, Integer
|
82
|
+
attribute :time, String
|
83
|
+
attribute :processed_time, String
|
84
|
+
attribute :sequence, Integer
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
module Messaging
|
2
|
+
module Fixtures
|
3
|
+
module Controls
|
4
|
+
module Handler
|
5
|
+
def self.example
|
6
|
+
Example.new
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.noop
|
10
|
+
Noop.new
|
11
|
+
end
|
12
|
+
|
13
|
+
class Example
|
14
|
+
include Messaging::Handle
|
15
|
+
include Log::Dependency
|
16
|
+
include Messaging::StreamName
|
17
|
+
|
18
|
+
dependency :store, Controls::Store::Example
|
19
|
+
dependency :write, Messaging::Write
|
20
|
+
dependency :clock, Clock::UTC
|
21
|
+
dependency :identifier, Identifier::UUID::Random
|
22
|
+
|
23
|
+
category :example
|
24
|
+
|
25
|
+
handle Controls::Message::Input do |input|
|
26
|
+
example_id = input.example_id
|
27
|
+
|
28
|
+
example, version = store.fetch(example_id, include: :version)
|
29
|
+
|
30
|
+
sequence = input.metadata.global_position
|
31
|
+
|
32
|
+
if example.processed?(sequence)
|
33
|
+
logger.info(tag: :ignored) { "Input message ignored (Message: #{input.message_type}, Example ID: #{example_id}, Message Sequence: #{sequence}, Entity Sequence: #{example.sequence})" }
|
34
|
+
return
|
35
|
+
end
|
36
|
+
|
37
|
+
time = clock.iso8601
|
38
|
+
stream_name = stream_name(example_id)
|
39
|
+
|
40
|
+
attributes = [
|
41
|
+
:example_id,
|
42
|
+
{ :quantity => :amount },
|
43
|
+
:time,
|
44
|
+
]
|
45
|
+
|
46
|
+
if example.alternate_condition?
|
47
|
+
alternate_output = Controls::Event::AlternateOutput.follow(input, copy: attributes)
|
48
|
+
|
49
|
+
alternate_output.processed_time = time
|
50
|
+
alternate_output.sequence = sequence
|
51
|
+
|
52
|
+
alternate_output.metadata.correlation_stream_name = 'someCorrelationStream'
|
53
|
+
alternate_output.metadata.reply_stream_name = 'someReplyStream'
|
54
|
+
|
55
|
+
write.(alternate_output, stream_name, expected_version: version)
|
56
|
+
|
57
|
+
return
|
58
|
+
end
|
59
|
+
|
60
|
+
output = Controls::Event::Output.follow(input, copy: attributes)
|
61
|
+
|
62
|
+
output.processed_time = time
|
63
|
+
output.sequence = sequence
|
64
|
+
|
65
|
+
output.metadata.correlation_stream_name = 'someCorrelationStream'
|
66
|
+
output.metadata.reply_stream_name = 'someReplyStream'
|
67
|
+
|
68
|
+
write.(output, stream_name, expected_version: version)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
class Noop
|
73
|
+
include Messaging::Handle
|
74
|
+
|
75
|
+
def handle(*)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Messaging
|
2
|
+
module Fixtures
|
3
|
+
module Controls
|
4
|
+
module Message
|
5
|
+
class Input
|
6
|
+
include Messaging::Message
|
7
|
+
|
8
|
+
attribute :example_id, String
|
9
|
+
attribute :quantity, Integer
|
10
|
+
attribute :time, String
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.example
|
14
|
+
input = Input.new
|
15
|
+
|
16
|
+
input.example_id = example_id
|
17
|
+
input.quantity = quantity
|
18
|
+
input.time = time
|
19
|
+
|
20
|
+
input.metadata = metadata
|
21
|
+
|
22
|
+
input
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.example_id
|
26
|
+
Entity.id
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.quantity
|
30
|
+
1
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.time
|
34
|
+
Time::Effective.example
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.metadata
|
38
|
+
Metadata.example
|
39
|
+
end
|
40
|
+
|
41
|
+
module SomeMessage
|
42
|
+
def self.example
|
43
|
+
Example.new
|
44
|
+
end
|
45
|
+
|
46
|
+
class Example
|
47
|
+
include Messaging::Message
|
48
|
+
|
49
|
+
attribute :some_attribute, String
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
module Metadata
|
54
|
+
def self.example
|
55
|
+
metadata = Messaging::Message::Metadata.new
|
56
|
+
|
57
|
+
metadata.stream_name = stream_name
|
58
|
+
metadata.position = position
|
59
|
+
metadata.global_position = global_position
|
60
|
+
|
61
|
+
metadata
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.stream_name
|
65
|
+
"example:command-#{Entity.id}"
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.position
|
69
|
+
1
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.global_position
|
73
|
+
111
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module Messaging
|
2
|
+
module Fixtures
|
3
|
+
module Controls
|
4
|
+
module Metadata
|
5
|
+
def self.example
|
6
|
+
metadata = Messaging::Message::Metadata.new
|
7
|
+
|
8
|
+
metadata.stream_name = stream_name
|
9
|
+
metadata.position = position
|
10
|
+
metadata.global_position = global_position
|
11
|
+
|
12
|
+
metadata.causation_message_stream_name = causation_message_stream_name
|
13
|
+
metadata.causation_message_position = causation_message_position
|
14
|
+
metadata.causation_message_global_position = causation_message_global_position
|
15
|
+
|
16
|
+
metadata.correlation_stream_name = correlation_stream_name
|
17
|
+
|
18
|
+
metadata.reply_stream_name = reply_stream_name
|
19
|
+
|
20
|
+
metadata.time = time
|
21
|
+
|
22
|
+
metadata.schema_version = schema_version
|
23
|
+
|
24
|
+
metadata
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.stream_name
|
28
|
+
"example:command-#{Entity.id}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.position
|
32
|
+
1
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.global_position
|
36
|
+
111
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.causation_message_stream_name
|
40
|
+
Message::Metadata.stream_name
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.causation_message_position
|
44
|
+
Message::Metadata.position
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.causation_message_global_position
|
48
|
+
Message::Metadata.global_position
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.correlation_stream_name
|
52
|
+
'someCorrelationStream'
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.reply_stream_name
|
56
|
+
'someReplyStream'
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.time
|
60
|
+
::Time.utc(2000, 1, 1, 0, 0, 0, 11)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.schema_version
|
64
|
+
'1'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Messaging
|
2
|
+
module Fixtures
|
3
|
+
module Controls
|
4
|
+
module Store
|
5
|
+
module Projection
|
6
|
+
class Example
|
7
|
+
include EntityProjection
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
module Reader
|
12
|
+
class Example
|
13
|
+
include MessageStore::Read
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Example
|
18
|
+
include EntityStore
|
19
|
+
|
20
|
+
category :example
|
21
|
+
entity Entity::Example
|
22
|
+
projection Store::Projection::Example
|
23
|
+
reader Store::Reader::Example
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Messaging
|
2
|
+
module Fixtures
|
3
|
+
class Follows
|
4
|
+
include TestBench::Fixture
|
5
|
+
include Initializer
|
6
|
+
|
7
|
+
initializer :metadata, :source_metadata
|
8
|
+
|
9
|
+
def self.build(metadata, source_metadata=nil)
|
10
|
+
new(metadata, source_metadata)
|
11
|
+
end
|
12
|
+
|
13
|
+
def call
|
14
|
+
context do
|
15
|
+
if metadata.nil?
|
16
|
+
test "Metadata not nil" do
|
17
|
+
detail "Metadata: nil"
|
18
|
+
refute(metadata.nil?)
|
19
|
+
end
|
20
|
+
return
|
21
|
+
end
|
22
|
+
|
23
|
+
if source_metadata.nil?
|
24
|
+
test "Source metadata not nil" do
|
25
|
+
detail "Source Metadata: nil"
|
26
|
+
refute(source_metadata.nil?)
|
27
|
+
end
|
28
|
+
return
|
29
|
+
end
|
30
|
+
|
31
|
+
call!
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def call!
|
36
|
+
test "Follows" do
|
37
|
+
detail "Stream Name: #{source_metadata.stream_name.inspect}"
|
38
|
+
detail "Causation Stream Name: #{metadata.causation_message_stream_name.inspect}"
|
39
|
+
|
40
|
+
detail "Position: #{source_metadata.position.inspect}"
|
41
|
+
detail "Causation Position: #{metadata.causation_message_position.inspect}"
|
42
|
+
|
43
|
+
detail "Global Position: #{source_metadata.global_position.inspect}"
|
44
|
+
detail "Causation Global Position: #{metadata.causation_message_global_position.inspect}"
|
45
|
+
|
46
|
+
detail "Source Correlation Stream Name: #{source_metadata.correlation_stream_name.inspect}"
|
47
|
+
detail "Correlation Stream Name: #{metadata.correlation_stream_name.inspect}"
|
48
|
+
|
49
|
+
detail "Source Reply Stream Name: #{source_metadata.reply_stream_name.inspect}"
|
50
|
+
detail "Reply Stream Name: #{metadata.reply_stream_name.inspect}"
|
51
|
+
|
52
|
+
assert(metadata.follows?(source_metadata))
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
module Messaging
|
2
|
+
module Fixtures
|
3
|
+
class Handler
|
4
|
+
Error = Class.new(RuntimeError)
|
5
|
+
|
6
|
+
include TestBench::Fixture
|
7
|
+
include Initializer
|
8
|
+
|
9
|
+
def entity_sequence
|
10
|
+
return nil if entity.nil?
|
11
|
+
entity.sequence
|
12
|
+
end
|
13
|
+
|
14
|
+
initializer :handler, :input_message, :entity, :entity_version, :clock_time, :identifier_uuid, :test_block
|
15
|
+
|
16
|
+
def self.build(handler, input_message, entity=nil, entity_version=nil, clock_time: nil, identifier_uuid: nil, &test_block)
|
17
|
+
instance = new(handler, input_message, entity, entity_version, clock_time, identifier_uuid, test_block)
|
18
|
+
|
19
|
+
set_store_entity(handler, entity, entity_version)
|
20
|
+
set_clock_time(handler, clock_time)
|
21
|
+
set_identifier_uuid(handler, identifier_uuid)
|
22
|
+
|
23
|
+
instance
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.set_store_entity(handler, entity, entity_version)
|
27
|
+
return if entity.nil?
|
28
|
+
|
29
|
+
handler.store.add(entity.id, entity, entity_version)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.set_clock_time(handler, clock_time)
|
33
|
+
if clock_time.nil?
|
34
|
+
if handler.respond_to?(:clock)
|
35
|
+
handler.clock.now = Defaults.clock_time
|
36
|
+
end
|
37
|
+
else
|
38
|
+
handler.clock.now = clock_time
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.set_identifier_uuid(handler, identifier_uuid)
|
43
|
+
if identifier_uuid.nil?
|
44
|
+
if handler.respond_to?(:identifier)
|
45
|
+
handler.identifier.set(Defaults.identifier_uuid)
|
46
|
+
end
|
47
|
+
else
|
48
|
+
handler.identifier.set(identifier_uuid)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def call
|
53
|
+
context "Handler: #{handler.class.name.split('::').last}" do
|
54
|
+
detail "Handler Class: #{handler.class.name}"
|
55
|
+
|
56
|
+
if test_block.nil?
|
57
|
+
raise Error, "Handler fixture must be executed with a block"
|
58
|
+
end
|
59
|
+
|
60
|
+
detail "Entity Class: #{entity.class.name}"
|
61
|
+
detail "Entity Data: #{entity&.attributes.inspect}"
|
62
|
+
|
63
|
+
if not clock_time.nil?
|
64
|
+
detail "Clock Time: #{clock_time.inspect}"
|
65
|
+
end
|
66
|
+
|
67
|
+
if not identifier_uuid.nil?
|
68
|
+
detail "Identifier UUID: #{identifier_uuid}"
|
69
|
+
end
|
70
|
+
|
71
|
+
handler.(input_message)
|
72
|
+
|
73
|
+
test_block.call(self)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def assert_input_message(&test_block)
|
78
|
+
context_name = "Input Message"
|
79
|
+
if not input_message.nil?
|
80
|
+
context_name = "#{context_name}: #{input_message.class.message_type}"
|
81
|
+
end
|
82
|
+
|
83
|
+
fixture(Message, input_message, title_context_name: context_name, &test_block)
|
84
|
+
end
|
85
|
+
|
86
|
+
def assert_written_message(written_message, &test_block)
|
87
|
+
context_name = "Written Message"
|
88
|
+
if not written_message.nil?
|
89
|
+
context_name = "#{context_name}: #{written_message.class.message_type}"
|
90
|
+
end
|
91
|
+
|
92
|
+
fixture(Message, written_message, input_message, title_context_name: context_name, &test_block)
|
93
|
+
end
|
94
|
+
|
95
|
+
def assert_write(message_class, &test_block)
|
96
|
+
fixture = fixture(Writer, handler.write, message_class, &test_block)
|
97
|
+
fixture.message
|
98
|
+
end
|
99
|
+
|
100
|
+
def refute_write(message_class=nil)
|
101
|
+
writer = handler.write
|
102
|
+
|
103
|
+
context_name = "No Write"
|
104
|
+
if not message_class.nil?
|
105
|
+
write_telemetry_data = Writer.get_data(writer, message_class)
|
106
|
+
written = !write_telemetry_data.nil?
|
107
|
+
context_name = "#{context_name}: #{message_class.message_type}"
|
108
|
+
else
|
109
|
+
written = writer.written?
|
110
|
+
end
|
111
|
+
|
112
|
+
context context_name do
|
113
|
+
detail "Message Class: #{message_class.inspect}"
|
114
|
+
test "Not written" do
|
115
|
+
refute(written)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
module Messaging
|
2
|
+
module Fixtures
|
3
|
+
class Message
|
4
|
+
Error = Class.new(RuntimeError)
|
5
|
+
|
6
|
+
include TestBench::Fixture
|
7
|
+
include Initializer
|
8
|
+
|
9
|
+
def message_class
|
10
|
+
message.class
|
11
|
+
end
|
12
|
+
|
13
|
+
def message_type
|
14
|
+
message_class.name.split('::').last
|
15
|
+
end
|
16
|
+
|
17
|
+
def source_message_class
|
18
|
+
source_message.class
|
19
|
+
end
|
20
|
+
|
21
|
+
def source_message_type
|
22
|
+
source_message_class.name.split('::').last
|
23
|
+
end
|
24
|
+
|
25
|
+
def title_context_name
|
26
|
+
@title_context_name ||= "Message"
|
27
|
+
end
|
28
|
+
|
29
|
+
initializer :message, :source_message, na(:title_context_name), :test_block
|
30
|
+
|
31
|
+
def self.build(message, source_message=nil, title_context_name: nil, &test_block)
|
32
|
+
new(message, source_message, title_context_name, test_block)
|
33
|
+
end
|
34
|
+
|
35
|
+
def call
|
36
|
+
context_name = title_context_name
|
37
|
+
|
38
|
+
context context_name do
|
39
|
+
if test_block.nil?
|
40
|
+
raise Error, "Message fixture must be executed with a block"
|
41
|
+
end
|
42
|
+
|
43
|
+
if message.nil?
|
44
|
+
test "Not nil" do
|
45
|
+
detail "Message: nil"
|
46
|
+
detail "Remaining message tests are skipped"
|
47
|
+
refute(message.nil?)
|
48
|
+
end
|
49
|
+
return
|
50
|
+
end
|
51
|
+
|
52
|
+
detail "Message Class: #{message_class.name}"
|
53
|
+
|
54
|
+
if not source_message.nil?
|
55
|
+
detail "Source Message Class: #{source_message_class.name}"
|
56
|
+
end
|
57
|
+
|
58
|
+
test_block.call(self)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def assert_attributes_assigned(attribute_names=nil)
|
63
|
+
fixture(
|
64
|
+
Schema::Fixtures::Assignment,
|
65
|
+
message,
|
66
|
+
attribute_names,
|
67
|
+
print_title_context: false,
|
68
|
+
attributes_context_name: "Attributes Assigned"
|
69
|
+
)
|
70
|
+
end
|
71
|
+
alias :assert_all_attributes_assigned :assert_attributes_assigned
|
72
|
+
|
73
|
+
def assert_attributes_copied(attribute_names=nil)
|
74
|
+
if source_message.nil?
|
75
|
+
test "Source message not nil" do
|
76
|
+
detail "Source Message: nil"
|
77
|
+
refute(source_message.nil?)
|
78
|
+
end
|
79
|
+
return
|
80
|
+
end
|
81
|
+
|
82
|
+
fixture(
|
83
|
+
Schema::Fixtures::Equality,
|
84
|
+
source_message,
|
85
|
+
message,
|
86
|
+
attribute_names,
|
87
|
+
ignore_class: true,
|
88
|
+
print_title_context: false,
|
89
|
+
attributes_context_name: "Attributes Copied: #{source_message_type} => #{message_type}"
|
90
|
+
)
|
91
|
+
end
|
92
|
+
|
93
|
+
def assert_metadata(&test_block)
|
94
|
+
fixture(
|
95
|
+
Metadata,
|
96
|
+
message.metadata,
|
97
|
+
source_message&.metadata,
|
98
|
+
&test_block
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
def assert_follows
|
103
|
+
metadata = message.metadata
|
104
|
+
source_metadata = source_message&.metadata
|
105
|
+
|
106
|
+
fixture(Follows, metadata, source_metadata)
|
107
|
+
end
|
108
|
+
|
109
|
+
def assert_attribute_value(name, value)
|
110
|
+
context "Attribute Value" do
|
111
|
+
attribute_value = message.public_send(name)
|
112
|
+
|
113
|
+
test "#{name}" do
|
114
|
+
detail "Attribute Value: #{attribute_value.inspect}"
|
115
|
+
detail "Compare Value: #{value.inspect}"
|
116
|
+
|
117
|
+
assert(attribute_value == value)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
@@ -0,0 +1,92 @@
|
|
1
|
+
module Messaging
|
2
|
+
module Fixtures
|
3
|
+
class Metadata
|
4
|
+
Error = Class.new(RuntimeError)
|
5
|
+
|
6
|
+
include TestBench::Fixture
|
7
|
+
include Initializer
|
8
|
+
|
9
|
+
initializer :metadata, :source_metadata, :test_block
|
10
|
+
|
11
|
+
def self.build(metadata, source_metadata=nil, &test_block)
|
12
|
+
new(metadata, source_metadata, test_block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def call
|
16
|
+
context "Metadata" do
|
17
|
+
if test_block.nil?
|
18
|
+
raise Error, "Metadata fixture must be executed with a block"
|
19
|
+
end
|
20
|
+
|
21
|
+
if metadata.nil?
|
22
|
+
test "Not nil" do
|
23
|
+
detail "Metadata: nil"
|
24
|
+
|
25
|
+
if not test_block.nil?
|
26
|
+
detail "Remaining message tests are skipped"
|
27
|
+
end
|
28
|
+
|
29
|
+
refute(metadata.nil?)
|
30
|
+
end
|
31
|
+
return
|
32
|
+
end
|
33
|
+
|
34
|
+
test_block.call(self)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def assert_attributes_assigned(attribute_names=nil, context_title_qualifier: nil)
|
39
|
+
attribute_names ||= Messaging::Message::Metadata.all_attribute_names
|
40
|
+
|
41
|
+
attributes_context_title = "#{context_title_qualifier} Attributes Assigned".lstrip
|
42
|
+
|
43
|
+
fixture(
|
44
|
+
Schema::Fixtures::Assignment,
|
45
|
+
metadata,
|
46
|
+
attribute_names,
|
47
|
+
print_title_context: false,
|
48
|
+
attributes_context_name: attributes_context_title
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
def assert_source_attributes_assigned
|
53
|
+
attribute_names = Messaging::Message::Metadata.source_attribute_names
|
54
|
+
assert_attributes_assigned(attribute_names, context_title_qualifier: 'Source')
|
55
|
+
end
|
56
|
+
|
57
|
+
def assert_workflow_attributes_assigned
|
58
|
+
attribute_names = Messaging::Message::Metadata.workflow_attribute_names
|
59
|
+
assert_attributes_assigned(attribute_names, context_title_qualifier: 'Workflow')
|
60
|
+
end
|
61
|
+
|
62
|
+
def assert_causation_attributes_assigned
|
63
|
+
attribute_names = Messaging::Message::Metadata.causation_attribute_names
|
64
|
+
assert_attributes_assigned(attribute_names, context_title_qualifier: 'Causation')
|
65
|
+
end
|
66
|
+
|
67
|
+
def assert_correlation_stream_name(correlation_stream_name)
|
68
|
+
metadata_value = metadata.correlation_stream_name
|
69
|
+
|
70
|
+
test "correlation_stream_name" do
|
71
|
+
detail "Metadata Value: #{metadata_value}"
|
72
|
+
detail "Compare Value: #{correlation_stream_name}"
|
73
|
+
assert(metadata_value == correlation_stream_name)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def assert_reply_stream_name(reply_stream_name)
|
78
|
+
metadata_value = metadata.reply_stream_name
|
79
|
+
|
80
|
+
test "reply_stream_name" do
|
81
|
+
detail "Metadata Value: #{metadata_value}"
|
82
|
+
detail "Compare Value: #{reply_stream_name}"
|
83
|
+
assert(metadata_value == reply_stream_name)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def assert_follows
|
88
|
+
fixture(Follows, metadata, source_metadata)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
module Messaging
|
2
|
+
module Fixtures
|
3
|
+
class Writer
|
4
|
+
Error = Class.new(RuntimeError)
|
5
|
+
|
6
|
+
include TestBench::Fixture
|
7
|
+
include Initializer
|
8
|
+
|
9
|
+
initializer :message, :stream_name, :expected_version, :reply_stream_name, :test_block
|
10
|
+
|
11
|
+
def self.build(writer, message_class, &test_block)
|
12
|
+
data = get_data(writer, message_class)
|
13
|
+
|
14
|
+
message = data&.message
|
15
|
+
stream_name = data&.stream_name
|
16
|
+
expected_version = data&.expected_version
|
17
|
+
reply_stream_name = data&.reply_stream_name
|
18
|
+
|
19
|
+
new(message, stream_name, expected_version, reply_stream_name, test_block)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.get_data(writer, message_class)
|
23
|
+
sink = writer.sink
|
24
|
+
|
25
|
+
records = sink.written_records.select do |record|
|
26
|
+
record.data.message.class == message_class
|
27
|
+
end
|
28
|
+
|
29
|
+
if records.length > 1
|
30
|
+
raise Error, "More than one message written (Message Class: #{message_class})"
|
31
|
+
end
|
32
|
+
|
33
|
+
if records.empty?
|
34
|
+
return nil
|
35
|
+
end
|
36
|
+
|
37
|
+
records.first.data
|
38
|
+
end
|
39
|
+
|
40
|
+
def call
|
41
|
+
message_class = message&.class
|
42
|
+
|
43
|
+
context_name = 'Write'
|
44
|
+
if not message_class.nil?
|
45
|
+
context_name = "#{context_name}: #{message_class&.message_type}"
|
46
|
+
end
|
47
|
+
|
48
|
+
context context_name do
|
49
|
+
if test_block.nil?
|
50
|
+
raise Error, "Write fixture must be executed with a block"
|
51
|
+
end
|
52
|
+
|
53
|
+
detail "Message Class: #{message_class.inspect}"
|
54
|
+
|
55
|
+
written = !message.nil?
|
56
|
+
|
57
|
+
test "Written" do
|
58
|
+
if not test_block.nil?
|
59
|
+
detail "Remaining message tests are skipped"
|
60
|
+
end
|
61
|
+
|
62
|
+
assert(written)
|
63
|
+
end
|
64
|
+
|
65
|
+
return if !written
|
66
|
+
|
67
|
+
test_block.call(self)
|
68
|
+
end
|
69
|
+
|
70
|
+
message
|
71
|
+
end
|
72
|
+
|
73
|
+
def assert_stream_name(stream_name)
|
74
|
+
test "Stream name" do
|
75
|
+
detail "Stream Name: #{stream_name}"
|
76
|
+
detail "Written Stream Name: #{self.stream_name}"
|
77
|
+
|
78
|
+
assert(stream_name == self.stream_name)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def assert_expected_version(expected_version)
|
83
|
+
test "Expected version" do
|
84
|
+
detail "Expected Version: #{expected_version}"
|
85
|
+
detail "Written Expected Version: #{self.expected_version}"
|
86
|
+
|
87
|
+
assert(expected_version == self.expected_version)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def assert_reply_stream_name(reply_stream_name)
|
92
|
+
test "Reply stream name" do
|
93
|
+
detail "Reply stream Name: #{reply_stream_name}"
|
94
|
+
detail "Written reply stream Name: #{self.reply_stream_name}"
|
95
|
+
|
96
|
+
assert(reply_stream_name == self.reply_stream_name)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: evt-messaging-fixtures
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- The Eventide Project
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name: evt-
|
14
|
+
name: evt-entity_store
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: evt-schema-fixtures
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -60,11 +60,26 @@ extra_rdoc_files: []
|
|
60
60
|
files:
|
61
61
|
- lib/messaging/fixtures.rb
|
62
62
|
- lib/messaging/fixtures/controls.rb
|
63
|
+
- lib/messaging/fixtures/controls/entity.rb
|
64
|
+
- lib/messaging/fixtures/controls/event.rb
|
65
|
+
- lib/messaging/fixtures/controls/handler.rb
|
66
|
+
- lib/messaging/fixtures/controls/id.rb
|
67
|
+
- lib/messaging/fixtures/controls/message.rb
|
68
|
+
- lib/messaging/fixtures/controls/metadata.rb
|
69
|
+
- lib/messaging/fixtures/controls/sequence.rb
|
70
|
+
- lib/messaging/fixtures/controls/store.rb
|
71
|
+
- lib/messaging/fixtures/controls/time.rb
|
72
|
+
- lib/messaging/fixtures/defaults.rb
|
73
|
+
- lib/messaging/fixtures/follows.rb
|
74
|
+
- lib/messaging/fixtures/handler.rb
|
75
|
+
- lib/messaging/fixtures/message.rb
|
76
|
+
- lib/messaging/fixtures/metadata.rb
|
77
|
+
- lib/messaging/fixtures/writer.rb
|
63
78
|
homepage: https://github.com/eventide-project/messaging-fixtures
|
64
79
|
licenses:
|
65
80
|
- MIT
|
66
81
|
metadata: {}
|
67
|
-
post_install_message:
|
82
|
+
post_install_message:
|
68
83
|
rdoc_options: []
|
69
84
|
require_paths:
|
70
85
|
- lib
|
@@ -79,8 +94,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
94
|
- !ruby/object:Gem::Version
|
80
95
|
version: '0'
|
81
96
|
requirements: []
|
82
|
-
rubygems_version: 3.1.
|
83
|
-
signing_key:
|
97
|
+
rubygems_version: 3.1.2
|
98
|
+
signing_key:
|
84
99
|
specification_version: 4
|
85
100
|
summary: TestBench fixtures for the Messaging library
|
86
101
|
test_files: []
|