From 3b16e827362e78fa8b6524a0f90e49f390c0071f Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Wed, 25 Jul 2012 16:54:51 +0800 Subject: [PATCH] add mocha style unit test --- Makefile | 16 +-- README.md | 34 +++++-- package.json | 5 +- test/curl.js | 225 +++++++++++++++++++++++++++++++++++++++++-- test/support/echo.js | 93 +++++++++--------- 5 files changed, 293 insertions(+), 80 deletions(-) diff --git a/Makefile b/Makefile index 289e425..c85ee76 100644 --- a/Makefile +++ b/Makefile @@ -4,22 +4,10 @@ REPORTER = spec MOCHAOPTS= build: - @node-gyp clean && node-gyp configure && node-gyp build + @node-gyp clean configure build test: @NODE_ENV=test ./node_modules/mocha/bin/mocha \ --reporter $(REPORTER) --timeout $(TIMEOUT) $(MOCHAOPTS) $(TESTS) -test-cov: lib-cov - @HTTPSYNC_COV=1 $(MAKE) test - @HTTPSYNC_COV=1 $(MAKE) test REPORTER=html-cov > coverage.html - -lib-cov: - @rm -rf lib-cov - @jscoverage lib lib-cov - -clean: - @rm -rf lib-cov - @rm -f coverage.html - -.PHONY: build test test-cov lib-cov clean +.PHONY: build test diff --git a/README.md b/README.md index a3dea74..74edd19 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ -# node-curl - - node-curl is a port of libcurl to node.js. Its interface emulates the - `http` module of node.js. But in contrast to `http` module's asynchronous - functions, node-curl provides the equivalent synchronous APIs. +# httpsync + +[![Build Status](https://secure.travis-ci.org/fengmk2/node-curl.png)](http://travis-ci.org/fengmk2/node-curl) + +`httpsync` is a port of libcurl to node.js. Its interface emulates the +`http` module of node.js. But in contrast to `http` module's asynchronous +functions, node-curl provides the equivalent synchronous APIs. ## Install @@ -10,10 +12,6 @@ $ npm install httpsync ``` -## Build - - node-waf configure && node-waf build - ## APIs ### curl.request(options) @@ -78,7 +76,7 @@ req.write("another text"); console.log(req.end()); ``` -### request.endFile (filePath) +### request.endFile(filePath) Send a file directly. The method will default to `PUT`. @@ -101,6 +99,22 @@ req.endFile("/etc/passwd"); - `ip` IP address of the server. - `statusCode` Status code that sent by server. +## Contributors + +Thanks goes to the people who have contributed code to this module, see the [GitHub Contributors page](https://github.com/fengmk2/node-curl/graphs/contributors). + +Below is the output from `git-summary` + +``` + project: node-curl + commits: 25 + active : 5 days + files : 21 + authors: + 21 赵成 84.0% + 4 fengmk2 16.0% +``` + ## License (The MIT License) diff --git a/package.json b/package.json index cc932ba..564d1a4 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,8 @@ "name": "httpsync", "version": "0.0.1", "scripts": { - "install": "node-gyp clean && node-gyp configure && node-gyp build" + "install": "node-gyp clean configure build", + "test": "make test" }, "description": "node-curl is a port of libcurl to node.js. Its interface emulates the `http` module of node.js. But in contrast to `http` module's asynchronous functions, node-curl provides the equivalent synchronous APIs.", "main": "index.js", @@ -11,7 +12,7 @@ }, "repository": { "type": "git", - "url": "git://github.com/zcbenz/node-curl.git" + "url": "git://github.com/fengmk2/node-curl.git" }, "keywords": [ "curl", diff --git a/test/curl.js b/test/curl.js index 6423769..bdab42d 100644 --- a/test/curl.js +++ b/test/curl.js @@ -12,18 +12,24 @@ var httpsync = require('../'); var should = require('should'); -var echo = require('./support/echo'); +var spawn = require('child_process').spawn; describe('curl.js', function () { - var app = echo.create(); var homeurl = 'http://127.0.0.1:'; + var echoProcess; before(function (done) { - app.listen(0, function () { - homeurl += app.address().port; + var echofile = __dirname + '/support/echo.js'; + echoProcess = spawn('node', [echofile]); + echoProcess.stdout.once('data', function (data) { + data = JSON.parse(data); + homeurl += data.port; done(); }); }); + after(function () { + echoProcess.kill(); + }); describe('request()', function () { it('should throw error', function () { @@ -51,11 +57,201 @@ describe('curl.js', function () { }).should.throw('Couldn\'t resolve host name'); }); - // it('should GET / return status 200', function () { - // var req = httpsync.get(homeurl); - // var res = req.end(); - // res.should.status(200); - // }); + it('should GET / return status 200', function () { + var req = httpsync.request({ + url: homeurl + }); + var res = req.end(); + res.should.header('x-request-url', '/'); + res.should.header('content-type', 'text/plain'); + res.should.status(200); + res.data.should.be.instanceof(Buffer); + res.data.toString().should.equal('GET\n'); + }); + + it('should ignore data when GET with some data', function () { + var req = httpsync.request({ + url: homeurl, + method: 'GET' + }); + var res = req.end('some data'); + res.should.header('x-request-url', '/'); + res.should.header('content-type', 'text/plain'); + res.should.status(200); + res.data.toString().should.equal('GET\n'); + }); + it('should POST with empty data', function () { + var req = httpsync.request({ + url: homeurl + '/post', + method: 'post' + }); + var res = req.end(); + res.should.header('x-request-url', '/post'); + res.should.header('content-type', 'text/plain'); + res.should.status(200); + res.data.toString().should.equal('POST\n'); + }); + it('should return data when POST with some data', function () { + var req = httpsync.request({ + url: homeurl + '/post', + method: 'post' + }); + req.write ("1 line\n"); + req.write ("2 line\n"); + req.write ("3 line\n"); + var res = req.end ("helloworld"); + res.data.toString().should.equal("POST\n1 line\n2 line\n3 line\nhelloworld"); + res.should.header('x-request-url', '/post'); + res.should.header('content-type', 'text/plain'); + res.should.status(200); + }); + it('should POST with many data', function () { + var req = httpsync.request({ + url: homeurl + '/pOst', + method: 'pOst' + }); + var res = req.end('some data'); + res.should.header('x-request-url', '/pOst'); + res.should.header('content-type', 'text/plain'); + res.should.status(200); + res.data.toString().should.equal('POST\nsome data'); + }); + + it('should HEAD return empty body', function () { + var req = httpsync.request({ + url: homeurl + '/HEAD', + method: 'HeAD' + }); + var res = req.end('some data'); + res.should.header('content-type', 'text/plain'); + res.should.status(200); + res.data.toString().should.equal(''); + }); + + it('should request with other methods', function () { + var req = httpsync.request({ + url: homeurl + '/put', + method: 'PUT' + }); + var res = req.end('put data'); + res.should.header('x-request-url', '/put'); + // res.should.header('content-type', 'text/plain'); + res.should.status(200); + res.data.toString().should.equal('PUT\nput data'); + + var req2 = httpsync.request({ + url: homeurl + '/delete', + method: 'DELETE' + }); + var res2 = req2.end('delete DATA'); + res2.should.header('x-request-url', '/delete'); + res2.should.header('content-type', 'text/plain'); + res2.should.status(200); + res2.data.toString().should.equal('DELETE\n'); + }); + + it('should request with custom headers', function () { + var req1 = httpsync.request({ + url: homeurl, + headers: { + "Custom": "true", + "String": "A very very long string", + "How": "Old are you" + } + }); + var res1 = req1.end (); + + var req2 = httpsync.request({ + url: homeurl, + method: "DELETE", + headers: { + "custom": "true", + "File": "/etc/passwd", + "Directory": "/usr" + } + }); + var res2 = req2.end(); + var host = homeurl.replace('http://', ''); + res1.data.toString().should.equal("GET\n{\"user-agent\":\"zcbenz/node-curl\",\"host\":\"" + + host + "\",\"accept\":\"*/*\",\"custom\":\"true\",\"string\":\"A very very long string\",\"how\":\"Old are you\"}"); + res1.should.status(200); + res2.data.toString().should.equal("DELETE\n{\"user-agent\":\"zcbenz/node-curl\",\"host\":\"" + + host + "\",\"accept\":\"*/*\",\"custom\":\"true\",\"file\":\"/etc/passwd\",\"directory\":\"/usr\"}"); + res2.should.status(200); + }); + + it('should write with buffer', function () { + var req = httpsync.request({ + url: homeurl, + method: "POST", + headers: { "nomethod": "true" } + }); + var buf = new Buffer (8); + buf.writeUInt8(0x3, 0, 'big'); + buf.writeUInt8(0x4, 1, 'big'); + buf.writeUInt8(0x23, 2, 'big'); + buf.writeUInt8(0x42, 3, 'big'); + buf.writeUInt8(0x3, 4, 'little'); + buf.writeUInt8(0x4, 5, 'little'); + buf.writeUInt8(0x23, 6, 'little'); + buf.writeUInt8(0x42, 7, 'little'); + var res = req.end(buf); + res.data.should.eql(buf); + }); + + it('should endFile() to send file data', function () { + var req = httpsync.request({ + url: homeurl + }); + var res = req.endFile(__filename); + + var req2 = httpsync.request({ + url: homeurl, + method: "POST" + }); + var res2 = req2.endFile(__filename); + res.data.toString("utf8").should.equal("PUT\n" + require("fs").readFileSync(__filename)); + res2.data.toString("utf8").should.equal("POST\n" + require("fs").readFileSync(__filename)); + }); + + it('should check responded headers', function () { + var req = httpsync.request ({ + url: homeurl, + headers: { + "customheaders": "Test String" + } + }); + var res = req.end(); + res.should.header('customheaders', 'Test String'); + res.should.status(42); + }); + + it('should throw err when request with invalid options', function () { + (function () { + var req = httpsync.request ({ + url: homeurl, + headers: { + "customheaders": "Test String", + }, + method: 'FUCK' + }); + var res = req.end(); + }).should.throw('Server returned nothing (no headers, no data)'); + }); + + it('should throw timeout', function () { + (function () { + var req = httpsync.request ({ + url: homeurl, + timeout: 1, + headers: { + "customheaders": "Test String", + timeout: 'true' + }, + }); + var res = req.end(); + }).should.throw('Timeout was reached'); + }); }); describe('get()', function () { @@ -93,6 +289,17 @@ describe('curl.js', function () { var res = req.end(); res.should.status(200); }); + + it('should GET with options', function () { + var req = httpsync.get({ + url: homeurl + '/get' + }); + var res = req.end(); + res.should.status(200); + res.should.header('x-request-url', '/get'); + res.should.header('x-request-method', 'GET'); + res.data.toString().should.equal('GET\n'); + }); }); }); diff --git a/test/support/echo.js b/test/support/echo.js index 76a1d0d..6955b6b 100644 --- a/test/support/echo.js +++ b/test/support/echo.js @@ -1,52 +1,55 @@ -exports.create = function () { - - var app = require("http").createServer(function (req, res) { - if (req.headers.timeout) { - setTimeout (function () { - res.end(); - }, 6000); - return; - } - - if (req.method === "HEAD") { - res.writeHead(200, { - 'Content-Type' : 'text/plain', - 'Date' : 'Wed, 17 Mar 2004 18 : 00 : 49 GMT', - 'Last-Modified' : 'Wed, 25 Feb 2004 22 : 37 : 23 GMT' - }); +var app = require("http").createServer(function (req, res) { + if (req.headers.timeout) { + setTimeout (function () { res.end(); - return; - } - - if (req.headers.customheaders) { - res.writeHead(42, { - 'Content-Type': 'text/plain', - 'customheaders': req.headers.customheaders - }); - } else { - res.writeHead(200, { - 'Content-Type': 'text/plain', - 'X-REQUEST-URL': req.url - }); - } + }, 2000); + return; + } + + if (req.method === "HEAD") { + res.writeHead(200, { + 'Content-Type' : 'text/plain', + 'Date' : 'Wed, 17 Mar 2004 18 : 00 : 49 GMT', + 'Last-Modified' : 'Wed, 25 Feb 2004 22 : 37 : 23 GMT' + }); + res.end(); + return; + } + + if (req.headers.customheaders) { + res.writeHead(42, { + 'Content-Type': 'text/plain', + 'customheaders': req.headers.customheaders + }); + } else { + res.writeHead(200, { + 'Content-Type': 'text/plain', + 'X-REQUEST-URL': req.url, + 'X-REQUEST-METHOD': req.method + }); + } - if (!req.headers.nomethod) { - res.write(req.method + "\n"); - } + if (!req.headers.nomethod) { + res.write(req.method + "\n"); + } - if (req.headers.custom) { - res.write(JSON.stringify(req.headers)); - } + if (req.headers.custom) { + res.write(JSON.stringify(req.headers)); + } - var data = new Buffer(""); - req.on("data", function (chunk) { - data += chunk; - }); - req.on("end", function (chunk) { - res.end(data); - }); + var data = new Buffer(""); + req.on("data", function (chunk) { + data += chunk; + }); + req.on("end", function (chunk) { + res.end(data); }); +}); - return app; +app.listen(0, function () { + console.log('%j', app.address()); +}); -}; \ No newline at end of file +setTimeout(function () { + process.exit(); +}, 10000); \ No newline at end of file