@remit/logger-lambda 0.0.3 → 0.0.5

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remit/logger-lambda",
3
- "version": "0.0.3",
3
+ "version": "0.0.5",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -12,7 +12,8 @@
12
12
  },
13
13
  "scripts": {
14
14
  "test:typecheck": "tsgo --noEmit",
15
- "test": "vitest run",
15
+ "test:run": "node --experimental-test-module-mocks --import tsx --test 'src/**/*.test.ts'",
16
+ "test": "npm run test:typecheck && npm run test:run",
16
17
  "build": "npm run test:typecheck"
17
18
  },
18
19
  "dependencies": {
@@ -20,9 +21,6 @@
20
21
  "@aws-lambda-powertools/metrics": "^2",
21
22
  "@types/aws-lambda": "*"
22
23
  },
23
- "devDependencies": {
24
- "vitest": "*"
25
- },
26
24
  "license": "MIT",
27
25
  "publishConfig": {
28
26
  "access": "public"
@@ -1,51 +1,79 @@
1
+ import assert from "node:assert/strict";
2
+ import { beforeEach, describe, it, mock } from "node:test";
1
3
  import type { Context } from "aws-lambda";
2
- import { beforeEach, describe, expect, it, vi } from "vitest";
3
-
4
- const mockPublishStoredMetrics = vi.fn();
5
- const mockAddMetric = vi.fn();
6
- const mockCaptureColdStartMetric = vi.fn();
7
- const mockAddContext = vi.fn();
8
- const mockLogTrace = vi.fn();
9
- const mockLogDebug = vi.fn();
10
- const mockLogInfo = vi.fn();
11
- const mockLogWarn = vi.fn();
12
- const mockLogError = vi.fn();
13
- const mockLogCritical = vi.fn();
14
- const mockAppendPersistentKeys = vi.fn();
15
- const mockCreateChild = vi.fn();
16
-
17
- vi.mock("@aws-lambda-powertools/metrics", () => {
18
- class MockMetrics {
19
- addMetric = mockAddMetric;
20
- publishStoredMetrics = mockPublishStoredMetrics;
21
- captureColdStartMetric = mockCaptureColdStartMetric;
22
- }
23
-
24
- return {
25
- Metrics: MockMetrics,
26
- MetricUnit: {
27
- Count: "Count",
28
- Milliseconds: "Milliseconds",
29
- },
30
- };
4
+
5
+ const addMetric = mock.fn();
6
+ const publishStoredMetrics = mock.fn();
7
+ const captureColdStartMetric = mock.fn();
8
+ const addContext = mock.fn();
9
+ const logTrace = mock.fn();
10
+ const logDebug = mock.fn();
11
+ const logInfo = mock.fn();
12
+ const logWarn = mock.fn();
13
+ const logError = mock.fn();
14
+ const logCritical = mock.fn();
15
+ const appendPersistentKeys = mock.fn();
16
+
17
+ class MockLogger {
18
+ addContext = addContext;
19
+ trace = logTrace;
20
+ debug = logDebug;
21
+ info = logInfo;
22
+ warn = logWarn;
23
+ error = logError;
24
+ critical = logCritical;
25
+ appendPersistentKeys = appendPersistentKeys;
26
+ createChild = () => createChild();
27
+ }
28
+
29
+ const createChild = mock.fn(() => new MockLogger());
30
+
31
+ class MockMetrics {
32
+ addMetric = addMetric;
33
+ publishStoredMetrics = publishStoredMetrics;
34
+ captureColdStartMetric = captureColdStartMetric;
35
+ }
36
+
37
+ mock.module("@aws-lambda-powertools/logger", {
38
+ namedExports: { Logger: MockLogger },
31
39
  });
32
40
 
33
- vi.mock("@aws-lambda-powertools/logger", () => {
34
- class MockLogger {
35
- addContext = mockAddContext;
36
- trace = mockLogTrace;
37
- debug = mockLogDebug;
38
- info = mockLogInfo;
39
- warn = mockLogWarn;
40
- error = mockLogError;
41
- critical = mockLogCritical;
42
- appendPersistentKeys = mockAppendPersistentKeys;
43
- createChild = mockCreateChild;
44
- }
45
-
46
- return { Logger: MockLogger };
41
+ mock.module("@aws-lambda-powertools/metrics", {
42
+ namedExports: {
43
+ Metrics: MockMetrics,
44
+ MetricUnit: { Count: "Count", Milliseconds: "Milliseconds" },
45
+ },
47
46
  });
48
47
 
48
+ const { createLogger, metrics, withTelemetry } = await import("./logger.js");
49
+ const { Metrics } = await import("@aws-lambda-powertools/metrics");
50
+
51
+ type Recorded = { mock: { calls: { arguments: unknown[] }[] } };
52
+
53
+ const calls = (fn: Recorded): unknown[][] =>
54
+ fn.mock.calls.map((call) => call.arguments);
55
+
56
+ const lastCall = (fn: Recorded): unknown[] => {
57
+ const recorded = calls(fn);
58
+ assert.ok(recorded.length > 0, "expected the mock to have been called");
59
+ return recorded[recorded.length - 1];
60
+ };
61
+
62
+ const recorded = [
63
+ addMetric,
64
+ publishStoredMetrics,
65
+ captureColdStartMetric,
66
+ addContext,
67
+ logTrace,
68
+ logDebug,
69
+ logInfo,
70
+ logWarn,
71
+ logError,
72
+ logCritical,
73
+ appendPersistentKeys,
74
+ createChild,
75
+ ];
76
+
49
77
  const makeContext = (): Context =>
50
78
  ({
51
79
  awsRequestId: "test-request-id",
@@ -57,140 +85,118 @@ const makeContext = (): Context =>
57
85
  getRemainingTimeInMillis: () => 30000,
58
86
  callbackWaitsForEmptyEventLoop: false,
59
87
  functionVersion: "$LATEST",
60
- done: vi.fn(),
61
- fail: vi.fn(),
62
- succeed: vi.fn(),
88
+ done: () => {},
89
+ fail: () => {},
90
+ succeed: () => {},
63
91
  }) as unknown as Context;
64
92
 
65
93
  describe("remit-logger-lambda", () => {
66
94
  beforeEach(() => {
67
- vi.clearAllMocks();
68
- mockCreateChild.mockImplementation(() => {
69
- const child = {
70
- trace: mockLogTrace,
71
- debug: mockLogDebug,
72
- info: mockLogInfo,
73
- warn: mockLogWarn,
74
- error: mockLogError,
75
- critical: mockLogCritical,
76
- appendPersistentKeys: mockAppendPersistentKeys,
77
- createChild: mockCreateChild,
78
- };
79
- return child;
80
- });
95
+ for (const fn of recorded) fn.mock.resetCalls();
81
96
  });
82
97
 
83
- it("exports metrics as a Metrics instance", async () => {
84
- const { metrics } = await import("./logger.js");
85
- const { Metrics } = await import("@aws-lambda-powertools/metrics");
86
- expect(metrics).toBeInstanceOf(Metrics);
98
+ it("exports metrics as a Metrics instance", () => {
99
+ assert.ok(metrics instanceof Metrics);
87
100
  });
88
101
 
89
- it("object-first call maps to Powertools message + attributes", async () => {
90
- const { createLogger } = await import("./logger.js");
102
+ it("object-first call maps to Powertools message + attributes", () => {
91
103
  const log = createLogger(makeContext());
92
104
  log.error({ error: "boom", messageId: "m1" }, "Failed to parse message");
93
- expect(mockLogError).toHaveBeenCalledWith("Failed to parse message", {
94
- error: "boom",
95
- messageId: "m1",
96
- });
105
+ assert.deepEqual(lastCall(logError), [
106
+ "Failed to parse message",
107
+ { error: "boom", messageId: "m1" },
108
+ ]);
97
109
  });
98
110
 
99
- it("object-first call without message uses empty string", async () => {
100
- const { createLogger } = await import("./logger.js");
111
+ it("object-first call without message uses empty string", () => {
101
112
  const log = createLogger();
102
113
  log.info({ count: 3 });
103
- expect(mockLogInfo).toHaveBeenCalledWith("", { count: 3 });
114
+ assert.deepEqual(lastCall(logInfo), ["", { count: 3 }]);
104
115
  });
105
116
 
106
- it("string-first call passes message then attributes", async () => {
107
- const { createLogger } = await import("./logger.js");
117
+ it("string-first call passes message then attributes", () => {
108
118
  const log = createLogger();
109
119
  log.warn("watch out", { reason: "slow" });
110
- expect(mockLogWarn).toHaveBeenCalledWith("watch out", { reason: "slow" });
120
+ assert.deepEqual(lastCall(logWarn), ["watch out", { reason: "slow" }]);
111
121
  });
112
122
 
113
- it("string-first call without attributes passes only the message", async () => {
114
- const { createLogger } = await import("./logger.js");
123
+ it("string-first call without attributes passes only the message", () => {
115
124
  const log = createLogger();
116
125
  log.debug("hello");
117
- expect(mockLogDebug).toHaveBeenCalledWith("hello");
126
+ assert.deepEqual(lastCall(logDebug), ["hello"]);
118
127
  });
119
128
 
120
- it("fatal maps to Powertools critical", async () => {
121
- const { createLogger } = await import("./logger.js");
129
+ it("fatal maps to Powertools critical", () => {
122
130
  const log = createLogger();
123
131
  log.fatal({ fatal: true }, "the end");
124
- expect(mockLogCritical).toHaveBeenCalledWith("the end", { fatal: true });
132
+ assert.deepEqual(lastCall(logCritical), ["the end", { fatal: true }]);
125
133
  });
126
134
 
127
- it("trace maps to Powertools trace", async () => {
128
- const { createLogger } = await import("./logger.js");
135
+ it("trace maps to Powertools trace", () => {
129
136
  const log = createLogger();
130
137
  log.trace("trace me");
131
- expect(mockLogTrace).toHaveBeenCalledWith("trace me");
138
+ assert.deepEqual(lastCall(logTrace), ["trace me"]);
132
139
  });
133
140
 
134
- it("child creates a Powertools child and appends bindings", async () => {
135
- const { createLogger } = await import("./logger.js");
141
+ it("child creates a Powertools child and appends bindings", () => {
136
142
  const log = createLogger();
137
143
  const child = log.child({ queue: "imap" });
138
- expect(mockCreateChild).toHaveBeenCalledOnce();
139
- expect(mockAppendPersistentKeys).toHaveBeenCalledWith({ queue: "imap" });
144
+ assert.equal(calls(createChild).length, 1);
145
+ assert.deepEqual(lastCall(appendPersistentKeys), [{ queue: "imap" }]);
140
146
  child.info({ done: true }, "child log");
141
- expect(mockLogInfo).toHaveBeenCalledWith("child log", { done: true });
147
+ assert.deepEqual(lastCall(logInfo), ["child log", { done: true }]);
142
148
  });
143
149
 
144
- it("setBindings appends persistent keys", async () => {
145
- const { createLogger } = await import("./logger.js");
150
+ it("setBindings appends persistent keys", () => {
146
151
  const log = createLogger();
147
152
  log.setBindings({ requestId: "r1" });
148
- expect(mockAppendPersistentKeys).toHaveBeenCalledWith({ requestId: "r1" });
153
+ assert.deepEqual(lastCall(appendPersistentKeys), [{ requestId: "r1" }]);
149
154
  });
150
155
 
151
156
  it("withTelemetry calls the handler and returns its result", async () => {
152
- const { withTelemetry } = await import("./logger.js");
153
- const handler = vi.fn().mockResolvedValue("hello");
157
+ const handler = mock.fn(async () => "hello");
154
158
  const wrapped = withTelemetry(handler);
155
159
  const result = await wrapped({ key: "value" }, makeContext());
156
- expect(result).toBe("hello");
157
- expect(handler).toHaveBeenCalledOnce();
160
+ assert.equal(result, "hello");
161
+ assert.equal(calls(handler).length, 1);
158
162
  });
159
163
 
160
164
  it("withTelemetry re-throws handler errors", async () => {
161
- const { withTelemetry } = await import("./logger.js");
162
- const boom = new Error("boom");
163
- const handler = vi.fn().mockRejectedValue(boom);
165
+ const handler = mock.fn(async () => {
166
+ throw new Error("boom");
167
+ });
164
168
  const wrapped = withTelemetry(handler);
165
- await expect(wrapped({}, makeContext())).rejects.toThrow("boom");
169
+ await assert.rejects(wrapped({}, makeContext()), /boom/);
166
170
  });
167
171
 
168
172
  it("withTelemetry publishes metrics in finally even on error", async () => {
169
- const { withTelemetry } = await import("./logger.js");
170
- const handler = vi.fn().mockRejectedValue(new Error("fail"));
173
+ const handler = mock.fn(async () => {
174
+ throw new Error("fail");
175
+ });
171
176
  const wrapped = withTelemetry(handler);
172
- await expect(wrapped({}, makeContext())).rejects.toThrow();
173
- expect(mockPublishStoredMetrics).toHaveBeenCalled();
177
+ await assert.rejects(wrapped({}, makeContext()));
178
+ assert.ok(calls(publishStoredMetrics).length > 0);
174
179
  });
175
180
 
176
181
  it("withTelemetry emits errorCount on handler failure", async () => {
177
- const { withTelemetry } = await import("./logger.js");
178
- const handler = vi.fn().mockRejectedValue(new Error("fail"));
182
+ const handler = mock.fn(async () => {
183
+ throw new Error("fail");
184
+ });
179
185
  const wrapped = withTelemetry(handler);
180
- await expect(wrapped({}, makeContext())).rejects.toThrow();
181
- expect(mockAddMetric).toHaveBeenCalledWith("errorCount", "Count", 1);
186
+ await assert.rejects(wrapped({}, makeContext()));
187
+ assert.deepEqual(calls(addMetric), [["errorCount", "Count", 1]]);
182
188
  });
183
189
 
184
190
  it("withTelemetry emits invocationCount and invocationLatency on success", async () => {
185
- const { withTelemetry } = await import("./logger.js");
186
- const handler = vi.fn().mockResolvedValue(42);
191
+ const handler = mock.fn(async () => 42);
187
192
  const wrapped = withTelemetry(handler);
188
193
  await wrapped({}, makeContext());
189
- expect(mockAddMetric).toHaveBeenCalledWith("invocationCount", "Count", 1);
190
- expect(mockAddMetric).toHaveBeenCalledWith(
194
+ const [countCall, latencyCall] = calls(addMetric);
195
+ assert.deepEqual(countCall, ["invocationCount", "Count", 1]);
196
+ assert.deepEqual(latencyCall.slice(0, 2), [
191
197
  "invocationLatency",
192
198
  "Milliseconds",
193
- expect.any(Number),
194
- );
199
+ ]);
200
+ assert.equal(typeof latencyCall[2], "number");
195
201
  });
196
202
  });
package/vitest.config.ts DELETED
@@ -1,3 +0,0 @@
1
- import { defineConfig } from "vitest/config";
2
-
3
- export default defineConfig({ test: { environment: "node" } });