Skip to content

Commit 9b289aa

Browse files
passes tests again
1 parent bf765ab commit 9b289aa

File tree

6 files changed

+135
-28
lines changed

6 files changed

+135
-28
lines changed

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"type": "cppdbg",
77
"request": "launch",
88
"program": "/home/daniele/git/simple-json-validator/build/tests/unit_tests",
9-
"args": ["file_01"],
9+
"args": ["file_type"],
1010
"stopAtEntry": false,
1111
"cwd": "/home/daniele/git/simple-json-validator/build/",
1212
"environment": [],

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
1. write a function to complete fields with default
2+
2. write a function to find all children of a pointer
3+
3. vector type
4+
4. *
5+

data/rules_01.json

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"pointer": "/geometry/",
1010
"type": "object",
1111
"required": ["mesh"],
12+
"optional": ["transformation","volume_selection","surface_selection","n_refs","advanced"],
1213
"doc": "Each geometry object stores a mesh, a set of transformations applied to it after loading, and a set of selections, which can be used to specify boundary conditions and materials."
1314
},
1415
{
@@ -20,24 +21,30 @@
2021
{
2122
"pointer": "/geometry/transformation/",
2223
"type": "object",
24+
"default": null,
25+
"optional": ["translation","rotation","scale"],
2326
"doc": "Geometric transformations applied to the geometry after loading it."
2427
},
2528
{
2629
"pointer": "/geometry/transformation/translation/",
2730
"type": "float",
31+
"default": [0,0,0],
2832
"doc": "Translation vector (2 entries for 2D problems, 3 entries for 3D problems)."
2933
},
3034
{
3135
"pointer": "/geometry/transformation/rotation/",
36+
"default": 0,
3237
"type": "float"
3338
},
3439
{
3540
"pointer": "/geometry/transformation/scale/",
41+
"default": 0,
3642
"type": "float"
3743
},
3844
{
3945
"pointer": "/geometry/volume_selection/",
40-
"type": "int"
46+
"type": "int",
47+
"default": 0
4148
},
4249
{
4350
"pointer": "/geometry/volume_selection/",
@@ -46,7 +53,8 @@
4653
},
4754
{
4855
"pointer": "/geometry/surface_selection/",
49-
"type": "int"
56+
"type": "int",
57+
"default": null
5058
},
5159
{
5260
"pointer": "/geometry/surface_selection/",
@@ -55,15 +63,19 @@
5563
},
5664
{
5765
"pointer": "/geometry/n_refs/",
58-
"type": "int"
66+
"type": "int",
67+
"default": 0
5968
},
6069
{
6170
"pointer": "/geometry/advanced/",
62-
"type": "object"
71+
"type": "object",
72+
"optional": ["normalize_mesh"],
73+
"default": null
6374
},
6475
{
6576
"pointer": "/geometry/advanced/normalize_mesh/",
66-
"type": "bool"
77+
"type": "bool",
78+
"default": false
6779
}
6880

6981
]

src/sjv/sjv.cpp

Lines changed: 56 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,18 +73,50 @@ namespace sjv
7373
// If it passes and if it is a dictionary, then test all childrens
7474
if (input.is_structured())
7575
for (auto &i : input.items())
76-
if (!verify_json(pointer + i.key() + "/", i.value(), rules))
76+
{
77+
string new_pointer = pointer + i.key() + "/";
78+
// first of all, let's check if the specs are correct
79+
json defaults = collect_default_rules(new_pointer,rules);
80+
81+
// if it is mandatory, make sure there are no defaults
82+
if (matching_rules[0].contains("required") && contained_in_list(i.key(),matching_rules[0]["required"]))
83+
{
84+
if (defaults.size() != 0)
85+
{
86+
log.push_back(log_item("error","Inconsistent specifications: " + new_pointer + " is a mandatory field with a default value."));
87+
return false;
88+
}
89+
}
90+
// if it is optional, there should be only one default in the specs
91+
else if (matching_rules[0].contains("optional") && contained_in_list(i.key(),matching_rules[0]["optional"]))
92+
{
93+
if (defaults.size() != 1)
94+
{
95+
log.push_back(log_item("error","Inconsistent specifications: " + new_pointer + " is an optional field with " + std::to_string(defaults.size()) + " default values."));
96+
return false;
97+
}
98+
}
99+
// if it is not mandatory and not optional, something is wrong
100+
else
101+
{
102+
log.push_back(log_item("warning","Inconsistent specifications: " + new_pointer + " is neither an optional or a mandatory field."));
103+
if (strict)
104+
return false;
105+
}
106+
107+
// now let's make sure it can be validated
108+
if (!verify_json(new_pointer, i.value(), rules))
77109
return false;
78110

111+
}
112+
79113
// If they all pass, return true
80114
return true;
81115
};
82116
bool sjv::verify_rule(const json &input, const json &rule)
83117
{
84118
string type = rule.at("type");
85-
if (type == "skip_check")
86-
return true;
87-
else if (type == "float")
119+
if (type == "float")
88120
return verify_rule_float(input, rule);
89121
else if (type == "int")
90122
return verify_rule_int(input, rule);
@@ -233,4 +265,24 @@ namespace sjv
233265
}
234266
return s.str();
235267
};
268+
269+
json sjv::collect_default_rules(const string &pointer, const json &rules)
270+
{
271+
// Find all rules that apply for the input node
272+
// TODO: accelerate this
273+
274+
std::vector<json> matching_rules;
275+
for (auto i : rules)
276+
{
277+
if (i.at("pointer") == pointer && i.contains("default"))
278+
matching_rules.push_back(i);
279+
}
280+
281+
return matching_rules;
282+
};
283+
284+
bool sjv::contained_in_list(string item, const json& list)
285+
{
286+
return std::find(list.begin(),list.end(),item) != list.end();
287+
};
236288
} // namespace sjv

src/sjv/sjv.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ namespace sjv
1414
public:
1515
// verify the input json against the set of rules in specs
1616
bool verify_json(const json &input, const json &rules);
17+
18+
// Verify a node pointed by
1719
bool verify_json(const string &pointer, const json &input, const json &rules);
1820

1921
// Dispatcher for rule verification
@@ -28,6 +30,12 @@ namespace sjv
2830
bool verify_rule_object(const json &input, const json &rule);
2931
bool verify_rule_bool(const json &input, const json &rule);
3032

33+
// Collect all rules having a default for a given pointer
34+
json collect_default_rules(const string &pointer, const json &rules);
35+
36+
// TODO
37+
json generate_default_json(const json &rules);
38+
3139
// Working directory
3240
string cwd = ".";
3341

@@ -40,6 +48,9 @@ namespace sjv
4048

4149
// log to string
4250
std::string log2str();
51+
52+
// Utils
53+
bool contained_in_list(string item, const json& list);
4354
};
4455

4556
} // namespace sjv

tests/test_validator.cpp

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,16 @@ TEST_CASE("single_rule", "[validator]")
2121
[
2222
{
2323
"pointer": "/",
24-
"type": "skip_check"
24+
"type": "object"
2525
}
2626
]
2727
)"_json;
2828

2929
sjv::sjv sjv;
3030

31-
REQUIRE(sjv.verify_json(input,rules));
32-
31+
bool b = sjv.verify_json(input,rules);
32+
INFO(sjv.log2str());
33+
REQUIRE(b);
3334
}
3435

3536
TEST_CASE("only_one_rule_can_be_valid", "[validator]")
@@ -43,18 +44,20 @@ TEST_CASE("only_one_rule_can_be_valid", "[validator]")
4344
[
4445
{
4546
"pointer": "/",
46-
"type": "skip_check"
47+
"type": "object"
4748
},
4849
{
4950
"pointer": "/",
50-
"type": "skip_check"
51+
"type": "object"
5152
}
5253
]
5354
)"_json;
5455

5556
sjv::sjv sjv;
5657

57-
REQUIRE(!sjv.verify_json(input,rules));
58+
bool b = sjv.verify_json(input,rules);
59+
INFO(sjv.log2str());
60+
REQUIRE(!b);
5861
}
5962

6063
TEST_CASE("min_bound_numeric", "[validator]")
@@ -69,7 +72,8 @@ TEST_CASE("min_bound_numeric", "[validator]")
6972
[
7073
{
7174
"pointer": "/",
72-
"type": "skip_check"
75+
"type": "object",
76+
"required": ["field1"]
7377
},
7478
{
7579
"pointer": "/field1/",
@@ -81,11 +85,15 @@ TEST_CASE("min_bound_numeric", "[validator]")
8185

8286
sjv::sjv sjv;
8387

84-
REQUIRE(sjv.verify_json(input,rules));
88+
bool b = sjv.verify_json(input,rules);
89+
INFO(sjv.log2str());
90+
REQUIRE(b);
8591

8692
input["field1"] = 40.5;
8793

88-
REQUIRE(!sjv.verify_json(input,rules));
94+
b = sjv.verify_json(input,rules);
95+
INFO(sjv.log2str());
96+
REQUIRE(!b);
8997
}
9098

9199
TEST_CASE("file_type", "[validator]")
@@ -100,28 +108,40 @@ TEST_CASE("file_type", "[validator]")
100108
[
101109
{
102110
"pointer": "/",
103-
"type": "skip_check"
111+
"type": "object",
112+
"optional": ["file1"]
104113
},
105114
{
106115
"pointer": "/file1/",
107116
"type": "file",
108-
"extensions": [".txt"]
117+
"extensions": [".txt"],
118+
"default": "somestring"
109119
}
110120
]
111121
)"_json;
112122

113123
sjv::sjv sjv;
124+
bool b;
125+
114126
sjv.cwd = std::filesystem::current_path();
127+
sjv.strict = true;
115128

116-
REQUIRE(!sjv.verify_json(input,rules));
129+
b = sjv.verify_json(input,rules);
130+
131+
INFO(sjv.log2str());
132+
REQUIRE(!b);
117133

118134
input["file1"] = "CMakeCache.txt";
119135

120-
REQUIRE(sjv.verify_json(input,rules));
136+
b = sjv.verify_json(input,rules);
137+
INFO(sjv.log2str());
138+
REQUIRE(b);
121139

122140
rules[1]["extensions"][0] = ".msh";
123141

124-
REQUIRE(!sjv.verify_json(input,rules));
142+
b = sjv.verify_json(input,rules);
143+
INFO(sjv.log2str());
144+
REQUIRE(!b);
125145

126146
}
127147

@@ -137,7 +157,7 @@ TEST_CASE("type_string", "[validator]")
137157
[
138158
{
139159
"pointer": "/",
140-
"type": "skip_check"
160+
"type": "object"
141161
},
142162
{
143163
"pointer": "/string1/",
@@ -148,15 +168,22 @@ TEST_CASE("type_string", "[validator]")
148168

149169
sjv::sjv sjv;
150170

151-
REQUIRE(sjv.verify_json(input,rules));
171+
bool b;
172+
b = sjv.verify_json(input,rules);
173+
INFO(sjv.log2str());
174+
REQUIRE(b);
152175

153176
rules[1]["options"][0] = "blah";
154177

155-
REQUIRE(!sjv.verify_json(input,rules));
178+
b = sjv.verify_json(input,rules);
179+
INFO(sjv.log2str());
180+
REQUIRE(!b);
156181

157182
rules[1]["options"][1] = "teststring";
158183

159-
REQUIRE(sjv.verify_json(input,rules));
184+
b = sjv.verify_json(input,rules);
185+
INFO(sjv.log2str());
186+
REQUIRE(b);
160187

161188
}
162189

0 commit comments

Comments
 (0)