store_attribute 0.4.1 → 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,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