GeezerVison is showing github.com — test: increase coverage of `Module.register` and `initialize` hook · nodejs/node@ced25a9
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: test/es-module/test-esm-loader-hooks.mjs +157-89Lines changed: 157 additions & 89 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -451,28 +451,29 @@ describe('Loader hooks', { concurrency: true }, () => { | 451 | 451 | assert.strictEqual(signal, null); | 452 | 452 | }); | 453 | 453 |
| 454 | | - it('should invoke `initialize` correctly', async () => { | 455 | | - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | 456 | | - '--no-warnings', | 457 | | - '--experimental-loader', | 458 | | - fixtures.fileURL('es-module-loaders/hooks-initialize.mjs'), | 459 | | - '--input-type=module', | 460 | | - '--eval', | 461 | | - 'import os from "node:os";', | 462 | | - ]); | | 454 | + describe('`initialize`/`register`', () => { | | 455 | + it('should invoke `initialize` correctly', async () => { | | 456 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 457 | + '--no-warnings', | | 458 | + '--experimental-loader', | | 459 | + fixtures.fileURL('es-module-loaders/hooks-initialize.mjs'), | | 460 | + '--input-type=module', | | 461 | + '--eval', | | 462 | + 'import os from "node:os";', | | 463 | + ]); | 463 | 464 |
| 464 | | - assert.strictEqual(stderr, ''); | 465 | | - assert.deepStrictEqual(stdout.split('\n'), ['hooks initialize 1', '']); | 466 | | - assert.strictEqual(code, 0); | 467 | | - assert.strictEqual(signal, null); | 468 | | - }); | | 465 | + assert.strictEqual(stderr, ''); | | 466 | + assert.deepStrictEqual(stdout.split('\n'), ['hooks initialize 1', '']); | | 467 | + assert.strictEqual(code, 0); | | 468 | + assert.strictEqual(signal, null); | | 469 | + }); | 469 | 470 |
| 470 | | - it('should allow communicating with loader via `register` ports', async () => { | 471 | | - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | 472 | | - '--no-warnings', | 473 | | - '--input-type=module', | 474 | | - '--eval', | 475 | | - ` | | 471 | + it('should allow communicating with loader via `register` ports', async () => { | | 472 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 473 | + '--no-warnings', | | 474 | + '--input-type=module', | | 475 | + '--eval', | | 476 | + ` | 476 | 477 | import {MessageChannel} from 'node:worker_threads'; | 477 | 478 | import {register} from 'node:module'; | 478 | 479 | import {once} from 'node:events'; | @@ -493,25 +494,25 @@ describe('Loader hooks', { concurrency: true }, () => { | 493 | 494 | ]); | 494 | 495 | clearTimeout(timeout); | 495 | 496 | port1.close(); | 496 | | - `, | 497 | | - ]); | | 497 | + `, | | 498 | + ]); | 498 | 499 |
| 499 | | - assert.strictEqual(stderr, ''); | 500 | | - assert.deepStrictEqual(stdout.split('\n'), [ 'register undefined', | 501 | | - 'message initialize', | 502 | | - 'message resolve node:os', | 503 | | - '' ]); | | 500 | + assert.strictEqual(stderr, ''); | | 501 | + assert.deepStrictEqual(stdout.split('\n'), [ 'register undefined', | | 502 | + 'message initialize', | | 503 | + 'message resolve node:os', | | 504 | + '' ]); | 504 | 505 |
| 505 | | - assert.strictEqual(code, 0); | 506 | | - assert.strictEqual(signal, null); | 507 | | - }); | | 506 | + assert.strictEqual(code, 0); | | 507 | + assert.strictEqual(signal, null); | | 508 | + }); | 508 | 509 |
| 509 | | - it('should have `register` work with cjs', async () => { | 510 | | - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | 511 | | - '--no-warnings', | 512 | | - '--input-type=commonjs', | 513 | | - '--eval', | 514 | | - ` | | 510 | + it('should have `register` work with cjs', async () => { | | 511 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 512 | + '--no-warnings', | | 513 | + '--input-type=commonjs', | | 514 | + '--eval', | | 515 | + ` | 515 | 516 | 'use strict'; | 516 | 517 | const {register} = require('node:module'); | 517 | 518 | register( | @@ -524,56 +525,54 @@ describe('Loader hooks', { concurrency: true }, () => { | 524 | 525 | import('node:os').then((result) => { | 525 | 526 | console.log(JSON.stringify(result)); | 526 | 527 | }); | 527 | | - `, | 528 | | - ]); | | 528 | + `, | | 529 | + ]); | 529 | 530 |
| 530 | | - assert.strictEqual(stderr, ''); | 531 | | - assert.deepStrictEqual(stdout.split('\n').sort(), ['hooks initialize 1', '{"default":"foo"}', ''].sort()); | | 531 | + assert.strictEqual(stderr, ''); | | 532 | + assert.deepStrictEqual(stdout.split('\n').sort(), ['hooks initialize 1', '{"default":"foo"}', ''].sort()); | 532 | 533 |
| 533 | | - assert.strictEqual(code, 0); | 534 | | - assert.strictEqual(signal, null); | 535 | | - }); | | 534 | + assert.strictEqual(code, 0); | | 535 | + assert.strictEqual(signal, null); | | 536 | + }); | 536 | 537 |
| 537 | | - it('`register` should work with `require`', async () => { | 538 | | - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | 539 | | - '--no-warnings', | 540 | | - '--require', | 541 | | - fixtures.path('es-module-loaders/register-loader.cjs'), | 542 | | - '--input-type=module', | 543 | | - '--eval', | 544 | | - 'import "node:os";', | 545 | | - ]); | | 538 | + it('`register` should work with `require`', async () => { | | 539 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 540 | + '--no-warnings', | | 541 | + '--require', | | 542 | + fixtures.path('es-module-loaders/register-loader.cjs'), | | 543 | + '--input-type=module', | | 544 | + '--eval', | | 545 | + 'import "node:os";', | | 546 | + ]); | 546 | 547 |
| 547 | | - assert.strictEqual(stderr, ''); | 548 | | - assert.deepStrictEqual(stdout.split('\n'), ['resolve passthru', 'resolve passthru', '']); | 549 | | - assert.strictEqual(code, 0); | 550 | | - assert.strictEqual(signal, null); | 551 | | - }); | | 548 | + assert.strictEqual(stderr, ''); | | 549 | + assert.deepStrictEqual(stdout.split('\n'), ['resolve passthru', 'resolve passthru', '']); | | 550 | + assert.strictEqual(code, 0); | | 551 | + assert.strictEqual(signal, null); | | 552 | + }); | 552 | 553 |
| 553 | | - it('`register` should work with `import`', async () => { | 554 | | - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | 555 | | - '--no-warnings', | 556 | | - '--import', | 557 | | - fixtures.fileURL('es-module-loaders/register-loader.mjs'), | 558 | | - '--input-type=module', | 559 | | - '--eval', | 560 | | - ` | 561 | | - import 'node:os'; | 562 | | - `, | 563 | | - ]); | | 554 | + it('`register` should work with `import`', async () => { | | 555 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 556 | + '--no-warnings', | | 557 | + '--import', | | 558 | + fixtures.fileURL('es-module-loaders/register-loader.mjs'), | | 559 | + '--input-type=module', | | 560 | + '--eval', | | 561 | + 'import "node:os"', | | 562 | + ]); | 564 | 563 |
| 565 | | - assert.strictEqual(stderr, ''); | 566 | | - assert.deepStrictEqual(stdout.split('\n'), ['resolve passthru', '']); | 567 | | - assert.strictEqual(code, 0); | 568 | | - assert.strictEqual(signal, null); | 569 | | - }); | | 564 | + assert.strictEqual(stderr, ''); | | 565 | + assert.deepStrictEqual(stdout.split('\n'), ['resolve passthru', '']); | | 566 | + assert.strictEqual(code, 0); | | 567 | + assert.strictEqual(signal, null); | | 568 | + }); | 570 | 569 |
| 571 | | - it('should execute `initialize` in sequence', async () => { | 572 | | - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | 573 | | - '--no-warnings', | 574 | | - '--input-type=module', | 575 | | - '--eval', | 576 | | - ` | | 570 | + it('should execute `initialize` in sequence', async () => { | | 571 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 572 | + '--no-warnings', | | 573 | + '--input-type=module', | | 574 | + '--eval', | | 575 | + ` | 577 | 576 | import {register} from 'node:module'; | 578 | 577 | console.log('result 1', register( | 579 | 578 | ${JSON.stringify(fixtures.fileURL('es-module-loaders/hooks-initialize.mjs'))} | @@ -583,17 +582,86 @@ describe('Loader hooks', { concurrency: true }, () => { | 583 | 582 | )); | 584 | 583 |
| 585 | 584 | await import('node:os'); | 586 | | - `, | 587 | | - ]); | | 585 | + `, | | 586 | + ]); | 588 | 587 |
| 589 | | - assert.strictEqual(stderr, ''); | 590 | | - assert.deepStrictEqual(stdout.split('\n'), [ 'hooks initialize 1', | 591 | | - 'result 1 undefined', | 592 | | - 'hooks initialize 2', | 593 | | - 'result 2 undefined', | 594 | | - '' ]); | 595 | | - assert.strictEqual(code, 0); | 596 | | - assert.strictEqual(signal, null); | | 588 | + assert.strictEqual(stderr, ''); | | 589 | + assert.deepStrictEqual(stdout.split('\n'), [ 'hooks initialize 1', | | 590 | + 'result 1 undefined', | | 591 | + 'hooks initialize 2', | | 592 | + 'result 2 undefined', | | 593 | + '' ]); | | 594 | + assert.strictEqual(code, 0); | | 595 | + assert.strictEqual(signal, null); | | 596 | + }); | | 597 | + | | 598 | + it('should handle `initialize` returning never-settling promise', async () => { | | 599 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 600 | + '--no-warnings', | | 601 | + '--input-type=module', | | 602 | + '--eval', | | 603 | + ` | | 604 | + import {register} from 'node:module'; | | 605 | + register('data:text/javascript,export function initialize(){return new Promise(()=>{})}'); | | 606 | + `, | | 607 | + ]); | | 608 | + | | 609 | + assert.strictEqual(stderr, ''); | | 610 | + assert.strictEqual(stdout, ''); | | 611 | + assert.strictEqual(code, 13); | | 612 | + assert.strictEqual(signal, null); | | 613 | + }); | | 614 | + | | 615 | + it('should handle `initialize` returning rejecting promise', async () => { | | 616 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 617 | + '--no-warnings', | | 618 | + '--input-type=module', | | 619 | + '--eval', | | 620 | + ` | | 621 | + import {register} from 'node:module'; | | 622 | + register('data:text/javascript,export function initialize(){return Promise.reject()}'); | | 623 | + `, | | 624 | + ]); | | 625 | + | | 626 | + assert.match(stderr, /undefined\r?\n/); | | 627 | + assert.strictEqual(stdout, ''); | | 628 | + assert.strictEqual(code, 1); | | 629 | + assert.strictEqual(signal, null); | | 630 | + }); | | 631 | + | | 632 | + it('should handle `initialize` throwing null', async () => { | | 633 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 634 | + '--no-warnings', | | 635 | + '--input-type=module', | | 636 | + '--eval', | | 637 | + ` | | 638 | + import {register} from 'node:module'; | | 639 | + register('data:text/javascript,export function initialize(){throw null}'); | | 640 | + `, | | 641 | + ]); | | 642 | + | | 643 | + assert.match(stderr, /null\r?\n/); | | 644 | + assert.strictEqual(stdout, ''); | | 645 | + assert.strictEqual(code, 1); | | 646 | + assert.strictEqual(signal, null); | | 647 | + }); | | 648 | + | | 649 | + it('should be fine to call `process.exit` from a initialize hook', async () => { | | 650 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 651 | + '--no-warnings', | | 652 | + '--input-type=module', | | 653 | + '--eval', | | 654 | + ` | | 655 | + import {register} from 'node:module'; | | 656 | + register('data:text/javascript,export function initialize(){process.exit(42);}'); | | 657 | + `, | | 658 | + ]); | | 659 | + | | 660 | + assert.strictEqual(stderr, ''); | | 661 | + assert.strictEqual(stdout, ''); | | 662 | + assert.strictEqual(code, 42); | | 663 | + assert.strictEqual(signal, null); | | 664 | + }); | 597 | 665 | }); | 598 | 666 |
| 599 | 667 | it('should use CJS loader to respond to require.resolve calls by default', async () => { | |
|