import { describe, it, expect } from 'vitest';
import {
version,
run,
marketSearch,
marketList,
templateList,
projectNew,
projectGenerate,
projectInit,
doctor,
help,
} from '../index.mjs';
describe('Vanilla JavaScript API - Core Functions', () => {
it('version() returns semantic version string', () => {
const v = version();
expect(typeof v).toBe('string');
expect(v.length).toBeGreaterThan(0);
expect(v).toMatch(/^\d+\.\d+\.\d+/);
});
it('run() executes with vanilla JS arguments array', async () => {
const args = ['--help'];
const result = await run(args);
const { code, stdout, stderr } = result;
expect(typeof code).toBe('number');
expect(typeof stdout).toBe('string');
expect(typeof stderr).toBe('string');
expect(code).toBe(0);
});
it('run() handles --version command', async () => {
const result = await run(['--version']);
const versionOutput = result.stdout.trim();
expect(versionOutput).toMatch(/^\d+\.\d+\.\d+/);
});
it('run() works with empty array', async () => {
const result = await run([]);
expect(typeof result.code).toBe('number');
});
it('run() handles error cases gracefully', async () => {
const result = await run(['invalid-xyz-command']);
expect(typeof result.code).toBe('number');
expect(result.code).not.toBe(0);
});
});
describe('Vanilla JavaScript API - Marketplace Operations', () => {
it('marketSearch() accepts string parameter', async () => {
const query = 'rust-templates';
const result = await marketSearch(query);
expect(result.code).toBeDefined();
expect(result.stdout).toBeDefined();
expect(typeof result.stderr).toBe('string');
});
it('marketList() returns marketplace catalog', async () => {
const result = await marketList();
expect(typeof result.code).toBe('number');
expect(typeof result.stdout).toBe('string');
expect(result.stdout.length).toBeGreaterThan(0);
});
it('marketSearch() with multiple queries', async () => {
const queries = ['rust', 'typescript', 'python'];
for (const q of queries) {
const result = await marketSearch(q);
expect(result).toHaveProperty('code');
expect(result).toHaveProperty('stdout');
expect(result).toHaveProperty('stderr');
}
});
});
describe('Vanilla JavaScript API - Template Operations', () => {
it('templateList() returns available templates', async () => {
const result = await templateList();
expect(result.code).toEqual(0);
expect(result.stdout.length).toBeGreaterThan(0);
});
it('templateList() result is plain object', async () => {
const result = await templateList();
expect(Object.prototype.toString.call(result)).toBe('[object Object]');
expect('code' in result).toBe(true);
expect('stdout' in result).toBe(true);
expect('stderr' in result).toBe(true);
});
});
describe('Vanilla JavaScript API - Project Scaffolding', () => {
it('projectInit() works with vanilla JS', async () => {
const result = await projectInit();
expect(typeof result.code).toBe('number');
expect(typeof result.stdout).toBe('string');
});
it('projectGenerate() accepts optional path parameter', async () => {
const result = await projectGenerate();
expect(result).toHaveProperty('code');
expect(result).toHaveProperty('stdout');
expect(result).toHaveProperty('stderr');
});
});
describe('Vanilla JavaScript API - Utility Commands', () => {
it('doctor() runs environment diagnostics', async () => {
const result = await doctor();
expect(typeof result.code).toBe('number');
expect(typeof result.stdout).toBe('string');
});
it('help() returns help text in vanilla JS', async () => {
const result = await help();
expect(result.code).toBe(0);
expect(result.stdout).toContain('ggen');
});
it('help(command) with specific command', async () => {
const result = await help('market');
expect(result.code).toBe(0);
expect(result.stdout.toLowerCase()).toContain('market');
});
});
describe('Vanilla JavaScript API - Type Contracts', () => {
it('all functions return RunResult shape', async () => {
const calls = [
run(['--version']),
marketSearch('test'),
marketList(),
templateList(),
doctor(),
help(),
];
const results = await Promise.all(calls);
for (const result of results) {
expect(result).toHaveProperty('code');
expect(result).toHaveProperty('stdout');
expect(result).toHaveProperty('stderr');
expect(typeof result.code).toBe('number');
expect(typeof result.stdout).toBe('string');
expect(typeof result.stderr).toBe('string');
}
});
it('code is always a number', async () => {
const testFunctions = [
() => run(['--help']),
() => marketSearch('test'),
() => templateList(),
() => doctor(),
];
for (const fn of testFunctions) {
const result = await fn();
expect(Number.isInteger(result.code)).toBe(true);
}
});
it('stdout and stderr are always strings', async () => {
const result = await run(['--help']);
expect(typeof result.stdout).toBe('string');
expect(typeof result.stderr).toBe('string');
});
});
describe('Vanilla JavaScript API - Browser Compatibility', () => {
it('functions work without ES6 class instantiation', async () => {
const result = await version().constructor === String.constructor;
expect(result).toBe(false); });
it('no global state pollution', async () => {
const v1 = version();
const v2 = version();
expect(v1).toBe(v2);
});
it('async/await works in vanilla JS', async () => {
let result;
try {
result = await run(['--version']);
} catch (error) {
result = null;
}
expect(result).not.toBeNull();
});
it('handles promise chains for vanilla JS', () => {
return run(['--help'])
.then((result) => {
expect(result.code).toBe(0);
return result.stdout;
})
.then((stdout) => {
expect(stdout).toContain('ggen');
});
});
it('works with vanilla JS destructuring', async () => {
const result = await help();
const { code, stdout, stderr } = result;
expect(code).toBeDefined();
expect(stdout).toBeDefined();
expect(stderr).toBeDefined();
});
it('supports spread operator in vanilla JS', async () => {
const baseArgs = ['market'];
const allArgs = [...baseArgs, '--help'];
const result = await run(allArgs);
expect(typeof result.code).toBe('number');
});
it('works with object shorthand in vanilla JS', async () => {
const query = 'templates';
const searchConfig = { query };
const result = await marketSearch(searchConfig.query);
expect(result).toHaveProperty('stdout');
});
});
describe('Vanilla JavaScript API - Error Handling', () => {
it('handles rejected promises in vanilla JS', async () => {
let errorCaught = false;
try {
await run(['--invalid-flag-xyz']);
} catch (error) {
errorCaught = true;
}
expect(typeof errorCaught).toBe('boolean');
});
it('supports vanilla JS try/catch/finally', async () => {
let executed = false;
try {
const result = await run(['--version']);
executed = result.code === 0;
} finally {
expect(executed).toBe(true);
}
});
});
describe('Vanilla JavaScript API - Performance', () => {
it('version() executes synchronously in milliseconds', () => {
const start = performance.now();
const v = version();
const end = performance.now();
const duration = end - start;
expect(v).toBeDefined();
expect(duration).toBeLessThan(100); });
it('multiple sequential calls work reliably', async () => {
const results = [];
for (let i = 0; i < 5; i++) {
const result = await help();
results.push(result.code);
}
expect(results.length).toBe(5);
expect(results.every((code) => code === 0)).toBe(true);
});
});