active_mocker 1.3.2 → 1.4.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.
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