c9-core/plugins/c9.ide.tree/tree_test.js

663 wiersze
30 KiB
JavaScript

/*global describe it before */
"use client";
require(["lib/architect/architect", "lib/chai/chai", "/vfs-root"],
function (architect, chai, baseProc) {
var expect = chai.expect;
expect.setupArchitectTest([
{
packagePath: "plugins/c9.core/c9",
startdate: new Date(),
debug: true,
hosted: true,
davPrefix: "/",
local: false,
projectName: "Test Project"
},
{
packagePath: "plugins/c9.ide.tree/tree",
staticPrefix: "/static/plugins/c9.ide.layout.classic"
},
"plugins/c9.core/ext",
"plugins/c9.core/http-xhr",
"plugins/c9.core/util",
{
packagePath: "plugins/c9.core/settings",
settings: "default"
},
"plugins/c9.core/api.js",
{
packagePath: "plugins/c9.ide.ui/ui",
staticPrefix: "plugins/c9.ide.ui"
},
"plugins/c9.ide.ui/lib_apf",
"plugins/c9.ide.ui/menus",
"plugins/c9.ide.ui/anims",
{
packagePath: "plugins/c9.fs/fs",
baseProc: baseProc
},
"plugins/c9.vfs.client/vfs_client",
"plugins/c9.vfs.client/endpoint",
"plugins/c9.ide.auth/auth",
"plugins/c9.fs/fs.cache.xml",
"plugins/c9.ide.dialog/dialog",
"plugins/c9.ide.dialog.common/alert",
"plugins/c9.ide.dialog.common/alert_internal",
"plugins/c9.ide.dialog.common/confirm",
"plugins/c9.ide.dialog.common/filechange",
"plugins/c9.ide.dialog.common/fileoverwrite",
"plugins/c9.ide.dialog.common/fileremove",
"plugins/c9.ide.dialog.common/question",
//Mock Plugins
{
consumes: ["apf", "ui", "Plugin"],
provides: [
"commands", "panels", "tabManager", "layout", "watcher",
"preferences", "clipboard", "Panel", "auth.bootstrap", "info",
"proc", "focusManager", "dialog.error", "error_handler"
],
setup: expect.html.mocked
},
{
consumes: ["tree", "fs", "fs.cache", "tabManager", "ui",
"dialog.question", "dialog.alert"],
provides: [],
setup: main
}
], architect);
function main(options, imports, register) {
var tree = imports.tree;
var fs = imports.fs;
var tabs = imports.tabManager;
var ui = imports.ui;
var fsCache = imports["fs.cache"];
var questionDialog = imports["dialog.question"];
var alertDialog = imports["dialog.alert"];
var container;
function getDomNode(treeNode) {
var r = tree.tree.renderer;
r.$renderChanges(r.$loop.changes);
var i = r.provider.getIndexForNode(treeNode)
return r.$cellLayer.getDomNodeAtIndex(i);
}
function countEvents(count, expected, done) {
if (count == expected)
done();
else
throw new Error("Wrong Event Count: "
+ count + " of " + expected);
}
expect.html.setConstructor(function(path) {
var treeNode = fsCache.findNode(path);
return getDomNode(treeNode);
});
describe('tree', function() {
before(function(done) {
tree.getElement("container", function(container_) {
container = container_;
container.$ext.style.height = "500px";
container.$ext.style.width = "200px";
tree.tree.resize();
done();
});
});
describe("expand()", function(){
before(function(done) {
fsCache.clear();
done();
});
it('should expand a folder in the tree that is already in the fs cache', function(done) {
tree.expand("/", function(err) {
if (err) throw err.message;
expect.html("/dir").to.exist.and.is.visible;
done();
});
});
it('should expand a folder in the tree that is not yet loaded', function(done) {
fsCache.clear();
tree.expand("/dir", function(err) {
if (err) throw err.message;
expect.html("/dir/smile.png").to.exist.and.is.visible;
done();
});
});
it('should give an error when the path does not exist', function(done) {
tree.expand("/does/not/exist", function(err) {
expect(err.message).to.equal("File Not Found");
done();
});
});
it('should give an error when the node does not exist', function(done) {
tree.expand(null, function(err) {
expect(err.message).to.equal("Missing Node");
done();
});
});
});
describe("getAllExpanded()", function(){
it('should return a list of expanded folders', function(done) {
fsCache.clear();
tree.expand("/dir", function(){
tree.expand("/dirLink", function(){
expect(tree.getAllExpanded().sort())
.deep.equal(["/", "/dir", "/dirLink"]);
done();
});
});
});
});
describe("collapse() and collapseAll()", function(){
it('should collapse a folder in the tree that is expanded', function(done) {
tree.expand("/", function(err) {
if (err) throw err.message;
tree.collapse("/");
expect.html("/dir").to.notExist;
expect(tree.getAllExpanded().sort())
.deep.equal(["/dir", "/dirLink"]);
done();
});
});
it('should collapse all expanded nodes', function(done) {
fsCache.clear();
tree.expand("/dir", function(){
expect.html("/dir").to.exist.and.visible;
expect.html("/dir/smile.png").to.exist.and.visible;
tree.expand("/dirLink", function(){
expect.html("/dirLink").to.exist.and.visible;
expect.html("/dirLink/smile.png").to.exist.and.visible;
tree.collapseAll();
//@todo expandedNode is sometimes empty
expect.html("/dir").to.notExist;
expect.html("/dir/smile.png").to.notExist;
expect.html("/dirLink").to.notExist;
expect.html("/dirLink/smile.png").to.notExist;
expect(tree.getAllExpanded()).deep.equal([]);
done();
});
});
});
});
describe("select() and selectList()", function(){
it('should select a node', function(done) {
tree.expand("/", function(err) {
if (err) throw err;
var node = fsCache.findNode("/dir");
expect(node, "xml node").to.ok;
tree.select(node);
expect.html("/dir")
.to.exist
.to.have.className("selected");
expect(tree.selection).deep.equal(["/dir"]);
done();
})
});
it('should select a path', function(done) {
tree.select("/dirLink");
expect.html("/dirLink")
.to.exist
.to.have.className("selected");
expect(tree.selection).deep.equal(["/dirLink"]);
done();
});
it('should select a list of paths', function(done) {
tree.selectList(["/", "/dir", "/dirLink"]);
expect.html("/dirLink")
.to.exist
.to.have.className("selected");
expect.html("/dir")
.to.exist
.to.have.className("selected");
expect.html("/")
.to.exist
.to.have.className("selected");
expect(tree.selection)
.deep.equal(["/", "/dir", "/dirLink"]);
done();
});
it('should select a list of nodes', function(done) {
tree.selectList(["/", "/file.txt"].map(function(p) {
return fsCache.findNode(p);
}));
expect.html("/file.txt")
.to.exist
.to.have.className("selected");
expect.html("/")
.to.exist
.to.have.className("selected");
expect(tree.selection)
.deep.equal(["/", "/file.txt"]);
done();
});
});
describe("openSelection()", function(){
before(function(done) {
fsCache.clear();
done();
})
it('should open all files selected and ignore folders', function(done) {
var count = 0;
function c1(){ count++; };
tabs.on("open", c1);
tree.expand("/", function(){
tree.selectList(["/dir", "/file.txt", "/listing.json"]);
tree.openSelection();
tabs.off("open", c1);
countEvents(count, 2, done);
});
});
});
describe("refresh()", function(){
//@todo fsCache.clear should actually reset the expanded nodes
//@todo add a test for refreshing of a not yet loaded folder
before(function(done) {
fsCache.clear();
done();
})
it('should refresh the entire tree and remember all the expanded states', function(done) {
tree.expand("/dir", function(){
tree.expand("/dirLink", function(){
tree.selectList(
["/dirLink/smile.png", "/dir/stuff.json"]);
expect(tree.selection)
.deep.equal(["/dirLink/smile.png", "/dir/stuff.json"]);
tree.refresh(function(){
expect.html("/dir").to.exist.and.visible
expect.html("/dirLink").to.exist.and.visible
expect(tree.getAllExpanded().sort())
.deep.equal(["/", "/dir", "/dirLink"]);
expect(tree.selection)
.deep.equal(["/dirLink/smile.png", "/dir/stuff.json"]);
done();
})
});
});
});
it('should refresh a sub tree and remember all the expanded states', function(done) {
fs.rmfile("/dir/test.html", function(){
fs.rmfile("/test.html", function(){
tree.expand("/dir", function(err) {
if (err) throw err.message;
expect(fsCache.findNode("/dir/test.html"), "start").not.ok;
expect(fsCache.findNode("/test.html"), "start").not.ok;
fs.writeFile("/dir/test.html", "test", "utf8", function(err) {
if (err) throw err.message;
fs.writeFile("/test.html", "test", "utf8", function(err) {
if (err) throw err.message;
tree.select("/dir/smile.png");
tree.refresh(["/dir"], function(err) {
if (err) throw err.message;
expect(fsCache.findNode("/dir/test.html")).ok;
// expect(fsCache.findNode("/test.html")).not.ok; // TODO why this shouldn't exist?
expect.html("/dir/test.html").to.exist.and.visible
// expect.html("/test.html").to.not.exist
expect(tree.selection)
.deep.equal(["/dir/smile.png"]);
fs.rmfile("/dir/test.html", function(){
fs.rmfile("/test.html", function(){
done();
});
});
});
});
});
});
});
});
});
});
describe("createFile() and createFolder()", function(){
// @todo should create a file while the requested name already extists
before(function(done) {
fsCache.clear();
done();
});
/**
* The problem is related to the fs caching. This ETAG thing is not always working properly
* Add the proper console.log statements to figure it out
*/
it('should create a file in the selected path and allow the user to rename it', function(done) {
fs.rmfile("/dir/test.html", function(){
tree.expand("/dir", function(err) {
if (err) throw err.message;
tree.select("/dir");
expect(fsCache.findNode("/dir/test.html")).to.not.ok
tree.createFile("test.html", false, function(err) {
if (err) throw err.message;
expect(fsCache.findNode("/dir/test.html")).to.ok;
expect.html("/dir/test.html").to.exist.and.visible;
expect(tree.tree.edit.renaming).is.ok;
tree.tree.edit.endRename(false);
fs.rmfile("/dir/test.html", function(){
done();
})
});
});
});
});
it('should create a file in the selected path without renaming', function(done) {
fs.rmfile("/dir/test.html", function(){
tree.expand("/dir", function(err) {
if (err) throw err.message;
tree.select("/dir");
expect(fsCache.findNode("/dir/test.html")).to.not.ok
tree.createFile("test.html", true, function(err) {
if (err) throw err.message;
expect(fsCache.findNode("/dir/test.html")).to.ok;
expect.html("/dir/test.html").to.exist.and.visible;
expect(tree.tree.edit.renaming).is.not.ok;
fs.rmfile("/dir/test.html", function(){
done();
})
});
});
});
});
it('should create a folder in the selected path and allow the user to rename it', function(done) {
fs.rmdir("/dir/dir", function(){
tree.expand("/dir", function(err) {
if (err) throw err.message;
tree.select("/dir");
expect(fsCache.findNode("/dir/dir")).to.not.ok
tree.createFolder("dir", false, function(err) {
if (err) throw err.message;
expect(fsCache.findNode("/dir/dir")).to.ok;
expect.html("/dir/dir").to.exist.and.visible;
expect(tree.tree.edit.renaming).is.ok;
tree.tree.edit.endRename(false);
fs.rmdir("/dir/dir", function(){
done();
})
});
});
});
});
it('should create a folder in the selected path without renaming', function(done) {
fs.rmfile("/dir/dir", function(){
tree.expand("/dir", function(err) {
if (err) throw err.message;
tree.select("/dir");
expect(fsCache.findNode("/dir/dir")).to.not.ok
tree.createFolder("dir", true, function(err) {
if (err) throw err.message;
expect(fsCache.findNode("/dir/dir")).to.ok;
expect.html("/dir/dir").to.exist.and.visible;
expect(tree.tree.edit.renaming).is.not.ok;
fs.rmdir("/dir/dir", function(){
done();
})
});
});
});
});
});
describe("Response to changes to the fs cache", function(){
before(function(done) {
fsCache.clear();
done();
});
it('should display the loading state and remove it', function(done) {
tree.expand("/", function(err) {
if (err) throw err.message;
expect.html("/").child(".filetree-icon").has.not.className("loading");
expect.html("/dirLink").has.className("symlink");
done();
});
expect.html("/").child(".filetree-icon").has.className("loading");
});
it('should add a node at the right sorting location', function(done) {
var node = fsCache.createNode("/gtest");
expect.html("/gtest").to.exist;
done();
});
it('should update a name', function(done) {
// TODO these were using setAttribute ui.xmldb.setAttribute
// we don't have equivalent method for now
var node = fsCache.findNode("/gtest");
fsCache.createNode("/atest", null, node);
expect.html("/gtest").to.not.exist;
expect.html("/atest")
.to.exist
.child(-1)
.to.have.text("atest");
done();
});
it('should update an icon', function(done) {
var node = fsCache.findNode("/atest");
fsCache.createNode("/atest.js", null, node);
expect.html("/atest.js")
.to.have.icon("page_white_code");
done();
});
it('should remove a node', function(done) {
var node = fsCache.findNode("/atest.js");
fsCache.removeNode(node);
expect.html("/atest.js").to.not.exist;
done();
});
it('should move a subtree', function(done) {
fs.mkdir("/dir2", function(err) {
tree.expand("/dirLink", function(err) {
tree.expand("/dir2", function(err) {
if (err) throw err.message;
fs.rename("/dir2", "/dirLink/dir2", function() {
done();
});
expect.html("/dirLink/dir2").to.have.text("dir2");
});
});
});
});
it('should deal correctly with a non-loaded subtree', function(done) {
fsCache.clear();
tree.expand("/dirLink", function(err) {
fs.rename("/dirLink/dir2", "/dir2", function() {
fs.rmdir("/dir2", function() {
done();
});
});
expect.html("/dir2").to.exist;
});
});
});
describe("Actions from the UI that trigger fs actions", function(){
before(function(done) {
fsCache.clear();
done();
});
it('should expand a node and load its contents', function(done) {
tree.select("/");
tree.expand(fsCache.findNode("/"));
fs.on("afterReaddir", function c1(e) {
fs.off("afterReaddir", c1);
setTimeout(function(){
expect.html("/dir")
.to.exist
.is.visible;
done();
}, 0);
});
});
it('should rename a node', function(done) {
tree.expand("/", function(){
fs.rmfile("/test2.html", function(){
fs.writeFile("/test.html", "test", function(err) {
if (err) throw err.message;
tree.select("/test.html");
var edit = tree.tree.edit;
edit.startRename();
edit.ace.setValue("test2.html");
edit.endRename();
expect(fsCache.findNode("/test2.html")).to.ok
.and.property("status").equals("predicted");
fs.once("afterRename", function(){
fs.exists("/test2.html", function(exists) {
expect(exists).to.ok;
expect(fsCache.findNode("/test2.html")).to.ok
.and.property("status").equals("loaded");
done();
});
});
});
});
});
});
it('should delete a node', function(done) {
tree.select("/test2.html");
tree.tree.execCommand("delete");
setTimeout(function(){
questionDialog.getElement("yes").onclick();
expect(fsCache.findNode("/test2.html")).to.not.ok;
fs.exists("/test2.html", function(exists) {
expect(exists).to.not.ok;
done();
});
}, 0);
});
it('should not be able to delete the root folder', function(done) {
tree.select("/");
var alerted;
alertDialog.once("show", function(){
alerted = true;
});
tree.tree.execCommand("delete");
expect(fsCache.findNode("/")).to.ok;
setTimeout(function(){
expect(alerted).to.ok;
alertDialog.hide();
fs.exists("/", function(exists) {
expect(exists).to.ok;
done();
});
}, 0);
});
it('should move a node', function(done) {
fs.rmfile("/dir/test.html", function(){
fs.writeFile("/test.html", "test", "utf8", function(err) {
if (err) throw err.message;
tree.select("/test.html");
tree.move(
[fsCache.findNode("/test.html")],
fsCache.findNode("/dir"),
null,
function() {
fs.exists("/dir/test.html", function(exists) {
expect(exists, "exists1").to.ok;
fs.exists("/test.html", function(exists) {
expect(exists, "exists2").to.not.ok;
expect(tree.selection).deep.equal(["/dir/test.html"]);
done();
});
});
}
);
expect(fsCache.findNode("/dir/test.html"), "/dir/test.html").to.ok;
expect(fsCache.findNode("/test.html"), "/test.html").to.not.ok;
});
});
});
it('should copy a node', function(done) {
tree.copy(
[fsCache.findNode("/dir/test.html")],
fsCache.findNode("/"),
function () {
fs.exists("/dir/test.html", function(exists) {
expect(exists).to.ok;
fs.exists("/test.html", function(exists) {
expect(exists).to.ok;
expect(tree.selection, "selection").deep.equal(["/test.html"]);
fs.rmfile("/dir/test.html", function(){
fs.rmfile("/test.html", function(){
done();
});
});
});
});
}
);
expect(fsCache.findNode("/dir/test.html")).to.ok;
expect(fsCache.findNode("/test.html")).to.ok;
});
});
if (!onload.remain) {
describe("unload()", function(){
it('should destroy all ui elements when it is unloaded', function(done) {
tree.unload();
expect(container.$amlDestroyed).to.equal(true);
done();
});
});
}
});
onload && onload();
}
});