toystore 0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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,172 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Toy::Lists do
|
4
|
+
uses_constants('Game', 'Move')
|
5
|
+
|
6
|
+
it "defaults lists to empty hash" do
|
7
|
+
Game.embedded_lists.should == {}
|
8
|
+
end
|
9
|
+
|
10
|
+
it "does not share with regular lists" do
|
11
|
+
Game.list(:moves)
|
12
|
+
Game.embedded_lists.should == {}
|
13
|
+
end
|
14
|
+
|
15
|
+
describe ".embedded_list?" do
|
16
|
+
before do
|
17
|
+
Game.embedded_list(:moves)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "returns true if attribute (symbol)" do
|
21
|
+
Game.embedded_list?(:moves).should be_true
|
22
|
+
end
|
23
|
+
|
24
|
+
it "returns true if attribute (string)" do
|
25
|
+
Game.embedded_list?('moves').should be_true
|
26
|
+
end
|
27
|
+
|
28
|
+
it "returns false if not attribute" do
|
29
|
+
Game.embedded_list?(:foobar).should be_false
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe ".parent_reference" do
|
34
|
+
before do
|
35
|
+
Game.embedded_list(:moves)
|
36
|
+
end
|
37
|
+
|
38
|
+
context "with single name" do
|
39
|
+
before do
|
40
|
+
Move.parent_reference(:game)
|
41
|
+
@game = Game.new
|
42
|
+
@move = Move.new
|
43
|
+
end
|
44
|
+
|
45
|
+
it "defines method that calls parent_reference" do
|
46
|
+
@move.parent_reference = @game
|
47
|
+
@move.game.should == @game
|
48
|
+
end
|
49
|
+
|
50
|
+
it "defaults boolean method that checks parent_reference existence" do
|
51
|
+
@move.game?.should be_false
|
52
|
+
@move.parent_reference = @game
|
53
|
+
@move.game?.should be_true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "with multiple names" do
|
58
|
+
before do
|
59
|
+
Move.parent_reference(:game, :yaypants)
|
60
|
+
@game = Game.new
|
61
|
+
@move = Move.new
|
62
|
+
end
|
63
|
+
|
64
|
+
it "defines method that calls parent_reference" do
|
65
|
+
@move.parent_reference = @game
|
66
|
+
@move.game.should == @game
|
67
|
+
@move.yaypants.should == @game
|
68
|
+
end
|
69
|
+
|
70
|
+
it "defaults boolean method that checks parent_reference existence" do
|
71
|
+
@move.game?.should be_false
|
72
|
+
@move.yaypants?.should be_false
|
73
|
+
@move.parent_reference = @game
|
74
|
+
@move.game?.should be_true
|
75
|
+
@move.yaypants?.should be_true
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
describe '.parent_references' do
|
81
|
+
it 'keeps track of single names' do
|
82
|
+
Move.parent_reference(:game)
|
83
|
+
Move.parent_references.should == [:game]
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'keeps track of single names' do
|
87
|
+
Move.parent_reference(:game, :yaypants)
|
88
|
+
Move.parent_references.should == [:game, :yaypants]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe '.parent_reference?' do
|
93
|
+
before do
|
94
|
+
Move.parent_reference(:game)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'returns true if attribute (symbol)' do
|
98
|
+
Move.parent_reference?(:game).should be_true
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'returns true if attribute (string)' do
|
102
|
+
Move.parent_reference?('game').should be_true
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'returns false if not an attribute' do
|
106
|
+
Move.parent_reference?(:foobar).should be_false
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "declaring an embedded list" do
|
111
|
+
describe "using conventions" do
|
112
|
+
before do
|
113
|
+
@list = Game.embedded_list(:moves)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "knows about its lists" do
|
117
|
+
Game.embedded_lists[:moves].should == Toy::EmbeddedList.new(Game, :moves)
|
118
|
+
end
|
119
|
+
|
120
|
+
it "returns list" do
|
121
|
+
@list.should == Toy::EmbeddedList.new(Game, :moves)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "with type" do
|
126
|
+
before do
|
127
|
+
@list = Game.embedded_list(:recent_moves, Move)
|
128
|
+
end
|
129
|
+
let(:list) { @list }
|
130
|
+
|
131
|
+
it "sets type" do
|
132
|
+
list.type.should be(Move)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "sets options to hash" do
|
136
|
+
list.options.should be_instance_of(Hash)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "with options" do
|
141
|
+
before do
|
142
|
+
@list = Game.embedded_list(:moves, :some_option => true)
|
143
|
+
end
|
144
|
+
let(:list) { @list }
|
145
|
+
|
146
|
+
it "sets type" do
|
147
|
+
list.type.should be(Move)
|
148
|
+
end
|
149
|
+
|
150
|
+
it "sets options" do
|
151
|
+
list.options.should have_key(:some_option)
|
152
|
+
list.options[:some_option].should be_true
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "with type and options" do
|
157
|
+
before do
|
158
|
+
@list = Game.embedded_list(:recent_moves, Move, :some_option => true)
|
159
|
+
end
|
160
|
+
let(:list) { @list }
|
161
|
+
|
162
|
+
it "sets type" do
|
163
|
+
list.type.should be(Move)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "sets options" do
|
167
|
+
list.options.should have_key(:some_option)
|
168
|
+
list.options[:some_option].should be_true
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Toy::Equality do
|
4
|
+
uses_constants('User', 'Game', 'Person')
|
5
|
+
|
6
|
+
describe "#eql?" do
|
7
|
+
it "returns true if same class and id" do
|
8
|
+
User.new(:id => 1).should eql(User.new(:id => 1))
|
9
|
+
end
|
10
|
+
|
11
|
+
it "return false if different class" do
|
12
|
+
User.new(:id => 1).should_not eql(Person.new(:id => 1))
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns false if different id" do
|
16
|
+
User.new(:id => 1).should_not eql(User.new(:id => 2))
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns true if reference and target is same class and id" do
|
20
|
+
Game.reference(:user)
|
21
|
+
user = User.create
|
22
|
+
game = Game.create(:user => user)
|
23
|
+
user.should eql(game.user)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "equal?" do
|
28
|
+
it "returns true if same object" do
|
29
|
+
user = User.create(:id => 1)
|
30
|
+
user.should equal(user)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns true if same object through proxy" do
|
34
|
+
Game.reference(:user)
|
35
|
+
user = User.create
|
36
|
+
game = Game.create(:user => user)
|
37
|
+
|
38
|
+
user.should equal(game.user)
|
39
|
+
game.user.should equal(user)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "returns false if not same object" do
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe Toy::RecordInvalidError do
|
4
|
+
uses_constants('User')
|
5
|
+
|
6
|
+
before do
|
7
|
+
User.attribute(:name, String)
|
8
|
+
User.attribute(:age, Integer)
|
9
|
+
User.validates_presence_of(:name)
|
10
|
+
User.validates_presence_of(:age)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should include a message of the errors" do
|
14
|
+
user = User.new
|
15
|
+
user.should_not be_valid
|
16
|
+
Toy::RecordInvalidError.new(user).message.should == "Invalid record: Name can't be blank and Age can't be blank"
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe "Array.to_store" do
|
4
|
+
it "should convert value to_a" do
|
5
|
+
Array.to_store([1, 2, 3, 4]).should == [1, 2, 3, 4]
|
6
|
+
Array.to_store('1').should == ['1']
|
7
|
+
Array.to_store({'1' => '2', '3' => '4'}).should == [['1', '2'], ['3', '4']]
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "Array.from_store" do
|
12
|
+
it "should be array if array" do
|
13
|
+
Array.from_store([1, 2]).should == [1, 2]
|
14
|
+
end
|
15
|
+
|
16
|
+
it "should be empty array if nil" do
|
17
|
+
Array.from_store(nil).should == []
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "Array.store_default" do
|
22
|
+
it "returns emtpy array" do
|
23
|
+
Array.store_default.should == []
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe "Boolean.to_store" do
|
4
|
+
it "should be true for true" do
|
5
|
+
Boolean.to_store(true).should be_true
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should be false for false" do
|
9
|
+
Boolean.to_store(false).should be_false
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should handle odd assortment of other values" do
|
13
|
+
Boolean.to_store('true').should be_true
|
14
|
+
Boolean.to_store('t').should be_true
|
15
|
+
Boolean.to_store('1').should be_true
|
16
|
+
Boolean.to_store(1).should be_true
|
17
|
+
|
18
|
+
Boolean.to_store('false').should be_false
|
19
|
+
Boolean.to_store('f').should be_false
|
20
|
+
Boolean.to_store('0').should be_false
|
21
|
+
Boolean.to_store(0).should be_false
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should be nil for nil" do
|
25
|
+
Boolean.to_store(nil).should be_nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "Boolean.from_store" do
|
30
|
+
it "should be true for true" do
|
31
|
+
Boolean.from_store(true).should be_true
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should be false for false" do
|
35
|
+
Boolean.from_store(false).should be_false
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should be nil for nil" do
|
39
|
+
Boolean.from_store(nil).should be_nil
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe "Date.to_store" do
|
4
|
+
it "should be time if string" do
|
5
|
+
date = Date.to_store('2009-10-01')
|
6
|
+
date.should == Time.utc(2009, 10, 1)
|
7
|
+
date.should == date
|
8
|
+
date.month.should == 10
|
9
|
+
date.day.should == 1
|
10
|
+
date.year.should == 2009
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should be time if date" do
|
14
|
+
Date.to_store(Date.new(2009, 10, 1)).should == Time.utc(2009, 10, 1)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should be date if time" do
|
18
|
+
Date.to_store(Time.parse("2009-10-1T12:30:00")).should == Time.utc(2009, 10, 1)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should be nil if bogus string" do
|
22
|
+
Date.to_store('jdsafop874').should be_nil
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should be nil if empty string" do
|
26
|
+
Date.to_store('').should be_nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe "Date.from_store" do
|
31
|
+
it "should be date if date" do
|
32
|
+
date = Date.new(2009, 10, 1)
|
33
|
+
from_date = Date.from_store(date)
|
34
|
+
from_date.should == date
|
35
|
+
from_date.month.should == 10
|
36
|
+
from_date.day.should == 1
|
37
|
+
from_date.year.should == 2009
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should be date if time" do
|
41
|
+
time = Time.now
|
42
|
+
Date.from_store(time).should == time.to_date
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should be nil if nil" do
|
46
|
+
Date.from_store(nil).should be_nil
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe "Float.to_store" do
|
4
|
+
it "should convert value to_f" do
|
5
|
+
[21, 21.0, '21'].each do |value|
|
6
|
+
Float.to_store(value).should == 21.0
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should leave nil values nil" do
|
11
|
+
Float.to_store(nil).should == nil
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe "Hash.from_store" do
|
4
|
+
it "should convert hash to hash with indifferent access" do
|
5
|
+
hash = Hash.from_store(:foo => 'bar')
|
6
|
+
hash[:foo].should == 'bar'
|
7
|
+
hash['foo'].should == 'bar'
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should be hash if nil" do
|
11
|
+
hash = Hash.from_store(nil)
|
12
|
+
hash.should == {}
|
13
|
+
hash.is_a?(HashWithIndifferentAccess).should be_true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "Hash.store_default" do
|
18
|
+
it "returns emtpy hash with indifferent access" do
|
19
|
+
Hash.store_default.should == {}.with_indifferent_access
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe "Integer.to_store" do
|
4
|
+
it "should convert value to integer" do
|
5
|
+
[21, 21.0, '21'].each do |value|
|
6
|
+
Integer.to_store(value).should == 21
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should work fine with big integers" do
|
11
|
+
[9223372036854775807, '9223372036854775807'].each do |value|
|
12
|
+
Integer.to_store(value).should == 9223372036854775807
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "Integer.from_store" do
|
18
|
+
it "should convert value to integer" do
|
19
|
+
[21, 21.0, '21'].each do |value|
|
20
|
+
Integer.from_store(value).should == 21
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should work fine with big integers" do
|
25
|
+
[9223372036854775807, '9223372036854775807'].each do |value|
|
26
|
+
Integer.from_store(value).should == 9223372036854775807
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
describe "Set.to_store" do
|
4
|
+
it "should convert value to_a" do
|
5
|
+
Set.to_store(Set.new([1,2,3])).should == [1,2,3]
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should convert to empty array if nil" do
|
9
|
+
Set.to_store(nil).should == []
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "Set.from_store" do
|
14
|
+
it "should be a set if array" do
|
15
|
+
Set.from_store([1,2,3]).should == Set.new([1,2,3])
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should be empty set if nil" do
|
19
|
+
Set.from_store(nil).should == Set.new([])
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "Set.store_default" do
|
24
|
+
it "returns empty set" do
|
25
|
+
Set.store_default.should == Set.new
|
26
|
+
end
|
27
|
+
end
|