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
@@ -0,0 +1,81 @@
|
|
1
|
+
module ActiveMocker
|
2
|
+
module MockInstanceMethods
|
3
|
+
|
4
|
+
def mock_instance_method(method, &block)
|
5
|
+
model_instance_methods[method] = block
|
6
|
+
end
|
7
|
+
|
8
|
+
def inspect
|
9
|
+
inspection = self.class.column_names.map { |name|
|
10
|
+
"#{name}: #{attribute_for_inspect(name)}"
|
11
|
+
}.compact.join(", ")
|
12
|
+
|
13
|
+
"#<#{self.class} #{inspection}>"
|
14
|
+
end
|
15
|
+
|
16
|
+
def attribute_for_inspect(attr_name)
|
17
|
+
value = self.attributes[attr_name]
|
18
|
+
if value.is_a?(String) && value.length > 50
|
19
|
+
"#{value[0, 50]}...".inspect
|
20
|
+
elsif value.is_a?(Date) || value.is_a?(Time)
|
21
|
+
%("#{value.to_s(:db)}")
|
22
|
+
elsif value.is_a?(Array) && value.size > 10
|
23
|
+
inspected = value.first(10).inspect
|
24
|
+
%(#{inspected[0...-1]}, ...])
|
25
|
+
else
|
26
|
+
value.inspect
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def hash
|
31
|
+
attributes.hash
|
32
|
+
end
|
33
|
+
|
34
|
+
def ==(obj)
|
35
|
+
hash == obj.attributes.hash
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def read_attribute(attr)
|
41
|
+
attributes[attr]
|
42
|
+
end
|
43
|
+
|
44
|
+
def write_attribute(attr, value)
|
45
|
+
attributes[attr] = value
|
46
|
+
end
|
47
|
+
|
48
|
+
def read_association(attr)
|
49
|
+
@associations[attr]
|
50
|
+
end
|
51
|
+
|
52
|
+
def write_association(attr, value)
|
53
|
+
@associations[attr] = value
|
54
|
+
end
|
55
|
+
|
56
|
+
def attribute_to_string
|
57
|
+
attributes.map {|k, v| "#{k.to_s}: #{v.inspect}"}.join(', ')
|
58
|
+
end
|
59
|
+
|
60
|
+
def delegate_to_model_instance(method, *args)
|
61
|
+
self.class.send(:delegate_to_model_instance, method, *args)
|
62
|
+
end
|
63
|
+
|
64
|
+
def delegate_to_model_class(method, *args)
|
65
|
+
self.class.send(:delegate_to_model_class, method, *args)
|
66
|
+
end
|
67
|
+
|
68
|
+
def model_instance_methods
|
69
|
+
@model_instance_methods ||= self.class.send(:model_instance_methods).dup
|
70
|
+
end
|
71
|
+
|
72
|
+
def model_class_methods
|
73
|
+
@model_class_methods ||= self.class.send(:model_class_methods).dup
|
74
|
+
end
|
75
|
+
|
76
|
+
def schema_attributes
|
77
|
+
@schema_attributes ||= self.class.send(:attribute_template).dup
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'active_mocker/collection_association'
|
2
|
+
require 'active_mocker/mock_class_methods'
|
3
|
+
require 'active_mocker/mock_instance_methods'
|
4
|
+
require 'active_hash'
|
5
|
+
require 'active_hash/ar_api'
|
6
|
+
|
7
|
+
def class_exists?(class_name)
|
8
|
+
klass = Module.const_get(class_name)
|
9
|
+
return klass.is_a?(Class)
|
10
|
+
rescue NameError
|
11
|
+
return false
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# http://blog.nathanhumbert.com/2010/02/rails-3-loading-rake-tasks-from-gem.html
|
2
|
+
|
3
|
+
# ['db:schema:load', 'db:migrate', 'db:reset'].each do |task|
|
4
|
+
# Rake::Task[task].enhance do
|
5
|
+
# Rake::Task['rebuild_mocks'].invoke
|
6
|
+
# end
|
7
|
+
# end
|
8
|
+
|
9
|
+
task rebuild_mocks: :environment do
|
10
|
+
puts 'rebuilding mocks'
|
11
|
+
ActiveMocker::Generate.new
|
12
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'active_mocker/mock_requires'
|
2
|
+
|
3
|
+
Object.send(:remove_const, '<%= class_name %>') if class_exists? '<%= class_name %>'
|
4
|
+
|
5
|
+
class <%= class_name %> < ::ActiveHash::Base
|
6
|
+
include ActiveMocker::ActiveHash::ARApi
|
7
|
+
include ActiveMocker::MockInstanceMethods
|
8
|
+
extend ActiveMocker::MockClassMethods
|
9
|
+
|
10
|
+
def self.column_names
|
11
|
+
<%= attribute_names %>
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.association_names
|
15
|
+
@association_names = <%= association_names.map{|a| a.to_sym} %>
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.attribute_names
|
19
|
+
@attribute_names = <%= attribute_names.map{|a| a.to_sym} %>
|
20
|
+
end
|
21
|
+
|
22
|
+
<% attributes.each do |meth| %>
|
23
|
+
def <%= meth %>
|
24
|
+
attributes['<%= meth %>']
|
25
|
+
end
|
26
|
+
|
27
|
+
def <%= meth %>=(val)
|
28
|
+
attributes['<%= meth %>'] = val
|
29
|
+
end
|
30
|
+
<% end %>
|
31
|
+
|
32
|
+
<% single_associations.each do |meth| %>
|
33
|
+
def <%= meth %>
|
34
|
+
associations['<%= meth %>']
|
35
|
+
end
|
36
|
+
|
37
|
+
def <%= meth %>=(val)
|
38
|
+
associations['<%= meth %>'] = val
|
39
|
+
end
|
40
|
+
<% end %>
|
41
|
+
|
42
|
+
<% collection_associations.each do |meth| %>
|
43
|
+
def <%= meth %>
|
44
|
+
associations['<%= meth %>']
|
45
|
+
end
|
46
|
+
|
47
|
+
def <%= meth %>=(val)
|
48
|
+
associations['<%= meth %>'] = ActiveMocker::CollectionAssociation.new(val)
|
49
|
+
end
|
50
|
+
<% end %>
|
51
|
+
|
52
|
+
def self.model_instance_methods
|
53
|
+
return @model_instance_methods if @model_instance_methods
|
54
|
+
@model_instance_methods = {}<% model_instance_methods.each do |key, value| %>
|
55
|
+
@model_instance_methods[:<%= key %>] = :not_implemented
|
56
|
+
<% end %>
|
57
|
+
@model_instance_methods
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.model_class_methods
|
61
|
+
return @model_class_methods if @model_class_methods
|
62
|
+
@model_class_methods = {}<% model_class_methods.each do |key, value| %>
|
63
|
+
@model_class_methods[:<%= key %>] = :not_implemented
|
64
|
+
<% end %>
|
65
|
+
@model_class_methods
|
66
|
+
end
|
67
|
+
|
68
|
+
<% instance_methods.each do |method| %>
|
69
|
+
def <%= method.method %>(<%= method.params %>)
|
70
|
+
block = model_instance_methods[<%= method.method.inspect %>]
|
71
|
+
self.class.is_implemented(block, "#<%= method.method %>")
|
72
|
+
instance_exec(*[<%= method.params_pass %>], &block)
|
73
|
+
end
|
74
|
+
<% end %>
|
75
|
+
|
76
|
+
<% class_methods.each do |method| %>
|
77
|
+
def self.<%= method.method %>(<%= method.params %>)
|
78
|
+
block = model_class_methods[<%= method.method.inspect %>]
|
79
|
+
is_implemented(block, "::<%= method.method %>")
|
80
|
+
instance_exec(*[<%= method.params_pass %>], &block)
|
81
|
+
end
|
82
|
+
<% end %>
|
83
|
+
|
84
|
+
end
|
@@ -1,11 +1,15 @@
|
|
1
1
|
module ActiveMocker
|
2
2
|
|
3
3
|
def self.mock(model_name)
|
4
|
-
|
4
|
+
Generate.mock(model_name)
|
5
5
|
end
|
6
6
|
|
7
7
|
def self.configure(&block)
|
8
|
-
|
8
|
+
Generate.configure(&block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.config(&block)
|
12
|
+
Generate.configure(&block)
|
9
13
|
end
|
10
14
|
|
11
15
|
end
|
@@ -1,20 +1,27 @@
|
|
1
|
+
require 'pathname'
|
1
2
|
module ActiveMocker
|
2
|
-
|
3
3
|
class SchemaReader
|
4
4
|
|
5
|
-
attr_reader :model_name,
|
5
|
+
attr_reader :model_name,
|
6
|
+
:schema_file,
|
7
|
+
:file_reader,
|
8
|
+
:tables,
|
9
|
+
:clear_cache,
|
10
|
+
:schema_version,
|
11
|
+
:cache_file,
|
12
|
+
:cache_tables,
|
13
|
+
:migration_dir
|
6
14
|
|
7
15
|
def initialize(options={})
|
8
|
-
@file_reader
|
9
|
-
@schema_file
|
10
|
-
|
16
|
+
@file_reader = options[:file_reader] ||= FileReader
|
17
|
+
@schema_file = options[:schema_file]
|
18
|
+
|
11
19
|
end
|
12
20
|
|
13
21
|
def search(model_name)
|
14
22
|
@model_name = model_name
|
15
|
-
|
16
|
-
@
|
17
|
-
@table
|
23
|
+
load_table
|
24
|
+
@tables
|
18
25
|
end
|
19
26
|
|
20
27
|
private
|
@@ -23,18 +30,14 @@ module ActiveMocker
|
|
23
30
|
model_name
|
24
31
|
end
|
25
32
|
|
26
|
-
def
|
27
|
-
|
28
|
-
|
29
|
-
return search_result if search_result
|
30
|
-
schema_result = eval_file
|
31
|
-
raise "#{table_name} table not found." if schema_result.nil?
|
32
|
-
schema_result
|
33
|
+
def load_table
|
34
|
+
eval_file
|
35
|
+
raise "#{table_name} table not found." unless tables
|
33
36
|
end
|
34
37
|
|
35
38
|
def eval_file
|
36
39
|
m = Module.new
|
37
|
-
m.module_eval(read_file)
|
40
|
+
@tables = m.module_eval(read_file).tables
|
38
41
|
end
|
39
42
|
|
40
43
|
def read_file
|
@@ -43,5 +46,21 @@ module ActiveMocker
|
|
43
46
|
|
44
47
|
end
|
45
48
|
|
49
|
+
class SchemaVersion
|
50
|
+
|
51
|
+
def self.migration_dir(dir)
|
52
|
+
@migration_dir = dir || '/Users/zeisler/dev/active_mocker/spec/lib/active_mocker/performance/migration'
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.get
|
56
|
+
return @schema_version unless @schema_version.nil?
|
57
|
+
r = Dir["#{@migration_dir}/*"].last
|
58
|
+
p = Pathname.new(r)
|
59
|
+
s = p.basename.to_s.match(/(\d*)_.*\.rb/).captures
|
60
|
+
@schema_version = s.first
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
46
65
|
end
|
47
66
|
|
data/lib/active_mocker/table.rb
CHANGED
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'active_mocker/mock_requires'
|
2
|
+
|
3
|
+
Object.send(:remove_const, 'MicropostMock') if class_exists? 'MicropostMock'
|
4
|
+
|
5
|
+
class MicropostMock < ::ActiveHash::Base
|
6
|
+
include ActiveMocker::ActiveHash::ARApi
|
7
|
+
include ActiveMocker::MockInstanceMethods
|
8
|
+
extend ActiveMocker::MockClassMethods
|
9
|
+
|
10
|
+
def self.column_names
|
11
|
+
["id", "content", "user_id", "created_at", "updated_at"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.association_names
|
15
|
+
@association_names = [:user]
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.attribute_names
|
19
|
+
@attribute_names = [:id, :content, :user_id, :created_at, :updated_at]
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def id
|
24
|
+
attributes['id']
|
25
|
+
end
|
26
|
+
|
27
|
+
def id=(val)
|
28
|
+
attributes['id'] = val
|
29
|
+
end
|
30
|
+
|
31
|
+
def content
|
32
|
+
attributes['content']
|
33
|
+
end
|
34
|
+
|
35
|
+
def content=(val)
|
36
|
+
attributes['content'] = val
|
37
|
+
end
|
38
|
+
|
39
|
+
def user_id
|
40
|
+
attributes['user_id']
|
41
|
+
end
|
42
|
+
|
43
|
+
def user_id=(val)
|
44
|
+
attributes['user_id'] = val
|
45
|
+
end
|
46
|
+
|
47
|
+
def created_at
|
48
|
+
attributes['created_at']
|
49
|
+
end
|
50
|
+
|
51
|
+
def created_at=(val)
|
52
|
+
attributes['created_at'] = val
|
53
|
+
end
|
54
|
+
|
55
|
+
def updated_at
|
56
|
+
attributes['updated_at']
|
57
|
+
end
|
58
|
+
|
59
|
+
def updated_at=(val)
|
60
|
+
attributes['updated_at'] = val
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
def user
|
66
|
+
associations['user']
|
67
|
+
end
|
68
|
+
|
69
|
+
def user=(val)
|
70
|
+
associations['user'] = val
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
|
76
|
+
def self.model_instance_methods
|
77
|
+
return @model_instance_methods if @model_instance_methods
|
78
|
+
@model_instance_methods = {}
|
79
|
+
@model_instance_methods
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.model_class_methods
|
83
|
+
return @model_class_methods if @model_class_methods
|
84
|
+
@model_class_methods = {}
|
85
|
+
@model_class_methods[:from_users_followed_by] = :not_implemented
|
86
|
+
|
87
|
+
@model_class_methods
|
88
|
+
end
|
89
|
+
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
def self.from_users_followed_by(user)
|
94
|
+
block = model_class_methods[:from_users_followed_by]
|
95
|
+
is_implemented(block, "::from_users_followed_by")
|
96
|
+
instance_exec(*[user], &block)
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'active_mocker/mock_requires'
|
2
|
+
|
3
|
+
Object.send(:remove_const, 'RelationshipMock') if class_exists? 'RelationshipMock'
|
4
|
+
|
5
|
+
class RelationshipMock < ::ActiveHash::Base
|
6
|
+
include ActiveMocker::ActiveHash::ARApi
|
7
|
+
include ActiveMocker::MockInstanceMethods
|
8
|
+
extend ActiveMocker::MockClassMethods
|
9
|
+
|
10
|
+
def self.column_names
|
11
|
+
["id", "follower_id", "followed_id", "created_at", "updated_at"]
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.association_names
|
15
|
+
@association_names = [:follower, :followed]
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.attribute_names
|
19
|
+
@attribute_names = [:id, :follower_id, :followed_id, :created_at, :updated_at]
|
20
|
+
end
|
21
|
+
|
22
|
+
|
23
|
+
def id
|
24
|
+
attributes['id']
|
25
|
+
end
|
26
|
+
|
27
|
+
def id=(val)
|
28
|
+
attributes['id'] = val
|
29
|
+
end
|
30
|
+
|
31
|
+
def follower_id
|
32
|
+
attributes['follower_id']
|
33
|
+
end
|
34
|
+
|
35
|
+
def follower_id=(val)
|
36
|
+
attributes['follower_id'] = val
|
37
|
+
end
|
38
|
+
|
39
|
+
def followed_id
|
40
|
+
attributes['followed_id']
|
41
|
+
end
|
42
|
+
|
43
|
+
def followed_id=(val)
|
44
|
+
attributes['followed_id'] = val
|
45
|
+
end
|
46
|
+
|
47
|
+
def created_at
|
48
|
+
attributes['created_at']
|
49
|
+
end
|
50
|
+
|
51
|
+
def created_at=(val)
|
52
|
+
attributes['created_at'] = val
|
53
|
+
end
|
54
|
+
|
55
|
+
def updated_at
|
56
|
+
attributes['updated_at']
|
57
|
+
end
|
58
|
+
|
59
|
+
def updated_at=(val)
|
60
|
+
attributes['updated_at'] = val
|
61
|
+
end
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
def follower
|
66
|
+
associations['follower']
|
67
|
+
end
|
68
|
+
|
69
|
+
def follower=(val)
|
70
|
+
associations['follower'] = val
|
71
|
+
end
|
72
|
+
|
73
|
+
def followed
|
74
|
+
associations['followed']
|
75
|
+
end
|
76
|
+
|
77
|
+
def followed=(val)
|
78
|
+
associations['followed'] = val
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
def self.model_instance_methods
|
85
|
+
return @model_instance_methods if @model_instance_methods
|
86
|
+
@model_instance_methods = {}
|
87
|
+
@model_instance_methods
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.model_class_methods
|
91
|
+
return @model_class_methods if @model_class_methods
|
92
|
+
@model_class_methods = {}
|
93
|
+
@model_class_methods
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
end
|