Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion test/cli/init.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { mkdir, rm, readdir, readFile } from 'fs/promises';
import { join } from 'path';
import { existsSync } from 'fs';
import { tmpdir } from 'os';
import { randomBytes } from 'crypto';
import { runInit } from '@bradygaster/squad-cli/core/init';
import { getPackageVersion } from '@bradygaster/squad-cli/core/version';

const TEST_ROOT = join(process.cwd(), `.test-cli-init-${randomBytes(4).toString('hex')}`);
const TEST_ROOT = join(tmpdir(), `.test-cli-init-${randomBytes(4).toString('hex')}`);

describe('CLI: init command', () => {
beforeEach(async () => {
Expand Down
2 changes: 1 addition & 1 deletion test/cli/loop.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ describe('runLoop', () => {
});

await expect(runLoop(DEST, defaultOptions)).rejects.toThrow(
/gh CLI/i,
/Copilot CLI/i,
);
});

Expand Down
3 changes: 2 additions & 1 deletion test/cli/upgrade.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
import { mkdir, rm, readFile, writeFile } from 'fs/promises';
import { join } from 'path';
import { existsSync, mkdirSync, writeFileSync, readFileSync, rmSync, chmodSync } from 'fs';
import { tmpdir } from 'os';
import { randomBytes } from 'crypto';
import { runInit } from '@bradygaster/squad-cli/core/init';
import { runUpgrade, ensureGitattributes, ensureGitignore, ensureDirectories, ensureCastingDefaults, selfUpgradeCli } from '@bradygaster/squad-cli/core/upgrade';
import { getPackageVersion } from '@bradygaster/squad-cli/core/version';

const TEST_ROOT = join(process.cwd(), `.test-cli-upgrade-${randomBytes(4).toString('hex')}`);
const TEST_ROOT = join(tmpdir(), `.test-cli-upgrade-${randomBytes(4).toString('hex')}`);

describe('CLI: upgrade command', () => {
beforeEach(async () => {
Expand Down
28 changes: 18 additions & 10 deletions test/migrate-directory.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -249,13 +249,17 @@ describe('detectProjectType: .NET extensions (.slnx, .fsproj, .vbproj)', () => {
beforeEach(() => { tmpDir = makeTempDir(); });
afterEach(() => cleanDir(tmpDir));

it('init in a dir with .slnx generates a dotnet stub CI workflow', () => {
it('upgrade in a dir with .slnx generates a dotnet stub CI workflow', () => {
fs.writeFileSync(path.join(tmpDir, 'MyApp.slnx'), '');
const result = runSquad([], tmpDir);
assert.equal(result.exitCode, 0, `init should succeed: ${result.stdout}`);
// init creates .squad/ structure but skips CI workflows (by design since PR #847)
const initResult = runSquad([], tmpDir);
assert.equal(initResult.exitCode, 0, `init should succeed: ${initResult.stdout}`);
// upgrade installs CI/CD workflows including project-type-specific ones
const result = runSquad(['upgrade'], tmpDir);
assert.equal(result.exitCode, 0, `upgrade should succeed: ${result.stdout}`);

const ciPath = path.join(tmpDir, '.github', 'workflows', 'squad-ci.yml');
assert.ok(fs.existsSync(ciPath), 'squad-ci.yml should be created');
assert.ok(fs.existsSync(ciPath), 'squad-ci.yml should be created by upgrade');
const ciContent = fs.readFileSync(ciPath, 'utf8');
assert.ok(
ciContent.includes('dotnet') || ciContent.toLowerCase().includes('dotnet'),
Expand All @@ -268,10 +272,12 @@ describe('detectProjectType: .NET extensions (.slnx, .fsproj, .vbproj)', () => {
);
});

it('init in a dir with .fsproj generates a dotnet stub CI workflow', () => {
it('upgrade in a dir with .fsproj generates a dotnet stub CI workflow', () => {
fs.writeFileSync(path.join(tmpDir, 'MyLib.fsproj'), '');
const result = runSquad([], tmpDir);
assert.equal(result.exitCode, 0, `init should succeed: ${result.stdout}`);
const initResult = runSquad([], tmpDir);
assert.equal(initResult.exitCode, 0, `init should succeed: ${initResult.stdout}`);
const result = runSquad(['upgrade'], tmpDir);
assert.equal(result.exitCode, 0, `upgrade should succeed: ${result.stdout}`);

const ciPath = path.join(tmpDir, '.github', 'workflows', 'squad-ci.yml');
const ciContent = fs.readFileSync(ciPath, 'utf8');
Expand All @@ -281,10 +287,12 @@ describe('detectProjectType: .NET extensions (.slnx, .fsproj, .vbproj)', () => {
);
});

it('init in a dir with .vbproj generates a dotnet stub CI workflow', () => {
it('upgrade in a dir with .vbproj generates a dotnet stub CI workflow', () => {
fs.writeFileSync(path.join(tmpDir, 'MyApp.vbproj'), '');
const result = runSquad([], tmpDir);
assert.equal(result.exitCode, 0, `init should succeed: ${result.stdout}`);
const initResult = runSquad([], tmpDir);
assert.equal(initResult.exitCode, 0, `init should succeed: ${initResult.stdout}`);
const result = runSquad(['upgrade'], tmpDir);
assert.equal(result.exitCode, 0, `upgrade should succeed: ${result.stdout}`);

const ciPath = path.join(tmpDir, '.github', 'workflows', 'squad-ci.yml');
const ciContent = fs.readFileSync(ciPath, 'utf8');
Expand Down
16 changes: 14 additions & 2 deletions test/template-sync.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* 4. Semantic checks — universe counts, casting-policy internal consistency.
*/

import { describe, it, expect } from 'vitest';
import { describe, it, expect, beforeAll } from 'vitest';
import { readFileSync, existsSync, readdirSync } from 'node:fs';
import { resolve, dirname, join } from 'node:path';
import { fileURLToPath } from 'node:url';
Expand All @@ -22,6 +22,18 @@
const __dirname = dirname(fileURLToPath(import.meta.url));
const ROOT = resolve(__dirname, '..');

// Re-sync templates before any byte-comparison checks.
// Other test files (e.g., acceptance tests) may run `squad init` in the
// repo root, overwriting .github/agents/squad.agent.md from the CLI
// template and making it diverge from .squad-templates/squad.agent.md.
beforeAll(() => {
execSync('node scripts/sync-templates.mjs', {
cwd: ROOT,
encoding: 'utf-8',
timeout: 60_000,
});
});

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
Expand Down Expand Up @@ -137,7 +149,7 @@
expect(fileExists(agentPath), `${agentPath} should exist`).toBe(true);
const src = readFileBytes(canonicalPath);
const dst = readFileBytes(agentPath);
expect(Buffer.compare(src, dst), `${agentPath} content mismatch`).toBe(0);

Check failure on line 152 in test/template-sync.test.ts

View workflow job for this annotation

GitHub Actions / test

test/template-sync.test.ts > dynamic template enumeration (all synced files) > .github/agents/squad.agent.md is byte-for-byte identical to .squad-templates/squad.agent.md

AssertionError: .github/agents/squad.agent.md content mismatch: expected -1 to be +0 // Object.is equality - Expected + Received - 0 + -1 ❯ test/template-sync.test.ts:152:75
});
}
}
Expand All @@ -153,7 +165,7 @@
const output = execSync('node scripts/sync-templates.mjs', {
cwd: ROOT,
encoding: 'utf-8',
timeout: 30_000,
timeout: 60_000,
});
expect(output).toContain('Synced');
});
Expand Down
Loading