object_protocol 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/CHANGELOG.md +6 -3
- data/Gemfile.lock +3 -3
- data/README.adoc +133 -0
- data/lib/object_protocol.rb +49 -8
- data/lib/object_protocol/execution.rb +17 -7
- data/lib/object_protocol/{step.rb → message_expectation.rb} +19 -8
- data/lib/object_protocol/rspec.rb +2 -2
- data/lib/object_protocol/satisfaction_attempt.rb +6 -9
- data/lib/object_protocol/{satisfiable_step.rb → satisfiable_message_expectation.rb} +9 -5
- data/lib/object_protocol/satisfiable_unordered_message_sequence_expectation.rb +36 -0
- data/lib/object_protocol/stand_in.rb +6 -4
- data/lib/object_protocol/unordered_message_sequence_expectation.rb +31 -0
- data/lib/object_protocol/version.rb +1 -1
- metadata +7 -5
- data/README.md +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dd7f3c31f616d5f7d1d1e41c6aa8414dc0aa07b175f587e692878453d9735166
|
4
|
+
data.tar.gz: 43e98c4fa8a3f5efeb4dffe1eaf41e353dac9628b1ede3748ad3c8b79d7ab5de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a9af361219c6a9ee45684da4f7cc6196703827f2aa75ecd0562432f88ec47329759c027aaac141b24135be0f4cb23fa9a6733448bedcf6d4215173c0a3052063
|
7
|
+
data.tar.gz: 9a88fd2277328dfc311c350ee1c491fb25d5eb9470060593e2f25c68bec2e1cffc342b64f775c1fbb283ac6acad5a03b5594a8e573a6a19a1caff9a6ca53ce5f
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,12 +1,15 @@
|
|
1
1
|
## ROADMAP
|
2
2
|
|
3
3
|
* in_order
|
4
|
-
*
|
5
|
-
* doesnt_send (and figure out how it relates to ordering steps)
|
6
|
-
* add diffs to failure message
|
4
|
+
* doesnt_send (and figure out how it relates to ordering message expectations)
|
7
5
|
* add color to failure message diffs
|
8
6
|
* make failure message diff colors configurable via env vars for acessibility
|
9
7
|
|
8
|
+
## RELEASE 0.2.0
|
9
|
+
|
10
|
+
* FEATURE: `in_any_order` lets you declare a subset of protocol messages that you don't care about the order of, just that they are sent & received with the correct arguments (if any).
|
11
|
+
* ENHANCEMENT: `ObjectProtocol#bind` now provides a helpful error message if you try to bind the wrong participant names.
|
12
|
+
|
10
13
|
## RELEASE 0.1.0
|
11
14
|
|
12
15
|
* FEATURE: ObjectProtocols can be instantiated and used in tests
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
object_protocol (0.
|
4
|
+
object_protocol (0.2.0)
|
5
5
|
binding_of_caller
|
6
6
|
|
7
7
|
GEM
|
@@ -13,7 +13,7 @@ GEM
|
|
13
13
|
coderay (1.1.2)
|
14
14
|
debug_inspector (0.0.3)
|
15
15
|
diff-lcs (1.3)
|
16
|
-
git (1.
|
16
|
+
git (1.5.0)
|
17
17
|
method_source (0.9.0)
|
18
18
|
pry (0.11.3)
|
19
19
|
coderay (~> 1.1.0)
|
@@ -35,7 +35,7 @@ GEM
|
|
35
35
|
diff-lcs (>= 1.2.0, < 2.0)
|
36
36
|
rspec-support (~> 3.7.0)
|
37
37
|
rspec-support (3.7.1)
|
38
|
-
structured_changelog (0.10.
|
38
|
+
structured_changelog (0.10.2)
|
39
39
|
git
|
40
40
|
|
41
41
|
PLATFORMS
|
data/README.adoc
ADDED
@@ -0,0 +1,133 @@
|
|
1
|
+
= ObjectProtocol
|
2
|
+
:ext-relative: .adoc
|
3
|
+
:source-highlighter: coderay
|
4
|
+
:sectanchors:
|
5
|
+
:linkattrs:
|
6
|
+
:toc: left
|
7
|
+
ifdef::env-github[]
|
8
|
+
:tip-caption: :bulb:
|
9
|
+
:note-caption: :information_source:
|
10
|
+
:important-caption: :heavy_exclamation_mark:
|
11
|
+
:caution-caption: :fire:
|
12
|
+
:warning-caption: :warning:
|
13
|
+
endif::[]
|
14
|
+
|
15
|
+
== Goals
|
16
|
+
|
17
|
+
. Write message expectation tests with less boilerplate than when using RSpec spies
|
18
|
+
. Resulting protocols should be usable as documentation
|
19
|
+
. Be able to specify which object sent the message and which object received it (traditional message expectation test only allow the latter)
|
20
|
+
|
21
|
+
== What's An Object Protocol?
|
22
|
+
|
23
|
+
Protocols are the types of an OO program. They structure and order the messages passed between communicating agents.
|
24
|
+
|
25
|
+
== Using Object Protocols
|
26
|
+
|
27
|
+
=== A Simple Logger
|
28
|
+
|
29
|
+
Given a unrealistically simple logger:
|
30
|
+
[source,ruby]
|
31
|
+
----
|
32
|
+
class UnrealisticLogger
|
33
|
+
def initialize(device)
|
34
|
+
@device = device
|
35
|
+
end
|
36
|
+
|
37
|
+
def log(message)
|
38
|
+
@device << message
|
39
|
+
end
|
40
|
+
|
41
|
+
def rotate
|
42
|
+
@device.shift
|
43
|
+
end
|
44
|
+
end
|
45
|
+
----
|
46
|
+
|
47
|
+
we can write a protocol for what happens when we call `#log` on an instance of `UnrealisticLogger`
|
48
|
+
|
49
|
+
[source.ruby]
|
50
|
+
----
|
51
|
+
UnrealisticLoggingProtocol = ObjectProtocol.new(:device, :logger) do # <1>
|
52
|
+
logger.sends(:<<).to(device) # <2>
|
53
|
+
end
|
54
|
+
----
|
55
|
+
<1> we need to tell the protocol the names of the participants
|
56
|
+
<2> we switch to using local variables here instead of the symbols
|
57
|
+
|
58
|
+
Then, we can test this protocol:
|
59
|
+
|
60
|
+
[source,ruby]
|
61
|
+
----
|
62
|
+
require 'object_protocol/rspec'
|
63
|
+
|
64
|
+
RSpec.describe UnrealisticLoggingProtocol do
|
65
|
+
it "is satisfied by calling #log on the logger" do
|
66
|
+
device = []
|
67
|
+
logger = UnrealisticLogger.new(device) # <1>
|
68
|
+
|
69
|
+
UnrealisticLoggingProtocol.bind( # <2>
|
70
|
+
device: device,
|
71
|
+
logger: logger,
|
72
|
+
)
|
73
|
+
|
74
|
+
expect(UnrealisticLoggingProtocol).to be_satisfied_by do
|
75
|
+
logger.log("message") # <3>
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
----
|
80
|
+
<1> instantiate the participants
|
81
|
+
<2> bind participants to the protocol
|
82
|
+
<3> test an execution against the protocol
|
83
|
+
|
84
|
+
Ok, but what was all that?
|
85
|
+
|
86
|
+
Well, we created a protocol that we can use as documentation, and tested it with a lot less fanfare and boilerplate than you'd need with traditional message expectation tests!
|
87
|
+
|
88
|
+
In real life, you'd use an actual object defined in your codebase in place of a fake logger, but you'd probably inject fake or stub collaborator objects to avoid side-effects.
|
89
|
+
|
90
|
+
== How Does This All Work, Anyway?
|
91
|
+
|
92
|
+
During an execution (the block passed to `satisfied_by`), we spy on every public method (except `#__send__` and `#object_id` because of the warnings) defined on each bound participant object. We record the message, the sender, the receiver, and the arguments (if any) that were passed. Then, we invoke the actual method behavior defined by that object.
|
93
|
+
|
94
|
+
=== Interaction with `#method_missing`
|
95
|
+
|
96
|
+
`#method_missing` is rarely a message that is sent from one object to another. We currently record the name of the missing method as the "sent message" and record any arguments beyond that message name, as well as the sender and receiver.
|
97
|
+
|
98
|
+
== Installation
|
99
|
+
|
100
|
+
Add this line to your application's Gemfile:
|
101
|
+
|
102
|
+
[source,ruby]
|
103
|
+
----
|
104
|
+
gem 'object_protocol'
|
105
|
+
----
|
106
|
+
|
107
|
+
And then execute:
|
108
|
+
|
109
|
+
[source,shell]
|
110
|
+
----
|
111
|
+
$ bundle
|
112
|
+
----
|
113
|
+
|
114
|
+
Or install it yourself as:
|
115
|
+
|
116
|
+
[source,shell]
|
117
|
+
----
|
118
|
+
$ gem install object_protocol
|
119
|
+
----
|
120
|
+
|
121
|
+
== Development
|
122
|
+
|
123
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
124
|
+
|
125
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to https://rubygems.org[rubygems.org].
|
126
|
+
|
127
|
+
== Contributing
|
128
|
+
|
129
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/yarmiganosca/object_protocol. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the http://contributor-covenant.org[Contributor Covenant] code of conduct.
|
130
|
+
|
131
|
+
== Code of Conduct
|
132
|
+
|
133
|
+
Everyone interacting in the ObjectProtocol project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the https://github.com/yarmiganosca/object_protocol/blob/master/CODE_OF_CONDUCT.md[code of conduct].
|
data/lib/object_protocol.rb
CHANGED
@@ -1,30 +1,65 @@
|
|
1
1
|
require "object_protocol/version"
|
2
2
|
require 'object_protocol/stand_in'
|
3
3
|
require 'object_protocol/satisfaction_attempt'
|
4
|
+
require 'object_protocol/unordered_message_sequence_expectation'
|
4
5
|
|
5
6
|
class ObjectProtocol
|
6
7
|
attr_reader :participants_by_name
|
7
8
|
|
8
|
-
def initialize(*participant_names, &
|
9
|
+
def initialize(*participant_names, &expectations)
|
10
|
+
@participant_names = participant_names.map(&:to_sym)
|
11
|
+
|
9
12
|
participant_names.each(&method(:define_stand_in))
|
10
|
-
instance_exec(&
|
13
|
+
instance_exec(&expectations)
|
11
14
|
participant_names.each(&method(:undefine_stand_in))
|
12
15
|
end
|
13
16
|
|
17
|
+
def in_any_order(&expectations)
|
18
|
+
unordered_message_sequence_expectation = UnorderedMessageSequenceExpectation.new(protocol: self)
|
19
|
+
self.expectations << unordered_message_sequence_expectation
|
20
|
+
|
21
|
+
expectation_sequence_stack.push(unordered_message_sequence_expectation)
|
22
|
+
instance_exec(&expectations)
|
23
|
+
expectation_sequence_stack.pop
|
24
|
+
end
|
25
|
+
|
14
26
|
def bind(**participants_by_name)
|
15
|
-
|
27
|
+
bind_attempt_participant_names = participants_by_name.keys.map(&:to_sym)
|
28
|
+
|
29
|
+
missing_participant_names = participant_names - bind_attempt_participant_names
|
30
|
+
extra_participant_names = bind_attempt_participant_names - participant_names
|
31
|
+
|
32
|
+
if missing_participant_names.empty? && extra_participant_names.empty?
|
33
|
+
@participants_by_name = participants_by_name
|
34
|
+
|
35
|
+
@participants_by_name.each(&method(:define_participant))
|
36
|
+
|
37
|
+
self
|
38
|
+
else
|
39
|
+
key_error_message_parts = []
|
16
40
|
|
17
|
-
|
41
|
+
if missing_participant_names.any?
|
42
|
+
key_error_message_parts << "These keys are required by this protocol but weren't provided: #{missing_participant_names.join(', ')}"
|
43
|
+
end
|
18
44
|
|
19
|
-
|
45
|
+
if extra_participant_names.any?
|
46
|
+
key_error_message_parts << "These keys aren't used in this protocol but were provided: #{extra_participant_names.join(', ')}"
|
47
|
+
end
|
48
|
+
|
49
|
+
raise KeyError, key_error_message_parts.join("\n ") # makes the second line indent correctly
|
50
|
+
end
|
20
51
|
end
|
21
52
|
|
22
53
|
def satisfied_by?(&blk)
|
23
54
|
SatisfactionAttempt.new(self, &blk).to_bool
|
24
55
|
end
|
25
56
|
|
26
|
-
def
|
27
|
-
|
57
|
+
def add_expectation(expectation)
|
58
|
+
expectation_sequence_stack.last.expectations << expectation
|
59
|
+
end
|
60
|
+
|
61
|
+
def expectations
|
62
|
+
@expectations ||= []
|
28
63
|
end
|
29
64
|
|
30
65
|
def participant_by_name(name)
|
@@ -40,11 +75,13 @@ class ObjectProtocol
|
|
40
75
|
end
|
41
76
|
|
42
77
|
def to_rspec_matcher_failure_message_lines
|
43
|
-
|
78
|
+
expectations.flat_map(&:to_rspec_matcher_failure_message_lines)
|
44
79
|
end
|
45
80
|
|
46
81
|
private
|
47
82
|
|
83
|
+
attr_reader :participant_names
|
84
|
+
|
48
85
|
def define_participant(name, participant)
|
49
86
|
instance_variable_set("@#{name}_participant", participant)
|
50
87
|
|
@@ -65,4 +102,8 @@ class ObjectProtocol
|
|
65
102
|
instance_eval("undef :#{name}")
|
66
103
|
remove_instance_variable("@#{name}_stand_in")
|
67
104
|
end
|
105
|
+
|
106
|
+
def expectation_sequence_stack
|
107
|
+
@expectation_sequence_stack ||= [self]
|
108
|
+
end
|
68
109
|
end
|
@@ -62,13 +62,23 @@ class ObjectProtocol
|
|
62
62
|
args
|
63
63
|
end
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
65
|
+
if method_name == :method_missing
|
66
|
+
sent_message = SentMessage.new(
|
67
|
+
sender: sender,
|
68
|
+
receiver: self,
|
69
|
+
name: arguments.first
|
70
|
+
)
|
71
|
+
|
72
|
+
sent_message.with(arguments[1..-1]) if arguments.size > 1
|
73
|
+
else
|
74
|
+
sent_message = SentMessage.new(
|
75
|
+
sender: sender,
|
76
|
+
receiver: self,
|
77
|
+
name: method_name
|
78
|
+
)
|
79
|
+
|
80
|
+
sent_message.with(arguments) if arguments.any?
|
81
|
+
end
|
72
82
|
|
73
83
|
execution.messages << sent_message
|
74
84
|
end
|
@@ -1,10 +1,13 @@
|
|
1
|
+
require 'object_protocol/satisfiable_message_expectation'
|
2
|
+
|
1
3
|
class ObjectProtocol
|
2
|
-
class
|
4
|
+
class MessageExpectation
|
3
5
|
attr_reader :sender, :message, :receiver, :arguments
|
4
6
|
|
5
|
-
def initialize(sender:, message:)
|
6
|
-
@
|
7
|
-
@
|
7
|
+
def initialize(protocol:, sender:, message:)
|
8
|
+
@protocol = protocol
|
9
|
+
@sender = sender
|
10
|
+
@message = message
|
8
11
|
|
9
12
|
@arguments_specified = false
|
10
13
|
end
|
@@ -23,17 +26,21 @@ class ObjectProtocol
|
|
23
26
|
self
|
24
27
|
end
|
25
28
|
|
29
|
+
def to_satisfiable
|
30
|
+
SatisfiableMessageExpectation.new(protocol: protocol, message_expectation: self)
|
31
|
+
end
|
32
|
+
|
26
33
|
def inspect
|
27
|
-
"
|
34
|
+
"<#{self.class.name.split('::').last}[#{sender.name}, :#{message}, #{receiver.name}]>"
|
28
35
|
end
|
29
36
|
|
30
|
-
def
|
37
|
+
def to_rspec_matcher_failure_message_lines
|
31
38
|
fragment_base = "#{sender.name}.sends(:#{message}).to(#{receiver.name})"
|
32
39
|
|
33
40
|
if arguments_specified?
|
34
|
-
"#{fragment_base}.with(#{arguments})"
|
41
|
+
["#{fragment_base}.with(#{arguments})"]
|
35
42
|
else
|
36
|
-
fragment_base
|
43
|
+
[fragment_base]
|
37
44
|
end
|
38
45
|
end
|
39
46
|
|
@@ -51,5 +58,9 @@ class ObjectProtocol
|
|
51
58
|
def arguments_specified?
|
52
59
|
@arguments_specified
|
53
60
|
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
attr_reader :protocol
|
54
65
|
end
|
55
66
|
end
|
@@ -18,9 +18,9 @@ class SatisfactionAttemptVerifier
|
|
18
18
|
def failure_message
|
19
19
|
[
|
20
20
|
"expected",
|
21
|
-
protocol.to_rspec_matcher_failure_message_lines.
|
21
|
+
*protocol.to_rspec_matcher_failure_message_lines.flat_map(&" ".method(:+)),
|
22
22
|
"to be satisfied by",
|
23
|
-
attempt.to_rspec_matcher_failure_message_lines.
|
23
|
+
*attempt.to_rspec_matcher_failure_message_lines.flat_map(&" ".method(:+)),
|
24
24
|
].join("\n")
|
25
25
|
end
|
26
26
|
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'object_protocol/execution'
|
2
|
-
require 'object_protocol/satisfiable_step'
|
3
2
|
|
4
3
|
class ObjectProtocol
|
5
4
|
class SatisfactionAttempt
|
@@ -11,21 +10,19 @@ class ObjectProtocol
|
|
11
10
|
def to_bool
|
12
11
|
execution.call(protocol)
|
13
12
|
|
14
|
-
|
15
|
-
SatisfiableStep.new(protocol: protocol, step: step)
|
16
|
-
end
|
13
|
+
satisfiable_expectations = protocol.expectations.map(&:to_satisfiable)
|
17
14
|
|
18
15
|
execution.messages.each do |sent_message|
|
19
|
-
|
16
|
+
next_expectation = satisfiable_expectations.first
|
20
17
|
|
21
|
-
|
18
|
+
next_expectation.attempt_to_apply_sent_message(sent_message)
|
22
19
|
|
23
|
-
if
|
24
|
-
|
20
|
+
if next_expectation.satisfied?
|
21
|
+
satisfiable_expectations.shift
|
25
22
|
end
|
26
23
|
end
|
27
24
|
|
28
|
-
|
25
|
+
satisfiable_expectations.empty?
|
29
26
|
end
|
30
27
|
|
31
28
|
def to_rspec_matcher_failure_message_lines
|
@@ -1,14 +1,14 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
|
3
3
|
class ObjectProtocol
|
4
|
-
class
|
4
|
+
class SatisfiableMessageExpectation
|
5
5
|
extend Forwardable
|
6
6
|
|
7
|
-
delegate %i(sender receiver message arguments arguments_specified?) => :@
|
7
|
+
delegate %i(sender receiver message arguments arguments_specified?) => :@message_expectation
|
8
8
|
|
9
|
-
def initialize(protocol:,
|
10
|
-
@protocol
|
11
|
-
@
|
9
|
+
def initialize(protocol:, message_expectation:)
|
10
|
+
@protocol = protocol
|
11
|
+
@message_expectation = message_expectation
|
12
12
|
|
13
13
|
@satisfied = false
|
14
14
|
end
|
@@ -36,6 +36,10 @@ class ObjectProtocol
|
|
36
36
|
!!@satisfied
|
37
37
|
end
|
38
38
|
|
39
|
+
def unsatisfied?
|
40
|
+
!satisfied?
|
41
|
+
end
|
42
|
+
|
39
43
|
private
|
40
44
|
|
41
45
|
attr_reader :protocol
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
|
3
|
+
class ObjectProtocol
|
4
|
+
class SatisfiableUnorderedMessageSequenceExpectation
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def initialize(protocol:, sequence_expectation:)
|
8
|
+
@protocol = protocol
|
9
|
+
@sequence_expectation = sequence_expectation
|
10
|
+
end
|
11
|
+
|
12
|
+
def attempt_to_apply_sent_message(sent_message)
|
13
|
+
return if satisfied?
|
14
|
+
|
15
|
+
satisfiable_expectations.each do |satisfiable_expectation|
|
16
|
+
if satisfiable_expectation.unsatisfied?
|
17
|
+
satisfiable_expectation.attempt_to_apply_sent_message(sent_message)
|
18
|
+
|
19
|
+
break if satisfiable_expectation.satisfied?
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def satisfied?
|
25
|
+
satisfiable_expectations.all?(&:satisfied?)
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
attr_reader :protocol, :sequence_expectation
|
31
|
+
|
32
|
+
def satisfiable_expectations
|
33
|
+
@satisfiable_expectations ||= sequence_expectation.expectations.map(&:to_satisfiable)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require 'object_protocol/
|
1
|
+
require 'object_protocol/message_expectation'
|
2
2
|
|
3
3
|
class ObjectProtocol
|
4
4
|
class StandIn
|
@@ -10,9 +10,11 @@ class ObjectProtocol
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def sends(message)
|
13
|
-
|
14
|
-
protocol
|
15
|
-
|
13
|
+
MessageExpectation.new(
|
14
|
+
protocol: protocol,
|
15
|
+
sender: self,
|
16
|
+
message: message
|
17
|
+
).tap(&protocol.method(:add_expectation))
|
16
18
|
end
|
17
19
|
|
18
20
|
private
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'object_protocol/satisfiable_unordered_message_sequence_expectation'
|
2
|
+
|
3
|
+
class ObjectProtocol
|
4
|
+
class UnorderedMessageSequenceExpectation
|
5
|
+
def initialize(protocol:)
|
6
|
+
@protocol = protocol
|
7
|
+
end
|
8
|
+
|
9
|
+
def expectations
|
10
|
+
@expectations ||= []
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_rspec_matcher_failure_message_lines
|
14
|
+
[
|
15
|
+
"in_any_order",
|
16
|
+
*expectations.flat_map(&:to_rspec_matcher_failure_message_lines).map(&" ".method(:+)),
|
17
|
+
]
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_satisfiable
|
21
|
+
SatisfiableUnorderedMessageSequenceExpectation.new(
|
22
|
+
protocol: protocol,
|
23
|
+
sequence_expectation: self
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
attr_reader :protocol
|
30
|
+
end
|
31
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: object_protocol
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Hoffman
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-08-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -109,18 +109,20 @@ files:
|
|
109
109
|
- Gemfile
|
110
110
|
- Gemfile.lock
|
111
111
|
- LICENSE
|
112
|
-
- README.
|
112
|
+
- README.adoc
|
113
113
|
- Rakefile
|
114
114
|
- bin/console
|
115
115
|
- bin/setup
|
116
116
|
- lib/object_protocol.rb
|
117
117
|
- lib/object_protocol/execution.rb
|
118
|
+
- lib/object_protocol/message_expectation.rb
|
118
119
|
- lib/object_protocol/rspec.rb
|
119
120
|
- lib/object_protocol/satisfaction_attempt.rb
|
120
|
-
- lib/object_protocol/
|
121
|
+
- lib/object_protocol/satisfiable_message_expectation.rb
|
122
|
+
- lib/object_protocol/satisfiable_unordered_message_sequence_expectation.rb
|
121
123
|
- lib/object_protocol/sent_message.rb
|
122
124
|
- lib/object_protocol/stand_in.rb
|
123
|
-
- lib/object_protocol/
|
125
|
+
- lib/object_protocol/unordered_message_sequence_expectation.rb
|
124
126
|
- lib/object_protocol/version.rb
|
125
127
|
- object_protocol.gemspec
|
126
128
|
homepage: https://www.github.com/yarmiganosca/object_protocol
|
data/README.md
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
# ObjectProtocol
|
2
|
-
|
3
|
-
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/object_protocol`. To experiment with that code, run `bin/console` for an interactive prompt.
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
6
|
-
|
7
|
-
## Installation
|
8
|
-
|
9
|
-
Add this line to your application's Gemfile:
|
10
|
-
|
11
|
-
```ruby
|
12
|
-
gem 'object_protocol'
|
13
|
-
```
|
14
|
-
|
15
|
-
And then execute:
|
16
|
-
|
17
|
-
$ bundle
|
18
|
-
|
19
|
-
Or install it yourself as:
|
20
|
-
|
21
|
-
$ gem install object_protocol
|
22
|
-
|
23
|
-
## Usage
|
24
|
-
|
25
|
-
TODO: Write usage instructions here
|
26
|
-
|
27
|
-
## Development
|
28
|
-
|
29
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
|
-
|
31
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
-
|
33
|
-
## Contributing
|
34
|
-
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/yarmiganosca/object_protocol. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
36
|
-
|
37
|
-
## Code of Conduct
|
38
|
-
|
39
|
-
Everyone interacting in the ObjectProtocol project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/yarmiganosca/object_protocol/blob/master/CODE_OF_CONDUCT.md).
|