CoolProp
8.0.0
An open-source fluid property and humid air property database
src
Tests
CoolProp-Tests-SchemaValidation.cpp
Go to the documentation of this file.
1
// Catch2 tests for CoolProp::validate_json_against_schema and
2
// CoolProp::to_canonical_json_str (CoolProp-bh2).
3
4
#if defined(ENABLE_CATCH)
5
6
# include <catch2/catch_all.hpp>
7
8
# include <string>
9
10
# include "
CoolProp/SchemaValidation.h
"
11
# include "
CoolProp/Exceptions.h
"
12
13
namespace
{
14
15
// Common test schema modelled after the SVDSBTL options schema we're
16
// about to write — exercises objects, nested objects, enums, types,
17
// required keys, and additionalProperties:false (strict mode).
18
constexpr
const
char
* kSchema = R
"({
19
"$schema": "http://json-schema.org/draft-07/schema#",
20
"type": "object",
21
"additionalProperties": false,
22
"required": ["schema"],
23
"properties": {
24
"schema": {"type": "integer", "const": 1},
25
"grid": {
26
"type": "object",
27
"additionalProperties": false,
28
"properties": {
29
"NT": {"type": "integer", "minimum": 2},
30
"NR": {"type": "integer", "minimum": 2},
31
"rank": {"type": "integer", "minimum": 1}
32
}
33
},
34
"critical_patch": {
35
"type": "object",
36
"additionalProperties": false,
37
"properties": {
38
"mode": {"type": "string", "enum": ["auto", "off", "fixed"]},
39
"tolerance": {"type": "number", "exclusiveMinimum": 0},
40
"bbox": {
41
"type": "array",
42
"minItems": 4,
43
"maxItems": 4,
44
"items": {"type": "number"}
45
}
46
}
47
}
48
}
49
})";
50
51
}
// namespace
52
53
// ---------------------------------------------------------------------------
54
// validate_json_against_schema
55
// ---------------------------------------------------------------------------
56
57
TEST_CASE(
"validate_against_schema: minimal valid instance passes"
,
"[SchemaValidation]"
) {
58
REQUIRE_NOTHROW(
CoolProp::validate_json_against_schema
(R
"({"schema": 1})", std::string(kSchema)));
59
}
60
61
TEST_CASE(
"validate_against_schema: fully populated valid instance passes"
,
"[SchemaValidation]"
) {
62
REQUIRE_NOTHROW(
CoolProp::validate_json_against_schema
(R
"({
63
"schema": 1,
64
"grid": {"NT": 200, "NR": 800, "rank": 20},
65
"critical_patch": {"mode": "auto", "tolerance": 1e-3, "bbox": [0.95, 1.05, 0.75, 1.15]}
66
})",
67
std::string(kSchema)));
68
}
69
70
TEST_CASE(
"validate_against_schema: unknown top-level key throws"
,
"[SchemaValidation]"
) {
71
REQUIRE_THROWS_AS(
CoolProp::validate_json_against_schema
(R
"({"schema": 1, "frobnitz": true})", std::string(kSchema)),
CoolProp::ValueError
);
72
}
73
74
TEST_CASE(
"validate_against_schema: unknown nested key throws"
,
"[SchemaValidation]"
) {
75
REQUIRE_THROWS_AS(
CoolProp::validate_json_against_schema
(R
"({"schema": 1, "grid": {"NT": 200, "extra": 3}})", std::string(kSchema)),
76
CoolProp::ValueError
);
77
}
78
79
TEST_CASE(
"validate_against_schema: type mismatch throws"
,
"[SchemaValidation]"
) {
80
REQUIRE_THROWS_AS(
CoolProp::validate_json_against_schema
(R
"({"schema": 1, "grid": {"NT": "two-hundred"}})", std::string(kSchema)),
81
CoolProp::ValueError
);
82
}
83
84
TEST_CASE(
"validate_against_schema: enum violation throws"
,
"[SchemaValidation]"
) {
85
REQUIRE_THROWS_AS(
CoolProp::validate_json_against_schema
(R
"({"schema": 1, "critical_patch": {"mode": "ON"}})", std::string(kSchema)),
86
CoolProp::ValueError
);
87
}
88
89
TEST_CASE(
"validate_against_schema: required key missing throws"
,
"[SchemaValidation]"
) {
90
REQUIRE_THROWS_AS(
CoolProp::validate_json_against_schema
(R
"({"grid": {"NT": 200}})", std::string(kSchema)),
CoolProp::ValueError
);
91
}
92
93
TEST_CASE(
"validate_against_schema: bbox wrong size throws"
,
"[SchemaValidation]"
) {
94
REQUIRE_THROWS_AS(
CoolProp::validate_json_against_schema
(R
"({"schema": 1, "critical_patch": {"bbox": [1, 2, 3]}})", std::string(kSchema)),
95
CoolProp::ValueError
);
96
}
97
98
TEST_CASE(
"validate_against_schema: invalid schema JSON throws"
,
"[SchemaValidation]"
) {
99
REQUIRE_THROWS_AS(
CoolProp::validate_json_against_schema
(R
"({"schema": 1})", std::string(
"not json"
)),
CoolProp::ValueError
);
100
}
101
102
// ---------------------------------------------------------------------------
103
// to_canonical_json_str
104
// ---------------------------------------------------------------------------
105
106
TEST_CASE(
"to_canonical_json: sorts object keys"
,
"[SchemaValidation]"
) {
107
const
auto
a =
CoolProp::to_canonical_json_str
(R
"({"b": 2, "a": 1, "c": 3})");
108
REQUIRE(a == R
"({"a":1,"b":2,"c":3})");
109
}
110
111
TEST_CASE(
"to_canonical_json: sorts nested object keys recursively"
,
"[SchemaValidation]"
) {
112
const
auto
a =
CoolProp::to_canonical_json_str
(R
"({"outer": {"z": 1, "a": 2}, "inner": 3})");
113
REQUIRE(a == R
"({"inner":3,"outer":{"a":2,"z":1}})");
114
}
115
116
TEST_CASE(
"to_canonical_json: preserves array order"
,
"[SchemaValidation]"
) {
117
const
auto
a =
CoolProp::to_canonical_json_str
(R
"([3, 1, 2])");
118
REQUIRE(a == R
"([3,1,2])");
119
}
120
121
TEST_CASE(
"to_canonical_json: logically-equal inputs produce identical output"
,
"[SchemaValidation]"
) {
122
const
auto
a =
CoolProp::to_canonical_json_str
(R
"({"grid":{"NT":200,"rank":20,"NR":800}})");
123
const
auto
b =
CoolProp::to_canonical_json_str
(R
"({"grid":{"rank":20,"NR":800,"NT":200}})");
124
REQUIRE(a == b);
125
}
126
127
TEST_CASE(
"to_canonical_json: idempotent — re-canonicalising returns the same bytes"
,
"[SchemaValidation]"
) {
128
const
auto
a =
CoolProp::to_canonical_json_str
(R
"({"b":2,"a":1})");
129
const
auto
b =
CoolProp::to_canonical_json_str
(a);
130
REQUIRE(a == b);
131
}
132
133
TEST_CASE(
"to_canonical_json: handles all JSON scalar types"
,
"[SchemaValidation]"
) {
134
const
auto
a =
CoolProp::to_canonical_json_str
(R
"({"i":1,"f":1.5,"s":"x","b":true,"n":null,"a":[1,2]})");
135
// Sorted: a, b, f, i, n, s
136
REQUIRE(a == R
"({"a":[1,2],"b":true,"f":1.5,"i":1,"n":null,"s":"x"})");
137
}
138
139
TEST_CASE(
"to_canonical_json: invalid JSON throws"
,
"[SchemaValidation]"
) {
140
REQUIRE_THROWS_AS(
CoolProp::to_canonical_json_str
(std::string(
"{not: json}"
)),
CoolProp::ValueError
);
141
}
142
143
#endif
// ENABLE_CATCH
Generated by
1.9.4