@enact/ui
Version:
A collection of simplified unstyled cross-platform UI components for Enact
304 lines (303 loc) • 13.2 kB
JavaScript
;
var _react = require("@testing-library/react");
var _Cancelable = require("../Cancelable");
var _jsxRuntime = require("react/jsx-runtime");
var _excluded = ["children", "className", "onKeyUp"];
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
describe('Cancelable', function () {
// Suite-wide setup
var Component = function Component(_ref) {
var children = _ref.children,
className = _ref.className,
onKeyUp = _ref.onKeyUp,
rest = _objectWithoutProperties(_ref, _excluded);
return /*#__PURE__*/(0, _jsxRuntime.jsx)("div", _objectSpread(_objectSpread({
className: className,
"data-testid": "cancelable",
onKeyUp: onKeyUp
}, rest), {}, {
children: children
}));
};
var makeKeyEvent = function makeKeyEvent(keyCode) {
return {
keyCode: keyCode,
nativeEvent: {
stopImmediatePropagation: jest.fn()
}
};
};
var returnsTrue = function returnsTrue() {
return true;
};
var stop = function stop(ev) {
return ev.stopPropagation();
};
test('should call onCancel with type from prop for escape key', function () {
var handleCancel = jest.fn(returnsTrue);
var Comp = (0, _Cancelable.Cancelable)({
onCancel: 'onCustomEvent'
}, Component);
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {
onCustomEvent: handleCancel
}));
var component = _react.screen.getByTestId('cancelable');
_react.fireEvent.keyUp(component, makeKeyEvent(27));
var expected = 1;
var expectedType = {
type: 'onCustomEvent'
};
var actual = handleCancel.mock.calls.length && handleCancel.mock.calls[0][0];
expect(handleCancel).toHaveBeenCalledTimes(expected);
expect(actual).toMatchObject(expectedType);
});
test('should only call onCancel with type for escape key by default', function () {
var handleCancel = jest.fn(returnsTrue);
var Comp = (0, _Cancelable.Cancelable)({
onCancel: handleCancel
}, Component);
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {}));
var component = _react.screen.getByTestId('cancelable');
_react.fireEvent.keyUp(component, makeKeyEvent(27));
var expected = 1;
var expectedType = {
type: 'onCancel'
};
var actual = handleCancel.mock.calls.length && handleCancel.mock.calls[0][0];
expect(handleCancel).toHaveBeenCalledTimes(expected);
expect(actual).toMatchObject(expectedType);
});
test('should not call onCancel for non-escape key', function () {
var handleCancel = jest.fn(returnsTrue);
var Comp = (0, _Cancelable.Cancelable)({
onCancel: handleCancel
}, Component);
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {}));
var component = _react.screen.getByTestId('cancelable');
_react.fireEvent.keyUp(component, makeKeyEvent(42));
expect(handleCancel).not.toHaveBeenCalled();
});
test('should stop propagation when handled', function () {
var handleCancel = jest.fn(stop);
var handleCancelParent = jest.fn(stop);
var keyEvent = makeKeyEvent(27);
var Comp = (0, _Cancelable.Cancelable)({
onCancel: handleCancel
}, Component);
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
onKeyUp: handleCancelParent,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {})
}));
var component = _react.screen.getByTestId('cancelable');
_react.fireEvent.keyUp(component, keyEvent);
expect(handleCancelParent).not.toHaveBeenCalled();
});
test('should not stop propagation for not handled', function () {
var handleCancel = jest.fn(returnsTrue);
var handleCancelParent = jest.fn(returnsTrue);
var keyEvent = makeKeyEvent(42);
var Comp = (0, _Cancelable.Cancelable)({
onCancel: handleCancel
}, Component);
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
onKeyUp: handleCancelParent,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {})
}));
var component = _react.screen.getByTestId('cancelable');
_react.fireEvent.keyUp(component, keyEvent);
var expected = 1;
expect(handleCancelParent).toHaveBeenCalledTimes(expected);
});
test('should forward to onKeyUp handler for any key', function () {
var handleKeyUp = jest.fn();
var keyEvent = makeKeyEvent(42);
var Comp = (0, _Cancelable.Cancelable)({
onCancel: returnsTrue
}, Component);
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {
onKeyUp: handleKeyUp
}));
var component = _react.screen.getByTestId('cancelable');
_react.fireEvent.keyUp(component, keyEvent);
var expected = 1;
expect(handleKeyUp).toHaveBeenCalledTimes(expected);
});
test('should call onCancel when additional cancel handlers pass', function () {
var customCancelHandler = function customCancelHandler(ev) {
return ev.keyCode === 461;
};
(0, _Cancelable.addCancelHandler)(customCancelHandler);
var handleCancel = jest.fn(returnsTrue);
var Comp = (0, _Cancelable.Cancelable)({
onCancel: handleCancel
}, Component);
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {}));
var component = _react.screen.getByTestId('cancelable');
_react.fireEvent.keyUp(component, makeKeyEvent(461));
(0, _Cancelable.removeCancelHandler)(customCancelHandler);
var expected = 1;
expect(handleCancel).toHaveBeenCalledTimes(expected);
});
test('should bubble up the component tree when config handler does not call stopPropagation', function () {
var handleCancel = jest.fn(returnsTrue);
var Comp = (0, _Cancelable.Cancelable)({
onCancel: handleCancel
}, Component);
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {
"data-testid": "second",
className: "second"
})
}));
var secondComponent = _react.screen.getByTestId('second');
_react.fireEvent.keyUp(secondComponent, makeKeyEvent(27));
var expected = 2;
expect(handleCancel).toHaveBeenCalledTimes(expected);
});
test('should not bubble up the component tree when config handler calls stopPropagation', function () {
var handleCancel = jest.fn(stop);
var Comp = (0, _Cancelable.Cancelable)({
onCancel: handleCancel
}, Component);
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {
"data-testid": "second",
className: "second"
})
}));
var secondComponent = _react.screen.getByTestId('second');
_react.fireEvent.keyUp(secondComponent, makeKeyEvent(27));
var expected = 1;
expect(handleCancel).toHaveBeenCalledTimes(expected);
});
test('should bubble up the component tree when prop handler does not call stopPropagation', function () {
var handleCancel = jest.fn();
var Comp = (0, _Cancelable.Cancelable)({
onCancel: 'onCustomEvent'
}, Component);
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {
onCustomEvent: handleCancel,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {
"data-testid": "second",
className: "second",
onCustomEvent: returnsTrue
})
}));
var secondComponent = _react.screen.getByTestId('second');
_react.fireEvent.keyUp(secondComponent, makeKeyEvent(27));
var expected = 1;
expect(handleCancel).toHaveBeenCalledTimes(expected);
});
test('should not bubble up the component tree when prop handler calls stopPropagation', function () {
var handleCancel = jest.fn();
var Comp = (0, _Cancelable.Cancelable)({
onCancel: 'onCustomEvent'
}, Component);
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {
onCustomEvent: handleCancel,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {
"data-testid": "second",
className: "second",
onCustomEvent: stop
})
}));
var secondComponent = _react.screen.getByTestId('second');
_react.fireEvent.keyUp(secondComponent, makeKeyEvent(27));
expect(handleCancel).not.toHaveBeenCalled();
});
describe('modal instances', function () {
var customEventHandler = function customEventHandler(ev) {
return ev.keyIdentifier === '27';
};
var makeKeyboardEvent = function makeKeyboardEvent(keyCode) {
return new window.KeyboardEvent('keyup', {
keyCode: keyCode,
code: keyCode,
bubbles: true
});
};
beforeAll(function () {
(0, _Cancelable.addCancelHandler)(customEventHandler);
});
afterAll(function () {
(0, _Cancelable.removeCancelHandler)(customEventHandler);
});
test('should invoke handler for cancel events dispatch to the window', function () {
var handleCancel = jest.fn(returnsTrue);
var Comp = (0, _Cancelable.Cancelable)({
modal: true,
onCancel: handleCancel
}, Component);
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(Comp, {}));
document.dispatchEvent(makeKeyboardEvent(27));
var expected = 1;
expect(handleCancel).toHaveBeenCalledTimes(expected);
});
test('should invoke modal handlers in LIFO order', function () {
var results = [];
var append = function append(str) {
return function () {
results.push(str);
return false;
};
};
var First = (0, _Cancelable.Cancelable)({
modal: true,
onCancel: append('first')
}, Component);
var Second = (0, _Cancelable.Cancelable)({
modal: true,
onCancel: append('second')
}, Component);
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(First, {}));
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(Second, {}));
document.dispatchEvent(makeKeyboardEvent(27));
var expected = ['second', 'first'];
expect(results).toEqual(expected);
});
test('should invoke nested modal handlers in LIFO order', function () {
var results = [];
var append = function append(str) {
return function () {
results.push(str);
return false;
};
};
var First = (0, _Cancelable.Cancelable)({
modal: true,
onCancel: append('first')
}, Component);
var Second = (0, _Cancelable.Cancelable)({
modal: true,
onCancel: append('second')
}, Component);
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(First, {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(Second, {})
}));
document.dispatchEvent(makeKeyboardEvent(27));
var expected = ['second', 'first'];
expect(results).toEqual(expected);
});
test('should not invoke modal handlers after one calls stopPropagation', function () {
var handleCancel = jest.fn(returnsTrue);
var First = (0, _Cancelable.Cancelable)({
modal: true,
onCancel: handleCancel
}, Component);
var Second = (0, _Cancelable.Cancelable)({
modal: true,
onCancel: stop
}, Component);
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(First, {}));
(0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(Second, {}));
document.dispatchEvent(makeKeyboardEvent(27));
expect(handleCancel).not.toHaveBeenCalled();
});
});
});