import { Assertions, Chain, GeneralSteps, Logger, NamedChain, Pipeline, Step, UiFinder } from '@ephox/agar';
import { UnitTest } from '@ephox/bedrock-client';
import { Arr, Fun, Result } from '@ephox/katamari';
import { Attribute, Compare, Html, Insert, Remove, SelectorFilter, SugarElement, Truncate } from '@ephox/sugar';
import * as DescribedHandler from 'ephox/alloy/events/DescribedHandler';
import { type ElementAndHandler, EventRegistry } from 'ephox/alloy/events/EventRegistry';
import * as Tagger from 'ephox/alloy/registry/Tagger';
interface ExpectedType {
readonly id?: string;
readonly handler: string;
readonly target?: string;
readonly purpose?: string;
}
UnitTest.asynctest('EventRegistryTest', (success, failure) => {
const body = SugarElement.fromDom(document.body);
const page = SugarElement.fromTag('div');
Html.set(page,
'
'
);
// Add alloy UID tags to match these attributes.
const pageBits = SelectorFilter.descendants(page, '[data-test-uid]');
Arr.each(pageBits, (bit) => {
Attribute.getOpt(bit, 'data-test-uid').each((testUid) => Tagger.writeOnly(bit, testUid));
});
const isRoot = Fun.curry(Compare.eq, page);
Insert.append(body, page);
const teardown = () => {
Remove.remove(page);
};
const events = EventRegistry();
events.registerId([ 'extra-args' ], 'comp-1', {
'event.alpha': DescribedHandler.uncurried(
(extra: string) => 'event.alpha.1(' + extra + ')',
'event.alpha.1.handler'
),
'event.only': DescribedHandler.uncurried(
(extra: string) => 'event.only(' + extra + ')',
'event.only.handler'
)
});
events.registerId([ 'extra-args' ], 'comp-4', {
'event.alpha': DescribedHandler.uncurried(
(extra: string) => 'event.alpha.4(' + extra + ')',
'event.alpha.4.handler'
)
});
const sAssertFilterByType = (expected: ExpectedType[], type: string) => Step.sync(() => {
const filtered = events.filterByType(type);
const raw = Arr.map(filtered, (f) => ({
// Invoke the handler
handler: f.descHandler.cHandler(),
purpose: f.descHandler.purpose,
id: f.id
})).sort((f, g) => {
if (f.id < g.id) {
return -1;
} else if (f.id > g.id) {
return +1;
} else {
return 0;
}
});
Assertions.assertEq(() => 'filter(' + type + ') = ' + JSON.stringify(expected), expected, raw);
});
const sAssertNotFound = (label: string, type: string, id: string) => Logger.t(
'Test: ' + label + '\nLooking for handlers for id = ' + id + ' and event = ' + type + '. Should not find any',
GeneralSteps.sequence([
Chain.asStep(page, [
UiFinder.cFindIn('[data-test-uid="' + id + '"]'),
Chain.binder((target) => {
const handler = events.find(isRoot, type, target);
return handler.fold(() => Result.value({ }), (h) => Result.error(
'Unexpected handler found: ' + JSON.stringify({
element: Truncate.getHtml(h.element),
// INVESTIGATE: Should this have changed?
handler: h.descHandler
})
));
})
])
])
);
const sAssertFind = (label: string, expected: ExpectedType, type: string, id: string) => {
const cFindHandler = Chain.binder((target: SugarElement) => events.find(isRoot, type, target).fold(
() => Result.error('No event handler for ' + type + ' on ' + target.dom),
Result.value
));
return Logger.t(
'Test: ' + label + '\nLooking for handlers for id = ' + id + ' and event = ' + type,
GeneralSteps.sequence([
Chain.asStep({}, [
NamedChain.asChain([
NamedChain.writeValue('page', page),
NamedChain.direct('page', UiFinder.cFindIn('[data-test-uid="' + id + '"]'), 'target'),
NamedChain.direct('target', cFindHandler, 'handler'),
NamedChain.bundle(Result.value)
]),
Chain.op((actual) => {
const section: ElementAndHandler = actual.handler;
Assertions.assertEq(
'find(' + type + ', ' + id + ') = true',
expected.target,
Attribute.get(section.element as SugarElement, 'data-test-uid')
);
Assertions.assertEq(
() => 'find(' + type + ', ' + id + ') = ' + JSON.stringify(expected.handler),
expected.handler,
section.descHandler.cHandler()
);
})
])
])
);
};
Pipeline.async({}, [
sAssertFilterByType([ ], 'event.none'),
sAssertFilterByType([
{ handler: 'event.alpha.1(extra-args)', id: 'comp-1', purpose: 'event.alpha.1.handler' },
{ handler: 'event.alpha.4(extra-args)', id: 'comp-4', purpose: 'event.alpha.4.handler' }
], 'event.alpha'),
sAssertFind('comp-1!',
{ handler: 'event.alpha.1(extra-args)', target: 'comp-1', purpose: 'event.alpha.1.handler' },
'event.alpha', 'comp-1'
),
sAssertFind('comp-2 > comp-1', { handler: 'event.alpha.1(extra-args)', target: 'comp-1' }, 'event.alpha', 'comp-2'),
sAssertFind('comp-3 > comp-2 > comp-1', { handler: 'event.alpha.1(extra-args)', target: 'comp-1' }, 'event.alpha', 'comp-3'),
sAssertFind('comp-4!', { handler: 'event.alpha.4(extra-args)', target: 'comp-4' }, 'event.alpha', 'comp-4'),
sAssertFind('comp-5 > comp-4!', { handler: 'event.alpha.4(extra-args)', target: 'comp-4' }, 'event.alpha', 'comp-5'),
sAssertNotFound('comp-5 > comp-4 > comp-3 > comp-2 > comp-1 > NOT FOUND', 'event.beta', 'comp-5'),
sAssertFind(
'comp-5 > comp-4 > comp-3 > comp-2 > comp-1!',
{ handler: 'event.only(extra-args)', target: 'comp-1' },
'event.only', 'comp-5'
)
], () => {
teardown();
success();
}, failure);
});