jmonteiro-mongo_mapper 0.1.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 (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