mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-26 01:27:42 +00:00
feat(web): multitap selection test
This commit is contained in:
parent
1c18334817
commit
f11ae5c570
2 changed files with 138 additions and 11 deletions
|
|
@ -54,7 +54,7 @@ describe("MatcherSelector", function () {
|
|||
selectorPromise,
|
||||
executor
|
||||
} = simulateSelectorInput({
|
||||
pathSpecs: { type: 'sequence', samples: turtle.path, terminate: false },
|
||||
pathSpecs: [{ type: 'sequence', samples: turtle.path, terminate: false }],
|
||||
specSet: [LongpressModel]
|
||||
}, this.fakeClock);
|
||||
|
||||
|
|
@ -91,7 +91,7 @@ describe("MatcherSelector", function () {
|
|||
selectorPromise,
|
||||
executor
|
||||
} = simulateSelectorInput({
|
||||
pathSpecs: { type: 'sequence', samples: turtle.path, terminate: false },
|
||||
pathSpecs: [{ type: 'sequence', samples: turtle.path, terminate: false }],
|
||||
specSet: [LongpressModel, MultitapModel, SimpleTapModel]
|
||||
}, this.fakeClock);
|
||||
|
||||
|
|
@ -129,7 +129,7 @@ describe("MatcherSelector", function () {
|
|||
selectorPromise,
|
||||
executor
|
||||
} = simulateSelectorInput({
|
||||
pathSpecs: { type: 'sequence', samples: turtle.path, terminate: false },
|
||||
pathSpecs: [{ type: 'sequence', samples: turtle.path, terminate: false }],
|
||||
specSet: [LongpressModel]
|
||||
}, this.fakeClock);
|
||||
|
||||
|
|
@ -175,7 +175,7 @@ describe("MatcherSelector", function () {
|
|||
selectorPromise,
|
||||
executor
|
||||
} = simulateSelectorInput({
|
||||
pathSpecs: { type: 'sequence', samples: turtle.path, terminate: false },
|
||||
pathSpecs: [{ type: 'sequence', samples: turtle.path, terminate: false }],
|
||||
specSet: [LongpressModel]
|
||||
}, this.fakeClock);
|
||||
|
||||
|
|
@ -231,7 +231,7 @@ describe("MatcherSelector", function () {
|
|||
selectorPromise,
|
||||
executor
|
||||
} = simulateSelectorInput({
|
||||
pathSpecs: { type: 'sequence', samples: turtle.path, terminate: false },
|
||||
pathSpecs: [{ type: 'sequence', samples: turtle.path, terminate: false }],
|
||||
// Current problem: adding the extra models leads to rejection of all?
|
||||
specSet: [LongpressModel, MultitapModel, SimpleTapModel]
|
||||
}, this.fakeClock);
|
||||
|
|
@ -286,7 +286,7 @@ describe("MatcherSelector", function () {
|
|||
selectorPromise,
|
||||
executor
|
||||
} = simulateSelectorInput({
|
||||
pathSpecs: { type: 'sequence', samples: turtle.path, terminate: true },
|
||||
pathSpecs: [{ type: 'sequence', samples: turtle.path, terminate: true }],
|
||||
specSet: [LongpressModel, MultitapModel, SimpleTapModel]
|
||||
}, this.fakeClock);
|
||||
|
||||
|
|
@ -328,7 +328,7 @@ describe("MatcherSelector", function () {
|
|||
selectorPromise,
|
||||
executor
|
||||
} = simulateSelectorInput({
|
||||
pathSpecs: { type: 'sequence', samples: turtle.path, terminate: true },
|
||||
pathSpecs: [{ type: 'sequence', samples: turtle.path, terminate: true }],
|
||||
specSet: [LongpressModel, MultitapModel, SimpleTapModel]
|
||||
}, this.fakeClock);
|
||||
|
||||
|
|
@ -408,11 +408,11 @@ describe("MatcherSelector", function () {
|
|||
executor
|
||||
} = simulateSelectorInput(
|
||||
{
|
||||
pathSpecs: {
|
||||
pathSpecs: [{
|
||||
type: 'prior-matcher',
|
||||
matcher: predecessorMatcher,
|
||||
continuation: [{ type: 'sequence', samples: remainingPath, terminate: true }]
|
||||
},
|
||||
}],
|
||||
specSet: [SubkeySelectModel]
|
||||
}
|
||||
, this.fakeClock);
|
||||
|
|
@ -435,4 +435,130 @@ describe("MatcherSelector", function () {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Multi-source", function() {
|
||||
describe("First stage", function() {
|
||||
it("Simple tap (from second contact point during lifetime)", async function() {
|
||||
const turtle1 = new TouchpathTurtle({
|
||||
targetX: 1,
|
||||
targetY: 1,
|
||||
t: 100,
|
||||
item: 'a'
|
||||
});
|
||||
turtle1.wait(100, 5);
|
||||
turtle1.commitPending();
|
||||
|
||||
const {
|
||||
sources,
|
||||
selectionPromises,
|
||||
selectorPromise,
|
||||
executor
|
||||
} = simulateSelectorInput({
|
||||
pathSpecs: [
|
||||
{ type: 'sequence', samples: turtle1.path, terminate: false },
|
||||
{ type: 'sequence', samples: [{
|
||||
targetX: 5,
|
||||
targetY: 1,
|
||||
t: 200,
|
||||
item: 'b'
|
||||
}], terminate: false }
|
||||
],
|
||||
specSet: [LongpressModel, MultitapModel, SimpleTapModel]
|
||||
}, this.fakeClock);
|
||||
|
||||
let completion = executor();
|
||||
const selector = await selectorPromise;
|
||||
await Promise.race([completion, selectionPromises[0]]);
|
||||
|
||||
// So, the terminate signal didn't complete the selection?
|
||||
assert.equal(await promiseStatus(selectionPromises[0]), PromiseStatuses.PROMISE_RESOLVED);
|
||||
assert.equal(await promiseStatus(completion), PromiseStatusModule.PROMISE_PENDING);
|
||||
|
||||
const selection = await selectionPromises[0];
|
||||
|
||||
assert.deepEqual(selection.result, {matched: true, action: { type: 'optional-chain', item: 'a', allowNext: 'multitap' }});
|
||||
assert.deepEqual(selection.matcher.model, SimpleTapModel);
|
||||
assert.isTrue(sources[0].path.isComplete);
|
||||
|
||||
// Allow the rest of the simulation to play out; it's easy cleanup that way.
|
||||
await completion;
|
||||
});
|
||||
});
|
||||
|
||||
describe("Later stages", function() {
|
||||
it("Multi-tap", async function() {
|
||||
const turtle1 = new TouchpathTurtle({
|
||||
targetX: 1,
|
||||
targetY: 1,
|
||||
t: 100,
|
||||
item: 'a'
|
||||
});
|
||||
turtle1.wait(100, 5);
|
||||
turtle1.commitPending();
|
||||
|
||||
// Set up the prior stage's match
|
||||
const {
|
||||
executor: predExecutor,
|
||||
modelMatcherPromise
|
||||
} = simulateMultiSourceMatcherInput([
|
||||
{ type: 'sequence', samples: turtle1.path, terminate: true }
|
||||
], this.fakeClock, LongpressModel);
|
||||
|
||||
await predExecutor();
|
||||
const predecessorMatcher = await modelMatcherPromise;
|
||||
assert.equal(await promiseStatus(modelMatcherPromise), PromiseStatuses.PROMISE_RESOLVED);
|
||||
|
||||
const turtle2 = new TouchpathTurtle({
|
||||
targetX: 2,
|
||||
targetY: 2,
|
||||
t: 300,
|
||||
item: 'a'
|
||||
});
|
||||
turtle2.wait(100, 5);
|
||||
turtle2.commitPending();
|
||||
|
||||
const {
|
||||
sources,
|
||||
selectionPromises,
|
||||
selectorPromise,
|
||||
executor
|
||||
} = simulateSelectorInput(
|
||||
{
|
||||
pathSpecs: [
|
||||
{
|
||||
type: 'prior-matcher',
|
||||
matcher: predecessorMatcher,
|
||||
continuation: null // that GestureSource is DONE, terminated. No continues.
|
||||
}, {
|
||||
type: 'sequence',
|
||||
samples: turtle2.path,
|
||||
terminate: true
|
||||
}
|
||||
],
|
||||
specSet: [LongpressModel, MultitapModel, SimpleTapModel]
|
||||
}
|
||||
, this.fakeClock);
|
||||
|
||||
let completion = executor();
|
||||
const selector = await selectorPromise;
|
||||
await Promise.race([completion, selectionPromises[0]]);
|
||||
|
||||
assert.equal(await promiseStatus(selectionPromises[0]), PromiseStatuses.PROMISE_RESOLVED);
|
||||
assert.equal(await promiseStatus(completion), PromiseStatusModule.PROMISE_PENDING);
|
||||
|
||||
const selection = await selectionPromises[0];
|
||||
|
||||
assert.deepEqual(selection.result, {matched: true, action: { type: 'chain', item: 'a', next: 'multitap' }});
|
||||
assert.deepEqual(selection.matcher.model, MultitapModel);
|
||||
assert.isTrue(sources[0].path.isComplete);
|
||||
|
||||
// Allow the rest of the simulation to play out; it's easy cleanup that way.
|
||||
await completion;
|
||||
});
|
||||
|
||||
it.skip("Single tap (on different key/item than prior tap)", function() {
|
||||
//
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -333,7 +333,7 @@ export function simulateMultiSourceMatcherInput<Type>(
|
|||
}
|
||||
|
||||
type MatcherSelectorInput<Type> = {
|
||||
pathSpecs: SimSpecSequence<Type> | SimSpecPriorMatch<Type>,
|
||||
pathSpecs: (SimSpecSequence<Type> | SimSpecPriorMatch<Type>)[],
|
||||
specSet: GestureModel<Type>[]
|
||||
};
|
||||
|
||||
|
|
@ -383,7 +383,8 @@ export function simulateSelectorInput<Type>(
|
|||
sources,
|
||||
testObjPromise,
|
||||
executor
|
||||
} = simulateMultiSourceInput(config, [input.pathSpecs], fakeClock);
|
||||
// Minor TS inference problem below (b/c arrays aren't necessarily guaranteed a first entry?)
|
||||
} = simulateMultiSourceInput(config, input.pathSpecs as any, fakeClock);
|
||||
|
||||
return {
|
||||
sources,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue