jmonteiro-mongo_mapper 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/.gitignore +10 -0
  2. data/LICENSE +20 -0
  3. data/README.rdoc +38 -0
  4. data/Rakefile +55 -0
  5. data/VERSION +1 -0
  6. data/bin/mmconsole +60 -0
  7. data/jmonteiro-mongo_mapper.gemspec +195 -0
  8. data/lib/mongo_mapper.rb +128 -0
  9. data/lib/mongo_mapper/descendant_appends.rb +44 -0
  10. data/lib/mongo_mapper/document.rb +402 -0
  11. data/lib/mongo_mapper/dynamic_finder.rb +74 -0
  12. data/lib/mongo_mapper/embedded_document.rb +61 -0
  13. data/lib/mongo_mapper/finder_options.rb +127 -0
  14. data/lib/mongo_mapper/plugins.rb +19 -0
  15. data/lib/mongo_mapper/plugins/associations.rb +104 -0
  16. data/lib/mongo_mapper/plugins/associations/base.rb +121 -0
  17. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +28 -0
  18. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +23 -0
  19. data/lib/mongo_mapper/plugins/associations/collection.rb +21 -0
  20. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +49 -0
  21. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +139 -0
  22. data/lib/mongo_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  23. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +117 -0
  24. data/lib/mongo_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +31 -0
  25. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +23 -0
  26. data/lib/mongo_mapper/plugins/associations/many_polymorphic_proxy.rb +13 -0
  27. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +66 -0
  28. data/lib/mongo_mapper/plugins/associations/proxy.rb +118 -0
  29. data/lib/mongo_mapper/plugins/callbacks.rb +65 -0
  30. data/lib/mongo_mapper/plugins/clone.rb +13 -0
  31. data/lib/mongo_mapper/plugins/descendants.rb +16 -0
  32. data/lib/mongo_mapper/plugins/dirty.rb +119 -0
  33. data/lib/mongo_mapper/plugins/equality.rb +11 -0
  34. data/lib/mongo_mapper/plugins/identity_map.rb +66 -0
  35. data/lib/mongo_mapper/plugins/inspect.rb +14 -0
  36. data/lib/mongo_mapper/plugins/keys.rb +295 -0
  37. data/lib/mongo_mapper/plugins/logger.rb +17 -0
  38. data/lib/mongo_mapper/plugins/pagination.rb +85 -0
  39. data/lib/mongo_mapper/plugins/protected.rb +31 -0
  40. data/lib/mongo_mapper/plugins/rails.rb +80 -0
  41. data/lib/mongo_mapper/plugins/serialization.rb +109 -0
  42. data/lib/mongo_mapper/plugins/validations.rb +48 -0
  43. data/lib/mongo_mapper/support.rb +213 -0
  44. data/performance/read_write.rb +52 -0
  45. data/specs.watchr +51 -0
  46. data/test/NOTE_ON_TESTING +1 -0
  47. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +63 -0
  48. data/test/functional/associations/test_belongs_to_proxy.rb +93 -0
  49. data/test/functional/associations/test_in_array_proxy.rb +309 -0
  50. data/test/functional/associations/test_many_documents_as_proxy.rb +246 -0
  51. data/test/functional/associations/test_many_documents_proxy.rb +437 -0
  52. data/test/functional/associations/test_many_embedded_polymorphic_proxy.rb +175 -0
  53. data/test/functional/associations/test_many_embedded_proxy.rb +216 -0
  54. data/test/functional/associations/test_many_polymorphic_proxy.rb +340 -0
  55. data/test/functional/associations/test_one_proxy.rb +149 -0
  56. data/test/functional/test_associations.rb +44 -0
  57. data/test/functional/test_binary.rb +27 -0
  58. data/test/functional/test_callbacks.rb +81 -0
  59. data/test/functional/test_dirty.rb +156 -0
  60. data/test/functional/test_document.rb +1171 -0
  61. data/test/functional/test_embedded_document.rb +125 -0
  62. data/test/functional/test_identity_map.rb +233 -0
  63. data/test/functional/test_logger.rb +20 -0
  64. data/test/functional/test_modifiers.rb +252 -0
  65. data/test/functional/test_pagination.rb +93 -0
  66. data/test/functional/test_protected.rb +41 -0
  67. data/test/functional/test_string_id_compatibility.rb +67 -0
  68. data/test/functional/test_validations.rb +329 -0
  69. data/test/models.rb +232 -0
  70. data/test/support/custom_matchers.rb +55 -0
  71. data/test/support/timing.rb +16 -0
  72. data/test/test_helper.rb +60 -0
  73. data/test/unit/associations/test_base.rb +207 -0
  74. data/test/unit/associations/test_proxy.rb +103 -0
  75. data/test/unit/serializers/test_json_serializer.rb +189 -0
  76. data/test/unit/test_descendant_appends.rb +71 -0
  77. data/test/unit/test_document.rb +203 -0
  78. data/test/unit/test_dynamic_finder.rb +125 -0
  79. data/test/unit/test_embedded_document.rb +628 -0
  80. data/test/unit/test_finder_options.rb +325 -0
  81. data/test/unit/test_keys.rb +169 -0
  82. data/test/unit/test_mongo_mapper.rb +65 -0
  83. data/test/unit/test_pagination.rb +127 -0
  84. data/test/unit/test_plugins.rb +42 -0
  85. data/test/unit/test_rails.rb +139 -0
  86. data/test/unit/test_rails_compatibility.rb +42 -0
  87. data/test/unit/test_serialization.rb +51 -0
  88. data/test/unit/test_support.rb +350 -0
  89. data/test/unit/test_time_zones.rb +39 -0
  90. data/test/unit/test_validations.rb +492 -0
  91. metadata +260 -0
@@ -0,0 +1,125 @@
1
+ require 'test_helper'
2
+ require 'models'
3
+
4
+ class EmbeddedDocumentTest < Test::Unit::TestCase
5
+ def setup
6
+ @klass = Doc do
7
+ key :first_name, String
8
+ key :last_name, String
9
+ end
10
+
11
+ @pet_klass = EDoc do
12
+ key :name, String
13
+ end
14
+
15
+ @klass.many :pets, :class => @pet_klass
16
+
17
+ @address_class = EDoc do
18
+ key :city, String
19
+ key :state, String
20
+ end
21
+ end
22
+
23
+ context "Saving a document with an embedded document" do
24
+ setup do
25
+ @klass.key :foo, @address_class
26
+
27
+ @address = @address_class.new(:city => 'South Bend', :state => 'IN')
28
+ @doc = @klass.new(:foo => @address)
29
+ end
30
+
31
+ should "embed embedded document" do
32
+ @doc.save
33
+ @doc.foo.city.should == 'South Bend'
34
+ @doc.foo.state.should == 'IN'
35
+
36
+ doc = @doc.reload
37
+ doc.foo.city.should == 'South Bend'
38
+ doc.foo.state.should == 'IN'
39
+ end
40
+ end
41
+
42
+ should "correctly instantiate single collection inherited embedded documents" do
43
+ document = Doc('Foo') do
44
+ key :message, Message
45
+ end
46
+
47
+ doc1 = document.create(:message => Enter.new)
48
+ doc1.reload.message.class.should be(Enter)
49
+ end
50
+
51
+ context "new?" do
52
+ setup do
53
+ @klass.key :foo, @address_class
54
+ end
55
+
56
+ should "be new until document is saved" do
57
+ address = @address_class.new(:city => 'South Bend', :state => 'IN')
58
+ doc = @klass.new(:foo => address)
59
+ address.new?.should == true
60
+ end
61
+
62
+ should "not be new after document is saved" do
63
+ address = @address_class.new(:city => 'South Bend', :state => 'IN')
64
+ doc = @klass.new(:foo => address)
65
+ doc.save
66
+ doc.foo.new?.should == false
67
+ end
68
+
69
+ should "not be new when document is read back" do
70
+ address = @address_class.new(:city => 'South Bend', :state => 'IN')
71
+ doc = @klass.new(:foo => address)
72
+ doc.save
73
+
74
+ doc = doc.reload
75
+ doc.foo.new?.should == false
76
+ end
77
+ end
78
+
79
+ should "be able to save" do
80
+ person = @klass.create
81
+
82
+ pet = @pet_klass.new(:name => 'sparky')
83
+ person.pets << pet
84
+ pet.should be_new
85
+ pet.save
86
+ pet.should_not be_new
87
+
88
+ person.reload
89
+ person.pets.first.should == pet
90
+ end
91
+
92
+ should "be able to dynamically add new keys and save" do
93
+ person = @klass.create
94
+
95
+ pet = @pet_klass.new(:name => 'sparky', :crazy_key => 'crazy')
96
+ person.pets << pet
97
+ pet.save
98
+
99
+ person.reload
100
+ person.pets.first.crazy_key.should == 'crazy'
101
+ end
102
+
103
+ should "be able to update_attributes" do
104
+ pet = @pet_klass.new(:name => 'sparky')
105
+ person = @klass.create(:pets => [pet])
106
+ person.reload
107
+ pet = person.pets.first
108
+
109
+ pet.update_attributes(:name => 'koda').should be_true
110
+ person.reload
111
+ person.pets.first._id.should == pet._id
112
+ person.pets.first.name.should == 'koda'
113
+ end
114
+
115
+ should "be able to update_attributes!" do
116
+ person = @klass.create(:pets => [@pet_klass.new(:name => 'sparky')])
117
+ person.reload
118
+ pet = person.pets.first
119
+
120
+ attributes = {:name => 'koda'}
121
+ pet.expects(:attributes=).with(attributes)
122
+ pet.expects(:save!)
123
+ pet.update_attributes!(attributes)
124
+ end
125
+ end
@@ -0,0 +1,233 @@
1
+ require 'test_helper'
2
+
3
+ class IdentityMapTest < Test::Unit::TestCase
4
+ def assert_in_map(resource)
5
+ resource.identity_map.keys.should include(resource.identity_map_key)
6
+ mapped_resource = resource.identity_map[resource.identity_map_key]
7
+ resource.object_id.should == mapped_resource.object_id
8
+ end
9
+
10
+ def assert_not_in_map(resource)
11
+ resource.identity_map.keys.should_not include(resource.identity_map_key)
12
+ end
13
+
14
+ context "Document" do
15
+ setup do
16
+ @person_class = Doc('Person') do
17
+ key :name, String
18
+ plugin MongoMapper::Plugins::IdentityMap
19
+ end
20
+
21
+ @post_class = Doc('Post') do
22
+ key :title, String
23
+ plugin MongoMapper::Plugins::IdentityMap
24
+ end
25
+
26
+ @person_class.identity_map = {}
27
+ @post_class.identity_map = {}
28
+ end
29
+
30
+ should "default identity map to hash" do
31
+ Doc() do
32
+ plugin MongoMapper::Plugins::IdentityMap
33
+ end.identity_map.should == {}
34
+ end
35
+
36
+ should "share identity map with other classes" do
37
+ map = @post_class.identity_map
38
+ map.object_id.should == @person_class.identity_map.object_id
39
+ end
40
+
41
+ should "have identity map key that is always unique per document and class" do
42
+ person = @person_class.new
43
+ person.identity_map_key.should == "Person:#{person.id}"
44
+ @person_class.identity_map_key(person.id).should == person.identity_map_key
45
+
46
+ post = @post_class.new
47
+ post.identity_map_key.should == "Post:#{post.id}"
48
+ @post_class.identity_map_key(post.id).should == post.identity_map_key
49
+
50
+ person.identity_map_key.should_not == post.identity_map_key
51
+ end
52
+
53
+ should "add key to map when saved" do
54
+ person = @person_class.new
55
+ assert_not_in_map(person)
56
+ person.save.should be_true
57
+ assert_in_map(person)
58
+ end
59
+
60
+ should "remove key from map when deleted" do
61
+ person = @person_class.create(:name => 'Fred')
62
+ assert_in_map(person)
63
+ person.destroy
64
+ assert_not_in_map(person)
65
+ end
66
+
67
+ context "#load" do
68
+ setup do
69
+ @id = Mongo::ObjectID.new
70
+ end
71
+
72
+ should "add document to map with _id key as symbol" do
73
+ loaded = @person_class.load({:_id => @id, :name => 'Frank'})
74
+ assert_in_map(loaded)
75
+ end
76
+
77
+ should "add document to map with _id key as string" do
78
+ loaded = @person_class.load({'_id' => @id, :name => 'Frank'})
79
+ assert_in_map(loaded)
80
+ end
81
+
82
+ should "add document to map with id key as symbol" do
83
+ loaded = @person_class.load({:id => @id, :name => 'Frank'})
84
+ assert_in_map(loaded)
85
+ end
86
+
87
+ should "add document to map with id key as string" do
88
+ loaded = @person_class.load({'id' => @id, :name => 'Frank'})
89
+ assert_in_map(loaded)
90
+ end
91
+
92
+ should "return document if already in map" do
93
+ first_load = @person_class.load({:_id => @id, :name => 'Frank'})
94
+ @person_class.identity_map.expects(:[]=).never
95
+ second_load = @person_class.load({:_id => @id, :name => 'Frank'})
96
+ first_load.object_id.should == second_load.object_id
97
+ end
98
+ end
99
+
100
+ context "#find (with one id)" do
101
+ context "for object not in map" do
102
+ setup do
103
+ @person = @person_class.create(:name => 'Fred')
104
+ @person_class.identity_map.clear
105
+ end
106
+
107
+ should "query the database" do
108
+ Mongo::Collection.any_instance.expects(:find_one).once
109
+ @person_class.find(@person.id)
110
+ end
111
+
112
+ should "add object to map" do
113
+ assert_not_in_map(@person)
114
+ found_person = @person_class.find(@person.id)
115
+ assert_in_map(found_person)
116
+ end
117
+ end
118
+
119
+ context "for object in map" do
120
+ setup do
121
+ @person = @person_class.create(:name => 'Fred')
122
+ end
123
+
124
+ should "not query database" do
125
+ Mongo::Collection.any_instance.expects(:find).never
126
+ Mongo::Collection.any_instance.expects(:find_one).never
127
+ @person_class.find(@person.id)
128
+ end
129
+
130
+ should "return exact object" do
131
+ assert_in_map(@person)
132
+ found_person = @person_class.find(@person.id)
133
+ found_person.object_id.should == @person.object_id
134
+ end
135
+ end
136
+ end
137
+
138
+ context "#find (with multiple ids)" do
139
+ should "add all documents to map" do
140
+ person1 = @person_class.create(:name => 'Fred')
141
+ person2 = @person_class.create(:name => 'Bill')
142
+ person3 = @person_class.create(:name => 'Jesse')
143
+ @person_class.identity_map.clear
144
+
145
+ people = @person_class.find(person1.id, person2.id, person3.id)
146
+ people.each { |person| assert_in_map(person) }
147
+ end
148
+
149
+ should "add missing documents to map and return existing ones" do
150
+ person1 = @person_class.create(:name => 'Fred')
151
+ @person_class.identity_map.clear
152
+ person2 = @person_class.create(:name => 'Bill')
153
+ person3 = @person_class.create(:name => 'Jesse')
154
+
155
+ assert_not_in_map(person1)
156
+ assert_in_map(person2)
157
+ assert_in_map(person3)
158
+
159
+ people = @person_class.find(person1.id, person2.id, person3.id)
160
+ assert_in_map(people.first) # making sure one that wasn't mapped now is
161
+ assert_in_map(person2)
162
+ assert_in_map(person3)
163
+ end
164
+ end
165
+
166
+ context "#first" do
167
+ context "for object not in map" do
168
+ setup do
169
+ @person = @person_class.create(:name => 'Fred')
170
+ @person_class.identity_map.clear
171
+ end
172
+
173
+ should "query the database" do
174
+ Mongo::Collection.any_instance.expects(:find_one).once
175
+ @person_class.first(:_id => @person.id)
176
+ end
177
+
178
+ should "add object to map" do
179
+ assert_not_in_map(@person)
180
+ found_person = @person_class.first(:_id => @person.id)
181
+ assert_in_map(found_person)
182
+ end
183
+ end
184
+
185
+ context "for object in map" do
186
+ setup do
187
+ @person = @person_class.create(:name => 'Fred')
188
+ end
189
+
190
+ should "not query database" do
191
+ Mongo::Collection.any_instance.expects(:find).never
192
+ Mongo::Collection.any_instance.expects(:find_one).never
193
+ @person_class.first(:_id => @person.id)
194
+ end
195
+
196
+ should "return exact object" do
197
+ assert_in_map(@person)
198
+ found_person = @person_class.first(:_id => @person.id)
199
+ found_person.object_id.should == @person.object_id
200
+ end
201
+ end
202
+ end
203
+
204
+ context "#all" do
205
+ should "add all documents to map" do
206
+ person1 = @person_class.create(:name => 'Fred')
207
+ person2 = @person_class.create(:name => 'Bill')
208
+ person3 = @person_class.create(:name => 'Jesse')
209
+ @person_class.identity_map.clear
210
+
211
+ people = @person_class.all(:_id => [person1.id, person2.id, person3.id])
212
+ people.each { |person| assert_in_map(person) }
213
+ end
214
+
215
+ should "add missing documents to map and return existing ones" do
216
+ person1 = @person_class.create(:name => 'Fred')
217
+ @person_class.identity_map.clear
218
+ person2 = @person_class.create(:name => 'Bill')
219
+ person3 = @person_class.create(:name => 'Jesse')
220
+
221
+ assert_not_in_map(person1)
222
+ assert_in_map(person2)
223
+ assert_in_map(person3)
224
+
225
+ people = @person_class.all(:_id => [person1.id, person2.id, person3.id])
226
+ assert_in_map(people.first) # making sure one that wasn't mapped now is
227
+ assert_in_map(person2)
228
+ assert_in_map(person3)
229
+ end
230
+ end
231
+
232
+ end
233
+ end
@@ -0,0 +1,20 @@
1
+ require 'test_helper'
2
+
3
+ class LoggerTest < Test::Unit::TestCase
4
+ context "with connection that has logger" do
5
+ setup do
6
+ @output = StringIO.new
7
+ @logger = Logger.new(@output)
8
+ MongoMapper.connection = Mongo::Connection.new('127.0.0.1', 27017, :logger => @logger)
9
+ end
10
+
11
+ should "be able to get access to that logger" do
12
+ MongoMapper.logger.should == @logger
13
+ end
14
+
15
+ should "be able to log messages" do
16
+ MongoMapper.logger.debug 'testing'
17
+ @output.string.include?('testing').should be_true
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,252 @@
1
+ require 'test_helper'
2
+
3
+ class ModifierTest < Test::Unit::TestCase
4
+ def setup
5
+ @page_class = Doc do
6
+ key :title, String
7
+ key :day_count, Integer, :default => 0
8
+ key :week_count, Integer, :default => 0
9
+ key :month_count, Integer, :default => 0
10
+ key :tags, Array
11
+ end
12
+ end
13
+
14
+ def assert_page_counts(page, day_count, week_count, month_count)
15
+ page.reload
16
+ page.day_count.should == day_count
17
+ page.week_count.should == week_count
18
+ page.month_count.should == month_count
19
+ end
20
+
21
+ should "be able to increment with criteria and modifier hashes" do
22
+ page = @page_class.create(:title => 'Home')
23
+ page2 = @page_class.create(:title => 'Home')
24
+
25
+ @page_class.increment({:title => 'Home'}, {
26
+ :day_count => 1, :week_count => 2, :month_count => 3
27
+ })
28
+
29
+ assert_page_counts page, 1, 2, 3
30
+ assert_page_counts page2, 1, 2, 3
31
+ end
32
+
33
+ should "be able to increment with ids and modifier hash" do
34
+ page = @page_class.create(:title => 'Home')
35
+ page2 = @page_class.create(:title => 'Home')
36
+
37
+ @page_class.increment(page.id, page2.id, {
38
+ :day_count => 1, :week_count => 2, :month_count => 3
39
+ })
40
+
41
+ assert_page_counts page, 1, 2, 3
42
+ assert_page_counts page2, 1, 2, 3
43
+ end
44
+
45
+ should "be able to decrement with criteria and modifier hashes" do
46
+ page = @page_class.create(:title => 'Home', :day_count => 1, :week_count => 2, :month_count => 3)
47
+ page2 = @page_class.create(:title => 'Home', :day_count => 1, :week_count => 2, :month_count => 3)
48
+
49
+ @page_class.decrement({:title => 'Home'}, {
50
+ :day_count => 1, :week_count => 2, :month_count => 3
51
+ })
52
+
53
+ assert_page_counts page, 0, 0, 0
54
+ assert_page_counts page2, 0, 0, 0
55
+ end
56
+
57
+ should "be able to decrement with ids and modifier hash" do
58
+ page = @page_class.create(:title => 'Home', :day_count => 1, :week_count => 2, :month_count => 3)
59
+ page2 = @page_class.create(:title => 'Home', :day_count => 1, :week_count => 2, :month_count => 3)
60
+
61
+ @page_class.decrement(page.id, page2.id, {
62
+ :day_count => 1, :week_count => 2, :month_count => 3
63
+ })
64
+
65
+ assert_page_counts page, 0, 0, 0
66
+ assert_page_counts page2, 0, 0, 0
67
+ end
68
+
69
+ should "always decrement when decrement is called whether number is positive or negative" do
70
+ page = @page_class.create(:title => 'Home', :day_count => 1, :week_count => 2, :month_count => 3)
71
+ page2 = @page_class.create(:title => 'Home', :day_count => 1, :week_count => 2, :month_count => 3)
72
+
73
+ @page_class.decrement(page.id, page2.id, {
74
+ :day_count => -1, :week_count => 2, :month_count => -3
75
+ })
76
+
77
+ assert_page_counts page, 0, 0, 0
78
+ assert_page_counts page2, 0, 0, 0
79
+ end
80
+
81
+ should "be able to set with criteria and modifier hashes" do
82
+ page = @page_class.create(:title => 'Home')
83
+ page2 = @page_class.create(:title => 'Home')
84
+
85
+ @page_class.set({:title => 'Home'}, :title => 'Home Revised')
86
+
87
+ page.reload
88
+ page.title.should == 'Home Revised'
89
+
90
+ page2.reload
91
+ page2.title.should == 'Home Revised'
92
+ end
93
+
94
+ should "be able to set with ids and modifier hash" do
95
+ page = @page_class.create(:title => 'Home')
96
+ page2 = @page_class.create(:title => 'Home')
97
+
98
+ @page_class.set(page.id, page2.id, :title => 'Home Revised')
99
+
100
+ page.reload
101
+ page.title.should == 'Home Revised'
102
+
103
+ page2.reload
104
+ page2.title.should == 'Home Revised'
105
+ end
106
+
107
+ should "be able to push with criteria and modifier hashes" do
108
+ page = @page_class.create(:title => 'Home')
109
+ page2 = @page_class.create(:title => 'Home')
110
+
111
+ @page_class.push({:title => 'Home'}, :tags => 'foo')
112
+
113
+ page.reload
114
+ page.tags.should == %w(foo)
115
+
116
+ page2.reload
117
+ page.tags.should == %w(foo)
118
+ end
119
+
120
+ should "be able to push with ids and modifier hash" do
121
+ page = @page_class.create(:title => 'Home')
122
+ page2 = @page_class.create(:title => 'Home')
123
+
124
+ @page_class.push(page.id, page2.id, :tags => 'foo')
125
+
126
+ page.reload
127
+ page.tags.should == %w(foo)
128
+
129
+ page2.reload
130
+ page.tags.should == %w(foo)
131
+ end
132
+
133
+ should "be able to push all with criteria and modifier hashes" do
134
+ page = @page_class.create(:title => 'Home')
135
+ page2 = @page_class.create(:title => 'Home')
136
+ tags = %w(foo bar)
137
+
138
+ @page_class.push_all({:title => 'Home'}, :tags => tags)
139
+
140
+ page.reload
141
+ page.tags.should == tags
142
+
143
+ page2.reload
144
+ page.tags.should == tags
145
+ end
146
+
147
+ should "be able to push all with ids and modifier hash" do
148
+ page = @page_class.create(:title => 'Home')
149
+ page2 = @page_class.create(:title => 'Home')
150
+ tags = %w(foo bar)
151
+
152
+ @page_class.push_all(page.id, page2.id, :tags => tags)
153
+
154
+ page.reload
155
+ page.tags.should == tags
156
+
157
+ page2.reload
158
+ page.tags.should == tags
159
+ end
160
+
161
+ should "be able to pull with criteria and modifier hashes" do
162
+ page = @page_class.create(:title => 'Home', :tags => %w(foo bar))
163
+ page2 = @page_class.create(:title => 'Home', :tags => %w(foo bar))
164
+
165
+ @page_class.pull({:title => 'Home'}, :tags => 'foo')
166
+
167
+ page.reload
168
+ page.tags.should == %w(bar)
169
+
170
+ page2.reload
171
+ page.tags.should == %w(bar)
172
+ end
173
+
174
+ should "be able to pull with ids and modifier hash" do
175
+ page = @page_class.create(:title => 'Home', :tags => %w(foo bar))
176
+ page2 = @page_class.create(:title => 'Home', :tags => %w(foo bar))
177
+
178
+ @page_class.pull(page.id, page2.id, :tags => 'foo')
179
+
180
+ page.reload
181
+ page.tags.should == %w(bar)
182
+
183
+ page2.reload
184
+ page.tags.should == %w(bar)
185
+ end
186
+
187
+ should "be able to pull all with criteria and modifier hashes" do
188
+ page = @page_class.create(:title => 'Home', :tags => %w(foo bar baz))
189
+ page2 = @page_class.create(:title => 'Home', :tags => %w(foo bar baz))
190
+
191
+ @page_class.pull_all({:title => 'Home'}, :tags => %w(foo bar))
192
+
193
+ page.reload
194
+ page.tags.should == %w(baz)
195
+
196
+ page2.reload
197
+ page.tags.should == %w(baz)
198
+ end
199
+
200
+ should "be able to pull all with ids and modifier hash" do
201
+ page = @page_class.create(:title => 'Home', :tags => %w(foo bar baz))
202
+ page2 = @page_class.create(:title => 'Home', :tags => %w(foo bar baz))
203
+
204
+ @page_class.pull_all(page.id, page2.id, :tags => %w(foo bar))
205
+
206
+ page.reload
207
+ page.tags.should == %w(baz)
208
+
209
+ page2.reload
210
+ page.tags.should == %w(baz)
211
+ end
212
+
213
+ should "be able to push uniq with criteria and modifier hash" do
214
+ page = @page_class.create(:title => 'Home', :tags => 'foo')
215
+ page2 = @page_class.create(:title => 'Home')
216
+
217
+ @page_class.push_uniq({:title => 'Home'}, :tags => 'foo')
218
+
219
+ page.reload
220
+ page.tags.should == %w(foo)
221
+
222
+ page2.reload
223
+ page.tags.should == %w(foo)
224
+ end
225
+
226
+ should "be able to push uniq with ids and modifier hash" do
227
+ page = @page_class.create(:title => 'Home', :tags => 'foo')
228
+ page2 = @page_class.create(:title => 'Home')
229
+
230
+ @page_class.push_uniq(page.id, page2.id, :tags => 'foo')
231
+
232
+ page.reload
233
+ page.tags.should == %w(foo)
234
+
235
+ page2.reload
236
+ page.tags.should == %w(foo)
237
+ end
238
+
239
+ should "be able to remove the last element the array" do
240
+ page = @page_class.create(:title => 'Home', :tags => %w(foo bar))
241
+ @page_class.pop(page.id, :tags => 1)
242
+ page.reload
243
+ page.tags.should == %w(foo)
244
+ end
245
+
246
+ should "be able to remove the first element of the array" do
247
+ page = @page_class.create(:title => 'Home', :tags => %w(foo bar))
248
+ @page_class.pop(page.id, :tags => -1)
249
+ page.reload
250
+ page.tags.should == %w(bar)
251
+ end
252
+ end