toystore 0.13.0 → 0.13.1
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/Changelog.md +12 -0
- data/Guardfile +2 -2
- data/README.md +26 -35
- data/examples/attributes_abbreviation.rb +2 -2
- data/examples/attributes_virtual.rb +2 -2
- data/examples/identity_map.rb +2 -2
- data/examples/memcached.rb +2 -2
- data/examples/memory.rb +2 -2
- data/examples/mongo.rb +2 -2
- data/examples/namespacing_keys.rb +1 -1
- data/examples/plain_old_object.rb +2 -2
- data/examples/plain_old_object_on_roids.rb +13 -22
- data/examples/redis.rb +2 -2
- data/examples/riak.rb +2 -2
- data/lib/toy.rb +4 -0
- data/lib/toy/attributes.rb +10 -21
- data/lib/toy/cloneable.rb +1 -3
- data/lib/toy/dirty.rb +0 -6
- data/lib/toy/equality.rb +3 -14
- data/lib/toy/extensions/symbol.rb +17 -0
- data/lib/toy/extensions/uuid.rb +6 -2
- data/lib/toy/identity.rb +39 -2
- data/lib/toy/inspect.rb +3 -4
- data/lib/toy/object.rb +1 -5
- data/lib/toy/persistence.rb +34 -5
- data/lib/toy/querying.rb +9 -9
- data/lib/toy/reloadable.rb +3 -3
- data/lib/toy/store.rb +1 -0
- data/lib/toy/types/json.rb +20 -0
- data/lib/toy/version.rb +1 -1
- data/spec/helper.rb +1 -0
- data/spec/toy/attributes_spec.rb +21 -59
- data/spec/toy/cloneable_spec.rb +1 -8
- data/spec/toy/equality_spec.rb +18 -19
- data/spec/toy/extensions/symbol_spec.rb +26 -0
- data/spec/toy/extensions/uuid_spec.rb +31 -11
- data/spec/toy/identity/uuid_key_factory_spec.rb +4 -4
- data/spec/toy/identity_spec.rb +111 -5
- data/spec/toy/inheritance_spec.rb +4 -4
- data/spec/toy/inspect_spec.rb +3 -3
- data/spec/toy/object_spec.rb +0 -40
- data/spec/toy/persistence_spec.rb +99 -1
- data/spec/toy/reloadable_spec.rb +9 -4
- data/spec/toy/serialization_spec.rb +16 -21
- data/spec/toy/types/json_spec.rb +37 -0
- data/spec/toy/validations_spec.rb +13 -0
- metadata +10 -4
data/spec/toy/cloneable_spec.rb
CHANGED
@@ -30,13 +30,6 @@ describe Toy::Cloneable do
|
|
30
30
|
user.clone.skills.should_not equal(user.skills)
|
31
31
|
end
|
32
32
|
|
33
|
-
it "regenerates id" do
|
34
|
-
user.clone.tap do |clone|
|
35
|
-
clone.id.should_not be_nil
|
36
|
-
clone.id.should_not == user.id
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
33
|
it "nullifies defined instance variables" do
|
41
34
|
user.instance_variable_set("@foo", true)
|
42
35
|
user.clone.tap do |clone|
|
@@ -44,4 +37,4 @@ describe Toy::Cloneable do
|
|
44
37
|
end
|
45
38
|
end
|
46
39
|
end
|
47
|
-
end
|
40
|
+
end
|
data/spec/toy/equality_spec.rb
CHANGED
@@ -1,39 +1,38 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
3
|
describe Toy::Equality do
|
4
|
-
uses_objects('User'
|
4
|
+
uses_objects('User')
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
before do
|
7
|
+
User.attribute :name, String
|
8
|
+
end
|
9
|
+
|
10
|
+
shared_examples_for 'object equality' do |method_name|
|
11
|
+
it "returns true if same class and attributes" do
|
12
|
+
User.new(:name => 'John').send(method_name, User.new(:name => 'John')).should be_true
|
9
13
|
end
|
10
14
|
|
11
15
|
it "return false if different class" do
|
12
|
-
User.new(:
|
16
|
+
User.new(:name => 'John').send(method_name, Object.new).should be_false
|
13
17
|
end
|
14
18
|
|
15
|
-
it "returns false if different
|
16
|
-
User.new(:
|
19
|
+
it "returns false if different attributes" do
|
20
|
+
User.new(:name => 'John').send(method_name, User.new(:name => 'Steve')).should be_false
|
17
21
|
end
|
18
22
|
end
|
19
23
|
|
20
|
-
describe "#
|
21
|
-
|
22
|
-
|
23
|
-
user.should equal(user)
|
24
|
-
end
|
24
|
+
describe "#eql?" do
|
25
|
+
include_examples 'object equality', :eql?
|
26
|
+
end
|
25
27
|
|
26
|
-
|
27
|
-
|
28
|
-
other_user = User.new
|
29
|
-
user.should_not equal(other_user)
|
30
|
-
end
|
28
|
+
describe "#==" do
|
29
|
+
include_examples 'object equality', :==
|
31
30
|
end
|
32
31
|
|
33
32
|
describe "#hash" do
|
34
|
-
it "returns the hash of the
|
33
|
+
it "returns the hash of the attributes" do
|
35
34
|
user = User.new
|
36
|
-
user.hash.should eq(user.
|
35
|
+
user.hash.should eq(user.attributes.hash)
|
37
36
|
end
|
38
37
|
end
|
39
38
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Symbol, ".to_store" do
|
4
|
+
it "should convert value to string" do
|
5
|
+
['foo', :foo].each do |value|
|
6
|
+
described_class.to_store(value).should eq('foo')
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should be nil if nil" do
|
11
|
+
described_class.to_store(nil).should be_nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe Symbol, ".from_store" do
|
16
|
+
it "should convert value to symbol" do
|
17
|
+
['foo', :foo].each do |value|
|
18
|
+
described_class.from_store(value).should == :foo
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should return nil if nil" do
|
23
|
+
described_class.from_store(nil).should be_nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -1,19 +1,39 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
describe
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
3
|
+
describe SimpleUUID::UUID do
|
4
|
+
describe ".to_store" do
|
5
|
+
it "returns nil if value is already nil" do
|
6
|
+
described_class.to_store(nil).should be(nil)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "returns value if value is already uuid" do
|
10
|
+
uuid = described_class.new
|
11
|
+
described_class.to_store(uuid).should be(uuid)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "converts value to uuid if not already uuid" do
|
15
|
+
uuid = described_class.new
|
16
|
+
[uuid.to_guid, uuid.to_s, uuid.to_i].each do |value|
|
17
|
+
described_class.from_store(value).should eq(uuid)
|
18
|
+
end
|
8
19
|
end
|
9
20
|
end
|
10
|
-
end
|
11
21
|
|
12
|
-
describe "
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
22
|
+
describe ".from_store" do
|
23
|
+
it "returns nil if value is already nil" do
|
24
|
+
described_class.from_store(nil).should be(nil)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns value if value is already uuid" do
|
28
|
+
uuid = described_class.new
|
29
|
+
described_class.from_store(uuid).should be(uuid)
|
30
|
+
end
|
31
|
+
|
32
|
+
it "converts value to uuid if not already uuid" do
|
33
|
+
uuid = described_class.new
|
34
|
+
[uuid.to_guid, uuid.to_s, uuid.to_i].each do |value|
|
35
|
+
described_class.from_store(value).should eq(uuid)
|
36
|
+
end
|
17
37
|
end
|
18
38
|
end
|
19
39
|
end
|
@@ -13,11 +13,11 @@ describe Toy::Identity::UUIDKeyFactory do
|
|
13
13
|
|
14
14
|
describe "#eql?" do
|
15
15
|
it "returns true for same class and key type" do
|
16
|
-
subject.eql?(
|
16
|
+
subject.eql?(described_class.new).should be_true
|
17
17
|
end
|
18
18
|
|
19
19
|
it "returns false for same class and different key type" do
|
20
|
-
other =
|
20
|
+
other = described_class.new
|
21
21
|
other.stub(:key_type).and_return(Integer)
|
22
22
|
subject.eql?(other).should be_false
|
23
23
|
end
|
@@ -29,11 +29,11 @@ describe Toy::Identity::UUIDKeyFactory do
|
|
29
29
|
|
30
30
|
describe "#==" do
|
31
31
|
it "returns true for same class and key type" do
|
32
|
-
subject.==(
|
32
|
+
subject.==(described_class.new).should be_true
|
33
33
|
end
|
34
34
|
|
35
35
|
it "returns false for same class and different key type" do
|
36
|
-
other =
|
36
|
+
other = described_class.new
|
37
37
|
other.stub(:key_type).and_return(Integer)
|
38
38
|
subject.==(other).should be_false
|
39
39
|
end
|
data/spec/toy/identity_spec.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
3
|
describe Toy::Identity do
|
4
|
-
|
4
|
+
uses_constants('User')
|
5
|
+
|
6
|
+
describe "including" do
|
7
|
+
it "adds id attribute" do
|
8
|
+
User.attributes.keys.should == ['id']
|
9
|
+
end
|
10
|
+
end
|
5
11
|
|
6
12
|
describe "setting the key" do
|
7
13
|
it "should set key factory to UUIDKeyFactory" do
|
@@ -51,12 +57,112 @@ describe Toy::Identity do
|
|
51
57
|
end
|
52
58
|
end
|
53
59
|
|
60
|
+
describe "#initialize" do
|
61
|
+
before do
|
62
|
+
User.attribute :name, String
|
63
|
+
User.attribute :age, Integer
|
64
|
+
end
|
65
|
+
|
66
|
+
it "writes id" do
|
67
|
+
id = User.new.id
|
68
|
+
id.should_not be_nil
|
69
|
+
id.size.should == 36
|
70
|
+
end
|
71
|
+
|
72
|
+
it "does not attempt to set id if already set" do
|
73
|
+
user = User.new(:id => 'frank')
|
74
|
+
user.id.should == 'frank'
|
75
|
+
end
|
76
|
+
|
77
|
+
it "defaults attributes to hash with only id" do
|
78
|
+
attrs = User.new.attributes
|
79
|
+
attrs.keys.should eq(['id'])
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "#clone" do
|
84
|
+
it "regenerates id" do
|
85
|
+
user = User.new
|
86
|
+
user.clone.tap do |clone|
|
87
|
+
clone.id.should_not be_nil
|
88
|
+
clone.id.should_not == user.id
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
shared_examples_for 'identity equality' do |method_name|
|
94
|
+
it "returns true if same class and id" do
|
95
|
+
User.new(:id => 1).send(method_name, User.new(:id => 1)).should be_true
|
96
|
+
end
|
97
|
+
|
98
|
+
it "returns true if same class and id even if other attributes have changed" do
|
99
|
+
User.new(:id => 1, :name => 'John').send(method_name, User.new(:id => 1, :name => 'Steve')).should be_true
|
100
|
+
end
|
101
|
+
|
102
|
+
it "return false if different class" do
|
103
|
+
User.new(:id => 1).send(method_name, Object.new).should be_false
|
104
|
+
end
|
105
|
+
|
106
|
+
it "returns false if different id" do
|
107
|
+
User.new(:id => 1).send(method_name, User.new(:id => 2)).should be_false
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe "#eql?" do
|
112
|
+
include_examples 'identity equality', :eql?
|
113
|
+
end
|
114
|
+
|
115
|
+
describe "#==" do
|
116
|
+
include_examples 'identity equality', :==
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "#equal?" do
|
120
|
+
it "returns true if same object" do
|
121
|
+
user = User.new(:name => 'John')
|
122
|
+
user.should equal(user)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "returns false if not same object" do
|
126
|
+
user = User.new
|
127
|
+
other_user = User.new
|
128
|
+
user.should_not equal(other_user)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
54
132
|
describe "initializing the id" do
|
55
133
|
it "should pass use pass the new object" do
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
134
|
+
User.key NameAndNumberKeyFactory.new
|
135
|
+
User.attribute :name, String
|
136
|
+
User.attribute :number, Integer
|
137
|
+
User.new(:name => 'John', :number => 1).id.should == 'John-1'
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
describe "#to_key" do
|
142
|
+
it "returns [id] if persisted" do
|
143
|
+
user = User.new
|
144
|
+
user.stub(:persisted?).and_return(true)
|
145
|
+
user.to_key.should == [user.id]
|
146
|
+
end
|
147
|
+
|
148
|
+
it "returns nil if not persisted" do
|
149
|
+
User.new.to_key.should be_nil
|
150
|
+
end
|
151
|
+
|
152
|
+
context "with native uuid" do
|
153
|
+
before do
|
154
|
+
User.key :native_uuid
|
155
|
+
end
|
156
|
+
|
157
|
+
it "returns array with guid if persisted" do
|
158
|
+
user = User.new
|
159
|
+
user.stub(:persisted?).and_return(true)
|
160
|
+
user.to_key.should == [user.id.to_guid]
|
161
|
+
end
|
162
|
+
|
163
|
+
it "returns nil if not persisted" do
|
164
|
+
User.new.to_key.should be_nil
|
165
|
+
end
|
60
166
|
end
|
61
167
|
end
|
62
168
|
end
|
@@ -36,10 +36,6 @@ describe 'Toy Inheritance' do
|
|
36
36
|
it "sets type to class name" do
|
37
37
|
Child.new.type.should eq('Child')
|
38
38
|
end
|
39
|
-
|
40
|
-
it "sets the key factory to same as parent" do
|
41
|
-
Child.key_factory.should eq(Parent.key_factory)
|
42
|
-
end
|
43
39
|
end
|
44
40
|
|
45
41
|
describe 'using Toy::Store' do
|
@@ -89,5 +85,9 @@ describe 'Toy Inheritance' do
|
|
89
85
|
it "sets the adapter to the same as the parent" do
|
90
86
|
Child.adapter.should eq(Parent.adapter)
|
91
87
|
end
|
88
|
+
|
89
|
+
it "sets the key factory to same as parent" do
|
90
|
+
Child.key_factory.should eq(Parent.key_factory)
|
91
|
+
end
|
92
92
|
end
|
93
93
|
end
|
data/spec/toy/inspect_spec.rb
CHANGED
@@ -10,14 +10,14 @@ describe Toy::Attributes do
|
|
10
10
|
|
11
11
|
describe ".inspect" do
|
12
12
|
it "prints out attribute names and types" do
|
13
|
-
User.inspect.should == %Q(User(
|
13
|
+
User.inspect.should == %Q(User(age:Integer name:String))
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
17
|
describe "#inspect" do
|
18
|
-
it "prints out
|
18
|
+
it "prints out attributes sorted with values" do
|
19
19
|
user = User.new(:age => 28, :name => 'John')
|
20
|
-
user.inspect.should == %Q(#<User:#{user.object_id}
|
20
|
+
user.inspect.should == %Q(#<User:#{user.object_id} age: 28, name: "John">)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
data/spec/toy/object_spec.rb
CHANGED
@@ -24,44 +24,4 @@ describe Toy::Object do
|
|
24
24
|
User.new.persisted?.should be_false
|
25
25
|
end
|
26
26
|
end
|
27
|
-
|
28
|
-
describe "#to_key" do
|
29
|
-
it "returns [id] if persisted" do
|
30
|
-
user = User.new
|
31
|
-
user.stub(:persisted?).and_return(true)
|
32
|
-
user.to_key.should == [user.id]
|
33
|
-
end
|
34
|
-
|
35
|
-
it "returns nil if not persisted" do
|
36
|
-
User.new.to_key.should be_nil
|
37
|
-
end
|
38
|
-
|
39
|
-
context "with native uuid" do
|
40
|
-
before do
|
41
|
-
User.key :native_uuid
|
42
|
-
end
|
43
|
-
|
44
|
-
it "returns array with guid if persisted" do
|
45
|
-
user = User.new
|
46
|
-
user.stub(:persisted?).and_return(true)
|
47
|
-
user.to_key.should == [user.id.to_guid]
|
48
|
-
end
|
49
|
-
|
50
|
-
it "returns nil if not persisted" do
|
51
|
-
User.new.to_key.should be_nil
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
describe "#to_param" do
|
57
|
-
it "returns key joined by - if to_key present" do
|
58
|
-
user = User.new
|
59
|
-
user.stub(:persisted?).and_return(true)
|
60
|
-
user.to_param.should == user.to_key.join('-')
|
61
|
-
end
|
62
|
-
|
63
|
-
it "returns nil if to_key nil" do
|
64
|
-
User.new.to_param.should be_nil
|
65
|
-
end
|
66
|
-
end
|
67
27
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
3
|
describe Toy::Persistence do
|
4
|
-
uses_constants('User')
|
4
|
+
uses_constants('User', 'Game')
|
5
5
|
|
6
6
|
let(:klass) do
|
7
7
|
Class.new { include Toy::Store }
|
@@ -42,6 +42,37 @@ describe Toy::Persistence do
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
+
describe ".persisted_attributes" do
|
46
|
+
before do
|
47
|
+
@name = User.attribute(:name, String)
|
48
|
+
@password = User.attribute(:password, String, :virtual => true)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "includes attributes that are not virtual" do
|
52
|
+
User.persisted_attributes.should include(@name)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "excludes attributes that are virtual" do
|
56
|
+
User.persisted_attributes.should_not include(@password)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "memoizes after first call" do
|
60
|
+
User.should_receive(:attributes).once.and_return({
|
61
|
+
'name' => @name,
|
62
|
+
'password' => @password,
|
63
|
+
})
|
64
|
+
User.persisted_attributes
|
65
|
+
User.persisted_attributes
|
66
|
+
User.persisted_attributes
|
67
|
+
end
|
68
|
+
|
69
|
+
it "is unmemoized when declaring a new attribute" do
|
70
|
+
User.persisted_attributes
|
71
|
+
age = User.attribute :age, Integer
|
72
|
+
User.persisted_attributes.map(&:name).sort.should eq(%w[age name])
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
45
76
|
describe ".create" do
|
46
77
|
before do
|
47
78
|
User.attribute :name, String
|
@@ -318,6 +349,13 @@ describe Toy::Persistence do
|
|
318
349
|
doc.delete
|
319
350
|
User.key?(doc.id).should be_false
|
320
351
|
end
|
352
|
+
|
353
|
+
it "uses persisted id for adapter delete" do
|
354
|
+
user = User.new
|
355
|
+
user.stub(:persisted_id => 1)
|
356
|
+
user.adapter.should_receive(:delete).with(1)
|
357
|
+
user.delete
|
358
|
+
end
|
321
359
|
end
|
322
360
|
|
323
361
|
describe "#destroy" do
|
@@ -354,4 +392,64 @@ describe Toy::Persistence do
|
|
354
392
|
user.clone.should_not be_destroyed
|
355
393
|
end
|
356
394
|
end
|
395
|
+
|
396
|
+
describe "#persisted_id" do
|
397
|
+
it "returns id attribute value converted for storage" do
|
398
|
+
raw_value = 1
|
399
|
+
typecast_for_store_value = '1'
|
400
|
+
user = User.new(:id => raw_value)
|
401
|
+
user.persisted_id.should eq(typecast_for_store_value)
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
describe "#persisted_attributes" do
|
406
|
+
before do
|
407
|
+
@over = Game.attribute(:over, Boolean)
|
408
|
+
@score = Game.attribute(:creator_score, Integer, :virtual => true)
|
409
|
+
@abbr = Game.attribute(:super_secret_hash, String, :abbr => :ssh)
|
410
|
+
@rewards = Game.attribute(:rewards, Set)
|
411
|
+
@time = Game.attribute(:time, Time)
|
412
|
+
@game = Game.new({
|
413
|
+
:over => true,
|
414
|
+
:creator_score => 20,
|
415
|
+
:rewards => %w(twigs berries).to_set,
|
416
|
+
:ssh => 'h4x',
|
417
|
+
:time => nil,
|
418
|
+
})
|
419
|
+
end
|
420
|
+
|
421
|
+
it "includes persisted attributes" do
|
422
|
+
@game.persisted_attributes.should have_key('over')
|
423
|
+
end
|
424
|
+
|
425
|
+
it "includes abbreviated names for abbreviated attributes" do
|
426
|
+
@game.persisted_attributes.should have_key('ssh')
|
427
|
+
end
|
428
|
+
|
429
|
+
it "does not include full names for abbreviated attributes" do
|
430
|
+
@game.persisted_attributes.should_not have_key('super_secret_hash')
|
431
|
+
end
|
432
|
+
|
433
|
+
it "does not include virtual attributes" do
|
434
|
+
@game.persisted_attributes.should_not have_key(:creator_score)
|
435
|
+
end
|
436
|
+
|
437
|
+
it "includes to_store values for attributes" do
|
438
|
+
@game.persisted_attributes['rewards'].should be_instance_of(Array)
|
439
|
+
@game.persisted_attributes['rewards'].should == @rewards.to_store(@game.rewards)
|
440
|
+
end
|
441
|
+
|
442
|
+
it "does not include nil attributes" do
|
443
|
+
@game.persisted_attributes.should_not have_key('time')
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
describe "#persist" do
|
448
|
+
it "calls write on adapter with persisted id and attributes" do
|
449
|
+
user = User.new
|
450
|
+
user.stub(persisted_id: 1, persisted_attributes: {one: 'two'})
|
451
|
+
user.adapter.should_receive(:write).with(1, {one: 'two'})
|
452
|
+
user.persist
|
453
|
+
end
|
454
|
+
end
|
357
455
|
end
|