active_data 1.1.2 → 1.1.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aec99c84b95cc5a79feaf4230cdbf4eb89780afc910bf03278d5f2377a48b0c5
4
- data.tar.gz: 71941c2fd303ccca637d7f58646dc5a3e3417f506e8cee405a57649a3c770d6c
3
+ metadata.gz: 5de412d5036c1e3192c87b9c7c7cc553cccaa5d53dc48adb32d992c3cf9fca25
4
+ data.tar.gz: 52c67fb161d13a2f7b4791f048c662962b2f0355b77fb8f10d434e6e5279692f
5
5
  SHA512:
6
- metadata.gz: 3603d8b5de895f35f5c19db31a1de8fa71853595a0d93cf772c2894ff0a89fec0afb1d3b3c6f56b8d410ea22339f5e9abe96ca1023a1b414b720f1526afcc09e
7
- data.tar.gz: 35a90113764e1a5125d8cd205036e804e9dbfe7e2cb1ffdd812d6b99a5b0233c7efebafaab8452ef12d89c1a78f3d8ee212b55dd5ad59bbc8b399e80c256cbc8
6
+ metadata.gz: a804cb81e49839e78dbd9de0bd7c670bfde5b34c46651009f15bc70b890edae3a2148d0fd48251179fe83068769c6ddb950969cb2f8eb06b116e1c184d2724e2
7
+ data.tar.gz: 6b8277845088785bb3a4cd95eb2c56882a7ece7c1cb395e04106717a1ec7ace440709b70c7bec9150be2c9b48626cbb458e8c6882ab01ac808067e428f1a55c3
@@ -49,6 +49,7 @@ Metrics/BlockLength:
49
49
  Metrics/ModuleLength:
50
50
  Exclude:
51
51
  - '**/*_spec.rb'
52
+ - 'lib/active_data.rb'
52
53
 
53
54
  Style/Alias:
54
55
  EnforcedStyle: prefer_alias_method
@@ -1,32 +1,15 @@
1
1
  sudo: false
2
2
 
3
- rvm:
4
- - 2.2.10
5
- - 2.3.7
6
- - 2.4.4
7
- - rbx
8
-
9
- gemfile:
10
- - gemfiles/rails.4.0.gemfile
11
- - gemfiles/rails.4.1.gemfile
12
- - gemfiles/rails.4.2.gemfile
13
- - gemfiles/rails.5.0.gemfile
14
- - gemfiles/rails.5.1.gemfile
15
- - gemfiles/rails.5.2.gemfile
16
-
17
3
  matrix:
18
- allow_failures:
19
- - rvm: rbx
20
- exclude:
21
- - rvm: 2.4.4
22
- gemfile: gemfiles/rails.4.0.gemfile
23
- - rvm: 2.4.4
24
- gemfile: gemfiles/rails.4.1.gemfile
25
- - rvm: 2.4.4
4
+ include:
5
+ - rvm: 2.3.8
26
6
  gemfile: gemfiles/rails.4.2.gemfile
27
-
28
- before_install:
29
- - gem update --system --no-doc
7
+ - rvm: 2.4.7
8
+ gemfile: gemfiles/rails.5.1.gemfile
9
+ - rvm: 2.5.6
10
+ gemfile: gemfiles/rails.5.2.gemfile
11
+ - rvm: 2.6.4
12
+ gemfile: gemfiles/rails.6.0.gemfile
30
13
 
31
14
  script:
32
15
  - bundle exec rspec
data/Appraisals CHANGED
@@ -1,7 +1,8 @@
1
- %w[4.0 4.1 4.2 5.0 5.1 5.2].each do |version|
1
+ %w[4.2 5.1 5.2 6.0].each do |version|
2
2
  appraise "rails.#{version}" do
3
3
  gem 'activesupport', "~> #{version}.0"
4
4
  gem 'activemodel', "~> #{version}.0"
5
5
  gem 'activerecord', "~> #{version}.0"
6
+ gem 'sqlite3', '~> 1.3.6' if version < '6.0'
6
7
  end
7
8
  end
@@ -1,5 +1,29 @@
1
1
  # master
2
2
 
3
+ # Version 1.1.7
4
+
5
+ * Add typecasting from `ActionController::Parameters` to `Hash` (#73)
6
+
7
+ # Version 1.1.6
8
+
9
+ * Fix Ruby 2.6 deprecations (#72)
10
+
11
+ # Version 1.1.5
12
+
13
+ * Rails 6 support (#70, #71)
14
+
15
+ # Version 1.1.4
16
+
17
+ ## Changes
18
+
19
+ * `came_from_default?` attribute method (#66)
20
+
21
+ # Version 1.1.3
22
+
23
+ ## Changes
24
+
25
+ * `came_from_user?` attribute method (#65)
26
+
3
27
  # Version 1.1.2
4
28
 
5
29
  ## Changes
@@ -14,14 +14,14 @@ Gem::Specification.new do |gem|
14
14
  gem.require_paths = ['lib']
15
15
  gem.version = ActiveData::VERSION
16
16
 
17
+ gem.add_development_dependency 'actionpack', '>= 4.0'
17
18
  gem.add_development_dependency 'activerecord', '>= 4.0'
18
19
  gem.add_development_dependency 'appraisal'
19
20
  gem.add_development_dependency 'database_cleaner'
20
21
  gem.add_development_dependency 'rake'
21
- gem.add_development_dependency 'rspec'
22
+ gem.add_development_dependency 'rspec', '~> 3.7.0'
22
23
  gem.add_development_dependency 'rspec-its'
23
24
  gem.add_development_dependency 'rubocop', '0.52.1'
24
- gem.add_development_dependency 'rubysl', '~> 2.0' if RUBY_ENGINE == 'rbx'
25
25
  gem.add_development_dependency 'sqlite3'
26
26
  gem.add_development_dependency 'uuidtools'
27
27
 
@@ -5,6 +5,7 @@ source "https://rubygems.org"
5
5
  gem "activesupport", "~> 4.2.0"
6
6
  gem "activemodel", "~> 4.2.0"
7
7
  gem "activerecord", "~> 4.2.0"
8
+ gem "sqlite3", "~> 1.3.6"
8
9
 
9
10
  group :test do
10
11
  gem "guard"
@@ -5,6 +5,7 @@ source "https://rubygems.org"
5
5
  gem "activesupport", "~> 5.1.0"
6
6
  gem "activemodel", "~> 5.1.0"
7
7
  gem "activerecord", "~> 5.1.0"
8
+ gem "sqlite3", "~> 1.3.6"
8
9
 
9
10
  group :test do
10
11
  gem "guard"
@@ -5,6 +5,7 @@ source "https://rubygems.org"
5
5
  gem "activesupport", "~> 5.2.0"
6
6
  gem "activemodel", "~> 5.2.0"
7
7
  gem "activerecord", "~> 5.2.0"
8
+ gem "sqlite3", "~> 1.3.6"
8
9
 
9
10
  group :test do
10
11
  gem "guard"
@@ -2,9 +2,9 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activesupport", "~> 4.0.0"
6
- gem "activemodel", "~> 4.0.0"
7
- gem "activerecord", "~> 4.0.0"
5
+ gem "activesupport", "~> 6.0.0"
6
+ gem "activemodel", "~> 6.0.0"
7
+ gem "activerecord", "~> 6.0.0"
8
8
 
9
9
  group :test do
10
10
  gem "guard"
@@ -61,6 +61,16 @@ module ActiveData
61
61
  value
62
62
  end
63
63
  end
64
+ ActiveSupport.on_load :action_controller do
65
+ ActiveData.typecaster('Hash') do |value|
66
+ case value
67
+ when ActionController::Parameters
68
+ value.to_h if value.permitted?
69
+ when ::Hash then
70
+ value
71
+ end
72
+ end
73
+ end
64
74
  typecaster('Date') do |value|
65
75
  begin
66
76
  value.to_date
@@ -100,7 +110,7 @@ module ActiveData
100
110
  typecaster('BigDecimal') do |value|
101
111
  next unless value
102
112
  begin
103
- ::BigDecimal.new Float(value).to_s
113
+ BigDecimal(Float(value).to_s)
104
114
  rescue ArgumentError, TypeError
105
115
  nil
106
116
  end
@@ -141,6 +141,10 @@ module ActiveData
141
141
  attribute(name).read_before_type_cast
142
142
  end
143
143
 
144
+ def attribute_came_from_user?(name)
145
+ attribute(name).came_from_user?
146
+ end
147
+
144
148
  def attribute_present?(name)
145
149
  attribute(name).value_present?
146
150
  end
@@ -8,14 +8,16 @@ module ActiveData
8
8
  def initialize(name, owner)
9
9
  @name = name
10
10
  @owner = owner
11
+ @origin = :default
11
12
  end
12
13
 
13
14
  def reflection
14
15
  @owner.class._attributes[name]
15
16
  end
16
17
 
17
- def write_value(value)
18
+ def write_value(value, origin: :user)
18
19
  reset
20
+ @origin = origin
19
21
  @value_cache = value
20
22
  end
21
23
 
@@ -36,6 +38,14 @@ module ActiveData
36
38
  @value_cache
37
39
  end
38
40
 
41
+ def came_from_user?
42
+ @origin == :user
43
+ end
44
+
45
+ def came_from_default?
46
+ @origin == :default
47
+ end
48
+
39
49
  def value_present?
40
50
  !read.nil? && !(read.respond_to?(:empty?) && read.empty?)
41
51
  end
@@ -71,8 +81,13 @@ module ActiveData
71
81
  pollute = owner.class.dirty? && !owner.send(:attribute_changed?, name)
72
82
 
73
83
  if pollute
74
- previous_value = read
84
+ previous_value = owner.__send__(name)
85
+ owner.send("#{name}_will_change!")
86
+
75
87
  result = yield
88
+
89
+ owner.__send__(:clear_attribute_changes, [name]) if owner.__send__(name) == previous_value
90
+
76
91
  if previous_value != read || (
77
92
  read.respond_to?(:changed?) &&
78
93
  read.changed?
@@ -27,6 +27,10 @@ module ActiveData
27
27
  attribute('#{name}').read_before_type_cast
28
28
  end
29
29
 
30
+ def #{name}_came_from_user?
31
+ attribute('#{name}').came_from_user?
32
+ end
33
+
30
34
  def #{name}_default
31
35
  attribute('#{name}').default
32
36
  end
@@ -26,7 +26,7 @@ module ActiveData
26
26
 
27
27
  def build_attribute(owner, raw_value = ActiveData::UNDEFINED)
28
28
  attribute = self.class.attribute_class.new(name, owner)
29
- attribute.write_value(raw_value) unless raw_value == ActiveData::UNDEFINED
29
+ attribute.write_value(raw_value, origin: :persistence) unless raw_value == ActiveData::UNDEFINED
30
30
  attribute
31
31
  end
32
32
 
@@ -1,3 +1,3 @@
1
1
  module ActiveData
2
- VERSION = '1.1.2'.freeze
2
+ VERSION = '1.1.7'.freeze
3
3
  end
@@ -58,9 +58,48 @@ describe ActiveData::Model::Attributes::Attribute do
58
58
  end
59
59
 
60
60
  describe '#typecast' do
61
- specify { expect(attribute.typecast(:hello)).to eq(:hello) }
62
- specify { expect(attribute(type: Integer).typecast(42)).to eq(42) }
63
- specify { expect(attribute(type: Integer).typecast('42')).to eq(42) }
61
+ context 'when Object' do
62
+ specify { expect(attribute.typecast(:hello)).to eq(:hello) }
63
+ end
64
+
65
+ context 'when Integer' do
66
+ specify { expect(attribute(type: Integer).typecast(42)).to eq(42) }
67
+ specify { expect(attribute(type: Integer).typecast('42')).to eq(42) }
68
+ end
69
+
70
+ context 'when Hash' do
71
+ let(:to_h) { {'x' => {'foo' => 'bar'}, 'y' => 2} }
72
+ let(:parameters) { ActionController::Parameters.new(to_h) }
73
+
74
+ before(:all) do
75
+ @default_hash_typecaster = ActiveData.typecaster('Hash')
76
+ require 'action_controller'
77
+ Class.new(ActionController::Base)
78
+ @action_controller_hash_typecaster = ActiveData.typecaster('Hash')
79
+ end
80
+
81
+ context 'when ActionController is loaded' do
82
+ before { ActiveData.typecaster('Hash', &@action_controller_hash_typecaster) }
83
+ after { ActiveData.typecaster('Hash', &@default_hash_typecaster) }
84
+
85
+ specify { expect(attribute(type: Hash).typecast(nil)).to be_nil }
86
+ specify { expect(attribute(type: Hash).typecast(to_h)).to eq(to_h) }
87
+ specify { expect(attribute(type: Hash).typecast(parameters)).to be_nil }
88
+ specify { expect(attribute(type: Hash).typecast(parameters.permit(:y, x: [:foo]))).to eq(to_h) }
89
+ end
90
+
91
+ context 'when ActionController is not loaded' do
92
+ before { ActiveData.typecaster('Hash', &@default_hash_typecaster) }
93
+
94
+ specify { expect(attribute(type: Hash).typecast(nil)).to be_nil }
95
+ specify { expect(attribute(type: Hash).typecast(to_h)).to eq(to_h) }
96
+ if ActiveSupport.version > Gem::Version.new('4.3')
97
+ specify { expect(attribute(type: Hash).typecast(parameters.permit(:y, x: [:foo]))).to be_nil }
98
+ else
99
+ specify { expect(attribute(type: Hash).typecast(parameters.permit(:y, x: [:foo]))).to eq(to_h) }
100
+ end
101
+ end
102
+ end
64
103
  end
65
104
 
66
105
  describe '#enum' do
@@ -37,6 +37,22 @@ describe ActiveData::Model::Attributes::Base do
37
37
  end
38
38
  end
39
39
 
40
+ describe '#came_from_user?' do
41
+ let(:field) { attribute(type: String, default: 'world') }
42
+ let(:object) { Object.new }
43
+
44
+ specify { expect(field.came_from_user?).to eq(false) }
45
+ specify { expect(field.tap { |r| r.write('value') }.came_from_user?).to eq(true) }
46
+ end
47
+
48
+ describe '#came_from_default?' do
49
+ let(:field) { attribute(type: String, default: 'world') }
50
+ let(:object) { Object.new }
51
+
52
+ specify { expect(field.came_from_default?).to eq(true) }
53
+ specify { expect(field.tap { |r| r.write('value') }.came_from_default?).to eq(false) }
54
+ end
55
+
40
56
  describe '#value_present?' do
41
57
  let(:field) { attribute }
42
58
 
@@ -249,6 +249,7 @@ describe ActiveData::Model::Attributes do
249
249
  its(:hello?) { should eq(false) }
250
250
  its(:count) { should == 10 }
251
251
  its(:count_before_type_cast) { should == '10' }
252
+ its(:count_came_from_user?) { should eq(false) }
252
253
  its(:count?) { should eq(true) }
253
254
  its(:calc) { should == 5 }
254
255
  its(:enum?) { should eq(false) }
@@ -256,6 +257,7 @@ describe ActiveData::Model::Attributes do
256
257
  specify { expect { subject.hello = 'worlds' }.to change { subject.hello }.from(nil).to('worlds') }
257
258
  specify { expect { subject.count = 20 }.to change { subject.count }.from(10).to(20) }
258
259
  specify { expect { subject.calc = 15 }.to change { subject.calc }.from(5).to(15) }
260
+ specify { expect { subject.count = '11' }.to change { subject.count_came_from_user? }.from(false).to(true) }
259
261
 
260
262
  context 'enums' do
261
263
  specify do
@@ -71,8 +71,8 @@ describe ActiveData::Model::Dirty do
71
71
  specify { expect(Model.new(numbers: '42').changes).to eq('numbers' => [[], [42]]) }
72
72
 
73
73
  # Have no idea how should it work right now
74
- specify { expect(Model.new(title: 'Hello').changes).to eq('title' => [{}, 'Hello']) }
75
- specify { expect(Model.new(title_translations: {en: 'Hello'}).changes).to eq('title' => [{}, 'Hello']) }
74
+ specify { expect(Model.new(title: 'Hello').changes).to eq('title' => [nil, 'Hello']) }
75
+ specify { expect(Model.new(title_translations: {en: 'Hello'}).changes).to eq('title' => [nil, 'Hello']) }
76
76
 
77
77
  specify { expect(Model.new).not_to respond_to :something_changed? }
78
78
  specify { expect(Model.new).to respond_to :n_changed? }
@@ -39,11 +39,17 @@ describe ActiveData::Model::Representation do
39
39
  end
40
40
 
41
41
  context 'dirty' do
42
- before { Post.include ActiveData::Model::Dirty }
42
+ before do
43
+ Author.include ActiveData::Model::Dirty
44
+ Post.include ActiveData::Model::Dirty
45
+ end
43
46
 
44
47
  specify do
45
48
  expect(Post.new(author: author, rate: '33').changes)
46
49
  .to eq('author' => [nil, author], 'rate' => [42, 33])
50
+
51
+ expect(Post.new(author: author, rate: '33').changes)
52
+ .to eq('author' => [nil, author])
47
53
  end
48
54
  end
49
55
 
@@ -4,6 +4,8 @@ Bundler.require
4
4
 
5
5
  require 'rspec/its'
6
6
  require 'active_record'
7
+ require 'rack/test'
8
+ require 'action_controller/metal/strong_parameters'
7
9
  require 'database_cleaner'
8
10
 
9
11
  require 'support/model_helpers'
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_data
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - pyromaniac
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-11 00:00:00.000000000 Z
11
+ date: 2020-08-20 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: actionpack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '4.0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: activerecord
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -70,16 +84,16 @@ dependencies:
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
72
86
  requirements:
73
- - - ">="
87
+ - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '0'
89
+ version: 3.7.0
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
- - - ">="
94
+ - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '0'
96
+ version: 3.7.0
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rspec-its
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -199,12 +213,10 @@ files:
199
213
  - README.md
200
214
  - Rakefile
201
215
  - active_data.gemspec
202
- - gemfiles/rails.4.0.gemfile
203
- - gemfiles/rails.4.1.gemfile
204
216
  - gemfiles/rails.4.2.gemfile
205
- - gemfiles/rails.5.0.gemfile
206
217
  - gemfiles/rails.5.1.gemfile
207
218
  - gemfiles/rails.5.2.gemfile
219
+ - gemfiles/rails.6.0.gemfile
208
220
  - lib/active_data.rb
209
221
  - lib/active_data/active_record/associations.rb
210
222
  - lib/active_data/active_record/nested_attributes.rb
@@ -318,7 +330,7 @@ files:
318
330
  homepage: ''
319
331
  licenses: []
320
332
  metadata: {}
321
- post_install_message:
333
+ post_install_message:
322
334
  rdoc_options: []
323
335
  require_paths:
324
336
  - lib
@@ -333,9 +345,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
333
345
  - !ruby/object:Gem::Version
334
346
  version: '0'
335
347
  requirements: []
336
- rubyforge_project:
337
- rubygems_version: 2.7.6
338
- signing_key:
348
+ rubygems_version: 3.1.2
349
+ signing_key:
339
350
  specification_version: 4
340
351
  summary: Working with hashes in AR style
341
352
  test_files:
@@ -1,14 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activesupport", "~> 4.1.0"
6
- gem "activemodel", "~> 4.1.0"
7
- gem "activerecord", "~> 4.1.0"
8
-
9
- group :test do
10
- gem "guard"
11
- gem "guard-rspec"
12
- end
13
-
14
- gemspec path: "../"
@@ -1,14 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activesupport", "~> 5.0.0"
6
- gem "activemodel", "~> 5.0.0"
7
- gem "activerecord", "~> 5.0.0"
8
-
9
- group :test do
10
- gem "guard"
11
- gem "guard-rspec"
12
- end
13
-
14
- gemspec path: "../"