Skip to content

Commit aaf91a9

Browse files
committed
Don't change the ordering of enumeration values when removing duplicates
Fixes: #1841 Signed-off-by: Juan Cruz Viotti <[email protected]>
1 parent 0be5ca5 commit aaf91a9

9 files changed

+37
-14
lines changed

src/extension/alterschema/linter/duplicate_enum_values.h

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,18 @@ class DuplicateEnumValues final : public SchemaTransformRule {
2929
}
3030

3131
auto transform(JSON &schema) const -> void override {
32-
auto collection = schema.at("enum");
33-
std::sort(collection.as_array().begin(), collection.as_array().end());
34-
auto last =
35-
std::unique(collection.as_array().begin(), collection.as_array().end());
36-
collection.erase(last, collection.as_array().end());
37-
schema.at("enum").into(std::move(collection));
32+
// We want to be super careful to maintain the current ordering
33+
// as we delete the duplicates
34+
auto &enumeration{schema.at("enum")};
35+
std::unordered_set<JSON, HashJSON<JSON>> cache;
36+
for (auto iterator = enumeration.as_array().cbegin();
37+
iterator != enumeration.as_array().cend();) {
38+
if (cache.contains(*iterator)) {
39+
iterator = enumeration.erase(iterator);
40+
} else {
41+
cache.emplace(*iterator);
42+
iterator++;
43+
}
44+
}
3845
}
3946
};

test/alterschema/alterschema_lint_2019_09_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ TEST(AlterSchema_lint_2019_09, duplicate_enum_values_1) {
516516

517517
const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
518518
"$schema": "https://json-schema.org/draft/2019-09/schema",
519-
"enum": [ 1, 2, 3, {} ]
519+
"enum": [ 1, {}, 2, 3 ]
520520
})JSON");
521521

522522
EXPECT_EQ(document, expected);

test/alterschema/alterschema_lint_2020_12_test.cc

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,23 @@ TEST(AlterSchema_lint_2020_12, duplicate_enum_values_1) {
519519

520520
const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
521521
"$schema": "https://json-schema.org/draft/2020-12/schema",
522-
"enum": [ 1, 2, 3, {} ]
522+
"enum": [ 1, {}, 2, 3 ]
523+
})JSON");
524+
525+
EXPECT_EQ(document, expected);
526+
}
527+
528+
TEST(AlterSchema_lint_2020_12, duplicate_enum_values_2) {
529+
sourcemeta::core::JSON document = sourcemeta::core::parse_json(R"JSON({
530+
"$schema": "https://json-schema.org/draft/2020-12/schema",
531+
"enum": [ "S", "C", "U", "F", "E", "N", "L", "R", "U", null ]
532+
})JSON");
533+
534+
LINT_AND_FIX_FOR_READABILITY(document);
535+
536+
const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
537+
"$schema": "https://json-schema.org/draft/2020-12/schema",
538+
"enum": [ "S", "C", "U", "F", "E", "N", "L", "R", null ]
523539
})JSON");
524540

525541
EXPECT_EQ(document, expected);

test/alterschema/alterschema_lint_draft1_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ TEST(AlterSchema_lint_draft1, duplicate_enum_values_1) {
154154

155155
const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
156156
"$schema": "http://json-schema.org/draft-01/schema#",
157-
"enum": [ 1, 2, 3, {} ]
157+
"enum": [ 1, {}, 2, 3 ]
158158
})JSON");
159159

160160
EXPECT_EQ(document, expected);

test/alterschema/alterschema_lint_draft2_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ TEST(AlterSchema_lint_draft2, duplicate_enum_values_2) {
154154

155155
const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
156156
"$schema": "http://json-schema.org/draft-02/schema#",
157-
"enum": [ 1, 2, 3, {} ]
157+
"enum": [ 1, {}, 2, 3 ]
158158
})JSON");
159159

160160
EXPECT_EQ(document, expected);

test/alterschema/alterschema_lint_draft3_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ TEST(AlterSchema_lint_draft3, duplicate_enum_values_3) {
154154

155155
const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
156156
"$schema": "http://json-schema.org/draft-03/schema#",
157-
"enum": [ 1, 2, 3, {} ]
157+
"enum": [ 1, {}, 2, 3 ]
158158
})JSON");
159159

160160
EXPECT_EQ(document, expected);

test/alterschema/alterschema_lint_draft4_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ TEST(AlterSchema_lint_draft4, duplicate_enum_values_4) {
154154

155155
const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
156156
"$schema": "http://json-schema.org/draft-04/schema#",
157-
"enum": [ 1, 2, 3, {} ]
157+
"enum": [ 1, {}, 2, 3 ]
158158
})JSON");
159159

160160
EXPECT_EQ(document, expected);

test/alterschema/alterschema_lint_draft6_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ TEST(AlterSchema_lint_draft6, duplicate_enum_values_6) {
187187

188188
const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
189189
"$schema": "http://json-schema.org/draft-06/schema#",
190-
"enum": [ 1, 2, 3, {} ]
190+
"enum": [ 1, {}, 2, 3 ]
191191
})JSON");
192192

193193
EXPECT_EQ(document, expected);

test/alterschema/alterschema_lint_draft7_test.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ TEST(AlterSchema_lint_draft7, duplicate_enum_values_7) {
283283

284284
const sourcemeta::core::JSON expected = sourcemeta::core::parse_json(R"JSON({
285285
"$schema": "http://json-schema.org/draft-07/schema#",
286-
"enum": [ 1, 2, 3, {} ]
286+
"enum": [ 1, {}, 2, 3 ]
287287
})JSON");
288288

289289
EXPECT_EQ(document, expected);

0 commit comments

Comments
 (0)