Skip to content

Commit c71f3dc

Browse files
authored
Make path optional in SchemaConfig (#1993)
Signed-off-by: Juan Cruz Viotti <[email protected]>
1 parent 6c68c28 commit c71f3dc

File tree

4 files changed

+83
-49
lines changed

4 files changed

+83
-49
lines changed

src/extension/schemaconfig/parse.cc

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ auto SchemaConfig::from_json(const JSON &value,
3535
SCHEMACONFIG_ENSURE(!value.defines("website") ||
3636
value.at("website").is_string(),
3737
"The website property must be a string", {"website"});
38-
SCHEMACONFIG_ENSURE(value.defines("path"), "The path property is required",
39-
{"path"});
40-
SCHEMACONFIG_ENSURE(value.at("path").is_string(),
38+
SCHEMACONFIG_ENSURE(!value.defines("path") || value.at("path").is_string(),
4139
"The path property must be a string", {"path"});
4240
SCHEMACONFIG_ENSURE(!value.defines("baseUri") ||
4341
value.at("baseUri").is_string(),
@@ -66,11 +64,16 @@ auto SchemaConfig::from_json(const JSON &value,
6664
sourcemeta::core::from_json<decltype(result.website)::value_type>(
6765
value.at_or("website", JSON{nullptr}));
6866

69-
const std::filesystem::path path{value.at("path").to_string()};
70-
if (path.is_absolute()) {
71-
result.absolute_path = std::filesystem::weakly_canonical(path);
67+
if (value.defines("path")) {
68+
const std::filesystem::path path{value.at("path").to_string()};
69+
if (path.is_absolute()) {
70+
result.absolute_path = std::filesystem::weakly_canonical(path);
71+
} else {
72+
result.absolute_path =
73+
std::filesystem::weakly_canonical(base_path / path);
74+
}
7275
} else {
73-
result.absolute_path = std::filesystem::weakly_canonical(base_path / path);
76+
result.absolute_path = std::filesystem::weakly_canonical(base_path);
7477
}
7578

7679
assert(result.absolute_path.is_absolute());

test/schemaconfig/schemaconfig_from_json_test.cc

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -129,71 +129,83 @@ TEST(SchemaConfig_from_json, valid_4) {
129129
EXPECT_EQ(manifest.extra.at("x-foo").to_string(), "bar");
130130
}
131131

132-
TEST(SchemaConfig_from_json, invalid_1) {
133-
const auto input{sourcemeta::core::parse_json("{}")};
134-
EXPECT_SCHEMACONFIG_FROM_JSON_PARSE_ERROR(
135-
input, TEST_DIRECTORY, "The path property is required", "/path");
132+
TEST(SchemaConfig_from_json, valid_without_path) {
133+
const auto input{sourcemeta::core::parse_json(R"JSON({
134+
"title": "Test Project"
135+
})JSON")};
136+
137+
const auto manifest{
138+
sourcemeta::core::SchemaConfig::from_json(input, TEST_DIRECTORY)};
139+
140+
EXPECT_TRUE(manifest.title.has_value());
141+
EXPECT_EQ(manifest.title.value(), "Test Project");
142+
EXPECT_FALSE(manifest.description.has_value());
143+
EXPECT_FALSE(manifest.email.has_value());
144+
EXPECT_FALSE(manifest.github.has_value());
145+
EXPECT_FALSE(manifest.website.has_value());
146+
EXPECT_EQ(manifest.absolute_path, TEST_DIRECTORY);
147+
EXPECT_EQ(
148+
manifest.base,
149+
sourcemeta::core::URI::from_path(manifest.absolute_path).recompose());
150+
EXPECT_FALSE(manifest.default_dialect.has_value());
151+
EXPECT_EQ(manifest.resolve.size(), 0);
152+
EXPECT_EQ(manifest.extra.size(), 0);
136153
}
137154

138-
TEST(SchemaConfig_from_json, invalid_2) {
155+
TEST(SchemaConfig_from_json, invalid_1) {
139156
const auto input{sourcemeta::core::parse_json("[]")};
140157
EXPECT_SCHEMACONFIG_FROM_JSON_PARSE_ERROR(
141158
input, TEST_DIRECTORY, "The configuration must be an object", "");
142159
}
143160

144-
TEST(SchemaConfig_from_json, invalid_3) {
161+
TEST(SchemaConfig_from_json, invalid_2) {
145162
const auto input{sourcemeta::core::parse_json(R"JSON({
146-
"title": 1,
147-
"path": "./schemas"
163+
"title": 1
148164
})JSON")};
149165

150166
EXPECT_SCHEMACONFIG_FROM_JSON_PARSE_ERROR(
151167
input, TEST_DIRECTORY, "The title property must be a string", "/title");
152168
}
153169

154-
TEST(SchemaConfig_from_json, invalid_4) {
170+
TEST(SchemaConfig_from_json, invalid_3) {
155171
const auto input{sourcemeta::core::parse_json(R"JSON({
156-
"description": 1,
157-
"path": "./schemas"
172+
"description": 1
158173
})JSON")};
159174

160175
EXPECT_SCHEMACONFIG_FROM_JSON_PARSE_ERROR(
161176
input, TEST_DIRECTORY, "The description property must be a string",
162177
"/description");
163178
}
164179

165-
TEST(SchemaConfig_from_json, invalid_5) {
180+
TEST(SchemaConfig_from_json, invalid_4) {
166181
const auto input{sourcemeta::core::parse_json(R"JSON({
167-
"email": 1,
168-
"path": "./schemas"
182+
"email": 1
169183
})JSON")};
170184

171185
EXPECT_SCHEMACONFIG_FROM_JSON_PARSE_ERROR(
172186
input, TEST_DIRECTORY, "The email property must be a string", "/email");
173187
}
174188

175-
TEST(SchemaConfig_from_json, invalid_6) {
189+
TEST(SchemaConfig_from_json, invalid_5) {
176190
const auto input{sourcemeta::core::parse_json(R"JSON({
177-
"github": 1,
178-
"path": "./schemas"
191+
"github": 1
179192
})JSON")};
180193

181194
EXPECT_SCHEMACONFIG_FROM_JSON_PARSE_ERROR(
182195
input, TEST_DIRECTORY, "The github property must be a string", "/github");
183196
}
184197

185-
TEST(SchemaConfig_from_json, invalid_7) {
198+
TEST(SchemaConfig_from_json, invalid_6) {
186199
const auto input{sourcemeta::core::parse_json(R"JSON({
187-
"website": 1,
188-
"path": "./schemas"
200+
"website": 1
189201
})JSON")};
190202

191203
EXPECT_SCHEMACONFIG_FROM_JSON_PARSE_ERROR(
192204
input, TEST_DIRECTORY, "The website property must be a string",
193205
"/website");
194206
}
195207

196-
TEST(SchemaConfig_from_json, invalid_8) {
208+
TEST(SchemaConfig_from_json, invalid_7) {
197209
const auto input{sourcemeta::core::parse_json(R"JSON({
198210
"path": 1
199211
})JSON")};
@@ -202,80 +214,73 @@ TEST(SchemaConfig_from_json, invalid_8) {
202214
input, TEST_DIRECTORY, "The path property must be a string", "/path");
203215
}
204216

205-
TEST(SchemaConfig_from_json, invalid_9) {
217+
TEST(SchemaConfig_from_json, invalid_8) {
206218
const auto input{sourcemeta::core::parse_json(R"JSON({
207-
"baseUri": 1,
208-
"path": "./schemas"
219+
"baseUri": 1
209220
})JSON")};
210221

211222
EXPECT_SCHEMACONFIG_FROM_JSON_PARSE_ERROR(
212223
input, TEST_DIRECTORY, "The baseUri property must be a string",
213224
"/baseUri");
214225
}
215226

216-
TEST(SchemaConfig_from_json, invalid_10) {
227+
TEST(SchemaConfig_from_json, invalid_9) {
217228
const auto input{sourcemeta::core::parse_json(R"JSON({
218-
"defaultDialect": 1,
219-
"path": "./schemas"
229+
"defaultDialect": 1
220230
})JSON")};
221231

222232
EXPECT_SCHEMACONFIG_FROM_JSON_PARSE_ERROR(
223233
input, TEST_DIRECTORY, "The defaultDialect property must be a string",
224234
"/defaultDialect");
225235
}
226236

227-
TEST(SchemaConfig_from_json, invalid_11) {
237+
TEST(SchemaConfig_from_json, invalid_10) {
228238
const auto input{sourcemeta::core::parse_json(R"JSON({
229-
"resolve": 1,
230-
"path": "./schemas"
239+
"resolve": 1
231240
})JSON")};
232241

233242
EXPECT_SCHEMACONFIG_FROM_JSON_PARSE_ERROR(
234243
input, TEST_DIRECTORY, "The resolve property must be an object",
235244
"/resolve");
236245
}
237246

238-
TEST(SchemaConfig_from_json, invalid_12) {
247+
TEST(SchemaConfig_from_json, invalid_11) {
239248
const auto input{sourcemeta::core::parse_json(R"JSON({
240249
"resolve": {
241250
"foo": 1
242-
},
243-
"path": "./schemas"
251+
}
244252
})JSON")};
245253

246254
EXPECT_SCHEMACONFIG_FROM_JSON_PARSE_ERROR(
247255
input, TEST_DIRECTORY, "The values in the resolve object must be strings",
248256
"/resolve/foo");
249257
}
250258

251-
TEST(SchemaConfig_from_json, invalid_13) {
259+
TEST(SchemaConfig_from_json, invalid_12) {
252260
const auto input{sourcemeta::core::parse_json(R"JSON({
253-
"baseUri": "%",
254-
"path": "./schemas"
261+
"baseUri": "%"
255262
})JSON")};
256263

257264
EXPECT_SCHEMACONFIG_FROM_JSON_PARSE_ERROR(
258265
input, TEST_DIRECTORY, "The baseUri property must represent a valid URI",
259266
"/baseUri");
260267
}
261268

262-
TEST(SchemaConfig_from_json, invalid_14) {
269+
TEST(SchemaConfig_from_json, invalid_13) {
263270
const auto input{sourcemeta::core::parse_json(R"JSON({
264-
"baseUri": "relative",
265-
"path": "./schemas"
271+
"baseUri": "relative"
266272
})JSON")};
267273

268274
EXPECT_SCHEMACONFIG_FROM_JSON_PARSE_ERROR(
269275
input, TEST_DIRECTORY, "The baseUri property must be an absolute URI",
270276
"/baseUri");
271277
}
272278

273-
TEST(SchemaConfig_from_json, invalid_15) {
279+
TEST(SchemaConfig_from_json, invalid_14) {
274280
const auto input{sourcemeta::core::parse_json(R"JSON({
275281
"resolve": {
276282
"foo": "%"
277-
},
278-
"path": "./schemas"
283+
}
279284
})JSON")};
280285

281286
EXPECT_SCHEMACONFIG_FROM_JSON_PARSE_ERROR(

test/schemaconfig/schemaconfig_read_json_test.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,25 @@ TEST(SchemaConfig_read_json, valid_1) {
2828
"../single.json");
2929
EXPECT_EQ(manifest.extra.size(), 0);
3030
}
31+
32+
TEST(SchemaConfig_read_json, valid_without_path) {
33+
const auto path{std::filesystem::path{TEST_DIRECTORY} /
34+
"stub-valid-no-path.json"};
35+
const auto manifest{sourcemeta::core::SchemaConfig::read_json(path)};
36+
37+
EXPECT_TRUE(manifest.title.has_value());
38+
EXPECT_EQ(manifest.title.value(), "Test Config Without Path");
39+
EXPECT_TRUE(manifest.description.has_value());
40+
EXPECT_EQ(manifest.description.value(),
41+
"A test configuration file without a path property");
42+
EXPECT_FALSE(manifest.email.has_value());
43+
EXPECT_FALSE(manifest.github.has_value());
44+
EXPECT_FALSE(manifest.website.has_value());
45+
EXPECT_EQ(manifest.absolute_path, TEST_DIRECTORY);
46+
EXPECT_EQ(
47+
manifest.base,
48+
sourcemeta::core::URI::from_path(manifest.absolute_path).recompose());
49+
EXPECT_FALSE(manifest.default_dialect.has_value());
50+
EXPECT_EQ(manifest.resolve.size(), 0);
51+
EXPECT_EQ(manifest.extra.size(), 0);
52+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"title": "Test Config Without Path",
3+
"description": "A test configuration file without a path property"
4+
}

0 commit comments

Comments
 (0)