store_attribute 0.4.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'rack', github: "rack/rack"
4
- gem 'arel', github: 'rails/arel'
5
- gem 'rails', github: 'rails/rails'
6
-
7
- gemspec path: '..'
@@ -1,5 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- gem 'activerecord', "~>4.2"
4
-
5
- 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
data/spec/spec_helper.rb DELETED
@@ -1,42 +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
- ActiveRecord::Base.establish_connection(
17
- adapter: 'postgresql',
18
- database: 'store_attribute_test'
19
- )
20
- connection = ActiveRecord::Base.connection
21
-
22
- unless connection.extension_enabled?('hstore')
23
- connection.enable_extension 'hstore'
24
- connection.commit_db_transaction
25
- end
26
-
27
- connection.reconnect!
28
-
29
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
30
-
31
- RSpec.configure do |config|
32
- config.mock_with :rspec
33
-
34
- config.filter_run :focus
35
- config.run_all_when_everything_filtered = true
36
-
37
- config.example_status_persistence_file_path = "tmp/rspec_examples.txt"
38
-
39
- if config.files_to_run.one?
40
- config.default_formatter = 'doc'
41
- end
42
- end
@@ -1,94 +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
- let(:yaml_type) do
6
- ActiveRecord::Type::Serialized.new(
7
- ActiveRecord::Type::Text.new,
8
- ActiveRecord::Store::IndifferentCoder.new(
9
- ActiveRecord::Coders::YAMLColumn.new(Hash)
10
- )
11
- )
12
- end
13
-
14
- context "with json store" do
15
- subject { described_class.new(json_type) }
16
-
17
- describe "#type_cast_from_user" do
18
- it "without key types", :aggregate_failures do
19
- expect(subject.type_cast_from_user([1, 2])).to eq [1, 2]
20
- expect(subject.type_cast_from_user('a' => 'b')).to eq('a' => 'b')
21
- end
22
-
23
- it "with type keys" do
24
- subject.add_typed_key('date', :date)
25
-
26
- date = ::Date.new(2016, 6, 22)
27
- expect(subject.type_cast_from_user(date: '2016-06-22')).to eq('date' => date)
28
- end
29
- end
30
-
31
- describe "#type_cast_from_database" do
32
- it "without key types", :aggregate_failures do
33
- expect(subject.type_cast_from_database('[1,2]')).to eq [1, 2]
34
- expect(subject.type_cast_from_database('{"a":"b"}')).to eq('a' => 'b')
35
- end
36
-
37
- it "with type keys" do
38
- subject.add_typed_key('date', :date)
39
-
40
- date = ::Date.new(2016, 6, 22)
41
- expect(subject.type_cast_from_database('{"date":"2016-06-22"}')).to eq('date' => date)
42
- end
43
- end
44
-
45
- describe "#type_cast_for_database" do
46
- it "without key types", :aggregate_failures do
47
- expect(subject.type_cast_for_database([1, 2])).to eq '[1,2]'
48
- expect(subject.type_cast_for_database('a' => 'b')).to eq '{"a":"b"}'
49
- end
50
-
51
- it "with type keys" do
52
- subject.add_typed_key('date', :date)
53
-
54
- date = ::Date.new(2016, 6, 22)
55
- expect(subject.type_cast_for_database(date: date)).to eq '{"date":"2016-06-22"}'
56
- end
57
-
58
- it "with type key with option" do
59
- subject.add_typed_key('val', :integer, limit: 1)
60
-
61
- expect { subject.type_cast_for_database(val: 1024) }.to raise_error(RangeError)
62
- end
63
- end
64
-
65
- describe ".create_from_type" do
66
- it "creates with valid types", :aggregate_failures do
67
- type = described_class.create_from_type(json_type, 'date', :date)
68
- new_type = described_class.create_from_type(type, 'val', :integer)
69
-
70
- date = ::Date.new(2016, 6, 22)
71
-
72
- expect(type.type_cast_from_user(date: '2016-06-22', val: '1.2')).to eq('date' => date, 'val' => '1.2')
73
- expect(new_type.type_cast_from_user(date: '2016-06-22', val: '1.2')).to eq('date' => date, 'val' => 1)
74
- end
75
- end
76
- end
77
-
78
- context "with yaml coder" do
79
- let(:subject) { described_class.new(yaml_type) }
80
-
81
- it "works", :aggregate_failures do
82
- subject.add_typed_key('date', :date)
83
-
84
- date = ::Date.new(2016, 6, 22)
85
-
86
- expect(subject.type_cast_from_user(date: '2016-06-22')).to eq('date' => date)
87
- expect(subject.type_cast_from_user('date' => '2016-06-22')).to eq('date' => date)
88
- expect(subject.type_cast_from_database("---\n:date: 2016-06-22\n")).to eq('date' => date)
89
- expect(subject.type_cast_from_database("---\ndate: 2016-06-22\n")).to eq('date' => date)
90
- expect(subject.type_cast_for_database(date: date)).to eq "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\ndate: 2016-06-22\n"
91
- expect(subject.type_cast_for_database('date' => date)).to eq "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\ndate: 2016-06-22\n"
92
- end
93
- end
94
- end
@@ -1,12 +0,0 @@
1
- class MoneyType < ActiveRecord::Type::Integer
2
- def type_cast_from_user(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::Base.connection.type_map.register_type('money_type', MoneyType.new)
data/spec/support/user.rb DELETED
@@ -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", ">=4.2.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.4.0"
27
- end