kbaum-mongo 0.18.3p

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