diff --git a/.gitignore b/.gitignore index 8924a06..78971b4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules/ .idea/ - +coverage +.nyc_output diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7ca0112..3d79bde 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,9 +11,9 @@ When these are put in the [fixtures](https://github.com/remy/inliner/tree/master If there are any external assets the example needs, please also include these and name them with the same root as your example, i.e. `.css` or `.min.js` etc. -In addition `.opts.json` can be loaded to help specify runtime options during the test. +In addition `.opts.json` can be loaded to help specify runtime options during the test. -**To test a single fixture you can use: `npm test `** +**To test a single fixture you can use: `FILTER= npm test`** ## Commit messages diff --git a/lib/get.js b/lib/get.js index 1321cae..fbe361f 100644 --- a/lib/get.js +++ b/lib/get.js @@ -56,16 +56,15 @@ module.exports = function get(url, options) { return reject(error); } - if (!res) { - res = { headers: {}, statusCode: null }; - } - debug('response: %s %s', res.statusCode, url); if (res.statusCode !== 200) { - body = ''; inliner.emit('warning', res.statusCode + ' on ' + url); } + if (res.statusCode >= 400) { + body = ''; + } + resolve({ body: body, headers: res.headers, diff --git a/lib/index.js b/lib/index.js index dd00f1f..268129b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -128,7 +128,13 @@ function Inliner(source, options, callback) { setTimeout(fn, 0); }; } - global.setImmediate(this.main.bind(this)); + this.promise = new Promise(function (resolve) { + global.setImmediate(function () { + resolve(inliner.main()); + }); + }); + } else { + this.promise = Promise.reject(new Error('No source to inline')); } return this; @@ -157,10 +163,10 @@ function main() { var inliner = this; var url = this.source; - fs.exists(this.filename || url) + return fs.exists(this.filename || url) .then(function exists(isFile) { if (!isFile) { - throw new Error(); + throw new Error('Not a file - use URL parser'); } debug('inlining file'); @@ -169,7 +175,7 @@ function main() { inliner.url = url; // this is a hack for the `resolve` function later on return inliner.get(this.filename || url, { encoding: 'binary' }); }) - .catch(function isUrl() { + .catch(function isUrl(error) { // make the best guess as to whether we're working with a url if (inliner.url || url.indexOf('<') === -1) { url = inliner.url || inliner.source; @@ -310,6 +316,7 @@ function main() { debug('fail', error.stack); inliner.callback(error); inliner.emit('error', error); + throw error; }); } diff --git a/package.json b/package.json index 2fede25..418cc31 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,9 @@ "homepage": "http://github.com/remy/inliner", "main": "lib/index.js", "scripts": { - "test": "jscs -v cli/*.js lib/*.js && node test/*.test.js --cov", + "cover": "tap test/*.test.js --cov --coverage-report=lcov", + "lint": "jscs -v cli/*.js lib/*.js", + "test": "npm run lint && tap test/*.test.js --cov -R spec", "semantic-release": "semantic-release pre && npm publish && semantic-release post" }, "keywords": [ @@ -29,6 +31,7 @@ "minimist": "^1.1.3", "request": "^2.60.0", "svgo": "^0.5.6", + "tap-only": "0.0.5", "then-fs": "^2.0.0", "uglify-js": "^2.4.24", "update-notifier": "^0.5.0" @@ -43,9 +46,8 @@ }, "devDependencies": { "jscs": "^2.0.0", + "semantic-release": "^4.0.0", "st": "^0.5.5", - "tap-spec": "^4.0.2", - "tape": "^4.0.1", - "semantic-release": "^4.0.0" + "tap": "^5.4.2" } } diff --git a/test/index.test.js b/test/index.test.js index 6aa63ca..a668bf2 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -1,14 +1,22 @@ -'use strict'; -var test = require('tape'); +var test = require('tap-only'); var Promise = require('es6-promise').Promise; // jshint ignore:line var fs = require('then-fs'); var path = require('path'); -var tapSpec = require('tap-spec'); var http = require('http'); var debug = require('debug')('inliner:test'); var st = require('st'); +var server; -test.createStream().pipe(tapSpec()).pipe(process.stdout); +test('setup mock server', function (t) { + server = http.createServer( + st(path.resolve(__dirname, 'fixtures')) + ).listen(54321); + + server.on('listening', function listening() { + t.pass('mock server ready'); + t.end(); + }); +}); test('inliner core functions', function coreTests(t) { var Inliner = require('../'); @@ -28,14 +36,28 @@ test('inliner core functions', function coreTests(t) { }); }); +test('failures', function failureTests(t) { + var Inliner = require('../'); + var throwBack = function (e) { return e; }; + return Promise.all([ + 'http://localhost:11111_11', + 'http://localhost:11111', + 'http://localhost:1111'].map(function (url) { + return (new Inliner('http://localhost:11111_11').promise).catch(throwBack).then(function (res) { + t.ok(res instanceof Error, url + ' throws error'); + }); + })); +}); + test('inliner fixtures', function fixtureTests(t) { - var testFilter = process.argv.slice(-1).pop(); - var testOffset = 1; + var testFilter = Object.keys(process.env).map(function (key) { + if (key.toLowerCase() === 'filter') { + return process.env[key]; + } + return false; + }).filter(Boolean).shift(); - if (testFilter === '--cov') { // this is part of our npm test command - testFilter = null; - testOffset = 0; - } else { + if (testFilter) { t.pass('filtering against ' + testFilter + '.src.html'); } @@ -55,42 +77,35 @@ test('inliner fixtures', function fixtureTests(t) { return file; }); - t.plan(files.length + testOffset); + Promise.all(results).then(function then(results) { + return Promise.all(files.map(function map(file, i) { + // Read test-specific command line arguments. + var optsfile = file.replace('.src.html', '.opts.json'); + var opts = {}; + try { + opts = require(optsfile); + debug('loaded options %s', optsfile, opts); + } catch (e) {} - var server = http.createServer( - st(path.resolve(__dirname, 'fixtures')) - ).listen(54321); - - server.on('listening', function listening() { - Promise.all(results).then(function then(results) { - return Promise.all(files.map(function map(file, i) { - // Read test-specific command line arguments. - var optsfile = file.replace('.src.html', '.opts.json'); - var opts = {}; - try { - opts = require(optsfile); - debug('loaded options %s', optsfile, opts); - } catch (e) {} - - return new Promise(function inlinerPromise(resolve, reject) { - new Inliner(file, opts, function callback(error, html) { - var basename = path.basename(file); - if (error) { - error.message += ' @ ' + basename; - return reject(error); - } - t.ok(html.trim() === results[i].trim(), basename + ' matches'); - debug('result', html.trim()); - // debug('expected', results[i].trim()); - resolve(); - }); + return new Promise(function inlinerPromise(resolve, reject) { + new Inliner(file, opts, function callback(error, html) { + var basename = path.basename(file); + if (error) { + error.message += ' @ ' + basename; + return reject(error); + } + t.equal(html.trim(), results[i].trim(), basename + ' matches'); + debug('result', html.trim()); + // debug('expected', results[i].trim()); + resolve(); }); - })); - }).catch(function errHandler(error) { - t.fail(error.message); - console.log(error.stack); - }).then(function close() { - server.close(); - }); - }); + }); + })); + }).catch(t.threw).then(t.end); +}); + +test('tear down', function (t) { + server.close(); + t.pass('tear down complete'); + t.end(); });