Updating using GitHub API 2025-06-19-15:31

This commit is contained in:
nidhi-vm 2025-06-19 15:31:21 -04:00
parent 2960104a37
commit f40431a9db

View file

@ -15,38 +15,19 @@ import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.fail; import static org.junit.jupiter.api.Assertions.fail;
/**
* This test ensures that there are no hard-coded strings without internationalization in
* any HTML files. Also ensures that a string is translated in every language to avoid
* partial translations.
*
* @author Anuj Ashok Potdar
*/
public class I18nPropertiesSyncTest { public class I18nPropertiesSyncTest {
private static final String I18N_DIR = "src/main/resources"; private static final String I18N_DIR = "src/main/resources";
private static final String BASE_NAME = "messages"; private static final String BASE_NAME = "messages";
public static final String PROPERTIES = ".properties"; public static final String PROPERTIES = ".properties";
private static final Pattern HTML_TEXT_LITERAL = Pattern.compile(">([^<>{}]+)<"); private static final Pattern HTML_TEXT_LITERAL = Pattern.compile(">([^<>{}]+)<");
private static final Pattern BRACKET_ONLY = Pattern.compile("<[^>]*>\\s*[\\[\\]](?:&nbsp;)?\\s*</[^>]*>"); private static final Pattern BRACKET_ONLY = Pattern.compile("<[^>]*>\\s*[\\[\\]](?:&nbsp;)?\\s*</[^>]*>");
private static final Pattern HAS_TH_TEXT_ATTRIBUTE = Pattern.compile("th:(u)?text\\s*=\\s*\"[^\"]+\""); private static final Pattern HAS_TH_TEXT_ATTRIBUTE = Pattern.compile("th:(u)?text\\s*=\\s*\"[^\"]+\"");
@Test @Test
public void checkNonInternationalizedStrings() throws IOException { public void checkNonInternationalizedStrings() throws IOException {
Path root = Paths.get("src/main"); Path root = Paths.get("src/main");
List<Path> files; List<Path> files = getFiles(root);
try (Stream<Path> stream = Files.walk(root)) {
files = stream.filter(p -> p.toString().endsWith(".java") || p.toString().endsWith(".html"))
.filter(p -> !p.toString().contains("/test/"))
.filter(p -> !p.getFileName().toString().endsWith("Test.java"))
.toList();
}
StringBuilder report = new StringBuilder(); StringBuilder report = new StringBuilder();
@ -55,24 +36,18 @@ public class I18nPropertiesSyncTest {
for (int i = 0; i < lines.size(); i++) { for (int i = 0; i < lines.size(); i++) {
String line = lines.get(i).trim(); String line = lines.get(i).trim();
if (line.startsWith("//") || line.startsWith("@") || line.contains("log.") if (isIgnoredLine(line) || !file.toString().endsWith(".html")) {
|| line.contains("System.out"))
continue; continue;
}
if (file.toString().endsWith(".html")) { if (isNonInternationalizedHtmlLine(line)) {
boolean hasLiteralText = HTML_TEXT_LITERAL.matcher(line).find(); report.append("HTML: ")
boolean hasThTextAttribute = HAS_TH_TEXT_ATTRIBUTE.matcher(line).find(); .append(file)
boolean isBracketOnly = BRACKET_ONLY.matcher(line).find(); .append(" Line ")
.append(i + 1)
if (hasLiteralText && !line.contains("#{") && !hasThTextAttribute && !isBracketOnly) { .append(": ")
report.append("HTML: ") .append(line)
.append(file) .append("\n");
.append(" Line ")
.append(i + 1)
.append(": ")
.append(line)
.append("\n");
}
} }
} }
} }
@ -82,25 +57,29 @@ public class I18nPropertiesSyncTest {
} }
} }
@Test private List<Path> getFiles(Path root) throws IOException {
public void checkI18nPropertyFilesAreInSync() throws IOException { try (Stream<Path> stream = Files.walk(root)) {
List<Path> propertyFiles; return stream.filter(p -> p.toString().endsWith(".java") || p.toString().endsWith(".html"))
try (Stream<Path> stream = Files.walk(Paths.get(I18N_DIR))) { .filter(p -> !p.toString().contains("/test/"))
propertyFiles = stream.filter(p -> p.getFileName().toString().startsWith(BASE_NAME)) .filter(p -> !p.getFileName().toString().endsWith("Test.java"))
.filter(p -> p.getFileName().toString().endsWith(PROPERTIES))
.toList(); .toList();
} }
}
Map<String, Properties> localeToProps = new HashMap<>(); private boolean isIgnoredLine(String line) {
return line.startsWith("//") || line.startsWith("@") || line.contains("log.") || line.contains("System.out");
}
for (Path path : propertyFiles) { private boolean isNonInternationalizedHtmlLine(String line) {
Properties props = new Properties(); return HTML_TEXT_LITERAL.matcher(line).find() && !line.contains("#{") &&
try (var reader = Files.newBufferedReader(path)) { !HAS_TH_TEXT_ATTRIBUTE.matcher(line).find() && !BRACKET_ONLY.matcher(line).find();
props.load(reader); }
localeToProps.put(path.getFileName().toString(), props);
}
}
@Test
public void checkI18nPropertyFilesAreInSync() throws IOException {
List<Path> propertyFiles = getPropertyFiles();
Map<String, Properties> localeToProps = loadProperties(propertyFiles);
String baseFile = BASE_NAME + PROPERTIES; String baseFile = BASE_NAME + PROPERTIES;
Properties baseProps = localeToProps.get(baseFile); Properties baseProps = localeToProps.get(baseFile);
if (baseProps == null) { if (baseProps == null) {
@ -113,10 +92,9 @@ public class I18nPropertiesSyncTest {
for (Map.Entry<String, Properties> entry : localeToProps.entrySet()) { for (Map.Entry<String, Properties> entry : localeToProps.entrySet()) {
String fileName = entry.getKey(); String fileName = entry.getKey();
// We use fallback logic to include english strings, hence messages_en is not if (fileName.equals(baseFile) || fileName.equals("messages_en.properties")) {
// populated.
if (fileName.equals(baseFile) || fileName.equals("messages_en.properties"))
continue; continue;
}
Properties props = entry.getValue(); Properties props = entry.getValue();
Set<String> missingKeys = new TreeSet<>(baseKeys); Set<String> missingKeys = new TreeSet<>(baseKeys);
@ -133,4 +111,24 @@ public class I18nPropertiesSyncTest {
} }
} }
private List<Path> getPropertyFiles() throws IOException {
try (Stream<Path> stream = Files.walk(Paths.get(I18N_DIR))) {
return stream.filter(p -> p.getFileName().toString().startsWith(BASE_NAME))
.filter(p -> p.getFileName().toString().endsWith(PROPERTIES))
.toList();
}
}
private Map<String, Properties> loadProperties(List<Path> propertyFiles) throws IOException {
Map<String, Properties> localeToProps = new HashMap<>();
for (Path path : propertyFiles) {
Properties props = new Properties();
try (var reader = Files.newBufferedReader(path)) {
props.load(reader);
localeToProps.put(path.getFileName().toString(), props);
}
}
return localeToProps;
}
} }