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.
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