toystore 0.8.3 → 0.9.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.
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