@cosmicdrift/kumiko-testing 0.350.0 → 0.351.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.
@@ -19,8 +19,13 @@ const USAGE = `kumiko-testing <command>
19
19
  integration [--parallel N] run every *.integration.test.ts under the cwd,
20
20
  [--timings <file>] [--update-timings] or only the given file(s) when passed
21
21
  [file...] as positional args
22
+ -h, --help print this help (also works after a command)
22
23
  `;
23
24
 
25
+ function isHelpFlag(arg: string | undefined): boolean {
26
+ return arg === "--help" || arg === "-h";
27
+ }
28
+
24
29
  function runBunfig(args: readonly string[]): number {
25
30
  const { values } = parseArgs({
26
31
  args: [...args],
@@ -99,6 +104,10 @@ async function runIntegration(args: readonly string[]): Promise<number> {
99
104
  }
100
105
 
101
106
  const [command, ...rest] = process.argv.slice(2);
107
+ if (isHelpFlag(command) || rest.some(isHelpFlag)) {
108
+ console.log(USAGE);
109
+ process.exit(0);
110
+ }
102
111
  if (command === "bunfig") process.exit(runBunfig(rest));
103
112
  if (command === "integration") process.exit(await runIntegration(rest));
104
113
  console.error(USAGE);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosmicdrift/kumiko-testing",
3
- "version": "0.350.0",
3
+ "version": "0.351.0",
4
4
  "description": "Test template for Kumiko apps: per-flow seedTenant, app test stack, canonical test preloads, bunfig generator and integration runner.",
5
5
  "license": "BUSL-1.1",
6
6
  "author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
@@ -75,9 +75,9 @@
75
75
  "kumiko-testing": "./bin/kumiko-testing.ts"
76
76
  },
77
77
  "dependencies": {
78
- "@cosmicdrift/kumiko-bundled-features": "0.350.0",
79
- "@cosmicdrift/kumiko-dev-server": "0.350.0",
80
- "@cosmicdrift/kumiko-framework": "0.350.0",
78
+ "@cosmicdrift/kumiko-bundled-features": "0.351.0",
79
+ "@cosmicdrift/kumiko-dev-server": "0.351.0",
80
+ "@cosmicdrift/kumiko-framework": "0.351.0",
81
81
  "zod": "^4.4.3"
82
82
  },
83
83
  "peerDependencies": {
@@ -115,6 +115,7 @@
115
115
  "bin",
116
116
  "!src/**/__tests__/**",
117
117
  "README.md",
118
- "LICENSE"
118
+ "LICENSE",
119
+ "!bin/__tests__/**"
119
120
  ]
120
121
  }
package/src/changes.json CHANGED
@@ -1,4 +1,10 @@
1
1
  [
2
+ {
3
+ "version": "0.351.0",
4
+ "type": "improvement",
5
+ "title": "CapturedMail.text in the e2e seed route carries the mail's plain-text part",
6
+ "detail": "The e2e seed route returns the plain-text part of captured mails\n`CapturedMail` in the seed contract has an optional `text`, filled from the mail's text part, so e2e flows can assert on it."
7
+ },
2
8
  {
3
9
  "version": "0.345.0",
4
10
  "type": "improvement",
@@ -89,6 +89,7 @@ const capturedMailSchema = z.object({
89
89
  to: z.string(),
90
90
  subject: z.string(),
91
91
  html: z.string(),
92
+ text: z.string().optional(),
92
93
  from: z.string().optional(),
93
94
  fromName: z.string().optional(),
94
95
  replyTo: z.string().optional(),
@@ -145,6 +145,7 @@ function toCapturedMail(message: EmailMessage): CapturedMail {
145
145
  to: message.to,
146
146
  subject: message.subject,
147
147
  html: message.html,
148
+ ...(message.text !== undefined ? { text: message.text } : {}),
148
149
  ...(message.from !== undefined ? { from: message.from } : {}),
149
150
  ...(message.fromName !== undefined ? { fromName: message.fromName } : {}),
150
151
  ...(message.replyTo !== undefined ? { replyTo: message.replyTo } : {}),
@@ -1,76 +0,0 @@
1
- // kumiko-framework#3120: `kumiko-testing bunfig` used to overwrite an
2
- // existing bunfig.toml unconditionally, silently dropping app-owned sections
3
- // (e.g. `[install.scopes]` with a private-registry token) and unmanaged keys
4
- // (e.g. `concurrency`) alike. Foreign sections now merge back in verbatim;
5
- // only an unmanaged key inside a *managed* section still blocks the write.
6
-
7
- import { describe, expect, test } from "bun:test";
8
- import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
9
- import { tmpdir } from "node:os";
10
- import { join } from "node:path";
11
-
12
- const CLI_PATH = join(import.meta.dir, "..", "kumiko-testing.ts");
13
-
14
- async function runCli(args: string[], cwd: string) {
15
- const proc = Bun.spawn(["bun", CLI_PATH, ...args], { cwd, stdout: "pipe", stderr: "pipe" });
16
- const [stdout, stderr, exitCode] = await Promise.all([
17
- new Response(proc.stdout).text(),
18
- new Response(proc.stderr).text(),
19
- proc.exited,
20
- ]);
21
- return { stdout, stderr, exitCode };
22
- }
23
-
24
- describe("kumiko-testing bunfig — existing file with a foreign section", () => {
25
- test("merges [install.scopes] back in instead of dropping it", async () => {
26
- const dir = mkdtempSync(join(tmpdir(), "kumiko-testing-bunfig-"));
27
- try {
28
- const existing =
29
- '[install.scopes]\n"@cosmicdriftgamestudio" = { token = "$GITHUB_TOKEN" }\n\n[test]\npreload = []\n';
30
- writeFileSync(join(dir, "bunfig.toml"), existing);
31
-
32
- const { exitCode } = await runCli(["bunfig"], dir);
33
-
34
- expect(exitCode).toBe(0);
35
- const written = readFileSync(join(dir, "bunfig.toml"), "utf-8");
36
- expect(written).toContain("Generated by kumiko-testing");
37
- expect(written).toContain(
38
- '[install.scopes]\n"@cosmicdriftgamestudio" = { token = "$GITHUB_TOKEN" }',
39
- );
40
- } finally {
41
- rmSync(dir, { recursive: true, force: true });
42
- }
43
- });
44
-
45
- test("aborts and names an unmanaged key inside [test], leaves the file untouched", async () => {
46
- const dir = mkdtempSync(join(tmpdir(), "kumiko-testing-bunfig-"));
47
- try {
48
- const existing = "[test]\nconcurrency = 8\npreload = []\n";
49
- writeFileSync(join(dir, "bunfig.toml"), existing);
50
-
51
- const { exitCode, stderr } = await runCli(["bunfig"], dir);
52
-
53
- expect(exitCode).toBe(1);
54
- expect(stderr).toContain("test.concurrency");
55
- expect(readFileSync(join(dir, "bunfig.toml"), "utf-8")).toBe(existing);
56
- } finally {
57
- rmSync(dir, { recursive: true, force: true });
58
- }
59
- });
60
-
61
- test("regenerates a file with no foreign sections and no unmanaged keys", async () => {
62
- const dir = mkdtempSync(join(tmpdir(), "kumiko-testing-bunfig-"));
63
- try {
64
- writeFileSync(join(dir, "bunfig.toml"), "[test]\npreload = []\n");
65
-
66
- const { exitCode } = await runCli(["bunfig"], dir);
67
-
68
- expect(exitCode).toBe(0);
69
- expect(readFileSync(join(dir, "bunfig.toml"), "utf-8")).toContain(
70
- "Generated by kumiko-testing",
71
- );
72
- } finally {
73
- rmSync(dir, { recursive: true, force: true });
74
- }
75
- });
76
- });