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
@@ -24,7 +24,7 @@ module CallbackHelper
24
24
  end
25
25
 
26
26
  describe Toy::Callbacks do
27
- uses_constants('Game', 'Move')
27
+ uses_constants('Game')
28
28
 
29
29
  context "regular" do
30
30
  before do
@@ -50,48 +50,4 @@ describe Toy::Callbacks do
50
50
  doc.history.should == [:before_destroy, :after_destroy]
51
51
  end
52
52
  end
53
-
54
- context "embedded" do
55
- before do
56
- Game.embedded_list(:moves)
57
- Move.send(:include, CallbackHelper)
58
-
59
- @move = Move.new
60
- @game = Game.create(:moves => [@move])
61
- end
62
-
63
- it "runs callbacks for save of parent" do
64
- @move.history.should == [:before_save, :before_create, :after_create, :after_save]
65
- end
66
-
67
- it "runs callbacks for update of parent" do
68
- @move.clear_history
69
- @game.save
70
- @move.history.should == [:before_save, :before_update, :after_update, :after_save]
71
- end
72
-
73
- it "runs callbacks for destroy of parent" do
74
- @move.clear_history
75
- @game.destroy
76
- @move.history.should == [:before_destroy, :after_destroy]
77
- end
78
-
79
- it "does not attempt to run callback defined on parent that is not defined on embedded" do
80
- Game.define_callbacks :win
81
- @move.clear_history
82
-
83
- lambda do
84
- @game.run_callbacks(:win)
85
- @move.history.should be_empty
86
- end.should_not raise_error
87
- end
88
-
89
- it "runs create callback when saving new embbeded doc on existing parent" do
90
- @game.save
91
- move = Move.new
92
- @game.moves << move
93
- @game.save
94
- move.history.should == [:before_save, :before_create, :after_create, :after_save]
95
- end
96
- end
97
53
  end
@@ -0,0 +1,47 @@
1
+ require 'helper'
2
+
3
+ describe Toy::Cloneable do
4
+ uses_objects('User')
5
+
6
+ before do
7
+ User.attribute(:name, String)
8
+ User.attribute(:skills, Array)
9
+
10
+ @user = User.new({
11
+ :name => 'John',
12
+ :skills => ['looking awesome', 'growing beards'],
13
+ })
14
+ end
15
+ let(:user) { @user }
16
+
17
+ describe "#clone" do
18
+ it "clones the @attributes hash" do
19
+ user.clone.instance_variable_get("@attributes").should_not equal(user.instance_variable_get("@attributes"))
20
+ end
21
+
22
+ it "copies the attributes" do
23
+ user.clone.tap do |clone|
24
+ clone.name.should == user.name
25
+ clone.skills.should == user.skills
26
+ end
27
+ end
28
+
29
+ it "clones duplicable attributes" do
30
+ user.clone.skills.should_not equal(user.skills)
31
+ end
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
+ it "nullifies defined instance variables" do
41
+ user.instance_variable_set("@foo", true)
42
+ user.clone.tap do |clone|
43
+ clone.instance_variable_get("@foo").should be_nil
44
+ end
45
+ end
46
+ end
47
+ end
@@ -1,7 +1,7 @@
1
1
  require 'helper'
2
2
 
3
3
  describe Toy::Dirty do
4
- uses_constants('User')
4
+ uses_objects('User')
5
5
 
6
6
  before do
7
7
  User.attribute(:name, String)
@@ -29,49 +29,11 @@ describe Toy::Dirty do
29
29
  end
30
30
 
31
31
  it "knows when attribute did not change" do
32
- user = User.create(:name => 'Geoffrey')
33
- user.name = 'Geoffrey'
32
+ user = User.new
33
+ user.name = nil
34
34
  user.should_not be_changed
35
35
  end
36
36
 
37
- describe "#save" do
38
- before { @user = User.create(:name => 'Geoffrey') }
39
- let(:user) { @user }
40
-
41
- it "clears changes" do
42
- user.name = 'John'
43
- user.should be_changed
44
- user.save
45
- user.should_not be_changed
46
- end
47
-
48
- it "sets previous changes" do
49
- user.previous_changes.should == {'name' => [nil, 'Geoffrey']}
50
- end
51
- end
52
-
53
- it "does not have changes when loaded from database" do
54
- user = User.create
55
- loaded = User.get(user.id)
56
- loaded.should_not be_changed
57
- end
58
-
59
- describe "#reload" do
60
- before { @user = User.create(:name => 'John') }
61
- let(:user) { @user }
62
-
63
- it "clears changes" do
64
- user.name = 'Steve'
65
- user.reload
66
- user.should_not be_changed
67
- end
68
-
69
- it "clears previously changed" do
70
- user.reload
71
- user.previous_changes.should be_empty
72
- end
73
- end
74
-
75
37
  it "has attribute changed? method" do
76
38
  user = User.new
77
39
  user.should_not be_name_changed
@@ -80,20 +42,26 @@ describe Toy::Dirty do
80
42
  end
81
43
 
82
44
  it "has attribute was method" do
83
- user = User.create(:name => 'John')
45
+ user = User.new(:name => 'John')
84
46
  user.name = 'Steve'
85
47
  user.name_was.should == 'John'
86
48
  end
87
49
 
88
50
  it "has attribute change method" do
89
- user = User.create(:name => 'John')
51
+ user = User.new(:name => 'John')
90
52
  user.name = 'Steve'
91
53
  user.name_change.should == ['John', 'Steve']
92
54
  end
93
55
 
94
56
  it "has attribute will change! method" do
95
- user = User.create
57
+ user = User.new
96
58
  user.name_will_change!
97
59
  user.should be_changed
98
60
  end
61
+
62
+ describe "#clone" do
63
+ it "has no changes" do
64
+ User.new.clone.should_not be_changed
65
+ end
66
+ end
99
67
  end
@@ -0,0 +1,47 @@
1
+ require 'helper'
2
+
3
+ describe Toy::DirtyStore do
4
+ uses_constants('User')
5
+
6
+ before do
7
+ User.attribute(:name, String)
8
+ end
9
+
10
+ it "does not have changes when loaded from database" do
11
+ user = User.create
12
+ loaded = User.get(user.id)
13
+ loaded.should_not be_changed
14
+ end
15
+
16
+ describe "#reload" do
17
+ before { @user = User.create(:name => 'John') }
18
+ let(:user) { @user }
19
+
20
+ it "clears changes" do
21
+ user.name = 'Steve'
22
+ user.reload
23
+ user.should_not be_changed
24
+ end
25
+
26
+ it "clears previously changed" do
27
+ user.reload
28
+ user.previous_changes.should be_empty
29
+ end
30
+ end
31
+
32
+ describe "#save" do
33
+ before { @user = User.create(:name => 'Geoffrey') }
34
+ let(:user) { @user }
35
+
36
+ it "clears changes" do
37
+ user.name = 'John'
38
+ user.should be_changed
39
+ user.save
40
+ user.should_not be_changed
41
+ end
42
+
43
+ it "sets previous changes" do
44
+ user.previous_changes.should == {'name' => [nil, 'Geoffrey']}
45
+ end
46
+ end
47
+ end
@@ -1,7 +1,7 @@
1
1
  require 'helper'
2
2
 
3
3
  describe Toy::Equality do
4
- uses_constants('User', 'Game', 'Person')
4
+ uses_objects('User', 'Person')
5
5
 
6
6
  describe "#eql?" do
7
7
  it "returns true if same class and id" do
@@ -15,32 +15,18 @@ describe Toy::Equality do
15
15
  it "returns false if different id" do
16
16
  User.new(:id => 1).should_not eql(User.new(:id => 2))
17
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
18
  end
26
19
 
27
20
  describe "equal?" do
28
21
  it "returns true if same object" do
29
- user = User.create(:id => 1)
22
+ user = User.new(:id => 1)
30
23
  user.should equal(user)
31
24
  end
32
25
 
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
26
  it "returns false if not same object" do
43
-
27
+ user = User.new
28
+ other_user = User.new
29
+ user.should_not equal(other_user)
44
30
  end
45
31
  end
46
32
  end
@@ -13,11 +13,13 @@ describe "Boolean.to_store" do
13
13
  Boolean.to_store('true').should be_true
14
14
  Boolean.to_store('t').should be_true
15
15
  Boolean.to_store('1').should be_true
16
+ Boolean.to_store('on').should be_true
16
17
  Boolean.to_store(1).should be_true
17
18
 
18
19
  Boolean.to_store('false').should be_false
19
20
  Boolean.to_store('f').should be_false
20
21
  Boolean.to_store('0').should be_false
22
+ Boolean.to_store('off').should be_false
21
23
  Boolean.to_store(0).should be_false
22
24
  end
23
25
 
@@ -3,11 +3,11 @@ require 'helper'
3
3
  describe Toy::Identity::UUIDKeyFactory do
4
4
  uses_constants('User')
5
5
 
6
- it "should use String as store_type" do
6
+ it "should use String as key_type" do
7
7
  Toy::Identity::UUIDKeyFactory.new.key_type.should be(String)
8
8
  end
9
9
 
10
- it "should use uuid for next key" do
10
+ it "should use uuid for next_key" do
11
11
  Toy::Identity::UUIDKeyFactory.new.next_key(nil).length.should == 36
12
12
  end
13
13
 
@@ -4,17 +4,12 @@ describe Toy::IdentityMap do
4
4
  uses_constants('User', 'Skill')
5
5
 
6
6
  before do
7
- Toy.identity_map.clear
7
+ Toy::IdentityMap.enabled = true
8
+ Toy::IdentityMap.clear
8
9
  end
9
10
 
10
- describe ".identity_map" do
11
- it "defaults to hash" do
12
- User.identity_map.should == {}
13
- end
14
-
15
- it "memoizes" do
16
- User.identity_map.should equal(User.identity_map)
17
- end
11
+ after do
12
+ Toy::IdentityMap.enabled = false
18
13
  end
19
14
 
20
15
  it "adds to map on save" do
@@ -45,7 +40,7 @@ describe Toy::IdentityMap do
45
40
  describe ".get" do
46
41
  it "adds to map if not in map" do
47
42
  user = User.create
48
- user.identity_map.clear
43
+ Toy::IdentityMap.clear
49
44
  user.should_not be_in_identity_map
50
45
  user = User.get(user.id)
51
46
  user.should be_in_identity_map
@@ -60,7 +55,7 @@ describe Toy::IdentityMap do
60
55
  it "does not query if in map" do
61
56
  user = User.create
62
57
  user.should be_in_identity_map
63
- user.store.should_not_receive(:read)
58
+ user.adapter.should_not_receive(:read)
64
59
  User.get(user.id).should equal(user)
65
60
  end
66
61
  end
@@ -69,21 +64,21 @@ describe Toy::IdentityMap do
69
64
  it "forces new query each time and skips the identity map" do
70
65
  user = User.create
71
66
  user.should be_in_identity_map
72
- User.store.should_receive(:read).with(user.id).and_return({})
67
+ User.adapter.should_receive(:read).with(user.id).and_return({})
73
68
  user.reload
74
69
  end
75
70
  end
76
71
 
77
72
  describe "identity map off" do
78
73
  it "does not add to map on save" do
79
- User.identity_map_off
74
+ Toy::IdentityMap.enabled = false
80
75
  user = User.new
81
76
  user.save!
82
77
  user.should_not be_in_identity_map
83
78
  end
84
79
 
85
80
  it "does not add to map on load" do
86
- User.identity_map_off
81
+ Toy::IdentityMap.enabled = false
87
82
  user = User.load('1', 'name' => 'John')
88
83
  user.should_not be_in_identity_map
89
84
  end
@@ -91,7 +86,7 @@ describe Toy::IdentityMap do
91
86
  it "does not remove from map on delete" do
92
87
  user = User.create
93
88
  user.should be_in_identity_map
94
- User.identity_map_off
89
+ Toy::IdentityMap.enabled = false
95
90
  user.delete
96
91
  user.should be_in_identity_map
97
92
  end
@@ -99,14 +94,14 @@ describe Toy::IdentityMap do
99
94
  it "does not remove from map on destroy" do
100
95
  user = User.create
101
96
  user.should be_in_identity_map
102
- User.identity_map_off
97
+ Toy::IdentityMap.enabled = false
103
98
  user.destroy
104
99
  user.should be_in_identity_map
105
100
  end
106
101
 
107
102
  describe ".get" do
108
103
  it "does not add to map if not in map" do
109
- User.identity_map_off
104
+ Toy::IdentityMap.enabled = false
110
105
  user = User.create
111
106
  user.should_not be_in_identity_map
112
107
  user = User.get(user.id)
@@ -116,35 +111,48 @@ describe Toy::IdentityMap do
116
111
  it "does not load from map if in map" do
117
112
  user = User.create
118
113
  user.should be_in_identity_map
119
- User.identity_map_off
120
- user.store.should_receive(:read).with(user.id).and_return(user.persisted_attributes)
114
+ Toy::IdentityMap.enabled = false
115
+ user.adapter.should_receive(:read).with(user.id).and_return(user.persisted_attributes)
121
116
  User.get(user.id)
122
117
  end
123
118
  end
124
119
  end
125
120
 
126
- describe ".without_identity_map" do
127
- describe "with identity map off" do
128
- it "turns identity map off, yields, and returns it to previous state" do
129
- User.identity_map_off
130
- User.should be_identity_map_off
131
- User.without_identity_map do
132
- user = User.create
133
- user.should_not be_in_identity_map
134
- end
135
- User.should be_identity_map_off
121
+ describe ".without" do
122
+ before do
123
+ @user = User.create
124
+ Toy::IdentityMap.clear
125
+ end
126
+ let(:user) { @user }
127
+
128
+ it "skips the map" do
129
+ Toy::IdentityMap.without do
130
+ User.get(user.id).should_not equal(user.id)
131
+ end
132
+ end
133
+ end
134
+
135
+ describe ".use" do
136
+ before do
137
+ @user = User.create
138
+ Toy::IdentityMap.clear
139
+ end
140
+ let(:user) { @user }
141
+
142
+ it "uses the map" do
143
+ Toy::IdentityMap.enabled = false
144
+ Toy::IdentityMap.use do
145
+ User.get(user.id).should equal(User.get(user.id))
136
146
  end
137
147
  end
138
148
 
139
- describe "with identity map on" do
140
- it "turns identity map off, yields, and returns it to previous state" do
141
- User.should be_identity_map_on
142
- User.without_identity_map do
143
- user = User.create
144
- user.should_not be_in_identity_map
145
- end
146
- User.should be_identity_map_on
149
+ it "clears the map" do
150
+ Toy::IdentityMap.enabled = false
151
+ Toy::IdentityMap.repository['hello'] = 'world'
152
+ Toy::IdentityMap.use do
153
+ User.get(user.id)
147
154
  end
155
+ Toy::IdentityMap.repository.should be_empty
148
156
  end
149
157
  end
150
158
  end