/**
* Simple Integration Tests for Story 06: Dynamic Expected Value Construction
* Focus on basic functionality without complex command execution
*
* This validates core acceptance criteria with minimal external dependencies
*/
import * as os from 'os';
import { DynamicExpectedValueConstructor } from './dynamic-expected-value-constructor';
import './jest-matchers'; // Load custom matchers
describe('Story 06: Dynamic Expected Value Construction - Simple Integration', () => {
let constructor: DynamicExpectedValueConstructor;
beforeAll(() => {
constructor = new DynamicExpectedValueConstructor();
});
describe('AC 6.1: Dynamic username value construction', () => {
it('should dynamically resolve username', async () => {
const template = '${USER}';
const result = await constructor.resolveTemplate(template);
const expectedUser = process.env.USER || os.userInfo().username;
expect(result).toBe(expectedUser);
});
it('should work in command context', async () => {
const template = 'Current user: ${USER}';
const result = await constructor.resolveTemplate(template);
const expectedUser = process.env.USER || os.userInfo().username;
expect(result).toBe(`Current user: ${expectedUser}`);
});
});
describe('AC 6.2: Dynamic working directory value construction', () => {
it('should dynamically resolve working directory', async () => {
const template = '${PWD}';
const result = await constructor.resolveTemplate(template);
expect(result).toBe(process.cwd());
});
it('should work in path context', async () => {
const template = 'Directory: ${PWD}';
const result = await constructor.resolveTemplate(template);
expect(result).toBe(`Directory: ${process.cwd()}`);
});
});
describe('AC 6.3: Dynamic hostname value construction', () => {
it('should dynamically resolve hostname', async () => {
const template = '${HOSTNAME}';
const result = await constructor.resolveTemplate(template);
expect(result).toBe(os.hostname());
});
it('should work in full prompt context', async () => {
const template = '[${USER}@${HOSTNAME} ${PWD}]$ ';
const result = await constructor.resolveTemplate(template);
const expectedUser = process.env.USER || os.userInfo().username;
const expectedResult = `[${expectedUser}@${os.hostname()} ${process.cwd()}]$ `;
expect(result).toBe(expectedResult);
});
});
describe('AC 6.4: Environment value caching', () => {
it('should provide cached environment values', async () => {
const values = await constructor.getEnvironmentValues();
expect(values).toHaveProperty('USER');
expect(values).toHaveProperty('PWD');
expect(values).toHaveProperty('HOSTNAME');
expect(values).toHaveProperty('HOME');
expect(values.USER).toBe(process.env.USER || os.userInfo().username);
});
it('should support cache invalidation', () => {
expect(() => constructor.invalidateCache()).not.toThrow();
});
});
describe('AC 6.5: Multiple variable substitution', () => {
it('should substitute multiple variables in one template', async () => {
const template = 'User: ${USER}, Host: ${HOSTNAME}, Dir: ${PWD}';
const result = await constructor.resolveTemplate(template);
const expectedUser = process.env.USER || os.userInfo().username;
const expected = `User: ${expectedUser}, Host: ${os.hostname()}, Dir: ${process.cwd()}`;
expect(result).toBe(expected);
});
it('should handle templates with no variables', async () => {
const template = 'No variables here';
const result = await constructor.resolveTemplate(template);
expect(result).toBe('No variables here');
});
});
describe('AC 6.7: Volatile pattern creation', () => {
it('should create regex pattern for timestamps', () => {
const pattern = constructor.createVolatilePattern('timestamp');
expect(pattern).toBeInstanceOf(RegExp);
expect(pattern.test('1703505600')).toBe(true);
expect(pattern.test('1703505600000')).toBe(true);
expect(pattern.test('abc')).toBe(false);
});
it('should create regex pattern for dates', () => {
const pattern = constructor.createVolatilePattern('date');
expect(pattern).toBeInstanceOf(RegExp);
expect(pattern.test('Mon Dec 25 10:30:45 UTC 2023')).toBe(true);
expect(pattern.test('Fri Jan 1 00:00:00 EST 2024')).toBe(true);
expect(pattern.test('invalid date')).toBe(false);
});
it('should create regex pattern for process IDs', () => {
const pattern = constructor.createVolatilePattern('pid');
expect(pattern).toBeInstanceOf(RegExp);
expect(pattern.test('1234')).toBe(true);
expect(pattern.test('99999')).toBe(true);
expect(pattern.test('abc')).toBe(false);
});
});
describe('AC 6.13: Jest matcher integration', () => {
it('should work with toMatchDynamicTemplate matcher', async () => {
const actualOutput = process.env.USER || os.userInfo().username;
const template = '${USER}';
expect(actualOutput).toMatchDynamicTemplate(template);
});
it('should work with complex template matching', async () => {
const expectedUser = process.env.USER || os.userInfo().username;
const expectedHost = os.hostname();
const actualOutput = `${expectedUser}@${expectedHost}`;
const template = '${USER}@${HOSTNAME}';
expect(actualOutput).toMatchDynamicTemplate(template);
});
it('should validate that non-matching templates fail appropriately', async () => {
// This test documents that the matcher provides detailed error messages
// The actual error handling is demonstrated in the test output
const actualOutput = process.env.USER || require('os').userInfo().username;
const template = '${USER}';
// This should pass
expect(actualOutput).toMatchDynamicTemplate(template);
// Test that template matching works correctly
expect('test_value').not.toMatchDynamicTemplate('${HOSTNAME}');
});
});
describe('Error handling', () => {
it('should handle unknown variables gracefully', async () => {
const template = '${UNKNOWN_VARIABLE}';
await expect(constructor.resolveTemplate(template))
.rejects.toThrow('Unknown template variable');
});
it('should handle invalid template syntax', async () => {
const template = '${INVALID_SYNTAX';
await expect(constructor.resolveTemplate(template))
.rejects.toThrow('Invalid template syntax');
});
it('should handle empty templates', async () => {
const template = '';
const result = await constructor.resolveTemplate(template);
expect(result).toBe('');
});
});
describe('Cross-platform compatibility', () => {
it('should provide consistent results across environments', async () => {
const template = '${USER}@${HOSTNAME}:${PWD}';
const result = await constructor.resolveTemplate(template);
expect(typeof result).toBe('string');
expect(result.length).toBeGreaterThan(0);
expect(result).toContain('@');
expect(result).toContain(':');
});
it('should handle path separators correctly', async () => {
const template = '${PWD}';
const result = await constructor.resolveTemplate(template);
expect(result).toBe(process.cwd());
// Should work on both Unix and Windows paths
});
});
});