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
22 changes: 22 additions & 0 deletions src/services/config-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import * as output from '../utils/output.js';
let DEFAULT_CONFIG = {
comparison: {
threshold: 2.0,
minClusterSize: 2,
},
server: {
port: 47392,
Expand Down Expand Up @@ -104,6 +105,13 @@ export function createConfigService({ workingDir }) {
config.comparison.threshold = parseFloat(process.env.VIZZLY_THRESHOLD);
sources.comparison = 'env';
}
if (process.env.VIZZLY_MIN_CLUSTER_SIZE) {
config.comparison.minClusterSize = parseInt(
process.env.VIZZLY_MIN_CLUSTER_SIZE,
10
);
sources.comparison = 'env';
}
if (process.env.VIZZLY_PORT) {
config.server.port = parseInt(process.env.VIZZLY_PORT, 10);
sources.server = 'env';
Expand Down Expand Up @@ -241,6 +249,20 @@ export default defineConfig(${JSON.stringify(newConfig, null, 2)});
}
}

// Validate minClusterSize
if (config.comparison?.minClusterSize !== undefined) {
let minClusterSize = config.comparison.minClusterSize;
if (!Number.isInteger(minClusterSize) || minClusterSize < 1) {
errors.push(
'comparison.minClusterSize must be a positive integer (1 or greater)'
);
} else if (minClusterSize > 100) {
warnings.push(
'comparison.minClusterSize above 100 may filter out most differences'
);
}
}

// Validate port
if (config.server?.port !== undefined) {
let port = config.server.port;
Expand Down
72 changes: 72 additions & 0 deletions tests/services/config-service.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,15 @@ describe('services/config-service', () => {
tempDir = createTempDir();
// Clear any environment variables that might affect tests
delete process.env.VIZZLY_THRESHOLD;
delete process.env.VIZZLY_MIN_CLUSTER_SIZE;
delete process.env.VIZZLY_PORT;
});

afterEach(() => {
cleanupTempDir(tempDir);
// Clean up environment variables after each test
delete process.env.VIZZLY_THRESHOLD;
delete process.env.VIZZLY_MIN_CLUSTER_SIZE;
delete process.env.VIZZLY_PORT;
delete process.env.VIZZLY_HOME;
});
Expand Down Expand Up @@ -88,6 +90,32 @@ describe('services/config-service', () => {
assert.strictEqual(config.comparison.threshold, 5.0);
assert.strictEqual(sources.threshold, 'project');
});

it('applies VIZZLY_MIN_CLUSTER_SIZE env var override', async () => {
process.env.VIZZLY_MIN_CLUSTER_SIZE = '10';

let service = createConfigService({ workingDir: tempDir });
let { config, sources } = await service.getConfig('merged');

assert.strictEqual(config.comparison.minClusterSize, 10);
assert.strictEqual(sources.comparison, 'env');
});

it('env var overrides project config for minClusterSize', async () => {
// Create project config with minClusterSize
writeFileSync(
join(tempDir, 'vizzly.config.js'),
`export default { comparison: { minClusterSize: 3 } };`
);

// Env var should win
process.env.VIZZLY_MIN_CLUSTER_SIZE = '8';

let service = createConfigService({ workingDir: tempDir });
let { config } = await service.getConfig('merged');

assert.strictEqual(config.comparison.minClusterSize, 8);
});
});

describe('getConfig - project', () => {
Expand Down Expand Up @@ -334,6 +362,50 @@ describe('services/config-service', () => {
assert.ok(result.errors.some(e => e.includes('timeout')));
});

it('returns error for non-integer minClusterSize', async () => {
let service = createConfigService({ workingDir: tempDir });

let result = await service.validateConfig({
comparison: { minClusterSize: 3.5 },
});

assert.strictEqual(result.valid, false);
assert.ok(result.errors.some(e => e.includes('minClusterSize')));
});

it('returns error for zero or negative minClusterSize', async () => {
let service = createConfigService({ workingDir: tempDir });

let result = await service.validateConfig({
comparison: { minClusterSize: 0 },
});

assert.strictEqual(result.valid, false);
assert.ok(result.errors.some(e => e.includes('minClusterSize')));
});

it('returns warning for very high minClusterSize', async () => {
let service = createConfigService({ workingDir: tempDir });

let result = await service.validateConfig({
comparison: { minClusterSize: 150 },
});

assert.strictEqual(result.valid, true);
assert.ok(result.warnings.some(w => w.includes('100')));
});

it('validates valid minClusterSize', async () => {
let service = createConfigService({ workingDir: tempDir });

let result = await service.validateConfig({
comparison: { minClusterSize: 5 },
});

assert.strictEqual(result.valid, true);
assert.strictEqual(result.errors.length, 0);
});

it('validates empty config as valid', async () => {
let service = createConfigService({ workingDir: tempDir });

Expand Down