Plato on Github
Report Home
request/tests/test-pipes.js
Maintainability
76.15
Lines of code
362
Difficulty
37.17
Estimated Errors
3.94
Function weight
By Complexity
By SLOC
'use strict' var server = require('./server') , stream = require('stream') , fs = require('fs') , request = require('../index') , path = require('path') , util = require('util') , tape = require('tape') var s = server.createServer() s.on('/cat', function(req, res) { if (req.method === 'GET') { res.writeHead(200, { 'content-type': 'text/plain-test', 'content-length': 4 }) res.end('asdf') } else if (req.method === 'PUT') { var body = '' req.on('data', function(chunk) { body += chunk }).on('end', function() { res.writeHead(201) res.end() s.emit('catDone', req, res, body) }) } }) s.on('/doodle', function(req, res) { if (req.headers['x-oneline-proxy']) { res.setHeader('x-oneline-proxy', 'yup') } res.writeHead('200', { 'content-type': 'image/jpeg' }) fs.createReadStream(path.join(__dirname, 'googledoodle.jpg')).pipe(res) }) function ValidationStream(t, str) { this.str = str this.buf = '' this.on('data', function(data) { this.buf += data }) this.on('end', function() { t.equal(this.str, this.buf) }) this.writable = true } util.inherits(ValidationStream, stream.Stream) ValidationStream.prototype.write = function(chunk) { this.emit('data', chunk) } ValidationStream.prototype.end = function(chunk) { if (chunk) { this.emit('data', chunk) } this.emit('end') } tape('setup', function(t) { s.listen(s.port, function() { t.end() }) }) tape('piping to a request object', function(t) { s.once('/push', server.createPostValidator('mydata')) var mydata = new stream.Stream() mydata.readable = true var r1 = request.put({ url: s.url + '/push' }, function(err, res, body) { t.equal(err, null) t.equal(res.statusCode, 200) t.equal(body, 'mydata') t.end() }) mydata.pipe(r1) mydata.emit('data', 'mydata') mydata.emit('end') }) tape('piping to a request object with a json body', function(t) { var obj = {foo: 'bar'} var json = JSON.stringify(obj) s.once('/push-json', server.createPostValidator(json, 'application/json')) var mybodydata = new stream.Stream() mybodydata.readable = true var r2 = request.put({ url: s.url + '/push-json', json: true }, function(err, res, body) { t.equal(err, null) t.equal(res.statusCode, 200) t.deepEqual(body, obj) t.end() }) mybodydata.pipe(r2) mybodydata.emit('data', JSON.stringify({ foo: 'bar' })) mybodydata.emit('end') }) tape('piping from a request object', function(t) { s.once('/pull', server.createGetResponse('mypulldata')) var mypulldata = new stream.Stream() mypulldata.writable = true request({ url: s.url + '/pull' }).pipe(mypulldata) var d = '' mypulldata.write = function(chunk) { d += chunk } mypulldata.end = function() { t.equal(d, 'mypulldata') t.end() } }) tape('pause when piping from a request object', function(t) { s.once('/chunks', function(req, res) { res.writeHead(200, { 'content-type': 'text/plain' }) res.write('Chunk 1') setTimeout(function() { res.end('Chunk 2') }, 10) }) var chunkNum = 0 var paused = false request({ url: s.url + '/chunks' }) .on('data', function(chunk) { var self = this t.notOk(paused, 'Only receive data when not paused') ++chunkNum if (chunkNum === 1) { t.equal(chunk.toString(), 'Chunk 1') self.pause() paused = true setTimeout(function() { paused = false self.resume() }, 100) } else { t.equal(chunk.toString(), 'Chunk 2') } }) .on('end', t.end.bind(t)) }) tape('pause before piping from a request object', function(t) { s.once('/pause-before', function(req, res) { res.writeHead(200, { 'content-type': 'text/plain' }) res.end('Data') }) var paused = true var r = request({ url: s.url + '/pause-before' }) r.pause() r.on('data', function(data) { t.notOk(paused, 'Only receive data when not paused') t.equal(data.toString(), 'Data') }) r.on('end', t.end.bind(t)) setTimeout(function() { paused = false r.resume() }, 100) }) var fileContents = fs.readFileSync(__filename).toString() function testPipeFromFile(testName, hasContentLength) { tape(testName, function(t) { s.once('/pushjs', function(req, res) { if (req.method === 'PUT') { t.equal(req.headers['content-type'], 'application/javascript') t.equal( req.headers['content-length'], (hasContentLength ? '' + fileContents.length : undefined)) var body = '' req.on('data', function(data) { body += data }) req.on('end', function() { t.equal(body, fileContents) t.end() }) res.end() } }) var r = request.put(s.url + '/pushjs') fs.createReadStream(__filename).pipe(r) if (hasContentLength) { r.setHeader('content-length', fileContents.length) } }) } // TODO Piping from a file does not send content-length header testPipeFromFile('piping from a file', false) testPipeFromFile('piping from a file with content-length', true) tape('piping to and from same URL', function(t) { s.once('catDone', function(req, res, body) { t.equal(req.headers['content-type'], 'text/plain-test') t.equal(req.headers['content-length'], '4') t.equal(body, 'asdf') t.end() }) request.get(s.url + '/cat') .pipe(request.put(s.url + '/cat')) }) tape('piping between urls', function(t) { s.once('/catresp', function(req, res) { request.get(s.url + '/cat').pipe(res) }) request.get(s.url + '/catresp', function(err, res, body) { t.equal(err, null) t.equal(res.headers['content-type'], 'text/plain-test') t.equal(res.headers['content-length'], '4') t.end() }) }) tape('writing to file', function(t) { var doodleWrite = fs.createWriteStream(path.join(__dirname, 'test.jpg')) request.get(s.url + '/doodle').pipe(doodleWrite) doodleWrite.on('close', function() { t.deepEqual( fs.readFileSync(path.join(__dirname, 'googledoodle.jpg')), fs.readFileSync(path.join(__dirname, 'test.jpg'))) fs.unlinkSync(path.join(__dirname, 'test.jpg')) t.end() }) }) tape('one-line proxy', function(t) { s.once('/onelineproxy', function(req, res) { var x = request(s.url + '/doodle') req.pipe(x) x.pipe(res) }) request.get({ uri: s.url + '/onelineproxy', headers: { 'x-oneline-proxy': 'nope' } }, function(err, res, body) { t.equal(err, null) t.equal(res.headers['x-oneline-proxy'], 'yup') t.end() }) }) tape('piping after response', function(t) { s.once('/afterresponse', function(req, res) { res.write('d') res.end() }) var rAfterRes = request.post(s.url + '/afterresponse') rAfterRes.on('response', function() { var v = new ValidationStream(t, 'd') rAfterRes.pipe(v) v.on('end', function() { t.end() }) }) }) tape('piping through a redirect', function(t) { s.once('/forward1', function(req, res) { res.writeHead(302, { location: '/forward2' }) res.end() }) s.once('/forward2', function(req, res) { res.writeHead('200', { 'content-type': 'image/png' }) res.write('d') res.end() }) var validateForward = new ValidationStream(t, 'd') request.get(s.url + '/forward1').pipe(validateForward) validateForward.on('end', function() { t.end() }) }) tape('pipe options', function(t) { s.once('/opts', server.createGetResponse('opts response')) var optsStream = new stream.Stream() , optsData = '' optsStream.writable = true optsStream.write = function(buf) { optsData += buf if (optsData === 'opts response') { setTimeout(function() { t.end() }, 10) } } optsStream.end = function() { t.fail('end called') } request({ url: s.url + '/opts' }).pipe(optsStream, { end: false }) }) tape('request.pipefilter is called correctly', function(t) { s.once('/pipefilter', function(req, res) { res.end('d') }) var validatePipeFilter = new ValidationStream(t, 'd') var r3 = request.get(s.url + '/pipefilter') r3.pipe(validatePipeFilter) r3.pipefilter = function(res, dest) { t.equal(res, r3.response) t.equal(dest, validatePipeFilter) t.end() } }) tape('cleanup', function(t) { s.close(function() { t.end() }) })