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
@@ -1,24 +1,46 @@
1
- require 'active_mocker/mock_requires'
2
- Object.send(:remove_const, "UserMock") if ActiveMocker.class_exists?("UserMock")
1
+ require 'active_mocker/active_mock'
2
+ Object.send(:remove_const, "UserMock") if Object.const_defined?("UserMock")
3
3
 
4
- class UserMock < ::ActiveHash::Base
5
- include ActiveMocker::ActiveHash::ARApi
6
- include ActiveMocker::MockInstanceMethods
7
- extend ActiveMocker::MockClassMethods
4
+ class UserMock < ActiveMock::Base
8
5
 
9
- def initialize(attributes={}, &block)
10
- @attributes = HashWithIndifferentAccess.new({"id"=>nil, "name"=>nil, "email"=>"", "credits"=>nil, "created_at"=>nil, "updated_at"=>nil, "password_digest"=>nil, "remember_token"=>true, "admin"=>false})
11
- @associations = HashWithIndifferentAccess.new({:microposts=>nil, :relationships=>nil, :followed_users=>nil, :reverse_relationships=>nil, :followers=>nil})
12
- super(attributes, &block)
13
- end
6
+ class << self
14
7
 
8
+ def attributes
9
+ @attributes ||= HashWithIndifferentAccess.new({"id"=>nil, "name"=>nil, "email"=>"", "credits"=>nil, "created_at"=>nil, "updated_at"=>nil, "password_digest"=>nil, "remember_token"=>true, "admin"=>false})
10
+ end
15
11
 
16
- def self.column_names
17
- ["id", "name", "email", "credits", "created_at", "updated_at", "password_digest", "remember_token", "admin"]
18
- end
12
+ def types
13
+ @types ||= { id: build_type(Fixnum), name: build_type(String), email: build_type(String), credits: build_type(BigDecimal), created_at: build_type(DateTime), updated_at: build_type(DateTime), password_digest: build_type(String), remember_token: build_type(Axiom::Types::Boolean), admin: build_type(Axiom::Types::Boolean) }
14
+ end
15
+
16
+ def associations
17
+ @associations ||= {:microposts=>nil, :relationships=>nil, :followed_users=>nil, :reverse_relationships=>nil, :followers=>nil}
18
+ end
19
+
20
+ def model_instance_methods
21
+ @model_instance_methods ||= {"feed"=>:not_implemented, "following?"=>:not_implemented, "follow!"=>:not_implemented, "unfollow!"=>:not_implemented}
22
+ end
23
+
24
+ def model_class_methods
25
+ @model_class_methods ||= {"new_remember_token"=>:not_implemented, "digest"=>:not_implemented}
26
+ end
27
+
28
+ def mocked_class
29
+ 'User'
30
+ end
31
+
32
+ def column_names
33
+ attribute_names
34
+ end
35
+
36
+ def attribute_names
37
+ @attribute_names ||= ["id", "name", "email", "credits", "created_at", "updated_at", "password_digest", "remember_token", "admin"]
38
+ end
39
+
40
+ def primary_key
41
+ "id"
42
+ end
19
43
 
20
- def self.attribute_names
21
- @attribute_names = ["id", "name", "email", "credits", "created_at", "updated_at", "password_digest", "remember_token", "admin"]
22
44
  end
23
45
 
24
46
  ##################################
@@ -26,150 +48,127 @@ class UserMock < ::ActiveHash::Base
26
48
  ##################################
27
49
 
28
50
  def id
29
- @attributes['id']
51
+ read_attribute(:id)
30
52
  end
31
53
 
32
54
  def id=(val)
33
- type = (types[:id] ||= Virtus::Attribute.build(Fixnum))
34
- @attributes['id'] = type.coerce(val)
55
+ write_attribute(:id, val)
35
56
  end
36
57
 
37
58
  def name
38
- @attributes['name']
59
+ read_attribute(:name)
39
60
  end
40
61
 
41
62
  def name=(val)
42
- type = (types[:name] ||= Virtus::Attribute.build(String))
43
- @attributes['name'] = type.coerce(val)
63
+ write_attribute(:name, val)
44
64
  end
45
65
 
46
66
  def email
47
- @attributes['email']
67
+ read_attribute(:email)
48
68
  end
49
69
 
50
70
  def email=(val)
51
- type = (types[:email] ||= Virtus::Attribute.build(String))
52
- @attributes['email'] = type.coerce(val)
71
+ write_attribute(:email, val)
53
72
  end
54
73
 
55
74
  def credits
56
- @attributes['credits']
75
+ read_attribute(:credits)
57
76
  end
58
77
 
59
78
  def credits=(val)
60
- type = (types[:credits] ||= Virtus::Attribute.build(BigDecimal))
61
- @attributes['credits'] = type.coerce(val)
79
+ write_attribute(:credits, val)
62
80
  end
63
81
 
64
82
  def created_at
65
- @attributes['created_at']
83
+ read_attribute(:created_at)
66
84
  end
67
85
 
68
86
  def created_at=(val)
69
- type = (types[:created_at] ||= Virtus::Attribute.build(DateTime))
70
- @attributes['created_at'] = type.coerce(val)
87
+ write_attribute(:created_at, val)
71
88
  end
72
89
 
73
90
  def updated_at
74
- @attributes['updated_at']
91
+ read_attribute(:updated_at)
75
92
  end
76
93
 
77
94
  def updated_at=(val)
78
- type = (types[:updated_at] ||= Virtus::Attribute.build(DateTime))
79
- @attributes['updated_at'] = type.coerce(val)
95
+ write_attribute(:updated_at, val)
80
96
  end
81
97
 
82
98
  def password_digest
83
- @attributes['password_digest']
99
+ read_attribute(:password_digest)
84
100
  end
85
101
 
86
102
  def password_digest=(val)
87
- type = (types[:password_digest] ||= Virtus::Attribute.build(String))
88
- @attributes['password_digest'] = type.coerce(val)
103
+ write_attribute(:password_digest, val)
89
104
  end
90
105
 
91
106
  def remember_token
92
- @attributes['remember_token']
107
+ read_attribute(:remember_token)
93
108
  end
94
109
 
95
110
  def remember_token=(val)
96
- type = (types[:remember_token] ||= Virtus::Attribute.build(Virtus::Attribute::Boolean))
97
- @attributes['remember_token'] = type.coerce(val)
111
+ write_attribute(:remember_token, val)
98
112
  end
99
113
 
100
114
  def admin
101
- @attributes['admin']
115
+ read_attribute(:admin)
102
116
  end
103
117
 
104
118
  def admin=(val)
105
- type = (types[:admin] ||= Virtus::Attribute.build(Virtus::Attribute::Boolean))
106
- @attributes['admin'] = type.coerce(val)
119
+ write_attribute(:admin, val)
107
120
  end
108
121
 
109
122
  ##################################
110
- # Association getter/setters #
123
+ # Associations #
111
124
  ##################################
112
125
 
113
- def self.association_names
114
- @association_names = [:microposts, :relationships, :followed_users, :reverse_relationships, :followers]
115
- end
116
126
 
127
+ # has_many
117
128
  def microposts
118
- associations['microposts'] ||= ActiveMocker::Collection::Association.new
129
+ @associations[:microposts] ||= ActiveMock::HasMany.new([],'user_id', @attributes['id'], classes('Micropost'))
119
130
  end
120
131
 
121
132
  def microposts=(val)
122
- associations['microposts'] = ActiveMocker::Collection::Association.new(val)
133
+ @associations[:microposts] ||= ActiveMock::HasMany.new(val,'user_id', @attributes['id'], classes('Micropost'))
123
134
  end
124
135
 
125
136
  def relationships
126
- associations['relationships'] ||= ActiveMocker::Collection::Association.new
137
+ @associations[:relationships] ||= ActiveMock::HasMany.new([],'follower_id', @attributes['id'], classes('Relationship'))
127
138
  end
128
139
 
129
140
  def relationships=(val)
130
- associations['relationships'] = ActiveMocker::Collection::Association.new(val)
141
+ @associations[:relationships] ||= ActiveMock::HasMany.new(val,'follower_id', @attributes['id'], classes('Relationship'))
131
142
  end
132
143
 
133
144
  def followed_users
134
- associations['followed_users'] ||= ActiveMocker::Collection::Association.new
145
+ @associations[:followed_users] ||= ActiveMock::HasMany.new([],'user_id', @attributes['id'], classes('FollowedUser'))
135
146
  end
136
147
 
137
148
  def followed_users=(val)
138
- associations['followed_users'] = ActiveMocker::Collection::Association.new(val)
149
+ @associations[:followed_users] ||= ActiveMock::HasMany.new(val,'user_id', @attributes['id'], classes('FollowedUser'))
139
150
  end
140
151
 
141
152
  def reverse_relationships
142
- associations['reverse_relationships'] ||= ActiveMocker::Collection::Association.new
153
+ @associations[:reverse_relationships] ||= ActiveMock::HasMany.new([],'followed_id', @attributes['id'], classes('Relationship'))
143
154
  end
144
155
 
145
156
  def reverse_relationships=(val)
146
- associations['reverse_relationships'] = ActiveMocker::Collection::Association.new(val)
157
+ @associations[:reverse_relationships] ||= ActiveMock::HasMany.new(val,'followed_id', @attributes['id'], classes('Relationship'))
147
158
  end
148
159
 
149
160
  def followers
150
- associations['followers'] ||= ActiveMocker::Collection::Association.new
161
+ @associations[:followers] ||= ActiveMock::HasMany.new([],'user_id', @attributes['id'], classes('Follower'))
151
162
  end
152
163
 
153
164
  def followers=(val)
154
- associations['followers'] = ActiveMocker::Collection::Association.new(val)
165
+ @associations[:followers] ||= ActiveMock::HasMany.new(val,'user_id', @attributes['id'], classes('Follower'))
155
166
  end
156
167
 
157
168
  ##################################
158
169
  # Model Methods getter/setters #
159
170
  ##################################
160
171
 
161
- def self.model_instance_methods
162
- @model_instance_methods ||= {"feed"=>:not_implemented, "following?"=>:not_implemented, "follow!"=>:not_implemented, "unfollow!"=>:not_implemented}
163
- end
164
-
165
- def self.model_class_methods
166
- @model_class_methods ||= {"new_remember_token"=>:not_implemented, "digest"=>:not_implemented}
167
- end
168
-
169
- def self.clear_mock
170
- @model_class_methods, @model_instance_methods = nil, nil
171
- delete_all
172
- end
173
172
 
174
173
  def feed()
175
174
  block = model_instance_methods['feed']
@@ -207,10 +206,10 @@ class UserMock < ::ActiveHash::Base
207
206
  instance_exec(*[token], &block)
208
207
  end
209
208
 
209
+ private
210
+
210
211
  def self.reload
211
212
  load __FILE__
212
213
  end
213
214
 
214
- end
215
-
216
- ActiveMocker::LoadedMocks.add(UserMock)
215
+ end
@@ -11,7 +11,7 @@ RSpec.configure do |config|
11
11
  end
12
12
 
13
13
  $:.unshift File.expand_path('../../', __FILE__)
14
- APP_ROOT = File.expand_path('../../', __FILE__)
14
+ APP_ROOT = File.expand_path('../../', __FILE__) unless defined? APP_ROOT
15
15
  require 'config/initializers/active_mocker.rb'
16
16
  load 'mocks/user_mock.rb'
17
17
 
@@ -1,9 +1,10 @@
1
1
  require 'rspec'
2
2
  $:.unshift File.expand_path('../../', __FILE__)
3
- load 'spec/mocks/user_mock.rb'
4
- APP_ROOT = File.expand_path('../../', __FILE__)
3
+ require 'active_support'
4
+ require 'spec/mocks/user_mock.rb'
5
+ APP_ROOT = File.expand_path('../../', __FILE__) unless defined? APP_ROOT
5
6
  require 'config/initializers/active_mocker.rb'
6
-
7
+ require 'forwardable'
7
8
 
8
9
  describe 'UserMock' do
9
10
 
@@ -12,6 +13,23 @@ describe 'UserMock' do
12
13
  UserMock.clear_mock
13
14
  }
14
15
 
16
+ describe '::mocked_class' do
17
+
18
+ it 'returns the name of the class being mocked' do
19
+ expect(UserMock.mocked_class).to eq 'User'
20
+ end
21
+
22
+ end
23
+
24
+ describe 'ActiveMocker::LoadedMocks' do
25
+
26
+ it 'will be added when sub classed' do
27
+ expect(ActiveMocker::LoadedMocks.all.keys.include?('UserMock')).to eq true
28
+ end
29
+
30
+ end
31
+
32
+
15
33
  describe '::column_names' do
16
34
 
17
35
  it 'returns an array of column names found from the schema.rb file' do
@@ -29,7 +47,7 @@ describe 'UserMock' do
29
47
  end
30
48
 
31
49
  it 'will raise error if not an attribute or association' do
32
- expect{UserMock.new(baz: "Hello")}.to raise_error(ActiveMocker::RejectedParams, '{:baz=>"Hello"} for UserMock')
50
+ expect{UserMock.new(baz: "Hello")}.to raise_error(ActiveMock::RejectedParams, '{:baz=>"Hello"} for UserMock')
33
51
  end
34
52
 
35
53
  end
@@ -106,10 +124,10 @@ describe 'UserMock' do
106
124
 
107
125
  end
108
126
 
109
- context 'active_hash' do
127
+ context 'active_mock' do
110
128
 
111
- it 'uses active_hash::base as superclass' do
112
- expect(UserMock.superclass.name).to eq 'ActiveHash::Base'
129
+ it 'uses active_mock::base as superclass' do
130
+ expect(UserMock.superclass.name).to eq 'ActiveMock::Base'
113
131
  end
114
132
 
115
133
  it 'can save to class and then find instance by attribute' do
@@ -0,0 +1,207 @@
1
+ require 'rspec'
2
+ $:.unshift File.expand_path('../../', __FILE__)
3
+ require 'active_support/all'
4
+ require 'active_mock/queries'
5
+ require 'active_mock/collection'
6
+ require 'ostruct'
7
+
8
+ describe ActiveMock::Queries do
9
+
10
+ before do
11
+
12
+ class Queriable < ActiveMock::Collection
13
+ include ActiveMock::Queries
14
+ end
15
+
16
+ end
17
+
18
+ subject{ Queriable.new }
19
+
20
+ describe '#sum' do
21
+
22
+ it 'sum values by attribute name' do
23
+ subject << [OpenStruct.new(value: 1), OpenStruct.new(value: 1)]
24
+ expect(subject.sum(:value)).to eq 2
25
+ end
26
+
27
+ end
28
+
29
+ describe '#limit' do
30
+
31
+ let!(:given_collection){ [OpenStruct.new(value: 1),
32
+ OpenStruct.new(value: 2),
33
+ OpenStruct.new(value: 3)]}
34
+
35
+ it 'will return only the n-number of items' do
36
+ subject << given_collection
37
+ expect(subject.limit(1).count).to eq 1
38
+ end
39
+
40
+ end
41
+
42
+ describe '#<<' do
43
+
44
+ it 'will add a single item to the array' do
45
+
46
+ subject << "item"
47
+ expect(subject.count).to eq 1
48
+ expect(subject.first).to eq 'item'
49
+
50
+ end
51
+
52
+ it 'will add a many item to the array' do
53
+
54
+ subject << ['item1', 'item2', 'item3']
55
+ expect(subject.count).to eq 3
56
+ expect(subject).to eq ['item1', 'item2', 'item3']
57
+
58
+ end
59
+
60
+ end
61
+
62
+ describe 'new' do
63
+
64
+ it 'take optional item and adds to collection' do
65
+
66
+ subject = Queriable.new(1)
67
+
68
+ expect(subject.first).to eq 1
69
+
70
+ end
71
+
72
+ it 'can take an array' do
73
+
74
+ subject = Queriable.new([1])
75
+
76
+ expect(subject.first).to eq 1
77
+
78
+ subject = Queriable.new([1,2])
79
+
80
+ expect(subject.last).to eq 2
81
+
82
+ end
83
+
84
+ end
85
+
86
+ describe 'empty?' do
87
+
88
+ it 'returns true if collection is empty' do
89
+ expect(subject.empty?).to eq true
90
+ end
91
+
92
+ it 'returns false if collection is not empty' do
93
+ subject << 1
94
+ expect(subject.empty?).to eq false
95
+ end
96
+
97
+ end
98
+
99
+ describe 'each' do
100
+
101
+ it 'can iterate over array' do
102
+ sum = 0
103
+ Queriable.new([1, 2]).each { |a| sum += a }
104
+ expect(sum).to eq 3
105
+ end
106
+
107
+ end
108
+
109
+ describe 'map' do
110
+
111
+ it 'return a new array' do
112
+ expect(Queriable.new([1, 2]).map { |a| a + a }).to eq [2, 4]
113
+ end
114
+
115
+ it 'return an instance of the class' do
116
+ expect(Queriable.new([1, 2]).map { |a| a + a }).to be_a_kind_of Array
117
+ end
118
+
119
+ end
120
+
121
+ describe 'delete_all' do
122
+
123
+ let!(:given_collection) { [double(delete: true),
124
+ double(delete: true),
125
+ double(delete: true)] }
126
+
127
+ before do
128
+ given_collection.each do |item|
129
+ expect(item).to receive(:delete)
130
+ end
131
+ subject << given_collection
132
+ end
133
+
134
+ it 'calls delete on every item in the collection' do
135
+ subject.delete_all
136
+ end
137
+
138
+ context 'alias destroy_all' do
139
+
140
+ it 'calls delete on every item in the collection' do
141
+ subject.destroy_all
142
+ end
143
+
144
+ end
145
+
146
+ end
147
+
148
+ describe '#all' do
149
+ subject{ Queriable.new(given_collection)}
150
+
151
+ let(:given_collection) { [1,1,1] }
152
+
153
+ it 'return the collection' do
154
+ expect(subject.all).to eq given_collection
155
+ end
156
+
157
+ it 'returns an instance of the class' do
158
+ expect(subject.all).to be_a_kind_of Queriable
159
+ end
160
+
161
+ end
162
+
163
+ describe 'where' do
164
+
165
+ context 'with condition' do
166
+
167
+ subject{ Queriable.new(given_collection)}
168
+
169
+ let(:given_collection) { [OpenStruct.new(value: 1),
170
+ OpenStruct.new(value: 2),
171
+ OpenStruct.new(value: 3)] }
172
+
173
+ it 'returns array of values that meet the condition' do
174
+ expect(subject.where(value: 1)).to eq [given_collection.first]
175
+ end
176
+
177
+ it 'returns an instance of the class' do
178
+ expect(subject.where(value: 1)).to be_a_kind_of(Queriable)
179
+ end
180
+
181
+ end
182
+
183
+ context 'without condition' do
184
+
185
+ subject { Queriable.new(given_collection) }
186
+
187
+ it 'return a WhereNotChain' do
188
+ expect(subject.where).to be_a_kind_of(ActiveMock::Queries::WhereNotChain)
189
+ end
190
+
191
+ let(:given_collection) { [OpenStruct.new(value: 1),
192
+ OpenStruct.new(value: 2),
193
+ OpenStruct.new(value: 3)] }
194
+
195
+ it 'takes .not(condition)' do
196
+ expect(subject.where.not(value: 1)).to eq [given_collection[1], given_collection[2]]
197
+ end
198
+
199
+ it '.not(condition) return the class' do
200
+ expect(subject.where.not(value: 1)).to be_a_kind_of(Queriable)
201
+ end
202
+
203
+ end
204
+
205
+ end
206
+
207
+ end