@intentius/chant 0.28.0 → 0.29.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.
- package/dist/cli/handlers/components.d.ts.map +1 -1
- package/dist/cli/handlers/graph.d.ts.map +1 -1
- package/dist/cli/handlers/lifecycle.d.ts +5 -3
- package/dist/cli/handlers/lifecycle.d.ts.map +1 -1
- package/dist/config.d.ts +46 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/discovery/fold-import.d.ts +153 -17
- package/dist/discovery/fold-import.d.ts.map +1 -1
- package/dist/discovery/sandbox/config-wire.d.ts +3 -2
- package/dist/discovery/sandbox/config-wire.d.ts.map +1 -1
- package/dist/env.d.ts +5 -2
- package/dist/env.d.ts.map +1 -1
- package/dist/fold/fold.d.ts +12 -0
- package/dist/fold/fold.d.ts.map +1 -1
- package/dist/graph-ir.d.ts +29 -4
- package/dist/graph-ir.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/kubectl-context.d.ts +27 -0
- package/dist/kubectl-context.d.ts.map +1 -1
- package/dist/lexicon.d.ts +31 -6
- package/dist/lexicon.d.ts.map +1 -1
- package/dist/lifecycle/change-set.d.ts +26 -5
- package/dist/lifecycle/change-set.d.ts.map +1 -1
- package/dist/lifecycle/live-diff.d.ts +25 -1
- package/dist/lifecycle/live-diff.d.ts.map +1 -1
- package/dist/lifecycle/observe.d.ts +4 -2
- package/dist/lifecycle/observe.d.ts.map +1 -1
- package/dist/lifecycle/snapshot.d.ts.map +1 -1
- package/dist/lifecycle/status.d.ts +26 -1
- package/dist/lifecycle/status.d.ts.map +1 -1
- package/dist/lifecycle/types.d.ts +8 -0
- package/dist/lifecycle/types.d.ts.map +1 -1
- package/dist/live-endpoint.d.ts +92 -0
- package/dist/live-endpoint.d.ts.map +1 -0
- package/dist/observation.d.ts +123 -0
- package/dist/observation.d.ts.map +1 -0
- package/dist/stack-output.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/cli/handlers/components.test.ts +63 -4
- package/src/cli/handlers/components.ts +78 -35
- package/src/cli/handlers/graph.test.ts +69 -6
- package/src/cli/handlers/graph.ts +61 -27
- package/src/cli/handlers/lifecycle.test.ts +285 -6
- package/src/cli/handlers/lifecycle.ts +297 -185
- package/src/config.test.ts +75 -0
- package/src/config.ts +61 -3
- package/src/discovery/fold-composite.test.ts +594 -0
- package/src/discovery/fold-import.ts +987 -43
- package/src/discovery/sandbox/config-wire.ts +3 -2
- package/src/env.test.ts +12 -0
- package/src/env.ts +12 -4
- package/src/fold/fold.ts +12 -2
- package/src/graph-ir-live.test.ts +28 -1
- package/src/graph-ir.ts +68 -12
- package/src/index.ts +1 -0
- package/src/kubectl-context.ts +81 -0
- package/src/lexicon.ts +41 -6
- package/src/lifecycle/change-set.test.ts +93 -1
- package/src/lifecycle/change-set.ts +65 -13
- package/src/lifecycle/live-diff.test.ts +39 -0
- package/src/lifecycle/live-diff.ts +51 -5
- package/src/lifecycle/observe.test.ts +74 -3
- package/src/lifecycle/observe.ts +82 -22
- package/src/lifecycle/snapshot.test.ts +39 -1
- package/src/lifecycle/snapshot.ts +34 -9
- package/src/lifecycle/status.test.ts +89 -8
- package/src/lifecycle/status.ts +53 -3
- package/src/lifecycle/types.ts +8 -0
- package/src/live-endpoint.test.ts +115 -0
- package/src/live-endpoint.ts +148 -0
- package/src/observation.test.ts +96 -0
- package/src/observation.ts +213 -0
- package/src/stack-output.test.ts +55 -0
- package/src/stack-output.ts +41 -20
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { describe, test, expect, vi, beforeEach } from "vitest";
|
|
1
|
+
import { describe, test, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
2
|
import { sep } from "node:path";
|
|
3
|
-
import { createMockPlugin, staticDescribeResources, staticListArtifacts } from "@intentius/chant-test-utils";
|
|
3
|
+
import { createMockPlugin, staticDescribeResources, staticObservation, staticListArtifacts } from "@intentius/chant-test-utils";
|
|
4
4
|
import type { LexiconPlugin, ResourceMetadata } from "../../lexicon";
|
|
5
5
|
import type { BuildResult } from "../../build";
|
|
6
6
|
import type { ParsedArgs } from "../registry";
|
|
@@ -24,11 +24,15 @@ vi.mock("../../lifecycle/git", () => ({
|
|
|
24
24
|
vi.mock("../../lifecycle/snapshot", () => ({
|
|
25
25
|
takeSnapshot: (...args: unknown[]) => takeSnapshotMock(...args),
|
|
26
26
|
}));
|
|
27
|
-
vi.mock("../../config", () =>
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
vi.mock("../../config", async () => {
|
|
28
|
+
const actual = await vi.importActual<typeof import("../../config")>("../../config");
|
|
29
|
+
return {
|
|
30
|
+
...actual,
|
|
31
|
+
loadChantConfig: (...args: unknown[]) => loadChantConfigMock(...args),
|
|
32
|
+
};
|
|
33
|
+
});
|
|
30
34
|
|
|
31
|
-
const { runLifecycleDiff, runLifecycleSnapshot, runLifecycleShow, runLifecycleLog, runLifecycleUnknown } = await import("./lifecycle");
|
|
35
|
+
const { runLifecycleDiff, runLifecyclePlan, runLifecycleSnapshot, runLifecycleShow, runLifecycleLog, runLifecycleUnknown } = await import("./lifecycle");
|
|
32
36
|
|
|
33
37
|
function makeArgs(overrides: Partial<ParsedArgs>): ParsedArgs {
|
|
34
38
|
return {
|
|
@@ -128,6 +132,64 @@ describe("runLifecycleDiff --live", () => {
|
|
|
128
132
|
expect(output).toContain("UPDATE_COMPLETE");
|
|
129
133
|
});
|
|
130
134
|
|
|
135
|
+
// #1089 — a hole in the read is rendered as a hole, and never silently
|
|
136
|
+
// inflates the missing/drift counts that the all-clear line reads.
|
|
137
|
+
test("renders an UNOBSERVED section and qualifies the all-clear", async () => {
|
|
138
|
+
buildMock.mockResolvedValue(makeBuildResult({ k8s: ["widget"] }));
|
|
139
|
+
fetchLifecycleMock.mockResolvedValue(undefined);
|
|
140
|
+
readSnapshotMock.mockResolvedValue(null);
|
|
141
|
+
|
|
142
|
+
const plugins: LexiconPlugin[] = [
|
|
143
|
+
createMockPlugin({
|
|
144
|
+
name: "k8s",
|
|
145
|
+
describeResources: staticObservation({}, {
|
|
146
|
+
widget: { type: "K8s::X::Widget", reason: "unsupported-kind", detail: "no kubectl mapping" },
|
|
147
|
+
}),
|
|
148
|
+
}),
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
const exit = await runLifecycleDiff({
|
|
152
|
+
args: makeArgs({ path: "diff", extraPositional: "prod", live: true }),
|
|
153
|
+
plugins,
|
|
154
|
+
serializers: plugins.map((p) => p.serializer),
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
expect(exit).toBe(0);
|
|
158
|
+
const stdout = stdoutBuf.join("\n");
|
|
159
|
+
expect(stdout).toContain("UNOBSERVED");
|
|
160
|
+
expect(stdout).toContain("widget");
|
|
161
|
+
expect(stdout).toContain("no reader for this resource kind");
|
|
162
|
+
// Not counted as missing — "declared, not in cloud" is a claim we can't make.
|
|
163
|
+
expect(stdout).toContain("0 missing");
|
|
164
|
+
expect(stderrBuf.join("\n")).toContain("could not be observed");
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
test("a throwing describeResources reports its entities unobserved instead of skipping the lexicon", async () => {
|
|
168
|
+
buildMock.mockResolvedValue(makeBuildResult({ aws: ["bucket"] }));
|
|
169
|
+
fetchLifecycleMock.mockResolvedValue(undefined);
|
|
170
|
+
readSnapshotMock.mockResolvedValue(null);
|
|
171
|
+
|
|
172
|
+
const plugins: LexiconPlugin[] = [
|
|
173
|
+
createMockPlugin({
|
|
174
|
+
name: "aws",
|
|
175
|
+
describeResources: async () => { throw new Error("Unable to locate credentials"); },
|
|
176
|
+
}),
|
|
177
|
+
];
|
|
178
|
+
|
|
179
|
+
const exit = await runLifecycleDiff({
|
|
180
|
+
args: makeArgs({ path: "diff", extraPositional: "prod", live: true }),
|
|
181
|
+
plugins,
|
|
182
|
+
serializers: plugins.map((p) => p.serializer),
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
expect(exit).toBe(0);
|
|
186
|
+
expect(stderrBuf.join("\n")).toContain("not as absent");
|
|
187
|
+
const stdout = stdoutBuf.join("\n");
|
|
188
|
+
expect(stdout).toContain("UNOBSERVED");
|
|
189
|
+
expect(stdout).toContain("bucket");
|
|
190
|
+
expect(stdout).toContain("0 missing");
|
|
191
|
+
});
|
|
192
|
+
|
|
131
193
|
test("builds from config.sourceDir on a mixed-layout project", async () => {
|
|
132
194
|
buildMock.mockResolvedValue(makeBuildResult({ aws: ["bucket"] }));
|
|
133
195
|
fetchLifecycleMock.mockResolvedValue(undefined);
|
|
@@ -289,6 +351,187 @@ describe("runLifecycleDiff --live", () => {
|
|
|
289
351
|
expect(output).toContain("bucket");
|
|
290
352
|
expect(output).toContain("added");
|
|
291
353
|
});
|
|
354
|
+
|
|
355
|
+
// #1166 — an environment can declare its own endpoint (a local emulator like
|
|
356
|
+
// Floci), applied to the ambient var of every observing lexicon that has one
|
|
357
|
+
// unless the ambient shell already set it.
|
|
358
|
+
describe("declared endpoint (#1166)", () => {
|
|
359
|
+
const prevEndpoint = process.env.AWS_ENDPOINT_URL;
|
|
360
|
+
|
|
361
|
+
afterEach(() => {
|
|
362
|
+
if (prevEndpoint === undefined) delete process.env.AWS_ENDPOINT_URL;
|
|
363
|
+
else process.env.AWS_ENDPOINT_URL = prevEndpoint;
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
test("applies the declared endpoint to AWS_ENDPOINT_URL for the live describe, then restores it", async () => {
|
|
367
|
+
delete process.env.AWS_ENDPOINT_URL;
|
|
368
|
+
buildMock.mockResolvedValue(makeBuildResult({ aws: ["bucket"] }));
|
|
369
|
+
fetchLifecycleMock.mockResolvedValue(undefined);
|
|
370
|
+
readSnapshotMock.mockResolvedValue(null);
|
|
371
|
+
loadChantConfigMock.mockResolvedValue({
|
|
372
|
+
config: { environments: [{ name: "floci", endpoint: "http://localhost:4566" }] },
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
let seenDuringDescribe: string | undefined;
|
|
376
|
+
const plugins: LexiconPlugin[] = [
|
|
377
|
+
createMockPlugin({
|
|
378
|
+
name: "aws",
|
|
379
|
+
describeResources: async () => {
|
|
380
|
+
seenDuringDescribe = process.env.AWS_ENDPOINT_URL;
|
|
381
|
+
return {};
|
|
382
|
+
},
|
|
383
|
+
}),
|
|
384
|
+
];
|
|
385
|
+
|
|
386
|
+
const exit = await runLifecycleDiff({
|
|
387
|
+
args: makeArgs({ path: "diff", extraPositional: "floci", live: true }),
|
|
388
|
+
plugins,
|
|
389
|
+
serializers: plugins.map((p) => p.serializer),
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
expect(exit).toBe(0);
|
|
393
|
+
expect(seenDuringDescribe).toBe("http://localhost:4566");
|
|
394
|
+
expect(process.env.AWS_ENDPOINT_URL).toBeUndefined(); // restored
|
|
395
|
+
expect(stderrBuf.join("\n")).toMatch(/environment "floci" declares endpoint http:\/\/localhost:4566/);
|
|
396
|
+
});
|
|
397
|
+
|
|
398
|
+
test("ambient AWS_ENDPOINT_URL still wins over the declared endpoint", async () => {
|
|
399
|
+
process.env.AWS_ENDPOINT_URL = "http://real-endpoint.example";
|
|
400
|
+
buildMock.mockResolvedValue(makeBuildResult({ aws: ["bucket"] }));
|
|
401
|
+
fetchLifecycleMock.mockResolvedValue(undefined);
|
|
402
|
+
readSnapshotMock.mockResolvedValue(null);
|
|
403
|
+
loadChantConfigMock.mockResolvedValue({
|
|
404
|
+
config: { environments: [{ name: "floci", endpoint: "http://localhost:4566" }] },
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
let seenDuringDescribe: string | undefined;
|
|
408
|
+
const plugins: LexiconPlugin[] = [
|
|
409
|
+
createMockPlugin({
|
|
410
|
+
name: "aws",
|
|
411
|
+
describeResources: async () => {
|
|
412
|
+
seenDuringDescribe = process.env.AWS_ENDPOINT_URL;
|
|
413
|
+
return {};
|
|
414
|
+
},
|
|
415
|
+
}),
|
|
416
|
+
];
|
|
417
|
+
|
|
418
|
+
const exit = await runLifecycleDiff({
|
|
419
|
+
args: makeArgs({ path: "diff", extraPositional: "floci", live: true }),
|
|
420
|
+
plugins,
|
|
421
|
+
serializers: plugins.map((p) => p.serializer),
|
|
422
|
+
});
|
|
423
|
+
|
|
424
|
+
expect(exit).toBe(0);
|
|
425
|
+
expect(seenDuringDescribe).toBe("http://real-endpoint.example");
|
|
426
|
+
expect(process.env.AWS_ENDPOINT_URL).toBe("http://real-endpoint.example");
|
|
427
|
+
expect(stderrBuf.join("\n")).toMatch(/ambient AWS_ENDPOINT_URL already set/);
|
|
428
|
+
});
|
|
429
|
+
});
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
describe("runLifecyclePlan", () => {
|
|
433
|
+
let stdoutBuf: string[];
|
|
434
|
+
let stderrBuf: string[];
|
|
435
|
+
|
|
436
|
+
beforeEach(() => {
|
|
437
|
+
stdoutBuf = [];
|
|
438
|
+
stderrBuf = [];
|
|
439
|
+
vi.spyOn(console, "log").mockImplementation((s: string) => { stdoutBuf.push(s); });
|
|
440
|
+
vi.spyOn(console, "error").mockImplementation((s: string) => { stderrBuf.push(s); });
|
|
441
|
+
buildMock.mockReset();
|
|
442
|
+
fetchLifecycleMock.mockReset();
|
|
443
|
+
fetchLifecycleMock.mockResolvedValue(undefined);
|
|
444
|
+
readSnapshotMock.mockReset();
|
|
445
|
+
readSnapshotMock.mockResolvedValue(null);
|
|
446
|
+
loadChantConfigMock.mockReset();
|
|
447
|
+
loadChantConfigMock.mockResolvedValue({ config: {} });
|
|
448
|
+
});
|
|
449
|
+
|
|
450
|
+
test("happy path: proposes a create for a declared, unobserved-nowhere-else entity", async () => {
|
|
451
|
+
buildMock.mockResolvedValue(makeBuildResult({ aws: ["bucket"] }));
|
|
452
|
+
const plugins: LexiconPlugin[] = [
|
|
453
|
+
createMockPlugin({ name: "aws", describeResources: staticDescribeResources({}) }),
|
|
454
|
+
];
|
|
455
|
+
const exit = await runLifecyclePlan({
|
|
456
|
+
args: makeArgs({ path: "plan", extraPositional: "prod" }),
|
|
457
|
+
plugins,
|
|
458
|
+
serializers: plugins.map((p) => p.serializer),
|
|
459
|
+
});
|
|
460
|
+
expect(exit).toBe(0);
|
|
461
|
+
expect(stdoutBuf.join("\n")).toContain("bucket");
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
// #1166 — plan is always a live read (no `--live` flag of its own), so a
|
|
465
|
+
// declared environment endpoint applies here exactly as it does for
|
|
466
|
+
// `chant graph --live` / `chant lifecycle diff --live`.
|
|
467
|
+
describe("declared endpoint (#1166)", () => {
|
|
468
|
+
const prevEndpoint = process.env.AWS_ENDPOINT_URL;
|
|
469
|
+
|
|
470
|
+
afterEach(() => {
|
|
471
|
+
if (prevEndpoint === undefined) delete process.env.AWS_ENDPOINT_URL;
|
|
472
|
+
else process.env.AWS_ENDPOINT_URL = prevEndpoint;
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
test("applies the declared endpoint to AWS_ENDPOINT_URL for the plan's describe, then restores it", async () => {
|
|
476
|
+
delete process.env.AWS_ENDPOINT_URL;
|
|
477
|
+
buildMock.mockResolvedValue(makeBuildResult({ aws: ["bucket"] }));
|
|
478
|
+
loadChantConfigMock.mockResolvedValue({
|
|
479
|
+
config: { environments: [{ name: "floci", endpoint: "http://localhost:4566" }] },
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
let seenDuringDescribe: string | undefined;
|
|
483
|
+
const plugins: LexiconPlugin[] = [
|
|
484
|
+
createMockPlugin({
|
|
485
|
+
name: "aws",
|
|
486
|
+
describeResources: async () => {
|
|
487
|
+
seenDuringDescribe = process.env.AWS_ENDPOINT_URL;
|
|
488
|
+
return {};
|
|
489
|
+
},
|
|
490
|
+
}),
|
|
491
|
+
];
|
|
492
|
+
|
|
493
|
+
const exit = await runLifecyclePlan({
|
|
494
|
+
args: makeArgs({ path: "plan", extraPositional: "floci" }),
|
|
495
|
+
plugins,
|
|
496
|
+
serializers: plugins.map((p) => p.serializer),
|
|
497
|
+
});
|
|
498
|
+
|
|
499
|
+
expect(exit).toBe(0);
|
|
500
|
+
expect(seenDuringDescribe).toBe("http://localhost:4566");
|
|
501
|
+
expect(process.env.AWS_ENDPOINT_URL).toBeUndefined();
|
|
502
|
+
expect(stderrBuf.join("\n")).toMatch(/environment "floci" declares endpoint http:\/\/localhost:4566/);
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
test("ambient AWS_ENDPOINT_URL still wins over the declared endpoint", async () => {
|
|
506
|
+
process.env.AWS_ENDPOINT_URL = "http://real-endpoint.example";
|
|
507
|
+
buildMock.mockResolvedValue(makeBuildResult({ aws: ["bucket"] }));
|
|
508
|
+
loadChantConfigMock.mockResolvedValue({
|
|
509
|
+
config: { environments: [{ name: "floci", endpoint: "http://localhost:4566" }] },
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
let seenDuringDescribe: string | undefined;
|
|
513
|
+
const plugins: LexiconPlugin[] = [
|
|
514
|
+
createMockPlugin({
|
|
515
|
+
name: "aws",
|
|
516
|
+
describeResources: async () => {
|
|
517
|
+
seenDuringDescribe = process.env.AWS_ENDPOINT_URL;
|
|
518
|
+
return {};
|
|
519
|
+
},
|
|
520
|
+
}),
|
|
521
|
+
];
|
|
522
|
+
|
|
523
|
+
const exit = await runLifecyclePlan({
|
|
524
|
+
args: makeArgs({ path: "plan", extraPositional: "floci" }),
|
|
525
|
+
plugins,
|
|
526
|
+
serializers: plugins.map((p) => p.serializer),
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
expect(exit).toBe(0);
|
|
530
|
+
expect(seenDuringDescribe).toBe("http://real-endpoint.example");
|
|
531
|
+
expect(process.env.AWS_ENDPOINT_URL).toBe("http://real-endpoint.example");
|
|
532
|
+
expect(stderrBuf.join("\n")).toMatch(/ambient AWS_ENDPOINT_URL already set/);
|
|
533
|
+
});
|
|
534
|
+
});
|
|
292
535
|
});
|
|
293
536
|
|
|
294
537
|
describe("runLifecycleSnapshot", () => {
|
|
@@ -365,6 +608,42 @@ describe("runLifecycleSnapshot", () => {
|
|
|
365
608
|
expect(stderrBuf.join("\n")).toContain("Snapshot saved");
|
|
366
609
|
expect(takeSnapshotMock).toHaveBeenCalledTimes(1);
|
|
367
610
|
});
|
|
611
|
+
|
|
612
|
+
// #1166 — a snapshot is always a live read, so a declared environment
|
|
613
|
+
// endpoint applies here too, unless the ambient shell already set it.
|
|
614
|
+
describe("declared endpoint (#1166)", () => {
|
|
615
|
+
const prevEndpoint = process.env.AWS_ENDPOINT_URL;
|
|
616
|
+
|
|
617
|
+
afterEach(() => {
|
|
618
|
+
if (prevEndpoint === undefined) delete process.env.AWS_ENDPOINT_URL;
|
|
619
|
+
else process.env.AWS_ENDPOINT_URL = prevEndpoint;
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
test("applies the declared endpoint to AWS_ENDPOINT_URL for takeSnapshot, then restores it", async () => {
|
|
623
|
+
delete process.env.AWS_ENDPOINT_URL;
|
|
624
|
+
buildMock.mockResolvedValue(makeBuildResult({ aws: ["bucket"] }));
|
|
625
|
+
loadChantConfigMock.mockResolvedValue({
|
|
626
|
+
config: { environments: [{ name: "floci", endpoint: "http://localhost:4566" }] },
|
|
627
|
+
});
|
|
628
|
+
let seenDuringSnapshot: string | undefined;
|
|
629
|
+
takeSnapshotMock.mockImplementation(async () => {
|
|
630
|
+
seenDuringSnapshot = process.env.AWS_ENDPOINT_URL;
|
|
631
|
+
return { snapshots: [], commit: "sha", warnings: [], errors: [] };
|
|
632
|
+
});
|
|
633
|
+
const plugins: LexiconPlugin[] = [
|
|
634
|
+
createMockPlugin({ name: "aws", describeResources: staticDescribeResources({}) }),
|
|
635
|
+
];
|
|
636
|
+
const exit = await runLifecycleSnapshot({
|
|
637
|
+
args: makeArgs({ command: "state", path: "snapshot", extraPositional: "floci" }),
|
|
638
|
+
plugins,
|
|
639
|
+
serializers: plugins.map((p) => p.serializer),
|
|
640
|
+
});
|
|
641
|
+
expect(exit).toBe(0);
|
|
642
|
+
expect(seenDuringSnapshot).toBe("http://localhost:4566");
|
|
643
|
+
expect(process.env.AWS_ENDPOINT_URL).toBeUndefined();
|
|
644
|
+
expect(stderrBuf.join("\n")).toMatch(/environment "floci" declares endpoint http:\/\/localhost:4566/);
|
|
645
|
+
});
|
|
646
|
+
});
|
|
368
647
|
});
|
|
369
648
|
|
|
370
649
|
describe("runLifecycleShow", () => {
|