active_mocker 1.7.beta3 → 1.7rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -6
- data/README.md +29 -26
- data/lib/active_mocker.rb +1 -0
- data/lib/active_mocker/mock.rb +1 -0
- data/lib/active_mocker/mock/base.rb +11 -9
- data/lib/active_mocker/mock/exceptions.rb +8 -0
- data/lib/active_mocker/mock/single_relation.rb +10 -5
- data/lib/active_mocker/mock/template_methods.rb +4 -0
- data/lib/active_mocker/mock_template.erb +12 -3
- data/lib/active_mocker/model_schema.rb +10 -0
- data/lib/active_mocker/task.rake +1 -1
- data/lib/active_mocker/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68969de12e9868e62ba53f40b2cfd31c9925228d
|
4
|
+
data.tar.gz: ea587d10b8bafe99584433f1dcda1f76365444c2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81f6b93e765428f446b9d548dc07b76db3bee38d9837cb8c9240b14f73ea215ddb663eadf0b22053abd710104332237a3317faaa1bce34f5d90da18a6ece6cf4
|
7
|
+
data.tar.gz: 4e9c1da0648d571e2d9130829639fac2baf081ed27367cc4c1c2757bb0ea0faa958af39e4a24687b6766651548f5f1b018d320d26e2baf9176f360cc976821a6
|
data/CHANGELOG.md
CHANGED
@@ -1,31 +1,49 @@
|
|
1
1
|
# Changelog
|
2
2
|
All notable changes to this project will be documented in this file.
|
3
|
-
|
3
|
+
|
4
|
+
## 1.7rc2 - 2014-10-10
|
5
|
+
|
6
|
+
### Enhancement
|
7
|
+
- Now will regenerate mock after `rake db:rollback`.
|
8
|
+
- Check added to see if mock was created with same running gem version of ActiveMocker. If they are not the same it will raise an error informing you to run `rake active_mocker:build`.
|
9
|
+
- belong_to and has_one relationships when assigned will in most cases assign it's self to the corresponding has_many or like association. See `test_rails_4_app/spec/active_record_compatible_api.rb` for supported detail of supported ActiveRecord features.
|
10
|
+
|
11
|
+
### Removed
|
12
|
+
- `ActiveMocker::Mock::Config.experimental` flag has been removed, these are now on by default.
|
13
|
+
|
14
|
+
## Added
|
15
|
+
- Class method `table_name`.
|
16
|
+
|
17
|
+
## 1.7.beta3 - 2014-09-25
|
4
18
|
|
5
19
|
### Fix
|
6
|
-
- Last beta introduced a
|
20
|
+
- Last beta introduced a bug where after assigning some associations they could not be read. Solution was to never access @associations directly inside mock.
|
7
21
|
|
8
|
-
## 1.7.beta2 -
|
22
|
+
## 1.7.beta2 - 2014-09-18
|
9
23
|
|
10
24
|
### Fix
|
11
25
|
- Bug where creating record with an id could cause a duplicate id error.
|
12
26
|
- Issue whenever an ActiveRecord Model has no schema behind it.
|
13
27
|
- Issue assigning association would fail, added guard to @associations to only read and write symbols.
|
14
28
|
|
15
|
-
## 1.7.beta1 -
|
29
|
+
## 1.7.beta1 - 2014-09-06
|
16
30
|
|
17
31
|
### Enhancement
|
18
32
|
- A class that Inherits a model now has the table of the parent.
|
19
33
|
- Use this option if you need to modify where the mock generation hooks into. `ActiveMocker::Config.model_base_classes = %w[ ActiveRecord::Base ]`
|
20
34
|
- When running `rake active_mocker:build` it will display the number of mocks that failed.
|
21
|
-
- Remove deprecated option `ActiveMocker.mock`
|
22
35
|
- Exceptions in mock generation no longer halt the rest of the mocks from generating.
|
23
36
|
- Add explicit message of what to do when a method is unimplemented.
|
24
37
|
- Will create own log file `log/active_mocker.log` it will be cleared on each generation.
|
25
38
|
- Attributes, associations, and scopes will now inherit from their parent class.
|
26
|
-
|
39
|
+
|
40
|
+
###Removed
|
41
|
+
- Remove deprecated option `ActiveMocker.mock`
|
27
42
|
- Remove Experimental feature reload
|
28
43
|
- Remove experimental flag for set foreign_key on collection for has_many, belongs_to, and has_one.
|
44
|
+
|
45
|
+
### Added
|
46
|
+
- Initialization of an abstract class will raise an error.
|
29
47
|
- `record._create_caller_locations` for debugging obj’s creation location.
|
30
48
|
|
31
49
|
### Fix
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
[![Dependency Status](https://gemnasium.com/zeisler/active_mocker.svg)](https://gemnasium.com/zeisler/active_mocker)
|
6
6
|
[![Gitter chat](https://badges.gitter.im/zeisler/active_mocker.png)](https://gitter.im/zeisler/active_mocker)
|
7
7
|
|
8
|
-
ActiveMocker creates mocks classes from ActiveRecord models. Allowing your test suite to run very fast by not loading Rails or hooking to a database. It parses the schema.rb and the defined methods on a model then generates a ruby file that can be included within a test. The mock file can be run by themselves and come with a partial implementation of ActiveRecord. Attributes and associations can be used just the same as in ActiveRecord. Methods will have the correct arguments but raise an
|
8
|
+
ActiveMocker creates mocks classes from ActiveRecord models. Allowing your test suite to run very fast by not loading Rails or hooking to a database. It parses the schema.rb and the defined methods on a model then generates a ruby file that can be included within a test. The mock file can be run by themselves and come with a partial implementation of ActiveRecord. Attributes and associations can be used just the same as in ActiveRecord. Methods will have the correct arguments but raise an NotImplementedError when called. Mocks are regenerated when the schema is modified so your mocks will not go stale; preventing the case where your units tests pass but production code fails.
|
9
9
|
|
10
10
|
Examples from a real apps
|
11
11
|
|
@@ -48,9 +48,12 @@ Ask a question in the [chat room](https://gitter.im/zeisler/active_mocker).
|
|
48
48
|
## Installation
|
49
49
|
|
50
50
|
Add this line to your application's Gemfile:
|
51
|
-
|
52
|
-
|
53
|
-
|
51
|
+
```ruby
|
52
|
+
group :development, :test do
|
53
|
+
gem 'active_mocker'
|
54
|
+
end
|
55
|
+
```
|
56
|
+
It needs to be in development as well as test because development is where mocks will be generated.
|
54
57
|
And then execute:
|
55
58
|
|
56
59
|
$ bundle
|
@@ -61,7 +64,7 @@ Or install it yourself as:
|
|
61
64
|
|
62
65
|
## Dependencies
|
63
66
|
* Tested with Rails 4.1 may work with older versions but not supported.
|
64
|
-
* Requires Ruby MRI
|
67
|
+
* Requires Ruby MRI >= 2.1.
|
65
68
|
|
66
69
|
|
67
70
|
## Setup
|
@@ -128,9 +131,9 @@ end
|
|
128
131
|
```
|
129
132
|
----------
|
130
133
|
|
131
|
-
* Assigning the tag `active_mocker:true` will stub any ActiveRecord model Constants for Mock classes in `it` or `before/after(:each)`. This removes any need for dependency injection. Write tests and code like you would normally.
|
134
|
+
* Assigning the tag `active_mocker:true` will stub any ActiveRecord model Constants for Mock classes in an `it` or a `before/after(:each)`. This removes any need for dependency injection. Write tests and code like you would normally.
|
132
135
|
* To stub any Constants in `before(:all)`, `after(:all)` use `mock_class('ClassName')`.
|
133
|
-
*
|
136
|
+
* Mock state will be cleaned up for you in an `after(:all)`. To clean state your self use `ActiveMocker::LoadedMocks.delete_all`.
|
134
137
|
|
135
138
|
---------
|
136
139
|
|
@@ -174,15 +177,12 @@ Person.new(first_name: "Dustin", last_name: "Zeisler")
|
|
174
177
|
|
175
178
|
## Mocking Methods
|
176
179
|
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
+
#### Rspec 3 Mocks - verify double
|
181
|
+
Verifying doubles are a stricter alternative to normal doubles that provide guarantees about
|
182
|
+
what is being verified. When using verifying doubles, RSpec will check that the methods
|
183
|
+
being stubbed are actually present on the underlying object if it is available.
|
184
|
+
[rspec-mocks/docs/verifying-doubles](https://relishapp.com/rspec/rspec-mocks/docs/verifying-doubles)
|
180
185
|
```ruby
|
181
|
-
Person.bar('baz')
|
182
|
-
=> RuntimeError : :: bar is not Implemented for Class :PersonMock
|
183
|
-
|
184
|
-
# Rspec 3 Mocks
|
185
|
-
|
186
186
|
RSpec.configure do |config|
|
187
187
|
config.mock_framework = :rspec
|
188
188
|
config.mock_with :rspec do |mocks|
|
@@ -190,6 +190,11 @@ RSpec.configure do |config|
|
|
190
190
|
mocks.verify_partial_doubles = true
|
191
191
|
end
|
192
192
|
end
|
193
|
+
```
|
194
|
+
|
195
|
+
```ruby
|
196
|
+
Person.bar('baz')
|
197
|
+
=> NotImplementedError: ::bar is not Implemented for Class :PersonMock. To continue stub the method.
|
193
198
|
|
194
199
|
allow(Person).to receive(:bar) do |name, type=nil|
|
195
200
|
"Now implemented with #{name} and #{type}"
|
@@ -240,13 +245,12 @@ end
|
|
240
245
|
```
|
241
246
|
--------------
|
242
247
|
```ruby
|
243
|
-
# Rspec 3 Mocks
|
244
248
|
allow(person).to receive(:bar) do |name, type=nil|
|
245
249
|
"Now implemented with #{name} and #{type}"
|
246
250
|
end
|
247
251
|
=> NoMethodError : undefined method `bar' for class ` PersonMock '
|
248
252
|
```
|
249
|
-
### Constants and Modules
|
253
|
+
### Constants and Modules
|
250
254
|
|
251
255
|
* Any locally defined modules will not be included or extended.
|
252
256
|
|
@@ -263,7 +267,7 @@ PersonMock::CONSTANT_VALUE
|
|
263
267
|
```
|
264
268
|
|
265
269
|
### Scoped Methods
|
266
|
-
*
|
270
|
+
* Any chained scoped methods will be available when the mock file that defines it is required. When called it raises a `NotImplementedError`, stub the method with a value to continue.
|
267
271
|
|
268
272
|
### Managing Mocks
|
269
273
|
|
@@ -275,14 +279,15 @@ ActiveMocker::LoadedMocks.delete_all
|
|
275
279
|
|
276
280
|
See [Documentation](http://rdoc.info/github/zeisler/active_mocker/master/ActiveMocker) for a complete list of methods and usage.
|
277
281
|
|
278
|
-
**
|
282
|
+
**Class Methods** - [docs](http://rdoc.info/github/zeisler/active_mocker/master/ActiveMocker/Mock/Base)
|
279
283
|
|
280
284
|
* new
|
281
285
|
* create/create!
|
282
286
|
* column_names/attribute_names
|
283
287
|
* delete_all/destroy_all
|
288
|
+
* table_name
|
284
289
|
|
285
|
-
**Query Methods**
|
290
|
+
**Query Methods** - [docs](http://rdoc.info/github/zeisler/active_mocker/master/ActiveMocker/Mock/Queries)
|
286
291
|
|
287
292
|
* all
|
288
293
|
* find
|
@@ -308,7 +313,7 @@ See [Documentation](http://rdoc.info/github/zeisler/active_mocker/master/ActiveM
|
|
308
313
|
* reverse_order
|
309
314
|
* limit
|
310
315
|
|
311
|
-
**Relation Methods**
|
316
|
+
**Relation Methods** - [docs](http://rdoc.info/github/zeisler/active_mocker/master/ActiveMocker/Mock/Collection)
|
312
317
|
* concat
|
313
318
|
* include
|
314
319
|
* push
|
@@ -319,7 +324,7 @@ See [Documentation](http://rdoc.info/github/zeisler/active_mocker/master/ActiveM
|
|
319
324
|
* any?
|
320
325
|
* many?
|
321
326
|
|
322
|
-
**instance methods**
|
327
|
+
**instance methods** - [docs](http://rdoc.info/github/zeisler/active_mocker/master/ActiveMocker/Mock/Queries)
|
323
328
|
|
324
329
|
* attributes
|
325
330
|
* update
|
@@ -349,10 +354,8 @@ See [Documentation](http://rdoc.info/github/zeisler/active_mocker/master/ActiveM
|
|
349
354
|
|
350
355
|
### Known Limitations
|
351
356
|
* Model names and table names must follow the default ActiveRecord naming pattern.
|
352
|
-
*
|
353
|
-
|
354
|
-
|
355
|
-
* Validation/Callbacks are not present in mocks. A Work around is putting the method into a module with required ActiveSupport/ActiveModel dependencies and make sure the code is supported by the mock.
|
357
|
+
* When an association is set in one object it may not always be reflective in other objects, especially when it is a non standard/custom association. See [test_rails_4_app/spec/active_record_compatible_api.rb](https://github.com/zeisler/active_mocker/blob/master/test_rails_4_app/spec/active_record_compatible_api.rb) for a complete list of supported associations.
|
358
|
+
* Validation/Callbacks are not supported.
|
356
359
|
* Sql queries, joins, etc will never be supported.
|
357
360
|
|
358
361
|
## Inspiration
|
data/lib/active_mocker.rb
CHANGED
data/lib/active_mocker/mock.rb
CHANGED
@@ -125,6 +125,16 @@ class Base
|
|
125
125
|
delete_all
|
126
126
|
end
|
127
127
|
|
128
|
+
def _find_associations_by_class(klass_name)
|
129
|
+
associations_by_class[klass_name.to_s]
|
130
|
+
end
|
131
|
+
|
132
|
+
def created_with(version)
|
133
|
+
raise UpdateMocksError.new(self.name, version, ActiveMocker::VERSION) if version != ActiveMocker::VERSION
|
134
|
+
end
|
135
|
+
|
136
|
+
private :created_with
|
137
|
+
|
128
138
|
end
|
129
139
|
|
130
140
|
def classes(klass)
|
@@ -283,7 +293,7 @@ class Base
|
|
283
293
|
|
284
294
|
# @api private
|
285
295
|
def read_association(attr, assign_if_value_nil=nil)
|
286
|
-
@associations[attr.to_sym] ||= assign_if_value_nil
|
296
|
+
@associations[attr.to_sym] ||= assign_if_value_nil.try(:call)
|
287
297
|
end
|
288
298
|
|
289
299
|
# @api private
|
@@ -306,13 +316,5 @@ class Base
|
|
306
316
|
|
307
317
|
end
|
308
318
|
|
309
|
-
def self.config
|
310
|
-
@config ||= Config.new
|
311
|
-
end
|
312
|
-
|
313
|
-
class Config
|
314
|
-
attr_accessor :experimental
|
315
|
-
end
|
316
|
-
|
317
319
|
end
|
318
320
|
end
|
@@ -25,6 +25,14 @@ module Mock
|
|
25
25
|
|
26
26
|
end
|
27
27
|
|
28
|
+
class UpdateMocksError < Exception
|
29
|
+
|
30
|
+
def initialize(name, mock_version, gem_version)
|
31
|
+
super("#{name} was built with #{mock_version} but the gem version is #{gem_version}. Run `rake active_mocker:build` to update.")
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
28
36
|
class NotImplementedError < Exception
|
29
37
|
end
|
30
38
|
|
@@ -7,14 +7,19 @@ module ActiveMocker
|
|
7
7
|
|
8
8
|
def initialize(item, child_self:, foreign_key:, foreign_id:)
|
9
9
|
@item = item
|
10
|
-
assign_associations(child_self, item)
|
10
|
+
assign_associations(child_self, item) if item.class <= Base
|
11
11
|
end
|
12
12
|
|
13
13
|
def assign_associations(child_self, item)
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
[*item.class._find_associations_by_class(child_self.class.send('mocked_class'))].each do |type, relations|
|
15
|
+
relations.each do |relation|
|
16
|
+
if item.send(relation).class <= Collection
|
17
|
+
item.send(relation) << child_self
|
18
|
+
else
|
19
|
+
item.send(:write_association, relation, child_self)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
18
23
|
end
|
19
24
|
|
20
25
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'active_mocker/mock'
|
2
2
|
|
3
3
|
class <%= class_name + @mock_append_name %> < <%= parent_class %>
|
4
|
+
created_with('<%= ActiveMocker::VERSION %>')
|
4
5
|
<% constants.each do |constant| -%>
|
5
6
|
<%= constant.first %> = <%= constant.last.inspect %>
|
6
7
|
<% end -%>
|
@@ -25,8 +26,12 @@ class <%= class_name + @mock_append_name %> < <%= parent_class %>
|
|
25
26
|
@associations ||= <%= associations %>.merge(super)
|
26
27
|
end
|
27
28
|
|
29
|
+
def associations_by_class
|
30
|
+
@associations_by_class ||= <%= associations_by_class %>.merge(super)
|
31
|
+
end
|
32
|
+
|
28
33
|
def mocked_class
|
29
|
-
|
34
|
+
<%= class_name.inspect %>
|
30
35
|
end
|
31
36
|
|
32
37
|
private :mocked_class
|
@@ -43,6 +48,10 @@ class <%= class_name + @mock_append_name %> < <%= parent_class %>
|
|
43
48
|
<%= abstract_class.inspect %>
|
44
49
|
end
|
45
50
|
|
51
|
+
def table_name
|
52
|
+
<%= table_name.inspect %> || super
|
53
|
+
end
|
54
|
+
|
46
55
|
end
|
47
56
|
|
48
57
|
##################################
|
@@ -124,7 +133,7 @@ class <%= class_name + @mock_append_name %> < <%= parent_class %>
|
|
124
133
|
<%= '# has_many' unless has_many.empty? -%>
|
125
134
|
<% has_many.each do |meth| %>
|
126
135
|
def <%= meth.name %>
|
127
|
-
read_association(:<%= meth.name %>, ActiveMocker::Mock::HasMany.new([],foreign_key: '<%= meth.foreign_key %>', foreign_id: self.id, relation_class: classes('<%= meth.class_name %>'), source: '<%= meth.source %>'))
|
136
|
+
read_association(:<%= meth.name %>, -> { ActiveMocker::Mock::HasMany.new([],foreign_key: '<%= meth.foreign_key %>', foreign_id: self.id, relation_class: classes('<%= meth.class_name %>'), source: '<%= meth.source %>') })
|
128
137
|
end
|
129
138
|
|
130
139
|
def <%= meth.name %>=(val)
|
@@ -134,7 +143,7 @@ class <%= class_name + @mock_append_name %> < <%= parent_class %>
|
|
134
143
|
<%= '# has_and_belongs_to_many' unless has_and_belongs_to_many.empty? -%>
|
135
144
|
<% has_and_belongs_to_many.each do |meth| %>
|
136
145
|
def <%= meth.name %>
|
137
|
-
read_association(:<%= meth.name %>, ActiveMocker::Mock::HasAndBelongsToMany.new([]))
|
146
|
+
read_association(:<%= meth.name %>, ->{ ActiveMocker::Mock::HasAndBelongsToMany.new([]) })
|
138
147
|
end
|
139
148
|
|
140
149
|
def <%= meth.name %>=(val)
|
@@ -146,6 +146,16 @@ module ActiveMocker
|
|
146
146
|
hash
|
147
147
|
end
|
148
148
|
|
149
|
+
def associations_by_class
|
150
|
+
hash = {}
|
151
|
+
relationships.each do |r|
|
152
|
+
hash[r.class_name] ||= {}
|
153
|
+
hash[r.class_name][r.type] ||= []
|
154
|
+
hash[r.class_name][r.type] << r.name
|
155
|
+
end
|
156
|
+
hash
|
157
|
+
end
|
158
|
+
|
149
159
|
def mock_name(klass_name)
|
150
160
|
klass_name + "Mock"
|
151
161
|
end
|
data/lib/active_mocker/task.rake
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_mocker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.7rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dustin Zeisler
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|