matahari 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -1,6 +1,6 @@
1
1
  = matahari
2
2
 
3
- * https://github.com/mortice/matahari
3
+ * http://tomstuart.co.uk/2011/06/05/mocks-suck-matahari-sucks-less.html
4
4
 
5
5
  == DESCRIPTION:
6
6
 
@@ -10,8 +10,7 @@ It is designed to allow you to test interactions between objects *without* requi
10
10
  you to specify all method calls, including uninteresting ones.
11
11
 
12
12
  == SYNOPSIS:
13
-
14
- require 'matahari'
13
+ Matahari allows you to do this (RSpec example)
15
14
 
16
15
  describe "my object" do
17
16
  obj = MyAwesomeObject.new
@@ -23,7 +22,24 @@ you to specify all method calls, including uninteresting ones.
23
22
  collaborator.should have_received(3.times).some_interesting_method("Some", "arguments")
24
23
  end
25
24
 
26
- See also the cucumber feature, easily viewable at http://relishapp.com/Mortice/matahari
25
+ See also the cucumber features, easily viewable at http://relishapp.com/mortice/matahari
26
+
27
+ == USING:
28
+
29
+ === RSpec
30
+
31
+ In your spec_helper, include this:
32
+
33
+ RSpec.configure do |config|
34
+ config.include Matahari::Adapters::RSpec
35
+ end
36
+
37
+ === test/unit
38
+ In your test_helper, include this:
39
+
40
+ class Test::Unit::TestCase
41
+ include Matahari::Adapters::TestUnit
42
+ end
27
43
 
28
44
  == CONTEXT:
29
45
 
data/lib/matahari.rb CHANGED
@@ -1,14 +1,9 @@
1
1
  $:.unshift(File.dirname(__FILE__)) unless
2
2
  $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
3
 
4
- module Matahari
5
- VERSION = '0.1.1'
6
- end
7
-
8
4
  require 'matahari/spy'
9
5
  require 'matahari/debriefing'
10
- require 'matahari/rspec/matchers'
11
-
12
- def spy(name = nil)
13
- Spy.new(name)
14
- end
6
+ require 'matahari/adapters/matahari_methods'
7
+ require 'matahari/adapters/rspec'
8
+ require 'matahari/adapters/test_unit'
9
+ require 'matahari/version'
@@ -0,0 +1,9 @@
1
+ module Matahari
2
+ module Adapters
3
+ module MatahariMethods
4
+ def spy(name = nil)
5
+ Spy.new(name)
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ module Matahari
2
+ module Adapters
3
+ module RSpec
4
+ include Matahari::Adapters::MatahariMethods
5
+
6
+ def have_received(times = nil)
7
+ if times
8
+ @calls_expected = 0
9
+ times.each { @calls_expected+= 1 }
10
+
11
+ Debriefing.new(@calls_expected)
12
+ else
13
+ Debriefing.new
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ module Matahari
2
+ module Adapters
3
+ module TestUnit
4
+ include Matahari::Adapters::MatahariMethods
5
+
6
+ def assert_received(subject, &block)
7
+ result = block.call
8
+ assert result.matches?(subject), result.failure_message_for_should
9
+ end
10
+
11
+ def assert_not_received(subject, &block)
12
+ result = block.call
13
+ assert !result.matches?(subject), result.failure_message_for_should_not
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,4 +1,11 @@
1
1
  class Debriefing
2
+
3
+ #TODO I can't work out how to disentangle the 2 responsibilities of this class:
4
+ #1. Inspecting and acting on spy invocations
5
+ #2. Presenting the results of those inspections.
6
+ #
7
+ #One to revisit later when my head is less befuddled.
8
+
2
9
  def initialize(expected_call_count = nil)
3
10
  @expected_call_count = expected_call_count
4
11
  end
@@ -23,6 +30,9 @@ class Debriefing
23
30
  end
24
31
  end
25
32
 
33
+ #Allows chaining of method calls following has_received?/should have_received,
34
+ #e.g. spy.should_have received.some_method, where #some_method is handled by
35
+ #method_missing, its arguments and name being stored until #matches? is called.
26
36
  def method_missing(sym, *args, &block)
27
37
  @call_to_verify = sym
28
38
  @args_to_verify = args
data/lib/matahari/spy.rb CHANGED
@@ -5,12 +5,23 @@ class Spy
5
5
  @name = name if name
6
6
  @invocations = []
7
7
  @stubbed_calls = {}
8
+ self.class.instance_methods.each do |meth|
9
+ next if [:define_method, :stubs, :method_missing, :record_invocation].include?(meth)
10
+ end
11
+ class << self
12
+ instance_methods.each do |meth|
13
+ next if [:name, :define_method, :stubs, :method_missing, :record_invocation, :invocations, :has_received?, :object_id, :respond_to?, :respond_to_missing?, :instance_eval, :instance_exec, :class_eval, :__send__, :send, :should, :should_not].include?(meth)
14
+ undef_method(meth)
15
+ end
16
+ end
8
17
  end
9
18
 
19
+ #When a given method call, sym, is invoked on self, call block and return its result
10
20
  def stubs(sym, &block)
11
21
  @stubbed_calls[sym] = block
12
22
  end
13
23
 
24
+ #Captures the details of any method call and store for later inspection
14
25
  def method_missing(sym, *args, &block)
15
26
  if @verifying
16
27
  raise
@@ -20,12 +31,16 @@ class Spy
20
31
  end
21
32
  end
22
33
 
34
+ #Pass an iterator to this method to specify the number of times the method should
35
+ #have been called. E.g. spy.has_received?(3.times). While other iterators might work,
36
+ #the idea is to allow this nice DSL-ish way of asserting on the number of calls, hence
37
+ #the odd method signature.
23
38
  def has_received?(times=nil)
24
39
  if times
25
- @calls_expected = 0
26
- times.each { @calls_expected+= 1 }
40
+ calls_expected = 0
41
+ times.each { calls_expected += 1 }
27
42
 
28
- Debriefing.new(@calls_expected)
43
+ Debriefing.new(calls_expected)
29
44
  else
30
45
  Debriefing.new
31
46
  end
@@ -0,0 +1,3 @@
1
+ module Matahari
2
+ VERSION = "0.2.0"
3
+ end
metadata CHANGED
@@ -1,103 +1,88 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: matahari
3
- version: !ruby/object:Gem::Version
4
- hash: 31
5
- prerelease: false
6
- segments:
7
- - 0
8
- - 1
9
- - 2
10
- version: 0.1.2
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.0
5
+ prerelease:
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Tom Stuart
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2011-01-13 00:00:00 +00:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2011-06-10 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: rspec
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &2157293000 !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 3
30
- segments:
31
- - 0
32
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
33
22
  type: :development
34
- version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
23
+ prerelease: false
24
+ version_requirements: *2157293000
25
+ - !ruby/object:Gem::Dependency
36
26
  name: cucumber
27
+ requirement: &2157292460 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
37
34
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
35
+ version_requirements: *2157292460
36
+ - !ruby/object:Gem::Dependency
37
+ name: aruba
38
+ requirement: &2157292040 !ruby/object:Gem::Requirement
39
39
  none: false
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- hash: 3
44
- segments:
45
- - 0
46
- version: "0"
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
47
44
  type: :development
48
- version_requirements: *id002
49
- description:
50
- email: tom@therye.org
45
+ prerelease: false
46
+ version_requirements: *2157292040
47
+ description: Matahari provides test spies for Ruby
48
+ email:
49
+ - tom@therye.org
51
50
  executables: []
52
-
53
51
  extensions: []
54
-
55
- extra_rdoc_files:
56
- - README.rdoc
57
- files:
58
- - README.rdoc
59
- - test/spy_test.rb
60
- - spec/debriefing_spec.rb
61
- - spec/spec_helper.rb
62
- - spec/spy_spec.rb
52
+ extra_rdoc_files: []
53
+ files:
54
+ - lib/matahari/adapters/matahari_methods.rb
55
+ - lib/matahari/adapters/rspec.rb
56
+ - lib/matahari/adapters/test_unit.rb
63
57
  - lib/matahari/debriefing.rb
64
- - lib/matahari/rspec/matchers.rb
65
58
  - lib/matahari/spy.rb
59
+ - lib/matahari/version.rb
66
60
  - lib/matahari.rb
67
- has_rdoc: true
61
+ - README.rdoc
68
62
  homepage: https://github.com/mortice/matahari
69
63
  licenses: []
70
-
71
64
  post_install_message:
72
- rdoc_options:
65
+ rdoc_options:
73
66
  - --main
74
67
  - README.rdoc
75
- require_paths:
68
+ require_paths:
76
69
  - lib
77
- required_ruby_version: !ruby/object:Gem::Requirement
70
+ required_ruby_version: !ruby/object:Gem::Requirement
78
71
  none: false
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- hash: 3
83
- segments:
84
- - 0
85
- version: "0"
86
- required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
77
  none: false
88
- requirements:
89
- - - ">="
90
- - !ruby/object:Gem::Version
91
- hash: 3
92
- segments:
93
- - 0
94
- version: "0"
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: 1.3.6
95
82
  requirements: []
96
-
97
83
  rubyforge_project:
98
- rubygems_version: 1.3.7
84
+ rubygems_version: 1.8.5
99
85
  signing_key:
100
86
  specification_version: 3
101
87
  summary: Test spy library, inspired by Mockito and RR
102
88
  test_files: []
103
-
@@ -1,10 +0,0 @@
1
- def have_received(times = nil)
2
- if times
3
- @calls_expected = 0
4
- times.each { @calls_expected+= 1 }
5
-
6
- Debriefing.new(@calls_expected)
7
- else
8
- Debriefing.new
9
- end
10
- end
@@ -1,86 +0,0 @@
1
- require 'spec_helper'
2
- describe Debriefing do
3
- it "matches simple invocations" do
4
- #we have to use rspec mocks here because testing matahari with matahari
5
- #makes my brain hurt
6
-
7
- subject = mock(:subject)
8
- debriefing = Debriefing.new
9
-
10
- subject.should_receive(:invocations).and_return([{:method => :one, :args => [[]]}])
11
-
12
- debriefing.one
13
-
14
- debriefing.matches?(subject).should be_true
15
- end
16
-
17
- it "matches invocations based on arguments" do
18
- subject = mock(:subject)
19
- correct_debriefing = Debriefing.new
20
- incorrect_debriefing = Debriefing.new
21
-
22
- subject.should_receive(:invocations).twice.and_return([{:method => :one, :args => [["Hello", "goodbye"]]}])
23
-
24
- correct_debriefing.one("Hello", "goodbye")
25
- incorrect_debriefing.one("Hello", "goodbye", "Hello again")
26
-
27
- correct_debriefing.matches?(subject).should be_true
28
- incorrect_debriefing.matches?(subject).should be_false
29
- end
30
-
31
- it "gives a failure message for should when method not called" do
32
- subject = mock(:subject)
33
- debriefing = Debriefing.new
34
-
35
- subject.should_receive(:invocations).and_return([{:method => :one, :args => [[]]}])
36
- subject.should_receive(:name).and_return(:subject)
37
-
38
- debriefing.two
39
-
40
- debriefing.matches?(subject).should be_false
41
-
42
- debriefing.failure_message_for_should.should == "Spy(:subject) expected to receive :two once, received 0 times"
43
- end
44
-
45
- it "gives a failure message for should when method called with wrong arguments" do
46
- subject = mock(:subject)
47
- debriefing = Debriefing.new
48
-
49
- subject.should_receive(:invocations).and_return([{:method => :one, :args => [[]]}])
50
- subject.should_receive(:name).and_return(:subject)
51
-
52
- debriefing.one("Hello")
53
-
54
- debriefing.matches?(subject).should be_false
55
-
56
- debriefing.failure_message_for_should.should == "Spy(:subject) expected to receive :one(\"Hello\") once, received 0 times"
57
- end
58
-
59
- it "gives a failure message for should when method called wrong number of times" do
60
- subject = mock(:subject)
61
- debriefing = Debriefing.new(2)
62
-
63
- subject.should_receive(:invocations).and_return([{:method => :one, :args => [[]]}])
64
- subject.should_receive(:name).and_return(:subject)
65
-
66
- debriefing.one
67
-
68
- debriefing.matches?(subject).should be_false
69
-
70
- debriefing.failure_message_for_should.should == "Spy(:subject) expected to receive :one twice, received once"
71
- end
72
-
73
- it "gives a failure message for should not" do
74
- subject = mock(:subject)
75
- debriefing = Debriefing.new
76
-
77
- subject.should_receive(:invocations).and_return([{:method => :two, :args => [[]]}])
78
- subject.should_receive(:name).and_return(:subject)
79
-
80
- debriefing.two
81
-
82
- debriefing.matches?(subject).should be_true
83
-
84
- debriefing.failure_message_for_should_not.should == "Spy(:subject) expected not to receive :two but received it once"
85
- end
86
- end
data/spec/spec_helper.rb DELETED
@@ -1,2 +0,0 @@
1
- require File.dirname(__FILE__) + "/../lib/matahari"
2
- require 'rspec'
data/spec/spy_spec.rb DELETED
@@ -1,49 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Spy" do
4
- it "takes an optional name parameter" do
5
- named = Spy.new(:bond)
6
- unnamed = Spy.new
7
-
8
- named.name.should == :bond
9
- unnamed.name.should == nil
10
- end
11
-
12
- context "in the field" do
13
- it "remains as a sleeper agent until called upon" do
14
- mata_hari = Spy.new(:mata_hari)
15
- lambda do
16
- mata_hari.one
17
- mata_hari.two
18
- mata_hari.three
19
- end.should_not raise_error NoMethodError
20
- end
21
-
22
- it "captures communications" do
23
- mata_hari = Spy.new(:mata_hari)
24
-
25
- mata_hari.one
26
- mata_hari.two
27
-
28
- mata_hari.invocations.should == [{:method => :one, :args => [[]]}, {:method => :two, :args => [[]]}]
29
- end
30
-
31
- it "captures the details of communications" do
32
- mata_hari = Spy.new(:mata_hari)
33
-
34
- mata_hari.one
35
- mata_hari.two("Hello")
36
-
37
- mata_hari.invocations.should == [{:method => :one, :args => [[]]}, {:method => :two, :args => [["Hello"]]}]
38
- end
39
-
40
- it "doesn't stop you stubbing" do
41
- mata_hari = Spy.new(:mata_hari)
42
-
43
- mata_hari.stubs(:test) { "Hello" }
44
-
45
- mata_hari.test.should == "Hello"
46
- mata_hari.invocations.should == [{:method => :test, :args => [[]]}]
47
- end
48
- end
49
- end
data/test/spy_test.rb DELETED
@@ -1,16 +0,0 @@
1
- require 'test/unit'
2
- require 'matahari'
3
-
4
- class SpyTest < Test::Unit::TestCase
5
- #minimal test to make sure we stay compatible. For full tests, see spec/
6
- def test_matahari_works_with_test_unit
7
- mata_hari = spy(:mata_hari)
8
-
9
- mata_hari.one
10
-
11
- #I know this syntax sucks but at least it shows you don't *need* rspec to use matahari.
12
- #TODO make an assert_received method for test/unit
13
- assert mata_hari.has_received?.one.matches?(mata_hari)
14
- assert !mata_hari.has_received?.two.matches?(mata_hari)
15
- end
16
- end