/*global describe it before after bar*/ "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, local: false, workspaceId: "javruben/dev", davPrefix: "/" }, "plugins/c9.core/ext", "plugins/c9.core/http-xhr", "plugins/c9.core/util", "plugins/c9.ide.ui/lib_apf", "plugins/c9.ide.ui/menus", { packagePath: "plugins/c9.core/settings", testing: true }, "plugins/c9.core/api.js", { packagePath: "plugins/c9.ide.ui/ui", staticPrefix: "plugins/c9.ide.ui" }, "plugins/c9.ide.editors/document", "plugins/c9.ide.editors/undomanager", { packagePath: "plugins/c9.ide.editors/editors", defaultEditor: "texteditor" }, "plugins/c9.ide.editors/editor", "plugins/c9.ide.editors/tabmanager", "plugins/c9.ide.ui/focus", "plugins/c9.ide.editors/metadata", "plugins/c9.ide.editors/pane", "plugins/c9.ide.editors/tab", "plugins/c9.ide.ace/ace", { packagePath: "plugins/c9.ide.terminal/terminal", testing: true }, { packagePath: "plugins/c9.vfs.client/vfs_client" }, "plugins/c9.vfs.client/endpoint", "plugins/c9.ide.auth/auth", "plugins/c9.fs/proc", { packagePath: "plugins/c9.fs/fs", baseProc: baseProc }, "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", "plugins/c9.ide.dialog.file/file", // Mock plugins { consumes: ["apf", "ui", "Plugin"], provides: [ "commands", "menus", "commands", "layout", "watcher", "save", "preferences", "anims", "clipboard", "auth.bootstrap", "info", "dialog.error" ], setup: expect.html.mocked }, { consumes: ["tabManager", "fs", "settings", "metadata", "dialog.question"], provides: [], setup: main } ], architect); function main(options, imports, register) { var tabs = imports.tabManager; var fs = imports.fs; var settings = imports.settings; var metadata = imports.metadata; var question = imports["dialog.question"]; function countEvents(count, expected, done) { if (count == expected) done(); else throw new Error("Wrong Event Count: " + count + " of " + expected); } expect.html.setConstructor(function(tab) { if (typeof tab == "object") return tab.pane.aml.getPage("editor::" + tab.editorType).$ext; }); describe('metadata', function() { this.timeout(20000); before(function(done) { apf.config.setProperty("allow-select", false); apf.config.setProperty("allow-blur", false); bar.$ext.style.background = "rgba(220, 220, 220, 0.93)"; bar.$ext.style.position = "fixed"; bar.$ext.style.left = "20px"; bar.$ext.style.right = "20px"; bar.$ext.style.bottom = "20px"; bar.$ext.style.height = "33%"; // document.body.style.marginBottom = "33%"; fs.rmdir("/.c9/metadata", { recursive: true }, function(err) { if (err) throw err; tabs.once("ready", function(){ tabs.getPanes()[0].focus(); tabs.openFile("/file.js", true, function(){ tabs.openFile("/file.txt", false, function(){ tabs.openFile("/fileLink.txt", false, function(){ done(); }); }); }); }); }); }); describe("Triggering save", function(){ it('should trigger save when a tab is active and changed', function(done) { var editor = tabs.focussedTab.editor; fs.once("afterMetadata", function(){ fs.exists("/.c9/metadata/workspace/file.js", function(exists) { done(); }); }); editor.scrollTo(100, 5); setTimeout(function(){ settings.save(true); }, 100); }); it('should trigger save when a tab is changed and closed', function(done) { var tab = tabs.findTab("/file.txt"); tabs.focusTab(tab); var editor = tabs.focussedTab.editor; editor.scrollTo(0, 10); setTimeout(function(){ fs.once("afterMetadata", function(){ fs.exists("/.c9/metadata/workspace/file.txt", function(exists) { expect(exists).to.ok; done(); }); }); tab.close(); }, 100); }); }); describe("Loading metadata", function(){ it('should load metadata properly when a file has metadata', function(done) { fs.exists("/.c9/metadata/workspace/file.txt", function(exists) { expect(exists).to.ok; tabs.openFile("/file.txt", true, function(err, tab) { if (err) throw err; var state = tab.document.getState(); if (state.ace.selection.start.column === 10 && state.ace.selection.start.row === 0 && state.ace.selection.end.column === 10 && state.ace.selection.end.row === 0 && !tab.document.changed) done(); else throw new Error("Selection is not correct: ", state.ace.selection); tab.close(); }); }); }); it('should load metadata properly even when the file is not active when it\'s opened', function(done) { tabs.openFile("/file.txt", false, function(err, tab) { if (err) throw err; tab.activate(); var state = tab.document.getState(); if (state.ace.selection.start.column === 10 && state.ace.selection.start.row === 0 && state.ace.selection.end.column === 10 && state.ace.selection.end.row === 0 && !tab.document.changed) done(); else throw new Error("Selection is not correct"); }); }); it('should load metadata for a new file', function(done) { fs.writeFile("/.c9/metadata/workspace/newfile.txt", '{"changed":true,"filter":false,"title":"Untitled1","tooltip":"/Untitled1","value":"asdasdasdasd","undoManager":{"mark":-1,"position":11,"stack":[[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":0,"column":0},"end":{"row":0,"column":1}},"text":"a"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":0,"column":1},"end":{"row":0,"column":2}},"text":"s"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":0,"column":2},"end":{"row":0,"column":3}},"text":"d"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":0,"column":3},"end":{"row":0,"column":4}},"text":"a"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":0,"column":4},"end":{"row":0,"column":5}},"text":"s"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":0,"column":5},"end":{"row":0,"column":6}},"text":"d"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":0,"column":6},"end":{"row":0,"column":7}},"text":"a"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":0,"column":7},"end":{"row":0,"column":8}},"text":"s"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":0,"column":8},"end":{"row":0,"column":9}},"text":"d"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":0,"column":9},"end":{"row":0,"column":10}},"text":"a"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":0,"column":10},"end":{"row":0,"column":11}},"text":"s"}]}],[{"group":"doc","deltas":[{"action":"insertText","range":{"start":{"row":0,"column":11},"end":{"row":0,"column":12}},"text":"d"}]}]]},"ace":{"folds":[],"scrolltop":0,"scrollleft":0,"selection":{"start":{"row":0,"column":12},"end":{"row":0,"column":12},"isBackwards":false},"options":{"newLineMode":"auto","tabSize":4,"useSoftTabs":true,"useWrapMode":null,"wrapToView":null},"firstLineState":0}}', function(err, data) { expect(err).to.not.ok; tabs.open({ path: "/newfile.txt", active: true, init: true, document: { meta: { newfile: true } } }, function(err, tab) { if (err) throw err; expect(tab.document.value).to.equal("asdasdasdasd"); tab.close(); done(); }); }); }); it('should load metadata properly for loading an existing pane that is not a file', function(done) { tabs.openEditor("terminal", true, function(err, tab) { if (err) throw err; setTimeout(function(){ var state = tab.getState(true); var name = tab.name; tab.editor.write("ls -l\n"); setTimeout(function(){ var docstate = tab.getState().document; var value = docstate.terminal.scrolltop; fs.once("afterUnlink", function(e) { fs.metadata("/_/_/" + name, docstate, function(err) { if (err) throw err; state.name = name; state.active = true; fs.exists("/.c9/metadata/" + name, function(exists) { if (!exists) throw new Error("File not found"); fs.once("afterReadFile", function(e) { setTimeout(function(){ var state = tab.document.getState(); expect(state.terminal.scrolltop, "State did not get preserved").equals(value); done(); }, 1000); }); tabs.open(state, function(err, pg) { if (err) throw err; tab = pg; }); }); }); }); tab.close(); settings.save(true); }, 1000); }, 1000); }); }); it('should work well together with state set when opening tab', function(done) { var tab = tabs.findTab("/file.js"); tabs.once("tabDestroy", function(){ setTimeout(function(){ fs.exists("/.c9/metadata/workspace/file.js", function(exists) { expect(exists, "File not found").ok; tabs.open({ path: "/file.js", active: true, document: { ace: { jump: { row: 200, column: 10, select: { row: 202, column: 20 } } } } }, function(err, tab) { setTimeout(function(){ var state = tab.document.getState(); expect(state.ace.selection.start.column).equals(10); expect(state.ace.selection.start.row).equals(200); expect(state.ace.selection.end.column).equals(20); expect(state.ace.selection.end.row).equals(202); done(); }); }) }); }); }); tab.close(); }); }); describe("Content Collision", function(){ it('should load contents stored in metadata', function(done) { var path = "/collision.js"; fs.writeFile(path, String(Date.now()), function(err) { if (err) throw err; tabs.openFile(path, true, function(err, tab) { if (err) throw err; var state = tab.getState(true); var value = String(Date.now()); // Timeout to give the change the chance to propagate setTimeout(function(){ expect(tab.document.meta.timestamp, "Timing issue").to.ok; fs.once("afterMetadata", function(e) { tabs.open(state, function(err, tab) { expect(tab.document.value).equals(value); expect(tab.document.undoManager.position).equals(0); expect(tab.document.undoManager.length).equals(1); expect(tab.document.changed).equals(true); done(); }); }); tab.document.value = value; setTimeout(function(){ tab.close(); // Forces saving metadata }, 10) }, 1000); // Give time to collect timestamp }); }); }); it('should warn if file contents on disk is newer than stored in metadata', function(done) { var path = "/collision2.js"; fs.writeFile(path, Date.now() + "a", function(err) { if (err) throw err; tabs.openFile(path, true, function(err, tab) { if (err) throw err; var state = tab.getState(true); var value = Date.now() + "b" // Timeout to give the change the chance to propagate setTimeout(function(){ expect(tab.document.meta.timestamp, "Timing issue").to.ok; fs.once("afterMetadata", function(e) { setTimeout(function(){ fs.writeFile(path, Date.now() + "c", function(err) { if (err) throw err; var curTab; question.once("show", function(){ expect(question.getElement("window").visible).ok; question.getElement("yes").dispatchEvent("click"); setTimeout(function(){ expect(curTab.document.value, "value").not.equals(value); expect(curTab.document.undoManager.position, "position").equals(1); expect(curTab.document.undoManager.length, "length").equals(2); expect(curTab.document.changed, "changed").equals(false); done(); }, 10); }); expect(state.value).to.not.equal(value); tabs.open(state, function(err, tab) { curTab = tab; }); }); }, 1100); // wait at least a second because Node 10 and lower has that change granularity }); tab.document.value = value; setTimeout(function(){ tab.close(); // Forces saving metadata }, 10); // Time to process setting of value }, 1000); // Give time to collect timestamp }); }); }); it('should warn remove undo data from metadata if file on disk is different', function(done) { var path = "/collision3.js"; fs.writeFile(path, Date.now() + "a", function(err) { if (err) throw err; tabs.openFile(path, true, function(err, tab) { if (err) throw err; var state = tab.getState(true); var value = Date.now() + "b" tab.document.value = value; // Timeout to give the change the chance to propagate setTimeout(function(){ tab.document.undoManager.bookmark(); expect(tab.document.changed).not.ok; fs.once("afterMetadata", function(e) { setTimeout(function(){ fs.writeFile(path, Date.now() + "c", function(err) { if (err) throw err; tabs.open(state, function(err, tab) { setTimeout(function(){ expect(tab.document.value).not.equals(value); expect(tab.document.undoManager.position).equals(-1); expect(tab.document.undoManager.length).equals(0); expect(tab.document.changed).equals(false); fs.unlink(path, function(){ done(); }) }, 500); }); }); }, 1100); }); tab.close(); // Forces saving metadata }); }); }); }); }); if (!onload.remain) { after(function(done) { // document.body.style.marginBottom = ""; metadata.unload(); tabs.unload(); bar.destroy(true, true); done(); }); } }); onload && onload(); } });