orangutan 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README +100 -58
- data/lib/orangutan.rb +2 -2
- data/lib/orangutan/chantek.rb +86 -50
- data/lib/orangutan/container.rb +2 -2
- data/lib/orangutan/expectation.rb +75 -74
- data/lib/orangutan/mock_adapter.rb +16 -0
- data/lib/orangutan/raiser.rb +8 -9
- data/lib/orangutan/reflector.rb +21 -0
- data/lib/orangutan/stub_base.rb +33 -31
- metadata +21 -33
- data/Rakefile +0 -34
- data/VERSION.yml +0 -4
- data/orangutan.gemspec +0 -64
- data/prepare.cmd +0 -11
- data/spec/clr/ClassWithANonVirtualMethod.cs +0 -13
- data/spec/clr/ClassWithANonVirtualProperty.cs +0 -22
- data/spec/clr/ClassWithAVirtualMethod.cs +0 -13
- data/spec/clr/ClassWithAVirtualProperty.cs +0 -22
- data/spec/clr/Consumer.cs +0 -30
- data/spec/clr/IHaveAMethod.cs +0 -9
- data/spec/clr/IHaveAProperty.cs +0 -9
- data/spec/clr/IHaveAnEvent.cs +0 -9
- data/spec/spec_chantek.rb +0 -84
- data/spec/spec_chantek_clr.rb +0 -12
- data/spec/spec_chantek_recurse.rb +0 -31
- data/spec/spec_expectation.rb +0 -103
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Mark Ryall
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
CHANGED
@@ -1,59 +1,101 @@
|
|
1
|
-
Orangutan is a
|
2
|
-
|
3
|
-
It allows you to create stub objects and to
|
4
|
-
|
5
|
-
It can be used in testing .net code using ironruby.
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
1
|
+
Orangutan is a library for creating stubs.
|
2
|
+
|
3
|
+
It allows you to create stub objects and to specify methods to return and yield values as well as to raise errors.
|
4
|
+
|
5
|
+
It can be used in testing .net code using ironruby although at this stage only the simplest of clr interfaces can be stubbed.
|
6
|
+
|
7
|
+
Note that only stub instances of objects are created. It can not create mocks of class methods.
|
8
|
+
|
9
|
+
It works by recording all method calls so that assertions can be made about them after the fact and providing a simple
|
10
|
+
dsl for setting up stubbed methods (which can be used as expectations to assert on later).
|
11
|
+
|
12
|
+
Orangutan can be used with any testing framework and in combination with other mock frameworks.
|
13
|
+
|
14
|
+
Installation:
|
15
|
+
|
16
|
+
gem install orangutan
|
17
|
+
|
18
|
+
Some examples of usage (note that these are not in the context of any testing framework and are intended only to indicate how to use the api):
|
19
|
+
|
20
|
+
require 'orangutan'
|
21
|
+
|
22
|
+
include Orangutan::Chantek
|
23
|
+
|
24
|
+
reset_stubs
|
25
|
+
|
26
|
+
# Creating a pure ruby stub
|
27
|
+
@stub = stub :stub
|
28
|
+
|
29
|
+
# Creating a stub that implements a clr interface
|
30
|
+
@clr_stub = stub :clr_stub, :clr_interface => System::IDisposable
|
31
|
+
|
32
|
+
# Setting up stub methods that return values
|
33
|
+
so_when(:stub).receives(:execute).with(7).return('baz')
|
34
|
+
|
35
|
+
# Setting up stub methods that yield values
|
36
|
+
so_when(:stub).receives(:execute).with(7).yield('baz')
|
37
|
+
|
38
|
+
# Setting up stub methods that raise errors
|
39
|
+
so_when(:stub).receives(:execute).with(7).raise('baz')
|
40
|
+
|
41
|
+
# checking whether an expectation was met
|
42
|
+
expectation = so_when(:stub).receives(:execute).with(7)
|
43
|
+
puts expectation.matched? (=> false)
|
44
|
+
@stub.execute(7)
|
45
|
+
puts expectation.matched? (=> false)
|
46
|
+
|
47
|
+
# setting limits on expectations
|
48
|
+
|
49
|
+
so_when(:stub).receives(:execute).with(7).once
|
50
|
+
so_when(:stub).receives(:execute).with(7).twice
|
51
|
+
so_when(:stub).receives(:execute).with(7).exactly(4).times
|
52
|
+
|
53
|
+
# Note that once an expectation has reached its limit, it will no longer match.
|
54
|
+
# Expections will match in the order they are specified.
|
55
|
+
# This mechanism can be used to set up more complex expected call sequences:
|
56
|
+
|
57
|
+
e1 = so_when(:stub).receives(:execute).with(7).return('ok').once
|
58
|
+
e2 = so_when(:stub).receives(:execute).return('hmm').twice
|
59
|
+
|
60
|
+
puts e1.count (=> nil)
|
61
|
+
puts e2.count (=> nil)
|
62
|
+
@stub.execute(7) (=> 'ok')
|
63
|
+
puts e1.count (=> 1)
|
64
|
+
puts e2.count (=> nil)
|
65
|
+
@stub.execute(7) (=> 'hmm')
|
66
|
+
puts e1.count (=> 1)
|
67
|
+
puts e2.count (=> 1)
|
68
|
+
@stub.execute(7) (=> 'hmm')
|
69
|
+
puts e1.count (=> 1)
|
70
|
+
puts e2.count (=> 2)
|
71
|
+
@stub.execute(7) (=> nil)
|
72
|
+
puts e1.count (=> 1)
|
73
|
+
puts e2.count (=> 2)
|
74
|
+
puts e1.matched? (=> true)
|
75
|
+
puts e2.matched? (=> true)
|
76
|
+
|
77
|
+
# Checking all expectations
|
78
|
+
expectations.any? {|e| !e.matched? }
|
79
|
+
|
80
|
+
# Examining recorded method calls
|
81
|
+
calls.each {|call| puts "#{call.name}.#{call.method}(#{call.args.join(',')})" }
|
82
|
+
|
83
|
+
# Recorded call sequences can also be used for assertions in combination with or instead of checking expectations.
|
84
|
+
|
85
|
+
Questions:
|
86
|
+
|
87
|
+
* Why Orangutan?
|
88
|
+
|
89
|
+
My daughter likes orangutans and I couldn't think of a better name. Both Sumatran and Bornean orangutans are endangered species so even if you intensely dislike this project or its implementation, at least you can be made aware of the plight of these spectacular creatures.
|
90
|
+
|
91
|
+
* Did it have anything to do with Clyde in "Every Which Way But Loose"
|
92
|
+
|
93
|
+
Definately not. What a ridiculous question. I'm appalled.
|
94
|
+
|
95
|
+
* What's Chantek?
|
96
|
+
|
97
|
+
Chantek is a famous orangutan that can solve sudokus and the rubik's cube - http://en.wikipedia.org/wiki/Chantek
|
98
|
+
|
99
|
+
* Why do I not need to register this as a mock framework?
|
100
|
+
|
59
101
|
Most frameworks such as rspec's mocks, mocha and stubba replace methods on existing classes. Because this can't be done with this library - you can only create pure stub objects and setup method behaviours, there's nothing that needs to be undone at the end of a test/example.
|
data/lib/orangutan.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module Orangutan
|
2
|
-
end
|
1
|
+
module Orangutan
|
2
|
+
end
|
3
3
|
require 'orangutan/chantek'
|
data/lib/orangutan/chantek.rb
CHANGED
@@ -1,51 +1,87 @@
|
|
1
|
-
require 'orangutan/stub_base'
|
2
|
-
require 'orangutan/expectation'
|
3
|
-
require 'orangutan/call'
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
|
50
|
-
|
1
|
+
require 'orangutan/stub_base'
|
2
|
+
require 'orangutan/expectation'
|
3
|
+
require 'orangutan/call'
|
4
|
+
require 'orangutan/reflector'
|
5
|
+
|
6
|
+
module Orangutan
|
7
|
+
module Chantek
|
8
|
+
attr_reader :calls, :stubs, :expectations
|
9
|
+
|
10
|
+
def call name, method, *args
|
11
|
+
Call.new(name, method, args)
|
12
|
+
end
|
13
|
+
|
14
|
+
def reset_stubs
|
15
|
+
@calls = []
|
16
|
+
@expectations = {}
|
17
|
+
@stubs= {}
|
18
|
+
@events = {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def stub name, params={}
|
22
|
+
return @stubs[name] if @stubs[name]
|
23
|
+
clazz = Class.new(StubBase)
|
24
|
+
@events[name] = {}
|
25
|
+
implement_interface clazz, params[:clr_interface], @events[name]
|
26
|
+
@stubs[name] = clazz.new(name, self, params[:recursive])
|
27
|
+
end
|
28
|
+
|
29
|
+
def implement_interface clazz, interface, events
|
30
|
+
return unless interface
|
31
|
+
reflector = Reflector.new(interface)
|
32
|
+
clazz.instance_eval { include interface }
|
33
|
+
reflector.methods.each {|method| implement_method clazz, method }
|
34
|
+
reflector.events.each do |event|
|
35
|
+
events[event] = []
|
36
|
+
implement_event clazz, event, events[event]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def implement_method clazz, name
|
41
|
+
clazz.instance_eval do
|
42
|
+
define_method name do |*args|
|
43
|
+
yield_container, return_container = __react__(name, args)
|
44
|
+
yield_container.value.each {|v| yield *v } if yield_container && block_given?
|
45
|
+
return __return__(name, return_container)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def implement_event clazz, name, delegates
|
51
|
+
method = "add_#{name}".to_sym
|
52
|
+
clazz.instance_eval do
|
53
|
+
define_method method do |delegate|
|
54
|
+
__react__(method, [])
|
55
|
+
delegates << delegate
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def so_when name
|
61
|
+
expectations_for_name = @expectations[name]
|
62
|
+
@expectations[name] = expectations_for_name = [] unless expectations_for_name
|
63
|
+
expectation = Orangutan::Expectation.new
|
64
|
+
expectations_for_name << expectation
|
65
|
+
expectation
|
66
|
+
end
|
67
|
+
|
68
|
+
def first_match name, method, args
|
69
|
+
expectations_for_name = @expectations[name]
|
70
|
+
if expectations_for_name
|
71
|
+
expectations_for_name.each do |expectation|
|
72
|
+
return expectation if expectation.matches?(method, *args)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
|
78
|
+
def fire_event name, event, *args
|
79
|
+
events_for_name = @events[name]
|
80
|
+
raise "failed to find any events for #{name}" unless events_for_name
|
81
|
+
# it makes no sense, but 'events_for_name[event]' returns nil so in desperation, we iterate over the events
|
82
|
+
events_for_name.each do |event_name,delegates|
|
83
|
+
delegates.each { |delegate| delegate.invoke *args } if event_name == event
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
51
87
|
end
|
data/lib/orangutan/container.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
module Orangutan
|
2
|
-
Container = Struct.new(:value)
|
1
|
+
module Orangutan
|
2
|
+
Container = Struct.new(:value)
|
3
3
|
end
|
@@ -1,75 +1,76 @@
|
|
1
|
-
require 'orangutan/raiser'
|
2
|
-
require 'orangutan/container'
|
3
|
-
|
4
|
-
module Orangutan
|
5
|
-
class Expectation
|
6
|
-
attr_reader :return_container, :yield_container, :raiser, :count
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
@return_container = nil
|
10
|
-
@yield_container = nil
|
11
|
-
@raiser = nil
|
12
|
-
end
|
13
|
-
|
14
|
-
def receives method
|
15
|
-
@method = method
|
16
|
-
self
|
17
|
-
end
|
18
|
-
|
19
|
-
def with *args
|
20
|
-
@args = args
|
21
|
-
self
|
22
|
-
end
|
23
|
-
|
24
|
-
def return *value
|
25
|
-
@return_container = Container.new value
|
26
|
-
self
|
27
|
-
end
|
28
|
-
|
29
|
-
def yield *value
|
30
|
-
@yield_container
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
if
|
44
|
-
|
45
|
-
@count
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
1
|
+
require 'orangutan/raiser'
|
2
|
+
require 'orangutan/container'
|
3
|
+
|
4
|
+
module Orangutan
|
5
|
+
class Expectation
|
6
|
+
attr_reader :return_container, :yield_container, :raiser, :count
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@return_container = nil
|
10
|
+
@yield_container = nil
|
11
|
+
@raiser = nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def receives method
|
15
|
+
@method = method
|
16
|
+
self
|
17
|
+
end
|
18
|
+
|
19
|
+
def with *args
|
20
|
+
@args = args
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def return *value
|
25
|
+
@return_container = Container.new value
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def yield *value
|
30
|
+
@yield_container ||= Container.new([])
|
31
|
+
@yield_container.value << value
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def raise *args
|
36
|
+
@raiser = Raiser.new args
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
def matches? method, *args
|
41
|
+
return false unless method == @method
|
42
|
+
matched = @args ? @args == args : true
|
43
|
+
return false if @limit && @count && @count >= @limit
|
44
|
+
if matched
|
45
|
+
@count ||= 0
|
46
|
+
@count += 1
|
47
|
+
end
|
48
|
+
matched
|
49
|
+
end
|
50
|
+
|
51
|
+
def exactly count
|
52
|
+
@limit = count
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
def once
|
57
|
+
exactly 1
|
58
|
+
end
|
59
|
+
|
60
|
+
def twice
|
61
|
+
exactly 2
|
62
|
+
end
|
63
|
+
|
64
|
+
def times
|
65
|
+
self
|
66
|
+
end
|
67
|
+
|
68
|
+
def matched?
|
69
|
+
if @limit
|
70
|
+
@count && @count >= @limit
|
71
|
+
else
|
72
|
+
@count
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
75
76
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'orangutan/chantek'
|
2
|
+
|
3
|
+
module Orangutan
|
4
|
+
module MockAdapter
|
5
|
+
def setup_mocks_for_rspec
|
6
|
+
self.class.class_eval {include Orangutan::Chantek}
|
7
|
+
reset_stubs
|
8
|
+
end
|
9
|
+
|
10
|
+
def verify_mocks_for_rspec
|
11
|
+
end
|
12
|
+
|
13
|
+
def teardown_mocks_for_rspec
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/orangutan/raiser.rb
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
class Orangutan::Raiser
|
2
|
-
def initialize args
|
3
|
-
@args = args
|
4
|
-
end
|
5
|
-
|
6
|
-
def execute
|
7
|
-
|
8
|
-
|
9
|
-
end
|
1
|
+
class Orangutan::Raiser
|
2
|
+
def initialize args
|
3
|
+
@args = args
|
4
|
+
end
|
5
|
+
|
6
|
+
def execute
|
7
|
+
raise *@args
|
8
|
+
end
|
10
9
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Orangutan::Reflector
|
2
|
+
def initialize type
|
3
|
+
@type = type.to_clr_type
|
4
|
+
end
|
5
|
+
|
6
|
+
def methods
|
7
|
+
@type.get_methods.map { |info| snake info.name }
|
8
|
+
end
|
9
|
+
|
10
|
+
def properties
|
11
|
+
@type.get_properties.map { |info| snake info.name }
|
12
|
+
end
|
13
|
+
|
14
|
+
def events
|
15
|
+
@type.get_events.map { |info| info.name }
|
16
|
+
end
|
17
|
+
|
18
|
+
def snake text
|
19
|
+
text.scan(/[A-Z][a-z0-9]*/).map {|a|a.downcase}.join('_').to_sym
|
20
|
+
end
|
21
|
+
end
|
data/lib/orangutan/stub_base.rb
CHANGED
@@ -1,32 +1,34 @@
|
|
1
|
-
module Orangutan
|
2
|
-
class StubBase
|
3
|
-
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
|
4
|
-
|
5
|
-
def initialize name, parent, recursive=false
|
6
|
-
@name, @parent, @recursive = name, parent, recursive
|
7
|
-
end
|
8
|
-
|
9
|
-
def method_missing method, *args
|
10
|
-
yield_container, return_container = __react__(method, args)
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
1
|
+
module Orangutan
|
2
|
+
class StubBase
|
3
|
+
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
|
4
|
+
|
5
|
+
def initialize name, parent, recursive=false
|
6
|
+
@name, @parent, @recursive = name, parent, recursive
|
7
|
+
end
|
8
|
+
|
9
|
+
def method_missing method, *args
|
10
|
+
yield_container, return_container = __react__(method, args)
|
11
|
+
if yield_container && block_given?
|
12
|
+
yield_container.value.each {|v| yield *v }
|
13
|
+
end
|
14
|
+
__return__(method, return_container)
|
15
|
+
end
|
16
|
+
private
|
17
|
+
def __return__ method, return_container
|
18
|
+
return *return_container.value if return_container
|
19
|
+
return @parent.stub(:"#{@name}/#{method}", :recursive => true) if @recursive
|
20
|
+
nil
|
21
|
+
end
|
22
|
+
|
23
|
+
def __react__ method, args
|
24
|
+
yield_container, return_container = nil, nil
|
25
|
+
@parent.calls << Call.new(@name, method, args)
|
26
|
+
first_match = @parent.first_match(@name, method, args)
|
27
|
+
if first_match
|
28
|
+
first_match.raiser.execute if first_match.raiser
|
29
|
+
yield_container, return_container = first_match.yield_container, first_match.return_container
|
30
|
+
end
|
31
|
+
return yield_container, return_container
|
32
|
+
end
|
33
|
+
end
|
32
34
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: orangutan
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mark Ryall
|
@@ -9,48 +9,39 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-12-23 00:00:00 +11:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
|
-
description:
|
16
|
+
description: |
|
17
|
+
A mocking library that supports creation of ironruby mock objects (in addition to pure ruby ones)
|
18
|
+
|
17
19
|
email: mark@ryall.name
|
18
20
|
executables: []
|
19
21
|
|
20
22
|
extensions: []
|
21
23
|
|
22
|
-
extra_rdoc_files:
|
23
|
-
|
24
|
+
extra_rdoc_files: []
|
25
|
+
|
24
26
|
files:
|
25
|
-
- README
|
26
|
-
- Rakefile
|
27
|
-
- VERSION.yml
|
28
|
-
- lib/orangutan.rb
|
29
27
|
- lib/orangutan/call.rb
|
30
28
|
- lib/orangutan/chantek.rb
|
31
29
|
- lib/orangutan/container.rb
|
32
30
|
- lib/orangutan/expectation.rb
|
31
|
+
- lib/orangutan/mock_adapter.rb
|
33
32
|
- lib/orangutan/raiser.rb
|
33
|
+
- lib/orangutan/reflector.rb
|
34
34
|
- lib/orangutan/stub_base.rb
|
35
|
-
- orangutan.
|
36
|
-
-
|
37
|
-
-
|
38
|
-
- spec/clr/ClassWithANonVirtualProperty.cs
|
39
|
-
- spec/clr/ClassWithAVirtualMethod.cs
|
40
|
-
- spec/clr/ClassWithAVirtualProperty.cs
|
41
|
-
- spec/clr/Consumer.cs
|
42
|
-
- spec/clr/IHaveAMethod.cs
|
43
|
-
- spec/clr/IHaveAProperty.cs
|
44
|
-
- spec/clr/IHaveAnEvent.cs
|
45
|
-
- spec/spec_chantek.rb
|
46
|
-
- spec/spec_chantek_clr.rb
|
47
|
-
- spec/spec_chantek_recurse.rb
|
48
|
-
- spec/spec_expectation.rb
|
35
|
+
- lib/orangutan.rb
|
36
|
+
- README
|
37
|
+
- MIT-LICENSE
|
49
38
|
has_rdoc: true
|
50
39
|
homepage: http://github.com/markryall/orangutan
|
40
|
+
licenses: []
|
41
|
+
|
51
42
|
post_install_message:
|
52
|
-
rdoc_options:
|
53
|
-
|
43
|
+
rdoc_options: []
|
44
|
+
|
54
45
|
require_paths:
|
55
46
|
- lib
|
56
47
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -67,13 +58,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
67
58
|
version:
|
68
59
|
requirements: []
|
69
60
|
|
70
|
-
rubyforge_project:
|
71
|
-
rubygems_version: 1.3.
|
61
|
+
rubyforge_project:
|
62
|
+
rubygems_version: 1.3.5
|
72
63
|
signing_key:
|
73
|
-
specification_version:
|
64
|
+
specification_version: 3
|
74
65
|
summary: A mock objects library
|
75
|
-
test_files:
|
76
|
-
|
77
|
-
- spec/spec_chantek_clr.rb
|
78
|
-
- spec/spec_chantek_recurse.rb
|
79
|
-
- spec/spec_expectation.rb
|
66
|
+
test_files: []
|
67
|
+
|
data/Rakefile
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
desc 'build necessary assemblies for tests'
|
2
|
-
task 'spec/ClassLibrary.dll' => FileList["spec/**/*.cs"] do
|
3
|
-
system "csc /target:library /out:spec\\ClassLibrary.dll spec\\clr\\*.cs"
|
4
|
-
end
|
5
|
-
|
6
|
-
task :compile => 'spec/ClassLibrary.dll'
|
7
|
-
|
8
|
-
desc 'run specs with bacon on ironruby'
|
9
|
-
task :bacon => :compile do
|
10
|
-
system "ibacon -Ispec -a"
|
11
|
-
end
|
12
|
-
|
13
|
-
(1..4).each do |i|
|
14
|
-
desc "run spike #{i}"
|
15
|
-
task "spike#{i}" do
|
16
|
-
system "ir -I spec -I spikes spikes\\experiment#{i}.rb"
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
begin
|
21
|
-
require 'jeweler'
|
22
|
-
Jeweler::Tasks.new do |gemspec|
|
23
|
-
gemspec.name = "orangutan"
|
24
|
-
gemspec.summary = "A mock objects library"
|
25
|
-
gemspec.email = "mark@ryall.name"
|
26
|
-
gemspec.homepage = "http://github.com/markryall/orangutan"
|
27
|
-
gemspec.description = "A mocking library that supports creation of ironruby mock objects (in addition to pure ruby ones)"
|
28
|
-
gemspec.files = FileList["[A-Z]*", "{lib,spec}/**/*.{rb,cs}"]
|
29
|
-
gemspec.authors = ["Mark Ryall"]
|
30
|
-
gemspec.rubyforge_project = 'orangutan'
|
31
|
-
end
|
32
|
-
rescue LoadError
|
33
|
-
puts "Jeweler not available. Install it with: sudo gem install jeweler"
|
34
|
-
end
|
data/VERSION.yml
DELETED
data/orangutan.gemspec
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
|
3
|
-
Gem::Specification.new do |s|
|
4
|
-
s.name = %q{orangutan}
|
5
|
-
s.version = "0.0.4"
|
6
|
-
|
7
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
-
s.authors = ["Mark Ryall"]
|
9
|
-
s.date = %q{2009-05-13}
|
10
|
-
s.description = %q{A mocking library that supports creation of ironruby mock objects (in addition to pure ruby ones)}
|
11
|
-
s.email = %q{mark@ryall.name}
|
12
|
-
s.extra_rdoc_files = [
|
13
|
-
"README"
|
14
|
-
]
|
15
|
-
s.files = [
|
16
|
-
"README",
|
17
|
-
"Rakefile",
|
18
|
-
"VERSION.yml",
|
19
|
-
"lib/orangutan.rb",
|
20
|
-
"lib/orangutan/call.rb",
|
21
|
-
"lib/orangutan/chantek.rb",
|
22
|
-
"lib/orangutan/container.rb",
|
23
|
-
"lib/orangutan/expectation.rb",
|
24
|
-
"lib/orangutan/raiser.rb",
|
25
|
-
"lib/orangutan/stub_base.rb",
|
26
|
-
"orangutan.gemspec",
|
27
|
-
"prepare.cmd",
|
28
|
-
"spec/clr/ClassWithANonVirtualMethod.cs",
|
29
|
-
"spec/clr/ClassWithANonVirtualProperty.cs",
|
30
|
-
"spec/clr/ClassWithAVirtualMethod.cs",
|
31
|
-
"spec/clr/ClassWithAVirtualProperty.cs",
|
32
|
-
"spec/clr/Consumer.cs",
|
33
|
-
"spec/clr/IHaveAMethod.cs",
|
34
|
-
"spec/clr/IHaveAProperty.cs",
|
35
|
-
"spec/clr/IHaveAnEvent.cs",
|
36
|
-
"spec/spec_chantek.rb",
|
37
|
-
"spec/spec_chantek_clr.rb",
|
38
|
-
"spec/spec_chantek_recurse.rb",
|
39
|
-
"spec/spec_expectation.rb"
|
40
|
-
]
|
41
|
-
s.has_rdoc = true
|
42
|
-
s.homepage = %q{http://github.com/markryall/orangutan}
|
43
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
44
|
-
s.require_paths = ["lib"]
|
45
|
-
s.rubyforge_project = %q{orangutan}
|
46
|
-
s.rubygems_version = %q{1.3.1}
|
47
|
-
s.summary = %q{A mock objects library}
|
48
|
-
s.test_files = [
|
49
|
-
"spec/spec_chantek.rb",
|
50
|
-
"spec/spec_chantek_clr.rb",
|
51
|
-
"spec/spec_chantek_recurse.rb",
|
52
|
-
"spec/spec_expectation.rb"
|
53
|
-
]
|
54
|
-
|
55
|
-
if s.respond_to? :specification_version then
|
56
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
57
|
-
s.specification_version = 2
|
58
|
-
|
59
|
-
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
60
|
-
else
|
61
|
-
end
|
62
|
-
else
|
63
|
-
end
|
64
|
-
end
|
data/prepare.cmd
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
using System;
|
2
|
-
|
3
|
-
namespace ClassLibrary
|
4
|
-
{
|
5
|
-
public class ClassWithANonVirtualProperty : IHaveAProperty
|
6
|
-
{
|
7
|
-
private string _MyProperty;
|
8
|
-
public string MyProperty
|
9
|
-
{
|
10
|
-
get
|
11
|
-
{
|
12
|
-
Console.WriteLine("clr getter called");
|
13
|
-
return _MyProperty;
|
14
|
-
}
|
15
|
-
set
|
16
|
-
{
|
17
|
-
Console.WriteLine("clr setter called");
|
18
|
-
_MyProperty = value;
|
19
|
-
}
|
20
|
-
}
|
21
|
-
}
|
22
|
-
}
|
@@ -1,22 +0,0 @@
|
|
1
|
-
using System;
|
2
|
-
|
3
|
-
namespace ClassLibrary
|
4
|
-
{
|
5
|
-
public class ClassWithAVirtualProperty : IHaveAProperty
|
6
|
-
{
|
7
|
-
private string _MyProperty;
|
8
|
-
public virtual string MyProperty
|
9
|
-
{
|
10
|
-
get
|
11
|
-
{
|
12
|
-
Console.WriteLine("clr getter called");
|
13
|
-
return _MyProperty;
|
14
|
-
}
|
15
|
-
set
|
16
|
-
{
|
17
|
-
Console.WriteLine("clr setter called");
|
18
|
-
_MyProperty = value;
|
19
|
-
}
|
20
|
-
}
|
21
|
-
}
|
22
|
-
}
|
data/spec/clr/Consumer.cs
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
using System;
|
2
|
-
|
3
|
-
namespace ClassLibrary
|
4
|
-
{
|
5
|
-
public class Consumer
|
6
|
-
{
|
7
|
-
private int count = 0;
|
8
|
-
|
9
|
-
public void CallMethod(IHaveAMethod consumable)
|
10
|
-
{
|
11
|
-
consumable.MyMethod("thing");
|
12
|
-
}
|
13
|
-
|
14
|
-
public void RegisterEvent(IHaveAnEvent e)
|
15
|
-
{
|
16
|
-
e.MyEvent += (s,ev) => Console.WriteLine(s);
|
17
|
-
}
|
18
|
-
|
19
|
-
public void CallSetter(IHaveAProperty p)
|
20
|
-
{
|
21
|
-
p.MyProperty = ""+count;
|
22
|
-
count++;
|
23
|
-
}
|
24
|
-
|
25
|
-
public void CallGetter(IHaveAProperty p)
|
26
|
-
{
|
27
|
-
Console.WriteLine(p.MyProperty);
|
28
|
-
}
|
29
|
-
}
|
30
|
-
}
|
data/spec/clr/IHaveAMethod.cs
DELETED
data/spec/clr/IHaveAProperty.cs
DELETED
data/spec/clr/IHaveAnEvent.cs
DELETED
data/spec/spec_chantek.rb
DELETED
@@ -1,84 +0,0 @@
|
|
1
|
-
require 'orangutan'
|
2
|
-
|
3
|
-
describe Orangutan::Chantek, 'creating ruby stubs' do
|
4
|
-
before do
|
5
|
-
@o = Orangutan::Chantek.new
|
6
|
-
@foo = @o.stub :foo
|
7
|
-
end
|
8
|
-
|
9
|
-
it 'should record method calls and their parameters on a stub' do
|
10
|
-
@foo.method1(1,2,3)
|
11
|
-
@o.calls[0].should == Orangutan::Call.new(:foo, :method1, [1,2,3])
|
12
|
-
end
|
13
|
-
|
14
|
-
it 'should record all ordinary object methods calls (except __send__ and __id__)' do
|
15
|
-
methods = Object.new.methods
|
16
|
-
methods.each { |m| @foo.__send__(m.to_sym) unless m =~ /^__/ }
|
17
|
-
@o.calls.length.should == (methods.length-2)
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'should allow method return values to be stubbed' do
|
21
|
-
@o.when(:foo).receives(:bar).return('baz')
|
22
|
-
@foo.bar.should == 'baz'
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'should allow multiple method return values to be stubbed' do
|
26
|
-
@o.when(:foo).receives(:bar).return('baz', 'bat')
|
27
|
-
@foo.bar.should == ['baz', 'bat']
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'should allow method return values to be stubbed for method invocations with specific arguments' do
|
31
|
-
@o.when(:foo).receives(:bar).with(7).return('baz')
|
32
|
-
@foo.bar(7).should == 'baz'
|
33
|
-
end
|
34
|
-
|
35
|
-
it 'should not match method invocations with incorrect specific arguments' do
|
36
|
-
@o.when(:foo).receives(:bar).with(7).return('baz')
|
37
|
-
@foo.bar(8).should == nil
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'should allow method return values to be stubbed for method invocations with multiple specific arguments' do
|
41
|
-
@o.when(:foo).receives(:bar).with(7,8).return('baz')
|
42
|
-
@foo.bar(7,8).should == 'baz'
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'should allow stubbed methods to yield' do
|
46
|
-
@o.when(:foo).receives(:bar).with(7).yield('baz')
|
47
|
-
@foo.bar(7) do |v|
|
48
|
-
v.should == 'baz'
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'should allow stubbed methods to yield multiple values' do
|
53
|
-
@o.when(:foo).receives(:bar).with(7).yield('baz', 'bar')
|
54
|
-
@foo.bar(7) do |a,b|
|
55
|
-
a.should == 'baz'
|
56
|
-
b.should == 'bar'
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'should allow stubbed methods to yield nils' do
|
61
|
-
@o.when(:foo).receives(:bar).yield(nil)
|
62
|
-
called = false
|
63
|
-
@foo.bar {|s| called = true}
|
64
|
-
called.should == true
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'should allow stubbed methods to raise error from string' do
|
68
|
-
@o.when(:foo).receives(:bar).raise("you can't be serious")
|
69
|
-
begin
|
70
|
-
@foo.bar
|
71
|
-
rescue RuntimeError => e
|
72
|
-
e.message.should == "you can't be serious"
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'should allow stubbed methods to raise error from string' do
|
77
|
-
@o.when(:foo).receives(:bar).raise(RuntimeError, "you can't be serious")
|
78
|
-
begin
|
79
|
-
@foo.bar
|
80
|
-
rescue RuntimeError => e
|
81
|
-
e.message.should == "you can't be serious"
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
data/spec/spec_chantek_clr.rb
DELETED
@@ -1,12 +0,0 @@
|
|
1
|
-
require 'orangutan'
|
2
|
-
require 'ClassLibrary.dll'
|
3
|
-
|
4
|
-
describe Orangutan::Chantek, 'creating clr stubs' do
|
5
|
-
it 'should create stub implementations of a clr interface with a method' do
|
6
|
-
o = Orangutan::Chantek.new
|
7
|
-
s = o.stub :foo, :clr_interface => ClassLibrary::IHaveAMethod
|
8
|
-
c = ClassLibrary::Consumer.new
|
9
|
-
c.call_method(s)
|
10
|
-
o.calls[0].should == Orangutan::Call.new(:foo, :my_method, ['thing'])
|
11
|
-
end
|
12
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require 'orangutan'
|
2
|
-
|
3
|
-
module Orangutan
|
4
|
-
describe Chantek, 'creating recursive ruby stubs' do
|
5
|
-
before do
|
6
|
-
@o = Chantek.new
|
7
|
-
@foo = @o.stub :foo, :recursive => true
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should return the same object when generating a stub for the same name" do
|
11
|
-
@foo.__id__.should. == @o.stub(:foo).__id__
|
12
|
-
end
|
13
|
-
|
14
|
-
it "should return nil instead of new stub when instructed to" do
|
15
|
-
@o.when(:foo).receives(:bar).return(nil)
|
16
|
-
@foo.bar.should == nil
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should return new stubs from each method call" do
|
20
|
-
bar = @foo.bar
|
21
|
-
baz = bar.baz
|
22
|
-
@o.calls[0].should == Call.new(:foo, :bar,[])
|
23
|
-
@o.calls[1].should == Call.new(:"foo/bar", :baz,[])
|
24
|
-
end
|
25
|
-
|
26
|
-
it "should create recursive stubs" do
|
27
|
-
@foo.a.b.c
|
28
|
-
@o.stubs.keys.should == [:foo, :"foo/a", :"foo/a/b", :"foo/a/b/c"]
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
data/spec/spec_expectation.rb
DELETED
@@ -1,103 +0,0 @@
|
|
1
|
-
require 'orangutan'
|
2
|
-
|
3
|
-
module Orangutan
|
4
|
-
describe Expectation do
|
5
|
-
before do
|
6
|
-
@e = Expectation.new.receives(:foo)
|
7
|
-
end
|
8
|
-
|
9
|
-
it 'should not match when method is different' do
|
10
|
-
@e.matches?(:bar).should == false
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'should match when method matches and args are unspecified' do
|
14
|
-
@e.matches?(:foo).should == true
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'should match when method matches and args match' do
|
18
|
-
@e.with(7).matches?(:foo, 7).should == true
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'should not match when method matches but args do not match' do
|
22
|
-
@e.with(7).matches?(:foo, 8).should == false
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'should not yield by default' do
|
26
|
-
@e.yield_container.should == nil
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'should store yield value' do
|
30
|
-
@e.yield(1).yield_container.should == Container.new([1])
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'should store multiple yield values' do
|
34
|
-
@e.yield(1,2).yield_container.should == Container.new([1,2])
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'should not return by default' do
|
38
|
-
@e.return_container.should == nil
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'should store return value' do
|
42
|
-
@e.return(1).return_container.should == Container.new([1])
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'should store multiple return values' do
|
46
|
-
@e.return(1,2).return_container.should == Container.new([1,2])
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'should not raise by default' do
|
50
|
-
@e.raiser.should == nil
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'should store raiser' do
|
54
|
-
@e.raise('description').raiser.should.not == nil
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'should count matches' do
|
58
|
-
(1..10).each do |i|
|
59
|
-
@e.matches?(:foo)
|
60
|
-
@e.count.should == i
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'should limit matches when given limit of once' do
|
65
|
-
@e.once.should == @e
|
66
|
-
@e.matches?(:foo).should == true
|
67
|
-
@e.matches?(:foo).should == false
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'should limit matches when given limit of twice' do
|
71
|
-
@e.twice.should == @e
|
72
|
-
2.times { @e.matches?(:foo).should == true }
|
73
|
-
@e.matches?(:foo).should == false
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'should limit matches' do
|
77
|
-
@e.exactly(10).times.should == @e
|
78
|
-
10.times { @e.matches?(:foo).should == true }
|
79
|
-
@e.matches?(:foo).should == false
|
80
|
-
end
|
81
|
-
|
82
|
-
it 'should initially indicate that expectation was not matched' do
|
83
|
-
@e.should.not.be.matched?
|
84
|
-
end
|
85
|
-
|
86
|
-
it 'should when no limit specified indicate that the expectation was matched once' do
|
87
|
-
@e.matches?(:foo)
|
88
|
-
@e.should.be.matched?
|
89
|
-
end
|
90
|
-
|
91
|
-
it 'should when a limit specified indicate that the expectation was not matched until the is limit reached' do
|
92
|
-
@e.twice
|
93
|
-
@e.matches?(:foo)
|
94
|
-
@e.should.not.be.matched?
|
95
|
-
end
|
96
|
-
|
97
|
-
it 'should when a limit specified indicate that the expectation was matched once the is limit reached' do
|
98
|
-
@e.twice
|
99
|
-
2.times { @e.matches?(:foo) }
|
100
|
-
@e.should.be.matched?
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|