matahari 0.1.2 → 0.2.0

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.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