active_mocker 1.1.23 → 1.2.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +12 -22
- data/active_mocker.gemspec +1 -0
- data/lib/active_hash/init.rb +1 -1
- data/lib/active_mocker.rb +4 -5
- data/lib/active_mocker/active_record/schema.rb +2 -4
- data/lib/active_mocker/config.rb +6 -22
- data/lib/active_mocker/field.rb +3 -1
- data/lib/active_mocker/generate.rb +161 -0
- data/lib/active_mocker/mock_class_methods.rb +82 -0
- data/lib/active_mocker/mock_instance_methods.rb +81 -0
- data/lib/active_mocker/mock_requires.rb +12 -0
- data/lib/active_mocker/mock_task.rb +12 -0
- data/lib/active_mocker/mock_template.erb +84 -0
- data/lib/active_mocker/public_methods.rb +6 -2
- data/lib/active_mocker/schema_reader.rb +35 -16
- data/lib/active_mocker/table.rb +2 -0
- data/lib/active_mocker/version.rb +1 -1
- data/mocks/micropost_mock.rb +100 -0
- data/mocks/relationship_mock.rb +100 -0
- data/mocks/user_mock.rb +196 -0
- data/plan_mock.rb +2323 -0
- data/spec/lib/active_mocker/generate_spec.rb +49 -0
- data/spec/lib/active_mocker/{base_spec.rb → performance/base_spec.rb} +17 -37
- data/spec/lib/active_mocker/performance/large_schema.rb +3576 -0
- data/spec/lib/active_mocker/performance/migration/20140327205359_migration.rb +0 -0
- data/spec/lib/active_mocker/performance/schema_reader_spec.rb +96 -0
- data/spec/lib/active_mocker/schema_reader_spec.rb +12 -27
- data/spec/lib/compare_mocker_and_record_spec.rb +3 -2
- data/spec/lib/readme_spec.rb +205 -0
- data/spec/mocks/micropost_mock.rb +100 -0
- data/spec/mocks/relationship_mock.rb +100 -0
- data/spec/mocks/user_mock.rb +196 -0
- data/spec/mocks/user_mock_spec.rb +173 -0
- metadata +48 -9
- data/lib/active_mocker/base.rb +0 -356
- data/spec/lib/active_mocker/active_record/schema_spec.rb +0 -2721
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bbba1fbd943d80b9a68d611991326685d86ed5c4
|
4
|
+
data.tar.gz: bc4c0d888da88e4b9a678f3a9581f35657b286af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6507f76e5ad25d3817721c9cde6055ba8c559ab7bfd76154829222836793d13551ddd796dddef0a7f9603a355707f9f429392d07bba2cc4c29e72e522892eb15
|
7
|
+
data.tar.gz: 3d9ca4c2017bcc884a09f06d01e4916ddb770c7a322e1c280ee8bc90c541e4adebefb55a15d7d93580cfbb53a5037e3d7ad3b1c95cd040657439e4c4276b31ec
|
data/README.md
CHANGED
@@ -65,10 +65,10 @@ Or install it yourself as:
|
|
65
65
|
=> PersonMock
|
66
66
|
|
67
67
|
PersonMock.column_names
|
68
|
-
=> ["account_id", "first_name", "last_name", "address", "city"]
|
68
|
+
=> ["id", "account_id", "first_name", "last_name", "address", "city"]
|
69
69
|
|
70
70
|
person_mock = PersonMock.new(first_name: "Dustin", last_name: "Zeisler", account: ActiveMocker.mock('Account').new)
|
71
|
-
=> #<PersonMock
|
71
|
+
=> "#<PersonMock id: nil, account_id: nil, first_name: \"Dustin\", last_name: \"Zeisler\", address: nil, city: nil>"
|
72
72
|
|
73
73
|
person_mock.first_name
|
74
74
|
=> "Dustin"
|
@@ -89,18 +89,14 @@ Or install it yourself as:
|
|
89
89
|
|
90
90
|
end
|
91
91
|
|
92
|
-
|
93
|
-
|
92
|
+
PersonMock.new(first_name: "Dustin", last_name: "Zeisler")
|
93
|
+
=>#<RuntimeError Rejected params: {"first_name"=>"Dustin", "last_name"=>"Zeisler"} for PersonMock>
|
94
94
|
|
95
95
|
|
96
96
|
### Mocking instance and class methods
|
97
97
|
|
98
|
-
person_mock.bar
|
99
|
-
=> ArgumentError: wrong number of arguments (0 for 1..2)
|
100
|
-
|
101
98
|
person_mock.bar('baz')
|
102
|
-
=> RuntimeError:
|
103
|
-
|
99
|
+
=> RuntimeError: ::bar is not Implemented for Class: PersonMock
|
104
100
|
|
105
101
|
person_mock.mock_instance_method(:bar) do |name, type=nil|
|
106
102
|
"Now implemented with #{name} and #{type}"
|
@@ -109,7 +105,7 @@ Or install it yourself as:
|
|
109
105
|
person_mock.new.bar('foo', 'type')
|
110
106
|
=> "Now implemented with foo and type"
|
111
107
|
|
112
|
-
person_mock.mock_class_method(:
|
108
|
+
person_mock.mock_class_method(:bar) do
|
113
109
|
"Now implemented"
|
114
110
|
end
|
115
111
|
|
@@ -144,12 +140,13 @@ Or install it yourself as:
|
|
144
140
|
person_mock.mock_instance_method(:bar) do |name, type=nil|
|
145
141
|
"Now implemented with #{name} and #{type}"
|
146
142
|
end
|
147
|
-
=>
|
143
|
+
=> NoMethodError: undefined method `bar' for class `PersonMock'
|
148
144
|
|
149
145
|
### ActiveRecord supported methods
|
150
|
-
**
|
146
|
+
**class methods**
|
151
147
|
|
152
|
-
|
148
|
+
* new
|
149
|
+
* create
|
153
150
|
* column_names
|
154
151
|
* find
|
155
152
|
* find_by
|
@@ -162,21 +159,14 @@ Or install it yourself as:
|
|
162
159
|
* count
|
163
160
|
* first/last
|
164
161
|
|
165
|
-
**
|
162
|
+
**instance methods**
|
166
163
|
|
167
|
-
|
164
|
+
* attributes
|
168
165
|
* update
|
169
166
|
* save
|
170
167
|
* write_attribute - (private)
|
171
168
|
* read_attribute - (private)
|
172
169
|
|
173
|
-
**Collection Associations**
|
174
|
-
|
175
|
-
* last/first
|
176
|
-
* sum(attribute)
|
177
|
-
* <<
|
178
|
-
* Enumerable methods
|
179
|
-
|
180
170
|
### Known Limitations
|
181
171
|
|
182
172
|
* **::mock** model names and table names must follow the default ActiveRecord naming pattern.
|
data/active_mocker.gemspec
CHANGED
@@ -29,6 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.add_development_dependency "rspec", "~>2.14"
|
30
30
|
# spec.add_development_dependency "i18n", "~>0.6"
|
31
31
|
spec.add_development_dependency "sqlite3", "~>1.3"
|
32
|
+
spec.add_development_dependency "fuubar"
|
32
33
|
|
33
34
|
if ENV['DEBUG'] == '1'
|
34
35
|
spec.add_development_dependency "debase", "~>0.0"
|
data/lib/active_hash/init.rb
CHANGED
@@ -10,7 +10,7 @@ module ActiveHash
|
|
10
10
|
def initialize(attributes = {})
|
11
11
|
filter_associations(HashWithIndifferentAccess.new(attributes))
|
12
12
|
@attributes.dup.merge(@associations.dup).each do |key, value|
|
13
|
-
send "#{key}=", value
|
13
|
+
send "#{key}=", value #maybe could just check if responds_to method? How AR works?
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
data/lib/active_mocker.rb
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
require "active_mocker/version"
|
2
2
|
$:.unshift File.expand_path('../../', __FILE__)
|
3
|
+
|
4
|
+
require 'active_mocker/public_methods'
|
5
|
+
require 'active_mocker/config'
|
6
|
+
require 'active_mocker/generate'
|
3
7
|
require 'singleton'
|
4
8
|
require 'logger'
|
5
9
|
require 'active_mocker/logger'
|
@@ -7,18 +11,13 @@ require 'active_support/all'
|
|
7
11
|
require 'active_mocker/table'
|
8
12
|
require 'active_mocker/field'
|
9
13
|
require 'file_reader'
|
10
|
-
require 'active_mocker/public_methods'
|
11
|
-
require 'active_mocker/config'
|
12
14
|
require 'active_mocker/reparameterize'
|
13
15
|
require 'active_mocker/active_record'
|
14
16
|
require 'active_mocker/model_reader'
|
15
17
|
require 'active_mocker/schema_reader'
|
16
18
|
require 'active_mocker/active_record/schema'
|
17
19
|
require 'active_mocker/collection_association'
|
18
|
-
require 'active_mocker/base'
|
19
20
|
require 'active_mocker/active_record'
|
20
21
|
require 'active_mocker/model_reader'
|
21
22
|
require 'active_mocker/reparameterize'
|
22
23
|
require 'active_hash/ar_api'
|
23
|
-
|
24
|
-
|
@@ -9,8 +9,7 @@ module ActiveMocker
|
|
9
9
|
search_result unless search_result.nil?
|
10
10
|
schema = parse
|
11
11
|
schema.instance_eval(&block)
|
12
|
-
|
13
|
-
schema.tables.first
|
12
|
+
schema
|
14
13
|
end
|
15
14
|
|
16
15
|
def self.parse
|
@@ -47,11 +46,10 @@ module ActiveMocker
|
|
47
46
|
def initialize(table_search)
|
48
47
|
@table_search = table_search
|
49
48
|
@tables = []
|
50
|
-
|
51
49
|
end
|
52
50
|
|
53
51
|
def create_table(name, options={}, &block)
|
54
|
-
tables << ActiveMocker::Table.new(name, CreateTable.new.instance_eval(&block))
|
52
|
+
tables << ActiveMocker::Table.new(name, CreateTable.new.instance_eval(&block))
|
55
53
|
end
|
56
54
|
|
57
55
|
def method_missing(meth, *args)
|
data/lib/active_mocker/config.rb
CHANGED
@@ -9,13 +9,14 @@ module ActiveMocker
|
|
9
9
|
:model_attributes,
|
10
10
|
:schema_file_reader,
|
11
11
|
:model_file_reader,
|
12
|
-
:clear_cache
|
12
|
+
:clear_cache,
|
13
|
+
:migration_dir,
|
14
|
+
:mock_dir
|
13
15
|
|
14
16
|
def config
|
15
17
|
@@first_load ||= reload_default
|
16
18
|
yield self
|
17
19
|
check_required_settings
|
18
|
-
require_active_hash
|
19
20
|
end
|
20
21
|
|
21
22
|
def reload_default
|
@@ -27,37 +28,20 @@ module ActiveMocker
|
|
27
28
|
@clear_cache = false
|
28
29
|
@schema_file_reader = nil
|
29
30
|
@model_file_reader = nil
|
31
|
+
@migration_dir = nil
|
32
|
+
@mock_dir = nil
|
30
33
|
end
|
31
34
|
|
32
35
|
def check_required_settings
|
33
36
|
raise 'schema_file must be specified' if schema_file.nil?
|
34
37
|
raise 'model_dir must be specified' if model_dir.nil?
|
35
|
-
|
36
|
-
|
37
|
-
def require_active_hash
|
38
|
-
require 'active_hash' if schema_attributes
|
38
|
+
raise 'mock_dir must be specified' if mock_dir.nil?
|
39
39
|
end
|
40
40
|
|
41
41
|
def log_level=(level)
|
42
42
|
Logger_.level = level
|
43
43
|
end
|
44
44
|
|
45
|
-
def active_hash_as_base=(arg)
|
46
|
-
Logger_.warn('Deprecation Warning: config option `active_hash_as_base` is now model_attributes')
|
47
|
-
end
|
48
|
-
|
49
|
-
def model_relationships=(arg)
|
50
|
-
Logger_.warn('Deprecation Warning: config option `model_relationships` is now model_attributes')
|
51
|
-
end
|
52
|
-
|
53
|
-
def model_methods=(arg)
|
54
|
-
Logger_.warn('Deprecation Warning: config option `model_methods` is now model_attributes')
|
55
|
-
end
|
56
|
-
|
57
|
-
def mass_assignment=(arg)
|
58
|
-
Logger_.warn('Deprecation Warning: config option `mass_assignment` is now model_attributes')
|
59
|
-
end
|
60
|
-
|
61
45
|
end
|
62
46
|
|
63
47
|
end
|
data/lib/active_mocker/field.rb
CHANGED
@@ -15,11 +15,13 @@ module ActiveMocker
|
|
15
15
|
{name: name, type: type, options: options}
|
16
16
|
end
|
17
17
|
|
18
|
+
alias_method :to_hash, :to_h
|
19
|
+
|
18
20
|
def create_option_methods
|
19
21
|
options.each do |opt|
|
20
22
|
key, value = opt.first
|
21
23
|
self.instance_variable_set("@#{key}", value)
|
22
|
-
|
24
|
+
self.class.send(:attr_accessor, key)
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
@@ -0,0 +1,161 @@
|
|
1
|
+
module ActiveMocker
|
2
|
+
class Generate
|
3
|
+
extend Config
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
@@_self = self
|
7
|
+
def_delegators :@@_self,
|
8
|
+
:schema_attributes,
|
9
|
+
:model_attributes,
|
10
|
+
:model_dir,
|
11
|
+
:schema_file,
|
12
|
+
:model_file_reader,
|
13
|
+
:schema_file_reader,
|
14
|
+
:mock_dir
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
create_template
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.configure(&block)
|
21
|
+
config(&block)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.mock(model_name)
|
25
|
+
load_mock(model_name)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.load_mock(model_name)
|
29
|
+
load File.join(mock_dir, "#{model_name.tableize.singularize}_mock.rb")
|
30
|
+
"#{model_name}Mock".constantize
|
31
|
+
end
|
32
|
+
|
33
|
+
def model_definition(table)
|
34
|
+
return @model_definition if @model_definition_table == table
|
35
|
+
@model_definition_table = table
|
36
|
+
@model_definition = ModelReader.new({model_dir: model_dir, file_reader: model_file_reader}).parse(table_to_model_file(table))
|
37
|
+
end
|
38
|
+
|
39
|
+
def table_to_model_file(table)
|
40
|
+
table.singularize
|
41
|
+
end
|
42
|
+
|
43
|
+
def table_to_class_name(table)
|
44
|
+
table.camelize.singularize
|
45
|
+
end
|
46
|
+
|
47
|
+
def schema_reader
|
48
|
+
SchemaReader.new({schema_file: schema_file, file_reader: schema_file_reader}).search(nil)
|
49
|
+
end
|
50
|
+
|
51
|
+
def tables
|
52
|
+
schema_reader
|
53
|
+
end
|
54
|
+
|
55
|
+
def create_template
|
56
|
+
tables.each do |table|
|
57
|
+
mock_template = MockTemplate.new
|
58
|
+
# Schema Attributes
|
59
|
+
mock_template.class_name = mock_class_name(table.name)
|
60
|
+
mock_template.attribute_names = table.column_names
|
61
|
+
mock_template.attributes = table.column_names
|
62
|
+
|
63
|
+
# Model associations
|
64
|
+
mock_template.single_associations = model_definition(table.name).single_relationships
|
65
|
+
mock_template.collection_associations = model_definition(table.name).collections
|
66
|
+
mock_template.association_names = [*model_definition(table.name).single_relationships, *model_definition(table.name).collections]
|
67
|
+
|
68
|
+
# Model Methods
|
69
|
+
mock_template.instance_methods = instance_methods(table.name).methods
|
70
|
+
mock_template.model_instance_methods = instance_methods(table.name).model_instance_methods
|
71
|
+
mock_template.class_methods = class_methods(table.name).methods
|
72
|
+
mock_template.model_class_methods = class_methods(table.name).model_class_methods
|
73
|
+
|
74
|
+
klass_str = mock_template.render( File.open(File.join(File.expand_path('../', __FILE__), 'mock_template.erb')).read)
|
75
|
+
FileUtils::mkdir_p mock_dir unless File.directory? mock_dir
|
76
|
+
File.open(File.join(mock_dir,"#{table.name.singularize}_mock.rb"), 'w').write(klass_str)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
def mock_class_name(table_name)
|
85
|
+
"#{table_to_class_name(table_name)}Mock"
|
86
|
+
end
|
87
|
+
|
88
|
+
def instance_methods(table_name)
|
89
|
+
model_instance_methods = []
|
90
|
+
instance_methods = Methods.new
|
91
|
+
instance_methods.methods = model_definition(table_name).instance_methods_with_arguments.map do |method|
|
92
|
+
m = method.keys.first
|
93
|
+
if m == :attributes
|
94
|
+
Logger_.warn "ActiveMocker Depends on the #attributes method. It will not be redefined for the model."
|
95
|
+
next
|
96
|
+
end
|
97
|
+
params = Reparameterize.call(method.values.first)
|
98
|
+
params_pass = Reparameterize.call(method.values.first, true)
|
99
|
+
|
100
|
+
instance_method = Method.new
|
101
|
+
instance_method.method = m
|
102
|
+
instance_method.params = params
|
103
|
+
|
104
|
+
instance_method.params_pass = params_pass
|
105
|
+
model_instance_methods << m
|
106
|
+
instance_method
|
107
|
+
end
|
108
|
+
instance_methods.model_instance_methods = model_instance_methods
|
109
|
+
instance_methods
|
110
|
+
end
|
111
|
+
|
112
|
+
def class_methods(table_name)
|
113
|
+
model_class_methods = []
|
114
|
+
class_methods = Methods.new
|
115
|
+
class_methods.methods = model_definition(table_name).class_methods_with_arguments.map do |method|
|
116
|
+
m = method.keys.first
|
117
|
+
params = Reparameterize.call(method.values.first)
|
118
|
+
params_pass = Reparameterize.call(method.values.first, true)
|
119
|
+
|
120
|
+
class_method = Method.new
|
121
|
+
class_method.method = m
|
122
|
+
class_method.params = params
|
123
|
+
class_method.params_pass = params_pass
|
124
|
+
model_class_methods << m
|
125
|
+
class_method
|
126
|
+
end
|
127
|
+
class_methods.model_class_methods = model_class_methods
|
128
|
+
class_methods
|
129
|
+
end
|
130
|
+
|
131
|
+
class Method
|
132
|
+
attr_accessor :method, :params, :params_pass
|
133
|
+
end
|
134
|
+
|
135
|
+
class Methods
|
136
|
+
attr_accessor :methods, :model_class_methods, :model_instance_methods
|
137
|
+
end
|
138
|
+
|
139
|
+
class MockTemplate
|
140
|
+
attr_accessor :attributes,
|
141
|
+
:single_associations,
|
142
|
+
:collection_associations,
|
143
|
+
:class_name,
|
144
|
+
:association_names,
|
145
|
+
:attribute_names,
|
146
|
+
:column_names,
|
147
|
+
:instance_methods,
|
148
|
+
:class_methods,
|
149
|
+
:model_instance_methods,
|
150
|
+
:model_class_methods
|
151
|
+
|
152
|
+
def render(template)
|
153
|
+
ERB.new(template,nil,true).result(binding)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module ActiveMocker
|
2
|
+
module MockClassMethods
|
3
|
+
|
4
|
+
def mock_instance_method(method, &block)
|
5
|
+
model_instance_methods[method] = block
|
6
|
+
end
|
7
|
+
|
8
|
+
def mock_class_method(method, &block)
|
9
|
+
model_class_methods[method] = block
|
10
|
+
end
|
11
|
+
|
12
|
+
def column_names
|
13
|
+
schema_attributes_template
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def delegate_to_model_instance(method, *args)
|
19
|
+
model_class_instance.send(method, *args)
|
20
|
+
end
|
21
|
+
|
22
|
+
def delegate_to_model_class(method, *args)
|
23
|
+
model_class.send(method, *args)
|
24
|
+
end
|
25
|
+
|
26
|
+
def model_class_methods
|
27
|
+
@model_class_methods ||= HashWithIndifferentAccess.new
|
28
|
+
end
|
29
|
+
|
30
|
+
def model_methods_template
|
31
|
+
@model_methods_template ||= HashWithIndifferentAccess.new
|
32
|
+
end
|
33
|
+
|
34
|
+
def schema_attributes_template
|
35
|
+
@schema_attributes_template ||= HashWithIndifferentAccess.new
|
36
|
+
end
|
37
|
+
|
38
|
+
def model_class
|
39
|
+
@model_class
|
40
|
+
end
|
41
|
+
|
42
|
+
def model_class_instance
|
43
|
+
@model_class_instance ||= model_class.new
|
44
|
+
end
|
45
|
+
|
46
|
+
def attribute_names
|
47
|
+
@attribute_names
|
48
|
+
end
|
49
|
+
|
50
|
+
def attribute_names=(attributes)
|
51
|
+
@attribute_names = attributes.map{|a| a.to_sym}
|
52
|
+
end
|
53
|
+
|
54
|
+
def attribute_template
|
55
|
+
return @attribute_template unless @attribute_template.nil?
|
56
|
+
@attribute_template = HashWithIndifferentAccess.new
|
57
|
+
attribute_names.each {|a| @attribute_template[a] = nil}
|
58
|
+
return @attribute_template
|
59
|
+
end
|
60
|
+
|
61
|
+
def association_names
|
62
|
+
@association_names
|
63
|
+
end
|
64
|
+
|
65
|
+
def association_names=(associations)
|
66
|
+
@association_names = associations.map{|a| a.to_sym}
|
67
|
+
end
|
68
|
+
|
69
|
+
def association_template
|
70
|
+
return @association_template unless @association_template.nil?
|
71
|
+
@association_template = HashWithIndifferentAccess.new
|
72
|
+
association_names.each {|a| @association_template[a] = nil}
|
73
|
+
return @association_template
|
74
|
+
end
|
75
|
+
|
76
|
+
public
|
77
|
+
def is_implemented(val, method)
|
78
|
+
raise "#{method} is not Implemented for Class: #{name}" if val == :not_implemented
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|