Skip to content

Commit

Permalink
WIP - validation
Browse files Browse the repository at this point in the history
  • Loading branch information
mvollmer committed Jan 2, 2025
1 parent 2c7b21e commit 5791647
Show file tree
Hide file tree
Showing 6 changed files with 605 additions and 8 deletions.
1 change: 1 addition & 0 deletions files.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ const info = {
"base1/test-types.ts",
"base1/test-user.js",
"base1/test-websocket.js",
"base1/test-import-json.ts",

"kdump/test-config-client.js",

Expand Down
264 changes: 264 additions & 0 deletions pkg/base1/test-import-json.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
/*
* This file is part of Cockpit.
*
* Copyright (C) 2024 Red Hat, Inc.
*
* Cockpit is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* Cockpit is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Cockpit; If not, see <https://www.gnu.org/licenses/>.
*/

import { JsonValue } from 'cockpit';
import {
import_json_object, import_optional, import_mandatory,
import_string, import_number, import_boolean,
import_array, import_record,
validate
} from "import-json";

import QUnit from 'qunit-tests';

// Hook into console.error

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.throws(() => import_string(12), "not a string");
assert.deepEqual(
console_errors,
[
'JSON validation error for : Not a string: 12'
],
"console errors"
);
});

QUnit.test("import_number", function(assert) {
assert.equal(import_number(12), 12, "number");
assert.throws(() => import_number("foo"), "not a number");
assert.deepEqual(
console_errors,
[
'JSON validation error for : Not a number: "foo"'
],
"console errors"
);
});

QUnit.test("import_boolean", function(assert) {
assert.equal(import_boolean(true), true, "boolean");
assert.throws(() => import_boolean("foo"), "not a boolean");
assert.deepEqual(
console_errors,
[
'JSON validation error for : Not a boolean: "foo"'
],
"console errors"
);
});

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([1, 2, "c"], import_number), [1, 2], "array of numbers with a string");
assert.throws(() => import_array("foo", import_string), "not an array");
assert.deepEqual(
console_errors,
[
'JSON validation error for [2]: Not a number: "c"',
'JSON validation error for : Not an array: "foo"'
],
"console errors"
);
});

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.deepEqual(
import_record({ a: 1, b: 2, c: "c" }, import_number),
{ a: 1, b: 2 },
"record of numbers with a string");
assert.throws(() => import_record("foo", import_string), "not a record");
assert.deepEqual(
console_errors,
[
'JSON validation error for .c: Not a number: "c"',
'JSON validation error for : Not an object: "foo"'
],
"console errors"
);
});

QUnit.test("validate", function(assert) {
assert.equal(validate("test input", "foo", import_string, ""), "foo", "string");
assert.equal(validate("test input", 12, import_string, ""), "", "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;
}

function import_Player(val: JsonValue): Player {
const obj = import_json_object(val);
const res: Player = {
name: import_mandatory(obj, "name", import_string),
};
import_optional(res, obj, "age", import_number);
return res;
}

interface Team {
name: string;
players: Player[];
}

function import_Team(val: JsonValue): Team {
const obj = import_json_object(val);
const res: Team = {
name: import_mandatory(obj, "name", import_string),
players: import_mandatory(obj, "players", v => import_array(v, import_Player))
};
return res;
}

interface Teams {
[name: string]: Team;
}

function import_Teams(val: JsonValue): Teams {
return import_record(val, import_Team);
}

QUnit.test("objects", function(assert) {
const checks: [JsonValue, Teams][] = [
[
{
MAC: {
name: "ManCity",
players: [
{ name: "Haaland", age: 24 },
{ name: "De Bruyne", age: 33 }
],
stadium: "City of Manchester Stadium"
},
},
{
MAC: {
name: "ManCity",
players: [
{ name: "Haaland", age: 24 },
{ name: "De Bruyne", age: 33 }
],
},
}

],
[
{
MAC: {
name: "ManCity",
players: [
{ name: "Haaland", age: "unknown" },
{ name: "De Bruyne", age: 33 }
],
stadium: "City of Manchester Stadium"
},
},
{
MAC: {
name: "ManCity",
players: [
{ name: "Haaland" },
{ name: "De Bruyne", age: 33 }
],
},
}

],
[
{
MAC: {
name: "ManCity",
players: [
{ name: ["Erling", "Braut", "Haaland"] },
{ name: "De Bruyne", age: 33 }
],
stadium: "City of Manchester Stadium"
},
},
{
MAC: {
name: "ManCity",
players: [
{ name: "De Bruyne", age: 33 }
],
},
}
],
[
{
MAC: {
name: "ManCity",
players: "TBD",
stadium: "City of Manchester Stadium"
},
},
{}
],
[
"...",
{}
]
];

for (let i = 0; i < checks.length; i++) {
assert.deepEqual(validate("test input", checks[i][0], import_Teams, {}), checks[i][1]);
}

assert.deepEqual(
console_errors,
[
'JSON validation error for test input.MAC.players[0].age: Not a number: "unknown"',
'JSON validation error for test input.MAC.players[0].name: Not a string: ["Erling","Braut","Haaland"]',
'JSON validation error for test input.MAC.players: Not an array: "TBD"',
'JSON validation error for test input: Not an object: "..."'
],
"console errors"
);
});

QUnit.start();
Loading

0 comments on commit 5791647

Please sign in to comment.