toystore 0.5
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.
- data/.autotest +11 -0
- data/.bundle/config +2 -0
- data/.gitignore +6 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +49 -0
- data/LICENSE +9 -0
- data/LOGGING.rdoc +16 -0
- data/README.rdoc +13 -0
- data/Rakefile +7 -0
- data/examples/memcached.rb +20 -0
- data/examples/memory.rb +20 -0
- data/examples/models.rb +51 -0
- data/examples/redis.rb +20 -0
- data/lib/toy.rb +81 -0
- data/lib/toy/attribute.rb +73 -0
- data/lib/toy/attributes.rb +137 -0
- data/lib/toy/caching.rb +20 -0
- data/lib/toy/callbacks.rb +48 -0
- data/lib/toy/collection.rb +55 -0
- data/lib/toy/connection.rb +28 -0
- data/lib/toy/dirty.rb +47 -0
- data/lib/toy/dolly.rb +30 -0
- data/lib/toy/embedded_list.rb +45 -0
- data/lib/toy/embedded_lists.rb +68 -0
- data/lib/toy/equality.rb +19 -0
- data/lib/toy/exceptions.rb +29 -0
- data/lib/toy/extensions/array.rb +22 -0
- data/lib/toy/extensions/boolean.rb +43 -0
- data/lib/toy/extensions/date.rb +24 -0
- data/lib/toy/extensions/float.rb +13 -0
- data/lib/toy/extensions/hash.rb +17 -0
- data/lib/toy/extensions/integer.rb +22 -0
- data/lib/toy/extensions/nil_class.rb +17 -0
- data/lib/toy/extensions/object.rb +26 -0
- data/lib/toy/extensions/set.rb +23 -0
- data/lib/toy/extensions/string.rb +17 -0
- data/lib/toy/extensions/time.rb +29 -0
- data/lib/toy/identity.rb +26 -0
- data/lib/toy/identity/abstract_key_factory.rb +10 -0
- data/lib/toy/identity/uuid_key_factory.rb +9 -0
- data/lib/toy/identity_map.rb +109 -0
- data/lib/toy/index.rb +74 -0
- data/lib/toy/indices.rb +56 -0
- data/lib/toy/inspect.rb +12 -0
- data/lib/toy/list.rb +46 -0
- data/lib/toy/lists.rb +37 -0
- data/lib/toy/logger.rb +26 -0
- data/lib/toy/mass_assignment_security.rb +16 -0
- data/lib/toy/persistence.rb +138 -0
- data/lib/toy/plugins.rb +23 -0
- data/lib/toy/proxies/embedded_list.rb +74 -0
- data/lib/toy/proxies/list.rb +97 -0
- data/lib/toy/proxies/proxy.rb +59 -0
- data/lib/toy/querying.rb +57 -0
- data/lib/toy/reference.rb +134 -0
- data/lib/toy/references.rb +19 -0
- data/lib/toy/serialization.rb +81 -0
- data/lib/toy/store.rb +36 -0
- data/lib/toy/timestamps.rb +22 -0
- data/lib/toy/validations.rb +45 -0
- data/lib/toy/version.rb +3 -0
- data/lib/toystore.rb +1 -0
- data/spec/helper.rb +35 -0
- data/spec/spec.opts +3 -0
- data/spec/support/constants.rb +41 -0
- data/spec/support/identity_map_matcher.rb +20 -0
- data/spec/support/name_and_number_key_factory.rb +5 -0
- data/spec/toy/attribute_spec.rb +176 -0
- data/spec/toy/attributes_spec.rb +394 -0
- data/spec/toy/caching_spec.rb +62 -0
- data/spec/toy/callbacks_spec.rb +97 -0
- data/spec/toy/connection_spec.rb +47 -0
- data/spec/toy/dirty_spec.rb +99 -0
- data/spec/toy/dolly_spec.rb +76 -0
- data/spec/toy/embedded_list_spec.rb +607 -0
- data/spec/toy/embedded_lists_spec.rb +172 -0
- data/spec/toy/equality_spec.rb +46 -0
- data/spec/toy/exceptions_spec.rb +18 -0
- data/spec/toy/extensions/array_spec.rb +25 -0
- data/spec/toy/extensions/boolean_spec.rb +41 -0
- data/spec/toy/extensions/date_spec.rb +48 -0
- data/spec/toy/extensions/float_spec.rb +14 -0
- data/spec/toy/extensions/hash_spec.rb +21 -0
- data/spec/toy/extensions/integer_spec.rb +29 -0
- data/spec/toy/extensions/nil_class_spec.rb +14 -0
- data/spec/toy/extensions/set_spec.rb +27 -0
- data/spec/toy/extensions/string_spec.rb +28 -0
- data/spec/toy/extensions/time_spec.rb +94 -0
- data/spec/toy/identity/abstract_key_factory_spec.rb +7 -0
- data/spec/toy/identity/uuid_key_factory_spec.rb +7 -0
- data/spec/toy/identity_map_spec.rb +150 -0
- data/spec/toy/identity_spec.rb +52 -0
- data/spec/toy/index_spec.rb +230 -0
- data/spec/toy/indices_spec.rb +141 -0
- data/spec/toy/inspect_spec.rb +15 -0
- data/spec/toy/list_spec.rb +576 -0
- data/spec/toy/lists_spec.rb +95 -0
- data/spec/toy/logger_spec.rb +33 -0
- data/spec/toy/mass_assignment_security_spec.rb +116 -0
- data/spec/toy/persistence_spec.rb +312 -0
- data/spec/toy/plugins_spec.rb +39 -0
- data/spec/toy/querying_spec.rb +162 -0
- data/spec/toy/reference_spec.rb +400 -0
- data/spec/toy/references_spec.rb +86 -0
- data/spec/toy/serialization_spec.rb +354 -0
- data/spec/toy/store_spec.rb +41 -0
- data/spec/toy/timestamps_spec.rb +63 -0
- data/spec/toy/validations_spec.rb +171 -0
- data/spec/toy_spec.rb +26 -0
- data/specs.watchr +52 -0
- data/test/lint_test.rb +40 -0
- data/toystore.gemspec +24 -0
- metadata +290 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Toy::Lists do
|
4
|
+
uses_constants('User', 'Game', 'Move')
|
5
|
+
|
6
|
+
it "defaults lists to empty hash" do
|
7
|
+
User.lists.should == {}
|
8
|
+
end
|
9
|
+
|
10
|
+
it "does not share with embedded lists" do
|
11
|
+
Game.embedded_list(:moves)
|
12
|
+
Game.lists.should == {}
|
13
|
+
end
|
14
|
+
|
15
|
+
describe ".list?" do
|
16
|
+
before do
|
17
|
+
User.list(:games)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns true if attribute (symbol)" do
|
21
|
+
User.list?(:games).should be_true
|
22
|
+
end
|
23
|
+
|
24
|
+
it "returns true if attribute (string)" do
|
25
|
+
User.list?('games').should be_true
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns false if not attribute" do
|
29
|
+
User.list?(:foobar).should be_false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "declaring a list" do
|
34
|
+
describe "using conventions" do
|
35
|
+
before do
|
36
|
+
@list = User.list(:games)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "knows about its lists" do
|
40
|
+
User.lists[:games].should == Toy::List.new(User, :games)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "returns list" do
|
44
|
+
@list.should == Toy::List.new(User, :games)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "with type" do
|
49
|
+
before do
|
50
|
+
@list = User.list(:active_games, Game)
|
51
|
+
end
|
52
|
+
let(:list) { @list }
|
53
|
+
|
54
|
+
it "sets type" do
|
55
|
+
list.type.should be(Game)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "sets options to hash" do
|
59
|
+
list.options.should be_instance_of(Hash)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "with options" do
|
64
|
+
before do
|
65
|
+
@list = User.list(:games, :dependent => true)
|
66
|
+
end
|
67
|
+
let(:list) { @list }
|
68
|
+
|
69
|
+
it "sets type" do
|
70
|
+
list.type.should be(Game)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "sets options" do
|
74
|
+
list.options.should have_key(:dependent)
|
75
|
+
list.options[:dependent].should be_true
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "with type and options" do
|
80
|
+
before do
|
81
|
+
@list = User.list(:active_games, Game, :dependent => true)
|
82
|
+
end
|
83
|
+
let(:list) { @list }
|
84
|
+
|
85
|
+
it "sets type" do
|
86
|
+
list.type.should be(Game)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "sets options" do
|
90
|
+
list.options.should have_key(:dependent)
|
91
|
+
list.options[:dependent].should be_true
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Toy::Logger do
|
4
|
+
uses_constants('User')
|
5
|
+
|
6
|
+
it "should use Toy.logger for class" do
|
7
|
+
User.logger.should == Toy.logger
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should use Toy.logger for instance" do
|
11
|
+
User.new.logger.should == Toy.logger
|
12
|
+
end
|
13
|
+
|
14
|
+
describe ".log_operation" do
|
15
|
+
let(:adapter) { Adapter[:memory].new({}) }
|
16
|
+
|
17
|
+
it "logs operation" do
|
18
|
+
User.logger.should_receive(:debug).with('ToyStore GET :memory "foo"')
|
19
|
+
User.logger.should_receive(:debug).with(' "bar"')
|
20
|
+
User.log_operation('GET', adapter, 'foo', 'bar')
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "#log_operation" do
|
25
|
+
let(:adapter) { Adapter[:memory].new({}) }
|
26
|
+
|
27
|
+
it "logs operation" do
|
28
|
+
User.logger.should_receive(:debug).with('ToyStore GET :memory "foo"')
|
29
|
+
User.logger.should_receive(:debug).with(' "bar"')
|
30
|
+
User.log_operation('GET', adapter, 'foo', 'bar')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Toy::MassAssignmentSecurity do
|
4
|
+
uses_constants('User', 'Game')
|
5
|
+
|
6
|
+
describe 'A class with accessible attributes' do
|
7
|
+
before do
|
8
|
+
User.attribute :name, String
|
9
|
+
User.attribute :admin, Boolean, :default => false
|
10
|
+
|
11
|
+
User.attr_accessible :name
|
12
|
+
@user = User.create(:name => 'Steve Sloan')
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should have accessible attributes class method' do
|
16
|
+
User.accessible_attributes.should include(:name)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should default accessible attributes to empty" do
|
20
|
+
Game.accessible_attributes.should be_empty
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should assign inaccessible attribute through accessor" do
|
24
|
+
@user.admin = true
|
25
|
+
@user.admin.should be_true
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should ignore inaccessible attribute on #initialize" do
|
29
|
+
user = User.new(:name => 'John', :admin => true)
|
30
|
+
user.admin.should be_false
|
31
|
+
user.name.should == 'John'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should not ignore inaccessible attributes on #initialize from the database" do
|
35
|
+
user = User.new(:name => 'John')
|
36
|
+
user.admin = true
|
37
|
+
user.save!
|
38
|
+
|
39
|
+
user = User.get(user.id)
|
40
|
+
user.admin.should be_true
|
41
|
+
user.name.should == 'John'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should ignore inaccessible attribute on #update_attributes" do
|
45
|
+
@user.update_attributes(:name => 'Ren Hoek', :admin => true)
|
46
|
+
@user.name.should == 'Ren Hoek'
|
47
|
+
@user.admin.should be_false
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should be indifferent to whether the accessible keys are strings or symbols" do
|
51
|
+
@user.update_attributes("name" => 'Stimpson J. Cat', "admin" => true)
|
52
|
+
@user.name.should == 'Stimpson J. Cat'
|
53
|
+
@user.admin.should be_false
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should accept nil as constructor's argument without raising exception" do
|
57
|
+
lambda { User.new(nil) }.should_not raise_error
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe 'A class with protected attributes' do
|
62
|
+
before do
|
63
|
+
User.attribute :name, String
|
64
|
+
User.attribute :admin, Boolean, :default => false
|
65
|
+
|
66
|
+
User.attr_protected :admin
|
67
|
+
|
68
|
+
@user = User.create(:name => 'Steve Sloan')
|
69
|
+
end
|
70
|
+
|
71
|
+
it "should have protected attributes class method" do
|
72
|
+
User.protected_attributes.should include(:admin)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should default protected attributes to empty" do
|
76
|
+
Game.protected_attributes.should be_empty
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should assign protected attribute through accessor" do
|
80
|
+
@user.admin = true
|
81
|
+
@user.admin.should be_true
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should ignore protected attribute on #initialize" do
|
85
|
+
user = User.new(:name => 'John', :admin => true)
|
86
|
+
user.admin.should be_false
|
87
|
+
user.name.should == 'John'
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should not ignore protected attributes on #initialize from the database" do
|
91
|
+
user = User.new(:name => 'John')
|
92
|
+
user.admin = true
|
93
|
+
user.save!
|
94
|
+
|
95
|
+
user = User.get(user.id)
|
96
|
+
user.admin.should be_true
|
97
|
+
user.name.should == 'John'
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should ignore protected attribute on #update_attributes" do
|
101
|
+
@user.update_attributes(:name => 'Ren Hoek', :admin => true)
|
102
|
+
@user.name.should == 'Ren Hoek'
|
103
|
+
@user.admin.should be_false
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should be indifferent to whether the protected keys are strings or symbols" do
|
107
|
+
@user.update_attributes("name" => 'Stimpson J. Cat', "admin" => true)
|
108
|
+
@user.name.should == 'Stimpson J. Cat'
|
109
|
+
@user.admin.should be_false
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should accept nil as constructor's argument without raising exception" do
|
113
|
+
lambda { User.new(nil) }.should_not raise_error
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,312 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Toy::Persistence do
|
4
|
+
uses_constants('User')
|
5
|
+
|
6
|
+
let(:klass) do
|
7
|
+
Class.new { include Toy::Store }
|
8
|
+
end
|
9
|
+
|
10
|
+
describe ".store" do
|
11
|
+
it "sets if arguments and reads if not" do
|
12
|
+
User.store(:memory, {})
|
13
|
+
User.store.should == Adapter[:memory].new({})
|
14
|
+
end
|
15
|
+
|
16
|
+
it "works with options" do
|
17
|
+
Adapter[:memory].should_receive(:new).with({}, :something => true)
|
18
|
+
User.store(:memory, {}, :something => true)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "raises argument error if name provided but not client" do
|
22
|
+
lambda do
|
23
|
+
klass.store(:memory)
|
24
|
+
end.should raise_error(ArgumentError, 'Client is required')
|
25
|
+
end
|
26
|
+
|
27
|
+
it "raises argument error if no name or client provided and has not been set" do
|
28
|
+
lambda do
|
29
|
+
klass.store
|
30
|
+
end.should raise_error(StandardError, 'No store has been set')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe ".cache" do
|
35
|
+
it "sets if arguments and reads if not" do
|
36
|
+
klass.cache(:memory, {})
|
37
|
+
klass.cache.should == Adapter[:memory].new({})
|
38
|
+
end
|
39
|
+
|
40
|
+
it "raises argument error if name provided but not client" do
|
41
|
+
lambda do
|
42
|
+
klass.cache(:memory)
|
43
|
+
end.should raise_error(ArgumentError, 'Client is required')
|
44
|
+
end
|
45
|
+
|
46
|
+
it "raises argument error if no name or client provided and has not been set" do
|
47
|
+
lambda do
|
48
|
+
klass.cache
|
49
|
+
end.should raise_error(StandardError, 'No cache has been set')
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe ".has_store?" do
|
54
|
+
it "returns true if cache set" do
|
55
|
+
klass.store(:memory, {})
|
56
|
+
klass.has_store?.should be_true
|
57
|
+
end
|
58
|
+
|
59
|
+
it "returns false if cache not set" do
|
60
|
+
klass.has_store?.should be_false
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe ".has_cache?" do
|
65
|
+
it "returns true if cache set" do
|
66
|
+
klass.cache(:memory, {})
|
67
|
+
klass.has_cache?.should be_true
|
68
|
+
end
|
69
|
+
|
70
|
+
it "returns false if cache not set" do
|
71
|
+
klass.has_cache?.should be_false
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe ".store_key" do
|
76
|
+
it "returns namespace and id" do
|
77
|
+
doc = User.new
|
78
|
+
|
79
|
+
User.store_key(doc.id).should == "User:#{doc.id}"
|
80
|
+
User.namespace('Crazy')
|
81
|
+
User.store_key(doc.id).should == "Crazy:#{doc.id}"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe ".namespace" do
|
86
|
+
it "defaults to class name" do
|
87
|
+
User.namespace.should == 'User'
|
88
|
+
end
|
89
|
+
|
90
|
+
it "sets if argument and reads if not" do
|
91
|
+
User.namespace('CrazyUser')
|
92
|
+
User.namespace.should == 'CrazyUser'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe ".create" do
|
97
|
+
before do
|
98
|
+
User.attribute :name, String
|
99
|
+
User.attribute :age, Integer
|
100
|
+
@doc = User.create(:name => 'John', :age => 50)
|
101
|
+
end
|
102
|
+
let(:doc) { @doc }
|
103
|
+
|
104
|
+
it "creates key in database with attributes" do
|
105
|
+
User.store.read(doc.store_key).should == {
|
106
|
+
'name' => 'John',
|
107
|
+
'id' => doc.id,
|
108
|
+
'age' => 50,
|
109
|
+
}
|
110
|
+
end
|
111
|
+
|
112
|
+
it "returns instance of model" do
|
113
|
+
doc.should be_instance_of(User)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe ".delete(*ids)" do
|
118
|
+
it "should delete a single record" do
|
119
|
+
doc = User.create
|
120
|
+
User.delete(doc.id)
|
121
|
+
User.key?(doc.id).should be_false
|
122
|
+
end
|
123
|
+
|
124
|
+
it "should delete multiple records" do
|
125
|
+
doc1 = User.create
|
126
|
+
doc2 = User.create
|
127
|
+
|
128
|
+
User.delete(doc1.id, doc2.id)
|
129
|
+
|
130
|
+
User.key?(doc1.id).should be_false
|
131
|
+
User.key?(doc2.id).should be_false
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should not complain when records do not exist" do
|
135
|
+
doc = User.create
|
136
|
+
User.delete("taco:bell:tacos")
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe ".destroy(*ids)" do
|
141
|
+
it "should destroy a single record" do
|
142
|
+
doc = User.create
|
143
|
+
User.destroy(doc.id)
|
144
|
+
User.key?(doc.id).should be_false
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should destroy multiple records" do
|
148
|
+
doc1 = User.create
|
149
|
+
doc2 = User.create
|
150
|
+
|
151
|
+
User.destroy(doc1.id, doc2.id)
|
152
|
+
|
153
|
+
User.key?(doc1.id).should be_false
|
154
|
+
User.key?(doc2.id).should be_false
|
155
|
+
end
|
156
|
+
|
157
|
+
it "should not complain when records do not exist" do
|
158
|
+
doc = User.create
|
159
|
+
User.destroy("taco:bell:tacos")
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
describe "#store" do
|
164
|
+
it "delegates to class" do
|
165
|
+
User.new.store.should equal(User.store)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
describe "#store_key" do
|
170
|
+
it "returns pluralized human name and id" do
|
171
|
+
doc = User.new
|
172
|
+
doc.store_key.should == "User:#{doc.id}"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
describe "#new_record?" do
|
177
|
+
it "returns true if new" do
|
178
|
+
User.new.should be_new_record
|
179
|
+
end
|
180
|
+
|
181
|
+
it "returns false if not new" do
|
182
|
+
User.create.should_not be_new_record
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe "#persisted?" do
|
187
|
+
it "returns true if persisted" do
|
188
|
+
User.create.should be_persisted
|
189
|
+
end
|
190
|
+
|
191
|
+
it "returns false if not persisted" do
|
192
|
+
User.new.should_not be_persisted
|
193
|
+
end
|
194
|
+
|
195
|
+
it "returns false if deleted" do
|
196
|
+
doc = User.create
|
197
|
+
doc.delete
|
198
|
+
doc.should_not be_persisted
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
describe "#save" do
|
203
|
+
before do
|
204
|
+
User.attribute :name, String
|
205
|
+
User.attribute :age, Integer
|
206
|
+
User.attribute :accepted_terms, Boolean, :virtual => true
|
207
|
+
end
|
208
|
+
|
209
|
+
context "with new record" do
|
210
|
+
before do
|
211
|
+
@doc = User.new(:name => 'John', :age => 28, :accepted_terms => true)
|
212
|
+
@doc.save
|
213
|
+
end
|
214
|
+
|
215
|
+
it "saves to key" do
|
216
|
+
User.key?(@doc.id)
|
217
|
+
end
|
218
|
+
|
219
|
+
it "does not persist virtual attributes" do
|
220
|
+
@doc.store.read(@doc.store_key).should_not include('accepted_terms')
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
context "with existing record" do
|
225
|
+
before do
|
226
|
+
@doc = User.create(:name => 'John', :age => 28)
|
227
|
+
@key = @doc.store_key
|
228
|
+
@value = User.store.read(@doc.store_key)
|
229
|
+
@doc.name = 'Bill'
|
230
|
+
@doc.accepted_terms = false
|
231
|
+
@doc.save
|
232
|
+
end
|
233
|
+
let(:doc) { @doc }
|
234
|
+
|
235
|
+
it "stores in same key" do
|
236
|
+
doc.store_key.should == @key
|
237
|
+
end
|
238
|
+
|
239
|
+
it "updates value in store" do
|
240
|
+
User.store.read(doc.store_key).should_not == @value
|
241
|
+
end
|
242
|
+
|
243
|
+
it "does not persist virtual attributes" do
|
244
|
+
@doc.store.read(@doc.store_key).should_not include('accepted_terms')
|
245
|
+
end
|
246
|
+
|
247
|
+
it "updates the attributes in the instance" do
|
248
|
+
doc.name.should == 'Bill'
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
describe "#update_attributes" do
|
254
|
+
before do
|
255
|
+
User.attribute :name, String
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should change attribute and save" do
|
259
|
+
user = User.create(:name => 'John')
|
260
|
+
User.get(user.id).name.should == 'John'
|
261
|
+
|
262
|
+
user.update_attributes(:name => 'Geoffrey')
|
263
|
+
User.get(user.id).name.should == 'Geoffrey'
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
describe "#delete" do
|
268
|
+
it "should remove the instance from the store" do
|
269
|
+
doc = User.create
|
270
|
+
doc.delete
|
271
|
+
User.key?(doc.id).should be_false
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
describe "#destroy" do
|
276
|
+
it "should remove the instance from the store" do
|
277
|
+
doc = User.create
|
278
|
+
doc.destroy
|
279
|
+
User.key?(doc.id).should be_false
|
280
|
+
end
|
281
|
+
end
|
282
|
+
|
283
|
+
describe "#destroyed?" do
|
284
|
+
it "should be false if not deleted" do
|
285
|
+
doc = User.create
|
286
|
+
doc.should_not be_destroyed
|
287
|
+
end
|
288
|
+
|
289
|
+
it "should be true if deleted" do
|
290
|
+
doc = User.create
|
291
|
+
doc.delete
|
292
|
+
doc.should be_destroyed
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
describe "with cache store" do
|
297
|
+
before do
|
298
|
+
@cache = User.cache(:memory, {})
|
299
|
+
@memory = User.store(:memory, {})
|
300
|
+
@user = User.create
|
301
|
+
end
|
302
|
+
|
303
|
+
let(:cache) { @cache }
|
304
|
+
let(:memory) { @memory }
|
305
|
+
let(:user) { @user }
|
306
|
+
|
307
|
+
it "writes to cache and store" do
|
308
|
+
cache[user.store_key].should == user.persisted_attributes
|
309
|
+
memory[user.store_key].should == user.persisted_attributes
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|