active_mocker 0.1.1 → 0.3.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.
- checksums.yaml +4 -4
- data/README.md +116 -2
- data/active_mocker.gemspec +1 -0
- data/lib/active_mocker.rb +13 -2
- data/lib/active_mocker/base.rb +82 -43
- data/lib/active_mocker/config.rb +34 -0
- data/lib/active_mocker/model_reader.rb +4 -4
- data/lib/active_mocker/schema_reader.rb +3 -3
- data/lib/active_mocker/version.rb +1 -1
- data/spec/lib/active_mocker/base_spec.rb +161 -53
- data/spec/lib/active_mocker/model_reader_spec.rb +5 -6
- data/spec/lib/active_mocker/schema_reader_spec.rb +6 -6
- data/spec/lib/model.rb +4 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 088dc755f7c69b012b24059d5dde2327b51c2ac5
|
4
|
+
data.tar.gz: 056cc0f1af0680b37db122ba36a5c6406550d597
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 16e53701559ce5c97bee5cdef1a2d438bdc4b2dfe0e37fd8008046ec34d5527a224f651ef953adf098dc492d744b6467794fc2695dfc4f0c9599e41828567578
|
7
|
+
data.tar.gz: e2c885e9ab6358deb98b6ae3f25ffbec50e7b189c2b05dfda687e5c97e657d4655fe45cd4209fcec83120a67e9994905e3b68c7279098afdcd97501983c49839
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# ActiveMocker
|
2
2
|
[](https://travis-ci.org/zeisler/active_mocker)
|
3
|
-
|
3
|
+
|
4
|
+
Create mocks from active record models without loading rails or running a database.
|
5
|
+
|
4
6
|
|
5
7
|
## Installation
|
6
8
|
|
@@ -18,7 +20,119 @@ Or install it yourself as:
|
|
18
20
|
|
19
21
|
## Usage
|
20
22
|
|
21
|
-
|
23
|
+
|
24
|
+
#db/schema.rb
|
25
|
+
|
26
|
+
ActiveRecord::Schema.define(version: 20140327205359) do
|
27
|
+
|
28
|
+
create_table "people", force: true do |t|
|
29
|
+
t.integer "account_id"
|
30
|
+
t.string "first_name", limit: 128
|
31
|
+
t.string "last_name", limit: 128
|
32
|
+
t.string "address", limit: 200
|
33
|
+
t.string "city", limit: 100
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
#app/models/person.rb
|
39
|
+
|
40
|
+
class Person < ActiveRecord::Base
|
41
|
+
belongs_to :account
|
42
|
+
|
43
|
+
def bar(name, type=nil)
|
44
|
+
puts bar
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
require 'active_mocker'
|
50
|
+
|
51
|
+
ActiveMocker::Base.configure do |config|
|
52
|
+
config.schema_file = 'file is being inject as string'
|
53
|
+
config.model_dir = 'file is being inject as string'
|
54
|
+
# Dependency injection
|
55
|
+
config.schema_file_reader = schema_file
|
56
|
+
config.model_file_reader = model_file
|
57
|
+
# Additional Options
|
58
|
+
config.active_hash_as_base = false #default
|
59
|
+
config.schema_attributes = true #default
|
60
|
+
config.model_relationships = true #default
|
61
|
+
config.model_methods = true #default
|
62
|
+
config.mass_assignment = true #default
|
63
|
+
end
|
64
|
+
|
65
|
+
mocker = ActiveMocker::Base.new({schema: {path: [path to schema.rb file]},
|
66
|
+
model: {path: [dir of rails models]}}
|
67
|
+
|
68
|
+
mocker.mock('Person')
|
69
|
+
=> PersonMock
|
70
|
+
|
71
|
+
PersonMock.column_names
|
72
|
+
=> ["account_id", "first_name", "last_name", "address", "city"]
|
73
|
+
|
74
|
+
person_mock = PersonMock.new(first_name: "Dustin", last_name: "Zeisler", account: mocker.mock('Account').new)
|
75
|
+
=> #<PersonMock @first_name="Dustin", @last_name="Zeisler">
|
76
|
+
|
77
|
+
person_mock.first_name
|
78
|
+
=> "Dustin"
|
79
|
+
|
80
|
+
### When schema.rb changes the mock fails
|
81
|
+
|
82
|
+
#db/schema.rb
|
83
|
+
|
84
|
+
ActiveRecord::Schema.define(version: 20140327205359) do
|
85
|
+
|
86
|
+
create_table "people", force: true do |t|
|
87
|
+
t.integer "account_id"
|
88
|
+
t.string "f_name", limit: 128
|
89
|
+
t.string "l_name", limit: 128
|
90
|
+
t.string "address", limit: 200
|
91
|
+
t.string "city", limit: 100
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
|
96
|
+
person_mock = PersonMock.new(first_name: "Dustin", last_name: "Zeisler", account: AccountMock.new)
|
97
|
+
=> NoMethodError: undefined method `first_name=' for #<PersonMock:0x007f860abf6b10>
|
98
|
+
|
99
|
+
|
100
|
+
### Mocking instance methods
|
101
|
+
|
102
|
+
person_mock.bar
|
103
|
+
=> ArgumentError: wrong number of arguments (0 for 1..2)
|
104
|
+
|
105
|
+
person_mock.bar('baz')
|
106
|
+
=> RuntimeError: #bar is not Implemented for Class: PersonMock
|
107
|
+
|
108
|
+
|
109
|
+
mock_class.mock_instance_method(:bar) do |name, type=nil|
|
110
|
+
"Now implemented with #{name} and #{type}"
|
111
|
+
end
|
112
|
+
|
113
|
+
mock_class.new.bar('foo', 'type')
|
114
|
+
=> "Now implemented with foo and type"
|
115
|
+
|
116
|
+
### When the model changes the mock fails
|
117
|
+
|
118
|
+
#app/models/person.rb
|
119
|
+
|
120
|
+
class Person < ActiveRecord::Base
|
121
|
+
belongs_to :account
|
122
|
+
|
123
|
+
def bar(name)
|
124
|
+
puts bar
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
mock_class.new.bar('foo', 'type')
|
130
|
+
=> ArgumentError: wrong number of arguments (2 for 1)
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
### When the schema changes
|
135
|
+
|
22
136
|
|
23
137
|
## Contributing
|
24
138
|
|
data/active_mocker.gemspec
CHANGED
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "rspec", "~>2.14"
|
24
24
|
spec.add_development_dependency "i18n", "~>0.6"
|
25
25
|
spec.add_development_dependency "activesupport", "~>4.0"
|
26
|
+
spec.add_development_dependency "active_hash", "~>1.3"
|
26
27
|
|
27
28
|
#spec.add_development_dependency "debase", "~>0.0"
|
28
29
|
#spec.add_development_dependency "ruby-debug-ide", "~>0.4"
|
data/lib/active_mocker.rb
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
require "active_mocker/version"
|
2
|
-
|
2
|
+
$:.unshift File.expand_path('../../', __FILE__)
|
3
|
+
require 'string_reader'
|
4
|
+
require 'active_mocker/table'
|
5
|
+
require 'active_mocker/config'
|
6
|
+
require 'active_mocker/reparameterize'
|
7
|
+
require 'active_mocker/field'
|
8
|
+
require 'active_mocker/active_record'
|
9
|
+
require 'active_mocker/model_reader'
|
10
|
+
require 'active_mocker/schema_reader'
|
11
|
+
require 'active_mocker/active_record/schema'
|
12
|
+
require 'active_mocker/base'
|
13
|
+
require 'active_support/all'
|
3
14
|
module ActiveMocker
|
4
|
-
|
15
|
+
|
5
16
|
end
|
data/lib/active_mocker/base.rb
CHANGED
@@ -1,38 +1,39 @@
|
|
1
1
|
module ActiveMocker
|
2
2
|
|
3
|
-
#TODO DRY up method creation
|
4
|
-
#TODO have instance variable array for instance method
|
5
|
-
#TODO have class variable array for class method
|
6
|
-
#TODO enable support for active_hash as base class
|
7
|
-
#TODO work on options interface
|
8
|
-
|
9
3
|
class Base
|
4
|
+
extend Config
|
5
|
+
extend Forwardable
|
6
|
+
@@_self = self
|
7
|
+
def_delegators :@@_self,
|
8
|
+
:mass_assignment,
|
9
|
+
:model_relationships,
|
10
|
+
:schema_attributes,
|
11
|
+
:model_methods,
|
12
|
+
:active_hash_as_base,
|
13
|
+
:model_dir,
|
14
|
+
:schema_file,
|
15
|
+
:model_file_reader,
|
16
|
+
:schema_file_reader
|
17
|
+
|
18
|
+
attr_reader :model_name, :klass
|
19
|
+
|
20
|
+
def initialize(model_name)
|
21
|
+
@model_name = model_name
|
22
|
+
plain_mock_class unless active_hash_as_base
|
23
|
+
active_hash_mock_class if active_hash_as_base
|
24
|
+
end
|
10
25
|
|
11
|
-
|
12
|
-
|
13
|
-
:options_schema,
|
14
|
-
:mass_assignment,
|
15
|
-
:model_relationships,
|
16
|
-
:schema_attributes,
|
17
|
-
:model_methods
|
18
|
-
|
19
|
-
def initialize(options={})
|
20
|
-
@schema_attributes = options.fetch(:schema_attributes, true)
|
21
|
-
@model_relationships = options.fetch(:model_relationships, true)
|
22
|
-
@model_methods = options.fetch(:model_methods, true)
|
23
|
-
@mass_assignment = options.fetch(:mass_assignment, true)
|
24
|
-
@model_options = options[:model]
|
25
|
-
@options_schema = options[:schema]
|
26
|
+
def self.configure(&block)
|
27
|
+
config(&block)
|
26
28
|
end
|
27
29
|
|
28
|
-
def mock(model_name)
|
29
|
-
|
30
|
-
mock_class
|
30
|
+
def self.mock(model_name)
|
31
|
+
self.new(model_name).klass
|
31
32
|
end
|
32
33
|
|
33
34
|
def model_definition
|
34
35
|
return @model_definition unless @model_definition.nil?
|
35
|
-
@model_definition = ModelReader.new(
|
36
|
+
@model_definition = ModelReader.new({model_dir: model_dir, file_reader: model_file_reader}).parse(model_file_name)
|
36
37
|
end
|
37
38
|
|
38
39
|
def model_file_name
|
@@ -41,21 +42,42 @@ module ActiveMocker
|
|
41
42
|
|
42
43
|
def table_definition
|
43
44
|
table_name = model_name.tableize
|
44
|
-
table = SchemaReader.new(
|
45
|
+
table = SchemaReader.new({schema_file: schema_file, file_reader: schema_file_reader}).search(table_name)
|
45
46
|
raise "#{table_name} table not found." if table.nil?
|
46
47
|
return table
|
47
48
|
end
|
48
49
|
|
49
|
-
def
|
50
|
+
def active_hash_mock_class
|
51
|
+
|
52
|
+
add_column_names_method
|
53
|
+
klass = create_klass
|
54
|
+
fields = table_definition.column_names + model_definition.relationships
|
55
|
+
klass.class_eval do
|
56
|
+
klass.fields(*fields)
|
57
|
+
end
|
58
|
+
|
50
59
|
add_method_mock_of
|
51
|
-
|
52
|
-
|
60
|
+
if model_methods
|
61
|
+
add_instance_methods
|
62
|
+
add_mock_instance_method
|
63
|
+
add_mock_class_method
|
64
|
+
add_class_methods
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
def plain_mock_class
|
70
|
+
add_method_mock_of
|
71
|
+
if model_methods
|
72
|
+
add_instance_methods
|
73
|
+
add_mock_instance_method
|
74
|
+
add_mock_class_method
|
75
|
+
add_class_methods
|
76
|
+
end
|
53
77
|
add_relationships if model_relationships
|
54
|
-
add_class_methods if model_methods
|
55
78
|
add_column_names_method if schema_attributes
|
56
79
|
add_table_attributes if schema_attributes
|
57
80
|
create_initializer if mass_assignment
|
58
|
-
return @klass
|
59
81
|
end
|
60
82
|
|
61
83
|
def create_initializer
|
@@ -95,16 +117,30 @@ module ActiveMocker
|
|
95
117
|
klass = create_klass
|
96
118
|
model_definition.instance_methods_with_arguments.each do |method|
|
97
119
|
m = method.keys.first
|
98
|
-
params
|
120
|
+
params = Reparameterize.call(method.values.first)
|
99
121
|
params_pass = Reparameterize.call(method.values.first, true)
|
100
|
-
klass.instance_variable_set("
|
101
|
-
block = eval_lambda(params, %Q[ self.class.instance_variable_get("
|
122
|
+
klass.instance_variable_set("@instance_#{m}", eval_lambda(params, %Q[raise "##{m} is not Implemented for Class: #{klass.name}"]))
|
123
|
+
block = eval_lambda(params, %Q[ self.class.instance_variable_get("@instance_#{m}").call(#{params_pass})])
|
102
124
|
klass.instance_eval do
|
103
125
|
define_method(m, block)
|
104
126
|
end
|
105
127
|
end
|
106
128
|
end
|
107
129
|
|
130
|
+
def add_class_methods
|
131
|
+
klass = create_klass
|
132
|
+
model_definition.class_methods_with_arguments.each do |method|
|
133
|
+
m = method.keys.first
|
134
|
+
params = Reparameterize.call(method.values.first)
|
135
|
+
params_pass = Reparameterize.call(method.values.first, true)
|
136
|
+
klass.class_variable_set("@@klass_#{m}", eval_lambda(params, %Q[raise "::#{m} is not Implemented for Class: #{klass.name}"]))
|
137
|
+
block = eval_lambda(params, %Q[ class_variable_get("@@klass_#{m}").call(#{params_pass})])
|
138
|
+
klass.singleton_class.class_eval do
|
139
|
+
define_method(m, block)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
108
144
|
def eval_lambda(arguments, block)
|
109
145
|
eval(%Q[ ->(#{arguments}){ #{block} }])
|
110
146
|
end
|
@@ -113,18 +149,21 @@ module ActiveMocker
|
|
113
149
|
klass = create_klass
|
114
150
|
klass.singleton_class.class_eval do
|
115
151
|
define_method(:mock_instance_method) do |method, &block|
|
116
|
-
klass.instance_variable_set("
|
152
|
+
klass.instance_variable_set("@instance_#{method.to_s}", block)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
klass.instance_eval do
|
156
|
+
define_method(:mock_instance_method) do |method, &block|
|
157
|
+
klass.instance_variable_set("@instance_#{method.to_s}", block)
|
117
158
|
end
|
118
159
|
end
|
119
160
|
end
|
120
161
|
|
121
|
-
def
|
162
|
+
def add_mock_class_method
|
122
163
|
klass = create_klass
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
raise "::#{m} is not Implemented for Class: #{klass.name}"
|
127
|
-
end
|
164
|
+
klass.singleton_class.class_eval do
|
165
|
+
define_method(:mock_class_method) do |method, &block|
|
166
|
+
class_variable_set("@@klass_#{method.to_s}", block)
|
128
167
|
end
|
129
168
|
end
|
130
169
|
end
|
@@ -145,8 +184,8 @@ module ActiveMocker
|
|
145
184
|
|
146
185
|
def const_class
|
147
186
|
remove_const(mock_class_name) if class_exists? mock_class_name
|
148
|
-
return Object.const_set(mock_class_name,
|
149
|
-
return Object.
|
187
|
+
return Object.const_set(mock_class_name ,Class.new(ActiveHash::Base)) if active_hash_as_base
|
188
|
+
return Object.const_set(mock_class_name ,Class.new()) unless active_hash_as_base
|
150
189
|
end
|
151
190
|
|
152
191
|
def remove_const(class_name)
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module ActiveMocker
|
2
|
+
|
3
|
+
module Config
|
4
|
+
extend self
|
5
|
+
|
6
|
+
attr_accessor :schema_file,
|
7
|
+
:model_dir,
|
8
|
+
:active_hash_as_base,
|
9
|
+
:schema_attributes,
|
10
|
+
:model_relationships,
|
11
|
+
:model_methods,
|
12
|
+
:mass_assignment,
|
13
|
+
:schema_file_reader,
|
14
|
+
:model_file_reader
|
15
|
+
|
16
|
+
def config
|
17
|
+
default
|
18
|
+
yield self
|
19
|
+
end
|
20
|
+
|
21
|
+
def default
|
22
|
+
schema_file = nil
|
23
|
+
model_dir = nil
|
24
|
+
active_hash_as_base = false
|
25
|
+
schema_attributes = true
|
26
|
+
model_relationships = true
|
27
|
+
model_methods = true
|
28
|
+
mass_assignment = true
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
@@ -2,11 +2,11 @@ module ActiveMocker
|
|
2
2
|
|
3
3
|
class ModelReader
|
4
4
|
|
5
|
-
attr_reader :model_name, :
|
5
|
+
attr_reader :model_name, :model_dir, :file_reader
|
6
6
|
|
7
7
|
def initialize(options={})
|
8
8
|
@file_reader = options[:file_reader] ||= FileReader
|
9
|
-
@
|
9
|
+
@model_dir = options[:model_dir]
|
10
10
|
end
|
11
11
|
|
12
12
|
def parse(model_name)
|
@@ -26,11 +26,11 @@ module ActiveMocker
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def read_file
|
29
|
-
file_reader.read("#{
|
29
|
+
file_reader.read("#{model_dir}/#{model_name}.rb")
|
30
30
|
end
|
31
31
|
|
32
32
|
def class_methods
|
33
|
-
|
33
|
+
klass.methods(false)
|
34
34
|
end
|
35
35
|
|
36
36
|
def class_methods_with_arguments
|
@@ -2,11 +2,11 @@ module ActiveMocker
|
|
2
2
|
|
3
3
|
class SchemaReader
|
4
4
|
|
5
|
-
attr_reader :model_name, :
|
5
|
+
attr_reader :model_name, :schema_file, :file_reader, :table
|
6
6
|
|
7
7
|
def initialize(options={})
|
8
8
|
@file_reader = options[:file_reader] ||= FileReader
|
9
|
-
@
|
9
|
+
@schema_file = options[:schema_file]
|
10
10
|
end
|
11
11
|
|
12
12
|
def search(model_name)
|
@@ -37,7 +37,7 @@ module ActiveMocker
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def read_file
|
40
|
-
file_reader.read(
|
40
|
+
file_reader.read(schema_file)
|
41
41
|
end
|
42
42
|
|
43
43
|
end
|
@@ -2,6 +2,7 @@ require 'rspec'
|
|
2
2
|
$:.unshift File.expand_path('../../', __FILE__)
|
3
3
|
require 'string_reader'
|
4
4
|
require 'active_mocker/table'
|
5
|
+
require 'active_mocker/config'
|
5
6
|
require 'active_mocker/reparameterize'
|
6
7
|
require 'active_mocker/field'
|
7
8
|
require 'active_mocker/active_record'
|
@@ -13,13 +14,25 @@ require 'active_support/all'
|
|
13
14
|
|
14
15
|
describe ActiveMocker::Base do
|
15
16
|
|
16
|
-
let(:
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
let(:mock_class){described_class.mock('Person')}
|
18
|
+
|
19
|
+
before(:each) do
|
20
|
+
|
21
|
+
ActiveMocker::Base.configure do |config|
|
22
|
+
config.schema_file = 'file is being inject as string'
|
23
|
+
config.model_dir = 'file is being inject as string'
|
24
|
+
# Dependency injection
|
25
|
+
config.schema_file_reader = schema_file
|
26
|
+
config.model_file_reader = model_file
|
27
|
+
# Additional Options
|
28
|
+
config.active_hash_as_base = false #default
|
29
|
+
config.schema_attributes = true #default
|
30
|
+
config.model_relationships = true #default
|
31
|
+
config.model_methods = true #default
|
32
|
+
config.mass_assignment = true #default
|
33
|
+
end
|
21
34
|
|
22
|
-
|
35
|
+
end
|
23
36
|
|
24
37
|
let(:model_file){
|
25
38
|
StringReader.new <<-eos
|
@@ -32,22 +45,49 @@ describe ActiveMocker::Base do
|
|
32
45
|
StringReader.new <<-eos
|
33
46
|
ActiveRecord::Schema.define(version: 20140327205359) do
|
34
47
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
t.string "address_2", limit: 100
|
42
|
-
t.string "city", limit: 100
|
43
|
-
t.integer "state_id"
|
44
|
-
t.integer "zip_code_id"
|
45
|
-
end
|
46
|
-
|
48
|
+
create_table "people", force: true do |t|
|
49
|
+
t.integer "account_id"
|
50
|
+
t.string "first_name", limit: 128
|
51
|
+
t.string "last_name", limit: 128
|
52
|
+
t.string "address", limit: 200
|
53
|
+
t.string "city", limit: 100
|
47
54
|
end
|
55
|
+
|
56
|
+
end
|
48
57
|
eos
|
49
58
|
}
|
50
59
|
|
60
|
+
describe '::column_names' do
|
61
|
+
|
62
|
+
it 'returns an array of column names found from the schema.rb file' do
|
63
|
+
expect(mock_class.column_names).to eq(["account_id", "first_name", "last_name", "address", "city"])
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
describe 'mass_assignment' do
|
69
|
+
|
70
|
+
it "can pass any or all attributes from schema in initializer" do
|
71
|
+
result = mock_class.new(first_name: "Sam", last_name: 'Walton')
|
72
|
+
expect(result.first_name).to eq 'Sam'
|
73
|
+
expect(result.last_name).to eq 'Walton'
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
context 'set to false' do
|
78
|
+
|
79
|
+
it 'will fail' do
|
80
|
+
described_class.mass_assignment = false
|
81
|
+
person = described_class.mock("Person")
|
82
|
+
expect{
|
83
|
+
person.new(first_name: "Sam", last_name: 'Walton')
|
84
|
+
}.to raise_error ArgumentError
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
51
91
|
describe '#mock_class' do
|
52
92
|
|
53
93
|
it 'create a mock object after the active record' do
|
@@ -99,6 +139,38 @@ describe ActiveMocker::Base do
|
|
99
139
|
|
100
140
|
end
|
101
141
|
|
142
|
+
describe 'conflict of instance mocks and class mocks' do
|
143
|
+
|
144
|
+
let(:model_file){
|
145
|
+
StringReader.new <<-eos
|
146
|
+
class Person < ActiveRecord::Base
|
147
|
+
def bar(name, type=nil)
|
148
|
+
end
|
149
|
+
|
150
|
+
def self.bar
|
151
|
+
end
|
152
|
+
end
|
153
|
+
eos
|
154
|
+
}
|
155
|
+
|
156
|
+
it 'can mock instance method and class method of the same name' do
|
157
|
+
result = mock_class.new
|
158
|
+
result.mock_instance_method(:bar) do |name, type=nil|
|
159
|
+
"Now implemented with #{name} and #{type}"
|
160
|
+
end
|
161
|
+
result = result.bar('foo', 'type')
|
162
|
+
expect(result).to eq "Now implemented with foo and type"
|
163
|
+
expect{mock_class.bar}.to raise_error('::bar is not Implemented for Class: PersonMock')
|
164
|
+
|
165
|
+
mock_class.mock_class_method(:bar) do
|
166
|
+
"Now implemented"
|
167
|
+
end
|
168
|
+
expect{mock_class.bar}.to_not raise_error
|
169
|
+
expect(mock_class.bar).to eq("Now implemented")
|
170
|
+
end
|
171
|
+
|
172
|
+
end
|
173
|
+
|
102
174
|
describe 'instance methods' do
|
103
175
|
|
104
176
|
let(:model_file){
|
@@ -116,15 +188,6 @@ describe ActiveMocker::Base do
|
|
116
188
|
expect{mock_class.new.bar('foo', 'type')}.to raise_error('#bar is not Implemented for Class: PersonMock')
|
117
189
|
end
|
118
190
|
|
119
|
-
it 'can be implemented dynamically' do
|
120
|
-
|
121
|
-
mock_class.instance_variable_set(:@bar, ->(name, type=nil){ "Now implemented with #{name} and #{type}" })
|
122
|
-
result = mock_class.new
|
123
|
-
result = result.bar('foo', 'type')
|
124
|
-
expect(result).to eq "Now implemented with foo and type"
|
125
|
-
|
126
|
-
end
|
127
|
-
|
128
191
|
it 'can be implemented dynamically' do
|
129
192
|
|
130
193
|
mock_class.mock_instance_method(:bar) do |name, type=nil|
|
@@ -156,10 +219,13 @@ describe ActiveMocker::Base do
|
|
156
219
|
expect{mock_class.class_method}.to raise_error('::class_method is not Implemented for Class: PersonMock')
|
157
220
|
end
|
158
221
|
|
159
|
-
|
160
|
-
|
222
|
+
it 'can be implemented as follows' do
|
161
223
|
|
162
|
-
|
224
|
+
mock_class.mock_class_method(:class_method) do
|
225
|
+
"Now implemented"
|
226
|
+
end
|
227
|
+
expect{mock_class.class_method}.to_not raise_error
|
228
|
+
expect(mock_class.class_method).to eq("Now implemented")
|
163
229
|
|
164
230
|
end
|
165
231
|
|
@@ -171,50 +237,92 @@ describe ActiveMocker::Base do
|
|
171
237
|
|
172
238
|
end
|
173
239
|
|
174
|
-
|
240
|
+
context 'option active_hash_as_base' do
|
175
241
|
|
242
|
+
describe 'true' do
|
176
243
|
|
177
|
-
|
178
|
-
expect(mock_class.column_names).to eq(["company_id", "first_name", "middle_name", "last_name", "address_1", "address_2", "city", "state_id", "zip_code_id"])
|
179
|
-
end
|
244
|
+
before(:each) do
|
180
245
|
|
181
|
-
|
246
|
+
ActiveMocker::Base.configure do |config|
|
247
|
+
config.schema_file = 'file is being inject as string'
|
248
|
+
config.model_dir = 'file is being inject as string'
|
249
|
+
# Depenency injection
|
250
|
+
config.schema_file_reader = schema_file
|
251
|
+
config.model_file_reader = model_file
|
252
|
+
# Additional Options
|
253
|
+
config.active_hash_as_base = true
|
254
|
+
config.schema_attributes = false
|
255
|
+
config.model_relationships = false
|
256
|
+
config.model_methods = true
|
257
|
+
config.mass_assignment = false
|
258
|
+
end
|
182
259
|
|
260
|
+
end
|
261
|
+
require 'active_hash'
|
183
262
|
|
184
|
-
|
263
|
+
let(:model_file){
|
264
|
+
StringReader.new <<-eos
|
265
|
+
class Person < ActiveRecord::Base
|
266
|
+
belongs_to :account
|
185
267
|
|
186
|
-
|
268
|
+
def bar
|
269
|
+
end
|
187
270
|
|
188
|
-
|
271
|
+
end
|
272
|
+
eos
|
273
|
+
}
|
189
274
|
|
190
|
-
|
275
|
+
it 'uses active_hase::base as superclass' do
|
276
|
+
expect(mock_class.superclass.name).to eq 'ActiveHash::Base'
|
277
|
+
end
|
191
278
|
|
192
|
-
|
279
|
+
it 'can mass assign attributes to constructor' do
|
280
|
+
result = mock_class.new(first_name: "Sam", last_name: 'Walton', account: 0)
|
281
|
+
expect(result.first_name).to eq 'Sam'
|
282
|
+
expect(result.last_name).to eq 'Walton'
|
283
|
+
expect(result.account).to eq 0
|
284
|
+
end
|
193
285
|
|
194
|
-
|
286
|
+
it 'can save to class and then find instance by attribute' do
|
195
287
|
|
288
|
+
record = mock_class.create(first_name: "Sam", last_name: 'Walton')
|
289
|
+
expect(mock_class.find_by_first_name("Sam")).to eq record
|
196
290
|
|
291
|
+
end
|
197
292
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
293
|
+
it '::column_names' do
|
294
|
+
expect(mock_class.column_names).to eq(["account_id", "first_name", "last_name", "address", "city"])
|
295
|
+
end
|
296
|
+
|
297
|
+
it '#mock_of' do
|
298
|
+
expect(mock_class.new.mock_of).to eq 'Person'
|
299
|
+
end
|
300
|
+
|
301
|
+
it 'instance methods from model' do
|
302
|
+
expect{mock_class.new.bar}.to raise_error '#bar is not Implemented for Class: PersonMock'
|
303
|
+
end
|
304
|
+
|
305
|
+
it 'instance method can be mocked' do
|
306
|
+
|
307
|
+
mock_class.instance_variable_set(:@instance_bar, ->(){ "Now implemented" })
|
308
|
+
result = mock_class.new
|
309
|
+
result = result.bar
|
310
|
+
expect(result).to eq "Now implemented"
|
311
|
+
|
312
|
+
end
|
202
313
|
|
203
314
|
end
|
204
315
|
|
205
|
-
|
316
|
+
describe 'false' do
|
317
|
+
let(:base_options){{active_hash_as_base: false}}
|
318
|
+
|
319
|
+
it 'has object as supper class' do
|
320
|
+
expect(mock_class.superclass.name).to eq 'Object'
|
206
321
|
|
207
|
-
it 'will fail' do
|
208
|
-
mock = described_class.new(sub_options.merge({mass_assignment: false}))
|
209
|
-
person = mock.mock("Person")
|
210
|
-
expect{
|
211
|
-
person.new(first_name: "Sam", last_name: 'Walton')
|
212
|
-
}.to raise_error ArgumentError
|
213
322
|
end
|
214
323
|
|
215
324
|
end
|
216
325
|
|
217
326
|
end
|
218
327
|
|
219
|
-
|
220
328
|
end
|
@@ -8,11 +8,11 @@ require 'active_mocker/reparameterize'
|
|
8
8
|
|
9
9
|
describe ActiveMocker::ModelReader do
|
10
10
|
|
11
|
-
let(:subject){ described_class.new({
|
11
|
+
let(:subject){ described_class.new({model_dir: File.expand_path('../../', __FILE__)}).parse('Model') }
|
12
12
|
|
13
13
|
describe '#parse' do
|
14
14
|
|
15
|
-
let(:subject){ described_class.new({
|
15
|
+
let(:subject){ described_class.new({model_dir: File.expand_path('../../', __FILE__)}) }
|
16
16
|
|
17
17
|
it 'takes a model name to the active_record model class' do
|
18
18
|
subject.parse('Model')
|
@@ -22,9 +22,8 @@ describe ActiveMocker::ModelReader do
|
|
22
22
|
|
23
23
|
describe '#class_methods' do
|
24
24
|
|
25
|
-
|
26
25
|
it 'returns all public class methods' do
|
27
|
-
expect(subject.class_methods).to eq([:duper, :named])
|
26
|
+
expect(subject.class_methods).to eq([:duper, :named, :foo])
|
28
27
|
end
|
29
28
|
|
30
29
|
end
|
@@ -48,7 +47,7 @@ describe ActiveMocker::ModelReader do
|
|
48
47
|
describe '#class_methods_with_arguments' do
|
49
48
|
|
50
49
|
it 'returns all public instance methods' do
|
51
|
-
expect(subject.class_methods_with_arguments).to eq([{:duper=>[[:req, :value], [:rest, :args]]}, {:named=>[[:req, :name], [:opt, :value], [:opt, :options]]}])
|
50
|
+
expect(subject.class_methods_with_arguments).to eq( [{:duper=>[[:req, :value], [:rest, :args]]}, {:named=>[[:req, :name], [:opt, :value], [:opt, :options]]}, {:foo=>[]}] )
|
52
51
|
end
|
53
52
|
|
54
53
|
end
|
@@ -110,7 +109,7 @@ describe ActiveMocker::ModelReader do
|
|
110
109
|
)
|
111
110
|
}
|
112
111
|
|
113
|
-
let(:subject){described_class.new({
|
112
|
+
let(:subject){described_class.new({model_dir: File.expand_path('../../', __FILE__), file_reader: example_model})}
|
114
113
|
|
115
114
|
let(:search){subject.parse('Person')}
|
116
115
|
|
@@ -10,6 +10,8 @@ require 'active_support/all'
|
|
10
10
|
|
11
11
|
describe ActiveMocker::SchemaReader do
|
12
12
|
|
13
|
+
let(:schema_file){ File.join(File.expand_path('../../', __FILE__), 'schema.rb') }
|
14
|
+
|
13
15
|
let(:example_schema){
|
14
16
|
StringReader.new(
|
15
17
|
<<-eos
|
@@ -55,7 +57,7 @@ describe ActiveMocker::SchemaReader do
|
|
55
57
|
|
56
58
|
context 'inject string_reader as file_reader' do
|
57
59
|
|
58
|
-
let(:subject){described_class.new({
|
60
|
+
let(:subject){described_class.new({schema_file:nil, file_reader: example_schema})}
|
59
61
|
|
60
62
|
let(:search){subject.search('people')}
|
61
63
|
|
@@ -70,13 +72,13 @@ describe ActiveMocker::SchemaReader do
|
|
70
72
|
|
71
73
|
context 'reads from file' do
|
72
74
|
|
73
|
-
let(:subject){described_class.new({
|
75
|
+
let(:subject){described_class.new({schema_file: schema_file})}
|
74
76
|
|
75
77
|
|
76
78
|
describe '#search' do
|
77
79
|
|
78
80
|
it 'takes a table name and will return its attributes' do
|
79
|
-
described_class.new({
|
81
|
+
described_class.new({schema_file: schema_file}).search("people")
|
80
82
|
end
|
81
83
|
|
82
84
|
end
|
@@ -112,13 +114,11 @@ describe ActiveMocker::SchemaReader do
|
|
112
114
|
it 'returns an exception if table not found in schema.rb' do
|
113
115
|
expect{
|
114
116
|
described_class.new(
|
115
|
-
{
|
117
|
+
{schema_file: schema_file}
|
116
118
|
).search("disclosures")
|
117
119
|
}.to raise_error 'disclosures table not found.'
|
118
120
|
end
|
119
121
|
|
120
|
-
|
121
122
|
end
|
122
123
|
|
123
|
-
|
124
124
|
end
|
data/spec/lib/model.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_mocker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dustin Zeisler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-04-
|
11
|
+
date: 2014-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '4.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: active_hash
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.3'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.3'
|
83
97
|
description: Create mocks from active record models without loading rails or running
|
84
98
|
a database. The Mocks methods have the same arguments as the AR model and if they
|
85
99
|
change you get a error in your test.
|
@@ -102,6 +116,7 @@ files:
|
|
102
116
|
- lib/active_mocker/active_record/schema.rb
|
103
117
|
- lib/active_mocker/active_record/scope.rb
|
104
118
|
- lib/active_mocker/base.rb
|
119
|
+
- lib/active_mocker/config.rb
|
105
120
|
- lib/active_mocker/field.rb
|
106
121
|
- lib/active_mocker/model_reader.rb
|
107
122
|
- lib/active_mocker/reparameterize.rb
|