store_attribute 0.5.2 → 0.8.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.
@@ -1,5 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'rails', '~> 5.1.0'
4
-
5
- gemspec path: '..'
@@ -1,6 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'arel', github: 'rails/arel'
4
- gem 'rails', github: 'rails/rails'
5
-
6
- gemspec path: '..'
@@ -1,171 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe StoreAttribute do
4
- before do
5
- @connection = ActiveRecord::Base.connection
6
-
7
- @connection.transaction do
8
- @connection.create_table('users') do |t|
9
- t.jsonb :jparams, default: {}, null: false
10
- t.text :custom
11
- t.hstore :hdata, default: {}, null: false
12
- end
13
- end
14
-
15
- User.reset_column_information
16
- end
17
-
18
- after do
19
- @connection.drop_table 'users', if_exists: true
20
- end
21
-
22
- let(:time) { DateTime.new(2015, 2, 14, 17, 0, 0) }
23
- let(:time_str) { '2015-02-14 17:00' }
24
- let(:time_str_utc) { '2015-02-14 17:00:00 UTC' }
25
-
26
- context "hstore" do
27
- it "typecasts on build" do
28
- user = User.new(visible: 't', login_at: time_str)
29
- expect(user.visible).to eq true
30
- expect(user).to be_visible
31
- expect(user.login_at).to eq time
32
- end
33
-
34
- it "typecasts on reload" do
35
- user = User.new(visible: 't', login_at: time_str)
36
- user.save!
37
- user = User.find(user.id)
38
-
39
- expect(user.visible).to eq true
40
- expect(user).to be_visible
41
- expect(user.login_at).to eq time
42
- end
43
-
44
- it "works with accessors" do
45
- user = User.new
46
- user.visible = false
47
- user.login_at = time_str
48
- user.save!
49
-
50
- user = User.find(user.id)
51
-
52
- expect(user.visible).to be false
53
- expect(user).not_to be_visible
54
- expect(user.login_at).to eq time
55
-
56
- ron = RawUser.find(user.id)
57
- expect(ron.hdata['visible']).to eq 'false'
58
- expect(ron.hdata['login_at']).to eq time_str_utc
59
- end
60
-
61
- it "handles options" do
62
- expect { User.create!(ratio: 1024) }.to raise_error(RangeError)
63
- end
64
-
65
- it "YAML roundtrip" do
66
- user = User.create!(visible: '0', login_at: time_str)
67
- dumped = YAML.load(YAML.dump(user))
68
-
69
- expect(dumped.visible).to be false
70
- expect(dumped.login_at).to eq time
71
- end
72
- end
73
-
74
- context "jsonb" do
75
- it "typecasts on build" do
76
- jamie = User.new(
77
- active: 'true',
78
- salary: 3.1999,
79
- birthday: '2000-01-01'
80
- )
81
- expect(jamie).to be_active
82
- expect(jamie.salary).to eq 3
83
- expect(jamie.birthday).to eq Date.new(2000, 1, 1)
84
- expect(jamie.jparams['birthday']).to eq Date.new(2000, 1, 1)
85
- expect(jamie.jparams['active']).to eq true
86
- end
87
-
88
- it "typecasts on reload" do
89
- jamie = User.create!(jparams: { 'active' => '1', 'birthday' => '01/01/2000', 'salary' => '3.14' })
90
- jamie = User.find(jamie.id)
91
-
92
- expect(jamie).to be_active
93
- expect(jamie.salary).to eq 3
94
- expect(jamie.birthday).to eq Date.new(2000, 1, 1)
95
- expect(jamie.jparams['birthday']).to eq Date.new(2000, 1, 1)
96
- expect(jamie.jparams['active']).to eq true
97
- end
98
-
99
- it "works with accessors" do
100
- john = User.new
101
- john.active = 1
102
-
103
- expect(john).to be_active
104
- expect(john.jparams['active']).to eq true
105
-
106
- john.jparams = { active: 'true', salary: '123.123', birthday: '01/01/2012' }
107
- expect(john).to be_active
108
- expect(john.birthday).to eq Date.new(2012, 1, 1)
109
- expect(john.salary).to eq 123
110
-
111
- john.save!
112
-
113
- ron = RawUser.find(john.id)
114
- expect(ron.jparams['active']).to eq true
115
- expect(ron.jparams['birthday']).to eq '2012-01-01'
116
- expect(ron.jparams['salary']).to eq 123
117
- end
118
-
119
- it "re-typecast old data" do
120
- jamie = User.create!
121
- User.update_all('jparams = \'{"active":"1", "salary":"12.02"}\'::jsonb')
122
-
123
- jamie = User.find(jamie.id)
124
- expect(jamie).to be_active
125
- expect(jamie.salary).to eq 12
126
-
127
- jamie.save!
128
-
129
- ron = RawUser.find(jamie.id)
130
- expect(ron.jparams['active']).to eq true
131
- expect(ron.jparams['salary']).to eq 12
132
- end
133
- end
134
-
135
- context "custom types" do
136
- it "typecasts on build" do
137
- user = User.new(price: "$1")
138
- expect(user.price).to eq 100
139
- end
140
-
141
- it "typecasts on reload" do
142
- jamie = User.create!(custom: { price: '$12' })
143
- expect(jamie.reload.price).to eq 1200
144
-
145
- jamie = User.find(jamie.id)
146
-
147
- expect(jamie.price).to eq 1200
148
- end
149
- end
150
-
151
- context "store subtype" do
152
- it "typecasts on build" do
153
- user = User.new(inner_json: { x: 1 })
154
- expect(user.inner_json).to eq('x' => 1)
155
- end
156
-
157
- it "typecasts on update" do
158
- user = User.new
159
- user.update!(inner_json: { x: 1 })
160
- expect(user.inner_json).to eq('x' => 1)
161
-
162
- expect(user.reload.inner_json).to eq('x' => 1)
163
- end
164
-
165
- it "typecasts on reload" do
166
- jamie = User.create!(inner_json: { x: 1 })
167
- jamie = User.find(jamie.id)
168
- expect(jamie.inner_json).to eq('x' => 1)
169
- end
170
- end
171
- end
@@ -1,43 +0,0 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
- $LOAD_PATH.unshift(File.dirname(__FILE__))
3
-
4
- if ENV['COVER']
5
- require 'simplecov'
6
- SimpleCov.root File.join(File.dirname(__FILE__), '..')
7
- SimpleCov.start
8
- end
9
-
10
- require 'rspec'
11
- require 'pry-byebug'
12
- require 'active_record'
13
- require 'pg'
14
- require 'store_attribute'
15
-
16
- RAILS_5_1 = ActiveRecord.version.release >= Gem::Version.new("5.1.0")
17
-
18
- ActiveRecord::Base.establish_connection(
19
- adapter: 'postgresql',
20
- database: 'store_attribute_test'
21
- )
22
- connection = ActiveRecord::Base.connection
23
-
24
- unless connection.extension_enabled?('hstore')
25
- connection.enable_extension 'hstore'
26
- connection.commit_db_transaction
27
- end
28
-
29
- connection.reconnect!
30
-
31
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
32
-
33
- RSpec.configure do |config|
34
- config.mock_with :rspec
35
-
36
- config.filter_run_when_matching :focus
37
-
38
- config.example_status_persistence_file_path = "tmp/rspec_examples.txt"
39
-
40
- if config.files_to_run.one?
41
- config.default_formatter = 'doc'
42
- end
43
- end
@@ -1,107 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ActiveRecord::Type::TypedStore do
4
- let(:json_type) { ActiveRecord::Type::Serialized.new(ActiveRecord::Type::Text.new, ActiveRecord::Coders::JSON) }
5
-
6
- context "with json store" do
7
- subject { described_class.new(json_type) }
8
-
9
- describe "#cast" do
10
- it "without key types", :aggregate_failures do
11
- expect(subject.cast([1, 2])).to eq [1, 2]
12
- expect(subject.cast('a' => 'b')).to eq('a' => 'b')
13
- end
14
-
15
- it "with type keys" do
16
- subject.add_typed_key('date', :date)
17
-
18
- date = ::Date.new(2016, 6, 22)
19
- expect(subject.cast(date: '2016-06-22')).to eq('date' => date)
20
- end
21
- end
22
-
23
- describe "#deserialize" do
24
- it "without key types", :aggregate_failures do
25
- expect(subject.deserialize('[1,2]')).to eq [1, 2]
26
- expect(subject.deserialize('{"a":"b"}')).to eq('a' => 'b')
27
- end
28
-
29
- it "with type keys" do
30
- subject.add_typed_key('date', :date)
31
-
32
- date = ::Date.new(2016, 6, 22)
33
- expect(subject.deserialize('{"date":"2016-06-22"}')).to eq('date' => date)
34
- end
35
- end
36
-
37
- describe "#serialize" do
38
- it "without key types", :aggregate_failures do
39
- expect(subject.serialize([1, 2])).to eq '[1,2]'
40
- expect(subject.serialize('a' => 'b')).to eq '{"a":"b"}'
41
- end
42
-
43
- it "with type keys" do
44
- subject.add_typed_key('date', :date)
45
-
46
- date = ::Date.new(2016, 6, 22)
47
- expect(subject.serialize(date: date)).to eq '{"date":"2016-06-22"}'
48
- end
49
-
50
- it "with type key with option" do
51
- subject.add_typed_key('val', :integer, limit: 1)
52
-
53
- expect { subject.serialize(val: 1024) }.to raise_error(RangeError)
54
- end
55
- end
56
-
57
- describe ".create_from_type" do
58
- it "creates with valid types", :aggregate_failures do
59
- type = described_class.create_from_type(json_type, 'date', :date)
60
- new_type = described_class.create_from_type(type, 'val', :integer)
61
-
62
- date = ::Date.new(2016, 6, 22)
63
-
64
- expect(type.cast(date: '2016-06-22', val: '1.2')).to eq('date' => date, 'val' => '1.2')
65
- expect(new_type.cast(date: '2016-06-22', val: '1.2')).to eq('date' => date, 'val' => 1)
66
- end
67
- end
68
- end
69
-
70
- context "with yaml coder" do
71
- if RAILS_5_1
72
- let(:yaml_type) do
73
- ActiveRecord::Type::Serialized.new(
74
- ActiveRecord::Type::Text.new,
75
- ActiveRecord::Store::IndifferentCoder.new(
76
- 'test',
77
- ActiveRecord::Coders::YAMLColumn.new('test', Hash)
78
- )
79
- )
80
- end
81
- else
82
- let(:yaml_type) do
83
- ActiveRecord::Type::Serialized.new(
84
- ActiveRecord::Type::Text.new,
85
- ActiveRecord::Store::IndifferentCoder.new(
86
- ActiveRecord::Coders::YAMLColumn.new(Hash)
87
- )
88
- )
89
- end
90
- end
91
-
92
- let(:subject) { described_class.new(yaml_type) }
93
-
94
- it "works", :aggregate_failures do
95
- subject.add_typed_key('date', :date)
96
-
97
- date = ::Date.new(2016, 6, 22)
98
-
99
- expect(subject.cast(date: '2016-06-22')).to eq('date' => date)
100
- expect(subject.cast('date' => '2016-06-22')).to eq('date' => date)
101
- expect(subject.deserialize("---\n:date: 2016-06-22\n")).to eq('date' => date)
102
- expect(subject.deserialize("---\ndate: 2016-06-22\n")).to eq('date' => date)
103
- expect(subject.serialize(date: date)).to eq "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\ndate: 2016-06-22\n"
104
- expect(subject.serialize('date' => date)).to eq "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\ndate: 2016-06-22\n"
105
- end
106
- end
107
- end
@@ -1,12 +0,0 @@
1
- class MoneyType < ActiveRecord::Type::Integer
2
- def cast(value)
3
- if !value.is_a?(Numeric) && value.include?('$')
4
- price_in_dollars = value.delete('$').to_f
5
- super(price_in_dollars * 100)
6
- else
7
- super
8
- end
9
- end
10
- end
11
-
12
- ActiveRecord::Type.register(:money_type, MoneyType)
@@ -1,17 +0,0 @@
1
- class RawUser < ActiveRecord::Base
2
- self.table_name = 'users'
3
- end
4
-
5
- class User < ActiveRecord::Base
6
- store_accessor :jparams, :version, active: :boolean, salary: :integer
7
- store_attribute :jparams, :birthday, :date
8
-
9
- store_attribute :jparams, :inner_json, :json
10
-
11
- store :custom, accessors: [price: :money_type]
12
-
13
- store_accessor :hdata, visible: :boolean
14
-
15
- store_attribute :hdata, :ratio, :integer, limit: 1
16
- store_attribute :hdata, :login_at, :datetime
17
- end
@@ -1,27 +0,0 @@
1
- $:.push File.expand_path("../lib", __FILE__)
2
-
3
- # Maintain your gem's version:
4
- require "store_attribute/version"
5
-
6
- # Describe your gem and declare its dependencies:
7
- Gem::Specification.new do |s|
8
- s.name = "store_attribute"
9
- s.version = StoreAttribute::VERSION
10
- s.authors = ["palkan"]
11
- s.email = ["dementiev.vm@gmail.com"]
12
- s.homepage = "http://github.com/palkan/store_attribute"
13
- s.summary = "ActiveRecord extension which adds typecasting to store accessors"
14
- s.description = "ActiveRecord extension which adds typecasting to store accessors"
15
- s.license = "MIT"
16
-
17
- s.files = `git ls-files`.split($/)
18
- s.require_paths = ["lib"]
19
-
20
- s.add_runtime_dependency "activerecord", "~>5.0"
21
-
22
- s.add_development_dependency "pg", "~>0.18"
23
- s.add_development_dependency "rake", "~> 10.1"
24
- s.add_development_dependency "simplecov", ">= 0.3.8"
25
- s.add_development_dependency "pry-byebug"
26
- s.add_development_dependency "rspec", "~> 3.5.0"
27
- end