toystore 0.8.3 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. data/.gitignore +1 -2
  2. data/Changelog.md +9 -0
  3. data/Gemfile +5 -0
  4. data/Gemfile.lock +71 -0
  5. data/Guardfile +15 -0
  6. data/README.md +28 -0
  7. data/examples/attributes_abbreviation.rb +1 -2
  8. data/examples/attributes_virtual.rb +1 -2
  9. data/examples/identity_map.rb +7 -12
  10. data/examples/memcached.rb +1 -1
  11. data/examples/memory.rb +1 -1
  12. data/examples/mongo.rb +1 -1
  13. data/examples/redis.rb +1 -1
  14. data/examples/riak.rb +1 -1
  15. data/lib/toy.rb +40 -39
  16. data/lib/toy/attribute.rb +1 -6
  17. data/lib/toy/attributes.rb +61 -90
  18. data/lib/toy/caching.rb +11 -13
  19. data/lib/toy/callbacks.rb +12 -31
  20. data/lib/toy/cloneable.rb +20 -0
  21. data/lib/toy/collection.rb +8 -7
  22. data/lib/toy/dirty.rb +17 -36
  23. data/lib/toy/dirty_store.rb +32 -0
  24. data/lib/toy/equality.rb +2 -0
  25. data/lib/toy/extensions/boolean.rb +22 -18
  26. data/lib/toy/identity_map.rb +39 -62
  27. data/lib/toy/list.rb +23 -22
  28. data/lib/toy/logger.rb +2 -17
  29. data/lib/toy/mass_assignment_security.rb +3 -5
  30. data/lib/toy/middleware/identity_map.rb +23 -4
  31. data/lib/toy/object.rb +16 -0
  32. data/lib/toy/persistence.rb +72 -62
  33. data/lib/toy/proxies/list.rb +19 -18
  34. data/lib/toy/proxies/proxy.rb +7 -6
  35. data/lib/toy/querying.rb +2 -4
  36. data/lib/toy/reference.rb +28 -26
  37. data/lib/toy/reloadable.rb +17 -0
  38. data/lib/toy/serialization.rb +25 -25
  39. data/lib/toy/store.rb +3 -11
  40. data/lib/toy/validations.rb +9 -28
  41. data/lib/toy/version.rb +1 -1
  42. data/perf/reads.rb +7 -9
  43. data/perf/writes.rb +6 -8
  44. data/spec/helper.rb +3 -1
  45. data/spec/support/constants.rb +1 -4
  46. data/spec/support/identity_map_matcher.rb +5 -5
  47. data/spec/support/objects.rb +38 -0
  48. data/spec/toy/attribute_spec.rb +1 -1
  49. data/spec/toy/attributes_spec.rb +1 -153
  50. data/spec/toy/callbacks_spec.rb +1 -45
  51. data/spec/toy/cloneable_spec.rb +47 -0
  52. data/spec/toy/dirty_spec.rb +12 -44
  53. data/spec/toy/dirty_store_spec.rb +47 -0
  54. data/spec/toy/equality_spec.rb +5 -19
  55. data/spec/toy/extensions/boolean_spec.rb +2 -0
  56. data/spec/toy/identity/uuid_key_factory_spec.rb +2 -2
  57. data/spec/toy/identity_map_spec.rb +45 -37
  58. data/spec/toy/identity_spec.rb +1 -1
  59. data/spec/toy/inspect_spec.rb +1 -1
  60. data/spec/toy/lists_spec.rb +20 -5
  61. data/spec/toy/logger_spec.rb +1 -29
  62. data/spec/toy/mass_assignment_security_spec.rb +16 -5
  63. data/spec/toy/middleware/identity_map_spec.rb +68 -2
  64. data/spec/toy/persistence_spec.rb +88 -30
  65. data/spec/toy/reference_spec.rb +0 -1
  66. data/spec/toy/references_spec.rb +20 -0
  67. data/spec/toy/reloadable_spec.rb +81 -0
  68. data/spec/toy/serialization_spec.rb +1 -110
  69. data/spec/toy/validations_spec.rb +0 -21
  70. data/spec/toy_spec.rb +4 -5
  71. data/test/lint_test.rb +1 -1
  72. metadata +21 -26
  73. data/.autotest +0 -11
  74. data/LOGGING.rdoc +0 -12
  75. data/README.rdoc +0 -27
  76. data/examples/models.rb +0 -51
  77. data/lib/toy/dolly.rb +0 -30
  78. data/lib/toy/embedded_list.rb +0 -45
  79. data/lib/toy/embedded_lists.rb +0 -68
  80. data/lib/toy/index.rb +0 -74
  81. data/lib/toy/indices.rb +0 -56
  82. data/lib/toy/proxies/embedded_list.rb +0 -79
  83. data/spec/toy/dolly_spec.rb +0 -76
  84. data/spec/toy/embedded_list_spec.rb +0 -607
  85. data/spec/toy/embedded_lists_spec.rb +0 -172
  86. data/spec/toy/index_spec.rb +0 -230
  87. data/spec/toy/indices_spec.rb +0 -141
  88. data/specs.watchr +0 -52
@@ -1,172 +0,0 @@
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
@@ -1,230 +0,0 @@
1
- require 'helper'
2
-
3
- describe Toy::Index do
4
- uses_constants('User', 'Student', 'Friendship')
5
-
6
- before do
7
- User.attribute(:ssn, String)
8
- @index = User.index(:ssn)
9
- end
10
- let(:index) { @index }
11
-
12
- it "has a model" do
13
- index.model.should == User
14
- end
15
-
16
- it "has a name" do
17
- index.name.should == :ssn
18
- end
19
-
20
- it "raises error if attribute does not exist" do
21
- lambda {
22
- User.index :student_id
23
- }.should raise_error(ArgumentError, "No attribute student_id for index")
24
- end
25
-
26
- it "has a sha1'd key for a value" do
27
- index.key('some_value').should == 'User:ssn:8c818171573b03feeae08b0b4ffeb6999e3afc05'
28
- end
29
-
30
- it "adds index to model" do
31
- User.indices.keys.should include(:ssn)
32
- end
33
-
34
- describe "#eql?" do
35
- it "returns true if same class, model, and name" do
36
- index.should eql(index)
37
- end
38
-
39
- it "returns false if not same class" do
40
- index.should_not eql({})
41
- end
42
-
43
- it "returns false if not same model" do
44
- Student.attribute :ssn, String
45
- index.should_not eql(Toy::Index.new(Student, :ssn))
46
- end
47
-
48
- it "returns false if not the same name" do
49
- User.attribute :student_id, String
50
- index.should_not eql(Toy::Index.new(User, :student_id))
51
- end
52
- end
53
-
54
- describe "single key" do
55
- describe "creating with index" do
56
- before do
57
- @user = User.create(:ssn => '555-00-1234')
58
- end
59
- let(:user) { @user }
60
-
61
- it "creates key for indexed value" do
62
- User.store.should be_key("User:ssn:f6edc9155d79e311ad2d4a6e1b54004f31497f4c")
63
- end
64
-
65
- it "adds instance id to index array" do
66
- User.get_index(:ssn, '555-00-1234').should == [user.id]
67
- end
68
- end
69
-
70
- describe "creating second record for same index value" do
71
- before do
72
- @user1 = User.create(:ssn => '555-00-1234')
73
- @user2 = User.create(:ssn => '555-00-1234')
74
- end
75
-
76
- it "adds both instances to index" do
77
- User.get_index(:ssn, '555-00-1234').should == [@user1.id, @user2.id]
78
- end
79
- end
80
-
81
- describe "destroying with index" do
82
- before do
83
- @user = User.create(:ssn => '555-00-1234')
84
- @user.destroy
85
- end
86
-
87
- it "removes id from index" do
88
- User.get_index(:ssn, '555-00-1234').should == []
89
- end
90
- end
91
-
92
- describe "updating record and changing indexed value" do
93
- before do
94
- @user = User.create(:ssn => '555-00-1234')
95
- @user.update_attributes(:ssn => '555-00-4321')
96
- end
97
-
98
- it "removes from old index" do
99
- User.get_index(:ssn, '555-00-1234').should == []
100
- end
101
-
102
- it "adds to new index" do
103
- User.get_index(:ssn, '555-00-4321').should == [@user.id]
104
- end
105
- end
106
-
107
- describe "updating record without changing indexed value" do
108
- before do
109
- @user = User.create(:ssn => '555-00-1234')
110
- @user.update_attributes(:ssn => '555-00-1234')
111
- end
112
-
113
- it "leaves index alone" do
114
- User.get_index(:ssn, '555-00-1234').should == [@user.id]
115
- end
116
- end
117
-
118
- describe "first by index" do
119
- it "should not find values that are not in index" do
120
- User.first_by_ssn('does-not-exist').should be_nil
121
- end
122
-
123
- it "should find indexed value" do
124
- user = User.create(:ssn => '555-00-1234')
125
- User.first_by_ssn('555-00-1234').should == user
126
- end
127
- end
128
-
129
- describe "first or new by index" do
130
- it "initializes if not existing" do
131
- user = User.first_or_new_by_ssn('does-not-exist')
132
- user.ssn.should == 'does-not-exist'
133
- user.should_not be_persisted
134
- end
135
-
136
- it "returns if existing" do
137
- user = User.create(:ssn => '555-00-1234')
138
- User.first_or_new_by_ssn('555-00-1234').should == user
139
- end
140
- end
141
-
142
- describe "first or create by index" do
143
- it "creates if not existing" do
144
- user = User.first_or_create_by_ssn('does-not-exist')
145
- user.ssn.should == 'does-not-exist'
146
- user.should be_persisted
147
- end
148
-
149
- it "returns if existing" do
150
- user = User.create(:ssn => '555-00-1234')
151
- User.first_or_create_by_ssn('555-00-1234').should == user
152
- end
153
- end
154
- end
155
-
156
- describe "array key" do
157
- before do
158
- User.list :friendships
159
- Friendship.list :users
160
- Friendship.index :user_ids
161
- @user1 = User.create(:ssn => '555-00-1234')
162
- @user2 = User.create(:ssn => '555-00-9876')
163
- @friendship = Friendship.create(:user_ids => [@user1.id, @user2.id])
164
- end
165
- let(:user1) { @user1 }
166
- let(:user2) { @user2 }
167
- let(:friendship) { @friendship }
168
-
169
- describe "creating with index" do
170
- it "creates key for indexed values sorted" do
171
- sha_value = Digest::SHA1.hexdigest([user1.id, user2.id].sort.join(''))
172
- Friendship.store.should be_key("Friendship:user_ids:#{sha_value}")
173
- end
174
-
175
- it "adds instance id to index array" do
176
- Friendship.get_index(:user_ids, [user1.id, user2.id]).should == [friendship.id]
177
- Friendship.get_index(:user_ids, [user2.id, user1.id]).should == [friendship.id]
178
- end
179
- end
180
-
181
- describe "destroying with index" do
182
- before do
183
- friendship.destroy
184
- end
185
-
186
- it "removes id from index" do
187
- Friendship.get_index(:user_ids, [user2.id, user1.id]).should == []
188
- end
189
- end
190
-
191
- describe "first by index" do
192
- it "should not find values that are not in index" do
193
- Friendship.first_by_user_ids([user1.id, 'does-not-exist']).should be_nil
194
- end
195
-
196
- it "should find indexed value" do
197
- Friendship.first_by_user_ids([user1.id, user2.id]).should == friendship
198
- Friendship.first_by_user_ids([user2.id, user1.id]).should == friendship
199
- end
200
- end
201
-
202
- describe "first or new by index" do
203
- it "initializes if not existing" do
204
- new_friend = User.create(:ssn => '555-00-1928')
205
- new_friendship = Friendship.first_or_new_by_user_ids([user1.id, new_friend.id])
206
- new_friendship.user_ids.sort.should == [user1.id, new_friend.id].sort
207
- new_friendship.should_not be_persisted
208
- end
209
-
210
- it "returns if existing" do
211
- Friendship.first_or_new_by_user_ids([user1.id, user2.id]).should == friendship
212
- Friendship.first_or_new_by_user_ids([user2.id, user1.id]).should == friendship
213
- end
214
- end
215
-
216
- describe "first or create by index" do
217
- it "creates if not existing" do
218
- new_friend = User.create(:ssn => '555-00-1928')
219
- new_friendship = Friendship.first_or_create_by_user_ids([user1.id, new_friend.id])
220
- new_friendship.user_ids.sort.should == [user1.id, new_friend.id].sort
221
- new_friendship.should be_persisted
222
- end
223
-
224
- it "returns if existing" do
225
- Friendship.first_or_create_by_user_ids([user1.id, user2.id]).should == friendship
226
- Friendship.first_or_create_by_user_ids([user2.id, user1.id]).should == friendship
227
- end
228
- end
229
- end
230
- end
@@ -1,141 +0,0 @@
1
- require 'helper'
2
-
3
- describe Toy::Indices do
4
- uses_constants('User')
5
-
6
- it "defaults lists to empty hash" do
7
- User.indices.should == {}
8
- end
9
-
10
- describe "declaring a list" do
11
- before do
12
- User.attribute :ssn, String
13
- @index = User.index(:ssn)
14
- end
15
-
16
- it "knows about its lists" do
17
- User.indices[:ssn].should == Toy::Index.new(User, :ssn)
18
- end
19
-
20
- it "returns list" do
21
- @index.should == Toy::Index.new(User, :ssn)
22
- end
23
-
24
- it "adds indices instance method" do
25
- User.new.indices.should == User.indices
26
- end
27
- end
28
-
29
- describe ".index_key" do
30
- it "returns key if index exists" do
31
- sha = Digest::SHA1.hexdigest('taco@bell.com')
32
- User.attribute(:email, String)
33
- User.index(:email)
34
- User.index_key(:email, 'taco@bell.com').should == "User:email:#{sha}"
35
- end
36
-
37
- it "works with string name" do
38
- sha = Digest::SHA1.hexdigest('taco@bell.com')
39
- User.attribute(:email, String)
40
- User.index(:email)
41
- User.index_key('email', 'taco@bell.com').should == "User:email:#{sha}"
42
- end
43
-
44
- it "raises error if index does not exist" do
45
- lambda {
46
- User.index_key(:email, 'taco@bell.com')
47
- }.should raise_error(ArgumentError, 'Index for email does not exist')
48
- end
49
- end
50
-
51
- describe ".get_index (existing)" do
52
- before do
53
- User.attribute(:email, String)
54
- User.index(:email)
55
- User.create_index(:email, 'taco@bell.com', 1)
56
- User.create_index(:email, 'taco@bell.com', 2)
57
- @index = User.get_index(:email, 'taco@bell.com')
58
- end
59
-
60
- it "returns decoded array" do
61
- @index.should == [1, 2]
62
- end
63
- end
64
-
65
- describe ".get_index (missing)" do
66
- before do
67
- User.attribute(:email, String)
68
- User.index(:email)
69
- @index = User.get_index(:email, 'taco@bell.com')
70
- end
71
-
72
- it "returns empty array" do
73
- @index.should == []
74
- end
75
- end
76
-
77
- describe ".create_index (single value)" do
78
- before do
79
- User.attribute(:email, String)
80
- User.index(:email)
81
- User.create_index(:email, 'taco@bell.com', 1)
82
- end
83
-
84
- it "stores id in array" do
85
- User.get_index(:email, 'taco@bell.com').should == [1]
86
- end
87
- end
88
-
89
- describe ".create_index (multiple values)" do
90
- before do
91
- User.attribute(:email, String)
92
- User.index(:email)
93
- User.create_index(:email, 'taco@bell.com', 1)
94
- User.create_index(:email, 'taco@bell.com', 2)
95
- User.create_index(:email, 'taco@bell.com', 3)
96
- end
97
-
98
- it "stores each value in array" do
99
- User.get_index(:email, 'taco@bell.com').should == [1, 2, 3]
100
- end
101
- end
102
-
103
- describe ".create_index (same value multiple times)" do
104
- before do
105
- User.attribute(:email, String)
106
- User.index(:email)
107
- User.create_index(:email, 'taco@bell.com', 1)
108
- User.create_index(:email, 'taco@bell.com', 2)
109
- User.create_index(:email, 'taco@bell.com', 1)
110
- end
111
-
112
- it "stores value only once and doesn't change order" do
113
- User.get_index(:email, 'taco@bell.com').should == [1, 2]
114
- end
115
- end
116
-
117
- describe ".destroy_index (for missing index)" do
118
- before do
119
- User.attribute(:email, String)
120
- User.index(:email)
121
- User.destroy_index(:email, 'taco@bell.com', 1)
122
- end
123
-
124
- it "sets index to empty array" do
125
- User.get_index(:email, 'taco@bell.com').should == []
126
- end
127
- end
128
-
129
- describe ".destroy_index (for indexed id)" do
130
- before do
131
- User.attribute(:email, String)
132
- User.index(:email)
133
- User.create_index(:email, 'taco@bell.com', 1)
134
- User.destroy_index(:email, 'taco@bell.com', 1)
135
- end
136
-
137
- it "removes the value from the index" do
138
- User.get_index(:email, 'taco@bell.com').should == []
139
- end
140
- end
141
- end