.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / pretty-format / README.md
1 # pretty-format
2
3 > Stringify any JavaScript value.
4
5 - Supports all built-in JavaScript types
6   - primitive types: `Boolean`, `null`, `Number`, `String`, `Symbol`, `undefined`
7   - other non-collection types: `Date`, `Error`, `Function`, `RegExp`
8   - collection types:
9     - `arguments`, `Array`, `ArrayBuffer`, `DataView`, `Float32Array`, `Float64Array`, `Int8Array`, `Int16Array`, `Int32Array`, `Uint8Array`, `Uint8ClampedArray`, `Uint16Array`, `Uint32Array`,
10     - `Map`, `Set`, `WeakMap`, `WeakSet`
11     - `Object`
12 - [Blazingly fast](https://gist.github.com/thejameskyle/2b04ffe4941aafa8f970de077843a8fd)
13   - similar performance to `JSON.stringify` in v8
14   - significantly faster than `util.format` in Node.js
15 - Serialize application-specific data types with built-in or user-defined plugins
16
17 ## Installation
18
19 ```sh
20 $ yarn add pretty-format
21 ```
22
23 ## Usage
24
25 ```js
26 const prettyFormat = require('pretty-format'); // CommonJS
27 ```
28
29 ```js
30 import prettyFormat from 'pretty-format'; // ES2015 modules
31 ```
32
33 ```js
34 const val = {object: {}};
35 val.circularReference = val;
36 val[Symbol('foo')] = 'foo';
37 val.map = new Map([['prop', 'value']]);
38 val.array = [-0, Infinity, NaN];
39
40 console.log(prettyFormat(val));
41 /*
42 Object {
43   "array": Array [
44     -0,
45     Infinity,
46     NaN,
47   ],
48   "circularReference": [Circular],
49   "map": Map {
50     "prop" => "value",
51   },
52   "object": Object {},
53   Symbol(foo): "foo",
54 }
55 */
56 ```
57
58 ## Usage with options
59
60 ```js
61 function onClick() {}
62
63 console.log(prettyFormat(onClick));
64 /*
65 [Function onClick]
66 */
67
68 const options = {
69   printFunctionName: false,
70 };
71 console.log(prettyFormat(onClick, options));
72 /*
73 [Function]
74 */
75 ```
76
77 | key                 | type      | default    | description                                             |
78 | :------------------ | :-------- | :--------- | :------------------------------------------------------ |
79 | `callToJSON`        | `boolean` | `true`     | call `toJSON` method (if it exists) on objects          |
80 | `escapeRegex`       | `boolean` | `false`    | escape special characters in regular expressions        |
81 | `highlight`         | `boolean` | `false`    | highlight syntax with colors in terminal (some plugins) |
82 | `indent`            | `number`  | `2`        | spaces in each level of indentation                     |
83 | `maxDepth`          | `number`  | `Infinity` | levels to print in arrays, objects, elements, and so on |
84 | `min`               | `boolean` | `false`    | minimize added space: no indentation nor line breaks    |
85 | `plugins`           | `array`   | `[]`       | plugins to serialize application-specific data types    |
86 | `printFunctionName` | `boolean` | `true`     | include or omit the name of a function                  |
87 | `theme`             | `object`  |            | colors to highlight syntax in terminal                  |
88
89 Property values of `theme` are from [ansi-styles colors](https://github.com/chalk/ansi-styles#colors)
90
91 ```js
92 const DEFAULT_THEME = {
93   comment: 'gray',
94   content: 'reset',
95   prop: 'yellow',
96   tag: 'cyan',
97   value: 'green',
98 };
99 ```
100
101 ## Usage with plugins
102
103 The `pretty-format` package provides some built-in plugins, including:
104
105 - `ReactElement` for elements from `react`
106 - `ReactTestComponent` for test objects from `react-test-renderer`
107
108 ```js
109 // CommonJS
110 const prettyFormat = require('pretty-format');
111 const ReactElement = prettyFormat.plugins.ReactElement;
112 const ReactTestComponent = prettyFormat.plugins.ReactTestComponent;
113
114 const React = require('react');
115 const renderer = require('react-test-renderer');
116 ```
117
118 ```js
119 // ES2015 modules and destructuring assignment
120 import prettyFormat from 'pretty-format';
121 const {ReactElement, ReactTestComponent} = prettyFormat.plugins;
122
123 import React from 'react';
124 import renderer from 'react-test-renderer';
125 ```
126
127 ```js
128 const onClick = () => {};
129 const element = React.createElement('button', {onClick}, 'Hello World');
130
131 const formatted1 = prettyFormat(element, {
132   plugins: [ReactElement],
133   printFunctionName: false,
134 });
135 const formatted2 = prettyFormat(renderer.create(element).toJSON(), {
136   plugins: [ReactTestComponent],
137   printFunctionName: false,
138 });
139 /*
140 <button
141   onClick=[Function]
142 >
143   Hello World
144 </button>
145 */
146 ```
147
148 ## Usage in Jest
149
150 For snapshot tests, Jest uses `pretty-format` with options that include some of its built-in plugins. For this purpose, plugins are also known as **snapshot serializers**.
151
152 To serialize application-specific data types, you can add modules to `devDependencies` of a project, and then:
153
154 In an **individual** test file, you can add a module as follows. It precedes any modules from Jest configuration.
155
156 ```js
157 import serializer from 'my-serializer-module';
158 expect.addSnapshotSerializer(serializer);
159
160 // tests which have `expect(value).toMatchSnapshot()` assertions
161 ```
162
163 For **all** test files, you can specify modules in Jest configuration. They precede built-in plugins for React, HTML, and Immutable.js data types. For example, in a `package.json` file:
164
165 ```json
166 {
167   "jest": {
168     "snapshotSerializers": ["my-serializer-module"]
169   }
170 }
171 ```
172
173 ## Writing plugins
174
175 A plugin is a JavaScript object.
176
177 If `options` has a `plugins` array: for the first plugin whose `test(val)` method returns a truthy value, then `prettyFormat(val, options)` returns the result from either:
178
179 - `serialize(val, …)` method of the **improved** interface (available in **version 21** or later)
180 - `print(val, …)` method of the **original** interface (if plugin does not have `serialize` method)
181
182 ### test
183
184 Write `test` so it can receive `val` argument of any type. To serialize **objects** which have certain properties, then a guarded expression like `val != null && …` or more concise `val && …` prevents the following errors:
185
186 - `TypeError: Cannot read property 'whatever' of null`
187 - `TypeError: Cannot read property 'whatever' of undefined`
188
189 For example, `test` method of built-in `ReactElement` plugin:
190
191 ```js
192 const elementSymbol = Symbol.for('react.element');
193 const test = val => val && val.$$typeof === elementSymbol;
194 ```
195
196 Pay attention to efficiency in `test` because `pretty-format` calls it often.
197
198 ### serialize
199
200 The **improved** interface is available in **version 21** or later.
201
202 Write `serialize` to return a string, given the arguments:
203
204 - `val` which “passed the test”
205 - unchanging `config` object: derived from `options`
206 - current `indentation` string: concatenate to `indent` from `config`
207 - current `depth` number: compare to `maxDepth` from `config`
208 - current `refs` array: find circular references in objects
209 - `printer` callback function: serialize children
210
211 ### config
212
213 | key                 | type      | description                                             |
214 | :------------------ | :-------- | :------------------------------------------------------ |
215 | `callToJSON`        | `boolean` | call `toJSON` method (if it exists) on objects          |
216 | `colors`            | `Object`  | escape codes for colors to highlight syntax             |
217 | `escapeRegex`       | `boolean` | escape special characters in regular expressions        |
218 | `indent`            | `string`  | spaces in each level of indentation                     |
219 | `maxDepth`          | `number`  | levels to print in arrays, objects, elements, and so on |
220 | `min`               | `boolean` | minimize added space: no indentation nor line breaks    |
221 | `plugins`           | `array`   | plugins to serialize application-specific data types    |
222 | `printFunctionName` | `boolean` | include or omit the name of a function                  |
223 | `spacingInner`      | `strong`  | spacing to separate items in a list                     |
224 | `spacingOuter`      | `strong`  | spacing to enclose a list of items                      |
225
226 Each property of `colors` in `config` corresponds to a property of `theme` in `options`:
227
228 - the key is the same (for example, `tag`)
229 - the value in `colors` is a object with `open` and `close` properties whose values are escape codes from [ansi-styles](https://github.com/chalk/ansi-styles) for the color value in `theme` (for example, `'cyan'`)
230
231 Some properties in `config` are derived from `min` in `options`:
232
233 - `spacingInner` and `spacingOuter` are **newline** if `min` is `false`
234 - `spacingInner` is **space** and `spacingOuter` is **empty string** if `min` is `true`
235
236 ### Example of serialize and test
237
238 This plugin is a pattern you can apply to serialize composite data types. Of course, `pretty-format` does not need a plugin to serialize arrays :)
239
240 ```js
241 // We reused more code when we factored out a function for child items
242 // that is independent of depth, name, and enclosing punctuation (see below).
243 const SEPARATOR = ',';
244 function serializeItems(items, config, indentation, depth, refs, printer) {
245   if (items.length === 0) {
246     return '';
247   }
248   const indentationItems = indentation + config.indent;
249   return (
250     config.spacingOuter +
251     items
252       .map(
253         item =>
254           indentationItems +
255           printer(item, config, indentationItems, depth, refs), // callback
256       )
257       .join(SEPARATOR + config.spacingInner) +
258     (config.min ? '' : SEPARATOR) + // following the last item
259     config.spacingOuter +
260     indentation
261   );
262 }
263
264 const plugin = {
265   test(val) {
266     return Array.isArray(val);
267   },
268   serialize(array, config, indentation, depth, refs, printer) {
269     const name = array.constructor.name;
270     return ++depth > config.maxDepth
271       ? '[' + name + ']'
272       : (config.min ? '' : name + ' ') +
273           '[' +
274           serializeItems(array, config, indentation, depth, refs, printer) +
275           ']';
276   },
277 };
278 ```
279
280 ```js
281 const val = {
282   filter: 'completed',
283   items: [
284     {
285       text: 'Write test',
286       completed: true,
287     },
288     {
289       text: 'Write serialize',
290       completed: true,
291     },
292   ],
293 };
294 ```
295
296 ```js
297 console.log(
298   prettyFormat(val, {
299     plugins: [plugin],
300   }),
301 );
302 /*
303 Object {
304   "filter": "completed",
305   "items": Array [
306     Object {
307       "completed": true,
308       "text": "Write test",
309     },
310     Object {
311       "completed": true,
312       "text": "Write serialize",
313     },
314   ],
315 }
316 */
317 ```
318
319 ```js
320 console.log(
321   prettyFormat(val, {
322     indent: 4,
323     plugins: [plugin],
324   }),
325 );
326 /*
327 Object {
328     "filter": "completed",
329     "items": Array [
330         Object {
331             "completed": true,
332             "text": "Write test",
333         },
334         Object {
335             "completed": true,
336             "text": "Write serialize",
337         },
338     ],
339 }
340 */
341 ```
342
343 ```js
344 console.log(
345   prettyFormat(val, {
346     maxDepth: 1,
347     plugins: [plugin],
348   }),
349 );
350 /*
351 Object {
352   "filter": "completed",
353   "items": [Array],
354 }
355 */
356 ```
357
358 ```js
359 console.log(
360   prettyFormat(val, {
361     min: true,
362     plugins: [plugin],
363   }),
364 );
365 /*
366 {"filter": "completed", "items": [{"completed": true, "text": "Write test"}, {"completed": true, "text": "Write serialize"}]}
367 */
368 ```
369
370 ### print
371
372 The **original** interface is adequate for plugins:
373
374 - that **do not** depend on options other than `highlight` or `min`
375 - that **do not** depend on `depth` or `refs` in recursive traversal, and
376 - if values either
377   - do **not** require indentation, or
378   - do **not** occur as children of JavaScript data structures (for example, array)
379
380 Write `print` to return a string, given the arguments:
381
382 - `val` which “passed the test”
383 - current `printer(valChild)` callback function: serialize children
384 - current `indenter(lines)` callback function: indent lines at the next level
385 - unchanging `config` object: derived from `options`
386 - unchanging `colors` object: derived from `options`
387
388 The 3 properties of `config` are `min` in `options` and:
389
390 - `spacing` and `edgeSpacing` are **newline** if `min` is `false`
391 - `spacing` is **space** and `edgeSpacing` is **empty string** if `min` is `true`
392
393 Each property of `colors` corresponds to a property of `theme` in `options`:
394
395 - the key is the same (for example, `tag`)
396 - the value in `colors` is a object with `open` and `close` properties whose values are escape codes from [ansi-styles](https://github.com/chalk/ansi-styles) for the color value in `theme` (for example, `'cyan'`)
397
398 ### Example of print and test
399
400 This plugin prints functions with the **number of named arguments** excluding rest argument.
401
402 ```js
403 const plugin = {
404   print(val) {
405     return `[Function ${val.name || 'anonymous'} ${val.length}]`;
406   },
407   test(val) {
408     return typeof val === 'function';
409   },
410 };
411 ```
412
413 ```js
414 const val = {
415   onClick(event) {},
416   render() {},
417 };
418
419 prettyFormat(val, {
420   plugins: [plugin],
421 });
422 /*
423 Object {
424   "onClick": [Function onClick 1],
425   "render": [Function render 0],
426 }
427 */
428
429 prettyFormat(val);
430 /*
431 Object {
432   "onClick": [Function onClick],
433   "render": [Function render],
434 }
435 */
436 ```
437
438 This plugin **ignores** the `printFunctionName` option. That limitation of the original `print` interface is a reason to use the improved `serialize` interface, described above.
439
440 ```js
441 prettyFormat(val, {
442   plugins: [pluginOld],
443   printFunctionName: false,
444 });
445 /*
446 Object {
447   "onClick": [Function onClick 1],
448   "render": [Function render 0],
449 }
450 */
451
452 prettyFormat(val, {
453   printFunctionName: false,
454 });
455 /*
456 Object {
457   "onClick": [Function],
458   "render": [Function],
459 }
460 */
461 ```