preferable 0.4.0 → 0.5.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.
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ describe Preferable::Coder do
4
+
5
+ let :user do
6
+ User.create! do |u|
7
+ u.preferences[:newsletter] = '1'
8
+ end.reload
9
+ end
10
+
11
+ let :legacy do
12
+ User.create!
13
+ end
14
+
15
+ it 'should not dump blank values' do
16
+ subject.dump(nil).should be_nil
17
+ subject.dump("ANY").should be_nil
18
+ subject.dump({}).should be_nil
19
+ end
20
+
21
+ it 'should dump hashes values' do
22
+ subject.dump(user.preferences).should == %({"newsletter":true})
23
+ end
24
+
25
+ it 'should load blank values' do
26
+ subject.load(nil).should == {}
27
+ subject.load(" ").should == {}
28
+ end
29
+
30
+ it 'should load hashes as they are' do
31
+ subject.load({"newsletter" => false}).should == {"newsletter" => false}
32
+ end
33
+
34
+ it 'should not fail over encoding errors' do
35
+ subject.load("SOMETHING WRONG!?").should == {}
36
+ end
37
+
38
+ it 'should raise errors if something other than a hash was loaded' do
39
+ lambda { subject.load("[1, 2]") }.should raise_error(ActiveRecord::SerializationTypeMismatch)
40
+ end
41
+
42
+ it 'should load values' do
43
+ subject.load(subject.dump(user.preferences)).should == {"newsletter" => true}
44
+ end
45
+
46
+ it "should load legacy settings" do
47
+ legacy.update_column :preferences, "---\n:color: \"222222\"\n_: \"::User\"\n"
48
+ legacy.reload.preferences.should == { "color" => "222222" }
49
+
50
+ legacy.update_column :preferences, "--- !map:Preferable::Set \n:color: \"222222\"\n_: \"::User\"\n"
51
+ legacy.reload.preferences.should == { "color" => "222222" }
52
+
53
+ legacy.update_column :preferences, "--- !ruby/object:Preferable::Set \n:color: \"222222\"\n_: \"::User\"\n"
54
+ legacy.reload.preferences.should == { "color" => "222222" }
55
+ end
56
+
57
+ end
@@ -0,0 +1,94 @@
1
+ require 'spec_helper'
2
+
3
+ describe Preferable::Field do
4
+
5
+ def field(type, opts = {})
6
+ described_class.new :any, type, opts
7
+ end
8
+
9
+ def integer(opts = {})
10
+ field :integer, opts
11
+ end
12
+
13
+ subject do
14
+ described_class.new "color", "string", :if => lambda {|v| v =~ /^[A-F0-9]{6}$/ }, :default => '444444'
15
+ end
16
+
17
+ it 'should have a name' do
18
+ subject.name.should == "color"
19
+ end
20
+
21
+ it 'should have a type' do
22
+ subject.type.should == :string
23
+ end
24
+
25
+ it 'should have a default' do
26
+ subject.default.should == '444444'
27
+ end
28
+
29
+ it 'should have options' do
30
+ subject.options.keys.should == [:if]
31
+ end
32
+
33
+ it 'should reject invalid types' do
34
+ lambda { described_class.new :any, :invalid }.should raise_error(ArgumentError)
35
+ end
36
+
37
+ it 'should check if values are assignable' do
38
+ even = lambda {|v| (v % 2).zero? }
39
+ is_2 = lambda {|v| v == 2 }
40
+
41
+ integer(:if => even).valid?(1).should be(false)
42
+ integer(:if => even).valid?(2).should be(true)
43
+ integer(:unless => even).valid?(1).should be(true)
44
+ integer(:unless => even).valid?(2).should be(false)
45
+ integer(:if => even, :unless => is_2).valid?(2).should be(false)
46
+ integer(:if => even, :unless => is_2).valid?(3).should be(false)
47
+ integer(:if => even, :unless => is_2).valid?(4).should be(true)
48
+ end
49
+
50
+ it 'should type-cast strings' do
51
+ field(:string).type_cast(nil).should == nil
52
+ field(:string).type_cast(1).should == '1'
53
+ end
54
+
55
+ it 'should type-cast ints' do
56
+ field(:integer).type_cast(nil).should == nil
57
+ field(:integer).type_cast('1').should == 1
58
+ field(:integer).type_cast(2.5).should == 2
59
+ field(:integer).type_cast("").should == 0
60
+ end
61
+
62
+ it 'should type-cast floats' do
63
+ field(:float).type_cast(nil).should == nil
64
+ field(:float).type_cast('1').should == 1.0
65
+ field(:float).type_cast(2.5).should == 2.5
66
+ field(:float).type_cast("").should == 0
67
+ end
68
+
69
+ it 'should type-cast booleans' do
70
+ field(:boolean).type_cast(nil).should == nil
71
+ field(:boolean).type_cast('1').should == true
72
+ field(:boolean).type_cast(0).should == false
73
+ field(:boolean).type_cast(true).should == true
74
+ end
75
+
76
+ it 'should type-cast dates' do
77
+ field(:date).type_cast('2011-01-01').should == Date.civil(2011, 1, 1)
78
+ field(:date).type_cast(Date.civil(2011, 11, 11)).should == Date.civil(2011, 11, 11)
79
+ field(:date).type_cast(Time.at(1234567890)).should == Date.civil(2009, 2, 13)
80
+ end
81
+
82
+ it 'should type-cast datetimes' do
83
+ field(:datetime).type_cast('2011-01-01 12:10').should == Time.zone.local(2011, 1, 1, 12, 10)
84
+ field(:datetime).type_cast(Time.at(1234567890)).should == Time.at(1234567890)
85
+ field(:datetime).type_cast(Time.at(1234567890)).zone.should == "UTC"
86
+ end
87
+
88
+ it 'should type-cast arrays' do
89
+ field(:array).type_cast('1').should == ['1']
90
+ field(:array, :cast => :integer).type_cast('1').should == [1]
91
+ field(:array, :cast => :integer).type_cast(['1', 2, 'B']).should == [1, 2, 0]
92
+ end
93
+
94
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe Preferable::Model do
4
+
5
+ subject do
6
+ Class.new(ActiveRecord::Base)
7
+ end
8
+
9
+ it 'should be includable' do
10
+ subject.send(:included_modules).should include(described_class)
11
+ end
12
+
13
+ it 'should store a preferable schema' do
14
+ User._preferable.keys.should =~ ["newsletter", "color"]
15
+ end
16
+
17
+ it 'should inherit preferable schema correctly' do
18
+ Admin._preferable.keys.should =~ ["newsletter", "color", "reminder"]
19
+ end
20
+
21
+ it 'should allow to define preferables' do
22
+ res = nil
23
+ subject._preferable.should be_nil
24
+ subject.preferable { res = self.class.name }
25
+ subject._preferable.should be_a(Preferable::Schema)
26
+ res.should == "Preferable::Schema"
27
+ end
28
+
29
+ describe "saving" do
30
+
31
+ it 'should save preferences with new records' do
32
+ user = User.new
33
+ user.preferences.should == {}
34
+ user.preferences[:color] = '222222'
35
+ user.tap(&:save!).tap(&:reload).preferences.should == { "color" => '222222' }
36
+ end
37
+
38
+ it 'should save preferences with existing records' do
39
+ user = User.create!(:name => 'Random', :preferences => { :color => '222222' }).reload
40
+ user.preferences.should == { "color" => '222222' }
41
+ user.preferences[:newsletter] = '1'
42
+ user.tap(&:save!).tap(&:reload).preferences.should == { "color" => '222222', "newsletter" => true }
43
+ end
44
+
45
+ end
46
+
47
+
48
+ describe "instances" do
49
+
50
+ subject do
51
+ User.new
52
+ end
53
+
54
+ it 'should have preferences' do
55
+ subject.preferences.should be_a(Preferable::Set)
56
+ end
57
+
58
+ it 'should allow assigning preferences' do
59
+ subject.preferences = { :color => '222222' }
60
+ subject.preferences.should be_a(Preferable::Set)
61
+ subject.preferences.should == { "color" => '222222' }
62
+ end
63
+
64
+ it 'should serialize preferences' do
65
+ subject.class.serialized_attributes.keys.should include('preferences')
66
+ end
67
+
68
+ end
69
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe Preferable::Schema do
4
+
5
+ it { should be_a(Hash) }
6
+ it { should respond_to(:string) }
7
+ it { should respond_to(:integer) }
8
+ it { should respond_to(:float) }
9
+ it { should respond_to(:date) }
10
+ it { should respond_to(:datetime) }
11
+ it { should respond_to(:array) }
12
+ it { should respond_to(:boolean) }
13
+
14
+ it 'should build and store field' do
15
+ field = subject.field :color, :string
16
+ field.should be_a(Preferable::Field)
17
+ subject.should == { "color" => field }
18
+ end
19
+
20
+ it 'should provide shorthand method' do
21
+ subject.integer :client_id
22
+ subject.keys.should == ["client_id"]
23
+ subject.values.first.should be_a(Preferable::Field)
24
+ end
25
+
26
+ it 'should allow to specify options with shorthand method' do
27
+ subject.integer :client_id, :default => 1
28
+ subject.values.first.default.should == 1
29
+ end
30
+
31
+ it 'should allow specifying multiple fields with shorthand method' do
32
+ subject.integer :first, :second
33
+ subject.keys.should =~ ["first", "second"]
34
+ end
35
+
36
+ it 'should allow specifying multiple fields with options with shorthand method' do
37
+ subject.integer :first, :second, :default => 0
38
+ subject.keys.should =~ ["first", "second"]
39
+ subject.values.map(&:default).should == [0, 0]
40
+ end
41
+
42
+ end
@@ -0,0 +1,96 @@
1
+ require 'spec_helper'
2
+
3
+ describe Preferable::Set do
4
+
5
+ let :user do
6
+ User.new
7
+ end
8
+
9
+ let :admin do
10
+ Admin.new
11
+ end
12
+
13
+ subject do
14
+ user.preferences
15
+ end
16
+
17
+ it 'should wrap values' do
18
+ described_class.wrap(user, subject).should_not be(subject)
19
+ described_class.wrap(user, subject).should == subject
20
+ described_class.wrap(user, subject).owner.should be(user)
21
+
22
+ described_class.wrap(admin, subject).should be_instance_of(described_class)
23
+ described_class.wrap(admin, subject).owner.should be(admin)
24
+
25
+ described_class.wrap(user, {}).should be_instance_of(described_class)
26
+ described_class.wrap(user, {}).owner.should be(user)
27
+ end
28
+
29
+ it 'should reference the owner' do
30
+ subject.owner.should == user
31
+ end
32
+
33
+ it 'should be convertable to a simple hash' do
34
+ subject.to_hash.should be_instance_of(Hash)
35
+ end
36
+
37
+ describe "reading" do
38
+
39
+ it 'should return assignments or defaults' do
40
+ subject[:color].should == '444444'
41
+ subject[:color] = '222222'
42
+ subject[:color].should == '222222'
43
+ end
44
+
45
+ it 'should return nil for invalid keys' do
46
+ subject[:invalid].should be_nil
47
+ end
48
+
49
+ end
50
+
51
+ describe "writing" do
52
+
53
+ it 'should ignore invalid keys' do
54
+ subject[:invalid] = '1'
55
+ subject.should == {}
56
+ end
57
+
58
+ it 'should set values' do
59
+ subject[:color] = '222222'
60
+ subject.should == { "color" => '222222' }
61
+ end
62
+
63
+ it 'should notify record about changes' do
64
+ subject[:color] = '222222'
65
+ user.should be_changed
66
+ user.changed_attributes.should == { "preferences"=>{} }
67
+ end
68
+
69
+ it 'should type cast values' do
70
+ subject[:color] = 222222
71
+ subject.should == { "color" => '222222' }
72
+ end
73
+
74
+ it 'should unset key when defaults are assigned' do
75
+ subject[:color] = '222222'
76
+ subject.should == { "color" => '222222' }
77
+ subject[:color] = '444444'
78
+ subject.should == {}
79
+ end
80
+
81
+ it 'should unset key when nil is assigned' do
82
+ subject[:color] = '222222'
83
+ subject.should == { "color" => '222222' }
84
+ subject[:color] = nil
85
+ subject.should == {}
86
+ end
87
+
88
+ it 'should allow mass-update' do
89
+ subject.set 'color' => 222222, :newsletter => '1'
90
+ subject.should == { "color" => '222222', "newsletter" => true }
91
+ subject.set :color => nil, :newsletter => false
92
+ subject.should == {}
93
+ end
94
+
95
+ end
96
+ end
@@ -0,0 +1,38 @@
1
+ ENV["RAILS_ENV"] ||= 'test'
2
+
3
+ $: << File.dirname(__FILE__) + '/../lib'
4
+ require 'rubygems'
5
+ require 'bundler/setup'
6
+ Bundler.require :default, :test
7
+
8
+ require 'active_support'
9
+ require 'active_record'
10
+ require 'rspec'
11
+ require 'preferable'
12
+
13
+ Time.zone = 'UTC'
14
+ ActiveRecord::Base.time_zone_aware_attributes = true
15
+ ActiveRecord::Base.default_timezone = :utc
16
+ ActiveRecord::Base.configurations["test"] = { 'adapter' => 'sqlite3', 'database' => ":memory:" }
17
+ ActiveRecord::Base.establish_connection(:test)
18
+ ActiveRecord::Base.connection.create_table :users do |t|
19
+ t.string :name
20
+ t.text :preferences
21
+ end
22
+
23
+ class User < ActiveRecord::Base
24
+
25
+ preferable do
26
+ string :color, :default => '444444'
27
+ boolean :newsletter, :default => false
28
+ end
29
+
30
+ end
31
+
32
+ class Admin < User
33
+
34
+ preferable do
35
+ boolean :reminder, :default => false
36
+ end
37
+
38
+ end
metadata CHANGED
@@ -1,62 +1,89 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: preferable
3
- version: !ruby/object:Gem::Version
4
- hash: 15
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 4
9
- - 0
10
- version: 0.4.0
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Dimitrij Denissenko
14
9
  - Evgeniy Dolzhenko
15
10
  autorequire:
16
11
  bindir: bin
17
12
  cert_chain: []
18
-
19
- date: 2011-09-30 00:00:00 Z
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
13
+ date: 2012-01-24 00:00:00.000000000Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
22
16
  name: abstract
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
17
+ requirement: &9804020 !ruby/object:Gem::Requirement
25
18
  none: false
26
- requirements:
27
- - - ">="
28
- - !ruby/object:Gem::Version
29
- hash: 3
30
- segments:
31
- - 0
32
- version: "0"
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
33
23
  type: :runtime
34
- version_requirements: *id001
35
- - !ruby/object:Gem::Dependency
36
- name: activerecord
37
24
  prerelease: false
38
- requirement: &id002 !ruby/object:Gem::Requirement
25
+ version_requirements: *9804020
26
+ - !ruby/object:Gem::Dependency
27
+ name: activerecord
28
+ requirement: &9735560 !ruby/object:Gem::Requirement
39
29
  none: false
40
- requirements:
41
- - - ~>
42
- - !ruby/object:Gem::Version
43
- hash: 3
44
- segments:
45
- - 3
46
- - 1
47
- - 0
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
48
33
  version: 3.1.0
49
34
  type: :runtime
50
- version_requirements: *id002
35
+ prerelease: false
36
+ version_requirements: *9735560
37
+ - !ruby/object:Gem::Dependency
38
+ name: rake
39
+ requirement: &9731060 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *9731060
48
+ - !ruby/object:Gem::Dependency
49
+ name: rspec
50
+ requirement: &9691900 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :development
57
+ prerelease: false
58
+ version_requirements: *9691900
59
+ - !ruby/object:Gem::Dependency
60
+ name: sqlite3-ruby
61
+ requirement: &9690880 !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ type: :development
68
+ prerelease: false
69
+ version_requirements: *9690880
70
+ - !ruby/object:Gem::Dependency
71
+ name: shoulda-matchers
72
+ requirement: &9690140 !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ type: :development
79
+ prerelease: false
80
+ version_requirements: *9690140
51
81
  description: Great for storing user preferences
52
82
  email: dimitrij@blacksquaremedia.com
53
83
  executables: []
54
-
55
84
  extensions: []
56
-
57
85
  extra_rdoc_files: []
58
-
59
- files:
86
+ files:
60
87
  - README.markdown
61
88
  - lib/preferable.rb
62
89
  - lib/preferable/field.rb
@@ -64,42 +91,40 @@ files:
64
91
  - lib/preferable/set.rb
65
92
  - lib/preferable/schema.rb
66
93
  - lib/preferable/coder.rb
94
+ - spec/preferable/field_spec.rb
95
+ - spec/preferable/coder_spec.rb
96
+ - spec/preferable/model_spec.rb
97
+ - spec/preferable/schema_spec.rb
98
+ - spec/preferable/set_spec.rb
99
+ - spec/spec_helper.rb
67
100
  homepage: https://github.com/bsm/preferable
68
101
  licenses: []
69
-
70
102
  post_install_message:
71
103
  rdoc_options: []
72
-
73
- require_paths:
104
+ require_paths:
74
105
  - lib
75
- required_ruby_version: !ruby/object:Gem::Requirement
106
+ required_ruby_version: !ruby/object:Gem::Requirement
76
107
  none: false
77
- requirements:
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- hash: 57
81
- segments:
82
- - 1
83
- - 8
84
- - 7
85
- version: 1.8.7
86
- required_rubygems_version: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ! '>='
110
+ - !ruby/object:Gem::Version
111
+ version: 1.9.2
112
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
113
  none: false
88
- requirements:
89
- - - ">="
90
- - !ruby/object:Gem::Version
91
- hash: 23
92
- segments:
93
- - 1
94
- - 3
95
- - 6
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
96
117
  version: 1.3.6
97
118
  requirements: []
98
-
99
119
  rubyforge_project:
100
- rubygems_version: 1.8.5
120
+ rubygems_version: 1.8.10
101
121
  signing_key:
102
122
  specification_version: 3
103
123
  summary: Simple preferences store for ActiveRecord
104
- test_files: []
105
-
124
+ test_files:
125
+ - spec/preferable/field_spec.rb
126
+ - spec/preferable/coder_spec.rb
127
+ - spec/preferable/model_spec.rb
128
+ - spec/preferable/schema_spec.rb
129
+ - spec/preferable/set_spec.rb
130
+ - spec/spec_helper.rb