7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
115 lines
4.2 KiB
JavaScript
115 lines
4.2 KiB
JavaScript
/**
|
|
* Tests for utils/yaml_export.js — the YAML serialization helpers used by the
|
|
* benchmark export (yamlEscape / formatSettingValue / formatSettingsSnapshot).
|
|
*
|
|
* These are load-bearing for export correctness: a regression in yamlEscape
|
|
* would silently corrupt every downloaded benchmark YAML (and could let a
|
|
* model name / URL with YAML-special chars inject an unintended key). This
|
|
* pins the escaping behaviour now that the function is importable.
|
|
*/
|
|
|
|
import '@js/utils/yaml_export.js';
|
|
|
|
const { yamlEscape, formatSettingValue, formatSettingsSnapshot } = window;
|
|
|
|
describe('yamlEscape', () => {
|
|
it('returns empty string for null/undefined', () => {
|
|
expect(yamlEscape(null)).toBe('');
|
|
expect(yamlEscape(undefined)).toBe('');
|
|
});
|
|
|
|
it('leaves plain strings untouched', () => {
|
|
expect(yamlEscape('qwen3.6')).toBe('qwen3.6');
|
|
});
|
|
|
|
it('escapes backslash FIRST so later escapes are not double-escaped', () => {
|
|
// A lone backslash must become exactly two, not four.
|
|
expect(yamlEscape('a\\b')).toBe('a\\\\b');
|
|
// Backslash + quote: backslash doubled, quote escaped — order matters.
|
|
expect(yamlEscape('\\"')).toBe('\\\\\\"');
|
|
});
|
|
|
|
it('escapes double quotes, newlines, CR and tabs', () => {
|
|
expect(yamlEscape('he said "hi"')).toBe('he said \\"hi\\"');
|
|
expect(yamlEscape('a\nb')).toBe('a\\nb');
|
|
expect(yamlEscape('a\rb')).toBe('a\\rb');
|
|
expect(yamlEscape('a\tb')).toBe('a\\tb');
|
|
});
|
|
|
|
it('coerces non-strings via String()', () => {
|
|
expect(yamlEscape(42)).toBe('42');
|
|
});
|
|
});
|
|
|
|
describe('formatSettingValue', () => {
|
|
it('emits null for null/undefined', () => {
|
|
expect(formatSettingValue(null)).toBe('null');
|
|
expect(formatSettingValue(undefined)).toBe('null');
|
|
});
|
|
|
|
it('emits bare booleans and finite numbers', () => {
|
|
expect(formatSettingValue(true)).toBe('true');
|
|
expect(formatSettingValue(false)).toBe('false');
|
|
expect(formatSettingValue(128000)).toBe('128000');
|
|
});
|
|
|
|
it('emits null for non-finite numbers', () => {
|
|
expect(formatSettingValue(Infinity)).toBe('null');
|
|
expect(formatSettingValue(NaN)).toBe('null');
|
|
});
|
|
|
|
it('emits inline JSON for arrays and objects', () => {
|
|
expect(formatSettingValue([1, 'a'])).toBe('[1,"a"]');
|
|
expect(formatSettingValue({ a: 1 })).toBe('{"a":1}');
|
|
});
|
|
|
|
it('double-quotes and escapes strings', () => {
|
|
expect(formatSettingValue('gpt-4')).toBe('"gpt-4"');
|
|
// A value with a YAML-special char must stay a single safe scalar.
|
|
expect(formatSettingValue('a: b # c')).toBe('"a: b # c"');
|
|
expect(formatSettingValue('inject\nkey: pwned')).toBe(
|
|
'"inject\\nkey: pwned"',
|
|
);
|
|
});
|
|
});
|
|
|
|
describe('formatSettingsSnapshot', () => {
|
|
it('renders a sentinel comment for a null snapshot', () => {
|
|
expect(formatSettingsSnapshot(null)).toBe(
|
|
'settings: null # snapshot not captured for this run\n',
|
|
);
|
|
});
|
|
|
|
it('renders an empty flow map for {}', () => {
|
|
expect(formatSettingsSnapshot({})).toBe('settings: {}\n');
|
|
});
|
|
|
|
it('renders sorted keys with formatted values (metadata shape)', () => {
|
|
const out = formatSettingsSnapshot({
|
|
'llm.model': { value: 'qwen3.6', ui_element: 'select' },
|
|
'a.flag': { value: true, ui_element: 'checkbox' },
|
|
});
|
|
// a.flag sorts before llm.model; string quoted, bool bare.
|
|
expect(out).toBe(
|
|
'settings:\n a.flag: true\n llm.model: "qwen3.6"\n',
|
|
);
|
|
});
|
|
|
|
it('quotes keys that contain YAML-significant characters', () => {
|
|
const out = formatSettingsSnapshot({ 'has space': { value: 'x' } });
|
|
expect(out).toContain('"has space": "x"');
|
|
});
|
|
|
|
it('passes flat (non-metadata) scalar values through', () => {
|
|
const out = formatSettingsSnapshot({ 'llm.model': 'qwen3.6' });
|
|
expect(out).toBe('settings:\n llm.model: "qwen3.6"\n');
|
|
});
|
|
|
|
it('renders null for a metadata object missing its `value` key', () => {
|
|
const out = formatSettingsSnapshot({
|
|
'llm.model': { ui_element: 'select' },
|
|
});
|
|
expect(out).toBe('settings:\n llm.model: null\n');
|
|
});
|
|
});
|