kbaum-mongo 0.18.3p

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. data/LICENSE.txt +202 -0
  2. data/README.rdoc +339 -0
  3. data/Rakefile +138 -0
  4. data/bin/bson_benchmark.rb +59 -0
  5. data/bin/fail_if_no_c.rb +11 -0
  6. data/examples/admin.rb +42 -0
  7. data/examples/capped.rb +22 -0
  8. data/examples/cursor.rb +48 -0
  9. data/examples/gridfs.rb +88 -0
  10. data/examples/index_test.rb +126 -0
  11. data/examples/info.rb +31 -0
  12. data/examples/queries.rb +70 -0
  13. data/examples/simple.rb +24 -0
  14. data/examples/strict.rb +35 -0
  15. data/examples/types.rb +36 -0
  16. data/lib/mongo/collection.rb +609 -0
  17. data/lib/mongo/connection.rb +672 -0
  18. data/lib/mongo/cursor.rb +403 -0
  19. data/lib/mongo/db.rb +555 -0
  20. data/lib/mongo/exceptions.rb +66 -0
  21. data/lib/mongo/gridfs/chunk.rb +91 -0
  22. data/lib/mongo/gridfs/grid.rb +79 -0
  23. data/lib/mongo/gridfs/grid_file_system.rb +101 -0
  24. data/lib/mongo/gridfs/grid_io.rb +338 -0
  25. data/lib/mongo/gridfs/grid_store.rb +580 -0
  26. data/lib/mongo/gridfs.rb +25 -0
  27. data/lib/mongo/types/binary.rb +52 -0
  28. data/lib/mongo/types/code.rb +36 -0
  29. data/lib/mongo/types/dbref.rb +40 -0
  30. data/lib/mongo/types/min_max_keys.rb +58 -0
  31. data/lib/mongo/types/objectid.rb +180 -0
  32. data/lib/mongo/types/regexp_of_holding.rb +45 -0
  33. data/lib/mongo/util/bson_c.rb +18 -0
  34. data/lib/mongo/util/bson_ruby.rb +606 -0
  35. data/lib/mongo/util/byte_buffer.rb +222 -0
  36. data/lib/mongo/util/conversions.rb +87 -0
  37. data/lib/mongo/util/ordered_hash.rb +140 -0
  38. data/lib/mongo/util/server_version.rb +69 -0
  39. data/lib/mongo/util/support.rb +26 -0
  40. data/lib/mongo.rb +63 -0
  41. data/mongo-ruby-driver.gemspec +28 -0
  42. data/test/auxillary/autoreconnect_test.rb +42 -0
  43. data/test/binary_test.rb +15 -0
  44. data/test/bson_test.rb +427 -0
  45. data/test/byte_buffer_test.rb +81 -0
  46. data/test/chunk_test.rb +82 -0
  47. data/test/collection_test.rb +515 -0
  48. data/test/connection_test.rb +160 -0
  49. data/test/conversions_test.rb +120 -0
  50. data/test/cursor_test.rb +379 -0
  51. data/test/db_api_test.rb +780 -0
  52. data/test/db_connection_test.rb +16 -0
  53. data/test/db_test.rb +272 -0
  54. data/test/grid_file_system_test.rb +210 -0
  55. data/test/grid_io_test.rb +78 -0
  56. data/test/grid_store_test.rb +334 -0
  57. data/test/grid_test.rb +87 -0
  58. data/test/objectid_test.rb +125 -0
  59. data/test/ordered_hash_test.rb +172 -0
  60. data/test/replica/count_test.rb +34 -0
  61. data/test/replica/insert_test.rb +50 -0
  62. data/test/replica/pooled_insert_test.rb +54 -0
  63. data/test/replica/query_test.rb +39 -0
  64. data/test/slave_connection_test.rb +36 -0
  65. data/test/test_helper.rb +42 -0
  66. data/test/threading/test_threading_large_pool.rb +90 -0
  67. data/test/threading_test.rb +87 -0
  68. data/test/unit/collection_test.rb +61 -0
  69. data/test/unit/connection_test.rb +117 -0
  70. data/test/unit/cursor_test.rb +93 -0
  71. data/test/unit/db_test.rb +98 -0
  72. metadata +127 -0
@@ -0,0 +1,16 @@
1
+ require 'test/test_helper'
2
+
3
+ # NOTE: assumes Mongo is running
4
+ class DBConnectionTest < Test::Unit::TestCase
5
+
6
+ include Mongo
7
+
8
+ def test_no_exceptions
9
+ host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
10
+ port = ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT
11
+ db = Connection.new(host, port).db('ruby-mongo-demo')
12
+ coll = db.collection('test')
13
+ coll.remove
14
+ db.error
15
+ end
16
+ end
data/test/db_test.rb ADDED
@@ -0,0 +1,272 @@
1
+ require 'test/test_helper'
2
+ require 'digest/md5'
3
+ require 'stringio'
4
+ require 'logger'
5
+
6
+ class TestPKFactory
7
+ def create_pk(row)
8
+ row['_id'] ||= Mongo::ObjectID.new
9
+ row
10
+ end
11
+ end
12
+
13
+ # NOTE: assumes Mongo is running
14
+ class DBTest < Test::Unit::TestCase
15
+
16
+ include Mongo
17
+
18
+ @@host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
19
+ @@port = ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT
20
+ @@conn = Connection.new(@@host, @@port)
21
+ @@db = @@conn.db('ruby-mongo-test')
22
+ @@users = @@db.collection('system.users')
23
+
24
+ def test_close
25
+ @@conn.close
26
+ assert !@@conn.connected?
27
+ begin
28
+ @@db.collection('test').insert('a' => 1)
29
+ fail "expected 'NilClass' exception"
30
+ rescue => ex
31
+ assert_match /NilClass/, ex.to_s
32
+ ensure
33
+ @@db = Connection.new(@@host, @@port).db('ruby-mongo-test')
34
+ @@users = @@db.collection('system.users')
35
+ end
36
+ end
37
+
38
+ def test_logger
39
+ output = StringIO.new
40
+ logger = Logger.new(output)
41
+ logger.level = Logger::DEBUG
42
+ conn = Connection.new(@host, @port, :logger => logger)
43
+ assert_equal logger, conn.logger
44
+
45
+ conn.logger.debug 'testing'
46
+ assert output.string.include?('testing')
47
+ end
48
+
49
+ def test_full_coll_name
50
+ coll = @@db.collection('test')
51
+ assert_equal 'ruby-mongo-test.test', @@db.full_collection_name(coll.name)
52
+ end
53
+
54
+ def test_collection_names
55
+ @@db.collection("test").insert("foo" => 5)
56
+ @@db.collection("test.mike").insert("bar" => 0)
57
+
58
+ colls = @@db.collection_names()
59
+ assert colls.include?("test")
60
+ assert colls.include?("test.mike")
61
+ colls.each { |name|
62
+ assert !name.include?("$")
63
+ }
64
+ end
65
+
66
+ def test_collections
67
+ @@db.collection("test.durran").insert("foo" => 5)
68
+ @@db.collection("test.les").insert("bar" => 0)
69
+
70
+ colls = @@db.collections()
71
+ assert_not_nil colls.select { |coll| coll.name == "test.durran" }
72
+ assert_not_nil colls.select { |coll| coll.name == "test.les" }
73
+ assert_equal [], colls.select { |coll| coll.name == "does_not_exist" }
74
+
75
+ assert_kind_of Collection, colls[0]
76
+ end
77
+
78
+ def test_pair
79
+ @@conn.close
80
+ @@users = nil
81
+ @@conn = Connection.new({:left => "this-should-fail", :right => [@@host, @@port]})
82
+ @@db = @@conn['ruby-mongo-test']
83
+ assert @@conn.connected?
84
+ ensure
85
+ unless @@conn.connected?
86
+ @@conn = Connection.new(@@host, @@port)
87
+ @@db = @@conn.db('ruby-mongo-test')
88
+ end
89
+ @@users = @@db.collection('system.users')
90
+ end
91
+
92
+ def test_pk_factory
93
+ db = Connection.new(@@host, @@port).db('ruby-mongo-test', :pk => TestPKFactory.new)
94
+ coll = db.collection('test')
95
+ coll.remove
96
+
97
+ insert_id = coll.insert('name' => 'Fred', 'age' => 42)
98
+ # new id gets added to returned object
99
+ row = coll.find_one({'name' => 'Fred'})
100
+ oid = row['_id']
101
+ assert_not_nil oid
102
+ assert_equal insert_id, oid
103
+
104
+ oid = ObjectID.new
105
+ data = {'_id' => oid, 'name' => 'Barney', 'age' => 41}
106
+ coll.insert(data)
107
+ row = coll.find_one({'name' => data['name']})
108
+ db_oid = row['_id']
109
+ assert_equal oid, db_oid
110
+ assert_equal data, row
111
+
112
+ coll.remove
113
+ end
114
+
115
+ def test_pk_factory_reset
116
+ conn = Connection.new(@@host, @@port)
117
+ db = conn.db('ruby-mongo-test')
118
+ db.pk_factory = Object.new # first time
119
+ begin
120
+ db.pk_factory = Object.new
121
+ fail "error: expected exception"
122
+ rescue => ex
123
+ assert_match /Cannot change/, ex.to_s
124
+ ensure
125
+ conn.close
126
+ end
127
+ end
128
+
129
+ def test_authenticate
130
+ @@db.add_user('spongebob', 'squarepants')
131
+ assert_raise Mongo::AuthenticationError do
132
+ assert !@@db.authenticate('nobody', 'nopassword')
133
+ end
134
+ assert_raise Mongo::AuthenticationError do
135
+ assert !@@db.authenticate('spongebob' , 'squareliederhosen')
136
+ end
137
+ assert @@db.authenticate('spongebob', 'squarepants')
138
+ @@db.logout
139
+ @@db.remove_user('spongebob')
140
+ end
141
+
142
+ def test_authenticate_with_connection_uri
143
+ @@db.add_user('spongebob', 'squarepants')
144
+ assert Mongo::Connection.from_uri("mongodb://spongebob:squarepants@localhost/#{@@db.name}")
145
+
146
+ assert_raise Mongo::AuthenticationError do
147
+ Mongo::Connection.from_uri("mongodb://wrong:info@localhost/#{@@db.name}")
148
+ end
149
+ end
150
+
151
+ def test_logout
152
+ assert @@db.logout
153
+ end
154
+
155
+ def test_error
156
+ @@db.reset_error_history
157
+ assert_nil @@db.error
158
+ assert !@@db.error?
159
+ assert_nil @@db.previous_error
160
+
161
+ @@db.send(:command, :forceerror => 1)
162
+ assert @@db.error?
163
+ assert_not_nil @@db.error
164
+ assert_not_nil @@db.previous_error
165
+
166
+ @@db.send(:command, :forceerror => 1)
167
+ assert @@db.error?
168
+ assert @@db.error
169
+ prev_error = @@db.previous_error
170
+ assert_equal 1, prev_error['nPrev']
171
+ assert_equal prev_error["err"], @@db.error
172
+
173
+ @@db.collection('test').find_one
174
+ assert_nil @@db.error
175
+ assert !@@db.error?
176
+ assert @@db.previous_error
177
+ assert_equal 2, @@db.previous_error['nPrev']
178
+
179
+ @@db.reset_error_history
180
+ assert_nil @@db.error
181
+ assert !@@db.error?
182
+ assert_nil @@db.previous_error
183
+ end
184
+
185
+ def test_check_command_response
186
+ command = {:forceerror => 1}
187
+ assert_raise OperationFailure do
188
+ @@db.command(command, false, true)
189
+ end
190
+ end
191
+
192
+ def test_last_status
193
+ @@db['test'].remove
194
+ @@db['test'].save("i" => 1)
195
+
196
+ @@db['test'].update({"i" => 1}, {"$set" => {"i" => 2}})
197
+ assert @@db.last_status()["updatedExisting"]
198
+
199
+ @@db['test'].update({"i" => 1}, {"$set" => {"i" => 500}})
200
+ assert !@@db.last_status()["updatedExisting"]
201
+ end
202
+
203
+ def test_text_port_number_raises_no_errors
204
+ conn = Connection.new(@@host, @@port.to_s)
205
+ db = conn['ruby-mongo-test']
206
+ assert db.collection('users').remove
207
+ end
208
+
209
+ def test_user_management
210
+ @@db.add_user("bob", "secret")
211
+ assert @@db.authenticate("bob", "secret")
212
+ @@db.logout
213
+ assert @@db.remove_user("bob")
214
+ assert_raise Mongo::AuthenticationError do
215
+ @@db.authenticate("bob", "secret")
216
+ end
217
+ end
218
+
219
+ def test_remove_non_existant_user
220
+ assert !@@db.remove_user("joe")
221
+ end
222
+
223
+ context "database profiling" do
224
+ setup do
225
+ @db = @@conn['ruby-mongo-test-admin-functions']
226
+ @coll = @db['test']
227
+ @coll.remove
228
+ @r1 = @coll.insert('a' => 1) # collection not created until it's used
229
+ end
230
+
231
+ should "set default profiling level" do
232
+ assert_equal :off, @db.profiling_level
233
+ end
234
+
235
+ should "change profiling level" do
236
+ @db.profiling_level = :slow_only
237
+ assert_equal :slow_only, @db.profiling_level
238
+ @db.profiling_level = :off
239
+ assert_equal :off, @db.profiling_level
240
+ @db.profiling_level = :all
241
+ assert_equal :all, @db.profiling_level
242
+ begin
243
+ @db.profiling_level = :medium
244
+ fail "shouldn't be able to do this"
245
+ rescue
246
+ end
247
+ end
248
+
249
+ should "return profiling info" do
250
+ @db.profiling_level = :all
251
+ @coll.find()
252
+ @db.profiling_level = :off
253
+
254
+ info = @db.profiling_info
255
+ assert_kind_of Array, info
256
+ assert info.length >= 1
257
+ first = info.first
258
+ assert_kind_of String, first['info']
259
+ assert_kind_of Time, first['ts']
260
+ assert_kind_of Numeric, first['millis']
261
+ end
262
+
263
+ should "validate collection" do
264
+ doc = @db.validate_collection(@coll.name)
265
+ assert_not_nil doc
266
+ result = doc['result']
267
+ assert_not_nil result
268
+ assert_match /firstExtent/, result
269
+ end
270
+
271
+ end
272
+ end
@@ -0,0 +1,210 @@
1
+ require 'test/test_helper'
2
+ include Mongo
3
+
4
+ class GridFileSystemTest < Test::Unit::TestCase
5
+ context "GridFileSystem:" do
6
+ setup do
7
+ @con = Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
8
+ ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT)
9
+ @db = @con.db('mongo-ruby-test')
10
+ end
11
+
12
+ teardown do
13
+ @db['fs.files'].remove
14
+ @db['fs.chunks'].remove
15
+ end
16
+
17
+ context "When reading:" do
18
+ setup do
19
+ @chunks_data = "CHUNKS" * 50000
20
+ @grid = GridFileSystem.new(@db)
21
+ @grid.open('sample.file', 'w') do |f|
22
+ f.write @chunks_data
23
+ end
24
+
25
+ @grid = GridFileSystem.new(@db)
26
+ end
27
+
28
+ should "read sample data" do
29
+ data = @grid.open('sample.file', 'r') { |f| f.read }
30
+ assert_equal data.length, @chunks_data.length
31
+ end
32
+
33
+ should "return an empty string if length is zero" do
34
+ data = @grid.open('sample.file', 'r') { |f| f.read(0) }
35
+ assert_equal '', data
36
+ end
37
+
38
+ should "return the first n bytes" do
39
+ data = @grid.open('sample.file', 'r') {|f| f.read(288888) }
40
+ assert_equal 288888, data.length
41
+ assert_equal @chunks_data[0...288888], data
42
+ end
43
+
44
+ should "return the first n bytes even with an offset" do
45
+ data = @grid.open('sample.file', 'r') do |f|
46
+ f.seek(1000)
47
+ f.read(288888)
48
+ end
49
+ assert_equal 288888, data.length
50
+ assert_equal @chunks_data[1000...289888], data
51
+ end
52
+ end
53
+
54
+ context "When writing:" do
55
+ setup do
56
+ @data = "BYTES" * 50
57
+ @grid = GridFileSystem.new(@db)
58
+ @grid.open('sample', 'w') do |f|
59
+ f.write @data
60
+ end
61
+ end
62
+
63
+ should "read sample data" do
64
+ data = @grid.open('sample', 'r') { |f| f.read }
65
+ assert_equal data.length, @data.length
66
+ end
67
+
68
+ should "return the total number of bytes written" do
69
+ data = 'a' * 300000
70
+ assert_equal 300000, @grid.open('sample', 'w') {|f| f.write(data) }
71
+ end
72
+
73
+ should "more read sample data" do
74
+ data = @grid.open('sample', 'r') { |f| f.read }
75
+ assert_equal data.length, @data.length
76
+ end
77
+
78
+ should "raise exception if not opened for write" do
79
+ assert_raise GridError do
80
+ @grid.open('io', 'r') { |f| f.write('hello') }
81
+ end
82
+ end
83
+
84
+ context "and when overwriting the file" do
85
+ setup do
86
+ @old = @grid.open('sample', 'r')
87
+
88
+ @new_data = "DATA" * 10
89
+ sleep(2)
90
+ @grid.open('sample', 'w') do |f|
91
+ f.write @new_data
92
+ end
93
+
94
+ @new = @grid.open('sample', 'r')
95
+ end
96
+
97
+ should "have a newer upload date" do
98
+ assert @new.upload_date > @old.upload_date, "New data is not greater than old date."
99
+ end
100
+
101
+ should "have a different files_id" do
102
+ assert_not_equal @new.files_id, @old.files_id
103
+ end
104
+
105
+ should "contain the new data" do
106
+ assert_equal @new_data, @new.read, "Expected DATA"
107
+ end
108
+
109
+ context "and on a second overwrite" do
110
+ setup do
111
+ sleep(2)
112
+ new_data = "NEW" * 1000
113
+ @grid.open('sample', 'w') do |f|
114
+ f.write new_data
115
+ end
116
+
117
+ @ids = @db['fs.files'].find({'filename' => 'sample'}).map {|file| file['_id']}
118
+ end
119
+
120
+ should "write a third version of the file" do
121
+ assert_equal 3, @db['fs.files'].find({'filename' => 'sample'}).count
122
+ assert_equal 3, @db['fs.chunks'].find({'files_id' => {'$in' => @ids}}).count
123
+ end
124
+
125
+ should "remove all versions and their data on delete" do
126
+ @grid.delete('sample')
127
+ assert_equal 0, @db['fs.files'].find({'filename' => 'sample'}).count
128
+ assert_equal 0, @db['fs.chunks'].find({'files_id' => {'$in' => @ids}}).count
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ context "When writing chunks:" do
135
+ setup do
136
+ data = "B" * 50000
137
+ @grid = GridFileSystem.new(@db)
138
+ @grid.open('sample', 'w', :chunk_size => 1000) do |f|
139
+ f.write data
140
+ end
141
+ end
142
+
143
+ should "write the correct number of chunks" do
144
+ file = @db['fs.files'].find_one({:filename => 'sample'})
145
+ chunks = @db['fs.chunks'].find({'files_id' => file['_id']}).to_a
146
+ assert_equal 50, chunks.length
147
+ end
148
+ end
149
+
150
+ context "Positioning:" do
151
+ setup do
152
+ data = 'hello, world' + '1' * 5000 + 'goodbye!' + '2' * 1000 + '!'
153
+ @grid = GridFileSystem.new(@db)
154
+ @grid.open('hello', 'w', :chunk_size => 1000) do |f|
155
+ f.write data
156
+ end
157
+ end
158
+
159
+ should "seek within chunks" do
160
+ @grid.open('hello', 'r') do |f|
161
+ f.seek(0)
162
+ assert_equal 'h', f.read(1)
163
+ f.seek(7)
164
+ assert_equal 'w', f.read(1)
165
+ f.seek(4)
166
+ assert_equal 'o', f.read(1)
167
+ f.seek(0)
168
+ f.seek(7, IO::SEEK_CUR)
169
+ assert_equal 'w', f.read(1)
170
+ f.seek(-2, IO::SEEK_CUR)
171
+ assert_equal ' ', f.read(1)
172
+ f.seek(-4, IO::SEEK_CUR)
173
+ assert_equal 'l', f.read(1)
174
+ f.seek(3, IO::SEEK_CUR)
175
+ assert_equal 'w', f.read(1)
176
+ end
177
+ end
178
+
179
+ should "seek between chunks" do
180
+ @grid.open('hello', 'r') do |f|
181
+ f.seek(1000)
182
+ assert_equal '11111', f.read(5)
183
+
184
+ f.seek(5009)
185
+ assert_equal '111goodbye!222', f.read(14)
186
+
187
+ f.seek(-1, IO::SEEK_END)
188
+ assert_equal '!', f.read(1)
189
+ f.seek(-6, IO::SEEK_END)
190
+ assert_equal '2', f.read(1)
191
+ end
192
+ end
193
+
194
+ should "tell the current position" do
195
+ @grid.open('hello', 'r') do |f|
196
+ assert_equal 0, f.tell
197
+
198
+ f.seek(999)
199
+ assert_equal 999, f.tell
200
+ end
201
+ end
202
+
203
+ should "seek only in read mode" do
204
+ assert_raise GridError do
205
+ @grid.open('hello', 'w') {|f| f.seek(0) }
206
+ end
207
+ end
208
+ end
209
+ end
210
+ end
@@ -0,0 +1,78 @@
1
+ require 'test/test_helper'
2
+ include Mongo
3
+
4
+ class GridIOTest < Test::Unit::TestCase
5
+
6
+ context "GridIO" do
7
+ setup do
8
+ @db ||= Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
9
+ ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT).db('ruby-mongo-test')
10
+ @files = @db.collection('fs.files')
11
+ @chunks = @db.collection('fs.chunks')
12
+ @chunks.create_index([['files_id', Mongo::ASCENDING], ['n', Mongo::ASCENDING]])
13
+ end
14
+
15
+ teardown do
16
+ @files.remove
17
+ @chunks.remove
18
+ end
19
+
20
+ context "Options" do
21
+ setup do
22
+ @filename = 'test'
23
+ @mode = 'w'
24
+ end
25
+
26
+ should "set default 256k chunk size" do
27
+ file = GridIO.new(@files, @chunks, @filename, @mode)
28
+ assert_equal 256 * 1024, file.chunk_size
29
+ end
30
+
31
+ should "set chunk size" do
32
+ file = GridIO.new(@files, @chunks, @filename, @mode, :chunk_size => 1000)
33
+ assert_equal 1000, file.chunk_size
34
+ end
35
+ end
36
+
37
+ context "Grid MD5 check" do
38
+ should "run in safe mode" do
39
+ file = GridIO.new(@files, @chunks, 'smallfile', 'w', :safe => true)
40
+ file.write("DATA" * 100)
41
+ assert file.close
42
+ assert_equal file.server_md5, file.client_md5
43
+ end
44
+
45
+ should "validate with a large file" do
46
+ io = File.open(File.join(File.dirname(__FILE__), 'data', 'sample_file.pdf'), 'r')
47
+ file = GridIO.new(@files, @chunks, 'bigfile', 'w', :safe => true)
48
+ file.write(io)
49
+ assert file.close
50
+ assert_equal file.server_md5, file.client_md5
51
+ end
52
+ end
53
+
54
+ context "Content types" do
55
+
56
+ if defined?(MIME)
57
+ should "determine common content types from the extension" do
58
+ file = GridIO.new(@files, @chunks, 'sample.pdf', 'w')
59
+ assert_equal 'application/pdf', file.content_type
60
+
61
+ file = GridIO.new(@files, @chunks, 'sample.txt', 'w')
62
+ assert_equal 'text/plain', file.content_type
63
+ end
64
+ end
65
+
66
+ should "default to binary/octet-stream when type is unknown" do
67
+ file = GridIO.new(@files, @chunks, 'sample.l33t', 'w')
68
+ assert_equal 'binary/octet-stream', file.content_type
69
+ end
70
+
71
+ should "use any provided content type by default" do
72
+ file = GridIO.new(@files, @chunks, 'sample.l33t', 'w', :content_type => 'image/jpg')
73
+ assert_equal 'image/jpg', file.content_type
74
+ end
75
+ end
76
+ end
77
+
78
+ end