rspec-spy 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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