Skip to content

Commit 295b3d4

Browse files
authored
Merge pull request #33852 from xedin/localization-tests
[Localization] NFC: Add localization serialization unit tests
2 parents 4247b60 + dbe7995 commit 295b3d4

File tree

4 files changed

+218
-66
lines changed

4 files changed

+218
-66
lines changed

unittests/Localization/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
add_swift_unittest(swiftLocalizationTests
2-
DefToYAMLConverterTests.cpp)
2+
DefToYAMLConverterTests.cpp
3+
SerializationTests.cpp)
34

45
target_link_libraries(swiftLocalizationTests
56
PRIVATE

unittests/Localization/DefToYAMLConverterTests.cpp

Lines changed: 5 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,15 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include "LocalizationTest.h"
1314
#include "swift/Localization/LocalizationFormat.h"
1415
#include "llvm/ADT/ArrayRef.h"
1516
#include "llvm/ADT/SmallString.h"
1617
#include "llvm/ADT/StringExtras.h"
1718
#include "llvm/ADT/StringRef.h"
1819
#include "llvm/Support/FileSystem.h"
1920
#include "llvm/Support/Path.h"
20-
#include "llvm/Support/Signals.h"
2121
#include "llvm/Support/ToolOutputFile.h"
22-
#include "llvm/Support/YAMLParser.h"
23-
#include "llvm/Support/YAMLTraits.h"
2422
#include "llvm/Support/raw_ostream.h"
2523
#include "gtest/gtest.h"
2624
#include <cstdlib>
@@ -30,22 +28,7 @@
3028

3129
using namespace swift;
3230
using namespace swift::diag;
33-
34-
enum LocalDiagID : uint32_t {
35-
#define DIAG(KIND, ID, Options, Text, Signature) ID,
36-
#include "swift/AST/DiagnosticsAll.def"
37-
NumDiags
38-
};
39-
40-
static constexpr const char *const diagnosticID[] = {
41-
#define DIAG(KIND, ID, Options, Text, Signature) #ID,
42-
#include "swift/AST/DiagnosticsAll.def"
43-
};
44-
45-
static constexpr const char *const diagnosticMessages[] = {
46-
#define DIAG(KIND, ID, Options, Text, Signature) Text,
47-
#include "swift/AST/DiagnosticsAll.def"
48-
};
31+
using namespace swift::unittests;
4932

5033
static std::string getMainExecutablePath() {
5134
llvm::StringRef libPath = llvm::sys::path::parent_path(SWIFTLIB_DIR);
@@ -62,50 +45,7 @@ static std::string getDefaultLocalizationPath() {
6245
return std::string(DefaultDiagnosticMessagesDir);
6346
}
6447

65-
struct DefToYAMLConverterTest : public ::testing::Test {
66-
std::string YAMLPath;
67-
68-
public:
69-
DefToYAMLConverterTest() {
70-
llvm::SmallString<128> tempFilename;
71-
std::error_code error =
72-
llvm::sys::fs::createTemporaryFile("en", "yaml", tempFilename);
73-
assert(!error);
74-
75-
YAMLPath = std::string(tempFilename);
76-
}
77-
78-
void SetUp() override {
79-
bool failed = convertDefIntoYAML(YAMLPath);
80-
assert(!failed && "failed to generate a YAML file");
81-
}
82-
83-
void TearDown() override { llvm::sys::fs::remove(YAMLPath); }
84-
85-
/// Random number in [0,n)
86-
unsigned RandNumber(unsigned n) { return unsigned(rand()) % n; }
87-
88-
protected:
89-
static bool convertDefIntoYAML(std::string outputPath) {
90-
std::error_code error;
91-
llvm::raw_fd_ostream OS(outputPath, error, llvm::sys::fs::F_None);
92-
if (OS.has_error() || error)
93-
return true;
94-
95-
llvm::ArrayRef<const char *> ids(diagnosticID, LocalDiagID::NumDiags);
96-
llvm::ArrayRef<const char *> messages(diagnosticMessages,
97-
LocalDiagID::NumDiags);
98-
99-
DefToYAMLConverter converter(ids, messages);
100-
converter.convert(OS);
101-
102-
OS.flush();
103-
104-
return OS.has_error();
105-
}
106-
};
107-
108-
TEST_F(DefToYAMLConverterTest, MissingLocalizationFiles) {
48+
TEST_F(LocalizationTest, MissingLocalizationFiles) {
10949
ASSERT_TRUE(llvm::sys::fs::exists(getDefaultLocalizationPath()));
11050
llvm::SmallString<128> EnglishLocalization(getDefaultLocalizationPath());
11151
llvm::sys::path::append(EnglishLocalization, "en");
@@ -115,15 +55,15 @@ TEST_F(DefToYAMLConverterTest, MissingLocalizationFiles) {
11555
ASSERT_TRUE(llvm::sys::fs::exists(EnglishLocalization));
11656
}
11757

118-
TEST_F(DefToYAMLConverterTest, MatchDiagnosticMessagesSequentially) {
58+
TEST_F(LocalizationTest, ConverterTestMatchDiagnosticMessagesSequentially) {
11959
YAMLLocalizationProducer yaml(YAMLPath);
12060
yaml.forEachAvailable([](swift::DiagID id, llvm::StringRef translation) {
12161
llvm::StringRef msg = diagnosticMessages[static_cast<uint32_t>(id)];
12262
ASSERT_EQ(msg, translation);
12363
});
12464
}
12565

126-
TEST_F(DefToYAMLConverterTest, MatchDiagnosticMessagesRandomly) {
66+
TEST_F(LocalizationTest, ConverterTestMatchDiagnosticMessagesRandomly) {
12767
YAMLLocalizationProducer yaml(YAMLPath);
12868

12969
std::random_device rd;
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
//===--- LocalizationTest.h - Helper for setting up locale tests -*- C++-*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef LOCALIZATION_TEST_H
14+
#define LOCALIZATION_TEST_H
15+
16+
#include "swift/Localization/LocalizationFormat.h"
17+
#include "llvm/ADT/ArrayRef.h"
18+
#include "llvm/ADT/SmallString.h"
19+
#include "llvm/ADT/StringExtras.h"
20+
#include "llvm/ADT/StringRef.h"
21+
#include "llvm/Support/FileSystem.h"
22+
#include "llvm/Support/Signals.h"
23+
#include "llvm/Support/raw_ostream.h"
24+
#include "gtest/gtest.h"
25+
#include <random>
26+
#include <string>
27+
#include <system_error>
28+
29+
using namespace swift::diag;
30+
31+
namespace swift {
32+
namespace unittests {
33+
34+
enum LocalDiagID : uint32_t {
35+
#define DIAG(KIND, ID, Options, Text, Signature) ID,
36+
#include "swift/AST/DiagnosticsAll.def"
37+
NumDiags
38+
};
39+
40+
static constexpr const char *const diagnosticID[] = {
41+
#define DIAG(KIND, ID, Options, Text, Signature) #ID,
42+
#include "swift/AST/DiagnosticsAll.def"
43+
};
44+
45+
static constexpr const char *const diagnosticMessages[] = {
46+
#define DIAG(KIND, ID, Options, Text, Signature) Text,
47+
#include "swift/AST/DiagnosticsAll.def"
48+
};
49+
50+
struct LocalizationTest : public ::testing::Test {
51+
std::string YAMLPath;
52+
53+
LocalizationTest() {
54+
YAMLPath = std::string(createTemporaryFile("en", "yaml"));
55+
}
56+
57+
void SetUp() override {
58+
bool failed = convertDefIntoYAML(YAMLPath);
59+
assert(!failed && "failed to generate a YAML file");
60+
}
61+
62+
static std::string createTemporaryFile(std::string prefix,
63+
std::string suffix) {
64+
llvm::SmallString<128> tempFile;
65+
std::error_code error =
66+
llvm::sys::fs::createTemporaryFile(prefix, suffix, tempFile);
67+
assert(!error);
68+
llvm::sys::RemoveFileOnSignal(tempFile);
69+
return std::string(tempFile);
70+
}
71+
72+
/// Random number in [0,n)
73+
unsigned RandNumber(unsigned n) { return unsigned(rand()) % n; }
74+
75+
protected:
76+
static bool convertDefIntoYAML(std::string outputPath) {
77+
std::error_code error;
78+
llvm::raw_fd_ostream OS(outputPath, error, llvm::sys::fs::F_None);
79+
if (OS.has_error() || error)
80+
return true;
81+
82+
llvm::ArrayRef<const char *> ids(diagnosticID, LocalDiagID::NumDiags);
83+
llvm::ArrayRef<const char *> messages(diagnosticMessages,
84+
LocalDiagID::NumDiags);
85+
86+
DefToYAMLConverter converter(ids, messages);
87+
converter.convert(OS);
88+
89+
OS.flush();
90+
91+
return OS.has_error();
92+
}
93+
};
94+
95+
} // end namespace unittests
96+
} // end namespace swift
97+
98+
#endif
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
//===--- LocalizationProducerTests.cpp -------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#include "LocalizationTest.h"
14+
#include "swift/Localization/LocalizationFormat.h"
15+
#include "llvm/ADT/SmallBitVector.h"
16+
#include "llvm/ADT/StringRef.h"
17+
#include "llvm/Support/FileSystem.h"
18+
#include "llvm/Support/MemoryBuffer.h"
19+
#include "llvm/Support/raw_ostream.h"
20+
#include "gtest/gtest.h"
21+
#include <string>
22+
#include <random>
23+
24+
using namespace swift::diag;
25+
using namespace swift::unittests;
26+
27+
TEST_F(LocalizationTest, TestYAMLSerialization) {
28+
YAMLLocalizationProducer yaml(YAMLPath);
29+
30+
auto dbFile = createTemporaryFile("en", "db");
31+
32+
// First, let's serialize English translations
33+
{
34+
SerializedLocalizationWriter writer;
35+
36+
yaml.forEachAvailable([&writer](swift::DiagID id, llvm::StringRef translation) {
37+
writer.insert(id, translation);
38+
});
39+
40+
ASSERT_FALSE(writer.emit(dbFile));
41+
}
42+
43+
// Now, let's make sure that serialized version matches "source" YAML
44+
auto dbContent = llvm::MemoryBuffer::getFile(dbFile);
45+
ASSERT_TRUE(dbContent);
46+
47+
SerializedLocalizationProducer db(std::move(dbContent.get()));
48+
yaml.forEachAvailable([&db](swift::DiagID id, llvm::StringRef translation) {
49+
ASSERT_EQ(translation, db.getMessageOr(id, "<no-fallback>"));
50+
});
51+
}
52+
53+
TEST_F(LocalizationTest, TestSerializationOfEmptyFile) {
54+
auto dbFile = createTemporaryFile("by", "db");
55+
SerializedLocalizationWriter writer;
56+
ASSERT_FALSE(writer.emit(dbFile));
57+
58+
YAMLLocalizationProducer yaml(YAMLPath);
59+
60+
// Reading of the empty `db` file should always return default message.
61+
{
62+
auto dbContent = llvm::MemoryBuffer::getFile(dbFile);
63+
ASSERT_TRUE(dbContent);
64+
65+
SerializedLocalizationProducer db(std::move(dbContent.get()));
66+
yaml.forEachAvailable([&db](swift::DiagID id, llvm::StringRef translation) {
67+
ASSERT_EQ("<<<default-fallback>>>",
68+
db.getMessageOr(id, "<<<default-fallback>>>"));
69+
});
70+
}
71+
}
72+
73+
TEST_F(LocalizationTest, TestSerializationWithGaps) {
74+
// Initially all of the messages are included.
75+
llvm::SmallBitVector includedMessages(LocalDiagID::NumDiags, true);
76+
77+
// Let's punch some holes in the diagnostic content.
78+
for (unsigned i = 0, n = 200; i != n; ++i) {
79+
unsigned position = RandNumber(LocalDiagID::NumDiags);
80+
includedMessages.flip(position);
81+
}
82+
83+
YAMLLocalizationProducer yaml(YAMLPath);
84+
auto dbFile = createTemporaryFile("en", "db");
85+
86+
{
87+
SerializedLocalizationWriter writer;
88+
89+
yaml.forEachAvailable([&](swift::DiagID id, llvm::StringRef translation) {
90+
if (includedMessages.test((unsigned)id))
91+
writer.insert(id, translation);
92+
});
93+
94+
ASSERT_FALSE(writer.emit(dbFile));
95+
}
96+
97+
98+
{
99+
auto dbContent = llvm::MemoryBuffer::getFile(dbFile);
100+
ASSERT_TRUE(dbContent);
101+
102+
SerializedLocalizationProducer db(std::move(dbContent.get()));
103+
yaml.forEachAvailable([&](swift::DiagID id, llvm::StringRef translation) {
104+
auto position = (unsigned)id;
105+
106+
std::string expectedMessage = includedMessages.test(position)
107+
? std::string(translation)
108+
: "<<<default-fallback>>>";
109+
110+
ASSERT_EQ(expectedMessage, db.getMessageOr(id, "<<<default-fallback>>>"));
111+
});
112+
}
113+
}

0 commit comments

Comments
 (0)