amoeba 3.1.0 → 3.3.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.
Files changed (46) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/jruby.yml +27 -0
  3. data/.github/workflows/ruby_25.yml +30 -0
  4. data/.github/workflows/ruby_26.yml +30 -0
  5. data/.github/workflows/ruby_27.yml +30 -0
  6. data/.github/workflows/ruby_30.yml +34 -0
  7. data/.github/workflows/ruby_31.yml +34 -0
  8. data/.github/workflows/ruby_32.yml +34 -0
  9. data/.github/workflows/ruby_head.yml +34 -0
  10. data/.gitignore +1 -0
  11. data/.rubocop.yml +11 -7
  12. data/.rubocop_todo.yml +120 -0
  13. data/Appraisals +48 -9
  14. data/CHANGELOG.md +14 -0
  15. data/Gemfile +5 -2
  16. data/LICENSE.md +11 -0
  17. data/README.md +3 -17
  18. data/Rakefile +2 -0
  19. data/amoeba.gemspec +20 -17
  20. data/gemfiles/activerecord_5.2.gemfile +19 -0
  21. data/gemfiles/activerecord_6.0.gemfile +19 -0
  22. data/gemfiles/activerecord_6.1.gemfile +19 -0
  23. data/gemfiles/activerecord_7.0.gemfile +19 -0
  24. data/gemfiles/activerecord_head.gemfile +10 -12
  25. data/gemfiles/jruby_activerecord_7.0.gemfile +20 -0
  26. data/gemfiles/jruby_activerecord_head.gemfile +26 -0
  27. data/lib/amoeba/class_methods.rb +2 -0
  28. data/lib/amoeba/cloner.rb +11 -4
  29. data/lib/amoeba/config.rb +25 -51
  30. data/lib/amoeba/instance_methods.rb +3 -0
  31. data/lib/amoeba/macros/base.rb +4 -1
  32. data/lib/amoeba/macros/has_and_belongs_to_many.rb +2 -0
  33. data/lib/amoeba/macros/has_many.rb +2 -0
  34. data/lib/amoeba/macros/has_one.rb +4 -0
  35. data/lib/amoeba/macros.rb +2 -0
  36. data/lib/amoeba/version.rb +3 -1
  37. data/lib/amoeba.rb +6 -2
  38. data/spec/lib/amoeba_spec.rb +76 -34
  39. data/spec/spec_helper.rb +13 -5
  40. data/spec/support/data.rb +22 -15
  41. data/spec/support/models.rb +39 -38
  42. metadata +66 -30
  43. data/.travis.yml +0 -20
  44. data/gemfiles/activerecord_4.0.gemfile +0 -17
  45. data/gemfiles/activerecord_4.1.gemfile +0 -17
  46. data/gemfiles/activerecord_4.2.gemfile +0 -17
@@ -0,0 +1,19 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'activerecord', '~> 5.2.0'
6
+
7
+ group :development, :test do
8
+ gem 'rake'
9
+ gem 'simplecov', '~> 0.21.2'
10
+ gem 'simplecov-lcov', '~> 0.8.0'
11
+ gem 'sqlite3', '~> 1.3.0'
12
+ end
13
+
14
+ group :local_development do
15
+ gem 'appraisal'
16
+ gem 'pry'
17
+ end
18
+
19
+ gemspec path: '../'
@@ -0,0 +1,19 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'activerecord', '~> 6.0.0'
6
+
7
+ group :development, :test do
8
+ gem 'rake'
9
+ gem 'simplecov', '~> 0.21.2'
10
+ gem 'simplecov-lcov', '~> 0.8.0'
11
+ gem 'sqlite3', '~> 1.6.0'
12
+ end
13
+
14
+ group :local_development do
15
+ gem 'appraisal'
16
+ gem 'pry'
17
+ end
18
+
19
+ gemspec path: '../'
@@ -0,0 +1,19 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'activerecord', '~> 6.1.0'
6
+
7
+ group :development, :test do
8
+ gem 'rake'
9
+ gem 'simplecov', '~> 0.21.2'
10
+ gem 'simplecov-lcov', '~> 0.8.0'
11
+ gem 'sqlite3', '~> 1.6.0'
12
+ end
13
+
14
+ group :local_development do
15
+ gem 'appraisal'
16
+ gem 'pry'
17
+ end
18
+
19
+ gemspec path: '../'
@@ -0,0 +1,19 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'activerecord', '~> 7.0.0'
6
+
7
+ group :development, :test do
8
+ gem 'rake'
9
+ gem 'simplecov', '~> 0.21.2'
10
+ gem 'simplecov-lcov', '~> 0.8.0'
11
+ gem 'sqlite3', '~> 1.6.0'
12
+ end
13
+
14
+ group :local_development do
15
+ gem 'appraisal'
16
+ gem 'pry'
17
+ end
18
+
19
+ gemspec path: '../'
@@ -1,23 +1,21 @@
1
1
  # This file was generated by Appraisal
2
2
 
3
- source "https://rubygems.org"
3
+ source 'https://rubygems.org'
4
4
 
5
- git "git://github.com/rails/arel.git" do
6
- gem "arel"
7
- end
8
-
9
- git "git://github.com/rails/rails.git" do
10
- gem "activerecord"
5
+ git 'https://github.com/rails/rails.git', branch: 'main' do
6
+ gem 'activerecord'
11
7
  end
12
8
 
13
9
  group :development, :test do
14
- gem "rake"
15
- gem "coveralls", :require => false
10
+ gem 'rake'
11
+ gem 'simplecov', '~> 0.21.2'
12
+ gem 'simplecov-lcov', '~> 0.8.0'
13
+ gem 'sqlite3', '~> 1.6.0'
16
14
  end
17
15
 
18
16
  group :local_development do
19
- gem "pry"
20
- gem "appraisal"
17
+ gem 'appraisal'
18
+ gem 'pry'
21
19
  end
22
20
 
23
- gemspec :path => "../"
21
+ gemspec path: '../'
@@ -0,0 +1,20 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gem 'activerecord', '~> 7.0.0'
6
+
7
+ group :development, :test do
8
+ gem 'activerecord-jdbc-adapter', '~> 70.1'
9
+ gem 'activerecord-jdbcsqlite3-adapter', '~> 70.1'
10
+ gem 'rake'
11
+ gem 'simplecov', '~> 0.21.2'
12
+ gem 'simplecov-lcov', '~> 0.8.0'
13
+ end
14
+
15
+ group :local_development do
16
+ gem 'appraisal'
17
+ gem 'pry'
18
+ end
19
+
20
+ gemspec path: '../'
@@ -0,0 +1,26 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ git 'https://github.com/rails/rails.git', branch: 'main' do
6
+ gem 'activerecord'
7
+ end
8
+
9
+ group :development, :test do
10
+ git 'https://github.com/jruby/activerecord-jdbc-adapter' do
11
+ gem 'activerecord-jdbc-adapter'
12
+ gem 'activerecord-jdbcsqlite3-adapter',
13
+ glob: 'activerecord-jdbcsqlite3-adapter/activerecord-jdbcsqlite3-adapter.gemspec'
14
+ end
15
+
16
+ gem 'rake'
17
+ gem 'simplecov', '~> 0.21.2'
18
+ gem 'simplecov-lcov', '~> 0.8.0'
19
+ end
20
+
21
+ group :local_development do
22
+ gem 'appraisal'
23
+ gem 'pry'
24
+ end
25
+
26
+ gemspec path: '../'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Amoeba
2
4
  module ClassMethods
3
5
  def amoeba(&block)
data/lib/amoeba/cloner.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'forwardable'
2
4
 
3
5
  module Amoeba
@@ -29,7 +31,7 @@ module Amoeba
29
31
  private
30
32
 
31
33
  def parenting_style
32
- amoeba.upbringing ? amoeba.upbringing : _parent_amoeba.parenting
34
+ amoeba.upbringing || _parent_amoeba.parenting
33
35
  end
34
36
 
35
37
  def inherit_strict_parent_settings
@@ -47,8 +49,9 @@ module Amoeba
47
49
  end
48
50
 
49
51
  def inherit_parent_settings
50
- return if !_parent_amoeba.inherit
51
- return unless %w(strict relaxed submissive).include?(parenting_style.to_s)
52
+ return unless _parent_amoeba.inherit
53
+ return unless %w[strict relaxed submissive].include?(parenting_style.to_s)
54
+
52
55
  __send__("inherit_#{parenting_style}_parent_settings".to_sym)
53
56
  end
54
57
 
@@ -67,12 +70,14 @@ module Amoeba
67
70
  # and old children on the copy
68
71
  return unless association.macro == :has_many ||
69
72
  association.is_a?(::ActiveRecord::Reflection::ThroughReflection)
73
+
70
74
  amoeba.exclude_association(association.options[:through])
71
75
  end
72
76
 
73
77
  def follow_only_includes
74
78
  amoeba.includes.each do |include, options|
75
79
  next if options[:if] && !@old_object.send(options[:if])
80
+
76
81
  follow_association(include, @object_klass.reflect_on_association(include))
77
82
  end
78
83
  end
@@ -81,6 +86,7 @@ module Amoeba
81
86
  @object_klass.reflections.each do |name, association|
82
87
  exclude = amoeba.excludes[name.to_sym]
83
88
  next if exclude && (exclude.blank? || @old_object.send(exclude[:if]))
89
+
84
90
  follow_association(name, association)
85
91
  end
86
92
  end
@@ -108,8 +114,9 @@ module Amoeba
108
114
 
109
115
  def follow_association(relation_name, association)
110
116
  return unless amoeba.known_macros.include?(association.macro.to_sym)
117
+
111
118
  follow_klass = ::Amoeba::Macros.list[association.macro.to_sym]
112
- follow_klass.new(self).follow(relation_name, association) if follow_klass
119
+ follow_klass&.new(self)&.follow(relation_name, association)
113
120
  end
114
121
 
115
122
  def process_overrides
data/lib/amoeba/config.rb CHANGED
@@ -1,43 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Amoeba
2
4
  class Config
3
5
  DEFAULTS = {
4
- enabled: false,
5
- inherit: false,
6
- do_preproc: false,
7
- parenting: false,
8
- raised: false,
9
- dup_method: :dup,
10
- remap_method: nil,
11
- includes: {},
12
- excludes: {},
13
- clones: [],
6
+ enabled: false,
7
+ inherit: false,
8
+ do_preproc: false,
9
+ parenting: false,
10
+ raised: false,
11
+ dup_method: :dup,
12
+ remap_method: nil,
13
+ includes: {},
14
+ excludes: {},
15
+ clones: [],
14
16
  customizations: [],
15
- overrides: [],
16
- null_fields: [],
17
- coercions: {},
18
- prefixes: {},
19
- suffixes: {},
20
- regexes: {},
21
- known_macros: [:has_one, :has_many, :has_and_belongs_to_many]
22
- }
23
-
24
- # ActiveRecord 3.x have different implementation of deep_dup
25
- if ::ActiveRecord::VERSION::MAJOR == 3
26
- DEFAULTS.instance_eval do
27
- def deep_dup
28
- each_with_object(dup) do |(key, value), hash|
29
- hash[key.deep_dup] = value.deep_dup
30
- end
31
- end
32
- end
33
- Object.class_eval do
34
- def deep_dup
35
- duplicable? ? dup : self
36
- end
37
- end
38
- end
39
-
40
- DEFAULTS.freeze
17
+ overrides: [],
18
+ null_fields: [],
19
+ coercions: {},
20
+ prefixes: {},
21
+ suffixes: {},
22
+ regexes: {},
23
+ known_macros: %i[has_one has_many has_and_belongs_to_many]
24
+ }.freeze
41
25
 
42
26
  DEFAULTS.each do |key, value|
43
27
  value.freeze if value.is_a?(Array) || value.is_a?(Hash)
@@ -53,7 +37,7 @@ module Amoeba
53
37
  @config = self.class::DEFAULTS.deep_dup
54
38
  end
55
39
 
56
- alias_method :upbringing, :raised
40
+ alias upbringing raised
57
41
 
58
42
  def enable
59
43
  @config[:enabled] = true
@@ -110,35 +94,25 @@ module Amoeba
110
94
  def include_association(value = nil, options = {})
111
95
  enable
112
96
  @config[:excludes] = {}
113
- push_value_to_hash({ value => options }, :includes)
97
+ value = value.is_a?(Array) ? value.map! { |v| [v, options] }.to_h : { value => options }
98
+ push_value_to_hash(value, :includes)
114
99
  end
115
100
 
116
101
  def include_associations(*values)
117
102
  values.flatten.each { |v| include_association(v) }
118
103
  end
119
104
 
120
- # TODO: remove this method in v3.0.0
121
- def include_field(value = nil)
122
- warn 'include_field is deprecated and will be removed in version 3.0.0; please use include_association instead'
123
- include_association(value)
124
- end
125
-
126
105
  def exclude_association(value = nil, options = {})
127
106
  enable
128
107
  @config[:includes] = {}
129
- push_value_to_hash({ value => options }, :excludes)
108
+ value = value.is_a?(Array) ? value.map! { |v| [v, options] }.to_h : { value => options }
109
+ push_value_to_hash(value, :excludes)
130
110
  end
131
111
 
132
112
  def exclude_associations(*values)
133
113
  values.flatten.each { |v| exclude_association(v) }
134
114
  end
135
115
 
136
- # TODO: remove this method in v3.0.0
137
- def exclude_field(value = nil)
138
- warn 'exclude_field is deprecated and will be removed in version 3.0.0; please use exclude_association instead'
139
- exclude_association(value)
140
- end
141
-
142
116
  def clone(value = nil)
143
117
  enable
144
118
  push_value_to_array(value, :clones)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Amoeba
2
4
  module InstanceMethods
3
5
  def _parent_amoeba
@@ -10,6 +12,7 @@ module Amoeba
10
12
 
11
13
  def _first_superclass_with_amoeba
12
14
  return @_first_superclass_with_amoeba unless @_first_superclass_with_amoeba.nil?
15
+
13
16
  klass = self.class
14
17
  while klass.superclass < ::ActiveRecord::Base
15
18
  klass = klass.superclass
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Amoeba
2
4
  module Macros
3
5
  class Base
@@ -8,7 +10,7 @@ module Amoeba
8
10
  end
9
11
 
10
12
  def follow(_relation_name, _association)
11
- fail "#{self.class.name} doesn't implement `follow`!"
13
+ raise "#{self.class.name} doesn't implement `follow`!"
12
14
  end
13
15
 
14
16
  class << self
@@ -19,6 +21,7 @@ module Amoeba
19
21
 
20
22
  def remapped_relation_name(name)
21
23
  return name unless @cloner.amoeba.remap_method
24
+
22
25
  @old_object.__send__(@cloner.amoeba.remap_method, name.to_sym) || name
23
26
  end
24
27
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Amoeba
2
4
  module Macros
3
5
  class HasAndBelongsToMany < ::Amoeba::Macros::Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Amoeba
2
4
  module Macros
3
5
  class HasMany < ::Amoeba::Macros::Base
@@ -1,10 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Amoeba
2
4
  module Macros
3
5
  class HasOne < ::Amoeba::Macros::Base
4
6
  def follow(relation_name, association)
5
7
  return if association.is_a?(::ActiveRecord::Reflection::ThroughReflection)
8
+
6
9
  old_obj = @old_object.__send__(relation_name)
7
10
  return unless old_obj
11
+
8
12
  copy_of_obj = old_obj.amoeba_dup(@options)
9
13
  copy_of_obj[:"#{association.foreign_key}"] = nil
10
14
  relation_name = remapped_relation_name(relation_name)
data/lib/amoeba/macros.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Amoeba
2
4
  module Macros
3
5
  extend self
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Amoeba
2
- VERSION = '3.1.0'
4
+ VERSION = '3.3.0'
3
5
  end
data/lib/amoeba.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_record'
2
4
  require 'active_support/all'
3
5
  require 'amoeba/version'
@@ -14,5 +16,7 @@ require 'amoeba/instance_methods'
14
16
  module Amoeba
15
17
  end
16
18
 
17
- ActiveRecord::Base.send :extend, Amoeba::ClassMethods
18
- ActiveRecord::Base.send :include, Amoeba::InstanceMethods
19
+ ActiveSupport.on_load :active_record do
20
+ extend Amoeba::ClassMethods
21
+ include Amoeba::InstanceMethods
22
+ end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe 'amoeba' do
4
4
  context 'dup' do
5
- before :each do
5
+ before do
6
6
  require ::File.dirname(__FILE__) + '/../support/data.rb'
7
7
  end
8
8
 
@@ -73,12 +73,17 @@ describe 'amoeba' do
73
73
  expect(new_post.supercats.map(&:ramblings)).to include('Copy of zomg')
74
74
  expect(new_post.supercats.map(&:other_ramblings).uniq.length).to eq(1)
75
75
  expect(new_post.supercats.map(&:other_ramblings).uniq).to include('La la la')
76
- expect(new_post.contents).to eq("Here's a copy: #{old_post.contents.gsub(/dog/, 'cat')} (copied version)")
76
+ expect(new_post.contents).to eq("Here's a copy: #{old_post.contents.gsub(/dog/,
77
+ 'cat')} (copied version)")
77
78
  expect(new_post.comments.length).to eq(5)
78
- expect(new_post.comments.select { |c| c.nerf == 'ratatat' && c.contents.nil? }.length).to eq(1)
79
+ expect(new_post.comments.select do |c|
80
+ c.nerf == 'ratatat' && c.contents.nil?
81
+ end.length).to eq(1)
79
82
  expect(new_post.comments.select { |c| c.nerf == 'ratatat' }.length).to eq(2)
80
83
  expect(new_post.comments.select { |c| c.nerf == 'bonk' }.length).to eq(1)
81
- expect(new_post.comments.select { |c| c.nerf == 'bonkers' && c.contents.nil? }.length).to eq(1)
84
+ expect(new_post.comments.select do |c|
85
+ c.nerf == 'bonkers' && c.contents.nil?
86
+ end.length).to eq(1)
82
87
 
83
88
  new_post.widgets.map(&:id).each do |id|
84
89
  expect(old_post.widgets.map(&:id)).not_to include(id)
@@ -96,7 +101,9 @@ describe 'amoeba' do
96
101
  expect(new_author.errors.messages).to be_empty
97
102
  expect(new_author.posts.first.custom_things.length).to eq(3)
98
103
  expect(new_author.posts.first.custom_things.select { |ct| ct.value == [] }.length).to eq(1)
99
- expect(new_author.posts.first.custom_things.select { |ct| ct.value == [1, 2] }.length).to eq(1)
104
+ expect(new_author.posts.first.custom_things.select do |ct|
105
+ ct.value == [1, 2]
106
+ end.length).to eq(1)
100
107
  expect(new_author.posts.first.custom_things.select { |ct| ct.value == [78] }.length).to eq(1)
101
108
  # }}}
102
109
  # Products {{{
@@ -176,60 +183,90 @@ describe 'amoeba' do
176
183
  end
177
184
  end
178
185
 
179
- context 'use if condition in includes and excludes' do
186
+ context 'Using a if condition' do
187
+ subject { post.amoeba_dup.save! }
188
+
180
189
  before(:all) do
181
190
  require ::File.dirname(__FILE__) + '/../support/data.rb'
182
191
  end
192
+
183
193
  before { ::Post.fresh_amoeba }
184
194
 
185
- subject { post.amoeba_dup.save! }
186
195
  let(:post) { Post.first }
187
196
 
188
- it 'includes associations with truthy condition' do
197
+ it 'includes an association with truthy condition' do
189
198
  ::Post.amoeba do
190
199
  include_association :comments, if: :truthy?
191
200
  end
192
- expect { subject }.to change { Comment.count }.by(3)
201
+ expect { subject }.to change(Comment, :count).by(3)
193
202
  end
194
203
 
195
- it 'does not include associations with false condition' do
204
+ it 'does not include an association with a falsey condition' do
196
205
  ::Post.amoeba do
197
206
  include_association :comments, if: :falsey?
198
207
  end
199
- expect { subject }.not_to change { Comment.count }
208
+ expect { subject }.not_to change(Comment, :count)
200
209
  end
201
210
 
202
- it 'excludes associations with truthy condition' do
211
+ it 'excludes an association with a truthy condition' do
203
212
  ::Post.amoeba do
204
213
  exclude_association :comments, if: :truthy?
205
214
  end
206
- expect { subject }.not_to change { Comment.count }
215
+ expect { subject }.not_to change(Comment, :count)
207
216
  end
208
217
 
209
- it 'does not exclude associations with false condition' do
218
+ it 'does not exclude an association with a falsey condition' do
210
219
  ::Post.amoeba do
211
220
  exclude_association :comments, if: :falsey?
212
221
  end
213
- expect { subject }.to change { Comment.count }.by(3)
222
+ expect { subject }.to change(Comment, :count).by(3)
223
+ end
224
+
225
+ it 'includes associations from a given array with a truthy condition' do
226
+ ::Post.amoeba do
227
+ include_association [:comments], if: :truthy?
228
+ end
229
+ expect { subject }.to change(Comment, :count).by(3)
230
+ end
231
+
232
+ it 'does not include associations from a given array with a falsey condition' do
233
+ ::Post.amoeba do
234
+ include_association [:comments], if: :falsey?
235
+ end
236
+ expect { subject }.not_to change(Comment, :count)
237
+ end
238
+
239
+ it 'does exclude associations from a given array with a truthy condition' do
240
+ ::Post.amoeba do
241
+ exclude_association [:comments], if: :truthy?
242
+ end
243
+ expect { subject }.not_to change(Comment, :count)
244
+ end
245
+
246
+ it 'does not exclude associations from a given array with a falsey condition' do
247
+ ::Post.amoeba do
248
+ exclude_association [:comments], if: :falsey?
249
+ end
250
+ expect { subject }.to change(Comment, :count).by(3)
214
251
  end
215
252
  end
216
253
 
217
254
  context 'override' do
218
- before :each do
255
+ before do
219
256
  ::Image.fresh_amoeba
220
257
  ::Image.amoeba do
221
258
  override ->(old, new) { new.product_id = 13 if old.filename == 'test.jpg' }
222
259
  end
223
260
  end
224
261
 
225
- it 'should override fields' do
262
+ it 'overrides fields' do
226
263
  image = ::Image.create(filename: 'test.jpg', product_id: 12)
227
264
  image_dup = image.amoeba_dup
228
265
  expect(image_dup.save).to be_truthy
229
266
  expect(image_dup.product_id).to eq(13)
230
267
  end
231
268
 
232
- it 'should not override fields' do
269
+ it 'does not override fields' do
233
270
  image = ::Image.create(filename: 'test2.jpg', product_id: 12)
234
271
  image_dup = image.amoeba_dup
235
272
  expect(image_dup.save).to be_truthy
@@ -238,7 +275,7 @@ describe 'amoeba' do
238
275
  end
239
276
 
240
277
  context 'nullify' do
241
- before :each do
278
+ before do
242
279
  ::Image.fresh_amoeba
243
280
  ::Image.amoeba do
244
281
  nullify :product_id
@@ -248,14 +285,14 @@ describe 'amoeba' do
248
285
  let(:image) { ::Image.create(filename: 'test.jpg', product_id: 12) }
249
286
  let(:image_dup) { image.amoeba_dup }
250
287
 
251
- it 'should nullify fields' do
288
+ it 'nullifies fields' do
252
289
  expect(image_dup.save).to be_truthy
253
290
  expect(image_dup.product_id).to be_nil
254
291
  end
255
292
  end
256
293
 
257
294
  context 'strict propagate' do
258
- it 'should call #reset_amoeba' do
295
+ it 'calls #reset_amoeba' do
259
296
  expect(::SuperBlackBox).to receive(:reset_amoeba).and_call_original
260
297
  box = ::SuperBlackBox.create(title: 'Super Black Box', price: 9.99, length: 1, metal: '1')
261
298
  new_box = box.amoeba_dup
@@ -284,13 +321,16 @@ describe 'amoeba' do
284
321
 
285
322
  context 'preprocessing fields' do
286
323
  subject { super_admin.amoeba_dup }
287
- let(:super_admin) { ::SuperAdmin.create!(email: 'user@example.com', active: true, password: 'password') }
288
324
 
289
- it 'should accept "set" to set false to attribute' do
325
+ let(:super_admin) do
326
+ ::SuperAdmin.create!(email: 'user@example.com', active: true, password: 'password')
327
+ end
328
+
329
+ it 'accepts "set" to set false to attribute' do
290
330
  expect(subject.active).to be false
291
331
  end
292
332
 
293
- it 'should skip "prepend" if it equal to false' do
333
+ it 'skips "prepend" if it equal to false' do
294
334
  expect(subject.password).to eq('password')
295
335
  end
296
336
  end
@@ -301,13 +341,15 @@ describe 'amoeba' do
301
341
  it 'does not fail with a deep inheritance' do
302
342
  sub_sub_product = BoxSubSubProduct.create(title: 'Awesome shoes')
303
343
  another_product = BoxAnotherProduct.create(title: 'Cleaning product')
304
- sub_sub_product.update_attributes(box: box, another_product: another_product)
344
+ sub_sub_product.update(box: box, another_product: another_product)
305
345
  expect(box.sub_products.first.another_product.title).to eq('Cleaning product')
306
346
  expect(box.amoeba_dup.sub_products.first.another_product.title).to eq('Cleaning product')
307
347
  end
308
348
  end
309
349
 
310
350
  context 'inheritance extended' do
351
+ subject { stage.amoeba_dup }
352
+
311
353
  let(:stage) do
312
354
  stage = CustomStage.new(title: 'My Stage', external_id: 213)
313
355
  stage.listeners.build(name: 'John')
@@ -318,19 +360,19 @@ describe 'amoeba' do
318
360
  stage
319
361
  end
320
362
 
321
- subject { stage.amoeba_dup }
322
-
323
- it "contains parent association and own associations", :aggregate_failures do
363
+ it 'contains parent association and own associations', :aggregate_failures do
324
364
  subject
325
- expect { subject.save! }.to change(Listener, :count).by(2).
326
- and change(Specialist, :count).by(1).
327
- and change(CustomRule, :count).by(1)
365
+ expect { subject.save! }.to change(Listener, :count).by(2)
366
+ .and change(Specialist, :count).by(1)
367
+ .and change(
368
+ CustomRule, :count
369
+ ).by(1)
328
370
 
329
371
  expect(subject.title).to eq 'My Stage'
330
372
  expect(subject.external_id).to be_nil
331
- expect(subject.listeners.find_by(name: 'John')).to_not be_nil
332
- expect(subject.listeners.find_by(name: 'Helen')).to_not be_nil
333
- expect(subject.specialists.find_by(name: 'Jack')).to_not be_nil
373
+ expect(subject.listeners.find_by(name: 'John')).not_to be_nil
374
+ expect(subject.listeners.find_by(name: 'Helen')).not_to be_nil
375
+ expect(subject.specialists.find_by(name: 'Jack')).not_to be_nil
334
376
  expect(subject.custom_rules.first.description).to eq 'Kill all humans'
335
377
  end
336
378
  end