active_mocker 1.3.2 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/README.md +136 -24
  4. data/Rakefile +8 -2
  5. data/active_mocker.gemspec +3 -3
  6. data/lib/active_mock/association.rb +7 -0
  7. data/lib/active_mock/base.rb +250 -0
  8. data/lib/active_mock/collection.rb +52 -0
  9. data/lib/active_mock/creators.rb +25 -0
  10. data/lib/active_mock/do_nothing_active_record_methods.rb +51 -0
  11. data/lib/active_mock/has_and_belongs_to_many.rb +7 -0
  12. data/lib/active_mock/has_many.rb +54 -0
  13. data/lib/active_mock/next_id.rb +16 -0
  14. data/lib/active_mock/object_inspect.rb +39 -0
  15. data/lib/{active_mocker/collection → active_mock}/queries.rb +26 -19
  16. data/lib/active_mock/records.rb +81 -0
  17. data/lib/active_mock/relation.rb +8 -0
  18. data/lib/active_mocker.rb +3 -1
  19. data/lib/active_mocker/active_mock.rb +26 -0
  20. data/lib/active_mocker/active_record.rb +18 -0
  21. data/lib/active_mocker/active_record/relationships.rb +57 -6
  22. data/lib/active_mocker/active_record/schema.rb +1 -1
  23. data/lib/active_mocker/active_record/scope.rb +1 -1
  24. data/lib/active_mocker/active_record/unknown_class_method.rb +1 -1
  25. data/lib/active_mocker/active_record/unknown_module.rb +10 -9
  26. data/lib/active_mocker/db_to_ruby_type.rb +26 -0
  27. data/lib/active_mocker/field.rb +16 -8
  28. data/lib/active_mocker/generate.rb +19 -174
  29. data/lib/active_mocker/loaded_mocks.rb +48 -8
  30. data/lib/active_mocker/logger.rb +2 -0
  31. data/lib/active_mocker/mock_template.erb +123 -53
  32. data/lib/active_mocker/model_reader.rb +42 -13
  33. data/lib/active_mocker/model_schema.rb +279 -0
  34. data/lib/active_mocker/model_schema/generate.rb +175 -0
  35. data/lib/active_mocker/reparameterize.rb +23 -3
  36. data/lib/active_mocker/table.rb +2 -2
  37. data/lib/active_mocker/version.rb +1 -1
  38. data/sample_app_rails_4/Gemfile +1 -1
  39. data/sample_app_rails_4/app/models/micropost.rb +13 -1
  40. data/sample_app_rails_4/db/schema.rb +1 -1
  41. data/sample_app_rails_4/spec/compare_mocker_and_record_spec.rb +194 -7
  42. data/sample_app_rails_4/spec/micropost_mock_spec.rb +145 -0
  43. data/sample_app_rails_4/spec/mocks/micropost_mock.rb +81 -55
  44. data/sample_app_rails_4/spec/mocks/relationship_mock.rb +85 -54
  45. data/sample_app_rails_4/spec/mocks/user_mock.rb +71 -72
  46. data/sample_app_rails_4/spec/reload_spec.rb +1 -1
  47. data/sample_app_rails_4/spec/user_mock_spec.rb +25 -7
  48. data/spec/lib/acitve_mock/queriable_spec.rb +207 -0
  49. data/spec/lib/active_mocker/db_to_ruby_type_spec.rb +124 -0
  50. data/spec/lib/active_mocker/loaded_mocks_spec.rb +167 -0
  51. data/spec/lib/active_mocker/logger_spec.rb +32 -0
  52. data/spec/lib/active_mocker/model_reader_spec.rb +79 -28
  53. data/spec/lib/active_mocker/model_schema/generate_spec.rb +111 -0
  54. data/spec/lib/active_mocker/model_schema_spec.rb +145 -0
  55. data/spec/lib/model.rb +2 -1
  56. data/spec/lib/reparameterize_spec.rb +202 -0
  57. data/spec/unit_logger.rb +2 -2
  58. metadata +55 -35
  59. data/lib/active_hash/ar_api.rb +0 -77
  60. data/lib/active_hash/init.rb +0 -32
  61. data/lib/active_mocker/collection/association.rb +0 -12
  62. data/lib/active_mocker/collection/base.rb +0 -65
  63. data/lib/active_mocker/collection/relation.rb +0 -11
  64. data/lib/active_mocker/mock_class_methods.rb +0 -92
  65. data/lib/active_mocker/mock_instance_methods.rb +0 -84
  66. data/lib/active_mocker/mock_requires.rb +0 -10
  67. data/spec/lib/active_mocker/collection.rb +0 -94
@@ -0,0 +1,26 @@
1
+ require 'active_support'
2
+
3
+ begin
4
+ require 'active_support/core_ext'
5
+ rescue
6
+ end
7
+
8
+ begin
9
+ require 'active_model'
10
+ require 'active_model/naming'
11
+ rescue LoadError
12
+ end
13
+ require 'active_mocker/logger'
14
+ require 'active_mock/queries'
15
+ require 'active_mock/collection'
16
+ require 'active_mock/association'
17
+ require 'active_mock/has_many'
18
+ require 'active_mock/has_and_belongs_to_many'
19
+ require 'active_mocker/loaded_mocks'
20
+ require 'active_mock/do_nothing_active_record_methods'
21
+ require 'active_mock/next_id'
22
+ require 'active_mock/creators'
23
+ require 'active_mock/records'
24
+ require 'active_mock/base'
25
+ require 'virtus'
26
+ require 'active_mock/object_inspect'
@@ -14,6 +14,24 @@ module ActiveMocker
14
14
  extend UnknownModule
15
15
  extend ConstMissing
16
16
 
17
+ def self.table_name=(table_name)
18
+ @table_name = table_name
19
+ end
20
+
21
+ def self.table_name
22
+ @table_name ||= nil
23
+ @table_name
24
+ end
25
+
26
+ def self.primary_key=(primary_key)
27
+ @primary_key = primary_key
28
+ end
29
+
30
+ def self.primary_key
31
+ @primary_key ||= nil
32
+ @primary_key
33
+ end
34
+
17
35
  def self.const_missing(name)
18
36
  # Logger_.debug "ActiveMocker :: Can't can't find Constant #{name} from class #{}."
19
37
  end
@@ -1,5 +1,5 @@
1
1
  require 'ostruct'
2
-
2
+ require 'active_support/core_ext/string'
3
3
  module Relationships
4
4
 
5
5
  def self.included(base)
@@ -25,26 +25,77 @@ module Relationships
25
25
  has_and_belongs_to_many + has_many
26
26
  end
27
27
 
28
- private
28
+ class Relationship
29
+ attr_reader :name
30
+ def initialize(name, options={})
31
+ @name = name
32
+ @options = options.reduce(HashWithIndifferentAccess.new, :merge)
33
+ end
34
+
35
+ def options
36
+ @options.symbolize_keys
37
+ end
38
+
39
+ def through
40
+ options[:through]
41
+ end
42
+
43
+ def class_name
44
+ options[:class_name] || name.to_s.camelize.singularize
45
+ end
46
+
47
+ def foreign_key
48
+ options[:foreign_key] || name.to_s.foreign_key
49
+ end
50
+
51
+ def join_table
52
+ options[:join_table]
53
+ end
54
+ end
55
+
56
+ class HasMany < Relationship
57
+
58
+ attr_reader :klass_name
59
+
60
+ def initialize(name, klass_name, options={})
61
+ @klass_name = klass_name
62
+ super(name, options)
63
+ end
64
+
65
+ def foreign_key
66
+ options[:foreign_key] || klass_name.to_s.foreign_key
67
+ end
68
+
69
+ end
29
70
 
30
71
  def has_many(*args)
31
72
  @has_many ||= []
32
- @has_many.push [args.first]
73
+ @has_many.push HasMany.new(args.shift, self.name, args)
74
+ end
75
+
76
+ class HasOne < Relationship
33
77
  end
34
78
 
35
79
  def has_one(*args)
36
80
  @has_one ||= []
37
- @has_one.push [args.first]
81
+ @has_one.push HasOne.new(args.shift, args)
82
+ end
83
+
84
+ class BelongsTo < Relationship
38
85
  end
39
86
 
40
87
  def belongs_to(*args)
41
88
  @belongs_to ||= []
42
- @belongs_to.push [args.first]
89
+ @belongs_to.push BelongsTo.new(args.shift, args)
90
+ end
91
+
92
+
93
+ class HasAndBelongsToMany < Relationship
43
94
  end
44
95
 
45
96
  def has_and_belongs_to_many(*args)
46
97
  @has_and_belongs_to_many ||= []
47
- @has_and_belongs_to_many.push [args.first]
98
+ @has_and_belongs_to_many.push HasAndBelongsToMany.new(args.shift, args)
48
99
  end
49
100
 
50
101
  end
@@ -49,7 +49,7 @@ module ActiveMocker
49
49
  end
50
50
 
51
51
  def create_table(name, options={}, &block)
52
- tables << ActiveMocker::Table.new(name, CreateTable.new.instance_eval(&block))
52
+ tables << ActiveMocker::Table.new(name, options[:id], CreateTable.new.instance_eval(&block))
53
53
  end
54
54
 
55
55
  def method_missing(meth, *args)
@@ -2,7 +2,7 @@ module Scope
2
2
 
3
3
  def scope(method_name, proc)
4
4
  singleton_class.class_eval do
5
- params = Reparameterize.call(proc.parameters)
5
+ params = ActiveMocker::Reparameterize.call(proc.parameters)
6
6
  block = eval("lambda { |#{params}| }")
7
7
  define_method(method_name, block)
8
8
  end
@@ -3,7 +3,7 @@ module ActiveMocker
3
3
  module UnknownClassMethod
4
4
 
5
5
  def method_missing(meth, *args)
6
- Logger.debug "ActiveMocker :: #{meth} called from class #{self.name} is unknown and will not be available in mock."
6
+ Logger.debug "ActiveMocker :: DEBUG :: #{meth} called from class #{self.name} is unknown and will not be available in mock.\n"
7
7
  end
8
8
 
9
9
  end
@@ -3,20 +3,21 @@ module ActiveMocker
3
3
  module UnknownModule
4
4
 
5
5
  def include(_module)
6
- begin
7
- super _module
8
- rescue => e
9
- Logger.debug e
10
- Logger.debug "ActiveMocker :: Can't include module #{_module} from class #{self.name}.\n #{caller}"
11
-
12
- end
6
+ try_and_log('include', _module)
13
7
  end
14
8
 
15
9
  def extend(_module)
10
+ try_and_log('extend', _module)
11
+ end
12
+
13
+ private
14
+
15
+ def try_and_log(type, name)
16
16
  begin
17
17
  super _module
18
- rescue
19
- Logger.debug "ActiveMocker :: Can't extend module #{_module} from class #{self.name}..\n #{caller}"
18
+ rescue => e
19
+ Logger.debug "ActiveMocker :: Debug :: Can't #{type} module #{name} from class #{self.name}.\n\t\t\t\t\t\t\t\t#{caller}\n"
20
+ Logger.debug "\t\t\t\t\t\t\t\t#{e}"
20
21
  end
21
22
  end
22
23
 
@@ -0,0 +1,26 @@
1
+ module ActiveMocker
2
+ class DBToRubyType
3
+
4
+ def self.call(type)
5
+ case type
6
+ when :integer
7
+ Fixnum
8
+ when :float
9
+ Float
10
+ when :decimal
11
+ BigDecimal
12
+ when :timestamp, :time
13
+ Time
14
+ when :datetime
15
+ DateTime
16
+ when :date
17
+ Date
18
+ when :text, :string, :binary
19
+ String
20
+ when :boolean
21
+ Axiom::Types::Boolean
22
+ end
23
+ end
24
+
25
+ end
26
+ end
@@ -7,9 +7,12 @@ module ActiveMocker
7
7
  def initialize(name, type, options)
8
8
  @name = name
9
9
  @type = type
10
- @options = {}
11
- options.each{|hash| @options[hash.keys.first] = hash.values.first}
12
- create_option_methods
10
+ @primary_key
11
+ @options = options.first || {}
12
+ end
13
+
14
+ def primary_key
15
+ @primary_key
13
16
  end
14
17
 
15
18
  def to_h
@@ -18,11 +21,16 @@ module ActiveMocker
18
21
 
19
22
  alias_method :to_hash, :to_h
20
23
 
21
- def create_option_methods
22
- options.each do |key, value|
23
- self.instance_variable_set("@#{key}", value)
24
- self.class.send(:attr_accessor, key)
25
- end
24
+ def default
25
+ options[:default]
26
+ end
27
+
28
+ def precision
29
+ options[:precision]
30
+ end
31
+
32
+ def scale
33
+ options[:scale]
26
34
  end
27
35
 
28
36
  end
@@ -31,192 +31,37 @@ class Generate
31
31
  "#{model_name}Mock".constantize
32
32
  end
33
33
 
34
- def model_definition(table)
35
- return @model_definition if @model_definition_table == table
36
- @model_definition_table = table
37
- @model_definition = ModelReader.new({model_dir: model_dir, file_reader: model_file_reader}).parse(table_to_model_file(table))
38
- end
39
-
40
- def table_to_model_file(table)
41
- table.singularize
42
- end
43
-
44
- def table_to_class_name(table)
45
- table.camelize.singularize
46
- end
47
-
48
- def schema_reader
49
- SchemaReader.new({schema_file: schema_file, file_reader: schema_file_reader}).search(nil)
50
- end
51
-
52
- def tables
53
- schema_reader
34
+ def generate_model_schema
35
+ ActiveMocker::ModelSchema::Generate.new(schema_file: schema_file, models_dir: model_dir, logger: logger).run
54
36
  end
55
37
 
56
38
  def create_template
57
39
  mocks_created = 0
58
- tables.each do |table|
59
- begin
60
- mock_template = MockTemplate.new
61
- # Schema Attributes
62
- mock_template.class_name = mock_class_name(table.name)
63
- mock_template.attribute_names = table.column_names
64
- mock_template.attributes = field_type_to_class(table.fields)
65
- mock_template.default_attributes =default_attr_values(table.fields)
66
-
67
- # Model associations
68
- mock_template.single_associations = model_definition(table.name).single_relationships
69
- mock_template.collection_associations = model_definition(table.name).collections
70
- mock_template.association_names = [*model_definition(table.name).single_relationships, *model_definition(table.name).collections]
71
- mock_template.associations = associations(mock_template.association_names)
72
-
73
- # Model Methods
74
- mock_template.instance_methods = instance_methods(table.name).methods
75
- mock_template.model_instance_methods = instance_methods(table.name).model_instance_methods
76
- mock_template.class_methods = class_methods(table.name).methods
77
- mock_template.model_class_methods = class_methods(table.name).model_class_methods
78
-
79
- klass_str = mock_template.render( File.open(File.join(File.expand_path('../', __FILE__), 'mock_template.erb')).read)
40
+ models = generate_model_schema
41
+ models.each do |model|
42
+ # begin
43
+ klass_str = ''
44
+ klass_str = model.render(File.open(File.join(File.expand_path('../', __FILE__), 'mock_template.erb')).read, mock_append_name)
80
45
  FileUtils::mkdir_p mock_dir unless File.directory? mock_dir
81
- File.open(File.join(mock_dir,"#{table.name.singularize}_mock.rb"), 'w').write(klass_str)
82
- logger.info "saving mock #{table_to_model_file(table.name)} to #{mock_dir}"
83
-
84
- rescue Exception => exception
85
- logger.debug $!.backtrace
86
- logger.debug exception
87
- logger.info "failed to load #{table_to_model_file(table.name)} model"
88
- next
89
- end
46
+ File.open(File.join(mock_dir,"#{model.table_name.singularize}_mock.rb"), 'w').write(klass_str)
47
+ logger.info "saving mock #{model.class_name} to #{mock_dir}"
48
+
49
+ # rescue Exception => exception
50
+ # logger.debug $!.backtrace
51
+ # logger.debug exception
52
+ # logger.info "failed to load #{model} model"
53
+ # next
54
+ # end
90
55
  mocks_created += 1
91
56
 
92
57
  end
93
- logger.info "Generated #{mocks_created} of #{tables.count} mocks"
94
- end
95
-
96
- def field_type_to_class(fields)
97
- fields.map do |field|
98
- field.type = case field.type
99
- when :integer then
100
- Fixnum
101
- when :float then
102
- Float
103
- when :decimal then
104
- BigDecimal
105
- when :timestamp, :time then
106
- Time
107
- when :datetime then
108
- DateTime
109
- when :date then
110
- Date
111
- when :text, :string, :binary then
112
- String
113
- when :boolean then
114
- ::Virtus::Attribute::Boolean
115
- end
116
- field
117
- end
118
-
119
- end
120
-
121
- def mock_class_name(table_name)
122
- "#{table_to_class_name(table_name)}Mock"
123
- end
124
-
125
- def associations(names)
126
- hash = {}
127
- names.each do |name|
128
- hash[name] = nil
129
- end
130
- hash
131
- end
132
-
133
- def default_attr_values(fields)
134
- attributes = {}
135
- fields.each do |f|
136
- if f.options[:default].nil?
137
- attributes[f.name] = nil
138
- else
139
- value = f.default.class == String ? f.default : f.default
140
- attributes[f.name] = value
141
- end
142
- end
143
- attributes
144
- end
145
-
146
- def instance_methods(table_name)
147
- model_instance_methods = []
148
- instance_methods = Methods.new
149
- instance_methods.methods = model_definition(table_name).instance_methods_with_arguments.map do |method|
150
- m = method.keys.first.to_s
151
- if m == :attributes
152
- logger.warn "ActiveMocker Depends on the #attributes method. It will not be redefined for the model."
153
- next
154
- end
155
- params = Reparameterize.call(method.values.first)
156
- params_pass = Reparameterize.call(method.values.first, true)
157
-
158
- instance_method = Method.new
159
- instance_method.method = m
160
- instance_method.params = params
161
-
162
- instance_method.params_pass = params_pass
163
- model_instance_methods << m
164
- instance_method
165
- end
166
- instance_methods.model_instance_methods = {}
167
- model_instance_methods.each{|meth| instance_methods.model_instance_methods[meth] = :not_implemented }
168
- instance_methods
169
- end
170
-
171
- def class_methods(table_name)
172
- model_class_methods = []
173
- class_methods = Methods.new
174
- class_methods.methods = model_definition(table_name).class_methods_with_arguments.map do |method|
175
- m = method.keys.first.to_s
176
- params = Reparameterize.call(method.values.first)
177
- params_pass = Reparameterize.call(method.values.first, true)
178
-
179
- class_method = Method.new
180
- class_method.method = m
181
- class_method.params = params
182
- class_method.params_pass = params_pass
183
- model_class_methods << m
184
- class_method
185
- end
186
- class_methods.model_class_methods = {}
187
- model_class_methods.each { |meth| class_methods.model_class_methods[meth] = :not_implemented }
188
- class_methods
189
- end
190
-
191
- class Method
192
- attr_accessor :method, :params, :params_pass
58
+ logger.info "Generated #{mocks_created} of #{models.count} mocks"
193
59
  end
194
60
 
195
- class Methods
196
- attr_accessor :methods, :model_class_methods, :model_instance_methods
61
+ def mock_append_name
62
+ 'Mock'
197
63
  end
198
64
 
199
- class MockTemplate
200
- attr_accessor :attributes,
201
- :single_associations,
202
- :collection_associations,
203
- :class_name,
204
- :association_names,
205
- :attribute_names,
206
- :column_names,
207
- :instance_methods,
208
- :class_methods,
209
- :model_instance_methods,
210
- :model_class_methods,
211
- :default_attributes,
212
- :associations
213
-
214
- def render(template)
215
- ERB.new(template, nil, '-').result(binding)
216
- end
217
- end
218
-
219
-
220
65
  end
221
66
  end
222
67