active_mocker 1.1.23 → 1.2.pre

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +12 -22
  3. data/active_mocker.gemspec +1 -0
  4. data/lib/active_hash/init.rb +1 -1
  5. data/lib/active_mocker.rb +4 -5
  6. data/lib/active_mocker/active_record/schema.rb +2 -4
  7. data/lib/active_mocker/config.rb +6 -22
  8. data/lib/active_mocker/field.rb +3 -1
  9. data/lib/active_mocker/generate.rb +161 -0
  10. data/lib/active_mocker/mock_class_methods.rb +82 -0
  11. data/lib/active_mocker/mock_instance_methods.rb +81 -0
  12. data/lib/active_mocker/mock_requires.rb +12 -0
  13. data/lib/active_mocker/mock_task.rb +12 -0
  14. data/lib/active_mocker/mock_template.erb +84 -0
  15. data/lib/active_mocker/public_methods.rb +6 -2
  16. data/lib/active_mocker/schema_reader.rb +35 -16
  17. data/lib/active_mocker/table.rb +2 -0
  18. data/lib/active_mocker/version.rb +1 -1
  19. data/mocks/micropost_mock.rb +100 -0
  20. data/mocks/relationship_mock.rb +100 -0
  21. data/mocks/user_mock.rb +196 -0
  22. data/plan_mock.rb +2323 -0
  23. data/spec/lib/active_mocker/generate_spec.rb +49 -0
  24. data/spec/lib/active_mocker/{base_spec.rb → performance/base_spec.rb} +17 -37
  25. data/spec/lib/active_mocker/performance/large_schema.rb +3576 -0
  26. data/spec/lib/active_mocker/performance/migration/20140327205359_migration.rb +0 -0
  27. data/spec/lib/active_mocker/performance/schema_reader_spec.rb +96 -0
  28. data/spec/lib/active_mocker/schema_reader_spec.rb +12 -27
  29. data/spec/lib/compare_mocker_and_record_spec.rb +3 -2
  30. data/spec/lib/readme_spec.rb +205 -0
  31. data/spec/mocks/micropost_mock.rb +100 -0
  32. data/spec/mocks/relationship_mock.rb +100 -0
  33. data/spec/mocks/user_mock.rb +196 -0
  34. data/spec/mocks/user_mock_spec.rb +173 -0
  35. metadata +48 -9
  36. data/lib/active_mocker/base.rb +0 -356
  37. 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: 35394fa054b9991f64200432c22300c0338b5794
4
- data.tar.gz: 439c5e2cb084947588d5e9be24e1adef3169103b
3
+ metadata.gz: bbba1fbd943d80b9a68d611991326685d86ed5c4
4
+ data.tar.gz: bc4c0d888da88e4b9a678f3a9581f35657b286af
5
5
  SHA512:
6
- metadata.gz: b8116e203aefae67690da7552b188fbe3d36b9f8d40a4fa88a1a2deccacfaa7dcad891769795b8b61336c840be80fe819eb8540341c8ed5f9d03c6e8246f1455
7
- data.tar.gz: d53d2aaec5da61ecc346ddae968166016543bbf91d431e53d7f665a2814cac4c039f066cc1a7d4803d39fba33586e25249b821b8bec07acdde316978f3728645
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 @first_name="Dustin", @last_name="Zeisler">
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
- person_mock = PersonMock.new(first_name: "Dustin", last_name: "Zeisler", account: AccountMock.new)
93
- => NoMethodError: undefined method `first_name=' for #<PersonMock:0x007f860abf6b10>
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: #bar is not Implemented for Class: PersonMock
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(:baz) do
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
- => NameError: undefined method `bar' for class `PersonMock'
143
+ => NoMethodError: undefined method `bar' for class `PersonMock'
148
144
 
149
145
  ### ActiveRecord supported methods
150
- **Class methods**
146
+ **class methods**
151
147
 
152
- * create/new
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
- **Instance methods**
162
+ **instance methods**
166
163
 
167
- * attributes
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.
@@ -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"
@@ -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
- add_to_cache schema.tables.first
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)) if name == table_search
52
+ tables << ActiveMocker::Table.new(name, CreateTable.new.instance_eval(&block))
55
53
  end
56
54
 
57
55
  def method_missing(meth, *args)
@@ -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
- end
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
@@ -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
- define_singleton_method(key) {instance_variable_get("@#{key}")}
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