GeezerVison is showing github.com — test: increase coverage of `Module.register` and `initialize` hook · nodejs/node@866d646
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 |
|---|
@@ -399,28 +399,29 @@ describe('Loader hooks', { concurrency: true }, () => { | 399 | 399 | assert.strictEqual(signal, null); | 400 | 400 | }); | 401 | 401 |
| 402 | | - it('should invoke `initialize` correctly', async () => { | 403 | | - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | 404 | | - '--no-warnings', | 405 | | - '--experimental-loader', | 406 | | - fixtures.fileURL('es-module-loaders/hooks-initialize.mjs'), | 407 | | - '--input-type=module', | 408 | | - '--eval', | 409 | | - 'import os from "node:os";', | 410 | | - ]); | | 402 | + describe('`initialize`/`register`', () => { | | 403 | + it('should invoke `initialize` correctly', async () => { | | 404 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 405 | + '--no-warnings', | | 406 | + '--experimental-loader', | | 407 | + fixtures.fileURL('es-module-loaders/hooks-initialize.mjs'), | | 408 | + '--input-type=module', | | 409 | + '--eval', | | 410 | + 'import os from "node:os";', | | 411 | + ]); | 411 | 412 |
| 412 | | - assert.strictEqual(stderr, ''); | 413 | | - assert.deepStrictEqual(stdout.split('\n'), ['hooks initialize 1', '']); | 414 | | - assert.strictEqual(code, 0); | 415 | | - assert.strictEqual(signal, null); | 416 | | - }); | | 413 | + assert.strictEqual(stderr, ''); | | 414 | + assert.deepStrictEqual(stdout.split('\n'), ['hooks initialize 1', '']); | | 415 | + assert.strictEqual(code, 0); | | 416 | + assert.strictEqual(signal, null); | | 417 | + }); | 417 | 418 |
| 418 | | - it('should allow communicating with loader via `register` ports', async () => { | 419 | | - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | 420 | | - '--no-warnings', | 421 | | - '--input-type=module', | 422 | | - '--eval', | 423 | | - ` | | 419 | + it('should allow communicating with loader via `register` ports', async () => { | | 420 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 421 | + '--no-warnings', | | 422 | + '--input-type=module', | | 423 | + '--eval', | | 424 | + ` | 424 | 425 | import {MessageChannel} from 'node:worker_threads'; | 425 | 426 | import {register} from 'node:module'; | 426 | 427 | import {once} from 'node:events'; | @@ -441,25 +442,25 @@ describe('Loader hooks', { concurrency: true }, () => { | 441 | 442 | ]); | 442 | 443 | clearTimeout(timeout); | 443 | 444 | port1.close(); | 444 | | - `, | 445 | | - ]); | | 445 | + `, | | 446 | + ]); | 446 | 447 |
| 447 | | - assert.strictEqual(stderr, ''); | 448 | | - assert.deepStrictEqual(stdout.split('\n'), [ 'register undefined', | 449 | | - 'message initialize', | 450 | | - 'message resolve node:os', | 451 | | - '' ]); | | 448 | + assert.strictEqual(stderr, ''); | | 449 | + assert.deepStrictEqual(stdout.split('\n'), [ 'register undefined', | | 450 | + 'message initialize', | | 451 | + 'message resolve node:os', | | 452 | + '' ]); | 452 | 453 |
| 453 | | - assert.strictEqual(code, 0); | 454 | | - assert.strictEqual(signal, null); | 455 | | - }); | | 454 | + assert.strictEqual(code, 0); | | 455 | + assert.strictEqual(signal, null); | | 456 | + }); | 456 | 457 |
| 457 | | - it('should have `register` work with cjs', async () => { | 458 | | - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | 459 | | - '--no-warnings', | 460 | | - '--input-type=commonjs', | 461 | | - '--eval', | 462 | | - ` | | 458 | + it('should have `register` work with cjs', async () => { | | 459 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 460 | + '--no-warnings', | | 461 | + '--input-type=commonjs', | | 462 | + '--eval', | | 463 | + ` | 463 | 464 | 'use strict'; | 464 | 465 | const {register} = require('node:module'); | 465 | 466 | register( | @@ -472,56 +473,54 @@ describe('Loader hooks', { concurrency: true }, () => { | 472 | 473 | import('node:os').then((result) => { | 473 | 474 | console.log(JSON.stringify(result)); | 474 | 475 | }); | 475 | | - `, | 476 | | - ]); | | 476 | + `, | | 477 | + ]); | 477 | 478 |
| 478 | | - assert.strictEqual(stderr, ''); | 479 | | - assert.deepStrictEqual(stdout.split('\n').sort(), ['hooks initialize 1', '{"default":"foo"}', ''].sort()); | | 479 | + assert.strictEqual(stderr, ''); | | 480 | + assert.deepStrictEqual(stdout.split('\n').sort(), ['hooks initialize 1', '{"default":"foo"}', ''].sort()); | 480 | 481 |
| 481 | | - assert.strictEqual(code, 0); | 482 | | - assert.strictEqual(signal, null); | 483 | | - }); | | 482 | + assert.strictEqual(code, 0); | | 483 | + assert.strictEqual(signal, null); | | 484 | + }); | 484 | 485 |
| 485 | | - it('`register` should work with `require`', async () => { | 486 | | - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | 487 | | - '--no-warnings', | 488 | | - '--require', | 489 | | - fixtures.path('es-module-loaders/register-loader.cjs'), | 490 | | - '--input-type=module', | 491 | | - '--eval', | 492 | | - 'import "node:os";', | 493 | | - ]); | | 486 | + it('`register` should work with `require`', async () => { | | 487 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 488 | + '--no-warnings', | | 489 | + '--require', | | 490 | + fixtures.path('es-module-loaders/register-loader.cjs'), | | 491 | + '--input-type=module', | | 492 | + '--eval', | | 493 | + 'import "node:os";', | | 494 | + ]); | 494 | 495 |
| 495 | | - assert.strictEqual(stderr, ''); | 496 | | - assert.deepStrictEqual(stdout.split('\n'), ['resolve passthru', 'resolve passthru', '']); | 497 | | - assert.strictEqual(code, 0); | 498 | | - assert.strictEqual(signal, null); | 499 | | - }); | | 496 | + assert.strictEqual(stderr, ''); | | 497 | + assert.deepStrictEqual(stdout.split('\n'), ['resolve passthru', 'resolve passthru', '']); | | 498 | + assert.strictEqual(code, 0); | | 499 | + assert.strictEqual(signal, null); | | 500 | + }); | 500 | 501 |
| 501 | | - it('`register` should work with `import`', async () => { | 502 | | - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | 503 | | - '--no-warnings', | 504 | | - '--import', | 505 | | - fixtures.fileURL('es-module-loaders/register-loader.mjs'), | 506 | | - '--input-type=module', | 507 | | - '--eval', | 508 | | - ` | 509 | | - import 'node:os'; | 510 | | - `, | 511 | | - ]); | | 502 | + it('`register` should work with `import`', async () => { | | 503 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 504 | + '--no-warnings', | | 505 | + '--import', | | 506 | + fixtures.fileURL('es-module-loaders/register-loader.mjs'), | | 507 | + '--input-type=module', | | 508 | + '--eval', | | 509 | + 'import "node:os"', | | 510 | + ]); | 512 | 511 |
| 513 | | - assert.strictEqual(stderr, ''); | 514 | | - assert.deepStrictEqual(stdout.split('\n'), ['resolve passthru', '']); | 515 | | - assert.strictEqual(code, 0); | 516 | | - assert.strictEqual(signal, null); | 517 | | - }); | | 512 | + assert.strictEqual(stderr, ''); | | 513 | + assert.deepStrictEqual(stdout.split('\n'), ['resolve passthru', '']); | | 514 | + assert.strictEqual(code, 0); | | 515 | + assert.strictEqual(signal, null); | | 516 | + }); | 518 | 517 |
| 519 | | - it('should execute `initialize` in sequence', async () => { | 520 | | - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | 521 | | - '--no-warnings', | 522 | | - '--input-type=module', | 523 | | - '--eval', | 524 | | - ` | | 518 | + it('should execute `initialize` in sequence', async () => { | | 519 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 520 | + '--no-warnings', | | 521 | + '--input-type=module', | | 522 | + '--eval', | | 523 | + ` | 525 | 524 | import {register} from 'node:module'; | 526 | 525 | console.log('result 1', register( | 527 | 526 | ${JSON.stringify(fixtures.fileURL('es-module-loaders/hooks-initialize.mjs'))} | @@ -531,16 +530,85 @@ describe('Loader hooks', { concurrency: true }, () => { | 531 | 530 | )); | 532 | 531 |
| 533 | 532 | await import('node:os'); | 534 | | - `, | 535 | | - ]); | | 533 | + `, | | 534 | + ]); | 536 | 535 |
| 537 | | - assert.strictEqual(stderr, ''); | 538 | | - assert.deepStrictEqual(stdout.split('\n'), [ 'hooks initialize 1', | 539 | | - 'result 1 undefined', | 540 | | - 'hooks initialize 2', | 541 | | - 'result 2 undefined', | 542 | | - '' ]); | 543 | | - assert.strictEqual(code, 0); | 544 | | - assert.strictEqual(signal, null); | | 536 | + assert.strictEqual(stderr, ''); | | 537 | + assert.deepStrictEqual(stdout.split('\n'), [ 'hooks initialize 1', | | 538 | + 'result 1 undefined', | | 539 | + 'hooks initialize 2', | | 540 | + 'result 2 undefined', | | 541 | + '' ]); | | 542 | + assert.strictEqual(code, 0); | | 543 | + assert.strictEqual(signal, null); | | 544 | + }); | | 545 | + | | 546 | + it('should handle `initialize` returning never-settling promise', async () => { | | 547 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 548 | + '--no-warnings', | | 549 | + '--input-type=module', | | 550 | + '--eval', | | 551 | + ` | | 552 | + import {register} from 'node:module'; | | 553 | + register('data:text/javascript,export function initialize(){return new Promise(()=>{})}'); | | 554 | + `, | | 555 | + ]); | | 556 | + | | 557 | + assert.strictEqual(stderr, ''); | | 558 | + assert.strictEqual(stdout, ''); | | 559 | + assert.strictEqual(code, 13); | | 560 | + assert.strictEqual(signal, null); | | 561 | + }); | | 562 | + | | 563 | + it('should handle `initialize` returning rejecting promise', async () => { | | 564 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 565 | + '--no-warnings', | | 566 | + '--input-type=module', | | 567 | + '--eval', | | 568 | + ` | | 569 | + import {register} from 'node:module'; | | 570 | + register('data:text/javascript,export function initialize(){return Promise.reject()}'); | | 571 | + `, | | 572 | + ]); | | 573 | + | | 574 | + assert.match(stderr, /undefined\r?\n/); | | 575 | + assert.strictEqual(stdout, ''); | | 576 | + assert.strictEqual(code, 1); | | 577 | + assert.strictEqual(signal, null); | | 578 | + }); | | 579 | + | | 580 | + it('should handle `initialize` throwing null', async () => { | | 581 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 582 | + '--no-warnings', | | 583 | + '--input-type=module', | | 584 | + '--eval', | | 585 | + ` | | 586 | + import {register} from 'node:module'; | | 587 | + register('data:text/javascript,export function initialize(){throw null}'); | | 588 | + `, | | 589 | + ]); | | 590 | + | | 591 | + assert.match(stderr, /null\r?\n/); | | 592 | + assert.strictEqual(stdout, ''); | | 593 | + assert.strictEqual(code, 1); | | 594 | + assert.strictEqual(signal, null); | | 595 | + }); | | 596 | + | | 597 | + it('should be fine to call `process.exit` from a initialize hook', async () => { | | 598 | + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ | | 599 | + '--no-warnings', | | 600 | + '--input-type=module', | | 601 | + '--eval', | | 602 | + ` | | 603 | + import {register} from 'node:module'; | | 604 | + register('data:text/javascript,export function initialize(){process.exit(42);}'); | | 605 | + `, | | 606 | + ]); | | 607 | + | | 608 | + assert.strictEqual(stderr, ''); | | 609 | + assert.strictEqual(stdout, ''); | | 610 | + assert.strictEqual(code, 42); | | 611 | + assert.strictEqual(signal, null); | | 612 | + }); | 545 | 613 | }); | 546 | 614 | }); |
|