зеркало из https://github.com/mozilla/gecko-dev.git
713 строки
19 KiB
JavaScript
713 строки
19 KiB
JavaScript
// nsDoTestsForAutoCompleteWithComposition tests autocomplete with composition.
|
|
// Users must include SimpleTest.js and EventUtils.js.
|
|
|
|
function waitForCondition(condition, nextTest) {
|
|
var tries = 0;
|
|
var interval = setInterval(function() {
|
|
if (condition() || tries >= 30) {
|
|
moveOn();
|
|
}
|
|
tries++;
|
|
}, 100);
|
|
var moveOn = function() {
|
|
clearInterval(interval);
|
|
nextTest();
|
|
};
|
|
}
|
|
|
|
function nsDoTestsForAutoCompleteWithComposition(
|
|
aDescription,
|
|
aWindow,
|
|
aTarget,
|
|
aAutoCompleteController,
|
|
aIsFunc,
|
|
aGetTargetValueFunc,
|
|
aOnFinishFunc
|
|
) {
|
|
this._description = aDescription;
|
|
this._window = aWindow;
|
|
this._target = aTarget;
|
|
this._controller = aAutoCompleteController;
|
|
|
|
this._is = aIsFunc;
|
|
this._getTargetValue = aGetTargetValueFunc;
|
|
this._onFinish = aOnFinishFunc;
|
|
|
|
this._target.focus();
|
|
|
|
this._DefaultCompleteDefaultIndex = this._controller.input.completeDefaultIndex;
|
|
|
|
this._doTests();
|
|
}
|
|
|
|
nsDoTestsForAutoCompleteWithComposition.prototype = {
|
|
_window: null,
|
|
_target: null,
|
|
_controller: null,
|
|
_DefaultCompleteDefaultIndex: false,
|
|
_description: "",
|
|
|
|
_is: null,
|
|
_getTargetValue() {
|
|
return "not initialized";
|
|
},
|
|
_onFinish: null,
|
|
|
|
_doTests() {
|
|
if (++this._testingIndex == this._tests.length) {
|
|
this._controller.input.completeDefaultIndex = this._DefaultCompleteDefaultIndex;
|
|
this._onFinish();
|
|
return;
|
|
}
|
|
|
|
var test = this._tests[this._testingIndex];
|
|
if (
|
|
this._controller.input.completeDefaultIndex != test.completeDefaultIndex
|
|
) {
|
|
this._controller.input.completeDefaultIndex = test.completeDefaultIndex;
|
|
}
|
|
test.execute(this._window);
|
|
|
|
if (test.popup) {
|
|
waitForCondition(
|
|
() => this._controller.input.popupOpen,
|
|
this._checkResult.bind(this)
|
|
);
|
|
} else {
|
|
waitForCondition(() => {
|
|
this._controller.searchStatus >=
|
|
Ci.nsIAutoCompleteController.STATUS_COMPLETE_NO_MATCH;
|
|
}, this._checkResult.bind(this));
|
|
}
|
|
},
|
|
|
|
_checkResult() {
|
|
var test = this._tests[this._testingIndex];
|
|
this._is(
|
|
this._getTargetValue(),
|
|
test.value,
|
|
this._description + ", " + test.description + ": value"
|
|
);
|
|
this._is(
|
|
this._controller.searchString,
|
|
test.searchString,
|
|
this._description + ", " + test.description + ": searchString"
|
|
);
|
|
this._is(
|
|
this._controller.input.popupOpen,
|
|
test.popup,
|
|
this._description + ", " + test.description + ": popupOpen"
|
|
);
|
|
this._doTests();
|
|
},
|
|
|
|
_testingIndex: -1,
|
|
_tests: [
|
|
// Simple composition when popup hasn't been shown.
|
|
// The autocomplete popup should not be shown during composition, but
|
|
// after compositionend, the popup should be shown.
|
|
{
|
|
description: "compositionstart shouldn't open the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: {
|
|
string: "M",
|
|
clauses: [{ length: 1, attr: COMPOSITION_ATTR_RAW_CLAUSE }],
|
|
},
|
|
caret: { start: 1, length: 0 },
|
|
key: { key: "M" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "M",
|
|
searchString: "",
|
|
},
|
|
{
|
|
description: "modifying composition string shouldn't open the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: {
|
|
string: "Mo",
|
|
clauses: [{ length: 2, attr: COMPOSITION_ATTR_RAW_CLAUSE }],
|
|
},
|
|
caret: { start: 2, length: 0 },
|
|
key: { key: "o" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "Mo",
|
|
searchString: "",
|
|
},
|
|
{
|
|
description: "compositionend should open the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeComposition(
|
|
{ type: "compositioncommitasis", key: { key: "KEY_Enter" } },
|
|
aWindow
|
|
);
|
|
},
|
|
popup: true,
|
|
value: "Mo",
|
|
searchString: "Mo",
|
|
},
|
|
// If composition starts when popup is shown, the compositionstart event
|
|
// should cause closing the popup.
|
|
{
|
|
description: "compositionstart should close the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: {
|
|
string: "z",
|
|
clauses: [{ length: 1, attr: COMPOSITION_ATTR_RAW_CLAUSE }],
|
|
},
|
|
caret: { start: 1, length: 0 },
|
|
key: { key: "z" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "Moz",
|
|
searchString: "Mo",
|
|
},
|
|
{
|
|
description: "modifying composition string shouldn't reopen the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: {
|
|
string: "zi",
|
|
clauses: [{ length: 2, attr: COMPOSITION_ATTR_RAW_CLAUSE }],
|
|
},
|
|
caret: { start: 2, length: 0 },
|
|
key: { key: "i" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "Mozi",
|
|
searchString: "Mo",
|
|
},
|
|
{
|
|
description:
|
|
"compositionend should research the result and open the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeComposition(
|
|
{ type: "compositioncommitasis", key: { key: "KEY_Enter" } },
|
|
aWindow
|
|
);
|
|
},
|
|
popup: true,
|
|
value: "Mozi",
|
|
searchString: "Mozi",
|
|
},
|
|
// If composition is cancelled, the value shouldn't be changed.
|
|
{
|
|
description: "compositionstart should reclose the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: {
|
|
string: "l",
|
|
clauses: [{ length: 1, attr: COMPOSITION_ATTR_RAW_CLAUSE }],
|
|
},
|
|
caret: { start: 1, length: 0 },
|
|
key: { key: "l" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "Mozil",
|
|
searchString: "Mozi",
|
|
},
|
|
{
|
|
description: "modifying composition string shouldn't reopen the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: {
|
|
string: "ll",
|
|
clauses: [{ length: 2, attr: COMPOSITION_ATTR_RAW_CLAUSE }],
|
|
},
|
|
caret: { start: 2, length: 0 },
|
|
key: { key: "l" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "Mozill",
|
|
searchString: "Mozi",
|
|
},
|
|
{
|
|
description:
|
|
"modifying composition string to empty string shouldn't reopen the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: { string: "", clauses: [{ length: 0, attr: 0 }] },
|
|
caret: { start: 0, length: 0 },
|
|
key: { key: "KEY_Backspace" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "Mozi",
|
|
searchString: "Mozi",
|
|
},
|
|
{
|
|
description: "cancled compositionend should reopen the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeComposition(
|
|
{ type: "compositioncommit", data: "", key: { key: "KEY_Escape" } },
|
|
aWindow
|
|
);
|
|
},
|
|
popup: true,
|
|
value: "Mozi",
|
|
searchString: "Mozi",
|
|
},
|
|
// But if composition replaces some characters and canceled, the search
|
|
// string should be the latest value.
|
|
{
|
|
description:
|
|
"compositionstart with selected string should close the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeKey("VK_LEFT", { shiftKey: true }, aWindow);
|
|
synthesizeKey("VK_LEFT", { shiftKey: true }, aWindow);
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: {
|
|
string: "z",
|
|
clauses: [{ length: 1, attr: COMPOSITION_ATTR_RAW_CLAUSE }],
|
|
},
|
|
caret: { start: 1, length: 0 },
|
|
key: { key: "z" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "Moz",
|
|
searchString: "Mozi",
|
|
},
|
|
{
|
|
description: "modifying composition string shouldn't reopen the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: {
|
|
string: "zi",
|
|
clauses: [{ length: 2, attr: COMPOSITION_ATTR_RAW_CLAUSE }],
|
|
},
|
|
caret: { start: 2, length: 0 },
|
|
key: { key: "i" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "Mozi",
|
|
searchString: "Mozi",
|
|
},
|
|
{
|
|
description:
|
|
"modifying composition string to empty string shouldn't reopen the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: { string: "", clauses: [{ length: 0, attr: 0 }] },
|
|
caret: { start: 0, length: 0 },
|
|
key: { key: "KEY_Backspace" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "Mo",
|
|
searchString: "Mozi",
|
|
},
|
|
{
|
|
description:
|
|
"canceled compositionend should search the result with the latest value",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeComposition(
|
|
{ type: "compositioncommitasis", key: { key: "KEY_Escape" } },
|
|
aWindow
|
|
);
|
|
},
|
|
popup: true,
|
|
value: "Mo",
|
|
searchString: "Mo",
|
|
},
|
|
// If all characters are removed, the popup should be closed.
|
|
{
|
|
description:
|
|
"the value becomes empty by backspace, the popup should be closed",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeKey("KEY_Backspace", {}, aWindow);
|
|
synthesizeKey("KEY_Backspace", {}, aWindow);
|
|
},
|
|
popup: false,
|
|
value: "",
|
|
searchString: "",
|
|
},
|
|
// composition which is canceled shouldn't cause opening the popup.
|
|
{
|
|
description: "compositionstart shouldn't open the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: {
|
|
string: "M",
|
|
clauses: [{ length: 1, attr: COMPOSITION_ATTR_RAW_CLAUSE }],
|
|
},
|
|
caret: { start: 1, length: 0 },
|
|
key: { key: "M" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "M",
|
|
searchString: "",
|
|
},
|
|
{
|
|
description: "modifying composition string shouldn't open the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: {
|
|
string: "Mo",
|
|
clauses: [{ length: 2, attr: COMPOSITION_ATTR_RAW_CLAUSE }],
|
|
},
|
|
caret: { start: 2, length: 0 },
|
|
key: { key: "o" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "Mo",
|
|
searchString: "",
|
|
},
|
|
{
|
|
description:
|
|
"modifying composition string to empty string shouldn't open the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: { string: "", clauses: [{ length: 0, attr: 0 }] },
|
|
caret: { start: 0, length: 0 },
|
|
key: { key: "KEY_Backspace" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "",
|
|
searchString: "",
|
|
},
|
|
{
|
|
description:
|
|
"canceled compositionend shouldn't open the popup if it was closed",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeComposition(
|
|
{ type: "compositioncommitasis", key: { key: "KEY_Escape" } },
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "",
|
|
searchString: "",
|
|
},
|
|
// Down key should open the popup even if the editor is empty.
|
|
{
|
|
description: "DOWN key should open the popup even if the value is empty",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeKey("KEY_ArrowDown", {}, aWindow);
|
|
},
|
|
popup: true,
|
|
value: "",
|
|
searchString: "",
|
|
},
|
|
// If popup is open at starting composition, the popup should be reopened
|
|
// after composition anyway.
|
|
{
|
|
description: "compositionstart shouldn't open the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: {
|
|
string: "M",
|
|
clauses: [{ length: 1, attr: COMPOSITION_ATTR_RAW_CLAUSE }],
|
|
},
|
|
caret: { start: 1, length: 0 },
|
|
key: { key: "M" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "M",
|
|
searchString: "",
|
|
},
|
|
{
|
|
description: "modifying composition string shouldn't open the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: {
|
|
string: "Mo",
|
|
clauses: [{ length: 2, attr: COMPOSITION_ATTR_RAW_CLAUSE }],
|
|
},
|
|
caret: { start: 2, length: 0 },
|
|
key: { key: "o" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "Mo",
|
|
searchString: "",
|
|
},
|
|
{
|
|
description:
|
|
"modifying composition string to empty string shouldn't open the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: { string: "", clauses: [{ length: 0, attr: 0 }] },
|
|
caret: { start: 0, length: 0 },
|
|
key: { key: "KEY_Backspace" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "",
|
|
searchString: "",
|
|
},
|
|
{
|
|
description:
|
|
"canceled compositionend should open the popup if it was opened",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeComposition(
|
|
{ type: "compositioncommitasis", key: { key: "KEY_Escape" } },
|
|
aWindow
|
|
);
|
|
},
|
|
popup: true,
|
|
value: "",
|
|
searchString: "",
|
|
},
|
|
// Type normally, and hit escape, the popup should be closed.
|
|
{
|
|
description: "ESCAPE should close the popup after typing something",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeKey("M", {}, aWindow);
|
|
synthesizeKey("o", {}, aWindow);
|
|
synthesizeKey("KEY_Escape", {}, aWindow);
|
|
},
|
|
popup: false,
|
|
value: "Mo",
|
|
searchString: "Mo",
|
|
},
|
|
// Even if the popup is closed, composition which is canceled should open
|
|
// the popup if the value isn't empty.
|
|
// XXX This might not be good behavior, but anyway, this is minor issue...
|
|
{
|
|
description: "compositionstart shouldn't open the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: {
|
|
string: "z",
|
|
clauses: [{ length: 1, attr: COMPOSITION_ATTR_RAW_CLAUSE }],
|
|
},
|
|
caret: { start: 1, length: 0 },
|
|
key: { key: "z" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "Moz",
|
|
searchString: "Mo",
|
|
},
|
|
{
|
|
description: "modifying composition string shouldn't open the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: {
|
|
string: "zi",
|
|
clauses: [{ length: 2, attr: COMPOSITION_ATTR_RAW_CLAUSE }],
|
|
},
|
|
caret: { start: 2, length: 0 },
|
|
key: { key: "i" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "Mozi",
|
|
searchString: "Mo",
|
|
},
|
|
{
|
|
description:
|
|
"modifying composition string to empty string shouldn't open the popup",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: { string: "", clauses: [{ length: 0, attr: 0 }] },
|
|
caret: { start: 0, length: 0 },
|
|
key: { key: "KEY_Backspace" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "Mo",
|
|
searchString: "Mo",
|
|
},
|
|
{
|
|
description:
|
|
"canceled compositionend shouldn't open the popup if the popup was closed",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeComposition(
|
|
{ type: "compositioncommitasis", key: { key: "KEY_Escape" } },
|
|
aWindow
|
|
);
|
|
},
|
|
popup: true,
|
|
value: "Mo",
|
|
searchString: "Mo",
|
|
},
|
|
// House keeping...
|
|
{
|
|
description: "house keeping for next tests",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeKey("KEY_Backspace", {}, aWindow);
|
|
synthesizeKey("KEY_Backspace", {}, aWindow);
|
|
},
|
|
popup: false,
|
|
value: "",
|
|
searchString: "",
|
|
},
|
|
// Testing for nsIAutoCompleteInput.completeDefaultIndex being true.
|
|
{
|
|
description:
|
|
"compositionstart shouldn't open the popup (completeDefaultIndex is true)",
|
|
completeDefaultIndex: true,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: {
|
|
string: "M",
|
|
clauses: [{ length: 1, attr: COMPOSITION_ATTR_RAW_CLAUSE }],
|
|
},
|
|
caret: { start: 1, length: 0 },
|
|
key: { key: "M" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "M",
|
|
searchString: "",
|
|
},
|
|
{
|
|
description:
|
|
"modifying composition string shouldn't open the popup (completeDefaultIndex is true)",
|
|
completeDefaultIndex: true,
|
|
execute(aWindow) {
|
|
synthesizeCompositionChange(
|
|
{
|
|
composition: {
|
|
string: "Mo",
|
|
clauses: [{ length: 2, attr: COMPOSITION_ATTR_RAW_CLAUSE }],
|
|
},
|
|
caret: { start: 2, length: 0 },
|
|
key: { key: "o" },
|
|
},
|
|
aWindow
|
|
);
|
|
},
|
|
popup: false,
|
|
value: "Mo",
|
|
searchString: "",
|
|
},
|
|
{
|
|
description:
|
|
"compositionend should open the popup (completeDefaultIndex is true)",
|
|
completeDefaultIndex: true,
|
|
execute(aWindow) {
|
|
synthesizeComposition(
|
|
{ type: "compositioncommitasis", key: { key: "KEY_Enter" } },
|
|
aWindow
|
|
);
|
|
},
|
|
popup: true,
|
|
value: "Mozilla",
|
|
searchString: "Mo",
|
|
},
|
|
// House keeping...
|
|
{
|
|
description: "house keeping for next tests",
|
|
completeDefaultIndex: false,
|
|
execute(aWindow) {
|
|
synthesizeKey("KEY_Backspace", {}, aWindow);
|
|
synthesizeKey("KEY_Backspace", {}, aWindow);
|
|
synthesizeKey("KEY_Backspace", {}, aWindow);
|
|
synthesizeKey("KEY_Backspace", {}, aWindow);
|
|
synthesizeKey("KEY_Backspace", {}, aWindow);
|
|
synthesizeKey("KEY_Backspace", {}, aWindow);
|
|
},
|
|
popup: false,
|
|
value: "",
|
|
searchString: "",
|
|
},
|
|
],
|
|
};
|