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
@@ -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