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); });