jobarbiter 0.3.0 → 0.3.2
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/index.js +172 -43
- package/dist/lib/config.js +1 -1
- package/dist/lib/detect-tools.d.ts +46 -0
- package/dist/lib/detect-tools.js +473 -0
- package/dist/lib/observe.d.ts +52 -0
- package/dist/lib/observe.js +672 -0
- package/dist/lib/onboard.d.ts +13 -0
- package/dist/lib/onboard.js +580 -0
- package/package.json +15 -5
- package/src/index.ts +194 -48
- package/src/lib/config.ts +1 -1
- package/src/lib/detect-tools.ts +526 -0
- package/src/lib/observe.ts +753 -0
- package/src/lib/onboard.ts +694 -0
- package/test/smoke.test.ts +205 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI Smoke Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests that run the actual CLI binary to verify:
|
|
5
|
+
* - Basic commands work
|
|
6
|
+
* - Help and version output correctly
|
|
7
|
+
* - JSON output is valid
|
|
8
|
+
* - Error messages are clean
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { describe, it, expect, beforeAll } from "vitest";
|
|
12
|
+
import { execSync, ExecSyncOptionsWithStringEncoding } from "node:child_process";
|
|
13
|
+
import { existsSync } from "node:fs";
|
|
14
|
+
import { join } from "node:path";
|
|
15
|
+
|
|
16
|
+
// Path to the built CLI
|
|
17
|
+
const CLI_DIR = join(__dirname, "..");
|
|
18
|
+
const CLI_PATH = join(CLI_DIR, "dist", "index.js");
|
|
19
|
+
|
|
20
|
+
// Exec options
|
|
21
|
+
const execOpts: ExecSyncOptionsWithStringEncoding = {
|
|
22
|
+
encoding: "utf8",
|
|
23
|
+
cwd: CLI_DIR,
|
|
24
|
+
timeout: 30000,
|
|
25
|
+
env: {
|
|
26
|
+
...process.env,
|
|
27
|
+
// Ensure we don't use any existing config during tests
|
|
28
|
+
JOBARBITER_API_KEY: "",
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Run a CLI command and return the result
|
|
34
|
+
*/
|
|
35
|
+
function cli(args: string): { stdout: string; exitCode: number } {
|
|
36
|
+
try {
|
|
37
|
+
const stdout = execSync(`node ${CLI_PATH} ${args}`, execOpts);
|
|
38
|
+
return { stdout, exitCode: 0 };
|
|
39
|
+
} catch (err: unknown) {
|
|
40
|
+
const error = err as { stdout?: string; stderr?: string; status?: number };
|
|
41
|
+
// Command failed, but we still want to check the output
|
|
42
|
+
return {
|
|
43
|
+
stdout: error.stdout || error.stderr || "",
|
|
44
|
+
exitCode: error.status || 1,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Check if the CLI has been built
|
|
51
|
+
*/
|
|
52
|
+
function isBuilt(): boolean {
|
|
53
|
+
return existsSync(CLI_PATH);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
describe("CLI Build", () => {
|
|
57
|
+
it("CLI binary exists (npm run build was run)", () => {
|
|
58
|
+
if (!isBuilt()) {
|
|
59
|
+
console.warn("CLI not built - run `npm run build` in cli directory first");
|
|
60
|
+
}
|
|
61
|
+
// Don't fail the test if not built, just skip
|
|
62
|
+
expect(true).toBe(true);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe("CLI Help Commands", () => {
|
|
67
|
+
beforeAll(() => {
|
|
68
|
+
if (!isBuilt()) {
|
|
69
|
+
console.warn("Skipping CLI tests - binary not built");
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it("jobarbiter --help exits 0 and shows usage", () => {
|
|
74
|
+
if (!isBuilt()) return;
|
|
75
|
+
|
|
76
|
+
const { stdout, exitCode } = cli("--help");
|
|
77
|
+
|
|
78
|
+
expect(exitCode).toBe(0);
|
|
79
|
+
expect(stdout).toContain("JobArbiter");
|
|
80
|
+
expect(stdout).toContain("onboard");
|
|
81
|
+
expect(stdout).toContain("--help");
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("jobarbiter --version exits 0 and shows version", () => {
|
|
85
|
+
if (!isBuilt()) return;
|
|
86
|
+
|
|
87
|
+
const { stdout, exitCode } = cli("--version");
|
|
88
|
+
|
|
89
|
+
expect(exitCode).toBe(0);
|
|
90
|
+
// Should contain a version number like "0.3.0"
|
|
91
|
+
expect(stdout).toMatch(/\d+\.\d+\.\d+/);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("jobarbiter onboard --help shows onboard description", () => {
|
|
95
|
+
if (!isBuilt()) return;
|
|
96
|
+
|
|
97
|
+
const { stdout, exitCode } = cli("onboard --help");
|
|
98
|
+
|
|
99
|
+
expect(exitCode).toBe(0);
|
|
100
|
+
expect(stdout).toContain("onboard");
|
|
101
|
+
expect(stdout.toLowerCase()).toContain("wizard");
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("jobarbiter profile --help shows profile commands", () => {
|
|
105
|
+
if (!isBuilt()) return;
|
|
106
|
+
|
|
107
|
+
const { stdout, exitCode } = cli("profile --help");
|
|
108
|
+
|
|
109
|
+
expect(exitCode).toBe(0);
|
|
110
|
+
expect(stdout).toContain("profile");
|
|
111
|
+
expect(stdout).toContain("show");
|
|
112
|
+
expect(stdout).toContain("create");
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
describe("CLI Status Command", () => {
|
|
117
|
+
beforeAll(() => {
|
|
118
|
+
if (!isBuilt()) {
|
|
119
|
+
console.warn("Skipping CLI tests - binary not built");
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it("jobarbiter status --json returns valid JSON or clean error", () => {
|
|
124
|
+
if (!isBuilt()) return;
|
|
125
|
+
|
|
126
|
+
const { stdout, exitCode } = cli("status --json");
|
|
127
|
+
|
|
128
|
+
if (exitCode === 0) {
|
|
129
|
+
// If successful, should be valid JSON
|
|
130
|
+
expect(() => JSON.parse(stdout)).not.toThrow();
|
|
131
|
+
const data = JSON.parse(stdout);
|
|
132
|
+
expect(data).toBeDefined();
|
|
133
|
+
} else {
|
|
134
|
+
// If failed (no config), should have clean error message
|
|
135
|
+
// The error might be on stderr which gets merged into stdout
|
|
136
|
+
expect(stdout.length).toBeGreaterThan(0);
|
|
137
|
+
// Should not have a stack trace (clean error)
|
|
138
|
+
expect(stdout).not.toContain("at Object.");
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe("CLI Profile Commands", () => {
|
|
144
|
+
beforeAll(() => {
|
|
145
|
+
if (!isBuilt()) {
|
|
146
|
+
console.warn("Skipping CLI tests - binary not built");
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("jobarbiter profile show --json returns JSON or clean error", () => {
|
|
151
|
+
if (!isBuilt()) return;
|
|
152
|
+
|
|
153
|
+
const { stdout, exitCode } = cli("profile show --json");
|
|
154
|
+
|
|
155
|
+
if (exitCode === 0) {
|
|
156
|
+
// If successful, should be valid JSON
|
|
157
|
+
expect(() => JSON.parse(stdout)).not.toThrow();
|
|
158
|
+
} else {
|
|
159
|
+
// If failed (not configured), should be clean
|
|
160
|
+
expect(stdout).not.toContain("Error: ");
|
|
161
|
+
expect(stdout).not.toContain("at Object.");
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
describe("CLI Unknown Commands", () => {
|
|
167
|
+
beforeAll(() => {
|
|
168
|
+
if (!isBuilt()) {
|
|
169
|
+
console.warn("Skipping CLI tests - binary not built");
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it("Unknown command shows help or error", () => {
|
|
174
|
+
if (!isBuilt()) return;
|
|
175
|
+
|
|
176
|
+
const { stdout, exitCode } = cli("unknowncommand");
|
|
177
|
+
|
|
178
|
+
// Commander should show help or error for unknown commands
|
|
179
|
+
expect(exitCode).not.toBe(0);
|
|
180
|
+
// Output should mention help or unknown
|
|
181
|
+
const hasHelpInfo =
|
|
182
|
+
stdout.includes("--help") ||
|
|
183
|
+
stdout.includes("unknown") ||
|
|
184
|
+
stdout.includes("error");
|
|
185
|
+
expect(hasHelpInfo).toBe(true);
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
describe("CLI Error Handling", () => {
|
|
190
|
+
beforeAll(() => {
|
|
191
|
+
if (!isBuilt()) {
|
|
192
|
+
console.warn("Skipping CLI tests - binary not built");
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it("Missing required options show clean error", () => {
|
|
197
|
+
if (!isBuilt()) return;
|
|
198
|
+
|
|
199
|
+
// verify-email requires --email
|
|
200
|
+
const { stdout, exitCode } = cli("verify-email");
|
|
201
|
+
|
|
202
|
+
expect(exitCode).not.toBe(0);
|
|
203
|
+
expect(stdout).toContain("email");
|
|
204
|
+
});
|
|
205
|
+
});
|