active_mocker 0.1.1 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Build Status](https://travis-ci.org/zeisler/active_mocker.png?branch=master)](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
|