Files
plainleaf/plug-api/lib/yaml.test.ts
T

360 lines
11 KiB
TypeScript

import { assertEquals, assertExists } from "@std/assert";
import { applyPatches, type YamlPatch } from "./yaml.ts";
Deno.test("YAML patching - basic operations and value types", () => {
const initialYaml = `
name: my-package
version: 1.0.0
description: A sample package
`;
const patches: YamlPatch[] = [
{ op: "set-key", path: "version", value: "1.1.0" },
{ op: "set-key", path: "description", value: "Updated description" },
{ op: "set-key", path: "empty", value: "" },
{ op: "set-key", path: "special", value: "value:with:colons" },
{ op: "set-key", path: "null", value: null },
{ op: "set-key", path: "emptyList", value: [] },
{ op: "set-key", path: "emptyObject", value: {} },
];
const result = applyPatches(initialYaml, patches);
assertExists(result);
// Basic scalar updates
assertEquals(result.includes("version: 1.1.0"), true);
assertEquals(result.includes("description: Updated description"), true);
assertEquals(result.includes("name: my-package"), true);
// Special values and characters
assertEquals(result.includes('empty: ""'), true);
assertEquals(result.includes('special: "value:with:colons"'), true);
assertEquals(result.includes("null: null"), true);
// Empty collections
assertEquals(result.includes("emptyList: []"), true);
assertEquals(result.includes("emptyObject: {}"), true);
});
Deno.test("YAML patching - collections and nested structures", () => {
const initialYaml = `
name: my-package
tags:
- node
- typescript
`;
const patches: YamlPatch[] = [
{ op: "set-key", path: "tags", value: ["deno", "typescript", "yaml"] },
{ op: "set-key", path: "dependencies", value: ["std", "testing"] },
{
op: "set-key",
path: "config",
value: {
port: 3000,
host: "localhost",
settings: {
debug: true,
timeout: 5000,
},
},
},
];
const result = applyPatches(initialYaml, patches);
assertExists(result);
// Array values
assertEquals(result.includes("tags:"), true);
assertEquals(result.includes("- deno"), true);
assertEquals(result.includes("- typescript"), true);
assertEquals(result.includes("- yaml"), true);
assertEquals(result.includes("dependencies:"), true);
assertEquals(result.includes("- std"), true);
assertEquals(result.includes("- testing"), true);
// Nested object values
assertEquals(result.includes("config:"), true);
assertEquals(result.includes(" port: 3000"), true);
assertEquals(result.includes(" host: localhost"), true);
assertEquals(result.includes(" debug: true"), true);
assertEquals(result.includes(" timeout: 5000"), true);
});
Deno.test("YAML patching - comments and formatting preservation", () => {
const initialYaml = `
# Main package configuration
name: my-package # The package name
version: 1.0.0 # Current version
description: A sample package
# Additional metadata
author: John Doe # Package maintainer
license: MIT # License type
`;
const patches: YamlPatch[] = [
{ op: "set-key", path: "version", value: "2.0.0" },
{ op: "set-key", path: "description", value: "An updated package" },
{ op: "set-key", path: "newProp", value: "new value" },
];
const result = applyPatches(initialYaml, patches);
// Verify all comments are preserved
assertEquals(result.includes("# Main package configuration"), true);
assertEquals(result.includes("# The package name"), true);
assertEquals(result.includes("# Current version"), true);
assertEquals(result.includes("# Additional metadata"), true);
assertEquals(result.includes("# Package maintainer"), true);
assertEquals(result.includes("# License type"), true);
// Verify content is correct and in order
assertEquals(result.includes("version: 2.0.0"), true);
assertEquals(result.includes("description: An updated package"), true);
assertEquals(result.includes("newProp: new value"), true);
// Verify trailing newlines are preserved
assertEquals(result.endsWith("\n"), true);
const lines = result.split("\n");
assertEquals(lines[lines.length - 1], "");
});
Deno.test("YAML patching - edge cases", () => {
// Test empty input
const emptyResult = applyPatches("", [
{ op: "set-key", path: "name", value: "new-package" },
]);
assertEquals(emptyResult.trim(), "name: new-package");
// Test single line with trailing newline
const singleLineResult = applyPatches("key: value\n", [
{ op: "set-key", path: "key", value: "new value" },
]);
assertEquals(singleLineResult, "key: new value\n");
// Test multiple trailing newlines
const multiNewlineResult = applyPatches("key: value\n\n\n", [
{ op: "set-key", path: "key", value: "new value" },
]);
assertEquals(multiNewlineResult, "key: new value\n");
});
Deno.test("YAML patching - delete key basic operations", () => {
const initialYaml = `
name: my-package
version: 1.0.0
description: A sample package
author: John Doe
license: MIT
`;
const patches: YamlPatch[] = [
{ op: "delete-key", path: "version" },
{ op: "delete-key", path: "author" },
];
const result = applyPatches(initialYaml, patches);
assertExists(result);
// Verify deleted keys are gone
assertEquals(result.includes("version:"), false);
assertEquals(result.includes("author:"), false);
// Verify remaining keys are still present
assertEquals(result.includes("name: my-package"), true);
assertEquals(result.includes("description: A sample package"), true);
assertEquals(result.includes("license: MIT"), true);
});
Deno.test("YAML patching - delete key with comments", () => {
const initialYaml = `
# Package configuration
name: my-package
# Version number
version: 1.0.0 # Current version
# Description
description: A sample package
author: John Doe # Main author
`;
const patches: YamlPatch[] = [
{ op: "delete-key", path: "version" },
];
const result = applyPatches(initialYaml, patches);
// Verify the key and its comments are removed
assertEquals(result.includes("version:"), false);
assertEquals(result.includes("# Version number"), false);
assertEquals(result.includes("# Current version"), false);
// Verify other content remains
assertEquals(result.includes("# Package configuration"), true);
assertEquals(result.includes("name: my-package"), true);
assertEquals(result.includes("# Description"), true);
assertEquals(result.includes("description: A sample package"), true);
assertEquals(result.includes("author: John Doe"), true);
assertEquals(result.includes("# Main author"), true);
});
Deno.test("YAML patching - delete key with list values", () => {
const initialYaml = `
name: my-package
tags:
- node
- typescript
- yaml
dependencies:
- std
- testing
author: John Doe
`;
const patches: YamlPatch[] = [
{ op: "delete-key", path: "tags" },
];
const result = applyPatches(initialYaml, patches);
// Verify the key and its list values are removed
assertEquals(result.includes("tags:"), false);
assertEquals(result.includes("- node"), false);
assertEquals(result.includes("- typescript"), false);
assertEquals(result.includes("- yaml"), false);
// Verify other content remains
assertEquals(result.includes("name: my-package"), true);
assertEquals(result.includes("dependencies:"), true);
assertEquals(result.includes("- std"), true);
assertEquals(result.includes("- testing"), true);
assertEquals(result.includes("author: John Doe"), true);
});
Deno.test("YAML patching - delete key with nested object values", () => {
const initialYaml = `
name: my-package
config:
port: 3000
host: localhost
settings:
debug: true
timeout: 5000
author: John Doe
`;
const patches: YamlPatch[] = [
{ op: "delete-key", path: "config" },
];
const result = applyPatches(initialYaml, patches);
// Verify the key and its nested content are removed
assertEquals(result.includes("config:"), false);
assertEquals(result.includes("port: 3000"), false);
assertEquals(result.includes("host: localhost"), false);
assertEquals(result.includes("debug: true"), false);
assertEquals(result.includes("timeout: 5000"), false);
// Verify other content remains
assertEquals(result.includes("name: my-package"), true);
assertEquals(result.includes("author: John Doe"), true);
});
Deno.test("YAML patching - delete non-existent key", () => {
const initialYaml = `
name: my-package
version: 1.0.0
`;
const patches: YamlPatch[] = [
{ op: "delete-key", path: "nonexistent" },
];
const result = applyPatches(initialYaml, patches);
// Verify nothing changes when deleting a non-existent key
assertEquals(result.includes("name: my-package"), true);
assertEquals(result.includes("version: 1.0.0"), true);
assertEquals(result, initialYaml);
});
Deno.test("YAML patching - mixed set and delete operations", () => {
const initialYaml = `
name: my-package
version: 1.0.0
description: A sample package
author: John Doe
license: MIT
`;
const patches: YamlPatch[] = [
{ op: "set-key", path: "version", value: "2.0.0" },
{ op: "delete-key", path: "author" },
{ op: "set-key", path: "maintainer", value: "Jane Smith" },
{ op: "delete-key", path: "description" },
];
const result = applyPatches(initialYaml, patches);
// Verify deletions
assertEquals(result.includes("author:"), false);
assertEquals(result.includes("description:"), false);
// Verify updates and additions
assertEquals(result.includes("version: 2.0.0"), true);
assertEquals(result.includes("maintainer: Jane Smith"), true);
// Verify unchanged content
assertEquals(result.includes("name: my-package"), true);
assertEquals(result.includes("license: MIT"), true);
});
Deno.test("YAML patching - delete all keys", () => {
const initialYaml = `
name: my-package
version: 1.0.0
`;
const patches: YamlPatch[] = [
{ op: "delete-key", path: "name" },
{ op: "delete-key", path: "version" },
];
const result = applyPatches(initialYaml, patches);
// Result should be effectively empty (just newlines)
assertEquals(result.trim(), "");
});
Deno.test("YAML patching - delete key preserves surrounding structure", () => {
const initialYaml = `
# Header comment
name: my-package
version: 1.0.0
description: A sample package
# Footer comment
license: MIT
`;
const patches: YamlPatch[] = [
{ op: "delete-key", path: "version" },
];
const result = applyPatches(initialYaml, patches);
// Verify structure is maintained
assertEquals(result.includes("# Header comment"), true);
assertEquals(result.includes("name: my-package"), true);
assertEquals(result.includes("description: A sample package"), true);
assertEquals(result.includes("# Footer comment"), true);
assertEquals(result.includes("license: MIT"), true);
// Verify deleted key is gone
assertEquals(result.includes("version:"), false);
});