@onify/fake-amqplib 3.3.0 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. package/README.md +76 -44
  2. package/index.d.ts +86 -55
  3. package/index.js +69 -3
  4. package/main.cjs +69 -3
  5. package/package.json +21 -10
package/README.md CHANGED
@@ -4,6 +4,18 @@
4
4
 
5
5
  Mocked version of https://www.npmjs.com/package/amqplib.
6
6
 
7
+ <!-- toc -->
8
+
9
+ - [Fake api](#fake-api)
10
+ - [RabbitMQ versions](#rabbitmq-versions)
11
+ - [Mocking amqplib](#mocking-amqplib)
12
+ - [ESM](#esm)
13
+ - [Node 20+ — `node:test` `mock.module` (recommended)](#node-20-nodetest-mockmodule-recommended)
14
+ - [Alternative — Quibble](#alternative-quibble)
15
+ - [CommonJS](#commonjs)
16
+
17
+ <!-- /toc -->
18
+
7
19
  ## Fake api
8
20
 
9
21
  - `async connect(amqpurl[, ...otherOptions, callback])`: wait for a fake connection or expect one in the callback
@@ -38,46 +50,62 @@ var fakeAmqp = require('@onify/fake-amqplib');
38
50
 
39
51
  You might want to override `amqplib` with `@onify/fake-amqplib` in tests. This can be done in a number of ways.
40
52
 
41
- ### CommonJS
53
+ ### ESM
42
54
 
43
- Example on how to mock amqplib when working with commonjs.
55
+ Example on how to mock the `amqplib` import when working with modules.
44
56
 
45
- ```js
46
- const amqplib = require('amqplib');
47
- const fakeAmqp = require('@onify/fake-amqplib');
57
+ #### Node 20+ — `node:test` `mock.module` (recommended)
48
58
 
49
- amqplib.connect = fakeAmqp.connect;
59
+ Node's built-in test runner ships an experimental module-mocking API that needs no extra dependency. Set it up at the top of the test file (or in a setup file), then dynamically import `amqplib`.
60
+
61
+ _.mocharc.json_
62
+
63
+ ```json
64
+ {
65
+ "recursive": true,
66
+ "require": ["chai/register-expect.js"],
67
+ "node-option": ["experimental-test-module-mocks", "no-warnings"]
68
+ }
50
69
  ```
51
70
 
52
- or:
71
+ The `experimental-test-module-mocks` flag enables `mock.module`; `no-warnings` silences the "experimental feature" notice. Drop it if you'd rather see the warning.
53
72
 
54
- ```js
55
- const mock = require('mock-require');
56
- const fakeAmqp = require('@onify/fake-amqplib');
73
+ _test/amqplib-connection-test.js_
57
74
 
58
- mock('amqplib/callback_api', fakeAmqp);
59
- ```
75
+ ```javascript
76
+ import { mock } from 'node:test';
77
+ import { connect as fakeConnect, resetMock } from '@onify/fake-amqplib';
60
78
 
61
- or just mock the entire amqplib with:
79
+ describe('connection', () => {
80
+ let connect;
81
+ let ctx;
62
82
 
63
- ```js
64
- const mock = require('mock-require');
65
- const fakeAmqp = require('@onify/fake-amqplib');
83
+ before(async () => {
84
+ ctx = mock.module('amqplib', { namedExports: { connect: fakeConnect } });
85
+ ({ connect } = await import('amqplib'));
86
+ });
66
87
 
67
- mock('amqplib', fakeAmqp);
68
- ```
88
+ after(() => {
89
+ ctx.restore();
90
+ resetMock();
91
+ });
69
92
 
70
- ### ESM
93
+ it('connects to the fake', async () => {
94
+ const connection = await connect('amqp://host');
95
+ expect(connection.connection.serverProperties).to.have.property('product', 'RabbitMQ');
96
+ });
97
+ });
98
+ ```
71
99
 
72
- Example on how to mock amqplib import when working with modules.
100
+ If you also use `mocha --parallel` or run tests via `node --test`, the same setup works — `mock.module` is process-global, so register it before the first dynamic import in each test file.
73
101
 
74
- **[Quibble](https://www.npmjs.com/package/quibble) mocha example**
102
+ #### Alternative — Quibble
75
103
 
76
- Both amqplib and fake-amqplib have to be quibbled if reset mock is used during testing.
104
+ [Quibble](https://www.npmjs.com/package/quibble) is useful if you're on a Node version older than 20, or prefer not to rely on an experimental flag.
77
105
 
78
106
  _test/setup.js_
79
107
 
80
- ```javascript
108
+ ```js
81
109
  import * as fakeAmqpLib from '@onify/fake-amqplib';
82
110
  import { connect as fakeConnect } from '@onify/fake-amqplib';
83
111
  import quibble from 'quibble';
@@ -88,7 +116,7 @@ import quibble from 'quibble';
88
116
  })();
89
117
  ```
90
118
 
91
- _.mocharc.json_ (true for node version < 20)
119
+ _.mocharc.json_ (the `loader=quibble` option is only needed on Node < 20)
92
120
 
93
121
  ```json
94
122
  {
@@ -98,29 +126,33 @@ _.mocharc.json_ (true for node version < 20)
98
126
  }
99
127
  ```
100
128
 
101
- _test/amqplib-connection-test.js_
129
+ Then import `amqplib` normally in your tests; quibble rewires the import.
102
130
 
103
- ```javascript
104
- import assert from 'node:assert';
105
- import { connect } from 'amqplib';
106
- import { connect as connectCb } from 'amqplib';
131
+ ### CommonJS
107
132
 
108
- import { resetMock } from '@onify/fake-amqplib';
133
+ Example on how to mock amqplib when working with commonjs.
109
134
 
110
- describe('connection', () => {
111
- afterEach(resetMock);
135
+ ```js
136
+ const amqplib = require('amqplib');
137
+ const fakeAmqp = require('@onify/fake-amqplib');
112
138
 
113
- it('connect promise', async () => {
114
- const connection = await connect('amqp://host');
115
- assert.equal(connection.connection.serverProperties.version, '3.5.0');
116
- });
139
+ amqplib.connect = fakeAmqp.connect;
140
+ ```
117
141
 
118
- it('connect callback', (done) => {
119
- connectCb('amqp://host', (err, connection) => {
120
- if (err) return done(err);
121
- assert.equal(connection.connection.serverProperties.version, '3.5.0');
122
- done();
123
- });
124
- });
125
- });
142
+ or:
143
+
144
+ ```js
145
+ const mock = require('mock-require');
146
+ const fakeAmqp = require('@onify/fake-amqplib');
147
+
148
+ mock('amqplib/callback_api', fakeAmqp);
149
+ ```
150
+
151
+ or just mock the entire amqplib with:
152
+
153
+ ```js
154
+ const mock = require('mock-require');
155
+ const fakeAmqp = require('@onify/fake-amqplib');
156
+
157
+ mock('amqplib', fakeAmqp);
126
158
  ```
package/index.d.ts CHANGED
@@ -1,59 +1,90 @@
1
1
  /// <reference types="amqplib" />
2
2
  /// <reference types="node" />
3
3
 
4
- declare module '@onify/fake-amqplib' {
5
- import { Options, Connection, Channel, ChannelModel } from 'amqplib';
6
- import { Broker } from 'smqp';
7
-
8
- export interface FakeAmqplibChannel extends Channel {
9
- /** Channel name and identifier, for faking purposes */
10
- _channelName: string;
11
- _broker: Broker;
12
- _version: number;
13
- new (broker: Broker, connection: FakeAmqplibConnection): FakeAmqplibChannel;
14
- get _closed(): boolean;
15
- }
16
-
17
- export interface FakeAmqplibConnection extends Connection, ChannelModel {
18
- _channels: FakeAmqplibChannel[];
19
- _url: URL;
20
- /** Connection identifier, for faking purposes */
21
- _id: string;
22
- _broker: Broker;
23
- _version: number;
24
- new (broker: Broker, version: number, amqpUrl: string, options?: any): FakeAmqplibConnection;
25
- get _closed(): boolean;
26
- }
27
-
28
- interface SocketOptions {
29
- host?: string;
30
- keepAlive?: boolean;
31
- keepAliveDelay?: number;
32
- noDelay?: boolean;
33
- port?: number;
34
- serverName?: string;
35
- timeout?: number;
36
- [x: string]: any;
37
- }
38
-
39
- type connectCallback = (err: Error, connection: FakeAmqplibConnection) => void;
40
-
41
- export class FakeAmqplib {
42
- version: number;
43
- connections: FakeAmqplibConnection[];
44
- constructor(version?: number);
45
- connect(url: string | Options.Connect, socketOptions?: SocketOptions): Promise<FakeAmqplibConnection>;
46
- connect(url: string | Options.Connect, socketOptions: SocketOptions, callback: connectCallback): void;
47
- connect(url: string | Options.Connect, callback: (err: Error, connection: FakeAmqplibConnection) => void): void;
48
- connectSync(url: string | Options.Connect, socketOptions?: SocketOptions): FakeAmqplibConnection;
49
- resetMock(): void;
50
- setVersion(minorVersion: number): void;
51
- }
52
-
53
- export function connect(url: string | Options.Connect, socketOptions?: SocketOptions): Promise<FakeAmqplibConnection>;
54
- export function connect(url: string | Options.Connect, socketOptions: SocketOptions, callback: connectCallback): void;
55
- export function connect(url: string | Options.Connect, callback: connectCallback): void;
56
- export function connectSync(url: string | Options.Connect, socketOptions?: SocketOptions): FakeAmqplibConnection;
57
- export function resetMock(): void;
58
- export function setVersion(minorVersion: number): void;
4
+ import { Options, Connection, Channel, ChannelModel, Replies } from 'amqplib';
5
+ import { Broker } from 'smqp';
6
+
7
+ export interface FakeAmqplibChannel extends Channel {
8
+ /** Channel name and identifier, for faking purposes */
9
+ _channelName: string;
10
+ _broker: Broker;
11
+ _version: number;
12
+ readonly _closed: boolean;
13
+ }
14
+
15
+ export const FakeAmqplibChannel: {
16
+ new (broker: Broker, connection: FakeAmqplibConnection): FakeAmqplibChannel;
17
+ };
18
+
19
+ export interface FakeAmqplibConfirmChannel extends FakeAmqplibChannel {
20
+ publish(
21
+ exchange: string,
22
+ routingKey: string,
23
+ content: Buffer,
24
+ options?: Options.Publish,
25
+ callback?: (err: Error | null, ok: Replies.Empty) => void
26
+ ): boolean;
27
+ sendToQueue(
28
+ queue: string,
29
+ content: Buffer,
30
+ options?: Options.Publish,
31
+ callback?: (err: Error | null, ok: Replies.Empty) => void
32
+ ): boolean;
33
+ waitForConfirms(callback?: (err: Error | null) => void): Promise<void>;
34
+ }
35
+
36
+ export const FakeAmqplibConfirmChannel: {
37
+ new (broker: Broker, connection: FakeAmqplibConnection): FakeAmqplibConfirmChannel;
38
+ };
39
+
40
+ export interface FakeAmqplibConnection extends Connection, ChannelModel {
41
+ _channels: FakeAmqplibChannel[];
42
+ _url: URL;
43
+ /** Connection identifier, for faking purposes */
44
+ _id: string;
45
+ _broker: Broker;
46
+ _version: number;
47
+ readonly _closed: boolean;
48
+ }
49
+
50
+ export const FakeAmqplibConnection: {
51
+ new (broker: Broker, version: number, amqpUrl: string, options?: SocketOptions): FakeAmqplibConnection;
52
+ };
53
+
54
+ export interface SocketOptions {
55
+ host?: string;
56
+ keepAlive?: boolean;
57
+ keepAliveDelay?: number;
58
+ noDelay?: boolean;
59
+ port?: number;
60
+ serverName?: string;
61
+ timeout?: number;
62
+ [x: string]: any;
63
+ }
64
+
65
+ export type ConnectCallback = (err: Error | null, connection: FakeAmqplibConnection) => void;
66
+
67
+ export interface FakeAmqplib {
68
+ version: number;
69
+ connections: FakeAmqplibConnection[];
70
+ connect(url: string | Options.Connect, socketOptions?: SocketOptions): Promise<FakeAmqplibConnection>;
71
+ connect(url: string | Options.Connect, socketOptions: SocketOptions, callback: ConnectCallback): void;
72
+ connect(url: string | Options.Connect, callback: ConnectCallback): void;
73
+ connectSync(url: string | Options.Connect, socketOptions?: SocketOptions): FakeAmqplibConnection;
74
+ resetMock(): void;
75
+ setVersion(minorVersion: number | string): void;
59
76
  }
77
+
78
+ export const FakeAmqplib: {
79
+ new (minorVersion?: number | string): FakeAmqplib;
80
+ (minorVersion?: number | string): FakeAmqplib;
81
+ };
82
+
83
+ export const connections: FakeAmqplibConnection[];
84
+
85
+ export function connect(url: string | Options.Connect, socketOptions?: SocketOptions): Promise<FakeAmqplibConnection>;
86
+ export function connect(url: string | Options.Connect, socketOptions: SocketOptions, callback: ConnectCallback): void;
87
+ export function connect(url: string | Options.Connect, callback: ConnectCallback): void;
88
+ export function connectSync(url: string | Options.Connect, socketOptions?: SocketOptions): FakeAmqplibConnection;
89
+ export function resetMock(): void;
90
+ export function setVersion(minorVersion: number | string): void;
package/index.js CHANGED
@@ -7,6 +7,9 @@ const kClosed = Symbol.for('closed');
7
7
  const kDeliveryTag = Symbol.for('channel delivery tag');
8
8
  const kPrefetch = Symbol.for('prefetch');
9
9
  const kChannelPrefetch = Symbol.for('channel prefetch');
10
+ const kPendingConfirms = Symbol.for('pending confirms');
11
+
12
+ const CHANNEL_CLOSED_ERROR = 'Channel is closed';
10
13
 
11
14
  class AmqplibBroker extends Broker {
12
15
  constructor(...args) {
@@ -429,6 +432,19 @@ export class FakeAmqplibChannel extends EventEmitter {
429
432
  brokerMessage.reject(requeue);
430
433
  }
431
434
  }
435
+ recover(...args) {
436
+ const channelQ = this._channelQueue;
437
+ return this._callBroker(recoverChannel, ...args);
438
+
439
+ function recoverChannel() {
440
+ let msg;
441
+ while ((msg = channelQ.get())) {
442
+ msg.content[kSmqp].reject(true);
443
+ msg.reject(false);
444
+ }
445
+ return {};
446
+ }
447
+ }
432
448
  prefetch(val, isChannelPrefetch) {
433
449
  if (this.connection._version < 3.3) {
434
450
  if (isChannelPrefetch !== undefined) {
@@ -449,7 +465,7 @@ export class FakeAmqplibChannel extends EventEmitter {
449
465
  else poppedCb = null;
450
466
 
451
467
  if (this.connection._closed) throw new FakeAmqpError('Connection is closed', 504);
452
- if (this[kClosed]) throw new Error('Channel is closed');
468
+ if (this[kClosed]) throw new Error(CHANNEL_CLOSED_ERROR);
453
469
 
454
470
  return new Promise((resolve, reject) => {
455
471
  try {
@@ -509,19 +525,25 @@ export class FakeAmqplibChannel extends EventEmitter {
509
525
  }
510
526
 
511
527
  export class FakeAmqplibConfirmChannel extends FakeAmqplibChannel {
528
+ constructor(broker, connection) {
529
+ super(broker, connection);
530
+ this[kPendingConfirms] = new Set();
531
+ }
512
532
  publish(exchange, routingKey, content, options, callback) {
513
533
  if (!Buffer.isBuffer(content)) throw new TypeError('content is not a buffer');
514
534
  if (exchange === '') return this.sendToQueue(routingKey, content, options, callback);
535
+ if (this[kClosed]) throw new Error(CHANNEL_CLOSED_ERROR);
515
536
 
516
537
  const args = [this._broker.publish, exchange, routingKey, content];
517
538
 
518
- args.push(...addConfirmCallback(this._broker, options, callback));
539
+ args.push(...addConfirmCallback(this._broker, options, this._trackConfirm(callback)));
519
540
 
520
541
  this.checkExchange(exchange)
521
542
  .then(() => {
522
543
  return this._callBroker(...args);
523
544
  })
524
545
  .catch((err) => {
546
+ if (err.message === CHANNEL_CLOSED_ERROR) return;
525
547
  this.emit('error', err);
526
548
  });
527
549
 
@@ -529,21 +551,61 @@ export class FakeAmqplibConfirmChannel extends FakeAmqplibChannel {
529
551
  }
530
552
  sendToQueue(queue, content, options, callback) {
531
553
  if (!Buffer.isBuffer(content)) throw new TypeError('content is not a buffer');
554
+ if (this[kClosed]) throw new Error(CHANNEL_CLOSED_ERROR);
532
555
 
533
556
  const args = [this._broker.sendToQueue, queue, content];
534
557
 
535
- args.push(...addConfirmCallback(this._broker, options, callback));
558
+ args.push(...addConfirmCallback(this._broker, options, this._trackConfirm(callback)));
536
559
 
537
560
  this.checkQueue(queue)
538
561
  .then(() => {
539
562
  return this._callBroker(...args);
540
563
  })
541
564
  .catch((err) => {
565
+ if (err.message === CHANNEL_CLOSED_ERROR) return;
542
566
  this.emit('error', err);
543
567
  });
544
568
 
545
569
  return true;
546
570
  }
571
+ _trackConfirm(userCallback) {
572
+ let resolveSettled;
573
+ const settled = new Promise((resolve) => {
574
+ resolveSettled = resolve;
575
+ });
576
+ const entry = { settled, resolveSettled, userCallback };
577
+ this[kPendingConfirms].add(entry);
578
+
579
+ return (err, ok) => {
580
+ this[kPendingConfirms].delete(entry);
581
+ resolveSettled(err || null);
582
+ if (typeof userCallback === 'function') userCallback(err, ok);
583
+ };
584
+ }
585
+ waitForConfirms(callback) {
586
+ const snapshot = [...this[kPendingConfirms]].map((entry) => entry.settled);
587
+ const promise = Promise.all(snapshot).then((errs) => {
588
+ const firstErr = errs.find((e) => e !== null);
589
+ if (firstErr) throw firstErr;
590
+ });
591
+ if (typeof callback === 'function') {
592
+ promise.then(
593
+ () => callback(null),
594
+ (err) => callback(err)
595
+ );
596
+ }
597
+ return promise;
598
+ }
599
+ _teardown() {
600
+ super._teardown();
601
+ if (!this[kPendingConfirms] || this[kPendingConfirms].size === 0) return;
602
+ const err = new Error(CHANNEL_CLOSED_ERROR);
603
+ for (const entry of [...this[kPendingConfirms]]) {
604
+ this[kPendingConfirms].delete(entry);
605
+ entry.resolveSettled(err);
606
+ if (typeof entry.userCallback === 'function') entry.userCallback(err);
607
+ }
608
+ }
547
609
  }
548
610
 
549
611
  export class FakeAmqplibConnection extends EventEmitter {
@@ -586,6 +648,10 @@ export class FakeAmqplibConnection extends EventEmitter {
586
648
  this._channels.push(channel);
587
649
  return resolveOrCallback(args.slice(-1)[0], null, channel);
588
650
  }
651
+ updateSecret(...args) {
652
+ process.nextTick(() => this.emit('update-secret-ok'));
653
+ return resolveOrCallback(args.slice(-1)[0]);
654
+ }
589
655
  close(...args) {
590
656
  if (this[kClosed]) return resolveOrCallback(args.slice(-1)[0]);
591
657
  this[kClosed] = true;
package/main.cjs CHANGED
@@ -9,6 +9,9 @@ const kClosed = Symbol.for('closed');
9
9
  const kDeliveryTag = Symbol.for('channel delivery tag');
10
10
  const kPrefetch = Symbol.for('prefetch');
11
11
  const kChannelPrefetch = Symbol.for('channel prefetch');
12
+ const kPendingConfirms = Symbol.for('pending confirms');
13
+
14
+ const CHANNEL_CLOSED_ERROR = 'Channel is closed';
12
15
 
13
16
  class AmqplibBroker extends smqp.Broker {
14
17
  constructor(...args) {
@@ -431,6 +434,19 @@ class FakeAmqplibChannel extends events.EventEmitter {
431
434
  brokerMessage.reject(requeue);
432
435
  }
433
436
  }
437
+ recover(...args) {
438
+ const channelQ = this._channelQueue;
439
+ return this._callBroker(recoverChannel, ...args);
440
+
441
+ function recoverChannel() {
442
+ let msg;
443
+ while ((msg = channelQ.get())) {
444
+ msg.content[kSmqp].reject(true);
445
+ msg.reject(false);
446
+ }
447
+ return {};
448
+ }
449
+ }
434
450
  prefetch(val, isChannelPrefetch) {
435
451
  if (this.connection._version < 3.3) {
436
452
  if (isChannelPrefetch !== undefined) {
@@ -451,7 +467,7 @@ class FakeAmqplibChannel extends events.EventEmitter {
451
467
  else poppedCb = null;
452
468
 
453
469
  if (this.connection._closed) throw new FakeAmqpError('Connection is closed', 504);
454
- if (this[kClosed]) throw new Error('Channel is closed');
470
+ if (this[kClosed]) throw new Error(CHANNEL_CLOSED_ERROR);
455
471
 
456
472
  return new Promise((resolve, reject) => {
457
473
  try {
@@ -511,19 +527,25 @@ class FakeAmqplibChannel extends events.EventEmitter {
511
527
  }
512
528
 
513
529
  class FakeAmqplibConfirmChannel extends FakeAmqplibChannel {
530
+ constructor(broker, connection) {
531
+ super(broker, connection);
532
+ this[kPendingConfirms] = new Set();
533
+ }
514
534
  publish(exchange, routingKey, content, options, callback) {
515
535
  if (!Buffer.isBuffer(content)) throw new TypeError('content is not a buffer');
516
536
  if (exchange === '') return this.sendToQueue(routingKey, content, options, callback);
537
+ if (this[kClosed]) throw new Error(CHANNEL_CLOSED_ERROR);
517
538
 
518
539
  const args = [this._broker.publish, exchange, routingKey, content];
519
540
 
520
- args.push(...addConfirmCallback(this._broker, options, callback));
541
+ args.push(...addConfirmCallback(this._broker, options, this._trackConfirm(callback)));
521
542
 
522
543
  this.checkExchange(exchange)
523
544
  .then(() => {
524
545
  return this._callBroker(...args);
525
546
  })
526
547
  .catch((err) => {
548
+ if (err.message === CHANNEL_CLOSED_ERROR) return;
527
549
  this.emit('error', err);
528
550
  });
529
551
 
@@ -531,21 +553,61 @@ class FakeAmqplibConfirmChannel extends FakeAmqplibChannel {
531
553
  }
532
554
  sendToQueue(queue, content, options, callback) {
533
555
  if (!Buffer.isBuffer(content)) throw new TypeError('content is not a buffer');
556
+ if (this[kClosed]) throw new Error(CHANNEL_CLOSED_ERROR);
534
557
 
535
558
  const args = [this._broker.sendToQueue, queue, content];
536
559
 
537
- args.push(...addConfirmCallback(this._broker, options, callback));
560
+ args.push(...addConfirmCallback(this._broker, options, this._trackConfirm(callback)));
538
561
 
539
562
  this.checkQueue(queue)
540
563
  .then(() => {
541
564
  return this._callBroker(...args);
542
565
  })
543
566
  .catch((err) => {
567
+ if (err.message === CHANNEL_CLOSED_ERROR) return;
544
568
  this.emit('error', err);
545
569
  });
546
570
 
547
571
  return true;
548
572
  }
573
+ _trackConfirm(userCallback) {
574
+ let resolveSettled;
575
+ const settled = new Promise((resolve) => {
576
+ resolveSettled = resolve;
577
+ });
578
+ const entry = { settled, resolveSettled, userCallback };
579
+ this[kPendingConfirms].add(entry);
580
+
581
+ return (err, ok) => {
582
+ this[kPendingConfirms].delete(entry);
583
+ resolveSettled(err || null);
584
+ if (typeof userCallback === 'function') userCallback(err, ok);
585
+ };
586
+ }
587
+ waitForConfirms(callback) {
588
+ const snapshot = [...this[kPendingConfirms]].map((entry) => entry.settled);
589
+ const promise = Promise.all(snapshot).then((errs) => {
590
+ const firstErr = errs.find((e) => e !== null);
591
+ if (firstErr) throw firstErr;
592
+ });
593
+ if (typeof callback === 'function') {
594
+ promise.then(
595
+ () => callback(null),
596
+ (err) => callback(err)
597
+ );
598
+ }
599
+ return promise;
600
+ }
601
+ _teardown() {
602
+ super._teardown();
603
+ if (!this[kPendingConfirms] || this[kPendingConfirms].size === 0) return;
604
+ const err = new Error(CHANNEL_CLOSED_ERROR);
605
+ for (const entry of [...this[kPendingConfirms]]) {
606
+ this[kPendingConfirms].delete(entry);
607
+ entry.resolveSettled(err);
608
+ if (typeof entry.userCallback === 'function') entry.userCallback(err);
609
+ }
610
+ }
549
611
  }
550
612
 
551
613
  class FakeAmqplibConnection extends events.EventEmitter {
@@ -588,6 +650,10 @@ class FakeAmqplibConnection extends events.EventEmitter {
588
650
  this._channels.push(channel);
589
651
  return resolveOrCallback(args.slice(-1)[0], null, channel);
590
652
  }
653
+ updateSecret(...args) {
654
+ process.nextTick(() => this.emit('update-secret-ok'));
655
+ return resolveOrCallback(args.slice(-1)[0]);
656
+ }
591
657
  close(...args) {
592
658
  if (this[kClosed]) return resolveOrCallback(args.slice(-1)[0]);
593
659
  this[kClosed] = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@onify/fake-amqplib",
3
- "version": "3.3.0",
3
+ "version": "3.5.0",
4
4
  "description": "Fake amqplib",
5
5
  "type": "module",
6
6
  "exports": {
@@ -13,19 +13,21 @@
13
13
  "main": "./main.cjs",
14
14
  "scripts": {
15
15
  "test": "mocha",
16
- "posttest": "npm run lint && npm run dist",
16
+ "posttest": "npm run lint && npm run dist && npm run test:md",
17
17
  "lint": "eslint . --cache && prettier . -c --cache",
18
18
  "dist": "rollup -c",
19
19
  "prepack": "npm run dist",
20
20
  "cov:html": "c8 -r html -r text mocha",
21
- "test:lcov": "c8 -r lcov mocha && npm run lint"
21
+ "test:lcov": "c8 -r lcov mocha && npm run lint",
22
+ "test:md": "texample ./README.md -c ./.mocharc.json -r scripts/texample-mocha.js",
23
+ "toc": "node scripts/toc.js"
22
24
  },
23
25
  "author": {
24
26
  "name": "Onify",
25
27
  "url": "https://github.com/onify"
26
28
  },
27
29
  "engines": {
28
- "node": ">=14"
30
+ "node": ">=18"
29
31
  },
30
32
  "repository": {
31
33
  "type": "git",
@@ -33,21 +35,30 @@
33
35
  },
34
36
  "license": "MIT",
35
37
  "dependencies": {
36
- "smqp": "^10.0.0"
38
+ "smqp": "^12.0.0"
37
39
  },
38
40
  "devDependencies": {
41
+ "@eslint/js": "^10.0.1",
39
42
  "@rollup/plugin-commonjs": "^29.0.0",
40
43
  "@types/amqplib": "^0.10.2",
41
- "amqplib": "^0.10.4",
42
- "c8": "^10.1.2",
44
+ "amqplib": "^1.0.3",
45
+ "c8": "^11.0.0",
43
46
  "chai": "^6.2.1",
44
- "eslint": "^9.0.0",
45
- "globals": "^16.0.0",
47
+ "eslint": "^10.3.0",
48
+ "globals": "^17.0.0",
46
49
  "mocha": "^11.0.1",
47
50
  "prettier": "^3.2.5",
48
51
  "quibble": "^0.9.2",
49
52
  "rollup": "^4.0.2",
50
- "texample": "^0.1.0"
53
+ "texample": "^1.0.2"
54
+ },
55
+ "overrides": {
56
+ "c8": {
57
+ "yargs": "^18.0.0"
58
+ },
59
+ "mocha": {
60
+ "yargs": "^18.0.0"
61
+ }
51
62
  },
52
63
  "keywords": [
53
64
  "fake",