Skip to content

Commit 4c56090

Browse files
authored
Update allOf in-place when removing artificial $ref wrappers (#1827)
Fixes: #1826 Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
1 parent 4917ba7 commit 4c56090

File tree

2 files changed

+113
-9
lines changed

2 files changed

+113
-9
lines changed

src/extension/alterschema/linter/unnecessary_allof_ref_wrapper.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -59,16 +59,17 @@ class UnnecessaryAllOfRefWrapper final : public SchemaTransformRule {
5959
}
6060

6161
assert(iterator != array.end());
62-
auto reference{std::move(iterator->at("$ref"))};
63-
if (iterator->size() == 1) {
64-
schema.at("allOf").erase(iterator);
65-
if (schema.at("allOf").empty()) {
66-
schema.erase("allOf");
67-
}
68-
} else {
62+
63+
auto reference{iterator->at("$ref")};
64+
if (iterator->size() > 1) {
65+
schema.try_assign_before("$ref", std::move(reference), "allOf");
6966
iterator->erase("$ref");
67+
} else if (schema.at("allOf").size() == 1) {
68+
schema.at("allOf").into(std::move(reference));
69+
schema.rename("allOf", "$ref");
70+
} else {
71+
schema.try_assign_before("$ref", std::move(reference), "allOf");
72+
schema.at("allOf").erase(iterator);
7073
}
71-
72-
schema.assign("$ref", std::move(reference));
7374
}
7475
};

test/alterschema/alterschema_lint_2020_12_test.cc

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,6 +1843,109 @@ TEST(AlterSchema_lint_2020_12, unnecessary_allof_ref_wrapper_5) {
18431843
EXPECT_EQ(document, expected);
18441844
}
18451845

1846+
TEST(AlterSchema_lint_2020_12, unnecessary_allof_ref_wrapper_6) {
1847+
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
1848+
"$schema": "https://json-schema.org/draft/2020-12/schema",
1849+
"allOf": [
1850+
{ "$ref": "https://example.com" }
1851+
],
1852+
"title": "Foo"
1853+
})JSON");
1854+
1855+
LINT_AND_FIX_FOR_READABILITY(document);
1856+
1857+
const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
1858+
"$schema": "https://json-schema.org/draft/2020-12/schema",
1859+
"$ref": "https://example.com",
1860+
"title": "Foo"
1861+
})JSON");
1862+
1863+
EXPECT_EQ(document, expected);
1864+
1865+
// We expect the `$ref` keyword to take the place of `allOf` in
1866+
// terms of keyword ordering
1867+
std::vector<sourcemeta::core::JSON::String> keywords;
1868+
for (const auto &entry : document.as_object()) {
1869+
keywords.emplace_back(entry.first);
1870+
}
1871+
1872+
EXPECT_EQ(keywords.size(), 3);
1873+
EXPECT_EQ(keywords.at(0), "$schema");
1874+
EXPECT_EQ(keywords.at(1), "$ref");
1875+
EXPECT_EQ(keywords.at(2), "title");
1876+
}
1877+
1878+
TEST(AlterSchema_lint_2020_12, unnecessary_allof_ref_wrapper_7) {
1879+
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
1880+
"$schema": "https://json-schema.org/draft/2020-12/schema",
1881+
"allOf": [
1882+
{ "$ref": "https://example.com" },
1883+
{ "type": "string" }
1884+
],
1885+
"title": "Foo"
1886+
})JSON");
1887+
1888+
LINT_AND_FIX_FOR_READABILITY(document);
1889+
1890+
const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
1891+
"$schema": "https://json-schema.org/draft/2020-12/schema",
1892+
"$ref": "https://example.com",
1893+
"allOf": [
1894+
{ "type": "string" }
1895+
],
1896+
"title": "Foo"
1897+
})JSON");
1898+
1899+
EXPECT_EQ(document, expected);
1900+
1901+
// We expect the `$ref` keyword to take the place of `allOf` in
1902+
// terms of keyword ordering
1903+
std::vector<sourcemeta::core::JSON::String> keywords;
1904+
for (const auto &entry : document.as_object()) {
1905+
keywords.emplace_back(entry.first);
1906+
}
1907+
1908+
EXPECT_EQ(keywords.size(), 4);
1909+
EXPECT_EQ(keywords.at(0), "$schema");
1910+
EXPECT_EQ(keywords.at(1), "$ref");
1911+
EXPECT_EQ(keywords.at(2), "allOf");
1912+
EXPECT_EQ(keywords.at(3), "title");
1913+
}
1914+
1915+
TEST(AlterSchema_lint_2020_12, unnecessary_allof_ref_wrapper_8) {
1916+
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
1917+
"$schema": "https://json-schema.org/draft/2020-12/schema",
1918+
"allOf": [
1919+
{ "type": "string", "$ref": "https://example.com" }
1920+
],
1921+
"title": "Foo"
1922+
})JSON");
1923+
1924+
LINT_AND_FIX_FOR_READABILITY(document);
1925+
1926+
const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
1927+
"$schema": "https://json-schema.org/draft/2020-12/schema",
1928+
"$ref": "https://example.com",
1929+
"allOf": [ { "type": "string" } ],
1930+
"title": "Foo"
1931+
})JSON");
1932+
1933+
EXPECT_EQ(document, expected);
1934+
1935+
// We expect the `$ref` keyword to take the place of `allOf` in
1936+
// terms of keyword ordering
1937+
std::vector<sourcemeta::core::JSON::String> keywords;
1938+
for (const auto &entry : document.as_object()) {
1939+
keywords.emplace_back(entry.first);
1940+
}
1941+
1942+
EXPECT_EQ(keywords.size(), 4);
1943+
EXPECT_EQ(keywords.at(0), "$schema");
1944+
EXPECT_EQ(keywords.at(1), "$ref");
1945+
EXPECT_EQ(keywords.at(2), "allOf");
1946+
EXPECT_EQ(keywords.at(3), "title");
1947+
}
1948+
18461949
TEST(AlterSchema_lint_2020_12, multiple_of_default_1) {
18471950
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
18481951
"$schema": "https://json-schema.org/draft/2020-12/schema",

0 commit comments

Comments
 (0)