Spaces:
Paused
Paused
| ; | |
| var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); | |
| Object.defineProperty(exports, "__esModule", { | |
| value: true | |
| }); | |
| exports.toHaveFormValues = toHaveFormValues; | |
| var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); | |
| var _isEqualWith = _interopRequireDefault(require("lodash/isEqualWith")); | |
| var _uniq = _interopRequireDefault(require("lodash/uniq")); | |
| var _css = _interopRequireDefault(require("css.escape")); | |
| var _utils = require("./utils"); | |
| // Returns the combined value of several elements that have the same name | |
| // e.g. radio buttons or groups of checkboxes | |
| function getMultiElementValue(elements) { | |
| const types = (0, _uniq.default)(elements.map(element => element.type)); | |
| if (types.length !== 1) { | |
| throw new Error('Multiple form elements with the same name must be of the same type'); | |
| } | |
| switch (types[0]) { | |
| case 'radio': | |
| { | |
| const theChosenOne = elements.find(radio => radio.checked); | |
| return theChosenOne ? theChosenOne.value : undefined; | |
| } | |
| case 'checkbox': | |
| return elements.filter(checkbox => checkbox.checked).map(checkbox => checkbox.value); | |
| default: | |
| // NOTE: Not even sure this is a valid use case, but just in case... | |
| return elements.map(element => element.value); | |
| } | |
| } | |
| function getFormValue(container, name) { | |
| const elements = [...container.querySelectorAll(`[name="${(0, _css.default)(name)}"]`)]; | |
| /* istanbul ignore if */ | |
| if (elements.length === 0) { | |
| return undefined; // shouldn't happen, but just in case | |
| } | |
| switch (elements.length) { | |
| case 1: | |
| return (0, _utils.getSingleElementValue)(elements[0]); | |
| default: | |
| return getMultiElementValue(elements); | |
| } | |
| } | |
| // Strips the `[]` suffix off a form value name | |
| function getPureName(name) { | |
| return /\[\]$/.test(name) ? name.slice(0, -2) : name; | |
| } | |
| function getAllFormValues(container) { | |
| const names = Array.from(container.elements).map(element => element.name); | |
| return names.reduce((obj, name) => (0, _extends2.default)({}, obj, { | |
| [getPureName(name)]: getFormValue(container, name) | |
| }), {}); | |
| } | |
| function toHaveFormValues(formElement, expectedValues) { | |
| (0, _utils.checkHtmlElement)(formElement, toHaveFormValues, this); | |
| if (!formElement.elements) { | |
| // TODO: Change condition to use instanceof against the appropriate element classes instead | |
| throw new Error('toHaveFormValues must be called on a form or a fieldset'); | |
| } | |
| const formValues = getAllFormValues(formElement); | |
| return { | |
| pass: Object.entries(expectedValues).every(([name, expectedValue]) => (0, _isEqualWith.default)(formValues[name], expectedValue, _utils.compareArraysAsSet)), | |
| message: () => { | |
| const to = this.isNot ? 'not to' : 'to'; | |
| const matcher = `${this.isNot ? '.not' : ''}.toHaveFormValues`; | |
| const commonKeyValues = Object.keys(formValues).filter(key => expectedValues.hasOwnProperty(key)).reduce((obj, key) => (0, _extends2.default)({}, obj, { | |
| [key]: formValues[key] | |
| }), {}); | |
| return [this.utils.matcherHint(matcher, 'element', ''), `Expected the element ${to} have form values`, this.utils.diff(expectedValues, commonKeyValues)].join('\n\n'); | |
| } | |
| }; | |
| } |