1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2026-01-09 00:04:11 +01:00

Merge default.

--HG--
branch : key-processing
This commit is contained in:
Kris Maglione
2011-01-25 16:20:22 -05:00
11 changed files with 42 additions and 263 deletions

22
HACKING
View File

@@ -133,12 +133,20 @@ In general: Just look at the existing source code!
Wrong:
function splitStr()
== Testing/Optimization ==
== Testing ==
TODO: Add some information here about testing/validation/etc.
Information about how/when to use :regressions might be nice.
Additionally, maybe there should be some benchmark information here --
something to let a developer know what's "too" slow...? Or general
guidelines about optimization?
Functional tests are implemented using the Mozmill automated testing framework
-- https://developer.mozilla.org/en/Mozmill_Tests.
// vim: set ft=asciidoc fdm=marker sw=4 ts=4 et ai:
A fresh profile is created for the duration of the test run, however, passing
arguments to the host application won't be supported until Mozmill 1.5.2, the
next release, so any user RC and plugin files should be temporarily disabled.
This can be done by adding the following to the head of the RC file:
set loadplugins=
finish
The host application binary tested can be overridden via the HOSTAPP_PATH
makefile variable. E.g.,
$ HOSTAPP_PATH=/path/to/firefox make -e -C pentadactyl test
// vim: fdm=marker sw=4 ts=4 et ai:

View File

@@ -9,6 +9,9 @@ GOOGLE = https://$(GOOGLE_PROJ).googlecode.com/files
VERSION ?= $(shell sed -n 's/.*em:version\(>\|="\)\(.*\)["<].*/\2/p' $(TOP)/install.rdf | sed 1q)
UUID := $(shell sed -n 's/.*em:id\(>\|="\)\(.*\)["<].*/\2/p' $(TOP)/install.rdf | sed 1q)
MANGLE := $(shell date '+%s' | awk '{ printf "%x", $$1 }')
MOZMILL = mozmill
HOSTAPP_PATH = $(shell which $(HOSTAPP))
TEST_DIR = $(BASE)/tests/functional
LOCALEDIR = locale
DOC_FILES = $(wildcard $(LOCALEDIR)/*/*.xml)
@@ -48,7 +51,7 @@ CURL ?= curl
#### rules
TARGETS = all help info jar xpi install clean distclean install installxpi $(CHROME) $(JAR)
TARGETS = all help info jar xpi install clean distclean install installxpi test $(CHROME) $(JAR)
$(TARGETS:%=\%.%):
echo MAKE $* $(@:$*.%=%)
$(MAKE) -C $* $(@:$*.%=%)
@@ -71,6 +74,7 @@ help:
@echo " make dist - uploads to Google Code (this is not for you)"
@echo " make clean - clean up"
@echo " make distclean - clean up more"
@echo " make test - run functional tests"
@echo
@echo "running some commands with V=1 will show more build details"
@@ -158,6 +162,11 @@ distclean:
@echo "More $(NAME) cleanup..."
rm -rf $(BUILD_DIR)
# TODO: generalize log path
test: $(XPI)
@echo "Running functional tests..."
$(MOZMILL) --show-all -l /tmp/dactyl-test.log -b $(HOSTAPP_PATH) --addons $(XPI) -t $(TEST_DIR)
#### xpi
$(XPI): $(CHROME)

View File

@@ -105,7 +105,7 @@ var Bookmarks = Module("bookmarks", {
*/
addSearchKeyword: function (elem) {
if (elem instanceof HTMLFormElement || elem.form)
var [url, post,, charset] = util.parseForm(elem);
var [url, post, charset] = util.parseForm(elem);
else
var [url, post, charset] = [elem.href || elem.src, null, elem.ownerDocument.characterSet];

View File

@@ -12,7 +12,7 @@ var StatusLine = Module("statusline", {
init: function () {
this._statusLine = document.getElementById("status-bar");
this.statusBar = document.getElementById("addon-bar") || this._statusLine;
this.statusBar.collapsed = true; // it is later restored unless the user sets laststatus=0
this.statusBar.collapsed = true;
this.baseGroup = this.statusBar == this._statusLine ? "StatusLine " : "";
if (this.statusBar.localName == "toolbar") {

View File

@@ -211,8 +211,9 @@
<h2 tag="status-line status-bar">Status line</h2>
<p>
The status line appears at the bottom of each window. The <o>laststatus</o>
option can be used to specify when the status line appears.
The status line appears at the bottom of each window. You can use
<o>guioptions</o> to specify if and when the status line appears, as well
as its relation to the command line and messages.
</p>
<p>

View File

@@ -169,8 +169,12 @@ function endModule() {
function require(obj, name, from) {
try {
if (arguments.length === 1)
[obj, name] = [{}, obj];
defineModule.loadLog.push((from || "require") + ": loading " + name + " into " + obj.NAME);
JSMLoader.load(name + ".jsm", obj);
return obj;
}
catch (e) {
defineModule.dump("loading " + String.quote(name + ".jsm") + "\n");

View File

@@ -8,6 +8,7 @@
try {
let global = this;
Components.utils.import("resource://dactyl/bootstrap.jsm");
defineModule("config", {
exports: ["ConfigBase", "Config", "config"],
@@ -54,7 +55,7 @@ var ConfigBase = Class("ConfigBase", {
addon: Class.memoize(function () {
let addon = services.fuel.storage.get("dactyl.bootstrap", {}).addon;
if (!addon)
addon = AddonManager.getAddonByID(this.addonID);
addon = require("addons").AddonManager.getAddonByID(this.addonID);
return addon;
}),

View File

@@ -145,10 +145,10 @@ var Highlights = Module("Highlight", {
let highlight = this.highlight[key] || this._create(false, [key]);
let extends = extend || highlight.extend;
let bases = extend || highlight.extend;
if (append) {
newStyle = Styles.append(highlight.value || "", newStyle);
extends = highlight.extends.concat(extends);
bases = highlight.extends.concat(bases);
}
if (/^\s*$/.test(newStyle))
@@ -161,11 +161,11 @@ var Highlights = Module("Highlight", {
return null;
}
newStyle = highlight.defaultValue;
extends = highlight.defaultExtends;
bases = highlight.defaultExtends;
}
highlight.set("value", newStyle || "");
highlight.extends = array.uniq(extends, true);
highlight.extends = array.uniq(bases, true);
if (force)
highlight.style.enabled = true;
this.highlight[highlight.class] = highlight;

View File

@@ -836,7 +836,7 @@ unlet s:cpo_save
let result = io.system(arg);
if (result.returnValue != 0)
result.output += "\nshell returned " + res;
result.output += "\nshell returned " + result.returnValue;
modules.commandline.command = "!" + arg;
modules.commandline.commandOutput(<span highlight="CmdOutput">{result.output}</span>);

View File

@@ -1179,7 +1179,7 @@ var Util = Module("Util", XPCOM([Ci.nsIObserver, Ci.nsISupportsWeakReference]),
}
}
if (post)
return [url, elems.join('&'), elems, charset];
return [url, elems.join('&'), charset, elems];
return [url + "?" + elems.join('&'), null, charset];
},

View File

@@ -1,244 +0,0 @@
// Copyright (c) 2009 by Martin Stubenschrott <stubenschrott@vimperator.org>
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
// Script to find regressions
//
// It should use as few dactyl methods as possible, but fall back to standard mozilla/DOM methods
// The reason is, we don't want to find regressions in the regressions script, and it should survive
// massive changes in the internal dactyl API, but just test for functionality of
// user-visible commands/mappings
//
// NOTE: It is preferable to run this script in a clean profile or at least do NOT use
// :mkpentadactylrc afterwards, as it can remove commands/mappings, etc.
//
// Usage: :[count]regr[essions]
// When [count] is given, just run this test. TODO: move to :regressions [spec]?
// all tests
var skipTests = [":bmarks", "gg"];
/////////////////////////////////////////////////////////////////////////////////////////
// Put definitions here which might change due to internal dactyl refactoring
/////////////////////////////////////////////////////////////////////////////////////////
var doc; // document where we output status messages
var multilineOutput = document.getElementById("dactyl-multiline-output");
var singlelineOutput = document.getElementById("dactyl-message");
/////////////////////////////////////////////////////////////////////////////////////////
// TESTS
//
// They are run in order, so you can specify commands which expect side effects of a
// previous command
/////////////////////////////////////////////////////////////////////////////////////////
// A series of Ex commands or mappings, each with a
// function checking whether the command succeeded
// If the string starts with a ":" it is executed as an Ex command, otherwise as a mapping
// You can also mix commands and mappings
let tests = [
{ cmds: [":!dir"],
verify: function () getMultilineOutput().length > 10 },
{ cmds: [":abbr VIMP pentadactyl labs", ":abbr"],
verify: function () getOutput().indexOf("pentadactyl labs") >= 0 },
{ cmds: [":unabbr VIMP", ":abbr"],
verify: function () getOutput().indexOf("pentadactyl labs") == -1 },
{ cmds: [":bmarks"],
verify: function () getMultilineOutput().length > 100 },
{ cmds: [":echo \"test\""],
verify: function () getSinglelineOutput() == "test" },
{ cmds: [":qmark V http://test.vimperator.org", ":qmarks"],
verify: function () getMultilineOutput().indexOf("test.vimperator.org") >= 0 },
{ cmds: [":javascript dactyl.echo('test', commandline.FORCE_MULTILINE)"],
verify: function () getMultilineOutput() == "test" },
// { cmds: [":echomsg \"testmsg\""],
// verify: function () getOutput() == "testmsg" },
// { cmds: [":echoerr \"testerr\""],
// verify: function () getOutput() == "testerr" },
{ cmds: ["gg", "<C-f>"], // NOTE: does not work when there is no page to scroll, we should load a large page before doing these tests
verify: function () this._initialPos.y != getBufferPosition().y,
init: function () this._initialPos = getBufferPosition() }
// testing tab behavior
];
// these functions highly depend on the dactyl API, so use Ex command tests whenever possible
let functions = [
function () { return bookmarks.get("").length > 0 }, // will fail for people without bookmarks :( Might want to add one before
function () { return history.get("").length > 0 }
];
/////////////////////////////////////////////////////////////////////////////////////////
// functions below should be as generic as possible, and not require being rewritten
// even after doing major Pentadactyl refactoring
/////////////////////////////////////////////////////////////////////////////////////////
function resetEnvironment() {
multilineOutput.contentDocument.body.innerHTML = "";
singlelineOutput.value = "";
commandline.close();
modes.reset();
}
function getOutput() multilineOutput.contentDocument.body.textContent || singlelineOutput.value;
function getMultilineOutput() multilineOutput.contentDocument.body.textContent;
function getSinglelineOutput() singlelineOutput.value;
function getTabIndex() getBrowser().mTabContainer.selectedIndex;
function getTabCount() getBrowser().mTabs.length;
function getBufferPosition() {
let win = window.content;
return { x: win.scrollMaxX ? win.pageXOffset / win.scrollMaxX : 0,
y: win.scrollMaxY ? win.pageYOffset / win.scrollMaxY : 0 }
};
function getLocation() window.content.document.location.href;
function echoLine(str, group) {
if (!doc)
return;
doc.body.appendChild(util.xmlToDom(
<div highlight={group} style="border: 1px solid gray; white-space: pre; height: 1.5em; line-height: 1.5em;">{str}</div>,
doc));
}
function echoMulti(str, group) {
if (!doc)
return;
doc.body.appendChild(util.xmlToDom(<div class="ex-command-output"
style="white-space: nowrap; border: 1px solid black; min-height: 1.5em;"
highlight={group}>{template.maybeXML(str)}</div>,
doc));
}
commands.addUserCommand(["regr[essions]"],
"Run regression tests",
function (args) {
// TODO: might need to increase the 'messages' option temporarily
// TODO: count (better even range) support to just run test 34 of 102
// TODO: bang support to either: a) run commands like deleting bookmarks which
// should only be done in a clean profile or b) run functions and not
// just Ex command tests; Yet to be decided
let updateOutputHeight = null;
function init() {
dactyl.registerObserver("echoLine", echoLine);
dactyl.registerObserver("echoMultiline", echoMulti);
dactyl.open("chrome://dactyl/content/buffer.xhtml", dactyl.NEW_TAB);
events.waitForPageLoad();
doc = content.document;
doc.body.setAttributeNS(NS.uri, "highlight", "CmdLine");
updateOutputHeight = commandline.updateOutputHeight;
commandline.updateOutputHeight = function (open) {
let elem = document.getElementById("dactyl-multiline-output");
if (open)
elem.collapsed = false;
elem.height = 0;
};
}
function cleanup() {
dactyl.unregisterObserver("echoLine", echoLine);
dactyl.unregisterObserver("echoMultiline", echoMulti);
commandline.updateOutputHeight = updateOutputHeight;
}
function run() {
let now = Date.now();
let totalTests = tests.length + functions.length;
let successfulTests = 0;
let skippedTests = 0;
let currentTest = 0;
init();
// TODO: might want to unify 'tests' and 'functions' handling
// 1.) run commands and mappings tests
outer:
for (let [, test] in Iterator(tests)) {
currentTest++;
if (args.count >= 1 && currentTest != args.count)
continue;
let testDescription = util.clip(test.cmds.join(" -> "), 80);
for (let [, cmd] in Iterator(test.cmds)) {
if (skipTests.indexOf(cmd) != -1) {
skippedTests++;
dactyl.echomsg("Skipping test " + currentTest + " of " + totalTests + ": " + testDescription, 0);
continue outer;
}
};
commandline.echo("Running test " + currentTest + " of " + totalTests + ": " + testDescription, "Filter", commandline.APPEND_TO_MESSAGES);
resetEnvironment();
if ("init" in test)
test.init();
test.cmds.forEach(function (cmd) {
if (cmd[0] == ":")
dactyl.execute(cmd);
else
events.feedkeys(cmd);
});
if (!test.verify())
dactyl.echoerr("Test " + currentTest + " failed: " + testDescription);
else
successfulTests++;
}
// 2.) Run function tests
for (let [, func] in Iterator(functions)) {
currentTest++;
if (args.count >= 1 && currentTest != args.count)
continue;
commandline.echo("Running test " + currentTest + " of " + totalTests + ": " + util.clip(func.toString().replace(/[\s\n]+/gm, " "), 80), "Filter", commandline.APPEND_TO_MESSAGES);
resetEnvironment();
if (!func())
dactyl.echoerr("Test " + currentTest + " failed!");
else
successfulTests++;
}
cleanup();
let runTests = (args.count >= 1 ? 1 : totalTests) - skippedTests;
XML.ignoreWhitespace = false;
dactyl.echomsg(<e4x>
<span style="font-weight: bold">{successfulTests}</span> of <span style="font-weight: bold">{runTests}</span>
tests successfully completed (<span style="font-weight: bold">{skippedTests}</span> tests skipped) in
<span class="time-total">{((Date.now() - now) / 1000.0)}</span> msec
</e4x>.*);
dactyl.execute(":messages");
}
if (!args.bang) {
dactyl.echo(<e4x>
<span style="font-weight: bold">Running tests should always be done in a new profile.</span><br/>
It should not do any harm to your profile, but your current settings like options,
abbreviations or mappings might not be in the same state as before running the tests.
Just make sure, you don't :mkpentadactylrc, after running the tests.<br/><br/>
<!--' vim. -->
Use :regressions! to skip this prompt.
</e4x>.*);
commandline.input("Type 'yes' to run the tests: ", function (res) { if (res == "yes") run(); } );
return;
}
run();
},
{
bang: true,
argCount: "0",
count: true
});
// vim: set et sts=4 sw=4 :