Skip to content

Commit

Permalink
chore(compas): add cli test setup
Browse files Browse the repository at this point in the history
- Handles persisted directories in between test runs. Should improve debuggability icm with the `--debug` flag
- Supports sending inputs
- Collects the resulting stdout to match on.
- Feels somewhat overkill to snapshot output + directory state for now. May do that at some point.
  • Loading branch information
dirkdev98 committed Sep 6, 2023
1 parent 99ba21e commit 26a8c52
Show file tree
Hide file tree
Showing 7 changed files with 658 additions and 10 deletions.
6 changes: 1 addition & 5 deletions packages/compas/src/main/development/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,10 @@ export class State {
new ActionsIntegration(this),
new PackageManagerIntegration(this),

// Should be the last integration
// Should be the last integration, since it will
new FileWatcherIntegration(this),
];

// TODO: Package install command

// TODO: package install

// Init and add to state
for (const integration of integrations) {
await integration.init();
Expand Down
15 changes: 12 additions & 3 deletions packages/compas/src/main/init/compas.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { existsSync } from "node:fs";
import { readFile } from "node:fs/promises";
import { exec, spawn } from "@compas/stdlib";
import { environment, exec, spawn } from "@compas/stdlib";
import { writeFileChecked } from "../../shared/fs.js";
import { logger } from "../../shared/output.js";
import { packageManagerDetermine } from "../../shared/package-manager.js";
Expand Down Expand Up @@ -84,7 +84,6 @@ async function initCompasInNewProject(env) {
version: "0.0.1",
type: "module",
scripts: {},
keywords: [],
dependencies: {
compas: compasVersion,
},
Expand Down Expand Up @@ -136,7 +135,17 @@ coverage
await exec("git init");
await exec("git checkout -b main");
await exec("git add -A");
await exec(`git commit -m "Initialized project with ${env.compasVersion}"`);

if (environment._COMPAS_SKIP_COMMIT_SIGN === "true") {
// Test purposes
await exec(
`git commit -c commit.gpgsign=false -m "Initialized project with ${env.compasVersion}"`,
);
} else {
await exec(
`git commit -m "Initialized project with ${env.compasVersion}"`,
);
}
}

logger.info(`
Expand Down
11 changes: 9 additions & 2 deletions packages/compas/src/shared/package-manager.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { existsSync } from "node:fs";
import { pathJoin } from "@compas/stdlib";
import { environment, pathJoin } from "@compas/stdlib";

export const PACKAGE_MANAGER_LOCK_FILES = [
"bun.lockb",
Expand All @@ -21,7 +21,14 @@ export const PACKAGE_MANAGER_LOCK_FILES = [
* }}
*/
export function packageManagerDetermine(rootDirectory = "") {
if (existsSync(pathJoin(rootDirectory, "bun.lockb"))) {
if (environment._COMPAS_SKIP_PACKAGE_MANAGER === "true") {
return {
name: "_compas_skip_package_manager",
installCommand: "echo '_compas_skip_package_manager_install'",
nodeModulesBinCommand: "echo '_compas_skip_package_manager_bin'",
packageJsonScriptCommand: "echo '_compas_skip_package_manager_script'",
};
} else if (existsSync(pathJoin(rootDirectory, "bun.lockb"))) {
return {
name: "bun",
installCommand: "bun install",
Expand Down
73 changes: 73 additions & 0 deletions packages/compas/test/cli.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { existsSync } from "node:fs";
import { readdir } from "node:fs/promises";
import { mainTestFn, test } from "@compas/cli";
import { pathJoin } from "@compas/stdlib";
import { testCompasCli, testDirectory } from "./utils.js";

mainTestFn(import.meta);

test("compas/cli", (t) => {
t.jobs = 4;

const workingDirectory = testDirectory(t.name);

t.test("does not create a debug file without --debug", async (t) => {
const cwd = workingDirectory("no-debug");

await testCompasCli({
args: ["foo"],
inputs: [],
waitForExit: true,
cwd,
});

t.equal(existsSync(pathJoin(cwd, ".cache/compas")), false);
});

t.test("creates a debug file with --debug", async (t) => {
const cwd = workingDirectory("with-debug");

await testCompasCli({
args: ["foo", "--debug"],
inputs: [],
waitForExit: true,
cwd,
});

t.equal(existsSync(pathJoin(cwd, ".cache/compas")), true);
t.equal(
(await readdir(pathJoin(cwd, ".cache/compas"), {})).some(
(it) => it.startsWith("debug-") && it.endsWith(".txt"),
),
true,
);
});

t.test("package.json is not available", async (t) => {
const cwd = workingDirectory("no-package-json");

const { stdout } = await testCompasCli({
args: [],
inputs: [],
waitForExit: true,
cwd,
});

t.ok(
stdout.includes("Please run 'npx compas@latest init' to install Compas."),
);
});

t.test("unsupported command", async (t) => {
const cwd = workingDirectory("unknown-command");

const { stdout } = await testCompasCli({
args: ["foo"],
inputs: [],
waitForExit: true,
cwd,
});

t.ok(stdout.includes(`Unsupported command. Available commands:`));
});
});
242 changes: 242 additions & 0 deletions packages/compas/test/commands/init.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
import { existsSync } from "node:fs";
import { mkdir, readdir, readFile } from "node:fs/promises";
import { mainTestFn, test } from "@compas/cli";
import { dirnameForModule, pathJoin } from "@compas/stdlib";
import { writeFileChecked } from "../../src/shared/fs.js";
import { testCompasCli, testDirectory } from "../utils.js";

mainTestFn(import.meta);

test("compas/commands/init", (t) => {
t.jobs = 4;

const workingDirectory = testDirectory(t.name);

t.test("exits in CI mode", async (t) => {
const cwd = workingDirectory("no-ci");

const { stdout } = await testCompasCli({
args: ["init"],
inputs: [],
waitForExit: true,
cwd,
env: {
...process.env,
CI: "true",
},
});

t.ok(stdout.includes("'compas init' is not supported in CI."));
});

t.test("new project", async (t) => {
const cwd = workingDirectory("new-project");

const { stdout } = await testCompasCli({
args: ["init"],
inputs: [],
waitForExit: true,
cwd,
});

// Package.json
t.ok(
existsSync(pathJoin(cwd, "package.json")),
"Should create a package.json",
);
t.deepEqual(
JSON.parse(await readFile(pathJoin(cwd, "package.json"), "utf-8")),
{
name: "new-project",
private: true,
version: "0.0.1",
type: "module",
scripts: {},
dependencies: {
compas: JSON.parse(
await readFile(
pathJoin(dirnameForModule(import.meta), "../../package.json"),
"utf-8",
),
).version,
},
},
);

// Package manager
t.ok(stdout.includes("_compas_skip_package_manager_install"));

// Git
t.ok(
existsSync(pathJoin(cwd, ".gitignore")),
".gitignore should've been created",
);
t.ok(existsSync(pathJoin(cwd, ".git")), "Git repo should've been created");

// Output
t.ok(stdout.includes("'npx compas'"));
});

t.test("new project - already .git", async (t) => {
const cwd = workingDirectory("new-project-already-git");

await mkdir(pathJoin(cwd, ".git"));

const { stdout } = await testCompasCli({
args: ["init"],
inputs: [],
waitForExit: true,
cwd,
});

// Package.json
t.ok(
existsSync(pathJoin(cwd, "package.json")),
"Should create a package.json",
);

// Package manager
t.ok(stdout.includes("_compas_skip_package_manager_install"));

// Git
t.ok(
existsSync(pathJoin(cwd, ".gitignore")),
".gitignore should've been created",
);
t.equal(
(await readdir(pathJoin(cwd, ".git"))).length,
0,
".git directory should be empty",
);

// Output
t.ok(stdout.includes("'npx compas'"));
});

t.test("exiting project - no dependencies", async (t) => {
const cwd = workingDirectory("existing-project-no-deps");

await writeFileChecked(pathJoin(cwd, "package.json"), "{}");

const { stdout } = await testCompasCli({
args: ["init"],
inputs: [],
waitForExit: true,
cwd,
});

// Package.json

t.deepEqual(
JSON.parse(await readFile(pathJoin(cwd, "package.json"), "utf-8")),
{
dependencies: {
compas: JSON.parse(
await readFile(
pathJoin(dirnameForModule(import.meta), "../../package.json"),
"utf-8",
),
).version,
},
},
);

// Package manager
t.ok(stdout.includes("Patching package.json"));
t.ok(stdout.includes("_compas_skip_package_manager_install"));

// Output
t.ok(stdout.includes("Ready to roll!"));
});

t.test("exiting project - no update", async (t) => {
const cwd = workingDirectory("existing-project-no-update");

await writeFileChecked(
pathJoin(cwd, "package.json"),
JSON.stringify({
dependencies: {
compas: JSON.parse(
await readFile(
pathJoin(dirnameForModule(import.meta), "../../package.json"),
"utf-8",
),
).version,
},
}),
);

const { stdout } = await testCompasCli({
args: ["init"],
inputs: [],
waitForExit: true,
cwd,
});

// Package.json
t.deepEqual(
JSON.parse(await readFile(pathJoin(cwd, "package.json"), "utf-8")),
{
dependencies: {
compas: JSON.parse(
await readFile(
pathJoin(dirnameForModule(import.meta), "../../package.json"),
"utf-8",
),
).version,
},
},
);

// Package manager
t.ok(
!stdout.includes("_compas_skip_package_manager_install"),
"Package manager did run, but didn't need to",
);

// Output
t.ok(stdout.includes("Already up-to-date!"));
});

t.test("exiting project - update", async (t) => {
const cwd = workingDirectory("existing-project-update");

await writeFileChecked(
pathJoin(cwd, "package.json"),
JSON.stringify({
dependencies: {
compas: "*",
},
}),
);

const { stdout } = await testCompasCli({
args: ["init"],
inputs: [],
waitForExit: true,
cwd,
});

// Package.json
t.deepEqual(
JSON.parse(await readFile(pathJoin(cwd, "package.json"), "utf-8")),
{
dependencies: {
compas: JSON.parse(
await readFile(
pathJoin(dirnameForModule(import.meta), "../../package.json"),
"utf-8",
),
).version,
},
},
);

// Package manager
t.ok(stdout.includes("Patching package.json"));
t.ok(stdout.includes("_compas_skip_package_manager_install"));

// Output
t.ok(stdout.includes("Ready to roll!"));
});
});
Loading

0 comments on commit 26a8c52

Please sign in to comment.