* Copyright (C) 2024 Red Hat, Inc.
* SPDX-License-Identifier: LGPL-2.1-or-later
*/
import { JsonValue } from 'cockpit';
import {
import_json_object, get, get_optional,
import_string, import_number, import_boolean,
import_array, import_record,
validate
} from 'import-json';
import QUnit from 'qunit-tests';
let console_errors: string[] = [];
const console_error = console.error;
console.error = function (msg) {
console_errors.push(msg);
console_error(msg);
};
QUnit.hooks.beforeEach(() => {
console_errors = [];
});
QUnit.test("import_string", function(assert) {
assert.equal(import_string("foo"), "foo", "string");
assert.equal(import_string(""), "", "empty string");
assert.throws(() => import_string(12), /JSON validation error for : Not a string: 12/, "not a string");
});
QUnit.test("import_number", function(assert) {
assert.equal(import_number(12), 12, "number");
assert.throws(
() => import_number("foo"),
/JSON validation error for : Not a number: "foo"/,
"not a number");
});
QUnit.test("import_boolean", function(assert) {
assert.equal(import_boolean(true), true, "boolean");
assert.throws(
() => import_boolean("foo"),
/JSON validation error for : Not a boolean: "foo"/,
"not a boolean");
});
QUnit.test("import_array", function(assert) {
assert.deepEqual(import_array(["a", "b", "c"], import_string), ["a", "b", "c"], "array of strings");
assert.deepEqual(import_array([1, 2, 3], import_number), [1, 2, 3], "array of numbers");
assert.deepEqual(import_array([], import_number), [], "empty array");
assert.throws(
() => import_array([1, 2, "c"], import_number),
/JSON validation error for \[2\]: Not a number: "c"/,
"array of numbers with a string");
assert.throws(
() => import_array("foo", import_string),
/JSON validation error for : Not an array: "foo"/,
"not an array");
});
QUnit.test("import_record", function(assert) {
assert.deepEqual(
import_record({ a: "a", b: "b", c: "c" }, import_string),
{ a: "a", b: "b", c: "c" },
"record of strings");
assert.deepEqual(
import_record({ a: 1, b: 2, c: 3 }, import_number),
{ a: 1, b: 2, c: 3 },
"record of numbers");
assert.throws(
() => import_record({ a: 1, b: 2, c: "c" }, import_number),
/JSON validation error for \.c: Not a number: "c"/,
"record of numbers with a string");
assert.throws(
() => import_record("foo", import_string),
/JSON validation error for : Not an object: "foo"/,
"not a record");
});
QUnit.test("validate", function(assert) {
assert.equal(validate("test input", "foo", import_string, "default"), "foo", "string");
assert.equal(validate("test input", 12, import_string, "default"), "default", "not a string");
assert.deepEqual(
console_errors,
[
'JSON validation error for test input: Not a string: 12'
],
"console errors"
);
});
interface Player {
name: string;
age: number | undefined;
position: string;
}
function import_Player(val: JsonValue): Player {
const obj = import_json_object(val);
return {
name: get(obj, "name", import_string),
age: get_optional(obj, "age", import_number),
position: get(obj, "position", import_string, "unknown"),
};
}
interface Team {
name: string;
players: Player[];
}
function import_Team(val: JsonValue): Team {
const obj = import_json_object(val);
return {
name: get(obj, "name", import_string),
players: get(obj, "players", v => import_array(v, import_Player)),
};
}
interface Teams {
[name: string]: Team;
}
function import_Teams(val: JsonValue): Teams {
return import_record(val, import_Team);
}
QUnit.test("objects", function(assert) {
const valid_checks: [JsonValue, Teams][] = [
[
{
MAC: {
name: "ManCity",
players: [
{ name: "Haaland", age: 24, position: "striker" },
{ name: "De Bruyne", age: 33, position: "midfield" }
],
stadium: "City of Manchester Stadium"
},
},
{
MAC: {
name: "ManCity",
players: [
{ name: "Haaland", age: 24, position: "striker" },
{ name: "De Bruyne", age: 33, position: "midfield" }
],
},
}
],
[
{
MAC: {
name: "ManCity",
players: [
{ name: "Haaland", },
{ name: "De Bruyne", age: 33 }
],
},
},
{
MAC: {
name: "ManCity",
players: [
{ name: "Haaland", age: undefined, position: "unknown" },
{ name: "De Bruyne", age: 33, position: "unknown" }
],
},
}
],
];
const invalid_checks: [JsonValue, string][] = [
[
{
MAC: {
name: "ManCity",
players: [
{ name: "Haaland", age: "unknown" },
{ name: "De Bruyne", age: 33 }
],
},
},
'JSON validation error for test input.MAC.players[0].age: Not a number: "unknown"',
],
[
{
MAC: {
name: "ManCity",
players: [
{ name: ["Erling", "Braut", "Haaland"] },
{ name: "De Bruyne", age: 33 }
],
},
},
'JSON validation error for test input.MAC.players[0].name: Not a string: ["Erling","Braut","Haaland"]',
],
[
{
MAC: {
name: "ManCity",
players: "TBD",
},
},
'JSON validation error for test input.MAC.players: Not an array: "TBD"',
],
[
"...",
'JSON validation error for test input: Not an object: "..."'
]
];
for (let i = 0; i < valid_checks.length; i++) {
assert.deepEqual(validate("test input", valid_checks[i][0], import_Teams, {}), valid_checks[i][1]);
}
for (let i = 0; i < invalid_checks.length; i++) {
console_errors = [];
assert.deepEqual(validate("test input", invalid_checks[i][0], import_Teams, {}), {});
assert.deepEqual(console_errors, [invalid_checks[i][1]]);
}
});
QUnit.start();