Initial import from garrytan/gstack@026751e (main snapshot via local relay)
Some checks failed
Workflow Lint / actionlint (push) Has been cancelled
Build CI Image / build (push) Has been cancelled
Skill Docs Freshness / check-freshness (push) Has been cancelled
Periodic Evals / build-image (push) Has been cancelled
Periodic Evals / evals (map[file:test/codex-e2e.test.ts name:e2e-codex]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/gemini-e2e.test.ts name:e2e-gemini]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-design.test.ts name:e2e-design]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-plan.test.ts name:e2e-plan]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-qa-bugs.test.ts name:e2e-qa-bugs]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-qa-workflow.test.ts name:e2e-qa-workflow]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-review.test.ts name:e2e-review]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-workflow.test.ts name:e2e-workflow]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-routing-e2e.test.ts name:e2e-routing]) (push) Has been cancelled
Some checks failed
Workflow Lint / actionlint (push) Has been cancelled
Build CI Image / build (push) Has been cancelled
Skill Docs Freshness / check-freshness (push) Has been cancelled
Periodic Evals / build-image (push) Has been cancelled
Periodic Evals / evals (map[file:test/codex-e2e.test.ts name:e2e-codex]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/gemini-e2e.test.ts name:e2e-gemini]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-design.test.ts name:e2e-design]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-plan.test.ts name:e2e-plan]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-qa-bugs.test.ts name:e2e-qa-bugs]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-qa-workflow.test.ts name:e2e-qa-workflow]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-review.test.ts name:e2e-review]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-e2e-workflow.test.ts name:e2e-workflow]) (push) Has been cancelled
Periodic Evals / evals (map[file:test/skill-routing-e2e.test.ts name:e2e-routing]) (push) Has been cancelled
Source: https://github.com/garrytan/gstack/commit/026751e
This commit is contained in:
87
test/gstack-artifacts-url.test.ts
Normal file
87
test/gstack-artifacts-url.test.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* gstack-artifacts-url — URL canonicalization helper.
|
||||
*
|
||||
* Centralizes HTTPS↔SSH conversion so callers don't each string-mangle. Per
|
||||
* codex Finding #10: store one canonical form (HTTPS) and derive all others.
|
||||
*/
|
||||
|
||||
import { describe, test, expect } from 'bun:test';
|
||||
import * as path from 'path';
|
||||
import { spawnSync } from 'child_process';
|
||||
|
||||
const ROOT = path.resolve(import.meta.dir, '..');
|
||||
const URL_BIN = path.join(ROOT, 'bin', 'gstack-artifacts-url');
|
||||
|
||||
function run(args: string[]): { code: number; stdout: string; stderr: string } {
|
||||
const r = spawnSync(URL_BIN, args, { encoding: 'utf-8' });
|
||||
return {
|
||||
code: r.status ?? -1,
|
||||
stdout: (r.stdout || '').trim(),
|
||||
stderr: (r.stderr || '').trim(),
|
||||
};
|
||||
}
|
||||
|
||||
describe('gstack-artifacts-url', () => {
|
||||
test('--to ssh from canonical https', () => {
|
||||
const r = run(['--to', 'ssh', 'https://github.com/garrytan/gstack-artifacts-garrytan']);
|
||||
expect(r.code).toBe(0);
|
||||
expect(r.stdout).toBe('git@github.com:garrytan/gstack-artifacts-garrytan.git');
|
||||
});
|
||||
|
||||
test('--to ssh from https-with-.git', () => {
|
||||
const r = run(['--to', 'ssh', 'https://github.com/garrytan/gstack-artifacts-garrytan.git']);
|
||||
expect(r.stdout).toBe('git@github.com:garrytan/gstack-artifacts-garrytan.git');
|
||||
});
|
||||
|
||||
test('--to https is idempotent on https input', () => {
|
||||
const r = run(['--to', 'https', 'https://github.com/garrytan/gstack-artifacts-garrytan']);
|
||||
expect(r.stdout).toBe('https://github.com/garrytan/gstack-artifacts-garrytan');
|
||||
});
|
||||
|
||||
test('--to https from git@host:owner/repo.git', () => {
|
||||
const r = run(['--to', 'https', 'git@github.com:garrytan/gstack-artifacts-garrytan.git']);
|
||||
expect(r.stdout).toBe('https://github.com/garrytan/gstack-artifacts-garrytan');
|
||||
});
|
||||
|
||||
test('--to https from ssh:// scheme (gitlab self-hosted style)', () => {
|
||||
const r = run(['--to', 'https', 'ssh://git@gitlab.example.org/team/gstack-artifacts-team.git']);
|
||||
expect(r.stdout).toBe('https://gitlab.example.org/team/gstack-artifacts-team');
|
||||
});
|
||||
|
||||
test('--host extracts hostname from any form', () => {
|
||||
expect(run(['--host', 'https://github.com/x/y']).stdout).toBe('github.com');
|
||||
expect(run(['--host', 'git@gitlab.com:x/y.git']).stdout).toBe('gitlab.com');
|
||||
expect(run(['--host', 'ssh://git@gitlab.example.org/x/y.git']).stdout).toBe('gitlab.example.org');
|
||||
});
|
||||
|
||||
test('--owner-repo extracts the path segment', () => {
|
||||
expect(run(['--owner-repo', 'https://github.com/garrytan/gstack-artifacts-garrytan']).stdout)
|
||||
.toBe('garrytan/gstack-artifacts-garrytan');
|
||||
expect(run(['--owner-repo', 'git@github.com:team/gstack-artifacts-team.git']).stdout)
|
||||
.toBe('team/gstack-artifacts-team');
|
||||
});
|
||||
|
||||
test('rejects unrecognized URL form with exit 3', () => {
|
||||
const r = run(['--to', 'ssh', 'not a url']);
|
||||
expect(r.code).toBe(3);
|
||||
expect(r.stderr).toContain('unrecognized URL form');
|
||||
});
|
||||
|
||||
test('rejects missing args with exit 2', () => {
|
||||
expect(run([]).code).toBe(2);
|
||||
expect(run(['--to']).code).toBe(2);
|
||||
expect(run(['--to', 'ssh']).code).toBe(2);
|
||||
});
|
||||
|
||||
test('rejects unknown --to target', () => {
|
||||
const r = run(['--to', 'svn', 'https://github.com/x/y']);
|
||||
expect(r.code).toBe(2);
|
||||
});
|
||||
|
||||
test('round-trip: https → ssh → https is identity', () => {
|
||||
const original = 'https://github.com/garrytan/gstack-artifacts-garrytan';
|
||||
const ssh = run(['--to', 'ssh', original]).stdout;
|
||||
const back = run(['--to', 'https', ssh]).stdout;
|
||||
expect(back).toBe(original);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user