rspec-spy 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.
data/README.md CHANGED
@@ -1,6 +1,28 @@
1
- # Rspec::Spy
1
+ # RSpec::Spy
2
2
 
3
- TODO: Write a gem description
3
+ This gem allows you to write mock expectations in an AAA (Arrange-Act-Assert) fashion
4
+ with RSpec::Mocks. It does this by allowing you to declare examples within a spy block,
5
+ which is effectively executed before everything else. Here's a simple example:
6
+
7
+ ``` ruby
8
+ describe "Example" do
9
+ let(:collaborator) { stub.as_null_object }
10
+
11
+ before do
12
+ collaborator.message
13
+ end
14
+
15
+ spy do
16
+ it "should receive a message" do
17
+ collaborator.should_receive :message
18
+ end
19
+
20
+ it "should not receive other_message" do
21
+ collaborator.should_not_receive :other_message
22
+ end
23
+ end
24
+ end
25
+ ```
4
26
 
5
27
  ## Installation
6
28
 
@@ -18,7 +40,54 @@ Or install it yourself as:
18
40
 
19
41
  ## Usage
20
42
 
21
- TODO: Write usage instructions here
43
+ Add to your spec_helper.rb:
44
+
45
+ ``` ruby
46
+ require 'rspec-spy'
47
+ ```
48
+
49
+ If you want to be warned when using should_receive outside of spy blocks (recommended)
50
+ add this to your spec_helper.rb:
51
+
52
+ ``` ruby
53
+ # Require should_receive and should_not_receive to be inside spy blocks
54
+ # Use should_receive! and should_not_receive! outside spy blocks
55
+ RSpec::Spy.strict_mode = true
56
+ ```
57
+
58
+ Now just put your spy expectations within spy blocks in your specs. You should be able to
59
+ use all of the functionality from rspec-mocks that you're used to, including spying on
60
+ class methods.
61
+
62
+ ``` ruby
63
+ spy do
64
+ it "should receive message" do
65
+ collaborator.should_receive :message
66
+ end
67
+ end
68
+
69
+ # Shorthand:
70
+ spy.it "should receive message" do
71
+ collaborator.should_receive :message
72
+ end
73
+ ```
74
+
75
+ ## Warnings
76
+
77
+ * This is a hack, you'll want to make sure everyone on your team is aware of the behavior
78
+ and these warnings. You may not actually even want to use this.
79
+ * You should probably avoid instance vars, it gets confusing because you cannot set them
80
+ in before blocks and use them in spy blocks. Remember, spy blocks actually happen before
81
+ before blocks.
82
+ * If your tests depend on the method you are spying on returning something then you'll
83
+ need to use `and_return` in your spy block and if you have normal examples you'll also
84
+ need to stub it. Yes, this is annoying, but that's how rspec-mocks works.
85
+
86
+ ## Alternatives
87
+
88
+ * [matahari](https://github.com/mortice/matahari)
89
+ * [bourne](https://github.com/thoughtbot/bourne)
90
+ * [rspec-spies](https://github.com/technicalpickles/rspec-spies)
22
91
 
23
92
  ## Contributing
24
93
 
data/lib/rspec-spy.rb CHANGED
@@ -1,88 +1,11 @@
1
- require 'rspec-spy/version'
2
-
3
- require 'rspec/matchers'
4
- require 'rspec/mocks'
5
-
6
- RSpec::Mocks::Methods.class_eval do
7
- def should_receive_with_spy_check(*args, &block)
8
- should_receive!(*args, &block)
9
- end
10
-
11
- alias_method :should_receive!, :should_receive
12
- alias_method :should_receive, :should_receive_with_spy_check
13
-
14
- def should_not_receive_with_spy_check(*args, &block)
15
- should_not_receive!(*args, &block)
1
+ require 'rspec/spy/version'
2
+ require 'rspec/spy'
3
+ require 'rspec/spy/mock_methods'
4
+ require 'rspec/spy/example_group_methods'
5
+
6
+ RSpec.configure do |config|
7
+ config.before(:each) do |example|
8
+ example.spy_setup if example.respond_to? :spy_setup
16
9
  end
17
-
18
- alias_method :should_not_receive!, :should_not_receive
19
- alias_method :should_not_receive, :should_not_receive_with_spy_check
20
10
  end
21
11
 
22
- require 'rspec/core/hooks'
23
- module RSpec
24
- module Spy
25
- def self.included(mod)
26
- mod.extend ExampleGroupMethods
27
- end
28
-
29
- class SpyProxy
30
- def initialize(example_group)
31
- @example_group = example_group
32
- end
33
-
34
- def example_method(method, description, *args, &block)
35
- @example_group.context do
36
- let(:__spy__, &block)
37
-
38
- send(method, description, *args) do
39
- end
40
- end
41
- end
42
-
43
- [
44
- :example,
45
- :it,
46
- :specify,
47
- :focused,
48
- :focus,
49
- :pending,
50
- :xexample,
51
- :xit,
52
- :xspecify
53
- ].each do |name|
54
- module_eval(<<-END_RUBY, __FILE__, __LINE__)
55
- def #{name}(desc=nil, *args, &block)
56
- example_method(:#{name}, desc, *args, &block)
57
- end
58
- END_RUBY
59
- end
60
- end
61
-
62
- module ExampleGroupMethods
63
- def spy(&block)
64
- setup_spy_hook
65
-
66
- proxy = SpyProxy.new(self)
67
- proxy.instance_eval(&block)
68
- end
69
-
70
- private
71
- def setup_spy_hook
72
- return if @spy_hook_setup
73
-
74
- let(:__spy__) {}
75
- hook = RSpec::Core::Hooks::BeforeHook.new({}) do
76
- __spy__
77
- end
78
-
79
- hooks[:before][:each].unshift hook
80
- @spy_hook_setup = true
81
- end
82
- end
83
- end
84
- end
85
-
86
- RSpec::Core::ExampleGroup.class_eval do
87
- include RSpec::Spy
88
- end
@@ -0,0 +1,43 @@
1
+ # By putting this in lib/rspec/core it gets removed from the example file/line
2
+ # search so it can find a matching line from the backtrace
3
+ module RSpec
4
+ module Core
5
+ class SpyProxy
6
+ def initialize(example_group)
7
+ @example_group = example_group
8
+ end
9
+
10
+ def example_method(method, description, *args, &block)
11
+ @example_group.context do
12
+ let(:spy_setup) do
13
+ RSpec::Spy.in_spy_setup = true
14
+ instance_eval &block
15
+ RSpec::Spy.in_spy_setup = false
16
+ end
17
+
18
+ send(method, description, *args) do
19
+ end
20
+ end
21
+ end
22
+
23
+ [
24
+ :example,
25
+ :it,
26
+ :specify,
27
+ :focused,
28
+ :focus,
29
+ :pending,
30
+ :xexample,
31
+ :xit,
32
+ :xspecify
33
+ ].each do |name|
34
+ module_eval(<<-END_RUBY, __FILE__, __LINE__)
35
+ def #{name}(desc=nil, *args, &block)
36
+ example_method(:#{name}, desc, *args, &block)
37
+ end
38
+ END_RUBY
39
+ end
40
+ end
41
+ end
42
+ end
43
+
data/lib/rspec/spy.rb ADDED
@@ -0,0 +1,16 @@
1
+ module RSpec
2
+ module Spy
3
+ class << self
4
+ attr_accessor :in_spy_setup
5
+ attr_accessor :strict_mode
6
+ alias_method :in_spy_setup?, :in_spy_setup
7
+ alias_method :strict_mode?, :strict_mode
8
+
9
+ def ok_to_spy?
10
+ return true unless strict_mode?
11
+ in_spy_setup?
12
+ end
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,20 @@
1
+ require 'rspec/core/spy_proxy'
2
+
3
+ module RSpec
4
+ module Spy
5
+ module ExampleGroupMethods
6
+ def spy(&block)
7
+ proxy = RSpec::Core::SpyProxy.new(self)
8
+
9
+ if block
10
+ proxy.instance_eval(&block)
11
+ else
12
+ proxy
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+
19
+ RSpec::Core::ExampleGroup.extend RSpec::Spy::ExampleGroupMethods
20
+
@@ -0,0 +1,27 @@
1
+ require 'rspec/mocks'
2
+
3
+ RSpec::Mocks::Methods.class_eval do
4
+ def should_receive_with_spy_check(message, opts={}, &block)
5
+ spy_check(:should_receive)
6
+ __mock_proxy.add_message_expectation(opts[:expected_from] || caller(1)[0], message.to_sym, opts, &block)
7
+ end
8
+
9
+ def should_not_receive_with_spy_check(message, &block)
10
+ spy_check(:should_not_receive)
11
+ __mock_proxy.add_negative_message_expectation(caller(1)[0], message.to_sym, &block)
12
+ end
13
+
14
+ alias_method :should_receive!, :should_receive
15
+ alias_method :should_receive, :should_receive_with_spy_check
16
+
17
+ alias_method :should_not_receive!, :should_not_receive
18
+ alias_method :should_not_receive, :should_not_receive_with_spy_check
19
+
20
+ private
21
+
22
+ def spy_check(method)
23
+ return if RSpec::Spy.ok_to_spy?
24
+ raise "#{method} should not be used outside of a spy block. Please put it in a spy block or use #{method}!."
25
+ end
26
+ end
27
+
@@ -1,5 +1,5 @@
1
1
  module RSpec
2
2
  module Spy
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
data/rspec-spy.gemspec CHANGED
@@ -1,5 +1,5 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/rspec-spy/version', __FILE__)
2
+ require File.expand_path('../lib/rspec/spy/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
5
  gem.authors = ["Aaron Jensen"]
@@ -7,6 +7,8 @@ class Subject
7
7
  end
8
8
  end
9
9
 
10
+ RSpec::Spy.strict_mode = true
11
+
10
12
  describe RSpec::Spy do
11
13
  let(:collaborator) { stub.as_null_object }
12
14
 
@@ -28,6 +30,20 @@ describe RSpec::Spy do
28
30
  end
29
31
  end
30
32
 
33
+ spy do
34
+ specify "should work with specify" do
35
+ collaborator.should_receive :message
36
+ end
37
+ end
38
+ end
39
+
40
+ describe RSpec::Spy do
41
+ let(:collaborator) { stub.as_null_object }
42
+
43
+ before do
44
+ Subject.new.go(collaborator)
45
+ end
46
+
31
47
  context do
32
48
  spy do
33
49
  it "should work in nested contexts" do
@@ -35,10 +51,38 @@ describe RSpec::Spy do
35
51
  end
36
52
  end
37
53
  end
54
+ end
38
55
 
39
- spy do
40
- specify "should work with specify" do
41
- collaborator.should_receive :message
42
- end
56
+ describe RSpec::Spy, "the old way" do
57
+ let(:collaborator) { stub.as_null_object }
58
+
59
+ before do
60
+ collaborator.should_receive! :message
61
+ collaborator.should_not_receive! :message2
62
+ Subject.new.go(collaborator)
63
+ end
64
+
65
+ it "should still work" do
66
+ end
67
+ end
68
+
69
+ describe RSpec::Spy, "should_receive outside of spy block" do
70
+ let(:collaborator) { stub.as_null_object }
71
+
72
+ it "should warn" do
73
+ lambda { collaborator.should_receive :message }.should raise_error
74
+ lambda { collaborator.should_not_receive :message }.should raise_error
75
+ end
76
+ end
77
+
78
+ describe RSpec::Spy, "shorthand" do
79
+ let(:collaborator) { stub.as_null_object }
80
+
81
+ before do
82
+ Subject.new.go(collaborator)
83
+ end
84
+
85
+ spy.it "should work in nested contexts" do
86
+ collaborator.should_receive :message
43
87
  end
44
88
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rspec-spy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-28 00:00:00.000000000 Z
12
+ date: 2012-04-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70108880012800 !ruby/object:Gem::Requirement
16
+ requirement: &70351465973020 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '2.0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70108880012800
24
+ version_requirements: *70351465973020
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec-mocks
27
- requirement: &70108880012300 !ruby/object:Gem::Requirement
27
+ requirement: &70351465972520 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '2.0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70108880012300
35
+ version_requirements: *70351465972520
36
36
  description: Enables AAA testing for rspec-mock
37
37
  email:
38
38
  - aaronjensen@gmail.com
@@ -48,7 +48,11 @@ files:
48
48
  - README.md
49
49
  - Rakefile
50
50
  - lib/rspec-spy.rb
51
- - lib/rspec-spy/version.rb
51
+ - lib/rspec/core/spy_proxy.rb
52
+ - lib/rspec/spy.rb
53
+ - lib/rspec/spy/example_group_methods.rb
54
+ - lib/rspec/spy/mock_methods.rb
55
+ - lib/rspec/spy/version.rb
52
56
  - rspec-spy.gemspec
53
57
  - spec/rspec_spy_spec.rb
54
58
  - spec/spec_helper.rb
@@ -75,7 +79,7 @@ rubyforge_project:
75
79
  rubygems_version: 1.8.17
76
80
  signing_key:
77
81
  specification_version: 3
78
- summary: rspec-spy-0.0.1
82
+ summary: rspec-spy-0.0.2
79
83
  test_files:
80
84
  - spec/rspec_spy_spec.rb
81
85
  - spec/spec_helper.rb