rspec-process-mocks 0.0.1 → 0.0.2

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.
@@ -81,6 +81,90 @@ Feature: expect a message
81
81
  And the output should contain "expected: 1 time"
82
82
  And the output should contain "received: 0 times"
83
83
 
84
+ Scenario: expect a message, and it is called twice
85
+ Given a file named "spec/account_spec.rb" with:
86
+ """
87
+ RSpec.configuration.mock_framework = :rspec
88
+ $: << File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'lib'))
89
+ require 'rspec/process_mocks'
90
+ require "account"
91
+
92
+ describe Account do
93
+ context "when closed" do
94
+ it "logs an account closed message in a child process" do
95
+
96
+ logger = double("logger")
97
+ account = Account.new
98
+ account.logger = logger
99
+
100
+ logger.should_receive_in_child_process(:account_closed)
101
+
102
+ account.close
103
+
104
+ sleep 0.1
105
+ end
106
+ end
107
+ end
108
+ """
109
+ And a file named "lib/account.rb" with:
110
+ """
111
+ class Account
112
+ attr_accessor :logger
113
+
114
+ def close
115
+ Process.fork do
116
+ logger.account_closed
117
+ logger.account_closed
118
+ end
119
+ end
120
+ end
121
+ """
122
+ When I run `rspec spec/account_spec.rb`
123
+ Then the output should contain "1 example, 1 failure"
124
+ And the output should contain "expected: 1 time"
125
+ And the output should contain "received: 2 times"
126
+
127
+ Scenario: expect a message at least once, and it is called twice
128
+ Given a file named "spec/account_spec.rb" with:
129
+ """
130
+ RSpec.configuration.mock_framework = :rspec
131
+ $: << File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'lib'))
132
+ require 'rspec/process_mocks'
133
+ require "account"
134
+
135
+ describe Account do
136
+ context "when closed" do
137
+ it "logs an account closed message in a child process" do
138
+
139
+ logger = double("logger")
140
+ account = Account.new
141
+ account.logger = logger
142
+
143
+ logger.should_receive_in_child_process(:account_closed).at_least(1).times
144
+
145
+ account.close
146
+
147
+ sleep 0.1
148
+ end
149
+ end
150
+ end
151
+ """
152
+ And a file named "lib/account.rb" with:
153
+ """
154
+ class Account
155
+ attr_accessor :logger
156
+
157
+ def close
158
+ Process.fork do
159
+ logger.account_closed
160
+ logger.account_closed
161
+ end
162
+ end
163
+ end
164
+ """
165
+ When I run `rspec spec/account_spec.rb`
166
+ Then the output should contain "1 example, 0 failure"
167
+
84
168
  @wip
85
169
  Scenario: expect a message with an argument
86
170
  Given a file named "spec/account_spec.rb" with:
@@ -6,60 +6,67 @@ module RSpec
6
6
  def initialize(*args)
7
7
  super
8
8
 
9
- # The tempfile is used for interprocess communication
10
- @tempfile = Tempfile.new("should-receive-#{@expected_from.object_id}-#{@sym}")
9
+ # The temp files are used for interprocess communication.
10
+ # This one stores the calls that are exact matches.
11
+ @actual_tempfile = Tempfile.new("should-receive-#{@expected_from.object_id}-#{@sym}")
12
+ # This one stores the similar calls.
13
+ @similar_tempfile = Tempfile.new("should-receive-similar-#{@expected_from.object_id}-#{@sym}")
11
14
  end
12
- def verify_messages_received
13
- # Maybe we should add a sleep loop here if @tempfile is empty. This may
14
- # prevent a user of this library from having to add a sleep in the spec.
15
- # Maybe this:
16
- # @tempfile.rewind
17
- # lines = @tempfile.readlines
18
- # timeout = Configure.verify_timeout
19
- # while lines.empty? && timeout > 0
20
- # sleep 0.1
21
- # timeout -= 0.1
22
- # @tempfile.rewind
23
- # lines = @tempfile.readlines
24
- # end
25
15
 
26
- @tempfile.rewind
27
- lines = @tempfile.readlines
28
- #puts "lines in verify_messages_received: #{lines.inspect}"
29
- return true if lines.size == 1 #&& # Called exactly once.
30
- # lines[0] == "[]\n" # Called with no arguments.
31
16
 
32
- generate_error
33
- rescue RSpec::Mocks::MockExpectationError => error
34
- error.backtrace.insert(0, @expected_from)
35
- Kernel::raise error
17
+ # This method is executed in the _child_ process when the stubbed method
18
+ # is called exact arguments
19
+ # Overwritten from rspec.
20
+ def invoke(*args, &block)
21
+ msg = args.inspect
22
+ @actual_tempfile.puts msg
23
+ @actual_tempfile.flush
36
24
  end
37
25
 
38
- # This is a hack to get it to work. But it means we can only ever expect
39
- # exactly 1 message.
40
- def matches_exact_count?
41
- lines.size == 1
26
+ # This method is executed in the _child_ process when the stubbed method
27
+ # is called with similar argument.
28
+ # Overwritten from rspec.
29
+ def advise(*args)
30
+ @similar_tempfile.puts msg
31
+ @similar_tempfile.flush
32
+ similar_messages
42
33
  end
43
34
 
44
- # This method is executed in the _child_ process when the stubbed method
45
- # is called.
46
- def invoke(*args, &block)
35
+ # This overwrites the rspec implementation because we need to record
36
+ # similar messages in a temp file not instance variables.
37
+ def similar_messages
38
+ @similar_tempfile.rewind
39
+ @similar_tempfile.readlines
40
+ end
47
41
 
48
- msg = args.inspect
49
- @tempfile.puts msg
50
- @tempfile.flush
51
- # puts "##{@sym} called on #{@expected_from.class}-#{@expected_from.object_id}; args: #{args.inspect}"
52
- # yield block, *args if defined?(block)
42
+ # Reads back the actual/exact-match arguments written to the temp file.
43
+ # This is not a method in rspec.
44
+ def actual_messages
45
+ @actual_tempfile.rewind
46
+ @actual_tempfile.readlines
53
47
  end
54
48
 
55
- # This is a hack to get it to work. But it means we don't get info about
56
- # "similar" methods in the failure output. Similar messages are those with
57
- # a matching method name, but not matching arguments.
58
- # Note: this is only a rough definition of "similar" methods. "Similar"
59
- # methods are not part of RSpec's external API, so their definition is not
60
- # strictly documented.
61
- def similar_messages
62
- []
49
+ # The following methods used to use instance variables. But we can't do
50
+ # that because those aren't shared between processes. These methods
51
+ # overwrite rspec's behavior and instead keep the state in temp files.
52
+ def actual_received_count
53
+ actual_messages.size
54
+ end
55
+ def generate_error
56
+ if similar_messages.empty?
57
+ @error_generator.raise_expectation_error(@sym, @expected_received_count, actual_received_count, *@args_expectation.args)
58
+ else
59
+ @error_generator.raise_similar_message_args_error(self, *similar_messages)
60
+ end
61
+ end
62
+ def matches_at_least_count?
63
+ @at_least && actual_received_count >= @expected_received_count
64
+ end
65
+ def matches_at_most_count?
66
+ @at_most && actual_received_count <= @expected_received_count
67
+ end
68
+ def matches_exact_count?
69
+ @expected_received_count == actual_received_count
63
70
  end
64
71
  end
65
72
  end
@@ -1,7 +1,7 @@
1
1
  module RSpec # :nodoc:
2
2
  module ProcessMocks # :nodoc:
3
3
  module Version # :nodoc:
4
- STRING = '0.0.1'
4
+ STRING = '0.0.2'
5
5
  end
6
6
  end
7
7
  end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: rspec-process-mocks
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.1
5
+ version: 0.0.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Paul Cortens
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-05-28 00:00:00 -07:00
13
+ date: 2011-06-08 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies: []
16
16
 
@@ -64,6 +64,6 @@ rubyforge_project:
64
64
  rubygems_version: 1.5.0
65
65
  signing_key:
66
66
  specification_version: 3
67
- summary: rspec-process-mocks-0.0.1
67
+ summary: rspec-process-mocks-0.0.2
68
68
  test_files: []
69
69