MockActiveRecord 0.1.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/MIT-LICENSE +21 -0
- data/README +32 -0
- data/lib/mock_active_record.rb +162 -0
- data/tests/mock_active_record_test.rb +69 -0
- metadata +57 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2007 Lone Star Software Engineering Services, Inc.
|
2
|
+
Written by Tony Payne
|
3
|
+
|
4
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
5
|
+
a copy of this software and associated documentation files (the
|
6
|
+
"Software"), to deal in the Software without restriction, including
|
7
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
8
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
9
|
+
permit persons to whom the Software is furnished to do so, subject to
|
10
|
+
the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be
|
13
|
+
included in all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
17
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
19
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
20
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
21
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
Provides facilities for creating mock ActiveRecord objects and their associations.
|
2
|
+
|
3
|
+
Author:: Tony Payne <tony@lonestarsoftware.net>
|
4
|
+
Copyright:: Lone Star Software Engineering Services, Inc., 2007
|
5
|
+
Homepage:: http://lonestarsoftware.net
|
6
|
+
Blog:: http://blog.lonestarsoftware.net
|
7
|
+
License:: MIT
|
8
|
+
Version:: 0.1
|
9
|
+
Dependencies:: RubyGems, ActiveSupport (Inflector)
|
10
|
+
|
11
|
+
Currently, there is not a whole lot of ActiveRecord functionality supported. I've only implemented
|
12
|
+
what I need for the active_resources plugin. Hopefully this will provide a good basis to build on
|
13
|
+
for other needs, as well.
|
14
|
+
|
15
|
+
As of 0.1, *the tests pass with 100% code coverage and pass heckling with no mutations remaining*
|
16
|
+
|
17
|
+
Example:
|
18
|
+
|
19
|
+
include MockActiveRecord::Mixin
|
20
|
+
mock :Book do |book|
|
21
|
+
book.column :id, :integer
|
22
|
+
book.column :title, :string, :default => ''
|
23
|
+
book.column :publisher_id, :integer
|
24
|
+
book.column :foo, :string, :content => false
|
25
|
+
book.column :bar_id, :integer, :content => true
|
26
|
+
|
27
|
+
book.has_many :authorships
|
28
|
+
book.has_many :authors, :through => :authorships
|
29
|
+
book.belongs_to :publisher
|
30
|
+
book.has_one :fresnarus
|
31
|
+
end
|
32
|
+
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_support/inflector'
|
3
|
+
|
4
|
+
# :include:README
|
5
|
+
# :main:MockActiveRecord
|
6
|
+
# :title:MockActiveRecord Documentation
|
7
|
+
module MockActiveRecord
|
8
|
+
# Represents an association reflection as returned by MockActiveRecord::Base#reflect_on_all_associations
|
9
|
+
class Association
|
10
|
+
include Inflector
|
11
|
+
attr_reader :name, :macro, :primary_key_name, :active_record, :through_reflection, :class_name, :options
|
12
|
+
def initialize(name, macro, active_record, options = {})
|
13
|
+
pk = options.delete(:primary_key_name) || underscore(active_record.name.to_s) + "_id"
|
14
|
+
cn = options.delete(:class_name) || camelize(singularize(name.to_s))
|
15
|
+
@name = name
|
16
|
+
@macro = macro
|
17
|
+
@active_record = active_record
|
18
|
+
@primary_key_name = pk
|
19
|
+
@options = options
|
20
|
+
@class_name = cn
|
21
|
+
@through_reflection = true if options[:through]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# Represents an active record column as returned by MockActiveRecord::Base#columns
|
26
|
+
class Column
|
27
|
+
attr_reader :name, :type, :default
|
28
|
+
def initialize(name, type, default=nil)
|
29
|
+
@name = name
|
30
|
+
@type = type
|
31
|
+
@default = default
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Base class from which all mock model objects inherit
|
36
|
+
class Base
|
37
|
+
@@name = ''
|
38
|
+
@@columns = {}
|
39
|
+
@@content_columns = {}
|
40
|
+
@@associations = {}
|
41
|
+
|
42
|
+
# Returns the model name
|
43
|
+
def self.name
|
44
|
+
@@name
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns a list of MockActiveRecord::Column objects in the model
|
48
|
+
def self.columns
|
49
|
+
@@columns.values
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns a hash of MockActiveRecord::Column objects in the model with the name as the key value
|
53
|
+
def self.columns_hash()
|
54
|
+
return @@columns
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns a list of MockActiveRecord::Column objects in the model which contain content
|
58
|
+
def self.content_columns
|
59
|
+
@@content_columns.keys
|
60
|
+
end
|
61
|
+
|
62
|
+
# Returns a list of all MockActiveRecord::Association objects in the model
|
63
|
+
def self.reflect_on_all_associations
|
64
|
+
@@associations.values
|
65
|
+
end
|
66
|
+
|
67
|
+
# Adds a :has_many association to the model class
|
68
|
+
# Example:
|
69
|
+
# MockClass.has_many :fresnari, :through => :sharpoze
|
70
|
+
#
|
71
|
+
# Supported options are:
|
72
|
+
# [:through] creates a has-many :through association
|
73
|
+
# [:class_name] sets the name of the associated class
|
74
|
+
def self.has_many(name, options = {})
|
75
|
+
@@associations[name] = MockActiveRecord::Association.new(name, :has_many, self, options)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Adds a :has_one association to the model class
|
79
|
+
# Example:
|
80
|
+
# MockClass.has_one :fresnarus, :class_name => Sharpoze
|
81
|
+
#
|
82
|
+
# Supported options are:
|
83
|
+
# [:class_name] sets the name of the associated class
|
84
|
+
def self.has_one(name, options = {})
|
85
|
+
@@associations[name] = MockActiveRecord::Association.new(name, :has_one, self, options)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Adds a :belongs_to association to the model class
|
89
|
+
# Example:
|
90
|
+
# MockClass.belongs_to :fresnarus
|
91
|
+
#
|
92
|
+
# Supported options are:
|
93
|
+
# [:class_name] sets the name of the associated class
|
94
|
+
def self.belongs_to(name, options = {})
|
95
|
+
@@associations[name] = MockActiveRecord::Association.new(name, :belongs_to, self, options)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Adds a column to the model class
|
99
|
+
# Example:
|
100
|
+
# MockClass.column :id, :integer
|
101
|
+
# MockClass.column :kind, :string, :default => 'fresnarus'
|
102
|
+
#
|
103
|
+
# name:: name of column
|
104
|
+
# type:: type of column (:integer, :string, etc)
|
105
|
+
# options:: Supported values are:
|
106
|
+
# [:default] sets the default value for the column
|
107
|
+
# [:content] overrides the default behavior for determining if a column contains meaningful data.
|
108
|
+
# By default, this is determined by the absence of "_id" at the end of the column name
|
109
|
+
# except for the special columns (id, created|update|deleted_at|on, lock_version)
|
110
|
+
def self.column(name, type, options = {})
|
111
|
+
mock_ar_column = MockActiveRecord::Column.new(name.to_s, type, options[:default])
|
112
|
+
@@columns[name.to_sym] = mock_ar_column
|
113
|
+
if options.has_key?(:content)
|
114
|
+
@@content_columns[name.to_sym] = true if options[:content]
|
115
|
+
else
|
116
|
+
@@content_columns[name.to_sym] = true if is_content_column?(name)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Creates a new instance of the model object
|
121
|
+
# attrs:: Set the initial values for the object's columns
|
122
|
+
def initialize(attrs={})
|
123
|
+
@attrs = attrs.dup
|
124
|
+
self.class.columns.each do |column|
|
125
|
+
@attrs[column.name] = column.default
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# Returns the current attribute values for the model instance
|
130
|
+
def attributes
|
131
|
+
@attrs
|
132
|
+
end
|
133
|
+
|
134
|
+
protected
|
135
|
+
# Returns true if the column name looks like it holds meaningful data
|
136
|
+
def self.is_content_column?(name)
|
137
|
+
return false if name.to_s == 'id'
|
138
|
+
return false if name.to_s =~ /_id$/
|
139
|
+
return false if %w(created_at created_on update_at updated_on deleted_at deleted_on lock_version).include?(name.to_s)
|
140
|
+
return true
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
module Mixin
|
145
|
+
# Create a new mock class with the given name. The class is yielded to the block so that you can call the setup methods:
|
146
|
+
# mock :Book do |book|
|
147
|
+
# book.column :id, :integer
|
148
|
+
# book.column :title, :string
|
149
|
+
# book.has_many :authorships
|
150
|
+
# book.has_many :authors, :through => :authorships
|
151
|
+
# etc...
|
152
|
+
# end
|
153
|
+
def mock(name, &block) # :yields: Class
|
154
|
+
Kernel.module_eval <<-__END__
|
155
|
+
class #{name} < MockActiveRecord::Base
|
156
|
+
@@name = "#{name}"
|
157
|
+
end
|
158
|
+
__END__
|
159
|
+
yield Kernel.const_get(name)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + "/../lib/mock_active_record")
|
3
|
+
class ActiveResourcesTest < Test::Unit::TestCase
|
4
|
+
include MockActiveRecord::Mixin
|
5
|
+
public
|
6
|
+
def setup
|
7
|
+
mock :Book do |book|
|
8
|
+
book.column :id, :integer
|
9
|
+
book.column :title, :string, :default => ''
|
10
|
+
book.column :publisher_id, :integer
|
11
|
+
book.column :foo, :string, :content => false
|
12
|
+
book.column :bar_id, :integer, :content => true
|
13
|
+
|
14
|
+
book.has_many :authorships
|
15
|
+
book.has_many :authors, :through => :authorships
|
16
|
+
book.belongs_to :publisher
|
17
|
+
book.has_one :fresnarus
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_name
|
22
|
+
assert_equal 'Book', Book.name
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_columns
|
26
|
+
assert_equal ['bar_id', 'foo', 'id', 'publisher_id', 'title'], Book.columns.collect{|c| c.name}.sort
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_columns_hash
|
30
|
+
h = Book.columns_hash
|
31
|
+
|
32
|
+
assert h.has_key?(:id)
|
33
|
+
assert_equal 'id', h[:id].name
|
34
|
+
assert_equal :integer, h[:id].type
|
35
|
+
|
36
|
+
assert h.has_key?(:publisher_id)
|
37
|
+
assert_equal 'publisher_id', h[:publisher_id].name
|
38
|
+
assert_equal :integer, h[:publisher_id].type
|
39
|
+
|
40
|
+
assert h.has_key?(:title)
|
41
|
+
assert_equal 'title', h[:title].name
|
42
|
+
assert_equal :string, h[:title].type
|
43
|
+
|
44
|
+
assert h.has_key?(:foo)
|
45
|
+
assert_equal 'foo', h[:foo].name
|
46
|
+
assert_equal :string, h[:foo].type
|
47
|
+
|
48
|
+
assert h.has_key?(:bar_id)
|
49
|
+
assert_equal 'bar_id', h[:bar_id].name
|
50
|
+
assert_equal :integer, h[:bar_id].type
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_content_columns
|
54
|
+
assert_equal ['bar_id', 'title'], Book.content_columns.collect{|c| c.to_s}.sort
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_reflect_on_all_associations
|
58
|
+
assert_equal ['authors', 'authorships', 'fresnarus', 'publisher'], Book.reflect_on_all_associations.collect{|a| a.name.to_s}.sort
|
59
|
+
assert_equal [:has_many, :has_many, :has_one, :belongs_to], Book.reflect_on_all_associations.sort_by{|a| a.name.to_s}.collect{|a| a.macro}
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_new
|
63
|
+
assert_equal 'Book', Book.new.class.name
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_attrs
|
67
|
+
assert_equal({'bar_id' => nil, 'foo' => nil, 'id' => nil, 'publisher_id' => nil, 'title' => ''}, Book.new.attributes)
|
68
|
+
end
|
69
|
+
end
|
metadata
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.0
|
3
|
+
specification_version: 1
|
4
|
+
name: MockActiveRecord
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.1.0
|
7
|
+
date: 2007-03-09 00:00:00 -08:00
|
8
|
+
summary: Mock ActiveRecord Classes
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: tony@lonestarsoftware.net
|
12
|
+
homepage: http://lonestarsoftware.net/
|
13
|
+
rubyforge_project:
|
14
|
+
description:
|
15
|
+
autorequire: mock_active_record
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message:
|
29
|
+
authors:
|
30
|
+
- Tony Payne
|
31
|
+
files:
|
32
|
+
- tests/mock_active_record_test.rb
|
33
|
+
- lib/mock_active_record.rb
|
34
|
+
- README
|
35
|
+
- MIT-LICENSE
|
36
|
+
test_files:
|
37
|
+
- tests/mock_active_record_test.rb
|
38
|
+
rdoc_options: []
|
39
|
+
|
40
|
+
extra_rdoc_files: []
|
41
|
+
|
42
|
+
executables: []
|
43
|
+
|
44
|
+
extensions: []
|
45
|
+
|
46
|
+
requirements: []
|
47
|
+
|
48
|
+
dependencies:
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: activesupport
|
51
|
+
version_requirement:
|
52
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ">"
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 0.0.0
|
57
|
+
version:
|