Skip to content

Instantly share code, notes, and snippets.

@creationix
Created August 15, 2012 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save creationix/305ad492c2fd20c466be to your computer and use it in GitHub Desktop.
Save creationix/305ad492c2fd20c466be to your computer and use it in GitHub Desktop.
vfs-local unit tests

TOC

# vfs-local ## vfs.resolve() should prepend root when resolving virtual paths.
var vpath = "/dir/stuff.json";
vfs.resolve(vpath, {}, function (err, meta) {
  if (err) throw err;
  expect(meta).property("path").equals(base + vpath);
  done();
});

should reject paths that resolve outside the root.

vfs.resolve("/../test-local.js", {}, function (err, meta) {
  expect(err).property("code").equals("EACCESS");
  done();
});

should not prepend when already rooted.

var path = base + "/file.txt";
vfs.resolve(path, { alreadyRooted: true }, function (err, meta) {
  if (err) throw err;
  expect(meta).property("path").equal(path);
  done();
});

should error with ENOENT when the path is invalid.

vfs.resolve("/notexists.txt", {}, function (err, meta) {
  expect(err).property("code").equals("ENOENT");
  done();
});
## vfs.stat() should return stat info for the text file.
vfs.stat("/file.txt", {}, function (err, stat) {
  if (err) throw err;
  expect(stat).property("name").equal("file.txt");
  expect(stat).property("size").equal(23);
  expect(stat).property("mime").equal("text/plain");
  done();
});

should error with ENOENT when the file doesn't exist.

vfs.stat("/badfile.json", {}, function (err, stat) {
  expect(err).property("code").equal("ENOENT");
  done();
});
## vfs.readfile() should read the text file.
vfs.readfile("/file.txt", {}, function (err, meta) {
  if (err) throw err;
  expect(meta).property("mime").equals("text/plain");
  expect(meta).property("size").equals(23);
  expect(meta).property("etag");
  expect(meta).property("stream").property("readable");
  var stream = meta.stream;
  var chunks = [];
  var length = 0;
  stream.on("data", function (chunk) {
    chunks.push(chunk);
    length += chunk.length;
  });
  stream.on("end", function () {
    expect(length).equal(23);
    var body = chunks.join("");
    expect(body).equal("This is a simple file!\n");
    done();
  });
});

should error with ENOENT on missing files.

vfs.readfile("/badfile.json", {}, function (err, stat) {
  expect(err).property("code").equal("ENOENT");
  done();
});

should error with EISDIR on directories.

vfs.readfile("/", {}, function (err, stat) {
  expect(err).property("code").equal("EISDIR");
  done();
});
## vfs.readdir() should read the directory.
vfs.readdir("/", {}, function (err, meta) {
  if (err) throw err;
  expect(meta).property("etag");
  expect(meta).property("stream").property("readable");
  var stream = meta.stream;
  var parts = [];
  stream.on("data", function (part) {
    parts.push(part);
  });
  stream.on("end", function () {
    expect(parts).length(5);
    done();
  });
});

should error with ENOENT when the folder doesn't exist.

vfs.readdir("/fake", {}, function (err, meta) {
  expect(err).property("code").equal("ENOENT");
  done();
});

should error with ENOTDIR when the path is a file.

vfs.readdir("/file.txt", {}, function (err, meta) {
  expect(err).property("code").equal("ENOTDIR");
  done();
});
## vfs.mkfile() should create a file using using readble in options.
var stream = fs.createReadStream(__filename);
var vpath = "/test.js";
// Make sure the file doesn't exist.
expect(fs.existsSync(base + vpath)).not.ok;
vfs.mkfile(vpath, { stream: stream }, function (err, meta) {
  if (err) {
    fs.unlinkSync(base + vpath);
    return done(err);
  }
  var actual = fs.readFileSync(base + vpath, "utf8");
  var original = fs.readFileSync(__filename, "utf8");
  fs.unlinkSync(base + vpath);
  expect(actual).equal(original);
  done();
});

should create a file using writable in callback.

var vpath = "/test.js";
// Make sure the file doesn't exist.
expect(fs.existsSync(base + vpath)).not.ok;
vfs.mkfile(vpath, {}, function (err, meta) {
  if (err) {
    fs.unlinkSync(base + vpath);
    return done(err);
  }
  expect(meta).property("stream").property("writable").ok;
  var writable = meta.stream;
  var readable = fs.createReadStream(__filename);
  readable.pipe(writable);
  writable.on("saved", function () {
    var actual = fs.readFileSync(base + vpath, "utf8");
    var original = fs.readFileSync(__filename, "utf8");
    fs.unlinkSync(base + vpath);
    expect(actual).equal(original);
    done();
  });
});

should update an existing file using readble in options.

var vpath = "/changeme.txt";
var stream = fs.createReadStream(__filename);
fs.writeFileSync(base + vpath, "Original Content\n");
vfs.mkfile(vpath, {stream: stream}, function (err, meta) {
  if (err) {
    fs.unlinkSync(base + vpath);
    return done(err);
  }
  var actual = fs.readFileSync(base + vpath, "utf8");
  var original = fs.readFileSync(__filename, "utf8");
  fs.unlinkSync(base + vpath);
  expect(actual).equal(original);
  done();
});

should update an existing file using writable in callback.

var vpath = "/changeme.txt";
fs.writeFileSync(base + vpath, "Original Content\n");
vfs.mkfile(vpath, {}, function (err, meta) {
  if (err) {
    fs.unlinkSync(base + vpath);
    return done(err);
  }
  expect(meta).property("stream").property("writable").ok;
  var writable = meta.stream;
  var readable = fs.createReadStream(__filename);
  readable.pipe(writable);
  writable.on("saved", function () {
    var actual = fs.readFileSync(base + vpath, "utf8");
    var original = fs.readFileSync(__filename, "utf8");
    fs.unlinkSync(base + vpath);
    expect(actual).equal(original);
    done();
  });
});
## vfs.mkdir() should create a directory.
var vpath = "/newdir";
// Make sure it doesn't exist yet
expect(fs.existsSync(base + vpath)).not.ok;
vfs.mkdir(vpath, {}, function (err, meta) {
  if (err) {
    fs.rmdirSync(base + vpath);
    return done(err);
  }
  expect(fs.existsSync(base + vpath)).ok;
  fs.rmdirSync(base + vpath);
  done();
});

should error with EEXIST when the directory already exists.

vfs.mkdir("/dir", {}, function (err, meta) {
  expect(err).property("code").equal("EEXIST");
  done();
});

should error with EEXIST when the file already exists.

vfs.mkdir("/file.txt", {}, function (err, meta) {
  expect(err).property("code").equal("EEXIST");
  done();
});
## vfs.rmfile() should delete a file.
var vpath = "/deleteme.txt";
fs.writeFileSync(base + vpath, "DELETE ME!\n");
expect(fs.existsSync(base + vpath)).ok;
vfs.rmfile(vpath, {}, function (err, meta) {
  if (err) throw err;
  expect(fs.existsSync(base + vpath)).not.ok;
  done();
});

should error with ENOENT if the file doesn't exist.

var vpath = "/badname.txt";
expect(fs.existsSync(base + vpath)).not.ok;
vfs.rmfile(vpath, {}, function (err, meta) {
  expect(err).property("code").equal("ENOENT");
  done();
});

should error with EISDIR if the path is a directory.

var vpath = "/dir";
expect(fs.existsSync(base + vpath)).ok;
vfs.rmfile(vpath, {}, function (err, meta) {
  expect(err).property("code").equal("EISDIR");
  done();
});
## vfs.rmdir() should delete a file.
var vpath = "/newdir";
fs.mkdirSync(base + vpath);
expect(fs.existsSync(base + vpath)).ok;
vfs.rmdir(vpath, {}, function (err, meta) {
  if (err) throw err;
  expect(fs.existsSync(base + vpath)).not.ok;
  done();
});

should error with ENOENT if the file doesn't exist.

var vpath = "/badname.txt";
expect(fs.existsSync(base + vpath)).not.ok;
vfs.rmdir(vpath, {}, function (err, meta) {
  expect(err).property("code").equal("ENOENT");
  done();
});

should error with ENOTDIR if the path is a file.

var vpath = "/file.txt";
expect(fs.existsSync(base + vpath)).ok;
vfs.rmdir(vpath, {}, function (err, meta) {
  expect(err).property("code").equal("ENOTDIR");
  done();
});
## vfs.rename() should rename a file using options.to.
var before = "/start.txt";
var after = "/end.txt";
var text = "Move me please\n";
fs.writeFileSync(base + before, text);
expect(fs.existsSync(base + before)).ok;
expect(fs.existsSync(base + after)).not.ok;
vfs.rename(before, {to: after}, function (err, meta) {
  if (err) throw err;
  expect(fs.existsSync(base + before)).not.ok;
  expect(fs.existsSync(base + after)).ok;
  expect(fs.readFileSync(base + after, "utf8")).equal(text);
  fs.unlinkSync(base + after);
  done();
});

should rename a file using options.from.

var before = "/start.txt";
var after = "/end.txt";
var text = "Move me please\n";
fs.writeFileSync(base + before, text);
expect(fs.existsSync(base + before)).ok;
expect(fs.existsSync(base + after)).not.ok;
vfs.rename(after, {from: before}, function (err, meta) {
  if (err) throw err;
  expect(fs.existsSync(base + before)).not.ok;
  expect(fs.existsSync(base + after)).ok;
  expect(fs.readFileSync(base + after, "utf8")).equal(text);
  fs.unlinkSync(base + after);
  done();
});

should error with ENOENT if the source doesn't exist.

vfs.rename("/notexist", {to:"/newname"}, function (err, meta) {
  expect(err).property("code").equal("ENOENT");
  done();
});
## vfs.copy() should copy a file using options.to.
var source = "/file.txt";
var target = "/copy.txt";
var text = fs.readFileSync(base + source, "utf8");
vfs.copy(source, {to: target}, function (err, meta) {
  if (err) throw err;
  expect(fs.existsSync(base + target)).ok;
  expect(fs.readFileSync(base + target, "utf8")).equal(text);
  fs.unlinkSync(base + target);
  done();
});

should copy a file using options.from.

var source = "/file.txt";
var target = "/copy.txt";
var text = fs.readFileSync(base + source, "utf8");
vfs.copy(target, {from: source}, function (err, meta) {
  if (err) throw err;
  expect(fs.existsSync(base + target)).ok;
  expect(fs.readFileSync(base + target, "utf8")).equal(text);
  fs.unlinkSync(base + target);
  done();
});

should error with ENOENT if the source doesn't exist.

vfs.copy("/badname.txt", {to:"/copy.txt"}, function (err, meta) {
  expect(err).property("code").equal("ENOENT");
  done();
});
## vfs.symlink() should create a symlink.
var target = "file.txt";
var vpath = "/newlink.txt";
var text = fs.readFileSync(root + target, "utf8");
vfs.symlink(vpath, {target: target}, function (err, meta) {
  if (err) throw err;
  expect(fs.readFileSync(base + vpath, "utf8")).equal(text);
  fs.unlinkSync(base + vpath);
  done();
});

should error with EEXIST if the file already exists.

vfs.symlink("/file.txt", {target:"/this/is/crazy"}, function (err, meta) {
  expect(err).property("code").equal("EEXIST");
  done();
});
## vfs.watch() should notice a directly watched file change.
var vpath = "/newfile.txt";
expect(fs.existsSync(base + vpath)).not.ok;
var writable = fs.createWriteStream(base + vpath);
vfs.watch(vpath, {}, function (err, meta) {
  if (err) throw err;
  expect(meta).property("watcher").ok;
  var watcher = meta.watcher;
  watcher.on("change", function (event, filename) {
    watcher.close();
    expect(event).equal("change");
    expect(filename).equal(vpath.substr(1));
    writable.end();
    writable.on("close", function () {
      fs.unlinkSync(base + vpath);
      done();
    });
  });
  writable.write("Change!");
});

should notice a new file in a watched directory.

var vpath = "/newfile.txt";
expect(fs.existsSync(base + vpath)).not.ok;
vfs.watch("/", {}, function (err, meta) {
  if (err) throw err;
  expect(meta).property("watcher").ok;
  var watcher = meta.watcher;
  watcher.on("change", function (event, filename) {
    watcher.close();
    expect(event).ok;
    expect(filename).equal(vpath.substr(1));
    fs.unlinkSync(base + vpath);
    done();
  });
  fs.writeFileSync(base + vpath, "newfile!");
});
## vfs.connect() should connect to a tcp server and ping-pong.
var stream;
var server = net.createServer(function (client) {
  client.setEncoding('utf8');
  client.once("data", function (chunk) {
    expect(chunk).equal("ping");
    stream.once("data", function (chunk) {
      expect(chunk).equal("pong");
      client.end();
      stream.end();
      server.close();
      done();
    });
    client.write("pong");
  });
});
server.listen(function () {
  var port = server.address().port;
  vfs.connect(port, {encoding:"utf8"}, function (err, meta) {
    if (err) throw err;
    expect(meta).property("stream").ok;
    stream = meta.stream;
    stream.write("ping");
  });
});
## vfs.spawn() should spawn a child process.
var args = ["-e", "process.stdin.pipe(process.stdout);process.stdin.resume();"];
vfs.spawn(process.execPath, {args: args, stdoutEncoding: "utf8"}, function (err, meta) {
  if (err) throw err;
  expect(meta).property("process").ok;
  var child = meta.process;
  expect(child).property("stdout").ok;
  expect(child).property("stdin").ok;
  child.stdout.on("data", function (chunk) {
    expect(chunk).equal("echo me");
    child.stdout.on("end", function () {
      done();
    });
    child.stdin.end();
  });
  child.stdin.write("echo me");
});
## vfs.execFile() should exec a child process.
var args = ["-p", "-e", "process.version"];
vfs.execFile(process.execPath, {args:args}, function (err, meta) {
  if (err) throw err;
  expect(meta).property("stdout").equal(process.version + "\n");
  expect(meta).property("stderr").equal("");
  done();
});
## vfs.on(), vfs.off(), vfs.emit() should register an event listener and catch an event.
vfs.on("myevent", onEvent, function (err) {
  if (err) throw err;
  vfs.emit("myevent", 42, function (err) {
    if (err) throw err;
  });
});
function onEvent(data) {
  expect(data).equal(42);
  vfs.off("myevent", onEvent, done);
}

should catch multiple events of the same type.

var times = 0;
vfs.on("myevent", onEvent, function (err) {
  if (err) throw err;
  vfs.emit("myevent", 43, function (err) {
    if (err) throw err;
  });
  vfs.emit("myevent", 43, function (err) {
    if (err) throw err;
  });
});
function onEvent(data) {
  expect(data).equal(43);
  if (++times === 2) {
    vfs.off("myevent", onEvent, done);
  }
}

should call multiple listeners for a single event.

var times = 0;
vfs.on("myevent", onEvent1, function (err) {
  if (err) throw err;
  vfs.on("myevent", onEvent2, function (err) {
    if (err) throw err;
    vfs.emit("myevent", 44, function (err) {
      if (err) throw err;
    });
  });
});
function onEvent1(data) {
  expect(data).equal(44);
  times++;
}
function onEvent2(data) {
  expect(data).equal(44);
  if (++times === 2) {
    vfs.off("myevent", onEvent1, function (err) {
      if (err) throw err;
      vfs.off("myevent", onEvent2, done);
    });
  }
}

should stop listening after a handler is removed.

vfs.on("myevent", onEvent, function (err) {
  if (err) throw err;
  vfs.emit("myevent", 45, function (err) {
    if (err) throw err;
    vfs.off("myevent", onEvent, function (err) {
      if (err) throw err;
      vfs.emit("myevent", 46, done);
    });
  });
});
function onEvent(data) {
  expect(data).equal(45);
}
## vfs.extend() should extend using a local file.
vfs.extend("math", {file: __dirname + "/math.js"}, function (err, meta) {
  if (err) throw err;
  expect(meta).property("api").ok;
  var api = meta.api;
  expect(api).property("add").a("function");
  expect(api).property("multiply").a("function");
  api.add(3, 4, function (err, result) {
    if (err) throw err;
    expect(result).equal(3 + 4);
    vfs.unextend("math", {}, done);
  });
});

should extend using a string.

var code = fs.readFileSync(__dirname + "/math.js", "utf8");
vfs.extend("math2", {code: code}, function (err, meta) {
  if (err) throw err;
  expect(meta).property("api").ok;
  var api = meta.api;
  expect(api).property("add").a("function");
  expect(api).property("multiply").a("function");
  api.add(3, 4, function (err, result) {
    if (err) throw err;
    expect(result).equal(3 + 4);
    vfs.unextend("math2", {}, done);
  });
});

should extend using a stream.

var stream = fs.createReadStream(__dirname + "/math.js");
vfs.extend("math3", {stream: stream}, function (err, meta) {
  if (err) throw err;
  expect(meta).property("api").ok;
  var api = meta.api;
  expect(api).property("add").a("function");
  expect(api).property("multiply").a("function");
  api.add(3, 4, function (err, result) {
    if (err) throw err;
    expect(result).equal(3 + 4);
    vfs.unextend("math3", {}, done);
  });
});

should error with EEXIST if the same extension is added twice.

vfs.extend("math", {file: __dirname + "/math.js"}, function (err, meta) {
  if (err) throw err;
  expect(meta).property("api").ok;
  vfs.extend("math", {file: __dirname + "/math.js"}, function (err, meta) {
    expect(err).property("code").equal("EEXIST");
    vfs.unextend("math", {}, done);
  });
});

should allow a redefine if options.redefine is set.

vfs.extend("test", {file: __dirname + "/math.js"}, function (err, meta) {
  if (err) throw err;
  expect(meta).property("api").ok;
  vfs.extend("test", {redefine: true, file: __dirname + "/math.js"}, function (err, meta) {
    if (err) throw err;
    expect(meta).property("api").ok;
    vfs.unextend("test", {}, done);
  });
});
## vfs.unextend() should remove an extension.
vfs.extend("math7", {file: __dirname + "/math.js"}, function (err, meta) {
  if (err) throw err;
  expect(meta).property("api").ok;
  vfs.use("math7", {}, function (err, meta) {
    if (err) throw err;
    expect(meta).property("api").ok;
    vfs.unextend("math7", {}, function (err, meta) {
      if (err) throw err;
      vfs.use("math7", {}, function (err, meta) {
        expect(err).property("code").equal("ENOENT");
        done();
      });
    });
  });
});
## vfs.use() should load an existing api.
vfs.extend("math4", {file: __dirname + "/math.js"}, function (err, meta) {
  if (err) throw err;
  expect(meta).property("api").ok;
  vfs.use("math4", {}, function (err, meta) {
    if (err) throw err;
    expect(meta).property("api").ok;
    var api = meta.api;
    expect(api).property("add").a("function");
    expect(api).property("multiply").a("function");
    api.add(3, 4, function (err, result) {
      if (err) throw err;
      expect(result).equal(3 + 4);
      vfs.unextend("math4", {}, done);
    });
  });
});

should error with ENOENT if the api doesn't exist.

vfs.use("notfound", {}, function (err, meta) {
  expect(err).property("code").equal("ENOENT");
  done();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment