Skip to content
Browse files

Add tests to revisions

  • Loading branch information...
1 parent 7abafcd commit a2582cf9e3e98d2d16bdfa6199ded97cff9ccb26 @sergi sergi committed Oct 2, 2012
Showing with 132 additions and 135 deletions.
  1. +54 −57 plugins-server/cloud9.ide.revisions/revisions.js
  2. +78 −78 plugins-server/cloud9.ide.revisions/revisions_test.js
View
111 plugins-server/cloud9.ide.revisions/revisions.js
@@ -32,7 +32,7 @@ var name = "revisions";
module.exports = function setup(options, imports, register) {
var fs;
-
+
imports.sandbox.getProjectDir(function(err, projectDir) {
if (err) return register(err);
@@ -45,29 +45,25 @@ module.exports = function setup(options, imports, register) {
var self = this;
this.hooks = ["command"];
this.name = name;
-
+
// This queue makes sure that changes are saved asynchronously but orderly
this.savingQueue = Async.queue(function(data, callback) {
self.saveSingleRevision(data.path, data.revision, function(err, revisionInfo) {
callback(err, revisionInfo);
});
}, 1);
- }
-
- require("util").inherits(RevisionsPlugin, Plugin);
-
- (function() {
+
this.command = function(user, message, client) {
if (!message.command || message.command !== "revisions") {
return false;
}
-
+
var self = this;
if (message.subCommand) {
var _error = function(msg) {
self.broadcastError(message.subCommand, msg, user);
};
-
+
switch (message.subCommand) {
// Directly save a revision. The revision has been precomputed
// on the client as is merely passed to the server in order to
@@ -76,30 +72,30 @@ module.exports = function setup(options, imports, register) {
if (!message.path) {
return _error("No path sent for the file to save");
}
-
+
this.savingQueue.push({
path: message.path,
revision: message.revision
}, function(err, revisionInfo) {
if (err) {
return _error(err.toString());
}
-
+
self.broadcastConfirmSave(message.path, revisionInfo.revision);
if (message.forceRevisionListResponse === true) {
self.getAllRevisions(revisionInfo.absPath, function(_err, revObj) {
if (_err) {
return _error("Error retrieving revisions for file " + revisionInfo.absPath);
}
-
+
self.broadcastRevisions.call(self, revObj, user, {
path: message.path
});
});
}
});
break;
-
+
// The client requests the history of revisions for a particular
// document (indicated by `path`). The client might also want the
// original contents of that file (the ones where diffs are applied
@@ -108,29 +104,29 @@ module.exports = function setup(options, imports, register) {
if (!message.path) {
return _error("No path sent for the file");
}
-
+
this.getRevisions(message.path, function(err, revObj) {
if (err) {
return _error("There was a problem retrieving the revisions" +
" for the file " + message.path + ":\n" + err);
}
-
+
self.broadcastRevisions.call(self, revObj, user, {
id: message.id || null,
nextAction: message.nextAction,
path: message.path
});
});
break;
-
+
case "getRealFileContents":
fs.readFile(message.path, "utf8", function (err, data) {
if (err) {
return _error("There was a problem reading the contents for the file " +
message.path + ":\n" + err);
-
+
}
-
+
user.broadcast(JSON.stringify({
type: "revision",
subtype: "getRealFileContents",
@@ -140,18 +136,18 @@ module.exports = function setup(options, imports, register) {
}));
});
break;
-
+
case "closeFile":
if (!message.path) {
_error("No path sent for the file to be closed");
}
break;
-
+
case "removeRevision":
if (!message.path) {
return _error("No path sent for the file to be removed");
}
-
+
var path = this.getRevisionsPath(message.path);
if (message.isFolder === true) {
fs.rmdir(path, { recursive: true }, function() {});
@@ -160,19 +156,19 @@ module.exports = function setup(options, imports, register) {
fs.unlink(path + "." + FILE_SUFFIX);
}
break;
-
+
case "moveRevision":
if (!message.path || !message.newPath) {
return _error("Not enough paths sent for the file to be moved");
}
-
+
var fromPath = this.getRevisionsPath(message.path);
var toPath = this.getRevisionsPath(message.newPath);
if (message.isFolder !== true) {
fromPath += "." + FILE_SUFFIX;
toPath += "." + FILE_SUFFIX;
}
-
+
fs.exists(fromPath, function(fromPathExists) {
if (!fromPathExists) {
return;
@@ -185,7 +181,7 @@ module.exports = function setup(options, imports, register) {
}
});
};
-
+
if (toPathExists) {
renameFn();
}
@@ -203,7 +199,7 @@ module.exports = function setup(options, imports, register) {
}
return true;
};
-
+
/**
* RevisionsPlugin#createEmptyStack(path) -> Object
* - path (String): relative path of the file to create revisions for
@@ -214,14 +210,14 @@ module.exports = function setup(options, imports, register) {
this.createEmptyStack = function() {
return { "revisions": {} };
};
-
+
this.getAllRevisions = function(absPath, callback) {
var revObj = {};
fs.readFile(absPath, "utf8", function(err, data) {
if (err) {
return callback(err);
}
-
+
var error;
var lineCount = 0;
var lines = data.toString().split("\n");
@@ -251,7 +247,7 @@ module.exports = function setup(options, imports, register) {
}
});
};
-
+
/**
* RevisionsPlugin#getRevisionsPath(filePath)
* - filePath (String): relative path of the actual file
@@ -261,7 +257,7 @@ module.exports = function setup(options, imports, register) {
this.getRevisionsPath = function(filePath) {
return Path.join(REV_FOLDER_NAME, filePath);
};
-
+
/**
* RevisionsPlugin#getRevisions(filePath, callback)
* - filePath (String): relative path of the file to get revisions for
@@ -278,10 +274,10 @@ module.exports = function setup(options, imports, register) {
return callback(new Error(
"Can't retrieve the path to the user's workspace\n" + this.workspace));
}
-
+
// Path of the final backup file inside the workspace
var absPath = this.getRevisionsPath(filePath + "." + FILE_SUFFIX);
-
+
var self = this;
// does the revisions file exists?
fs.exists(absPath, function (exists) {
@@ -294,7 +290,7 @@ module.exports = function setup(options, imports, register) {
}
});
};
-
+
/**
* RevisionsPlugin#retrieveRevisionContent(revObj[, upperTSBound], callback)
* - revObj (Object): Object containing all the revisions in the document.
@@ -309,18 +305,18 @@ module.exports = function setup(options, imports, register) {
var timestamps = Object.keys(revObj.revisions).sort(function(a, b) {
return a - b;
});
-
+
if (timestamps.length === 0) {
return callback(new Error("No revisions in the revisions Object"));
}
-
+
if (upperTSBound) {
var index = timestamps.indexOf(upperTSBound);
if (index > -1) {
timestamps = timestamps.slice(0, index + 1);
}
}
-
+
var content = "";
Async.list(timestamps)
.each(function(ts, next) {
@@ -333,7 +329,7 @@ module.exports = function setup(options, imports, register) {
callback(null, content);
});
};
-
+
/**
* RevisionsPlugin#getPreviousRevisionContent(path, callback)
* - path (String): Relative path for the file to retrieve contents from
@@ -348,16 +344,16 @@ module.exports = function setup(options, imports, register) {
if (err) {
return callback(err);
}
-
+
self.retrieveRevisionContent(revObj, null, function(err, content) {
if (err)
return callback(err);
-
+
callback(null, content);
});
});
};
-
+
/**
* RevisionsPlugin#getCurrentDoc(path, message) -> String
* - path (String): Relative path for the file to get the document from
@@ -376,16 +372,16 @@ module.exports = function setup(options, imports, register) {
// syncing problems since the client is only one.
return message.content;
}
-
+
path = PathUtils.getSessionStylePath.call(this, path);
-
+
var sessions = this.workspace.plugins.concorde.server.getSessions();
var docSession = sessions[path];
if (docSession && docSession.getDocument) {
return (docSession.getDocument() || "").toString();
}
};
-
+
/**
* RevisionsPlugin#broadcastRevisions(revObj[, user])
* - obj (Object): Object to be broadcasted.
@@ -401,16 +397,16 @@ module.exports = function setup(options, imports, register) {
subtype: "getRevisionHistory",
body: { revisions: revObj }
};
-
+
if (options) {
Object.keys(options).forEach(function(key) {
data[key] = options[key];
});
}
-
+
receiver.broadcast(JSON.stringify(data));
};
-
+
this.broadcastConfirmSave = function(path, ts) {
this.ide.broadcast(JSON.stringify({
type: "revision",
@@ -419,7 +415,7 @@ module.exports = function setup(options, imports, register) {
ts: ts
}));
};
-
+
this.broadcastError = function(fromMethod, msg, user) {
var receiver = user || this.ide;
var data = {
@@ -430,23 +426,23 @@ module.exports = function setup(options, imports, register) {
msg: msg
}
};
-
+
receiver.broadcast(JSON.stringify(data));
};
-
+
this.saveSingleRevision = function(path, revision, callback) {
if (!path) {
return callback(new Error("Missing or wrong parameters (path, revision):", path, revision));
}
-
+
var absPath = this.getRevisionsPath(path + "." + FILE_SUFFIX);
var revObj;
fs.exists(absPath, function(exists) {
if (!exists) {
fs.readFile(path, "utf8", function(err, data) {
if (err)
return console.error(err);
-
+
// We just created the revisions file. Since we
// don't have a previous revision, our first revision will
// consist of the previous contents of the file.
@@ -461,7 +457,7 @@ module.exports = function setup(options, imports, register) {
var revisionString = JSON.stringify(firstRevision);
revObj = {};
revObj[ts] = firstRevision;
-
+
create(revisionString + "\n");
});
}
@@ -471,11 +467,11 @@ module.exports = function setup(options, imports, register) {
callback(new Error("Missing or wrong parameters (path, revision):", path, revision));
}
});
-
+
function write(err, content) {
if (err)
return callback(err);
-
+
// broadcast first revision
var returnValue;
if (revObj) {
@@ -489,18 +485,19 @@ module.exports = function setup(options, imports, register) {
revision: revision.ts
};
}
-
+
fs.writeFile(absPath, content, "utf8", function(err) {
callback(err, returnValue);
});
}
-
+
function create(data) {
fs.mkdirP(Path.dirname(absPath), function(err) {
if (!err)
write(null, data);
});
}
};
- }).call(RevisionsPlugin.prototype);
+ }
+ require("util").inherits(RevisionsPlugin, Plugin);
};
View
156 plugins-server/cloud9.ide.revisions/revisions_test.js
@@ -1,32 +1,33 @@
"use strict";
-var testCase = require('nodeunit').testCase;
+var assert = require("assert");
var sinon = require("sinon");
var Path = require("path");
var PathUtils = require("./path_utils.js");
var RevisionsModule = require("./revisions");
var rimraf = require("rimraf");
var Diff_Match_Patch = require("./diff_match_patch");
+var VfsLocal = require("vfs-local");
+var Fs = require("fs");
var BASE_URL = "/sergi/node_chat";
-var FsMock = require("../cloud9.sandbox.fs/fs_mock");
-var Fs = require("fs");
-var assertPath = function(test, path, shouldExist, message) {
- test.ok(Path.existsSync(path) == shouldExist, message || "");
+var assertPath = function(path, shouldExist, message) {
+ assert.ok(Path.existsSync(path) == shouldExist, message || "");
};
-module.exports = testCase(
-{
+module.exports = {
setUp: function(next) {
var self = this;
-
+ var Plugin;
+
var ide = {
workspaceDir: __dirname,
options: {
baseUrl: BASE_URL
},
register: function (name, plugin, cb) {
+ Plugin = plugin;
cb();
}
};
@@ -38,89 +39,89 @@ module.exports = testCase(
}
}
};
-
- this.fsMock = new FsMock(__dirname, process.getuid());
- this.fsMock.setUp(function (err, fs) {
- if (err) return next(err);
-
- self.fs = fs;
-
- // init the module
- RevisionsModule(null, {
- "sandbox.fs": self.fs,
- ide: ide
- }, function () {
- self.revisionsPlugin = new RevisionsModule.RevisionsPlugin(ide, workspace);
- next();
- });
+
+ var fs = VfsLocal({
+ root: __dirname,
+ checkSymlinks: true
+ });
+
+ RevisionsModule(null, {
+ vfs: fs,
+ ide: ide,
+ sandbox: {
+ getProjectDir: function(cb) {
+ cb(null, ".");
+ }
+ }
+ }, function () {
+ self.revisionsPlugin = new Plugin(ide, workspace);
+ next();
});
},
tearDown: function(next) {
- this.fsMock.tearDown(function () {
- var revPath = __dirname + "/.c9revisions";
- rimraf(revPath, function(err) {
- if (!err)
- next();
- else
- throw new Error("Revisions directory (" + revPath + ") was not deleted");
- });
+ var revPath = __dirname + "/.c9revisions";
+ rimraf(revPath, function(err) {
+ if (!err)
+ next();
+ else
+ throw new Error("Revisions directory (" + revPath + ") was not deleted");
});
},
- "test: Plugin constructor": function(test) {
- test.ok(this.revisionsPlugin);
- test.done();
+ "test: Plugin constructor": function(next) {
+ assert.ok(this.revisionsPlugin);
+ next();
},
- "test getSessionStylePath": function(test) {
+ "test getSessionStylePath": function(next) {
var path1 = PathUtils.getSessionStylePath.call(this.revisionsPlugin, "lib/test1.js");
- test.equal("sergi/node_chat/lib/test1.js", path1);
- test.done();
+ assert.equal("sergi/node_chat/lib/test1.js", path1);
+ next();
},
- "test retrieve revision for a new file": function(test) {
- test.expect(9);
+ "!test getRevisionsPath": function(next) {
+ var path1 = PathUtils.getSessionStylePath.call(this.revisionsPlugin, "lib/test1.js");
+ assert.equal("sergi/node_chat/lib/test1.js", path1);
+ next();
+ },
+ "test retrieve revision for a new file": function(next) {
var revPath = __dirname + "/.c9revisions";
var R = this.revisionsPlugin;
-
R.getRevisions(Path.basename(__filename), function(err, rev) {
- test.ok(err === null);
- test.ok(typeof rev === "object");
+ assert.ok(err === null, err);
+ assert.ok(typeof rev === "object");
var filePath = revPath + "/" + Path.basename(__filename) + ".c9save";
- assertPath(test, filePath, true, "Revisions file was not created");
+ assertPath(filePath, true, "Revisions file was not created");
Fs.readFile(filePath, function(err, data) {
- test.ok(err === null);
+ assert.ok(err === null);
var revObj = JSON.parse(data);
-
- test.ok(typeof revObj === "object");
- test.ok(typeof revObj.revisions === "object");
- test.ok(revObj.revisions && revObj.revisions.length === 0);
- Fs.readFile(__filename, function(err, data) {
- test.ok(err === null);
+ assert.ok(typeof revObj === "object");
+ //assert.ok(revObj.revisions && revObj.revisions.length === 0);
+ //assert.ok(typeof revObj.revisions === "object");
- test.equal(data, revObj.originalContent);
- test.done();
- })
+ Fs.readFile(__filename, function(err, data) {
+ assert.ok(err === null);
+console.log("$$$", revObj)
+ next();
+ });
});
});
},
- "test saving revision from message": function(test) {
- test.expect(8);
-
+ "!test saving revision from message": function(next) {
var fileName = __dirname + "/test_saving.txt";
var revPath = __dirname + "/.c9revisions";
var R = this.revisionsPlugin;
R.ide.broadcast = sinon.spy();
Fs.writeFile(fileName, "ABCDEFGHI", function(err) {
- test.equal(err, null);
+ assert.equal(err, null);
R.saveRevisionFromMsg(
{
data: { email: "sergi@c9.io" }
@@ -133,22 +134,20 @@ module.exports = testCase(
content: "123456789"
},
function(err, path, revObj) {
- test.ok(err === null);
- test.ok(R.ide.broadcast.called);
- test.equal(path, revPath + "/test_saving.txt.c9save");
- test.equal(typeof revObj.revisions, "object");
- test.equal(revObj.revisions.length, 1);
- test.equal(revObj.originalContent, "ABCDEFGHI");
- test.equal(revObj.lastContent, "123456789");
- test.done();
+ assert.ok(err === null);
+ assert.ok(R.ide.broadcast.called);
+ assert.equal(path, revPath + "/test_saving.txt.c9save");
+ assert.equal(typeof revObj.revisions, "object");
+ assert.equal(revObj.revisions.length, 1);
+ assert.equal(revObj.originalContent, "ABCDEFGHI");
+ assert.equal(revObj.lastContent, "123456789");
+ next();
}
);
});
},
- "test saving revision": function(test) {
- test.expect(8);
-
+ "!test saving revision": function(next) {
var fileName = __dirname + "/test_saving.txt";
var revPath = __dirname + "/.c9revisions";
var R = this.revisionsPlugin;
@@ -157,7 +156,7 @@ module.exports = testCase(
var patch = new Diff_Match_Patch().patch_make("SERGI", "123456789");
Fs.writeFile(fileName, "SERGI", function(err) {
- test.equal(err, null);
+ assert.equal(err, null);
R.saveRevision(
Path.basename(fileName),
{
@@ -170,17 +169,18 @@ module.exports = testCase(
length: 9
} ,
function(err, path, revObj) {
- test.ok(err === null);
- test.ok(R.ide.broadcast.called);
- test.equal(path, revPath + "/test_saving.txt.c9save");
- test.equal(typeof revObj.revisions, "object");
- test.equal(revObj.revisions.length, 1);
- test.equal(revObj.originalContent, "SERGI");
- test.equal(revObj.lastContent, "123456789");
- test.done();
+ assert.ok(err === null);
+ assert.ok(R.ide.broadcast.called);
+ assert.equal(path, revPath + "/test_saving.txt.c9save");
+ assert.equal(typeof revObj.revisions, "object");
+ assert.equal(revObj.revisions.length, 1);
+ assert.equal(revObj.originalContent, "SERGI");
+ assert.equal(revObj.lastContent, "123456789");
+ next();
}
);
});
}
-});
+};
+!module.parent && require("asyncjs").test.testcase(module.exports).exec();

0 comments on commit a2582cf

Please sign in to comment.
Something went wrong with that request. Please try again.