config and plugin

This commit is contained in:
2026-09-12 19:11:44 -04:00
parent 85bcb05a7d
commit 8c40bbeff1
19 changed files with 1685 additions and 86 deletions
+88
View File
@@ -0,0 +1,88 @@
import { describe, expect, it } from 'vitest';
import { composeCfg, parseCfg, parseOverlay } from '../../src/lib/server/fleet/config-compose.js';
const BASELINE = [
'// GENERAL',
'set g_inactivity "190"',
'set sv_voice "1"',
'',
'// GAMEPLAY',
'set g_playerCollision "0"',
'set sv_maprotation "map zombie_theater"'
].join('\n');
describe('parseCfg', () => {
it('captures set keys and preserves comments/blanks', () => {
const p = parseCfg(BASELINE);
expect(p.entries.get('g_inactivity')).toBe(1);
expect(p.entries.get('sv_voice')).toBe(2);
expect(p.entries.get('sv_maprotation')).toBe(6);
expect(p.order[0]).toEqual({ kind: 'raw', line: '// GENERAL' });
expect(p.order[3]).toEqual({ kind: 'raw', line: '' });
});
it('detects CRLF line endings', () => {
const crlf = 'set a "1"\r\nset b "2"\r\n';
expect(parseCfg(crlf).eol).toBe('\r\n');
});
});
describe('parseOverlay', () => {
it('reads set lines and ignores comments/blanks', () => {
const overlay = '// disable AFK\nset g_inactivity "0"\n';
const kv = parseOverlay(overlay);
expect(kv.size).toBe(1);
expect(kv.get('g_inactivity')).toBe('set g_inactivity "0"');
});
it('handles bare (unquoted) values', () => {
const overlay = 'set g_logSync 1';
const kv = parseOverlay(overlay);
expect(kv.get('g_logSync')).toBe('set g_logSync 1');
});
it('later duplicate wins within an overlay', () => {
const overlay = 'set x "1"\nset x "2"';
expect(parseOverlay(overlay).get('x')).toBe('set x "2"');
});
});
describe('composeCfg', () => {
it('replaces matching keys in place', () => {
const result = composeCfg(BASELINE, [{ id: 1, text: 'set g_inactivity "0"' }]);
expect(result).toContain('set g_inactivity "0"');
expect(result).not.toContain('set g_inactivity "190"');
// Structure preserved: sv_voice should still be at its original spot.
const lines = result.split('\n');
expect(lines[1]).toBe('set g_inactivity "0"');
expect(lines[2]).toBe('set sv_voice "1"');
});
it('appends new keys not present in baseline', () => {
const result = composeCfg(BASELINE, [{ id: 1, text: 'set new_flag "yes"' }]);
expect(result).toContain('set new_flag "yes"');
expect(result).toContain('// --- appended by electric-cherry overlays ---');
});
it('applies multiple overlays deterministically by id', () => {
const result = composeCfg(BASELINE, [
{ id: 2, text: 'set g_inactivity "60"' },
{ id: 1, text: 'set g_inactivity "0"' }
]);
// id=2 is later → wins
expect(result).toContain('set g_inactivity "60"');
expect(result).not.toContain('set g_inactivity "0"');
});
it('preserves inline comments on the overlay line', () => {
const result = composeCfg(BASELINE, [
{ id: 1, text: 'set g_inactivity "0" // AFK disabled' }
]);
expect(result).toContain('set g_inactivity "0" // AFK disabled');
});
it('is a no-op when no overlays are given', () => {
const result = composeCfg(BASELINE, []);
expect(result.trim()).toBe(BASELINE.trim());
});
});