amoeba 2.1.0 → 3.0.0
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/.cane +4 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +17 -0
- data/.travis.yml +13 -5
- data/Appraisals +24 -0
- data/Gemfile +6 -4
- data/README.md +134 -44
- data/Rakefile +2 -2
- data/amoeba.gemspec +20 -15
- data/defaults.reek +11 -0
- data/gemfiles/activerecord_3.2.gemfile +17 -0
- data/gemfiles/activerecord_4.0.gemfile +17 -0
- data/gemfiles/activerecord_4.1.gemfile +17 -0
- data/gemfiles/activerecord_4.2.gemfile +17 -0
- data/gemfiles/activerecord_head.gemfile +23 -0
- data/lib/amoeba.rb +13 -522
- data/lib/amoeba/class_methods.rb +23 -0
- data/lib/amoeba/cloner.rb +168 -0
- data/lib/amoeba/config.rb +172 -0
- data/lib/amoeba/instance_methods.rb +37 -0
- data/lib/amoeba/macros.rb +14 -0
- data/lib/amoeba/macros/base.rb +26 -0
- data/lib/amoeba/macros/has_and_belongs_to_many.rb +19 -0
- data/lib/amoeba/macros/has_many.rb +42 -0
- data/lib/amoeba/macros/has_one.rb +15 -0
- data/lib/amoeba/version.rb +1 -1
- data/spec/lib/amoeba_spec.rb +180 -87
- data/spec/spec_helper.rb +23 -4
- data/spec/support/data.rb +73 -73
- data/spec/support/models.rb +132 -28
- data/spec/support/schema.rb +69 -42
- metadata +38 -29
- data/.ruby-version +0 -1
- data/gemfiles/Gemfile.activerecord-3.2.x +0 -11
- data/gemfiles/Gemfile.activerecord-4.0.x +0 -11
@@ -0,0 +1,42 @@
|
|
1
|
+
module Amoeba
|
2
|
+
module Macros
|
3
|
+
class HasMany < ::Amoeba::Macros::Base
|
4
|
+
def follow(relation_name, association)
|
5
|
+
if @cloner.amoeba.clones.include?(relation_name.to_sym)
|
6
|
+
follow_with_clone(relation_name)
|
7
|
+
else
|
8
|
+
follow_without_clone(relation_name, association)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def follow_with_clone(relation_name)
|
13
|
+
# This is a M:M "has many through" where we
|
14
|
+
# actually copy and reassociate the new children
|
15
|
+
# rather than only maintaining the associations
|
16
|
+
@old_object.__send__(relation_name).each do |old_obj|
|
17
|
+
relation_name = remapped_relation_name(relation_name)
|
18
|
+
# associate this new child to the new parent object
|
19
|
+
@new_object.__send__(relation_name) << old_obj.amoeba_dup
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def follow_without_clone(relation_name, association)
|
24
|
+
# This is a regular 1:M "has many"
|
25
|
+
#
|
26
|
+
# copying the children of the regular has many will
|
27
|
+
# effectively do what is desired anyway, the through
|
28
|
+
# association is really just for convenience usage
|
29
|
+
# on the model
|
30
|
+
return if association.is_a?(ActiveRecord::Reflection::ThroughReflection)
|
31
|
+
|
32
|
+
@old_object.__send__(relation_name).each do |old_obj|
|
33
|
+
copy_of_obj = old_obj.amoeba_dup(@options)
|
34
|
+
copy_of_obj[:"#{association.foreign_key}"] = nil
|
35
|
+
relation_name = remapped_relation_name(relation_name)
|
36
|
+
# associate this new child to the new parent object
|
37
|
+
@new_object.__send__(relation_name) << copy_of_obj
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module Amoeba
|
2
|
+
module Macros
|
3
|
+
class HasOne < ::Amoeba::Macros::Base
|
4
|
+
def follow(relation_name, association)
|
5
|
+
return if association.is_a?(::ActiveRecord::Reflection::ThroughReflection)
|
6
|
+
old_obj = @old_object.__send__(relation_name)
|
7
|
+
return unless old_obj
|
8
|
+
copy_of_obj = old_obj.amoeba_dup(@options)
|
9
|
+
copy_of_obj[:"#{association.foreign_key}"] = nil
|
10
|
+
relation_name = remapped_relation_name(relation_name)
|
11
|
+
@new_object.__send__(:"#{relation_name}=", copy_of_obj)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/amoeba/version.rb
CHANGED
data/spec/lib/amoeba_spec.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
-
require 'active_record'
|
2
1
|
require 'spec_helper'
|
3
2
|
|
4
|
-
describe
|
5
|
-
context
|
6
|
-
|
3
|
+
describe 'amoeba' do
|
4
|
+
context 'dup' do
|
5
|
+
before :each do
|
6
|
+
require ::File.dirname(__FILE__) + '/../support/data.rb'
|
7
|
+
end
|
8
|
+
it 'duplicates associated child records' do
|
7
9
|
# Posts {{{
|
8
|
-
old_post = Post.find(1)
|
9
|
-
old_post.comments.map(&:contents).include?(
|
10
|
+
old_post = ::Post.find(1)
|
11
|
+
expect(old_post.comments.map(&:contents).include?('I love it!')).to be_truthy
|
10
12
|
|
11
13
|
old_post.class.amoeba do
|
12
|
-
prepend :
|
14
|
+
prepend contents: "Here's a copy: "
|
13
15
|
end
|
14
16
|
|
15
17
|
new_post = old_post.amoeba_dup
|
@@ -28,12 +30,12 @@ describe "amoeba" do
|
|
28
30
|
start_postwidget_count = PostWidget.all.count
|
29
31
|
start_superkitten_count = Superkitten.all.count
|
30
32
|
rs = ActiveRecord::Base.connection.select_one('SELECT COUNT(*) AS tag_count FROM posts_tags')
|
31
|
-
start_posttag_count = rs[
|
33
|
+
start_posttag_count = rs['tag_count']
|
32
34
|
rs = ActiveRecord::Base.connection.select_one('SELECT COUNT(*) AS note_count FROM notes_posts')
|
33
|
-
start_postnote_count = rs[
|
35
|
+
start_postnote_count = rs['note_count']
|
34
36
|
|
35
|
-
new_post.save
|
36
|
-
new_post.
|
37
|
+
expect(new_post.save!).to be_truthy
|
38
|
+
expect(new_post.title).to eq("Copy of #{old_post.title}")
|
37
39
|
|
38
40
|
end_account_count = Account.all.count
|
39
41
|
end_history_count = History.all.count
|
@@ -49,140 +51,231 @@ describe "amoeba" do
|
|
49
51
|
end_postwidget_count = PostWidget.all.count
|
50
52
|
end_superkitten_count = Superkitten.all.count
|
51
53
|
rs = ActiveRecord::Base.connection.select_one('SELECT COUNT(*) AS tag_count FROM posts_tags')
|
52
|
-
end_posttag_count = rs[
|
54
|
+
end_posttag_count = rs['tag_count']
|
53
55
|
rs = ActiveRecord::Base.connection.select_one('SELECT COUNT(*) AS note_count FROM notes_posts')
|
54
|
-
end_postnote_count = rs[
|
55
|
-
|
56
|
-
end_tag_count.
|
57
|
-
end_cat_count.
|
58
|
-
end_account_count.
|
59
|
-
end_history_count.
|
60
|
-
end_supercat_count.
|
61
|
-
end_post_count.
|
62
|
-
end_comment_count.
|
63
|
-
end_rating_count.
|
64
|
-
end_postconfig_count.
|
65
|
-
end_posttag_count.
|
66
|
-
end_widget_count.
|
67
|
-
end_postwidget_count.
|
68
|
-
end_note_count.
|
69
|
-
end_postnote_count.
|
70
|
-
end_superkitten_count.
|
71
|
-
|
72
|
-
new_post.supercats.map(&:ramblings).include?(
|
73
|
-
new_post.supercats.map(&:other_ramblings).uniq.length.
|
74
|
-
new_post.supercats.map(&:other_ramblings).uniq.include?(
|
75
|
-
new_post.
|
76
|
-
new_post.
|
77
|
-
new_post.comments.
|
78
|
-
new_post.comments.select{ |c| c.nerf == 'ratatat'
|
79
|
-
new_post.comments.select{ |c| c.nerf == '
|
80
|
-
new_post.comments.select{ |c| c.nerf == '
|
81
|
-
new_post.comments.select{ |c| c.nerf == 'bonkers' && c.contents.nil? }.length.should == 1
|
56
|
+
end_postnote_count = rs['note_count']
|
57
|
+
|
58
|
+
expect(end_tag_count).to eq(start_tag_count)
|
59
|
+
expect(end_cat_count).to eq(start_cat_count)
|
60
|
+
expect(end_account_count).to eq(start_account_count * 2)
|
61
|
+
expect(end_history_count).to eq(start_history_count * 2)
|
62
|
+
expect(end_supercat_count).to eq(start_supercat_count * 2)
|
63
|
+
expect(end_post_count).to eq(start_post_count * 2)
|
64
|
+
expect(end_comment_count).to eq((start_comment_count * 2) + 2)
|
65
|
+
expect(end_rating_count).to eq(start_rating_count * 2)
|
66
|
+
expect(end_postconfig_count).to eq(start_postconfig_count * 2)
|
67
|
+
expect(end_posttag_count).to eq(start_posttag_count * 2)
|
68
|
+
expect(end_widget_count).to eq(start_widget_count * 2)
|
69
|
+
expect(end_postwidget_count).to eq(start_postwidget_count * 2)
|
70
|
+
expect(end_note_count).to eq(start_note_count * 2)
|
71
|
+
expect(end_postnote_count).to eq(start_postnote_count * 2)
|
72
|
+
expect(end_superkitten_count).to eq(start_superkitten_count * 2)
|
73
|
+
|
74
|
+
expect(new_post.supercats.map(&:ramblings).include?('Copy of zomg')).to be true
|
75
|
+
expect(new_post.supercats.map(&:other_ramblings).uniq.length).to eq(1)
|
76
|
+
expect(new_post.supercats.map(&:other_ramblings).uniq.include?('La la la')).to be true
|
77
|
+
expect(new_post.contents).to eq("Here's a copy: #{old_post.contents.gsub(/dog/, 'cat')} (copied version)")
|
78
|
+
expect(new_post.comments.length).to eq(5)
|
79
|
+
expect(new_post.comments.select { |c| c.nerf == 'ratatat' && c.contents.nil? }.length).to eq(1)
|
80
|
+
expect(new_post.comments.select { |c| c.nerf == 'ratatat' }.length).to eq(2)
|
81
|
+
expect(new_post.comments.select { |c| c.nerf == 'bonk' }.length).to eq(1)
|
82
|
+
expect(new_post.comments.select { |c| c.nerf == 'bonkers' && c.contents.nil? }.length).to eq(1)
|
82
83
|
|
83
84
|
new_post.widgets.map(&:id).each do |id|
|
84
|
-
old_post.widgets.map(&:id).include?(id).
|
85
|
+
expect(old_post.widgets.map(&:id).include?(id)).not_to be true
|
85
86
|
end
|
86
87
|
|
87
|
-
new_post.custom_things.length.
|
88
|
-
new_post.custom_things.select{ |ct| ct.value == [] }.length.
|
89
|
-
new_post.custom_things.select{ |ct| ct.value == [1,2]}.length.
|
90
|
-
new_post.custom_things.select{ |ct| ct.value == [78]}.length.
|
88
|
+
expect(new_post.custom_things.length).to eq(3)
|
89
|
+
expect(new_post.custom_things.select { |ct| ct.value == [] }.length).to eq(1)
|
90
|
+
expect(new_post.custom_things.select { |ct| ct.value == [1, 2] }.length).to eq(1)
|
91
|
+
expect(new_post.custom_things.select { |ct| ct.value == [78] }.length).to eq(1)
|
91
92
|
# }}}
|
92
93
|
# Author {{{
|
93
94
|
old_author = Author.find(1)
|
94
95
|
new_author = old_author.amoeba_dup
|
95
|
-
new_author.save
|
96
|
-
new_author.errors.messages.length.
|
97
|
-
new_author.posts.first.custom_things.length.
|
98
|
-
new_author.posts.first.custom_things.select{ |ct| ct.value == [] }.length.
|
99
|
-
new_author.posts.first.custom_things.select{ |ct| ct.value == [1,2]}.length.
|
100
|
-
new_author.posts.first.custom_things.select{ |ct| ct.value == [78]}.length.
|
96
|
+
new_author.save!
|
97
|
+
expect(new_author.errors.messages.length).to eq(0)
|
98
|
+
expect(new_author.posts.first.custom_things.length).to eq(3)
|
99
|
+
expect(new_author.posts.first.custom_things.select { |ct| ct.value == [] }.length).to eq(1)
|
100
|
+
expect(new_author.posts.first.custom_things.select { |ct| ct.value == [1, 2] }.length).to eq(1)
|
101
|
+
expect(new_author.posts.first.custom_things.select { |ct| ct.value == [78] }.length).to eq(1)
|
101
102
|
# }}}
|
102
103
|
# Products {{{
|
103
104
|
# Base Class {{{
|
104
105
|
old_product = Product.find(1)
|
105
106
|
|
106
|
-
start_image_count = Image.where(:
|
107
|
+
start_image_count = Image.where(product_id: old_product.id).count
|
107
108
|
start_section_count = Section.all.length
|
108
109
|
rs = ActiveRecord::Base.connection.select_one('SELECT COUNT(*) AS section_count FROM products_sections WHERE product_id = ?', old_product.id)
|
109
|
-
start_prodsection_count = rs[
|
110
|
+
start_prodsection_count = rs['section_count']
|
110
111
|
|
111
112
|
new_product = old_product.amoeba_dup
|
112
113
|
new_product.save
|
113
|
-
new_product.errors.messages.length.
|
114
|
+
expect(new_product.errors.messages.length).to eq(0)
|
114
115
|
|
115
|
-
end_image_count = Image.where(:
|
116
|
-
end_newimage_count = Image.where(:
|
116
|
+
end_image_count = Image.where(product_id: old_product.id).count
|
117
|
+
end_newimage_count = Image.where(product_id: new_product.id).count
|
117
118
|
end_section_count = Section.all.length
|
118
119
|
rs = ActiveRecord::Base.connection.select_one('SELECT COUNT(*) AS section_count FROM products_sections WHERE product_id = ?', 1)
|
119
|
-
end_prodsection_count = rs[
|
120
|
+
end_prodsection_count = rs['section_count']
|
120
121
|
rs = ActiveRecord::Base.connection.select_one('SELECT COUNT(*) AS section_count FROM products_sections WHERE product_id = ?', new_product.id)
|
121
|
-
end_newprodsection_count = rs[
|
122
|
+
end_newprodsection_count = rs['section_count']
|
122
123
|
|
123
|
-
end_image_count.
|
124
|
-
end_newimage_count.
|
125
|
-
end_section_count.
|
126
|
-
end_prodsection_count.
|
127
|
-
end_newprodsection_count.
|
124
|
+
expect(end_image_count).to eq(start_image_count)
|
125
|
+
expect(end_newimage_count).to eq(start_image_count)
|
126
|
+
expect(end_section_count).to eq(start_section_count)
|
127
|
+
expect(end_prodsection_count).to eq(start_prodsection_count)
|
128
|
+
expect(end_newprodsection_count).to eq(start_prodsection_count)
|
128
129
|
# }}}
|
129
130
|
|
130
131
|
# Inherited Class {{{
|
131
132
|
# Shirt {{{
|
132
133
|
old_product = Shirt.find(2)
|
133
134
|
|
134
|
-
start_image_count = Image.where(:
|
135
|
+
start_image_count = Image.where(product_id: old_product.id).count
|
135
136
|
start_section_count = Section.all.length
|
136
137
|
rs = ActiveRecord::Base.connection.select_one('SELECT COUNT(*) AS section_count FROM products_sections WHERE product_id = ?', old_product.id)
|
137
|
-
start_prodsection_count = rs[
|
138
|
+
start_prodsection_count = rs['section_count']
|
138
139
|
|
139
140
|
new_product = old_product.amoeba_dup
|
140
141
|
new_product.save
|
141
|
-
new_product.errors.messages.length.
|
142
|
+
expect(new_product.errors.messages.length).to eq(0)
|
142
143
|
|
143
|
-
end_image_count = Image.where(:
|
144
|
-
end_newimage_count = Image.where(:
|
144
|
+
end_image_count = Image.where(product_id: old_product.id).count
|
145
|
+
end_newimage_count = Image.where(product_id: new_product.id).count
|
145
146
|
end_section_count = Section.all.length
|
146
147
|
rs = ActiveRecord::Base.connection.select_one('SELECT COUNT(*) AS section_count FROM products_sections WHERE product_id = ?', 1)
|
147
|
-
end_prodsection_count = rs[
|
148
|
+
end_prodsection_count = rs['section_count']
|
148
149
|
rs = ActiveRecord::Base.connection.select_one('SELECT COUNT(*) AS section_count FROM products_sections WHERE product_id = ?', new_product.id)
|
149
|
-
end_newprodsection_count = rs[
|
150
|
+
end_newprodsection_count = rs['section_count']
|
150
151
|
|
151
|
-
end_image_count.
|
152
|
-
end_newimage_count.
|
153
|
-
end_section_count.
|
154
|
-
end_prodsection_count.
|
155
|
-
end_newprodsection_count.
|
152
|
+
expect(end_image_count).to eq(start_image_count)
|
153
|
+
expect(end_newimage_count).to eq(start_image_count)
|
154
|
+
expect(end_section_count).to eq(start_section_count)
|
155
|
+
expect(end_prodsection_count).to eq(start_prodsection_count)
|
156
|
+
expect(end_newprodsection_count).to eq(start_prodsection_count)
|
156
157
|
# }}}
|
157
158
|
|
158
159
|
# Necklace {{{
|
159
160
|
old_product = Necklace.find(3)
|
160
161
|
|
161
|
-
start_image_count = Image.where(:
|
162
|
+
start_image_count = Image.where(product_id: old_product.id).count
|
162
163
|
start_section_count = Section.all.length
|
163
164
|
rs = ActiveRecord::Base.connection.select_one('SELECT COUNT(*) AS section_count FROM products_sections WHERE product_id = ?', old_product.id)
|
164
|
-
start_prodsection_count = rs[
|
165
|
+
start_prodsection_count = rs['section_count']
|
165
166
|
|
166
167
|
new_product = old_product.amoeba_dup
|
167
168
|
new_product.save
|
168
|
-
new_product.errors.messages.length.
|
169
|
+
expect(new_product.errors.messages.length).to eq(0)
|
169
170
|
|
170
|
-
end_image_count = Image.where(:
|
171
|
-
end_newimage_count = Image.where(:
|
171
|
+
end_image_count = Image.where(product_id: old_product.id).count
|
172
|
+
end_newimage_count = Image.where(product_id: new_product.id).count
|
172
173
|
end_section_count = Section.all.length
|
173
174
|
rs = ActiveRecord::Base.connection.select_one('SELECT COUNT(*) AS section_count FROM products_sections WHERE product_id = ?', 1)
|
174
|
-
end_prodsection_count = rs[
|
175
|
+
end_prodsection_count = rs['section_count']
|
175
176
|
rs = ActiveRecord::Base.connection.select_one('SELECT COUNT(*) AS section_count FROM products_sections WHERE product_id = ?', new_product.id)
|
176
|
-
end_newprodsection_count = rs[
|
177
|
+
end_newprodsection_count = rs['section_count']
|
177
178
|
|
178
|
-
end_image_count.
|
179
|
-
end_newimage_count.
|
180
|
-
end_section_count.
|
181
|
-
end_prodsection_count.
|
182
|
-
end_newprodsection_count.
|
179
|
+
expect(end_image_count).to eq(start_image_count)
|
180
|
+
expect(end_newimage_count).to eq(start_image_count)
|
181
|
+
expect(end_section_count).to eq(start_section_count)
|
182
|
+
expect(end_prodsection_count).to eq(start_prodsection_count)
|
183
|
+
expect(end_newprodsection_count).to eq(start_prodsection_count)
|
183
184
|
# }}}
|
184
185
|
# }}}
|
185
186
|
# }}}
|
186
187
|
end
|
187
188
|
end
|
189
|
+
context 'override' do
|
190
|
+
before :each do
|
191
|
+
::Image.fresh_amoeba
|
192
|
+
::Image.amoeba do
|
193
|
+
override ->(old, new) {
|
194
|
+
if old.filename == 'test.jpg'
|
195
|
+
new.product_id = 13
|
196
|
+
end
|
197
|
+
}
|
198
|
+
end
|
199
|
+
end
|
200
|
+
it 'should override fields' do
|
201
|
+
image = ::Image.create(filename: 'test.jpg', product_id: 12)
|
202
|
+
image_dup = image.amoeba_dup
|
203
|
+
expect(image_dup.save).to be_truthy
|
204
|
+
expect(image_dup.product_id).to eq(13)
|
205
|
+
end
|
206
|
+
it 'should not override fields' do
|
207
|
+
image = ::Image.create(filename: 'test2.jpg', product_id: 12)
|
208
|
+
image_dup = image.amoeba_dup
|
209
|
+
expect(image_dup.save).to be_truthy
|
210
|
+
expect(image_dup.product_id).to eq(12)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
context 'nullify' do
|
215
|
+
before :each do
|
216
|
+
::Image.fresh_amoeba
|
217
|
+
::Image.amoeba do
|
218
|
+
nullify :product_id
|
219
|
+
end
|
220
|
+
end
|
221
|
+
it 'should nullify fields' do
|
222
|
+
image = ::Image.create(filename: 'test.jpg', product_id: 12)
|
223
|
+
image_dup = image.amoeba_dup
|
224
|
+
expect(image_dup.save).to be_truthy
|
225
|
+
expect(image_dup.product_id).to be_nil
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
context 'strict propagate' do
|
230
|
+
it 'should call #fresh_amoeba' do
|
231
|
+
expect(::SuperBlackBox).to receive(:fresh_amoeba).and_call_original
|
232
|
+
box = ::SuperBlackBox.create(title: 'Super Black Box', price: 9.99, length: 1, metal: '1')
|
233
|
+
new_box = box.amoeba_dup
|
234
|
+
expect(new_box.save).to be_truthy
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
context 'remapping and custom dup method' do
|
239
|
+
let(:prototype) { ObjectPrototype.new }
|
240
|
+
context 'through' do
|
241
|
+
it do
|
242
|
+
real_object = prototype.amoeba_dup
|
243
|
+
expect(real_object).to be_a(::RealObject)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
context 'remapper' do
|
247
|
+
it do
|
248
|
+
prototype.subobject_prototypes << SubobjectPrototype.new
|
249
|
+
real_object = prototype.amoeba_dup
|
250
|
+
expect(real_object.subobjects.length).to eq(1)
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
context 'preprocessing fields' do
|
256
|
+
it 'should accept "set" to set false to attribute' do
|
257
|
+
super_admin = ::SuperAdmin.create!(email: 'user@example.com', active: true, password: 'password')
|
258
|
+
clone = super_admin.amoeba_dup
|
259
|
+
expect(clone.active).to eq(false)
|
260
|
+
end
|
261
|
+
it 'should skip "prepend" if it equal to false' do
|
262
|
+
super_admin = ::SuperAdmin.create!(email: 'user2@example.com', active: true, password: 'password')
|
263
|
+
clone = super_admin.amoeba_dup
|
264
|
+
expect(clone.password).to eq('password')
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
context 'inheritance' do
|
269
|
+
it 'does not fail with a deep inheritance' do
|
270
|
+
box = Box.create
|
271
|
+
sub_sub_product = BoxSubSubProduct.create(title: 'Awesome shoes')
|
272
|
+
another_product = BoxAnotherProduct.create(title: 'Cleaning product')
|
273
|
+
sub_sub_product.box = box
|
274
|
+
sub_sub_product.another_product = another_product
|
275
|
+
sub_sub_product.save
|
276
|
+
expect(box.sub_products.first.another_product.title).to eq('Cleaning product')
|
277
|
+
expect(box.amoeba_dup.sub_products.first.another_product.title).to eq('Cleaning product')
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
188
281
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,10 +1,29 @@
|
|
1
|
+
require 'simplecov'
|
1
2
|
require 'coveralls'
|
2
|
-
|
3
|
+
SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
|
4
|
+
SimpleCov::Formatter::HTMLFormatter,
|
5
|
+
Coveralls::SimpleCov::Formatter
|
6
|
+
]
|
7
|
+
SimpleCov.start do
|
8
|
+
add_filter 'spec'
|
9
|
+
minimum_coverage(76)
|
10
|
+
end
|
11
|
+
require 'active_record'
|
3
12
|
require 'amoeba'
|
4
13
|
|
5
|
-
|
6
|
-
|
14
|
+
adapter = if defined?(JRuby)
|
15
|
+
require 'activerecord-jdbcsqlite3-adapter'
|
16
|
+
'jdbcsqlite3'
|
17
|
+
else
|
18
|
+
require 'sqlite3'
|
19
|
+
'sqlite3'
|
20
|
+
end
|
21
|
+
|
22
|
+
ActiveRecord::Base.establish_connection(adapter: adapter, database: ':memory:')
|
23
|
+
|
24
|
+
::RSpec.configure do |config|
|
25
|
+
config.order = :default
|
26
|
+
end
|
7
27
|
|
8
28
|
load File.dirname(__FILE__) + '/support/schema.rb'
|
9
29
|
load File.dirname(__FILE__) + '/support/models.rb'
|
10
|
-
load File.dirname(__FILE__) + '/support/data.rb'
|
data/spec/support/data.rb
CHANGED
@@ -1,110 +1,110 @@
|
|
1
|
-
u1 = User.create(:
|
2
|
-
u2 = User.create(:
|
1
|
+
u1 = User.create(name: 'Robert Johnson', email: 'bob@crossroads.com')
|
2
|
+
u2 = User.create(name: 'Miles Davis', email: 'miles@kindofblue.com')
|
3
3
|
|
4
|
-
a1 = Author.create(:
|
5
|
-
a2 = Author.create(:
|
4
|
+
a1 = Author.create(full_name: 'Kermit The Vonnegut', nickname: 'kvsoitgoes')
|
5
|
+
a2 = Author.create(full_name: 'Arthur Sees Clarck', nickname: 'strangewater')
|
6
6
|
|
7
|
-
t = Topic.create(:
|
7
|
+
t = Topic.create(title: 'Ponies', description: 'Lets talk about my ponies.')
|
8
8
|
|
9
9
|
# First Post {{{
|
10
|
-
p1 = t.posts.create(:
|
11
|
-
f1 = p1.create_post_config(:
|
12
|
-
a1 = p1.create_account(:
|
13
|
-
h1 = p1.account.create_history(:
|
14
|
-
c1 = p1.comments.create(:
|
15
|
-
c1.ratings.create(:
|
16
|
-
c1.ratings.create(:
|
17
|
-
c1.ratings.create(:
|
18
|
-
c1.ratings.create(:
|
19
|
-
c1.ratings.create(:
|
20
|
-
c1.ratings.create(:
|
21
|
-
|
22
|
-
c2 = p1.comments.create(:
|
23
|
-
c2.ratings.create(:
|
24
|
-
c2.ratings.create(:
|
25
|
-
c2.ratings.create(:
|
26
|
-
c2.ratings.create(:
|
27
|
-
c2.ratings.create(:
|
28
|
-
c2.ratings.create(:
|
29
|
-
|
30
|
-
c3 = p1.comments.create(:
|
31
|
-
c3.ratings.create(:
|
32
|
-
c3.ratings.create(:
|
33
|
-
c3.ratings.create(:
|
34
|
-
c3.ratings.create(:
|
35
|
-
c3.ratings.create(:
|
36
|
-
c3.ratings.create(:
|
37
|
-
|
38
|
-
t1 = Tag.create(:
|
39
|
-
t2 = Tag.create(:
|
40
|
-
t3 = Tag.create(:
|
10
|
+
p1 = t.posts.create(owner: u1, author: a1, title: 'My little pony', contents: 'Lorum ipsum dolor rainbow bright. I like dogs, dogs are awesome.')
|
11
|
+
f1 = p1.create_post_config(is_visible: true, is_open: false, password: 'abcdefg123')
|
12
|
+
a1 = p1.create_account(title: 'Foo')
|
13
|
+
h1 = p1.account.create_history(some_stuff: 'Bar')
|
14
|
+
c1 = p1.comments.create(contents: 'I love it!', nerf: 'ratatat')
|
15
|
+
c1.ratings.create(num_stars: 5)
|
16
|
+
c1.ratings.create(num_stars: 5)
|
17
|
+
c1.ratings.create(num_stars: 4)
|
18
|
+
c1.ratings.create(num_stars: 3)
|
19
|
+
c1.ratings.create(num_stars: 5)
|
20
|
+
c1.ratings.create(num_stars: 5)
|
21
|
+
|
22
|
+
c2 = p1.comments.create(contents: 'I hate it!', nerf: 'whapaow')
|
23
|
+
c2.ratings.create(num_stars: 3)
|
24
|
+
c2.ratings.create(num_stars: 1)
|
25
|
+
c2.ratings.create(num_stars: 4)
|
26
|
+
c2.ratings.create(num_stars: 1)
|
27
|
+
c2.ratings.create(num_stars: 1)
|
28
|
+
c2.ratings.create(num_stars: 2)
|
29
|
+
|
30
|
+
c3 = p1.comments.create(contents: 'kthxbbq!!11!!!1!eleven!!', nerf: 'bonk')
|
31
|
+
c3.ratings.create(num_stars: 0)
|
32
|
+
c3.ratings.create(num_stars: 0)
|
33
|
+
c3.ratings.create(num_stars: 1)
|
34
|
+
c3.ratings.create(num_stars: 2)
|
35
|
+
c3.ratings.create(num_stars: 1)
|
36
|
+
c3.ratings.create(num_stars: 0)
|
37
|
+
|
38
|
+
t1 = Tag.create(value: 'funny')
|
39
|
+
t2 = Tag.create(value: 'wtf')
|
40
|
+
t3 = Tag.create(value: 'cats')
|
41
41
|
|
42
42
|
p1.tags << t1
|
43
43
|
p1.tags << t2
|
44
44
|
p1.tags << t3
|
45
45
|
p1.save
|
46
46
|
|
47
|
-
w1 = Widget.create(:
|
48
|
-
w2 = Widget.create(:
|
49
|
-
w3 = Widget.create(:
|
47
|
+
w1 = Widget.create(value: 'My Sidebar')
|
48
|
+
w2 = Widget.create(value: 'Photo Gallery')
|
49
|
+
w3 = Widget.create(value: 'Share & Like')
|
50
50
|
|
51
51
|
p1.widgets << w1
|
52
52
|
p1.widgets << w2
|
53
53
|
p1.widgets << w3
|
54
54
|
p1.save
|
55
55
|
|
56
|
-
n1 = Note.create(:
|
57
|
-
n2 = Note.create(:
|
58
|
-
n3 = Note.create(:
|
56
|
+
n1 = Note.create(value: 'This is important')
|
57
|
+
n2 = Note.create(value: "You've been warned")
|
58
|
+
n3 = Note.create(value: "Don't forget")
|
59
59
|
|
60
60
|
p1.notes << n1
|
61
61
|
p1.notes << n2
|
62
62
|
p1.notes << n3
|
63
63
|
p1.save
|
64
64
|
|
65
|
-
c1 = Category.create(:
|
66
|
-
c2 = Category.create(:
|
67
|
-
c3 = Category.create(:
|
65
|
+
c1 = Category.create(title: 'Umbrellas', description: 'Clown fart')
|
66
|
+
c2 = Category.create(title: 'Widgets', description: 'Humpty dumpty')
|
67
|
+
c3 = Category.create(title: 'Wombats', description: 'Slushy mushy')
|
68
68
|
|
69
|
-
s1 = Supercat.create(:
|
70
|
-
s2 = Supercat.create(:
|
71
|
-
s3 = Supercat.create(:
|
69
|
+
s1 = Supercat.create(post: p1, category: c1, ramblings: 'zomg', other_ramblings: 'nerp')
|
70
|
+
s2 = Supercat.create(post: p1, category: c2, ramblings: 'why', other_ramblings: 'narp')
|
71
|
+
s3 = Supercat.create(post: p1, category: c3, ramblings: 'ohnoes', other_ramblings: 'blap')
|
72
72
|
|
73
|
-
s1.superkittens.create(:
|
74
|
-
s1.superkittens.create(:
|
75
|
-
s1.superkittens.create(:
|
73
|
+
s1.superkittens.create(value: 'Fluffy')
|
74
|
+
s1.superkittens.create(value: 'Buffy')
|
75
|
+
s1.superkittens.create(value: 'Fuzzy')
|
76
76
|
|
77
|
-
s2.superkittens.create(:
|
78
|
-
s2.superkittens.create(:
|
79
|
-
s2.superkittens.create(:
|
77
|
+
s2.superkittens.create(value: 'Hairball')
|
78
|
+
s2.superkittens.create(value: 'Crosseye')
|
79
|
+
s2.superkittens.create(value: 'Spot')
|
80
80
|
|
81
|
-
s3.superkittens.create(:
|
82
|
-
s3.superkittens.create(:
|
83
|
-
s3.superkittens.create(:
|
81
|
+
s3.superkittens.create(value: 'Dopey')
|
82
|
+
s3.superkittens.create(value: 'Sneezy')
|
83
|
+
s3.superkittens.create(value: 'Sleepy')
|
84
84
|
|
85
|
-
p1.custom_things.create([{:
|
85
|
+
p1.custom_things.create([{ value: [1, 2] }, { value: [] }, { value: [78] }])
|
86
86
|
# }}}
|
87
87
|
|
88
88
|
# Product {{{
|
89
|
-
product1 = Product.create(:
|
90
|
-
shirt1 = Shirt.create(:
|
91
|
-
necklace1 = Necklace.create(:
|
89
|
+
product1 = Product.create(title: 'Sticky Notes 5-Pak', price: 5.99, weight: 0.56)
|
90
|
+
shirt1 = Shirt.create(title: 'Fancy Shirt', price: 48.95, sleeve: 32, collar: 15.5)
|
91
|
+
necklace1 = Necklace.create(title: 'Pearl Necklace', price: 2995.99, length: 18, metal: '14k')
|
92
92
|
|
93
|
-
img1 = product1.images.create(:
|
94
|
-
img2 = product1.images.create(:
|
93
|
+
img1 = product1.images.create(filename: 'sticky.jpg')
|
94
|
+
img2 = product1.images.create(filename: 'notes.jpg')
|
95
95
|
|
96
|
-
img1 = shirt1.images.create(:
|
97
|
-
img2 = shirt1.images.create(:
|
96
|
+
img1 = shirt1.images.create(filename: '02948u31.jpg')
|
97
|
+
img2 = shirt1.images.create(filename: 'zsif8327.jpg')
|
98
98
|
|
99
|
-
img1 = necklace1.images.create(:
|
100
|
-
img2 = necklace1.images.create(:
|
99
|
+
img1 = necklace1.images.create(filename: 'ae02x9f1.jpg')
|
100
|
+
img2 = necklace1.images.create(filename: 'cba9f912.jpg')
|
101
101
|
|
102
|
-
office = Section.create(:
|
103
|
-
supplies = Section.create(:
|
104
|
-
mens = Section.create(:
|
105
|
-
apparel = Section.create(:
|
106
|
-
accessories = Section.create(:
|
107
|
-
jewelry = Section.create(:
|
102
|
+
office = Section.create(name: 'Office', num_employees: 2, total_sales: '1234.56')
|
103
|
+
supplies = Section.create(name: 'Supplies', num_employees: 1, total_sales: '543.21')
|
104
|
+
mens = Section.create(name: 'Mens', num_employees: 3, total_sales: '11982.63')
|
105
|
+
apparel = Section.create(name: 'Apparel', num_employees: 5, total_sales: '1315.20')
|
106
|
+
accessories = Section.create(name: 'Accessories', num_employees: 1, total_sales: '8992.34')
|
107
|
+
jewelry = Section.create(name: 'Jewelry', num_employees: 3, total_sales: '25481.77')
|
108
108
|
|
109
109
|
product1.sections << office
|
110
110
|
product1.sections << supplies
|