active_data 1.1.2 → 1.1.7

Sign up to get free protection for your applications and to get access to all the features.
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: "../"