active_mocker 1.2.4 → 1.3
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.
- checksums.yaml +4 -4
- data/README.md +11 -11
- data/active_mocker.gemspec +1 -1
- data/lib/active_hash/ar_api.rb +23 -4
- data/lib/active_hash/init.rb +5 -1
- data/lib/active_mocker.rb +0 -1
- data/lib/active_mocker/collection/association.rb +12 -0
- data/lib/active_mocker/collection/base.rb +65 -0
- data/lib/active_mocker/collection/queries.rb +105 -0
- data/lib/active_mocker/collection/relation.rb +11 -0
- data/lib/active_mocker/mock_instance_methods.rb +3 -1
- data/lib/active_mocker/mock_requires.rb +3 -1
- data/lib/active_mocker/mock_template.erb +6 -6
- data/lib/active_mocker/version.rb +1 -1
- data/sample_app_rails_4/config/application.rb +1 -1
- data/sample_app_rails_4/db/schema.rb +1 -0
- data/sample_app_rails_4/spec/compare_mocker_and_record_spec.rb +496 -42
- data/sample_app_rails_4/spec/mocks/micropost_mock.rb +19 -10
- data/sample_app_rails_4/spec/mocks/relationship_mock.rb +8 -8
- data/sample_app_rails_4/spec/mocks/user_mock.rb +22 -22
- data/sample_app_rails_4/spec/user_mock_spec.rb +0 -1
- data/spec/lib/active_mocker/{collection_association_spec.rb → collection.rb} +4 -5
- data/spec/lib/active_mocker/generate_spec.rb +19 -30
- metadata +12 -11
- data/lib/active_hash/find_by.rb +0 -31
- data/lib/active_hash/update.rb +0 -18
- data/lib/active_mocker/collection_association.rb +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 469e40ce463c581d08ddf136c0a2e91082680baf
|
4
|
+
data.tar.gz: 347c0a56642bddfe071b63022705ada95e85baf9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e8c4e249f4eb55352ce3f3815a3f0daef791109970bdbf6e3fd89f035afe95967a583d4133c7b70fe20b98bac0aadca964f5bc512b99aa932ff335dc1ebfc90c
|
7
|
+
data.tar.gz: c672f2b89c749780ac4797357d2fd15e01a0d816fcd36f41c9246f3bf5c4b76be3cc721ab024c7f5dca81d89ab1fca15d2736b301c8beb65b6208875d7f491e8
|
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# ActiveMocker
|
2
2
|
[](https://travis-ci.org/zeisler/active_mocker)
|
3
3
|
|
4
|
-
Creates mocks from Active Record models. Allows your test suite to run very fast by not loading Rails or hooking to a database. It parse the schema definition and the
|
4
|
+
Creates mocks from Active Record models. Allows your test suite to run very fast by not loading Rails or hooking to a database. It parse the schema definition and the defined methods on a model then saves a ruby file that can be included with a test. Mocks are regenerated when the schema is modified so your mocks will not go stale. This prevents the case where your units tests pass but production code is failing.
|
5
5
|
|
6
6
|
Example from a real app
|
7
7
|
|
@@ -166,27 +166,28 @@ Here is an example of a rake task to regenerate mocks after every schema modifia
|
|
166
166
|
### ActiveRecord supported methods
|
167
167
|
**class methods**
|
168
168
|
|
169
|
-
* new
|
170
|
-
* create
|
169
|
+
* new
|
170
|
+
* create/create!
|
171
171
|
* column_names
|
172
172
|
* find
|
173
|
-
* find_by
|
174
|
-
* find_by!
|
173
|
+
* find_by/find_by!
|
175
174
|
* find_or_create_by
|
176
175
|
* find_or_initialize_by
|
177
|
-
* where
|
176
|
+
* where(conditions_hash)
|
178
177
|
* delete_all/destroy_all
|
178
|
+
* delete_all(conditions_hash)
|
179
|
+
* destroy(id)/delete(id)
|
179
180
|
* all
|
180
181
|
* count
|
181
182
|
* first/last
|
183
|
+
|
182
184
|
|
183
185
|
**instance methods**
|
184
186
|
|
185
|
-
* attributes
|
187
|
+
* attributes
|
186
188
|
* update
|
187
|
-
* save
|
188
|
-
* write_attribute - (private, can be used within an included module)
|
189
|
-
* read_attribute - (private)
|
189
|
+
* save/save!
|
190
|
+
* write_attribute/read_attribute - (private, can be used within an included module)
|
190
191
|
|
191
192
|
**has_many associations**
|
192
193
|
|
@@ -210,7 +211,6 @@ Here is an example of a rake task to regenerate mocks after every schema modifia
|
|
210
211
|
|
211
212
|
* Model names and table names must follow the default ActiveRecord naming pattern.
|
212
213
|
* Included/extended module methods will not be included on the mock. I suggest you keep domain logic out of the model and only add database queries. Domain logic can be put into modules and then included into the mock during test setup.
|
213
|
-
* Deleting one record at a time is not support, this is a limitation of ActiveHash.
|
214
214
|
* Queries will not call other mocks classes, for example when using `where` all attributes must reside inside of each record.
|
215
215
|
|
216
216
|
## Inspiration
|
data/active_mocker.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Dustin Zeisler"]
|
10
10
|
spec.email = ["dustin@zive.me"]
|
11
11
|
spec.summary = %q{Creates mocks from Active Record models. Allows your test suite to run very fast by not loading Rails or hooking to a database.}
|
12
|
-
spec.description = %q{Creates mocks from Active Record models. Allows your test suite to run very fast by not loading Rails or hooking to a database. It parse the schema definition and the
|
12
|
+
spec.description = %q{Creates mocks from Active Record models. Allows your test suite to run very fast by not loading Rails or hooking to a database. It parse the schema definition and the defined methods on a model then saves a ruby file that can be included with a test. Mocks are regenerated when the schema is modified so your mocks will not go stale. This prevents the case where your units tests pass but production code is failing.}
|
13
13
|
spec.homepage = "https://github.com/zeisler/active_mocker"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
data/lib/active_hash/ar_api.rb
CHANGED
@@ -1,12 +1,12 @@
|
|
1
|
-
require_relative 'update'
|
2
|
-
require_relative 'find_by'
|
3
1
|
require_relative 'init'
|
2
|
+
require_relative '../active_mocker/collection/queries'
|
3
|
+
require_relative '../active_mocker/collection/base'
|
4
|
+
require_relative '../active_mocker/collection/relation'
|
4
5
|
module ActiveMocker
|
5
6
|
module ActiveHash
|
6
7
|
|
7
8
|
module ARApi
|
8
9
|
|
9
|
-
include ::ActiveHash::ARApi::Update
|
10
10
|
include ::ActiveHash::ARApi::Init
|
11
11
|
|
12
12
|
def delete
|
@@ -16,12 +16,27 @@ module ActiveMocker
|
|
16
16
|
records.delete_at(index)
|
17
17
|
end
|
18
18
|
|
19
|
+
def update(options={})
|
20
|
+
options.each do |method, value|
|
21
|
+
send("#{method}=", value)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
19
26
|
def self.included(base)
|
20
27
|
base.extend(ClassMethods)
|
21
28
|
end
|
22
29
|
|
23
30
|
module ClassMethods
|
24
|
-
include ::
|
31
|
+
include ActiveMocker::Collection::Queries
|
32
|
+
|
33
|
+
def create(attributes = {}, &block)
|
34
|
+
record = new(attributes)
|
35
|
+
record = new(attributes, &block) if block_given?
|
36
|
+
record.save
|
37
|
+
mark_dirty
|
38
|
+
record
|
39
|
+
end
|
25
40
|
|
26
41
|
def find_or_create_by(attributes)
|
27
42
|
find_by(attributes) || create(attributes)
|
@@ -35,6 +50,10 @@ module ActiveMocker
|
|
35
50
|
find(id).delete
|
36
51
|
end
|
37
52
|
|
53
|
+
def to_a
|
54
|
+
@records
|
55
|
+
end
|
56
|
+
|
38
57
|
alias_method :destroy, :delete
|
39
58
|
|
40
59
|
def delete_all(options=nil)
|
data/lib/active_hash/init.rb
CHANGED
@@ -6,8 +6,9 @@ module ActiveHash
|
|
6
6
|
|
7
7
|
attr_reader :associations, :types
|
8
8
|
|
9
|
-
def initialize(attributes = {})
|
9
|
+
def initialize(attributes = {}, &block)
|
10
10
|
@types = {}
|
11
|
+
yield self if block_given?
|
11
12
|
attributes.each do |key, value|
|
12
13
|
begin
|
13
14
|
send "#{key}=", value
|
@@ -17,6 +18,9 @@ module ActiveHash
|
|
17
18
|
end
|
18
19
|
|
19
20
|
end
|
21
|
+
|
22
|
+
|
23
|
+
|
20
24
|
end
|
21
25
|
end
|
22
26
|
|
data/lib/active_mocker.rb
CHANGED
@@ -16,7 +16,6 @@ require 'active_mocker/active_record'
|
|
16
16
|
require 'active_mocker/model_reader'
|
17
17
|
require 'active_mocker/schema_reader'
|
18
18
|
require 'active_mocker/active_record/schema'
|
19
|
-
require 'active_mocker/collection_association'
|
20
19
|
require 'active_mocker/active_record'
|
21
20
|
require 'active_mocker/model_reader'
|
22
21
|
require 'active_mocker/reparameterize'
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module ActiveMocker
|
2
|
+
|
3
|
+
module Collection
|
4
|
+
|
5
|
+
|
6
|
+
class Base
|
7
|
+
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
def initialize(collection=[])
|
11
|
+
@collection = [*collection]
|
12
|
+
end
|
13
|
+
|
14
|
+
def <<(*records)
|
15
|
+
collection.concat(records.flatten)
|
16
|
+
end
|
17
|
+
|
18
|
+
delegate :take, :push, :clear, :first, :last, :concat, :replace, :distinct, :uniq, :count, :size, :length, :empty?, :any?, :include?, :delete, to: :collection
|
19
|
+
alias distinct uniq
|
20
|
+
|
21
|
+
# def delete(obj)
|
22
|
+
# collection.delete(obj)
|
23
|
+
# end
|
24
|
+
|
25
|
+
def order(key)
|
26
|
+
self.class.new(collection.sort_by{ |item| item.send(key) })
|
27
|
+
end
|
28
|
+
|
29
|
+
def reverse_order
|
30
|
+
self.class.new(collection.reverse)
|
31
|
+
end
|
32
|
+
|
33
|
+
def select(&block)
|
34
|
+
self.class.new(collection.select(&block))
|
35
|
+
end
|
36
|
+
|
37
|
+
def each(&block)
|
38
|
+
self.class.new(collection.each do |item|
|
39
|
+
block.call(item)
|
40
|
+
end)
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_a
|
44
|
+
@collection
|
45
|
+
end
|
46
|
+
|
47
|
+
def ==(val)
|
48
|
+
return false if val.nil?
|
49
|
+
collection.hash == val.hash
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def collection
|
55
|
+
@collection
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
|
63
|
+
|
64
|
+
|
65
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module ActiveMocker
|
2
|
+
|
3
|
+
class RecordNotFound < Exception
|
4
|
+
|
5
|
+
end
|
6
|
+
module Collection
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
module Queries
|
11
|
+
|
12
|
+
def delete_all
|
13
|
+
all.map(&:delete)
|
14
|
+
end
|
15
|
+
|
16
|
+
def destroy_all
|
17
|
+
delete_all
|
18
|
+
end
|
19
|
+
|
20
|
+
def all(options={})
|
21
|
+
if options.has_key?(:conditions)
|
22
|
+
where(options[:conditions])
|
23
|
+
else
|
24
|
+
Relation.new( to_a || [] )
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class WhereNotChain
|
29
|
+
|
30
|
+
def initialize(collection)
|
31
|
+
@collection = collection
|
32
|
+
end
|
33
|
+
|
34
|
+
def not(options={})
|
35
|
+
@collection.reject do |record|
|
36
|
+
options.all? { |col, match| record.send(col) == match }
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
def where(options=nil)
|
43
|
+
return WhereNotChain.new(all) if options.nil?
|
44
|
+
all.select do |record|
|
45
|
+
options.all? { |col, match| record.send(col) == match }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def find(ids)
|
50
|
+
ids_array = [*ids]
|
51
|
+
results = ids_array.map do |id|
|
52
|
+
where(id: id).first
|
53
|
+
end
|
54
|
+
return Relation.new(results) if ids.class == Array
|
55
|
+
return results.first
|
56
|
+
end
|
57
|
+
|
58
|
+
def update_all(options)
|
59
|
+
all.each{ |i| i.update(options)}
|
60
|
+
end
|
61
|
+
|
62
|
+
def find_by(options = {})
|
63
|
+
send(:where, options).first
|
64
|
+
end
|
65
|
+
|
66
|
+
def find_by!(options={})
|
67
|
+
result = find_by(options)
|
68
|
+
raise RecordNotFound if result.blank?
|
69
|
+
result
|
70
|
+
end
|
71
|
+
|
72
|
+
def limit(num)
|
73
|
+
Relation.new(all.take(num))
|
74
|
+
end
|
75
|
+
|
76
|
+
def sum(key)
|
77
|
+
values = values_by_key(key)
|
78
|
+
values.inject { |sum, n| sum + n }
|
79
|
+
end
|
80
|
+
|
81
|
+
def average(key)
|
82
|
+
values = values_by_key(key)
|
83
|
+
total = values.inject { |sum, n| sum + n }
|
84
|
+
BigDecimal.new(total) / BigDecimal.new(values.count)
|
85
|
+
end
|
86
|
+
|
87
|
+
def minimum(key)
|
88
|
+
values_by_key(key).min_by{|i| i }
|
89
|
+
end
|
90
|
+
|
91
|
+
def maximum(key)
|
92
|
+
values_by_key(key).max_by { |i| i }
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
def values_by_key(key)
|
98
|
+
all.map { |obj| obj.send(key) }
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
@@ -1,4 +1,6 @@
|
|
1
|
-
require 'active_mocker/
|
1
|
+
require 'active_mocker/collection/queries'
|
2
|
+
require 'active_mocker/collection/base'
|
3
|
+
require 'active_mocker/collection/association'
|
2
4
|
require 'active_mocker/mock_class_methods'
|
3
5
|
require 'active_mocker/mock_instance_methods'
|
4
6
|
require 'active_hash'
|
@@ -6,10 +6,10 @@ class <%= class_name %> < ::ActiveHash::Base
|
|
6
6
|
include ActiveMocker::MockInstanceMethods
|
7
7
|
extend ActiveMocker::MockClassMethods
|
8
8
|
|
9
|
-
def initialize(attributes
|
9
|
+
def initialize(attributes={}, &block)
|
10
10
|
@attributes = HashWithIndifferentAccess.new(<%= default_attributes %>)
|
11
11
|
@associations = HashWithIndifferentAccess.new(<%= associations %>)
|
12
|
-
super(attributes)
|
12
|
+
super(attributes, &block)
|
13
13
|
end
|
14
14
|
|
15
15
|
|
@@ -18,7 +18,7 @@ class <%= class_name %> < ::ActiveHash::Base
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def self.attribute_names
|
21
|
-
@attribute_names = <%= attribute_names
|
21
|
+
@attribute_names = <%= attribute_names %>
|
22
22
|
end
|
23
23
|
|
24
24
|
##################################
|
@@ -26,7 +26,7 @@ class <%= class_name %> < ::ActiveHash::Base
|
|
26
26
|
##################################
|
27
27
|
<% attributes.each do |meth| %>
|
28
28
|
def <%= meth.name %>
|
29
|
-
|
29
|
+
@attributes['<%= meth.name %>']
|
30
30
|
end
|
31
31
|
|
32
32
|
def <%= meth.name %>=(val)
|
@@ -52,11 +52,11 @@ class <%= class_name %> < ::ActiveHash::Base
|
|
52
52
|
<% end -%>
|
53
53
|
<% collection_associations.each do |meth| %>
|
54
54
|
def <%= meth %>
|
55
|
-
associations['<%= meth %>'] ||= ActiveMocker::
|
55
|
+
associations['<%= meth %>'] ||= ActiveMocker::Collection::Association.new
|
56
56
|
end
|
57
57
|
|
58
58
|
def <%= meth %>=(val)
|
59
|
-
associations['<%= meth %>'] = ActiveMocker::
|
59
|
+
associations['<%= meth %>'] = ActiveMocker::Collection::Association.new(val)
|
60
60
|
end
|
61
61
|
<% end -%>
|
62
62
|
|
@@ -5,7 +5,7 @@
|
|
5
5
|
# require "rails/test_unit/railtie"
|
6
6
|
|
7
7
|
# Assets should be precompiled for production (so we don't need the gems loaded then)
|
8
|
-
Bundler.require(*Rails.groups(assets: %w(development test)))
|
8
|
+
# Bundler.require(*Rails.groups(assets: %w(development test)))
|
9
9
|
|
10
10
|
module SampleApp
|
11
11
|
class Application < Rails::Application
|