diff --git a/.gitignore b/.gitignore index 10cfd35..2061c21 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /doc/ /node_modules/ +/tmp/ *.swp *.pdoc.yaml *.log diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..078510a --- /dev/null +++ b/.travis.yml @@ -0,0 +1,5 @@ +language: node_js +node_js: + - 0.6 +before_script: "npm install --dev" +script: "make test" diff --git a/Makefile b/Makefile index 1bc472f..04f915d 100644 --- a/Makefile +++ b/Makefile @@ -10,12 +10,9 @@ CURR_HEAD := $(firstword $(shell git show-ref --hash HEAD | cut --bytes=-6) mas GITHUB_NAME := nodeca/fs-tools SRC_URL_FMT := https://github.com/${GITHUB_NAME}/blob/${CURR_HEAD}/{file}\#L{line} -test: - NODE_ENV=test node ./test/run.js - lint: @if test ! `which jslint` ; then \ - echo "You need 'jslint' installed in order to generate docs." >&2 ; \ + echo "You need 'jslint' installed in order to run lint." >&2 ; \ echo " $ make dev-deps" >&2 ; \ exit 128 ; \ fi @@ -24,6 +21,14 @@ lint: # (nomen) -> tolerate underscores in identifiers (e.g. `var _val = 1`) jslint --node --nomen --indent=2 ./lib/*.js +test: lint + @if test ! `which vows` ; then \ + echo "You need 'vows' installed in order to run tests." >&2 ; \ + echo " $ make dev-deps" >&2 ; \ + exit 128 ; \ + fi + NODE_ENV=test vows --spec + doc: @if test ! `which ndoc` ; then \ echo "You need 'ndoc' installed in order to generate docs." >&2 ; \ diff --git a/lib/fs-tools.js b/lib/fs-tools.js index 701fd3d..3af49e9 100644 --- a/lib/fs-tools.js +++ b/lib/fs-tools.js @@ -9,16 +9,16 @@ // stdlib -var fs = require('fs'), - path_join = require('path').join, - path_exists = require('path').exists, - path_normalize = require('path').normalize, - dirname = require('path').dirname; +var fs = require('fs'); +var path_join = require('path').join; +var path_exists = require('path').exists; +var path_normalize = require('path').normalize; +var dirname = require('path').dirname; // 3rd-party -var Promise = require('simple-promise'), - _ = require('underscore'); +var Promise = require('simple-promise'); +var _ = require('underscore'); // epxorts: walk, mkdir, copy, remove @@ -71,7 +71,7 @@ function walk_flat(path, iterator, callback) { all = new Promise.Joint(callback); - _(files).chain().map(function(file) { + _(files).chain().map(function (file) { return path_join(path, file); }).each(function (path) { var promise = all.promise(); @@ -95,7 +95,7 @@ function walk_flat(path, iterator, callback) { all.wait(); }); -}; +} // walk_recursive(path, iterator, callback) -> void @@ -115,7 +115,10 @@ function walk_recursive(path, iterator, callback) { // call iterator if not directory iterator(path, stats, callback); }, callback); -}; +} + + +var copy; // hack for lint :)) function copy_file(src, dst, callback) { @@ -127,7 +130,7 @@ function copy_file(src, dst, callback) { // pipe src to dst ifd.pipe(ofd); -}; +} function copy_symlink(src, dst, callback) { @@ -141,7 +144,7 @@ function copy_symlink(src, dst, callback) { // create symlink fs.symlink(linkpath, dst, callback); }); -}; +} function copy_directory(src, dst, callback) { @@ -155,11 +158,11 @@ function copy_directory(src, dst, callback) { copy(sub_src, dst + sub_src.replace(src, ''), sub_stats, next); }, callback); }); -}; +} // copy src to dst recursively -function copy(src, dst, stats, callback) { +copy = function copy(src, dst, stats, callback) { var _callback = function _callback(err) { if (err) { callback(err); @@ -173,7 +176,7 @@ function copy(src, dst, stats, callback) { // the only thing we really care about is permission mode fs.chmod(dst, stats.mode.toString(8).slice(-4), callback); }); - } + }; // *** file if (stats.isFile()) { @@ -195,7 +198,7 @@ function copy(src, dst, stats, callback) { // *** unsupported src callback(new Error("Unsupported type of the source")); -} +}; function remove(path, stats, callback) { @@ -324,7 +327,7 @@ fstools.walk = function (path, pattern, iterator, callback) { } // start walking - walk_recursive(path_normalize(path), function(path, stats, callback) { + walk_recursive(path_normalize(path), function (path, stats, callback) { // call iterator on if (match(path)) { iterator(path, stats, callback); diff --git a/package.json b/package.json index d36184b..8fa6134 100644 --- a/package.json +++ b/package.json @@ -14,8 +14,12 @@ "main" : "./index.js", - "dependencies" : { "underscore": "1.1.7", "simple-promise": "0.1.0" }, + "dependencies" : { + "underscore" : "1.1.7", + "simple-promise" : "0.1.0" + }, "devDependencies" : { + "vows" : "~ 0.6.0", "jslint" : "https://github.com/reid/node-jslint/tarball/6131ebf5713274871b89735105e3286131804771" }, "engines" : { "node": "> 0.4.11" } diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 8818ab3..0000000 --- a/test/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/sandbox/ -!/sandbox/template/ diff --git a/test/copy-test.js b/test/copy-test.js new file mode 100644 index 0000000..a53653f --- /dev/null +++ b/test/copy-test.js @@ -0,0 +1,49 @@ +'use strict'; + + +var Assert = require('assert'); +var FsTools = require('../lib/fs-tools'); +var Helper = require('./helper'); +var exec = require('child_process').exec; + + +require('vows').describe('FsTools').addBatch({ + 'copy()': { + topic: function () { + var self = this; + Helper.createSandbox('copy', function (err, src) { + if (err) { + self.callback(err); + return; + } + + FsTools.copy(src, src + '-dst', function (err) { + if (err) { + self.callback(err); + return; + } + + exec('cd ' + src + ' && -R -p .', function (err, src_out) { + if (err) { + self.callback(err); + return; + } + + exec('cd ' + src + '-dst && -R -p .', function (err, dst_out) { + if (err) { + self.callback(err); + return; + } + + self.callback(null, src_out, dst_out); + }); + }); + }); + }); + }, + + 'should make an exact copy': function (err, src, dst) { + Assert.equal(src, dst); + } + } +}).export(module); diff --git a/test/helper.js b/test/helper.js new file mode 100644 index 0000000..7f61f2f --- /dev/null +++ b/test/helper.js @@ -0,0 +1,32 @@ +'use strict'; + + +var exec = require('child_process').exec; +var Helper = module.exports = {}; +var TMP_DIR = require('fs').realpathSync(__dirname + '/..') + '/tmp'; + + +function runExecs(err, funcs, callback) { + if (err || 0 === funcs.length) { + callback(err); + return; + } + + exec(funcs.shift(), function (err) { + runExecs(err, funcs, callback); + }); +} + + +Helper.createSandbox = function (name, cb) { + var base = TMP_DIR + '/' + name; + + runExecs(null, [ + 'rm -rf ' + base, + 'mkdir -p ' + base + '/foo/bar/baz', + 'touch ' + base + '/foo/bar/abc', + 'cd ' + base + '/foo && ln -s bar/baz baz' + ], function (err) { + cb(err, base); + }); +}; diff --git a/test/remove-test.js b/test/remove-test.js new file mode 100644 index 0000000..f4745c0 --- /dev/null +++ b/test/remove-test.js @@ -0,0 +1,37 @@ +'use strict'; + + +var Assert = require('assert'); +var FsTools = require('../lib/fs-tools'); +var Helper = require('./helper'); +var Path = require('path'); + + +require('vows').describe('FsTools').addBatch({ + 'remove()': { + topic: function () { + var self = this; + Helper.createSandbox('remove', function (err, src) { + if (err) { + self.callback(err); + return; + } + + FsTools.remove(src, function (err) { + if (err) { + self.callback(err); + return; + } + + process.nextTick(function () { + self.callback(null, Path.existsSync(src)); + }); + }); + }); + }, + + 'should remove all': function (err, exists) { + Assert.isFalse(exists); + } + } +}).export(module); diff --git a/test/run.js b/test/run.js deleted file mode 100644 index 5803117..0000000 --- a/test/run.js +++ /dev/null @@ -1,116 +0,0 @@ -'use strict'; - - -// modules -var assert = require('assert'), - path = require('path'), - exec = require('child_process').exec, - fstools = require('..'); - - -var SANDBOX = __dirname + '/sandbox'; - - -function cloneSandbox(name, cb) { - var src = SANDBOX + '/template', - dst = SANDBOX + '/' + name; - exec('cp -rf ' + src + ' ' + dst, cb); -} - -function dropSandbox(name, cb) { - exec('rm -rf ' + SANDBOX + '/' + name, cb); -} - -function reportError(err) { - console.error(err.stack || err.message || err.toString()); - process.exit(1); -} - - -cloneSandbox('remove', function (err) { - if (err) { - reportError(err); - return; - } - - if (!path.existsSync(SANDBOX + '/remove')) { - reportError(Error("Sandbox not created")); - return; - } - - fstools.remove(SANDBOX + '/remove', function (err) { - if (err) { - reportError(err); - return; - } - - if (path.existsSync(SANDBOX + '/remove')) { - console.log('remove() FAIL'); - } else { - console.log('remove() PASS'); - } - - dropSandbox('remove', function (err) { - if (err) { - reportError(err); - return; - } - }); - }); -}); - - -cloneSandbox('copy-src', function (err) { - if (err) { - reportError(err); - return; - } - - if (!path.existsSync(SANDBOX + '/copy-src')) { - reportError(Error("Sandbox not created")); - return; - } - - var src = SANDBOX + '/copy-src', dst = SANDBOX + '/copy-dst'; - - fstools.copy(src, dst, function (err) { - if (err) { - reportError(err); - return; - } - - exec('cd ' + src + ' && tree .', function (err, src_out) { - if (err) { - reportError(err); - return; - } - - exec('cd ' + dst + ' && tree .', function (err, dst_out) { - if (err) { - reportError(err); - return; - } - - if (src_out === dst_out) { - console.log('copy() PASS'); - } else { - console.log('copy() FAIL'); - } - - dropSandbox('copy-src', function (err) { - if (err) { - reportError(err); - return; - } - - dropSandbox('copy-dst', function (err) { - if (err) { - reportError(err); - return; - } - }); - }); - }); - }); - }); -});