[Pkg-javascript-commits] [node-tmp] 01/03: Imported Upstream version 0.0.24
Sebastiaan Couwenberg
sebastic at moszumanska.debian.org
Sat Feb 28 20:39:39 UTC 2015
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository node-tmp.
commit ba1f6ac99ecf7e284070afc4d4b85daba8fcddce
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Sat Feb 28 17:03:13 2015 +0100
Imported Upstream version 0.0.24
---
.gitignore | 2 +
.travis.yml | 5 +
README.md | 162 ++++++++++++++++++++++++++
lib/tmp.js | 307 +++++++++++++++++++++++++++++++++++++++++++++++++
package.json | 41 +++++++
test/base.js | 74 ++++++++++++
test/dir-test.js | 196 +++++++++++++++++++++++++++++++
test/file-test.js | 177 ++++++++++++++++++++++++++++
test/graceful.js | 15 +++
test/keep.js | 11 ++
test/name-test.js | 82 +++++++++++++
test/spawn.js | 32 ++++++
test/symlinkme/file.js | 0
test/unsafe.js | 30 +++++
14 files changed, 1134 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..78f2710
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+node_modules/
+.idea/
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..0175d82
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,5 @@
+language: node_js
+node_js:
+ - "0.6"
+ - "0.8"
+ - "0.10"
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3a1a509
--- /dev/null
+++ b/README.md
@@ -0,0 +1,162 @@
+# Tmp
+
+A simple temporary file and directory creator for [node.js.][1]
+
+[![Build Status](https://secure.travis-ci.org/raszi/node-tmp.png?branch=master)](http://travis-ci.org/raszi/node-tmp)
+
+## About
+
+The main difference between bruce's [node-temp][2] is that mine more
+aggressively checks for the existence of the newly created temporary file and
+creates the new file with `O_EXCL` instead of simple `O_CREAT | O_RDRW`, so it
+is safer.
+
+The API is slightly different as well, Tmp does not yet provide synchronous
+calls and all the parameters are optional.
+
+You can set whether you want to remove the temporary file on process exit or
+not, and the destination directory can also be set.
+
+## How to install
+
+```bash
+npm install tmp
+```
+
+## Usage
+
+### File creation
+
+Simple temporary file creation, the file will be unlinked on process exit.
+
+```javascript
+var tmp = require('tmp');
+
+tmp.file(function _tempFileCreated(err, path, fd) {
+ if (err) throw err;
+
+ console.log("File: ", path);
+ console.log("Filedescriptor: ", fd);
+});
+```
+
+### Directory creation
+
+Simple temporary directory creation, it will be removed on process exit.
+
+If the directory still contains items on process exit, then it won't be removed.
+
+```javascript
+var tmp = require('tmp');
+
+tmp.dir(function _tempDirCreated(err, path) {
+ if (err) throw err;
+
+ console.log("Dir: ", path);
+});
+```
+
+If you want to cleanup the directory even when there are entries in it, then
+you can pass the `unsafeCleanup` option when creating it.
+
+### Filename generation
+
+It is possible with this library to generate a unique filename in the specified
+directory.
+
+```javascript
+var tmp = require('tmp');
+
+tmp.tmpName(function _tempNameGenerated(err, path) {
+ if (err) throw err;
+
+ console.log("Created temporary filename: ", path);
+});
+```
+
+## Advanced usage
+
+### File creation
+
+Creates a file with mode `0644`, prefix will be `prefix-` and postfix will be `.txt`.
+
+```javascript
+var tmp = require('tmp');
+
+tmp.file({ mode: 0644, prefix: 'prefix-', postfix: '.txt' }, function _tempFileCreated(err, path, fd) {
+ if (err) throw err;
+
+ console.log("File: ", path);
+ console.log("Filedescriptor: ", fd);
+});
+```
+
+### Directory creation
+
+Creates a directory with mode `0755`, prefix will be `myTmpDir_`.
+
+```javascript
+var tmp = require('tmp');
+
+tmp.dir({ mode: 0750, prefix: 'myTmpDir_' }, function _tempDirCreated(err, path) {
+ if (err) throw err;
+
+ console.log("Dir: ", path);
+});
+```
+
+### mkstemps like
+
+Creates a new temporary directory with mode `0700` and filename like `/tmp/tmp-nk2J1u`.
+
+```javascript
+var tmp = require('tmp');
+
+tmp.dir({ template: '/tmp/tmp-XXXXXX' }, function _tempDirCreated(err, path) {
+ if (err) throw err;
+
+ console.log("Dir: ", path);
+});
+```
+
+### Filename generation
+
+The `tmpName()` function accepts the `prefix`, `postfix`, `dir`, etc. parameters also:
+
+```javascript
+var tmp = require('tmp');
+
+tmp.tmpName({ template: '/tmp/tmp-XXXXXX' }, function _tempNameGenerated(err, path) {
+ if (err) throw err;
+
+ console.log("Created temporary filename: ", path);
+});
+```
+
+## Graceful cleanup
+
+One may want to cleanup the temporary files even when an uncaught exception
+occurs. To enforce this, you can call the `setGracefulCleanup()` method:
+
+```javascript
+var tmp = require('tmp');
+
+tmp.setGracefulCleanup();
+```
+
+## Options
+
+All options are optional :)
+
+ * `mode`: the file mode to create with, it fallbacks to `0600` on file creation and `0700` on directory creation
+ * `prefix`: the optional prefix, fallbacks to `tmp-` if not provided
+ * `postfix`: the optional postfix, fallbacks to `.tmp` on file creation
+ * `template`: [`mkstemps`][3] like filename template, no default
+ * `dir`: the optional temporary directory, fallbacks to system default (guesses from environment)
+ * `tries`: how many times should the function try to get a unique filename before giving up, default `3`
+ * `keep`: signals that the temporary file or directory should not be deleted on exit, default is `false`, means delete
+ * `unsafeCleanup`: recursively removes the created temporary directory, even when it's not empty. default is `false`
+
+[1]: http://nodejs.org/
+[2]: https://github.com/bruce/node-temp
+[3]: http://www.kernel.org/doc/man-pages/online/pages/man3/mkstemp.3.html
diff --git a/lib/tmp.js b/lib/tmp.js
new file mode 100644
index 0000000..ea84faa
--- /dev/null
+++ b/lib/tmp.js
@@ -0,0 +1,307 @@
+/*!
+ * Tmp
+ *
+ * Copyright (c) 2011-2013 KARASZI Istvan <github at spam.raszi.hu>
+ *
+ * MIT Licensed
+ */
+
+/**
+ * Module dependencies.
+ */
+var
+ fs = require('fs'),
+ path = require('path'),
+ os = require('os'),
+ exists = fs.exists || path.exists,
+ tmpDir = os.tmpDir || _getTMPDir,
+ _c = require('constants');
+
+/**
+ * The working inner variables.
+ */
+var
+ // store the actual TMP directory
+ _TMP = tmpDir(),
+
+ // the random characters to choose from
+ randomChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz",
+ randomCharsLength = randomChars.length,
+
+ // this will hold the objects need to be removed on exit
+ _removeObjects = [],
+
+ _gracefulCleanup = false,
+ _uncaughtException = false;
+
+/**
+ * Gets the temp directory.
+ *
+ * @return {String}
+ * @api private
+ */
+function _getTMPDir() {
+ var tmpNames = [ 'TMPDIR', 'TMP', 'TEMP' ];
+
+ for (var i = 0, length = tmpNames.length; i < length; i++) {
+ if (_isUndefined(process.env[tmpNames[i]])) continue;
+
+ return process.env[tmpNames[i]];
+ }
+
+ // fallback to the default
+ return '/tmp';
+}
+
+/**
+ * Checks whether the `obj` parameter is defined or not.
+ *
+ * @param {Object} obj
+ * @return {Boolean}
+ * @api private
+ */
+function _isUndefined(obj) {
+ return typeof obj === 'undefined';
+}
+
+/**
+ * Parses the function arguments.
+ *
+ * This function helps to have optional arguments.
+ *
+ * @param {Object} options
+ * @param {Function} callback
+ * @api private
+ */
+function _parseArguments(options, callback) {
+ if (!callback || typeof callback != "function") {
+ callback = options;
+ options = {};
+ }
+
+ return [ options, callback ];
+}
+
+/**
+ * Gets a temporary file name.
+ *
+ * @param {Object} opts
+ * @param {Function} cb
+ * @api private
+ */
+function _getTmpName(options, callback) {
+ var
+ args = _parseArguments(options, callback),
+ opts = args[0],
+ cb = args[1],
+ template = opts.template,
+ templateDefined = !_isUndefined(template),
+ tries = opts.tries || 3;
+
+ if (isNaN(tries) || tries < 0)
+ return cb(new Error('Invalid tries'));
+
+ if (templateDefined && !template.match(/XXXXXX/))
+ return cb(new Error('Invalid template provided'));
+
+ function _getName() {
+
+ // prefix and postfix
+ if (!templateDefined) {
+ var name = [
+ (_isUndefined(opts.prefix)) ? 'tmp-' : opts.prefix,
+ process.pid,
+ (Math.random() * 0x1000000000).toString(36),
+ opts.postfix
+ ].join('');
+
+ return path.join(opts.dir || _TMP, name);
+ }
+
+ // mkstemps like template
+ var chars = [];
+
+ for (var i = 0; i < 6; i++) {
+ chars.push(randomChars.substr(Math.floor(Math.random() * randomCharsLength), 1));
+ }
+
+ return template.replace(/XXXXXX/, chars.join(''));
+ }
+
+ (function _getUniqueName() {
+ var name = _getName();
+
+ // check whether the path exists then retry if needed
+ exists(name, function _pathExists(pathExists) {
+ if (pathExists) {
+ if (tries-- > 0) return _getUniqueName();
+
+ return cb(new Error('Could not get a unique tmp filename, max tries reached'));
+ }
+
+ cb(null, name);
+ });
+ }());
+}
+
+/**
+ * Creates and opens a temporary file.
+ *
+ * @param {Object} options
+ * @param {Function} callback
+ * @api public
+ */
+function _createTmpFile(options, callback) {
+ var
+ args = _parseArguments(options, callback),
+ opts = args[0],
+ cb = args[1];
+
+ opts.postfix = (_isUndefined(opts.postfix)) ? '.tmp' : opts.postfix;
+
+ // gets a temporary filename
+ _getTmpName(opts, function _tmpNameCreated(err, name) {
+ if (err) return cb(err);
+
+ // create and open the file
+ fs.open(name, _c.O_CREAT | _c.O_EXCL | _c.O_RDWR, opts.mode || 0600, function _fileCreated(err, fd) {
+ if (err) return cb(err);
+
+ var removeCallback = _prepareRemoveCallback(fs.unlinkSync.bind(fs), name);
+
+ if (!opts.keep) {
+ _removeObjects.unshift(removeCallback);
+ }
+
+ cb(null, name, fd, removeCallback);
+ });
+ });
+}
+
+/**
+ * Removes files and folders in a directory recursively.
+ *
+ * @param {String} dir
+ */
+function _rmdirRecursiveSync(dir) {
+ var files = fs.readdirSync(dir);
+
+ for (var i = 0, length = files.length; i < length; i++) {
+ var file = path.join(dir, files[i]);
+ // lstat so we don't recurse into symlinked directories.
+ var stat = fs.lstatSync(file);
+
+ if (stat.isDirectory()) {
+ _rmdirRecursiveSync(file);
+ } else {
+ fs.unlinkSync(file);
+ }
+ }
+
+ fs.rmdirSync(dir);
+}
+
+/**
+ *
+ * @param {Function} removeFunction
+ * @param {String} path
+ * @returns {Function}
+ * @private
+ */
+function _prepareRemoveCallback(removeFunction, path) {
+ var called = false;
+ return function() {
+ if (called) {
+ return;
+ }
+
+ removeFunction(path);
+
+ called = true;
+ };
+}
+
+/**
+ * Creates a temporary directory.
+ *
+ * @param {Object} options
+ * @param {Function} callback
+ * @api public
+ */
+function _createTmpDir(options, callback) {
+ var
+ args = _parseArguments(options, callback),
+ opts = args[0],
+ cb = args[1];
+
+ // gets a temporary filename
+ _getTmpName(opts, function _tmpNameCreated(err, name) {
+ if (err) return cb(err);
+
+ // create the directory
+ fs.mkdir(name, opts.mode || 0700, function _dirCreated(err) {
+ if (err) return cb(err);
+
+ var removeCallback = _prepareRemoveCallback(
+ opts.unsafeCleanup
+ ? _rmdirRecursiveSync
+ : fs.rmdirSync.bind(fs),
+ name
+ );
+
+ if (!opts.keep) {
+ _removeObjects.unshift(removeCallback);
+ }
+
+ cb(null, name, removeCallback);
+ });
+ });
+}
+
+/**
+ * The garbage collector.
+ *
+ * @api private
+ */
+function _garbageCollector() {
+ if (_uncaughtException && !_gracefulCleanup) {
+ return;
+ }
+
+ for (var i = 0, length = _removeObjects.length; i < length; i++) {
+ try {
+ _removeObjects[i].call(null);
+ } catch (e) {
+ // already removed?
+ }
+ }
+}
+
+function _setGracefulCleanup() {
+ _gracefulCleanup = true;
+}
+
+var version = process.versions.node.split('.').map(function (value) {
+ return parseInt(value, 10);
+});
+
+if (version[0] === 0 && (version[1] < 9 || version[1] === 9 && version[2] < 5)) {
+ process.addListener('uncaughtException', function _uncaughtExceptionThrown( err ) {
+ _uncaughtException = true;
+ _garbageCollector();
+
+ throw err;
+ });
+}
+
+process.addListener('exit', function _exit(code) {
+ if (code) _uncaughtException = true;
+ _garbageCollector();
+});
+
+// exporting all the needed methods
+module.exports.tmpdir = _TMP;
+module.exports.dir = _createTmpDir;
+module.exports.file = _createTmpFile;
+module.exports.tmpName = _getTmpName;
+module.exports.setGracefulCleanup = _setGracefulCleanup;
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..eeb3127
--- /dev/null
+++ b/package.json
@@ -0,0 +1,41 @@
+{
+ "name": "tmp",
+ "version": "0.0.24",
+ "description": "Temporary file and directory creator",
+ "author": "KARASZI István <github at spam.raszi.hu> (http://raszi.hu/)",
+
+ "homepage": "http://github.com/raszi/node-tmp",
+ "keywords": [ "temporary", "tmp", "temp", "tempdir", "tempfile", "tmpdir", "tmpfile" ],
+
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "http://opensource.org/licenses/MIT"
+ }
+ ],
+
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/raszi/node-tmp.git"
+ },
+
+ "bugs": {
+ "url": "http://github.com/raszi/node-tmp/issues"
+ },
+
+ "main": "lib/tmp.js",
+
+ "scripts": {
+ "test": "vows test/*-test.js"
+ },
+
+ "engines": {
+ "node": ">=0.4.0"
+ },
+
+ "dependencies": {},
+
+ "devDependencies": {
+ "vows": "~0.7.0"
+ }
+}
diff --git a/test/base.js b/test/base.js
new file mode 100644
index 0000000..498d8fb
--- /dev/null
+++ b/test/base.js
@@ -0,0 +1,74 @@
+var
+ assert = require('assert'),
+ path = require('path'),
+ exec = require('child_process').exec;
+
+function _spawnTestWithError(testFile, params, cb) {
+ _spawnTest(true, testFile, params, cb);
+}
+
+function _spawnTestWithoutError(testFile, params, cb) {
+ _spawnTest(false, testFile, params, cb);
+}
+
+function _spawnTest(passError, testFile, params, cb) {
+ var
+ filename,
+ node_path = process.argv[0],
+ command = [ node_path, path.join(__dirname, testFile) ].concat(params).join(' ');
+
+ exec(command, function _execDone(err, stdout, stderr) {
+ if (passError) {
+ if (err) {
+ return cb(err);
+ } else if (stderr.length > 0) {
+ return cb(stderr.toString());
+ }
+ }
+
+ return cb(null, stdout.toString());
+ });
+}
+
+function _testStat(stat, mode) {
+ assert.equal(stat.uid, process.getuid(), 'should have the same UID');
+ assert.equal(stat.gid, process.getgid(), 'should have the same GUID');
+ assert.equal(stat.mode, mode);
+}
+
+function _testPrefix(prefix) {
+ return function _testPrefixGenerated(err, name, fd) {
+ assert.equal(path.basename(name).slice(0, prefix.length), prefix, 'should have the provided prefix');
+ };
+}
+
+function _testPostfix(postfix) {
+ return function _testPostfixGenerated(err, name, fd) {
+ assert.equal(name.slice(name.length - postfix.length, name.length), postfix, 'should have the provided postfix');
+ };
+}
+
+function _testKeep(type, keep, cb) {
+ _spawnTestWithError('keep.js', [ type, keep ], cb);
+}
+
+function _testGraceful(type, graceful, cb) {
+ _spawnTestWithoutError('graceful.js', [ type, graceful ], cb);
+}
+
+function _assertName(err, name) {
+ assert.isString(name);
+ assert.isNotZero(name.length);
+}
+
+function _testUnsafeCleanup(unsafe, cb) {
+ _spawnTestWithoutError('unsafe.js', [ 'dir', unsafe ], cb);
+}
+
+module.exports.testStat = _testStat;
+module.exports.testPrefix = _testPrefix;
+module.exports.testPostfix = _testPostfix;
+module.exports.testKeep = _testKeep;
+module.exports.testGraceful = _testGraceful;
+module.exports.assertName = _assertName;
+module.exports.testUnsafeCleanup = _testUnsafeCleanup;
diff --git a/test/dir-test.js b/test/dir-test.js
new file mode 100644
index 0000000..2e4e529
--- /dev/null
+++ b/test/dir-test.js
@@ -0,0 +1,196 @@
+var
+ vows = require('vows'),
+ assert = require('assert'),
+
+ path = require('path'),
+ fs = require('fs'),
+ existsSync = fs.existsSync || path.existsSync,
+
+ tmp = require('../lib/tmp.js'),
+ Test = require('./base.js');
+
+
+function _testDir(mode) {
+ return function _testDirGenerated(err, name) {
+ assert.ok(existsSync(name), 'should exist');
+
+ var stat = fs.statSync(name);
+ assert.ok(stat.isDirectory(), 'should be a directory');
+
+ Test.testStat(stat, mode);
+ };
+}
+
+vows.describe('Directory creation').addBatch({
+ 'when using without parameters': {
+ topic: function () {
+ tmp.dir(this.callback);
+ },
+
+ 'should be a directory': _testDir(040700),
+ 'should have the default prefix': Test.testPrefix('tmp-')
+ },
+
+ 'when using with prefix': {
+ topic: function () {
+ tmp.dir({ prefix: 'something' }, this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should be a directory': _testDir(040700),
+ 'should have the provided prefix': Test.testPrefix('something')
+ },
+
+ 'when using with postfix': {
+ topic: function () {
+ tmp.dir({ postfix: '.txt' }, this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should be a directory': _testDir(040700),
+ 'should have the provided postfix': Test.testPostfix('.txt')
+ },
+
+ 'when using template': {
+ topic: function () {
+ tmp.dir({ template: path.join(tmp.tmpdir, 'clike-XXXXXX-postfix') }, this.callback);
+ },
+
+ 'should not return with error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should be a file': _testDir(040700),
+ 'should have the provided prefix': Test.testPrefix('clike-'),
+ 'should have the provided postfix': Test.testPostfix('-postfix')
+ },
+
+ 'when using multiple options': {
+ topic: function () {
+ tmp.dir({ prefix: 'foo', postfix: 'bar', mode: 0750 }, this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should be a directory': _testDir(040750),
+ 'should have the provided prefix': Test.testPrefix('foo'),
+ 'should have the provided postfix': Test.testPostfix('bar')
+ },
+
+ 'when using multiple options and mode': {
+ topic: function () {
+ tmp.dir({ prefix: 'complicated', postfix: 'options', mode: 0755 }, this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should be a directory': _testDir(040755),
+ 'should have the provided prefix': Test.testPrefix('complicated'),
+ 'should have the provided postfix': Test.testPostfix('options')
+ },
+
+ 'no tries': {
+ topic: function () {
+ tmp.dir({ tries: -1 }, this.callback);
+ },
+
+ 'should return with an error': assert.isObject
+ },
+
+ 'keep testing': {
+ topic: function () {
+ Test.testKeep('dir', '1', this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should be a dir': function (err, name) {
+ _testDir(040700)(err, name);
+ fs.rmdirSync(name);
+ }
+ },
+
+ 'unlink testing': {
+ topic: function () {
+ Test.testKeep('dir', '0', this.callback);
+ },
+
+ 'should not return with error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should not exist': function (err, name) {
+ assert.ok(!existsSync(name), "Directory should be removed");
+ }
+ },
+
+ 'non graceful testing': {
+ topic: function () {
+ Test.testGraceful('dir', '0', this.callback);
+ },
+
+ 'should not return with error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should be a dir': function (err, name) {
+ _testDir(040700)(err, name);
+ fs.rmdirSync(name);
+ }
+ },
+
+ 'graceful testing': {
+ topic: function () {
+ Test.testGraceful('dir', '1', this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should not exist': function (err, name) {
+ assert.ok(!existsSync(name), "Directory should be removed");
+ }
+ },
+
+ 'unsafeCleanup === true': {
+ topic: function () {
+ Test.testUnsafeCleanup('1', this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should not exist': function (err, name) {
+ assert.ok(!existsSync(name), "Directory should be removed");
+ },
+ 'should remove symlinked dir': function(err, name) {
+ assert.ok(
+ !existsSync(name + '/symlinkme-target'),
+ 'should remove target'
+ );
+ },
+ 'should not remove contents of symlink dir': function(err, name) {
+ assert.ok(
+ existsSync(__dirname + '/symlinkme/file.js'),
+ 'should not remove symlinked directory\'s content'
+ );
+ }
+ },
+
+ 'unsafeCleanup === false': {
+ topic: function () {
+ Test.testUnsafeCleanup('0', this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should be a directory': _testDir(040700)
+ },
+
+ 'remove callback': {
+ topic: function () {
+ tmp.dir(this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'removeCallback should remove directory': function (_err, name, removeCallback) {
+ removeCallback();
+ assert.ok(!existsSync(name), "Directory should be removed");
+ }
+ }
+}).exportTo(module);
diff --git a/test/file-test.js b/test/file-test.js
new file mode 100644
index 0000000..d9605b3
--- /dev/null
+++ b/test/file-test.js
@@ -0,0 +1,177 @@
+var
+ vows = require('vows'),
+ assert = require('assert'),
+
+ path = require('path'),
+ fs = require('fs'),
+ existsSync = fs.existsSync || path.existsSync,
+
+ tmp = require('../lib/tmp.js'),
+ Test = require('./base.js');
+
+
+function _testFile(mode, fdTest) {
+ return function _testFileGenerated(err, name, fd) {
+ assert.ok(existsSync(name), 'should exist');
+
+ var stat = fs.statSync(name);
+ assert.equal(stat.size, 0, 'should have zero size');
+ assert.ok(stat.isFile(), 'should be a file');
+
+ Test.testStat(stat, mode);
+
+ // check with fstat as well (fd checking)
+ if (fdTest) {
+ var fstat = fs.fstatSync(fd);
+ assert.deepEqual(fstat, stat, 'fstat results should be the same');
+
+ var data = new Buffer('something');
+ assert.equal(fs.writeSync(fd, data, 0, data.length, 0), data.length, 'should be writable');
+ assert.ok(!fs.closeSync(fd), 'should not return with error');
+ }
+ };
+}
+
+vows.describe('File creation').addBatch({
+ 'when using without parameters': {
+ topic: function () {
+ tmp.file(this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should be a file': _testFile(0100600, true),
+ 'should have the default prefix': Test.testPrefix('tmp-'),
+ 'should have the default postfix': Test.testPostfix('.tmp')
+ },
+
+ 'when using with prefix': {
+ topic: function () {
+ tmp.file({ prefix: 'something' }, this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should be a file': _testFile(0100600, true),
+ 'should have the provided prefix': Test.testPrefix('something')
+ },
+
+ 'when using with postfix': {
+ topic: function () {
+ tmp.file({ postfix: '.txt' }, this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should be a file': _testFile(0100600, true),
+ 'should have the provided postfix': Test.testPostfix('.txt')
+ },
+
+ 'when using template': {
+ topic: function () {
+ tmp.file({ template: path.join(tmp.tmpdir, 'clike-XXXXXX-postfix') }, this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should be a file': _testFile(0100600, true),
+ 'should have the provided prefix': Test.testPrefix('clike-'),
+ 'should have the provided postfix': Test.testPostfix('-postfix')
+ },
+
+ 'when using multiple options': {
+ topic: function () {
+ tmp.file({ prefix: 'foo', postfix: 'bar', mode: 0640 }, this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should be a file': _testFile(0100640, true),
+ 'should have the provided prefix': Test.testPrefix('foo'),
+ 'should have the provided postfix': Test.testPostfix('bar')
+ },
+
+ 'when using multiple options and mode': {
+ topic: function () {
+ tmp.file({ prefix: 'complicated', postfix: 'options', mode: 0644 }, this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should be a file': _testFile(0100644, true),
+ 'should have the provided prefix': Test.testPrefix('complicated'),
+ 'should have the provided postfix': Test.testPostfix('options')
+ },
+
+ 'no tries': {
+ topic: function () {
+ tmp.file({ tries: -1 }, this.callback);
+ },
+
+ 'should not be created': assert.isObject
+ },
+
+ 'keep testing': {
+ topic: function () {
+ Test.testKeep('file', '1', this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should be a file': function (err, name) {
+ _testFile(0100600, false)(err, name, null);
+ fs.unlinkSync(name);
+ }
+ },
+
+ 'unlink testing': {
+ topic: function () {
+ Test.testKeep('file', '0', this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should not exist': function (err, name) {
+ assert.ok(!existsSync(name), "File should be removed");
+ }
+ },
+
+ 'non graceful testing': {
+ topic: function () {
+ Test.testGraceful('file', '0', this.callback);
+ },
+
+ 'should not return with error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should be a file': function (err, name) {
+ _testFile(0100600, false)(err, name, null);
+ fs.unlinkSync(name);
+ }
+ },
+
+ 'graceful testing': {
+ topic: function () {
+ Test.testGraceful('file', '1', this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'should not exist': function (err, name) {
+ assert.ok(!existsSync(name), "File should be removed");
+ }
+ },
+
+ 'remove callback': {
+ topic: function () {
+ tmp.file(this.callback);
+ },
+
+ 'should not return with an error': assert.isNull,
+ 'should return with a name': Test.assertName,
+ 'removeCallback should remove file': function (_err, name, _fd, removeCallback) {
+ removeCallback();
+ assert.ok(!existsSync(name), "File should be removed");
+ }
+ }
+
+}).exportTo(module);
diff --git a/test/graceful.js b/test/graceful.js
new file mode 100644
index 0000000..c898656
--- /dev/null
+++ b/test/graceful.js
@@ -0,0 +1,15 @@
+var
+ tmp = require('../lib/tmp'),
+ spawn = require('./spawn');
+
+var graceful = spawn.arg;
+
+if (graceful) {
+ tmp.setGracefulCleanup();
+}
+
+spawn.tmpFunction(function (err, name) {
+ spawn.out(name, function () {
+ throw new Error("Thrown on purpose");
+ });
+});
diff --git a/test/keep.js b/test/keep.js
new file mode 100644
index 0000000..9538605
--- /dev/null
+++ b/test/keep.js
@@ -0,0 +1,11 @@
+var spawn = require('./spawn');
+
+var keep = spawn.arg;
+
+spawn.tmpFunction({ keep: keep }, function (err, name) {
+ if (err) {
+ spawn.err(err, spawn.exit);
+ } else {
+ spawn.out(name, spawn.exit);
+ }
+});
diff --git a/test/name-test.js b/test/name-test.js
new file mode 100644
index 0000000..a242c21
--- /dev/null
+++ b/test/name-test.js
@@ -0,0 +1,82 @@
+var
+ vows = require('vows'),
+ assert = require('assert'),
+
+ path = require('path'),
+
+ tmp = require('../lib/tmp.js'),
+ Test = require('./base.js');
+
+vows.describe('Name creation').addBatch({
+ 'when using without parameters': {
+ topic: function () {
+ tmp.tmpName(this.callback);
+ },
+
+ 'should not return with error': assert.isNull,
+ 'should have the default prefix': Test.testPrefix('tmp-')
+ },
+
+ 'when using with prefix': {
+ topic: function () {
+ tmp.tmpName({ prefix: 'something' }, this.callback);
+ },
+
+ 'should not return with error': assert.isNull,
+ 'should have the provided prefix': Test.testPrefix('something')
+ },
+
+ 'when using with postfix': {
+ topic: function () {
+ tmp.tmpName({ postfix: '.txt' }, this.callback);
+ },
+
+ 'should not return with error': assert.isNull,
+ 'should have the provided postfix': Test.testPostfix('.txt')
+
+ },
+
+ 'when using template': {
+ topic: function () {
+ tmp.tmpName({ template: path.join(tmp.tmpdir, 'clike-XXXXXX-postfix') }, this.callback);
+ },
+
+ 'should not return with error': assert.isNull,
+ 'should have the provided prefix': Test.testPrefix('clike-'),
+ 'should have the provided postfix': Test.testPostfix('-postfix'),
+ 'should have template filled': function (err, name) {
+ assert.isTrue(/[a-zA-Z0-9]{6}/.test(name));
+ }
+ },
+
+ 'when using multiple options': {
+ topic: function () {
+ tmp.tmpName({ prefix: 'foo', postfix: 'bar', tries: 5 }, this.callback);
+ },
+
+ 'should not return with error': assert.isNull,
+ 'should have the provided prefix': Test.testPrefix('foo'),
+ 'should have the provided postfix': Test.testPostfix('bar')
+ },
+
+ 'no tries': {
+ topic: function () {
+ tmp.tmpName({ tries: -1 }, this.callback);
+ },
+
+ 'should fail': function (err, name) {
+ assert.isObject(err);
+ }
+ },
+
+ 'tries not numeric': {
+ topic: function () {
+ tmp.tmpName({ tries: 'hello'}, this.callback);
+ },
+
+ 'should fail': function (err, name) {
+ assert.isObject(err);
+ }
+ }
+
+}).exportTo(module);
diff --git a/test/spawn.js b/test/spawn.js
new file mode 100644
index 0000000..6468eb3
--- /dev/null
+++ b/test/spawn.js
@@ -0,0 +1,32 @@
+var
+ fs = require('fs'),
+ tmp = require('../lib/tmp');
+
+function _writeSync(stream, str, cb) {
+ var flushed = stream.write(str);
+ if (flushed) {
+ return cb(null);
+ }
+
+ stream.once('drain', function _flushed() {
+ cb(null);
+ });
+}
+
+module.exports.out = function (str, cb) {
+ _writeSync(process.stdout, str, cb);
+};
+
+module.exports.err = function (str, cb) {
+ _writeSync(process.stderr, str, cb);
+};
+
+module.exports.exit = function () {
+ process.exit(0);
+};
+
+var type = process.argv[2];
+module.exports.tmpFunction = (type == 'file') ? tmp.file : tmp.dir;
+
+var arg = (process.argv[3] && parseInt(process.argv[3], 10) === 1) ? true : false;
+module.exports.arg = arg;
diff --git a/test/symlinkme/file.js b/test/symlinkme/file.js
new file mode 100644
index 0000000..e69de29
diff --git a/test/unsafe.js b/test/unsafe.js
new file mode 100644
index 0000000..73e4fb3
--- /dev/null
+++ b/test/unsafe.js
@@ -0,0 +1,30 @@
+var
+ fs = require('fs'),
+ join = require('path').join,
+ spawn = require('./spawn');
+
+var unsafe = spawn.arg;
+spawn.tmpFunction({ unsafeCleanup: unsafe }, function (err, name) {
+ if (err) {
+ spawn.err(err, spawn.exit);
+ return;
+ }
+
+ try {
+ // file that should be removed
+ var fd = fs.openSync(join(name, 'should-be-removed.file'), 'w');
+ fs.closeSync(fd);
+
+ // in tree source
+ var symlinkSource = join(__dirname, 'symlinkme');
+ // testing target
+ var symlinkTarget = join(name, 'symlinkme-target');
+
+ // symlink that should be removed but the contents should be preserved.
+ fs.symlinkSync(symlinkSource, symlinkTarget, 'dir');
+
+ spawn.out(name, spawn.exit);
+ } catch (e) {
+ spawn.err(e.toString(), spawn.exit);
+ }
+});
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-tmp.git
More information about the Pkg-javascript-commits
mailing list