From 38aec143819ea825d42e6573cae6b0f565ae149e Mon Sep 17 00:00:00 2001 From: Osipov Vladimir Date: Mon, 8 Jan 2018 18:54:12 +0300 Subject: [PATCH] Pretty format for DOMStringMap and NamedNodeMap (#5246) --- CHANGELOG.md | 2 + packages/jest-diff/src/index.js | 2 + packages/jest-matcher-utils/src/index.js | 2 + packages/jest-snapshot/src/plugins.js | 2 + .../src/__tests__/dom_collection.test.js | 37 +++++++++++ packages/pretty-format/src/index.js | 2 + .../src/plugins/dom_collection.js | 65 +++++++++++++++++++ 7 files changed, 112 insertions(+) create mode 100644 packages/pretty-format/src/__tests__/dom_collection.test.js create mode 100644 packages/pretty-format/src/plugins/dom_collection.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d20bd7f4391..8edb37f3cea9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ ([#5230](https://github.com/facebook/jest/pull/5230)) * `[expect]` Do not override `Error` stack (with `Error.captureStackTrace`) for custom matchers. ([#5162](https://github.com/facebook/jest/pull/5162)) +* `[pretty-format]` Pretty format for DOMStringMap and NamedNodeMap + ([#5233](https://github.com/facebook/jest/pull/5233)) ### Features diff --git a/packages/jest-diff/src/index.js b/packages/jest-diff/src/index.js index e21a1784e76d..58024d26a4a4 100644 --- a/packages/jest-diff/src/index.js +++ b/packages/jest-diff/src/index.js @@ -17,6 +17,7 @@ import {NO_DIFF_MESSAGE, SIMILAR_MESSAGE} from './constants'; const { AsymmetricMatcher, + DOMCollection, DOMElement, Immutable, ReactElement, @@ -27,6 +28,7 @@ const PLUGINS = [ ReactTestComponent, ReactElement, DOMElement, + DOMCollection, Immutable, AsymmetricMatcher, ]; diff --git a/packages/jest-matcher-utils/src/index.js b/packages/jest-matcher-utils/src/index.js index 89f2442880e5..8fec77bea145 100644 --- a/packages/jest-matcher-utils/src/index.js +++ b/packages/jest-matcher-utils/src/index.js @@ -12,6 +12,7 @@ import getType from 'jest-get-type'; import prettyFormat from 'pretty-format'; const { AsymmetricMatcher, + DOMCollection, DOMElement, Immutable, ReactElement, @@ -22,6 +23,7 @@ const PLUGINS = [ ReactTestComponent, ReactElement, DOMElement, + DOMCollection, Immutable, AsymmetricMatcher, ]; diff --git a/packages/jest-snapshot/src/plugins.js b/packages/jest-snapshot/src/plugins.js index 72798154bb56..b561f7eb88b6 100644 --- a/packages/jest-snapshot/src/plugins.js +++ b/packages/jest-snapshot/src/plugins.js @@ -13,6 +13,7 @@ import prettyFormat from 'pretty-format'; import jestMockSerializer from './mock_serializer'; const { + DOMCollection, DOMElement, Immutable, ReactElement, @@ -23,6 +24,7 @@ let PLUGINS = [ ReactTestComponent, ReactElement, DOMElement, + DOMCollection, Immutable, jestMockSerializer, ]; diff --git a/packages/pretty-format/src/__tests__/dom_collection.test.js b/packages/pretty-format/src/__tests__/dom_collection.test.js new file mode 100644 index 000000000000..38128a3ff8c6 --- /dev/null +++ b/packages/pretty-format/src/__tests__/dom_collection.test.js @@ -0,0 +1,37 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @jest-environment jsdom + * @flow + */ +/* eslint-env browser*/ + +'use strict'; + +const prettyFormat = require('../'); +const {DOMCollection} = prettyFormat.plugins; +const toPrettyPrintTo = require('./expect_util').getPrettyPrint([ + DOMCollection, +]); + +const expect: any = global.expect; +expect.extend({toPrettyPrintTo}); + +describe('DOMCollection Plugin', () => { + it('supports a DOMStringMap', () => { + const el = document.createElement('div'); + el.dataset.foo = 'bar'; + + expect(el.dataset).toPrettyPrintTo('DOMStringMap {\n "foo": "bar",\n}'); + }); + + it('supports a NamedNodeMap', () => { + const el = document.createElement('div'); + el.setAttribute('foo', 'bar'); + + expect(el.attributes).toPrettyPrintTo('NamedNodeMap {\n "foo": "bar",\n}'); + }); +}); diff --git a/packages/pretty-format/src/index.js b/packages/pretty-format/src/index.js index a4b828e34204..a844c2108682 100644 --- a/packages/pretty-format/src/index.js +++ b/packages/pretty-format/src/index.js @@ -30,6 +30,7 @@ import { import AsymmetricMatcher from './plugins/asymmetric_matcher'; import ConvertAnsi from './plugins/convert_ansi'; +import DOMCollection from './plugins/dom_collection'; import DOMElement from './plugins/dom_element'; import Immutable from './plugins/immutable'; import ReactElement from './plugins/react_element'; @@ -489,6 +490,7 @@ function prettyFormat(val: any, options?: OptionsReceived): string { prettyFormat.plugins = { AsymmetricMatcher, ConvertAnsi, + DOMCollection, DOMElement, Immutable, ReactElement, diff --git a/packages/pretty-format/src/plugins/dom_collection.js b/packages/pretty-format/src/plugins/dom_collection.js new file mode 100644 index 000000000000..5af357b05af5 --- /dev/null +++ b/packages/pretty-format/src/plugins/dom_collection.js @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2014-present, Facebook, Inc. All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +import type {Config, NewPlugin, Printer, Refs} from 'types/PrettyFormat'; + +import {printObjectProperties} from '../collections'; + +const SPACE = ' '; + +const COLLECTION_NAMES = ['DOMStringMap', 'NamedNodeMap']; + +export const test = (val: any) => + val && + val.constructor && + COLLECTION_NAMES.indexOf(val.constructor.name) !== -1; + +const convertCollectionToObject = (collection: any) => { + let result = {}; + + if (collection.constructor.name === 'NamedNodeMap') { + for (let i = 0; i < collection.length; i++) { + result[collection[i].name] = collection[i].value; + } + } else { + result = Object.assign({}, collection); + } + + return result; +}; + +export const serialize = ( + collection: any, + config: Config, + indentation: string, + depth: number, + refs: Refs, + printer: Printer, +): string => { + if (++depth > config.maxDepth) { + return '[' + collection.constructor.name + ']'; + } + + return ( + collection.constructor.name + + SPACE + + '{' + + printObjectProperties( + convertCollectionToObject(collection), + config, + indentation, + depth, + refs, + printer, + ) + + '}' + ); +}; + +export default ({serialize, test}: NewPlugin);