1# Node.js Core Test Common Modules 2 3This directory contains modules used to test the Node.js implementation. 4 5## Table of Contents 6 7* [Benchmark module](#benchmark-module) 8* [Common module API](#common-module-api) 9* [Countdown module](#countdown-module) 10* [DNS module](#dns-module) 11* [Duplex pair helper](#duplex-pair-helper) 12* [Fixtures module](#fixtures-module) 13* [Heap dump checker module](#heap-dump-checker-module) 14* [HTTP2 module](#http2-module) 15* [Internet module](#internet-module) 16* [tick module](#tick-module) 17* [tmpdir module](#tmpdir-module) 18* [WPT module](#wpt-module) 19 20## Benchmark Module 21 22The `benchmark` module is used by tests to run benchmarks. 23 24### runBenchmark(name, args, env) 25 26* `name` [<string>] Name of benchmark suite to be run. 27* `args` [<Array>] Array of environment variable key/value pairs (ex: 28 `n=1`) to be applied via `--set`. 29* `env` [<Object>] Environment variables to be applied during the run. 30 31## Common Module API 32 33The `common` module is used by tests for consistency across repeated 34tasks. 35 36### allowGlobals(...whitelist) 37* `whitelist` [<Array>] Array of Globals 38* return [<Array>] 39 40Takes `whitelist` and concats that with predefined `knownGlobals`. 41 42### busyLoop(time) 43* `time` [<number>] 44 45Blocks for `time` amount of time. 46 47### canCreateSymLink() 48* return [<boolean>] 49 50Checks whether the current running process can create symlinks. On Windows, this 51returns `false` if the process running doesn't have privileges to create 52symlinks 53([SeCreateSymbolicLinkPrivilege](https://msdn.microsoft.com/en-us/library/windows/desktop/bb530716(v=vs.85).aspx)). 54On non-Windows platforms, this always returns `true`. 55 56### createZeroFilledFile(filename) 57 58Creates a 10 MB file of all null characters. 59 60### disableCrashOnUnhandledRejection() 61 62Removes the `process.on('unhandledRejection')` handler that crashes the process 63after a tick. The handler is useful for tests that use Promises and need to make 64sure no unexpected rejections occur, because currently they result in silent 65failures. However, it is useful in some rare cases to disable it, for example if 66the `unhandledRejection` hook is directly used by the test. 67 68### enoughTestMem 69* [<boolean>] 70 71Indicates if there is more than 1gb of total memory. 72 73### expectsError([fn, ]settings[, exact]) 74* `fn` [<Function>] a function that should throw. 75* `settings` [<Object>] 76 that must contain the `code` property plus any of the other following 77 properties (some properties only apply for `AssertionError`): 78 * `code` [<string>] 79 expected error must have this value for its `code` property. 80 * `type` [<Function>] 81 expected error must be an instance of `type` and must be an Error subclass. 82 * `message` [<string>] or [<RegExp>] 83 if a string is provided for `message`, expected error must have it for its 84 `message` property; if a regular expression is provided for `message`, the 85 regular expression must match the `message` property of the expected error. 86 * `name` [<string>] 87 expected error must have this value for its `name` property. 88 * `info` <Object> expected error must have the same `info` property 89 that is deeply equal to this value. 90 * `generatedMessage` [<string>] 91 (`AssertionError` only) expected error must have this value for its 92 `generatedMessage` property. 93 * `actual` <any> 94 (`AssertionError` only) expected error must have this value for its 95 `actual` property. 96 * `expected` <any> 97 (`AssertionError` only) expected error must have this value for its 98 `expected` property. 99 * `operator` <any> 100 (`AssertionError` only) expected error must have this value for its 101 `operator` property. 102* `exact` [<number>] default = 1 103* return [<Function>] 104 105 If `fn` is provided, it will be passed to `assert.throws` as first argument 106 and `undefined` will be returned. 107 Otherwise a function suitable as callback or for use as a validation function 108 passed as the second argument to `assert.throws()` will be returned. If the 109 returned function has not been called exactly `exact` number of times when the 110 test is complete, then the test will fail. 111 112### expectWarning(name, expected, code) 113* `name` [<string>] 114* `expected` [<string>] | [<Array>] 115* `code` [<string>] 116 117Tests whether `name`, `expected`, and `code` are part of a raised warning. If 118an expected warning does not have a code then `common.noWarnCode` can be used 119to indicate this. 120 121### getArrayBufferViews(buf) 122* `buf` [<Buffer>] 123* return [<ArrayBufferView[]>] 124 125Returns an instance of all possible `ArrayBufferView`s of the provided Buffer. 126 127### getBufferSources(buf) 128* `buf` [<Buffer>] 129* return [<BufferSource[]>] 130 131Returns an instance of all possible `BufferSource`s of the provided Buffer, 132consisting of all `ArrayBufferView` and an `ArrayBuffer`. 133 134### getCallSite(func) 135* `func` [<Function>] 136* return [<string>] 137 138Returns the file name and line number for the provided Function. 139 140### getTTYfd() 141 142Attempts to get a valid TTY file descriptor. Returns `-1` if it fails. 143 144The TTY file descriptor is assumed to be capable of being writable. 145 146### hasCrypto 147* [<boolean>] 148 149Indicates whether OpenSSL is available. 150 151### hasFipsCrypto 152* [<boolean>] 153 154Indicates `hasCrypto` and `crypto` with fips. 155 156### hasIntl 157* [<boolean>] 158 159Indicates if [internationalization] is supported. 160 161### hasIPv6 162* [<boolean>] 163 164Indicates whether `IPv6` is supported on this platform. 165 166### hasMultiLocalhost 167* [<boolean>] 168 169Indicates if there are multiple localhosts available. 170 171### inFreeBSDJail 172* [<boolean>] 173 174Checks whether free BSD Jail is true or false. 175 176### isAIX 177* [<boolean>] 178 179Platform check for Advanced Interactive eXecutive (AIX). 180 181### isAlive(pid) 182* `pid` [<number>] 183* return [<boolean>] 184 185Attempts to 'kill' `pid` 186 187### isFreeBSD 188* [<boolean>] 189 190Platform check for Free BSD. 191 192### isLinux 193* [<boolean>] 194 195Platform check for Linux. 196 197### isLinuxPPCBE 198* [<boolean>] 199 200Platform check for Linux on PowerPC. 201 202### isOSX 203* [<boolean>] 204 205Platform check for macOS. 206 207### isSunOS 208* [<boolean>] 209 210Platform check for SunOS. 211 212### isWindows 213* [<boolean>] 214 215Platform check for Windows. 216 217### localhostIPv4 218* [<string>] 219 220IP of `localhost`. 221 222### localIPv6Hosts 223* [<Array>] 224 225Array of IPV6 representations for `localhost`. 226 227### mustCall([fn][, exact]) 228* `fn` [<Function>] default = () => {} 229* `exact` [<number>] default = 1 230* return [<Function>] 231 232Returns a function that calls `fn`. If the returned function has not been called 233exactly `exact` number of times when the test is complete, then the test will 234fail. 235 236If `fn` is not provided, an empty function will be used. 237 238### mustCallAtLeast([fn][, minimum]) 239* `fn` [<Function>] default = () => {} 240* `minimum` [<number>] default = 1 241* return [<Function>] 242 243Returns a function that calls `fn`. If the returned function has not been called 244at least `minimum` number of times when the test is complete, then the test will 245fail. 246 247If `fn` is not provided, an empty function will be used. 248 249### mustNotCall([msg]) 250* `msg` [<string>] default = 'function should not have been called' 251* return [<Function>] 252 253Returns a function that triggers an `AssertionError` if it is invoked. `msg` is 254used as the error message for the `AssertionError`. 255 256### nodeProcessAborted(exitCode, signal) 257* `exitCode` [<number>] 258* `signal` [<string>] 259* return [<boolean>] 260 261Returns `true` if the exit code `exitCode` and/or signal name `signal` represent 262the exit code and/or signal name of a node process that aborted, `false` 263otherwise. 264 265### noWarnCode 266See `common.expectWarning()` for usage. 267 268### opensslCli 269* [<boolean>] 270 271Indicates whether 'opensslCli' is supported. 272 273### platformTimeout(ms) 274* `ms` [<number>] 275* return [<number>] 276 277Platform normalizes timeout. 278 279### PIPE 280* [<string>] 281 282Path to the test socket. 283 284### PORT 285* [<number>] 286 287A port number for tests to use if one is needed. 288 289### printSkipMessage(msg) 290* `msg` [<string>] 291 292Logs '1..0 # Skipped: ' + `msg` 293 294### pwdCommand 295* [<array>] First two argument for the `spawn`/`exec` functions. 296 297Platform normalized `pwd` command options. Usage example: 298```js 299const common = require('../common'); 300const { spawn } = require('child_process'); 301 302spawn(...common.pwdCommand, { stdio: ['pipe'] }); 303``` 304 305### rootDir 306* [<string>] 307 308Path to the 'root' directory. either `/` or `c:\\` (windows) 309 310### runWithInvalidFD(func) 311* `func` [<Function>] 312 313Runs `func` with an invalid file descriptor that is an unsigned integer and 314can be used to trigger `EBADF` as the first argument. If no such file 315descriptor could be generated, a skip message will be printed and the `func` 316will not be run. 317 318### skip(msg) 319* `msg` [<string>] 320 321Logs '1..0 # Skipped: ' + `msg` and exits with exit code `0`. 322 323### skipIfEslintMissing() 324 325Skip the rest of the tests in the current file when `ESLint` is not available 326at `tools/node_modules/eslint` 327 328### skipIfInspectorDisabled() 329 330Skip the rest of the tests in the current file when the Inspector 331was disabled at compile time. 332 333### skipIf32Bits() 334 335Skip the rest of the tests in the current file when the Node.js executable 336was compiled with a pointer size smaller than 64 bits. 337 338### skipIfWorker() 339 340Skip the rest of the tests in the current file when not running on a main 341thread. 342 343## ArrayStream Module 344 345The `ArrayStream` module provides a simple `Stream` that pushes elements from 346a given array. 347 348<!-- eslint-disable no-undef, node-core/required-modules --> 349```js 350const ArrayStream = require('../common/arraystream'); 351const stream = new ArrayStream(); 352stream.run(['a', 'b', 'c']); 353``` 354 355It can be used within tests as a simple mock stream. 356 357## Countdown Module 358 359The `Countdown` module provides a simple countdown mechanism for tests that 360require a particular action to be taken after a given number of completed 361tasks (for instance, shutting down an HTTP server after a specific number of 362requests). The Countdown will fail the test if the remainder did not reach 0. 363 364<!-- eslint-disable strict, node-core/required-modules --> 365```js 366const Countdown = require('../common/countdown'); 367 368function doSomething() { 369 console.log('.'); 370} 371 372const countdown = new Countdown(2, doSomething); 373countdown.dec(); 374countdown.dec(); 375``` 376 377### new Countdown(limit, callback) 378 379* `limit` {number} 380* `callback` {function} 381 382Creates a new `Countdown` instance. 383 384### Countdown.prototype.dec() 385 386Decrements the `Countdown` counter. 387 388### Countdown.prototype.remaining 389 390Specifies the remaining number of times `Countdown.prototype.dec()` must be 391called before the callback is invoked. 392 393## DNS Module 394 395The `DNS` module provides utilities related to the `dns` built-in module. 396 397### errorLookupMock(code, syscall) 398 399* `code` [<string>] Defaults to `dns.mockedErrorCode`. 400* `syscall` [<string>] Defaults to `dns.mockedSysCall`. 401* return [<Function>] 402 403A mock for the `lookup` option of `net.connect()` that would result in an error 404with the `code` and the `syscall` specified. Returns a function that has the 405same signature as `dns.lookup()`. 406 407### mockedErrorCode 408 409The default `code` of errors generated by `errorLookupMock`. 410 411### mockedSysCall 412 413The default `syscall` of errors generated by `errorLookupMock`. 414 415### readDomainFromPacket(buffer, offset) 416 417* `buffer` [<Buffer>] 418* `offset` [<number>] 419* return [<Object>] 420 421Reads the domain string from a packet and returns an object containing the 422number of bytes read and the domain. 423 424### parseDNSPacket(buffer) 425 426* `buffer` [<Buffer>] 427* return [<Object>] 428 429Parses a DNS packet. Returns an object with the values of the various flags of 430the packet depending on the type of packet. 431 432### writeIPv6(ip) 433 434* `ip` [<string>] 435* return [<Buffer>] 436 437Reads an IPv6 String and returns a Buffer containing the parts. 438 439### writeDomainName(domain) 440 441* `domain` [<string>] 442* return [<Buffer>] 443 444Reads a Domain String and returns a Buffer containing the domain. 445 446### writeDNSPacket(parsed) 447 448* `parsed` [<Object>] 449* return [<Buffer>] 450 451Takes in a parsed Object and writes its fields to a DNS packet as a Buffer 452object. 453 454## Duplex pair helper 455 456The `common/duplexpair` module exports a single function `makeDuplexPair`, 457which returns an object `{ clientSide, serverSide }` where each side is a 458`Duplex` stream connected to the other side. 459 460There is no difference between client or server side beyond their names. 461 462## Fixtures Module 463 464The `common/fixtures` module provides convenience methods for working with 465files in the `test/fixtures` directory. 466 467### fixtures.fixturesDir 468 469* [<string>] 470 471The absolute path to the `test/fixtures/` directory. 472 473### fixtures.path(...args) 474 475* `...args` [<string>] 476 477Returns the result of `path.join(fixtures.fixturesDir, ...args)`. 478 479### fixtures.readSync(args[, enc]) 480 481* `args` [<string>] | [<Array>] 482 483Returns the result of 484`fs.readFileSync(path.join(fixtures.fixturesDir, ...args), 'enc')`. 485 486### fixtures.readKey(arg[, enc]) 487 488* `arg` [<string>] 489 490Returns the result of 491`fs.readFileSync(path.join(fixtures.fixturesDir, 'keys', arg), 'enc')`. 492 493## Heap dump checker module 494 495This provides utilities for checking the validity of heap dumps. 496This requires the usage of `--expose-internals`. 497 498### heap.recordState() 499 500Create a heap dump and an embedder graph copy for inspection. 501The returned object has a `validateSnapshotNodes` function similar to the 502one listed below. (`heap.validateSnapshotNodes(...)` is a shortcut for 503`heap.recordState().validateSnapshotNodes(...)`.) 504 505### heap.validateSnapshotNodes(name, expected, options) 506 507* `name` [<string>] Look for this string as the name of heap dump nodes. 508* `expected` [<Array>] A list of objects, possibly with an `children` 509 property that points to expected other adjacent nodes. 510* `options` [<Array>] 511 * `loose` [<boolean>] Do not expect an exact listing of occurrences 512 of nodes with name `name` in `expected`. 513 514Create a heap dump and an embedder graph copy and validate occurrences. 515 516<!-- eslint-disable no-undef, node-core/required-modules --> 517```js 518validateSnapshotNodes('TLSWRAP', [ 519 { 520 children: [ 521 { name: 'enc_out' }, 522 { name: 'enc_in' }, 523 { name: 'TLSWrap' } 524 ] 525 } 526]); 527``` 528 529## hijackstdio Module 530 531The `hijackstdio` module provides utility functions for temporarily redirecting 532`stdout` and `stderr` output. 533 534<!-- eslint-disable no-undef, node-core/required-modules --> 535```js 536const { hijackStdout, restoreStdout } = require('../common/hijackstdio'); 537 538hijackStdout((data) => { 539 /* Do something with data */ 540 restoreStdout(); 541}); 542 543console.log('this is sent to the hijacked listener'); 544``` 545 546### hijackStderr(listener) 547* `listener` [<Function>]: a listener with a single parameter 548 called `data`. 549 550Eavesdrop to `process.stderr.write()` calls. Once `process.stderr.write()` is 551called, `listener` will also be called and the `data` of `write` function will 552be passed to `listener`. What's more, `process.stderr.writeTimes` is a count of 553the number of calls. 554 555### hijackStdout(listener) 556* `listener` [<Function>]: a listener with a single parameter 557 called `data`. 558 559Eavesdrop to `process.stdout.write()` calls. Once `process.stdout.write()` is 560called, `listener` will also be called and the `data` of `write` function will 561be passed to `listener`. What's more, `process.stdout.writeTimes` is a count of 562the number of calls. 563 564### restoreStderr() 565 566Restore the original `process.stderr.write()`. Used to restore `stderr` to its 567original state after calling [`hijackstdio.hijackStdErr()`][]. 568 569### restoreStdout() 570 571Restore the original `process.stdout.write()`. Used to restore `stdout` to its 572original state after calling [`hijackstdio.hijackStdOut()`][]. 573 574 575## HTTP/2 Module 576 577The http2.js module provides a handful of utilities for creating mock HTTP/2 578frames for testing of HTTP/2 endpoints 579 580<!-- eslint-disable no-unused-vars, node-core/required-modules --> 581```js 582const http2 = require('../common/http2'); 583``` 584 585### Class: Frame 586 587The `http2.Frame` is a base class that creates a `Buffer` containing a 588serialized HTTP/2 frame header. 589 590<!-- eslint-disable no-undef, node-core/required-modules --> 591```js 592// length is a 24-bit unsigned integer 593// type is an 8-bit unsigned integer identifying the frame type 594// flags is an 8-bit unsigned integer containing the flag bits 595// id is the 32-bit stream identifier, if any. 596const frame = new http2.Frame(length, type, flags, id); 597 598// Write the frame data to a socket 599socket.write(frame.data); 600``` 601 602The serialized `Buffer` may be retrieved using the `frame.data` property. 603 604### Class: DataFrame extends Frame 605 606The `http2.DataFrame` is a subclass of `http2.Frame` that serializes a `DATA` 607frame. 608 609<!-- eslint-disable no-undef, node-core/required-modules --> 610```js 611// id is the 32-bit stream identifier 612// payload is a Buffer containing the DATA payload 613// padlen is an 8-bit integer giving the number of padding bytes to include 614// final is a boolean indicating whether the End-of-stream flag should be set, 615// defaults to false. 616const frame = new http2.DataFrame(id, payload, padlen, final); 617 618socket.write(frame.data); 619``` 620 621### Class: HeadersFrame 622 623The `http2.HeadersFrame` is a subclass of `http2.Frame` that serializes a 624`HEADERS` frame. 625 626<!-- eslint-disable no-undef, node-core/required-modules --> 627```js 628// id is the 32-bit stream identifier 629// payload is a Buffer containing the HEADERS payload (see either 630// http2.kFakeRequestHeaders or http2.kFakeResponseHeaders). 631// padlen is an 8-bit integer giving the number of padding bytes to include 632// final is a boolean indicating whether the End-of-stream flag should be set, 633// defaults to false. 634const frame = new http2.HeadersFrame(id, payload, padlen, final); 635 636socket.write(frame.data); 637``` 638 639### Class: SettingsFrame 640 641The `http2.SettingsFrame` is a subclass of `http2.Frame` that serializes an 642empty `SETTINGS` frame. 643 644<!-- eslint-disable no-undef, node-core/required-modules --> 645```js 646// ack is a boolean indicating whether or not to set the ACK flag. 647const frame = new http2.SettingsFrame(ack); 648 649socket.write(frame.data); 650``` 651 652### http2.kFakeRequestHeaders 653 654Set to a `Buffer` instance that contains a minimal set of serialized HTTP/2 655request headers to be used as the payload of a `http2.HeadersFrame`. 656 657<!-- eslint-disable no-undef, node-core/required-modules --> 658```js 659const frame = new http2.HeadersFrame(1, http2.kFakeRequestHeaders, 0, true); 660 661socket.write(frame.data); 662``` 663 664### http2.kFakeResponseHeaders 665 666Set to a `Buffer` instance that contains a minimal set of serialized HTTP/2 667response headers to be used as the payload a `http2.HeadersFrame`. 668 669<!-- eslint-disable no-undef, node-core/required-modules --> 670```js 671const frame = new http2.HeadersFrame(1, http2.kFakeResponseHeaders, 0, true); 672 673socket.write(frame.data); 674``` 675 676### http2.kClientMagic 677 678Set to a `Buffer` containing the preamble bytes an HTTP/2 client must send 679upon initial establishment of a connection. 680 681<!-- eslint-disable no-undef, node-core/required-modules --> 682```js 683socket.write(http2.kClientMagic); 684``` 685 686## Internet Module 687 688The `common/internet` module provides utilities for working with 689internet-related tests. 690 691### internet.addresses 692 693* [<Object>] 694 * `INET_HOST` [<string>] A generic host that has registered common 695 DNS records, supports both IPv4 and IPv6, and provides basic HTTP/HTTPS 696 services 697 * `INET4_HOST` [<string>] A host that provides IPv4 services 698 * `INET6_HOST` [<string>] A host that provides IPv6 services 699 * `INET4_IP` [<string>] An accessible IPv4 IP, defaults to the 700 Google Public DNS IPv4 address 701 * `INET6_IP` [<string>] An accessible IPv6 IP, defaults to the 702 Google Public DNS IPv6 address 703 * `INVALID_HOST` [<string>] An invalid host that cannot be resolved 704 * `MX_HOST` [<string>] A host with MX records registered 705 * `SRV_HOST` [<string>] A host with SRV records registered 706 * `PTR_HOST` [<string>] A host with PTR records registered 707 * `NAPTR_HOST` [<string>] A host with NAPTR records registered 708 * `SOA_HOST` [<string>] A host with SOA records registered 709 * `CNAME_HOST` [<string>] A host with CNAME records registered 710 * `NS_HOST` [<string>] A host with NS records registered 711 * `TXT_HOST` [<string>] A host with TXT records registered 712 * `DNS4_SERVER` [<string>] An accessible IPv4 DNS server 713 * `DNS6_SERVER` [<string>] An accessible IPv6 DNS server 714 715A set of addresses for internet-related tests. All properties are configurable 716via `NODE_TEST_*` environment variables. For example, to configure 717`internet.addresses.INET_HOST`, set the environment 718variable `NODE_TEST_INET_HOST` to a specified host. 719 720## ongc Module 721 722The `ongc` module allows a garbage collection listener to be installed. The 723module exports a single `onGC()` function. 724 725```js 726require('../common'); 727const onGC = require('../common/ongc'); 728 729onGC({}, { ongc() { console.log('collected'); } }); 730``` 731 732### onGC(target, listener) 733* `target` [<Object>] 734* `listener` [<Object>] 735 * `ongc` [<Function>] 736 737Installs a GC listener for the collection of `target`. 738 739This uses `async_hooks` for GC tracking. This means that it enables 740`async_hooks` tracking, which may affect the test functionality. It also 741means that between a `global.gc()` call and the listener being invoked 742a full `setImmediate()` invocation passes. 743 744`listener` is an object to make it easier to use a closure; the target object 745should not be in scope when `listener.ongc()` is created. 746 747 748## tick Module 749 750The `tick` module provides a helper function that can be used to call a callback 751after a given number of event loop "ticks". 752 753### tick(x, cb) 754 755* `x` [<number>] Number of event loop "ticks". 756* `cb` [<Function>] A callback function. 757 758## tmpdir Module 759 760The `tmpdir` module supports the use of a temporary directory for testing. 761 762### path 763* [<string>] 764 765The realpath of the testing temporary directory. 766 767### refresh() 768 769Deletes and recreates the testing temporary directory. 770 771## WPT Module 772 773The wpt.js module is a port of parts of 774[W3C testharness.js](https://github.com/w3c/testharness.js) for testing the 775Node.js 776[WHATWG URL API](https://nodejs.org/api/url.html#url_the_whatwg_url_api) 777implementation with tests from 778[W3C Web Platform Tests](https://github.com/w3c/web-platform-tests). 779 780 781[<Array>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array 782[<ArrayBufferView[]>]: https://developer.mozilla.org/en-US/docs/Web/API/ArrayBufferView 783[<Buffer>]: https://nodejs.org/api/buffer.html#buffer_class_buffer 784[<Function>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function 785[<Object>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object 786[<RegExp>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp 787[<boolean>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Boolean_type 788[<number>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_type 789[<string>]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#String_type 790[`hijackstdio.hijackStdErr()`]: #hijackstderrlistener 791[`hijackstdio.hijackStdOut()`]: #hijackstdoutlistener 792[internationalization]: https://github.com/nodejs/node/wiki/Intl 793