From bfc840d1a7770cbf99f151545b2c7da9a0633d2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20Cruz?= Date: Mon, 22 Apr 2013 00:59:40 +0100 Subject: [PATCH] Complete some more tests related with the base resolver. --- lib/resolve/Resolver.js | 11 +- test/assets/test-temp-dir/test-exception.js | 15 ++ test/assets/test-temp-dir/test.js | 12 ++ test/resolve/resolver.js | 165 ++++++++++++++++++-- test/test.js | 5 + 5 files changed, 195 insertions(+), 13 deletions(-) create mode 100644 test/assets/test-temp-dir/test-exception.js create mode 100644 test/assets/test-temp-dir/test.js diff --git a/lib/resolve/Resolver.js b/lib/resolve/Resolver.js index f01e83a1..9ef3b40d 100644 --- a/lib/resolve/Resolver.js +++ b/lib/resolve/Resolver.js @@ -12,6 +12,8 @@ var glob = require('glob'); var config = require('../config'); var createError = require('../util/createError'); +tmp.setGracefulCleanup(); + var Resolver = function (source, options) { options = options || {}; @@ -95,8 +97,8 @@ Resolver.prototype._createTempDir = function () { .then(function () { return Q.nfcall(tmp.dir, { template: path.join(baseDir, this._name + '-XXXXXX'), - mode: parseInt('0777', 8) & (~process.umask()) - //unsafeCleanup: true // TODO: don't forget enable this + mode: parseInt('0777', 8) & ~process.umask(), + unsafeCleanup: true }); }.bind(this)) .then(function (dir) { @@ -116,7 +118,7 @@ Resolver.prototype._readJson = function (dir) { // Read it return Q.nfcall(bowerJson.read, filename) .then(null, function (err) { - throw createError('Something went wrong when reading "' + filename + '"', err.code, { + throw createError('Something went wrong while reading "' + filename + '"', err.code, { details: err.message }); }); @@ -128,11 +130,12 @@ Resolver.prototype._readJson = function (dir) { Resolver.prototype._applyPkgMeta = function (meta) { // Check if name defined in the json is different - // If so and if the name was "guessed", assume the json name if (meta.name !== this._name) { + // If so and if the name was "guessed", assume the json name if (this._guessedName) { this._name = meta.name; this.emit('name_change', this._name); + // Otherwise use/force the configured one } else { meta.name = this._name; } diff --git a/test/assets/test-temp-dir/test-exception.js b/test/assets/test-temp-dir/test-exception.js new file mode 100644 index 00000000..4cb53877 --- /dev/null +++ b/test/assets/test-temp-dir/test-exception.js @@ -0,0 +1,15 @@ +var fs = require('fs'); +var path = require('path'); +var Resolver = require('../../../lib/resolve/Resolver'); + +var resolver = new Resolver('foo'); +resolver._createTempDir() +.then(function (dir) { + // Need to write something to prevent tmp to automatically + // remove the temp dir (it removes if empty) + fs.writeFileSync(path.join(dir, 'some_file'), 'foo'); + + // Force an error + throw new Error('Some error'); +}) +.done(); \ No newline at end of file diff --git a/test/assets/test-temp-dir/test.js b/test/assets/test-temp-dir/test.js new file mode 100644 index 00000000..6f37fa38 --- /dev/null +++ b/test/assets/test-temp-dir/test.js @@ -0,0 +1,12 @@ +var fs = require('fs'); +var path = require('path'); +var Resolver = require('../../../lib/resolve/Resolver'); + +var resolver = new Resolver('foo'); +resolver._createTempDir() +.then(function (dir) { + // Need to write something to prevent tmp to automatically + // remove the temp dir (it removes if empty) + fs.writeFileSync(path.join(dir, 'some_file'), 'foo'); +}) +.done(); \ No newline at end of file diff --git a/test/resolve/resolver.js b/test/resolve/resolver.js index 3f7e1f68..f8644b2b 100644 --- a/test/resolve/resolver.js +++ b/test/resolve/resolver.js @@ -4,6 +4,8 @@ var path = require('path'); var util = require('util'); var mkdirp = require('mkdirp'); var rimraf = require('rimraf'); +var tmp = require('tmp'); +var cmd = require('../../lib/util/cmd'); var Resolver = require('../../lib/resolve/Resolver'); describe('Resolver', function () { @@ -181,7 +183,7 @@ describe('Resolver', function () { expect(resolver.getTempDir() == null).to.be(true); }); - it('should still return null if resolved failed', function () { + it('should still return null if resolve failed', function () { it('should still return null', function (next) { var resolver = new Resolver('foo'); @@ -221,7 +223,7 @@ describe('Resolver', function () { expect(resolver.getPkgMeta() == null).to.be(true); }); - it('should still return null if resolved failed', function () { + it('should still return null if resolve failed', function () { it('should still return null', function (next) { var resolver = new Resolver('foo'); @@ -252,6 +254,21 @@ describe('Resolver', function () { }); describe('_createTempDir', function () { + var tempDir = path.normalize(__dirname + '/../assets/tmp'), + dirMode0777; + + before(function () { + var stat; + + mkdirp.sync(tempDir, '0777'); + stat = fs.statSync(tempDir); + dirMode0777 = stat.mode; + }); + + after(function (next) { + rimraf(tempDir, next); + }); + it('should return a promise', function (done) { var resolver = new Resolver('foo'), promise = resolver._createTempDir(); @@ -260,13 +277,102 @@ describe('Resolver', function () { expect(promise.then).to.be.an('function'); promise.then(done.bind(done, null), done.bind(done, null)); }); - it.skip('should create a directory inside a bower folder, located within the OS temp folder'); - it.skip('should set the dir mode the same as the process'); - it.skip('should remove the folder after execution'); - it.skip('should set _tempDir with the created directory'); + + it('should create a directory inside a bower folder, located within the OS temp folder', function (next) { + var resolver = new Resolver('foo'); + + resolver._createTempDir() + .then(function (dir) { + var dirname, + osTempDir; + + expect(dir).to.be.a('string'); + expect(fs.existsSync(dir)).to.be(true); + + dirname = path.dirname(dir); + osTempDir = path.resolve(tmp.tmpdir); + + expect(path.basename(dirname)).to.equal('bower'); + expect(path.dirname(dirname)).to.equal(osTempDir); + next(); + }) + .done(); + }); + + it('should set the dir mode the same as the process', function (next) { + var resolver = new Resolver('foo'); + + resolver._createTempDir() + .then(function (dir) { + var stat = fs.statSync(dir), + expectedMode = dirMode0777 & ~process.umask(); + + expect(stat.mode).to.equal(expectedMode); + next(); + }) + .done(); + }); + + it('should remove the folder after execution', function (next) { + var bowerOsTempDir = path.join(tmp.tmpdir, 'bower'); + + rimraf(bowerOsTempDir, function (err) { + if (err) return next(err); + + cmd('node', ['test/assets/test-temp-dir/test.js'], { cwd: __dirname + '/../../' }) + .then(function () { + expect(fs.existsSync(bowerOsTempDir)).to.be(true); + expect(fs.readdirSync(bowerOsTempDir)).to.eql([]); + next(); + }, function (err) { + next(new Error(err.details)); + }) + .done(); + }); + }); + + it('should remove the folder on an uncaught exception', function (next) { + var bowerOsTempDir = path.join(tmp.tmpdir, 'bower'); + + rimraf(bowerOsTempDir, function (err) { + if (err) return next(err); + + cmd('node', ['test/assets/test-temp-dir/test-exception.js'], { cwd: __dirname + '/../../' }) + .then(function () { + next(new Error('The command should have failed')); + }, function () { + expect(fs.existsSync(bowerOsTempDir)).to.be(true); + expect(fs.readdirSync(bowerOsTempDir)).to.eql([]); + next(); + }) + .done(); + }); + }); + + it('should set _tempDir with the created directory', function (next) { + var resolver = new Resolver('foo'); + + resolver._createTempDir() + .then(function (dir) { + expect(resolver._tempDir).to.be.ok(); + expect(resolver._tempDir).to.equal(dir); + next(); + }) + .done(); + }); }); describe('_readJson', function () { + var tempDir = path.normalize(__dirname + '/../assets/tmp'); + + beforeEach(function (next) { + mkdirp(tempDir, next); + }); + + afterEach(function (next) { + rimraf(tempDir, next); + }); + it('should return a promise', function (done) { var resolver = new Resolver('foo'), promise = resolver._readJson(); @@ -275,9 +381,50 @@ describe('Resolver', function () { expect(promise.then).to.be.an('function'); promise.then(done.bind(done, null), done.bind(done, null)); }); - it.skip('should read the bower.json file'); - it.skip('should fallback to component.json'); - it.skip('should resolve to an inferred json if no json file was found'); + + it('should read the bower.json file', function (next) { + var resolver = new Resolver('foo'); + + fs.writeFileSync(path.join(tempDir, 'bower.json'), JSON.stringify({ name: 'foo', version: '0.0.0' })); + fs.writeFileSync(path.join(tempDir, 'component.json'), JSON.stringify({ name: 'bar', version: '0.0.0' })); + + resolver._readJson(tempDir) + .then(function (meta) { + expect(meta).to.be.an('object'); + expect(meta.name).to.equal('foo'); + expect(meta.version).to.equal('0.0.0'); + next(); + }) + .done(); + }); + + it('should fallback to component.json', function (next) { + var resolver = new Resolver('foo'); + + fs.writeFileSync(path.join(tempDir, 'component.json'), JSON.stringify({ name: 'bar', version: '0.0.0' })); + + resolver._readJson(tempDir) + .then(function (meta) { + expect(meta).to.be.an('object'); + expect(meta.name).to.equal('bar'); + expect(meta.version).to.equal('0.0.0'); + next(); + }) + .done(); + }); + + it('should resolve to an inferred json if no json file was found', function (next) { + var resolver = new Resolver('foo'); + + resolver._readJson(tempDir) + .then(function (meta) { + expect(meta).to.be.an('object'); + expect(meta.name).to.equal('foo'); + next(); + }) + .done(); + }); + it.skip('should apply normalisation, defaults and validation to the json object'); }); diff --git a/test/test.js b/test/test.js index a739b884..9145758a 100644 --- a/test/test.js +++ b/test/test.js @@ -49,6 +49,11 @@ if (process.argv[1] && !/mocha/.test(process.argv[1])) { //testGitFsResolver(); //testGitRemoteResolverNoTags(); } else { + + // Cleanup the uncaughtException added by the tmp module + // It messes with the mocha uncaughtException event to caught errors + process.removeAllListeners('uncaughtException'); + require('./resolve/resolver'); require('./resolve/worker'); } \ No newline at end of file