1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-20 05:27:59 +01:00

Bang on tests some more. Ameliorate some async completion issues.

--HG--
extra : rebase_source : 0f550b1650963e4010e447db2df7d6815627bae2
This commit is contained in:
Kris Maglione
2011-02-01 04:02:29 -05:00
parent e38f408b5d
commit a21db1858a
7 changed files with 174 additions and 107 deletions

View File

@@ -1418,7 +1418,7 @@ var CommandLine = Module("commandline", {
let command = commandline.command; let command = commandline.command;
self.accepted = true; self.accepted = true;
modes.pop(); return function () modes.pop();
}); });
[ [

View File

@@ -1989,19 +1989,6 @@ var Dactyl = Module("dactyl", XPCOM(Ci.nsISupportsWeakReference, ModuleBase), {
context.completions = [[k, v[0], v[2]] for ([k, v] in Iterator(config.dialogs))]; context.completions = [[k, v[0], v[2]] for ([k, v] in Iterator(config.dialogs))];
}; };
completion.extension = function extension(context) {
context.title = ["Extension"];
context.anchored = false;
context.keys = { text: "name", description: "description", icon: "iconURL" },
context.generate = function () {
context.incomplete = true;
AddonManager.getAddonsByTypes(["extension"], function (addons) {
context.incomplete = false;
context.completions = addons;
});
};
};
completion.help = function help(context, unchunked) { completion.help = function help(context, unchunked) {
dactyl.initHelp(); dactyl.initHelp();
context.title = ["Help"]; context.title = ["Help"];

View File

@@ -437,18 +437,32 @@ var Addons = Module("addons", {
context.completions = types.map(function (t) [t, util.capitalize(t)]); context.completions = types.map(function (t) [t, util.capitalize(t)]);
} }
if (AddonManager.getAllAddons)
context.incomplete = true;
context.generate = function generate() { context.generate = function generate() {
update(base); update(base);
if (AddonManager.getAllAddons) { if (AddonManager.getAllAddons)
context.incomplete = true;
AddonManager.getAllAddons(function (addons) { AddonManager.getAllAddons(function (addons) {
context.incomplete = false; context.incomplete = false;
update(array.uniq(base.concat(addons.map(function (a) a.type)), update(array.uniq(base.concat(addons.map(function (a) a.type)),
true)); true));
}); });
}
} }
} }
completion.extension = function extension(context, types) {
context.title = ["Extension"];
context.anchored = false;
context.keys = { text: "name", description: "description", icon: "iconURL" },
context.incomplete = true;
context.generate = function () {
AddonManager.getAddonsByTypes(types || ["extension"], function (addons) {
context.incomplete = false;
context.completions = addons;
});
};
};
} }
}); });

View File

@@ -798,14 +798,14 @@ var CompletionContext = Class("CompletionContext", {
/** /**
* Wait for all subcontexts to complete. * Wait for all subcontexts to complete.
* *
* @param {boolean} interruptible When true, the call may be interrupted
* via <C-c>, in which case, "Interrupted" may be thrown.
* @param {number} timeout The maximum time, in milliseconds, to wait. * @param {number} timeout The maximum time, in milliseconds, to wait.
* If 0 or null, wait indefinitely. * If 0 or null, wait indefinitely.
* @param {boolean} interruptible When true, the call may be interrupted
* via <C-c>, in which case, "Interrupted" may be thrown.
*/ */
wait: function wait(interruptable, timeout) { wait: function wait(timeout, interruptable) {
util.waitFor(function () !this.incomplete, this, timeout); this.allItems;
return this.incomplete; return util.waitFor(function () !this.incomplete, this, timeout, interruptable);
} }
}, { }, {
Sort: { Sort: {
@@ -852,7 +852,7 @@ var Completion = Module("completion", {
return { items: res.map(function (i) ({ item: i })) }; return { items: res.map(function (i) ({ item: i })) };
context.contexts["/run"].completions = res; context.contexts["/run"].completions = res;
} }
context.wait(true); context.wait(null, true);
return context.allItems; return context.allItems;
}, },
@@ -866,7 +866,7 @@ var Completion = Module("completion", {
context.maxItems = maxItems; context.maxItems = maxItems;
context.fork.apply(context, ["list", 0, this, name].concat(Array.slice(arguments, 3))); context.fork.apply(context, ["list", 0, this, name].concat(Array.slice(arguments, 3)));
context = context.contexts["/list"]; context = context.contexts["/list"];
context.wait(); context.wait(null, true);
let contexts = context.contextList.filter(function (c) c.hasItems && c.items.length); let contexts = context.contextList.filter(function (c) c.hasItems && c.items.length);
if (!contexts.length) if (!contexts.length)

View File

@@ -1536,10 +1536,19 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
this.yielders--; this.yielders--;
} }
}, },
waitFor: function waitFor(test, self, timeout, interruptable) { waitFor: function waitFor(test, self, timeout, interruptable) {
let end = timeout && Date.now() + timeout; let end = timeout && Date.now() + timeout, result;
while ((!end || Date.now() < end) && !test.call(self))
this.threadYield(false, interruptable); let timer = services.Timer(function () {}, 10, services.Timer.TYPE_REPEATING_SLACK);
try {
while (!(result = test.call(self)) && (!end || Date.now() < end))
this.threadYield(false, interruptable);
}
finally {
timer.cancel();
}
return result;
}, },
yieldable: function yieldable(func) yieldable: function yieldable(func)

View File

@@ -19,6 +19,10 @@ var teardownModule = function (module) {
dactyl.teardown(); dactyl.teardown();
} }
function hasItems(context) context.allItems.items.length;
function hasntNullItems(context) hasItems(context) &&
!context.allItems.items.some(function ({ text, description }) [text, description].some(function (text) /^\[object/.test(text)));
var tests = { var tests = {
"!": { "!": {
multiOutput: ["echo foo"] multiOutput: ["echo foo"]
@@ -32,18 +36,27 @@ var tests = {
noOutput: [""] noOutput: [""]
}, },
addons: { addons: {
multiOutput: ["", "dactyl", "-type=extension", "-type=extension dactyl"] multiOutput: ["", "dactyl", "-type=extension", "-type=extension dactyl"],
completions: [
"",
["-types=", hasItems]
]
}, },
autocmd: { autocmd: {
multiOutput: ["", "DOMLoad", "DOMLoad foo"], multiOutput: ["", "DOMLoad", "DOMLoad foo"],
noOutput: ["DOMLoad foo bar", "-js DOMLoad foo bar"], noOutput: ["DOMLoad foo bar", "-js DOMLoad foo bar"],
completions: ["", "DOMLoad foo ", "-js DOMLoad foo "] completions: [
["", hasntNullItems],
"DOMLoad foo ",
"-js DOMLoad foo "
]
}, },
back: { noOutput: [""] }, back: { noOutput: [""] },
bdelete: { bdelete: {
init: ["tabopen about:pentadactyl", "tabopen about:pentadactyl"], init: ["tabopen about:pentadactyl", "tabopen about:pentadactyl"],
noOutput: [""], noOutput: [""],
anyOutput: ["about:pentadactyl"] anyOutput: ["about:pentadactyl"],
completions: [["", hasItems]]
}, },
bmark: { bmark: {
someOutput: ["bmark", "bmark -tags=foo -titlt=bar -keyword=baz -charset=UTF-8 -post=quux about:pentadactyl"], someOutput: ["bmark", "bmark -tags=foo -titlt=bar -keyword=baz -charset=UTF-8 -post=quux about:pentadactyl"],
@@ -52,7 +65,7 @@ var tests = {
"-max=1 -keyword=", "-max=1 -keyword=",
"-max=1 -keyword=foo -tags=", "-max=1 -keyword=foo -tags=",
"-max=1 -keyword=foo -tags=bar -title=", "-max=1 -keyword=foo -tags=bar -title=",
"-max=1 -keyword=foo -tags=bar -title=baz -charset=", ["-max=1 -keyword=foo -tags=bar -title=baz -charset=", hasItems],
"-max=1 -keyword=foo -tags=bar -title=baz -charset= about:" "-max=1 -keyword=foo -tags=bar -title=baz -charset= about:"
] ]
}, },
@@ -68,7 +81,10 @@ var tests = {
buffer: { buffer: {
anyOutput: ["", "1"], anyOutput: ["", "1"],
noOutput: ["!", "! 1"], noOutput: ["!", "! 1"],
completions: ["", "1"] completions: [
["", hasItems],
["1", hasItems]
]
}, },
buffers: { buffers: {
multiOutput: ["", "1"], multiOutput: ["", "1"],
@@ -95,7 +111,10 @@ var tests = {
cookies: { cookies: {
anyOutput: ["dactyl.sf.net", "dactyl.sf.net list"], anyOutput: ["dactyl.sf.net", "dactyl.sf.net list"],
error: [""], error: [""],
completions: ["", "dactyl.sf.net "] completions: [
"",
["dactyl.sf.net ", hasItems]
]
}, },
delbmarks: { anyOutput: ["", "about:pentadactyl"] }, delbmarks: { anyOutput: ["", "about:pentadactyl"] },
delcommand: { delcommand: {
@@ -114,7 +133,9 @@ var tests = {
}, },
dialog: { dialog: {
// Skip implementation for now // Skip implementation for now
completions: ["", "pre"] completions: [
["", hasntNullItems]
]
}, },
doautoall: {}, // Skip for now doautoall: {}, // Skip for now
doautocmd: {}, // Skip for now doautocmd: {}, // Skip for now
@@ -147,24 +168,34 @@ var tests = {
emenu: { emenu: {
noOutput: ["View.Zoom.Zoom In", "View.Zoom.Zoom Out"], noOutput: ["View.Zoom.Zoom In", "View.Zoom.Zoom Out"],
error: [""], error: [""],
completions: ["", "View."] completions: [
["", hasItems],
["View.", hasItems]
]
}, },
endif: {}, // Skip for now endif: {}, // Skip for now
execute: { execute: {
noOutput: ["", "'js " + "".quote() + "'"], noOutput: ["", "'js " + "".quote() + "'"],
someOutput: ["'ls'"] someOutput: ["'ls'"],
completions: [["", hasItems]]
}, },
extadd: { extadd: {
completions: [""], completions: [["", hasItems]],
error: [""] error: [""]
}, },
extdelete: { extdelete: {
completions: [""], completions: [["", hasItems]],
error: [""] error: [""]
}, },
get extdisable() this.extdelete, get extdisable() this.extdelete,
get extenable() this.extdelete, extenable: {
get extoptions() this.extdelete, completions: [""],
error: [""]
},
extoptions: {
completions: [""],
error: [""]
},
get extrehash() this.extdelete, get extrehash() this.extdelete,
get exttoggle() this.extdelete, get exttoggle() this.extdelete,
get extupdate() this.extdelete, get extupdate() this.extdelete,
@@ -179,7 +210,10 @@ var tests = {
help: { help: {
noOutput: ["", "intro"], noOutput: ["", "intro"],
cleanup: ["tabdelete", "tabdelete"], cleanup: ["tabdelete", "tabdelete"],
completions: ["", "'wild"] completions: [
["", hasItems],
["'wild", hasItems]
]
}, },
get helpall() this.help, get helpall() this.help,
highlight: { highlight: {
@@ -190,34 +224,35 @@ var tests = {
"Help -group=FontCode foo: bar;" "Help -group=FontCode foo: bar;"
], ],
completions: [ completions: [
"", ["", hasItems],
"Help", ["Help", hasItems],
"Help ", ["Help ", hasItems],
"Help -group=", ["Help -group=", hasItems],
"Help -group=FontCode ", ["Help -group=FontCode ", hasItems],
"Help foo: bar; -moz" ["Help foo: bar; -moz", hasItems]
] ]
}, },
history: { history: {
init: ["open about:pentadactyl"],
anyOutput: ["-max=1", "-max=1 -sort=+date", "-max=1 dactyl"], anyOutput: ["-max=1", "-max=1 -sort=+date", "-max=1 dactyl"],
completions: [ completions: [
"", ["", hasItems],
"dactyl", "about:",
"-sort=+", ["-sort=+", hasItems],
"-sort=-", ["-sort=-", hasItems],
"-sort=+date ", ["-sort=+date ", hasItems],
"-sort=+date dactyl" "-sort=+date about:"
] ]
}, },
if: {}, // Skip for now if: {}, // Skip for now
javascript: { javascript: {
noOutput: ["''", "'\\n'", "<pre>foo bar</pre>", "window"], noOutput: ["''", "'\\n'", "<pre>foo bar</pre>", "window"],
completions: [ completions: [
"", ["", hasItems],
"window", ["window", hasItems],
"window.", ["window.", hasItems],
"window['", ["window['", hasItems],
"commands.get('" ["commands.get('", hasItems]
] ]
}, },
jumps: { jumps: {
@@ -231,7 +266,10 @@ var tests = {
let: {}, // Deprecated. Fuck it. let: {}, // Deprecated. Fuck it.
listcommands: { listcommands: {
anyOutput: ["", "in"], anyOutput: ["", "in"],
completions: ["", "in "] completions: [
["", hasItems],
"in "
]
}, },
get listkeys() this.listcommands, get listkeys() this.listcommands,
get listoptions() this.listcommands, get listoptions() this.listcommands,
@@ -256,14 +294,14 @@ var tests = {
"-gtroup=some-nonexistent-group <C-a> <C-a>" "-gtroup=some-nonexistent-group <C-a> <C-a>"
], ],
completeions: [ completeions: [
"", ["", hasItems],
"-", ["-", hasItems],
"-mode=ex ", ["-mode=ex ", hasItems],
"-mode=", ["-mode=", hasItems],
"-group=", ["-group=", hasItems],
"-builtin i ", ["-builtin i ", hasItems],
"-ex i ", ["-ex i ", hasItems],
"-javascript i ", ["-javascript i ", hasItems]
] ]
}, },
mapclear: { mapclear: {
@@ -326,7 +364,9 @@ var tests = {
"some-nonexistent-pentadactyl-dir/", "some-nonexistent-pentadactyl-dir/",
"some-nonexistent-pentadactyl-dir/foo.vim" "some-nonexistent-pentadactyl-dir/foo.vim"
], ],
completeions: [""], completeions: [
["", hasItems]
],
cleanup: ["silent !rm -r some-nonexistent-pentadactyl-dir/"] cleanup: ["silent !rm -r some-nonexistent-pentadactyl-dir/"]
}, },
normal: { normal: {
@@ -337,20 +377,20 @@ var tests = {
open: { open: {
noOutput: ["about:blank | about:home"], noOutput: ["about:blank | about:home"],
completions: [ completions: [
"", ["", hasItems],
"./", ["./", hasItems],
"./ | ", ["./ | ", hasItems],
"chrome://", ["chrome://", hasItems],
"chrome://browser/", ["chrome://browser/", hasItems],
"chrome://browser/content/", ["chrome://browser/content/", hasItems],
"about:", ["about:", hasItems],
"resource://", ["resource://", hasItems],
"resource://dactyl/" ["resource://dactyl/", hasItems]
] ]
}, },
pageinfo: { pageinfo: {
multiOutput: ["", "fgm"], multiOutput: ["", "fgm"],
completions: [""], completions: [["", hasItems]],
error: ["abcdefghijklmnopqrstuvwxyz", "f g m"] error: ["abcdefghijklmnopqrstuvwxyz", "f g m"]
}, },
pagestyle: { pagestyle: {
@@ -366,7 +406,10 @@ var tests = {
"m foo bar" "m foo bar"
], ],
error: ["", "#"], error: ["", "#"],
completions: ["", "m "] completions: [
["", hasItems], // Fails. Why?
["m ", hasItems]
]
}, },
qmarks: [ qmarks: [
{ {
@@ -376,7 +419,7 @@ var tests = {
{ {
init: ["qmark x"], init: ["qmark x"],
multiOutput: ["", "m", "x"], multiOutput: ["", "m", "x"],
completions: [""] completions: [["", hasItems]]
} }
], ],
quit: {}, // Skip for now quit: {}, // Skip for now
@@ -446,7 +489,10 @@ var tests = {
// "!" Previous sidebar isn't saved until the window loads. // "!" Previous sidebar isn't saved until the window loads.
// We don't give it enough time. // We don't give it enough time.
], ],
completions: ["", "! "] completions: [
["", hasntNullItems],
"! "
]
}, },
silent: { silent: {
noOutput: [ noOutput: [
@@ -455,7 +501,7 @@ var tests = {
"echoerr 'foo'", "echoerr 'foo'",
"echoerr " + "foo\nbar".quote() "echoerr " + "foo\nbar".quote()
], ],
completions: [""] completions: [["", hasItems]]
}, },
source: {}, source: {},
stop: {}, stop: {},
@@ -508,7 +554,7 @@ function runCommands(cmdName, testName, commands, test, forbidErrors) {
commands.forEach(function (val) { commands.forEach(function (val) {
var [cmd, testVal] = Array.concat(val); var [cmd, testVal] = Array.concat(val);
// dump("CMD: " + testName + " " + cmdName + " " + cmd + "\n"); dump("CMD: " + testName + " " + cmdName + " " + cmd + "\n");
dactyl.clearMessage(); dactyl.clearMessage();
dactyl.closeMessageWindow(); dactyl.closeMessageWindow();
@@ -529,7 +575,7 @@ function _runCommands(cmdName, testName, commands) {
commands.forEach(function (value) { commands.forEach(function (value) {
var [cmd, test] = Array.concat(value); var [cmd, test] = Array.concat(value);
// dump("CMD: " + testName + " " + cmdName + " " + cmd + "\n"); dump("CMD: " + testName + " " + cmdName + " " + cmd + "\n");
var res = dactyl.runExCommand(cmd); var res = dactyl.runExCommand(cmd);
controller.waitForPageLoad(controller.tabs.activeTab); controller.waitForPageLoad(controller.tabs.activeTab);
if (test) if (test)
@@ -602,12 +648,21 @@ for (var val in Iterator(tests)) (function ([command, paramsList]) {
addTest(command, testName, function () { addTest(command, testName, function () {
commands.forEach(function (val) { commands.forEach(function (val) {
var [cmd, test] = Array.concat(val); var [cmd, test] = Array.concat(val);
cmd = command + cmd.replace(/^(!?) ?/, "$1 ");
dactyl.assertNoErrorMessages(function () { dactyl.assertNoErrorMessages(function () {
dactyl.runExCompletion(command + cmd.replace(/^(!?) ?/, "$1 ")); dump("COMPL: " + cmd + "\n");
if (test) dactyl.runExCompletion(cmd);
jumlib.assert(test(dactyl.modules.commandline.commandSession.completions.context), if (test) {
"Initializing for " + cmdName + " tests failed: " + cmd.quote() + " " + test); /* Freezes. :(
var context = dactyl.modules.commandline.commandSession.completions.context;
*/
var context = dactyl.modules.CompletionContext(cmd);
context.tabPressed = true;
context.fork("ex", 0, dactyl.modules.completion, "ex");
jumlib.assert(context.wait(5000), "Completion failed: " + cmd.quote());
jumlib.assert(test(context), "Completion tests failed: " + cmd.quote() + " " + test);
}
}); });
}); });
}); });

View File

@@ -281,11 +281,16 @@ var Config = Module("config", ConfigBase, {
const { CompletionContext, bookmarkcache, bookmarks, completion } = modules; const { CompletionContext, bookmarkcache, bookmarks, completion } = modules;
const { document } = window; const { document } = window;
var searchRunning = false; // only until Firefox fixes https://bugzilla.mozilla.org/show_bug.cgi?id=510589 var searchRunning = null; // only until Firefox fixes https://bugzilla.mozilla.org/show_bug.cgi?id=510589
completion.location = function location(context) { completion.location = function location(context) {
if (!services.autoCompleteSearch) if (!services.autoCompleteSearch)
return; return;
if (searchRunning) {
searchRunning.completions = searchRunning.completions;
searchRunning.cancel();
}
context.anchored = false; context.anchored = false;
context.compare = CompletionContext.Sort.unsorted; context.compare = CompletionContext.Sort.unsorted;
context.filterFunc = null; context.filterFunc = null;
@@ -297,30 +302,27 @@ var Config = Module("config", ConfigBase, {
context.title = ["Smart Completions"]; context.title = ["Smart Completions"];
context.cancel = function () { context.cancel = function () {
if (searchRunning) { this.incomplete = false;
if (searchRunning === this) {
services.autoCompleteSearch.stopSearch(); services.autoCompleteSearch.stopSearch();
searchRunning = false; searchRunning = null;
} }
}; };
if (searchRunning)
services.autoCompleteSearch.stopSearch();
let timer = new Timer(50, 100, function (result) {
context.incomplete = result.searchResult >= result.RESULT_NOMATCH_ONGOING;
context.completions = [
{ url: result.getValueAt(i), title: result.getCommentAt(i), icon: result.getImageAt(i) }
for (i in util.range(0, result.matchCount))
];
});
services.autoCompleteSearch.startSearch(context.filter, "", context.result, { services.autoCompleteSearch.startSearch(context.filter, "", context.result, {
onSearchResult: function onSearchResult(search, result) { onSearchResult: function onSearchResult(search, result) {
timer.tell(result); if (result.searchResult <= result.RESULT_SUCCESS)
if (result.searchResult <= result.RESULT_SUCCESS) { searchRunning = null;
searchRunning = false;
timer.flush(); context.incomplete = result.searchResult >= result.RESULT_NOMATCH_ONGOING;
} context.completions = [
} { url: result.getValueAt(i), title: result.getCommentAt(i), icon: result.getImageAt(i) }
for (i in util.range(0, result.matchCount))
];
},
get onUpdateSearchResult() this.onSearchResult
}); });
searchRunning = true; searchRunning = context;
}; };
completion.sidebar = function sidebar(context) { completion.sidebar = function sidebar(context) {