mutle-smartmock 0.0.1

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.
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Mutwin Kraus
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 NONINFRINGEMENT.
17
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,69 @@
1
+ = Smartmock
2
+
3
+ == What is Smartmock?
4
+
5
+ Don't you hate how dumb your Model Mocks are sometimes? Little changes to your implementation can break your specs, as mocking forces you to test your implementation and not the results.
6
+
7
+ Well, no more.
8
+
9
+ Smartmock lets you focus on the results of your code instead of the implementation.
10
+
11
+ Plus it works with ActiveRecord as well as DataMapper.
12
+
13
+ == Status
14
+
15
+ Development of Smartmock just got started, and a lot is still missing. If you want to contribute, feel free to fork Smartmock on GitHub (<http://gitub.com/mutle/smartmock>) and send a pull request.
16
+
17
+ == Examples
18
+
19
+ To demonstrate, here is some code that shows the usage of Smartmock in a Merb Controller spec.
20
+
21
+ With Smartmock:
22
+
23
+ describe Users, "create action" do
24
+ before(:each) do
25
+ smartmock_next User
26
+ end
27
+
28
+ it "should create a user and save the attributes" do
29
+ controller = dispatch_to(Users, :create, {:user => {:login => "test"}})
30
+ User.last_smartmock.login.should == "test" # Verifies that the attributes get assigned
31
+ User.last_smartmock.should_not be_dirty # Verifies that the object was saved
32
+ end
33
+ end
34
+
35
+ Without Smartmock:
36
+
37
+ describe Users, "show action" do
38
+ before(:each) do
39
+ @user = mock("User", :to_xml => "XML")
40
+ end
41
+
42
+ it "should create a user and save the attributes" do
43
+ User.should_receive(:new).with("login" => "test').and_return(@user)
44
+ @user.should_receive!(:save).and_return(true)
45
+ controller = dispatch_to(Users, :create, {:user => {:login => "test"}})
46
+ end
47
+ end
48
+
49
+
50
+ == How to use
51
+
52
+ require 'rubygems'
53
+ gem 'mutle-smartmock'
54
+ require 'smartmock'
55
+
56
+ user = Smartmock[User].new(:login => 'mutle')
57
+ user.name = 'Mutwin Kraus' # Smartmock adds methods for all attributes of the mocked model
58
+ user.dirty? # => true
59
+ user.save # This doesn't write anything to the database
60
+ user.dirty? # => false
61
+
62
+ == Installation
63
+
64
+ gem source --add http://gems.github.com/
65
+ gem install mutle-smartmock
66
+
67
+ == Authors
68
+
69
+ Smartmock is written by Mutwin Kraus (<http://gitub.com/mutle>).
@@ -0,0 +1,4 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'smartmock/mock'
4
+ require 'smartmock/helpers'
@@ -0,0 +1,120 @@
1
+ module Smartmock
2
+
3
+ module Next
4
+ module ClassMethods
5
+ def smartmock_new(attribs={})
6
+ @last_mock = Mock.new(self, attribs)
7
+ if @smartmock_stubs
8
+ @last_mock.stubs = @smartmock_stubs
9
+ end
10
+ revert_smartmock_next
11
+ @last_mock
12
+ end
13
+
14
+ def last_smartmock
15
+ @last_mock
16
+ end
17
+
18
+ def smartmock_next_stub(stubs)
19
+ @smartmock_stubs = stubs
20
+ end
21
+
22
+
23
+ def revert_smartmock_next
24
+ class << self
25
+ alias new orig_new
26
+ end
27
+ end
28
+
29
+ def setup_smartmock_next
30
+ class << self
31
+ alias orig_new new
32
+ alias new smartmock_new
33
+ end
34
+ end
35
+ end
36
+
37
+ module InstanceMethods
38
+
39
+ end
40
+
41
+ def self.included(receiver)
42
+ receiver.extend ClassMethods
43
+ receiver.send :include, InstanceMethods
44
+ end
45
+ end
46
+
47
+ module Find
48
+ module ClassMethods
49
+ def smartmock_find_id(id, *args)
50
+ revert_smartmock_find
51
+ (@smartmocks and @smartmocks[id]) ? @smartmocks[id] : nil
52
+ end
53
+
54
+ def smartmock_find_id!(id, *args)
55
+ revert_smartmock_find
56
+ return @smartmocks[id] if @smartmocks and @smartmocks[id]
57
+ raise DataMapper::ObjectNotFoundError
58
+ end
59
+
60
+ def insert_smartmock(id, mock)
61
+ @smartmocks ||= {}
62
+ @smartmocks[id] = mock
63
+ end
64
+
65
+ def revert_smartmock_find
66
+ klass = @msmartmock_klass
67
+ if Smartmock.active_record?(klass)
68
+ class << klass
69
+ end
70
+ elsif Smartmock.data_mapper?(klass)
71
+ class << klass
72
+ alias get orig_find_id
73
+ alias get! orig_find_id!
74
+ end
75
+ end
76
+ end
77
+
78
+ def setup_smartmock_find(klass)
79
+ @msmartmock_klass = klass
80
+ if Smartmock.active_record?(klass)
81
+ class << klass
82
+ end
83
+ elsif Smartmock.data_mapper?(klass)
84
+ class << klass
85
+ alias orig_find_id get
86
+ alias orig_find_id! get!
87
+ alias get smartmock_find_id
88
+ alias get! smartmock_find_id!
89
+ end
90
+ end
91
+ end
92
+ end
93
+
94
+ module InstanceMethods
95
+
96
+ end
97
+
98
+ def self.included(receiver)
99
+ receiver.extend ClassMethods
100
+ receiver.send :include, InstanceMethods
101
+ end
102
+ end
103
+
104
+ end
105
+
106
+
107
+ class Object
108
+ def smartmock_next(klass, stubs={})
109
+ klass.send :include, Smartmock::Next
110
+ klass.setup_smartmock_next
111
+ klass.smartmock_next_stub(stubs)
112
+ end
113
+
114
+ def smartmock_insert(mock, conditions={})
115
+ klass = mock.klass
116
+ klass.send :include, Smartmock::Find
117
+ klass.setup_smartmock_find(mock.klass)
118
+ klass.insert_smartmock(mock.id, mock)
119
+ end
120
+ end
@@ -0,0 +1,93 @@
1
+ module Smartmock
2
+
3
+ def self.mock(klass)
4
+ MockProxy.new(klass)
5
+ end
6
+
7
+ def self.[](klass)
8
+ mock(klass)
9
+ end
10
+
11
+ def self.active_record?(klass)
12
+ defined?(ActiveRecord) and klass.superclass == ActiveRecord::Base
13
+ end
14
+
15
+ def self.data_mapper?(klass)
16
+ defined?(DataMapper) and klass.respond_to?(:properties)
17
+ end
18
+
19
+ class MockProxy
20
+ def initialize(klass)
21
+ @klass = klass
22
+ end
23
+
24
+ def new(attribs={})
25
+ Mock.new(@klass, attribs)
26
+ end
27
+
28
+ def create(attribs={})
29
+ mock = Mock.new(@klass, attribs)
30
+ mock.save
31
+ mock
32
+ end
33
+ end
34
+
35
+ class Mock
36
+ attr_accessor :klass
37
+
38
+ def initialize(klass, attribs={})
39
+ @attributes = {}
40
+ @stubs = {}
41
+ @dirty = false
42
+ @columns = if Smartmock.active_record?(klass)
43
+ klass.columns.map { |col| col.name.to_s }
44
+ elsif Smartmock.data_mapper?(klass)
45
+ klass.properties.map { |prop| prop.name.to_s }
46
+ else
47
+ []
48
+ end
49
+ @columns << "id"
50
+ attribs.each do |key, val|
51
+ @columns << key.to_s unless @columns.include?(key.to_s)
52
+ self.send("#{key}=".to_sym, val)
53
+ end
54
+ @klass = klass
55
+ end
56
+
57
+ def id
58
+ @attributes["id"]
59
+ end
60
+
61
+ def stubs=(stubs)
62
+ @stubs = stubs
63
+ end
64
+
65
+ def method_missing(meth, *args)
66
+ @columns.each do |col|
67
+ if meth.to_s == col
68
+ return @attributes[col]
69
+ elsif meth.to_s == "#{col}="
70
+ @dirty = true
71
+ @attributes[col] = args.first
72
+ return
73
+ end
74
+ end
75
+ @stubs.each do |stub,value|
76
+ if stub.to_s == meth.to_s
77
+ return value
78
+ end
79
+ end
80
+ raise NameError, "Method #{meth.to_s} is not defined"
81
+ end
82
+
83
+ def dirty?
84
+ @dirty
85
+ end
86
+
87
+ def save
88
+ @dirty = false
89
+ end
90
+ alias_method :save!, :save
91
+ end
92
+
93
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mutle-smartmock
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Mutwin Kraus
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-09-27 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Model Mocking done right
17
+ email:
18
+ - mkraus@engineyard.com
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files:
24
+ - README.txt
25
+ files:
26
+ - MIT-LICENSE
27
+ - lib/smartmock.rb
28
+ - lib/smartmock/mock.rb
29
+ - lib/smartmock/helpers.rb
30
+ - README.txt
31
+ has_rdoc: true
32
+ homepage:
33
+ post_install_message:
34
+ rdoc_options:
35
+ - --main
36
+ - README.txt
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ requirements: []
52
+
53
+ rubyforge_project: ""
54
+ rubygems_version: 1.2.0
55
+ signing_key:
56
+ specification_version: 2
57
+ summary: Model Mocking done right
58
+ test_files: []
59
+