Add coverage test to output missing translations + summary
This commit is contained in:
parent
c237a401c1
commit
56896ba5d1
|
@ -1,10 +1,7 @@
|
||||||
package org.hl7.fhir.utilities.i18n;
|
package org.hl7.fhir.utilities.i18n;
|
||||||
|
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
import java.util.Locale;
|
import java.util.*;
|
||||||
import java.util.Objects;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
@ -98,6 +95,10 @@ public abstract class I18nBase {
|
||||||
.map(entry -> baseKey + KEY_DELIMITER + entry).collect(Collectors.toSet());
|
.map(entry -> baseKey + KEY_DELIMITER + entry).collect(Collectors.toSet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Set<String> getPluralSuffixes() {
|
||||||
|
return Collections.unmodifiableSet(pluralRules.getKeywords());
|
||||||
|
}
|
||||||
|
|
||||||
protected String getRootKeyFromPlural(@Nonnull String pluralKey) {
|
protected String getRootKeyFromPlural(@Nonnull String pluralKey) {
|
||||||
checkPluralRulesAreLoaded();
|
checkPluralRulesAreLoaded();
|
||||||
for (String keyword : pluralRules
|
for (String keyword : pluralRules
|
||||||
|
|
|
@ -3,13 +3,9 @@ package org.hl7.fhir.utilities.i18n;
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.ResourceBundle;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
@ -17,8 +13,6 @@ import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
public class I18nCoverageTest {
|
public class I18nCoverageTest {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
final Set<Locale> locales = Set.of(
|
final Set<Locale> locales = Set.of(
|
||||||
Locale.ENGLISH,
|
Locale.ENGLISH,
|
||||||
Locale.GERMAN,
|
Locale.GERMAN,
|
||||||
|
@ -28,7 +22,117 @@ public class I18nCoverageTest {
|
||||||
);
|
);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCoverage() throws IllegalAccessException {
|
public void testPhraseCoverage() throws IllegalAccessException, IOException {
|
||||||
|
|
||||||
|
Properties englishMessages = new Properties();
|
||||||
|
englishMessages.load(I18nTestClass.class.getClassLoader().getResourceAsStream("Messages.properties"));
|
||||||
|
I18nTestClass englishTestClass = getI18nTestClass(Locale.ENGLISH);
|
||||||
|
Set<String> englishPluralSuffixes = englishTestClass.getPluralSuffixes();
|
||||||
|
|
||||||
|
Set<String> englishPluralKeys = new HashSet<>();
|
||||||
|
Set<String> englishKeys = new HashSet<>();
|
||||||
|
for (Object objectKey : englishMessages.keySet()) {
|
||||||
|
String key = (String) objectKey;
|
||||||
|
if (isPluralKey(key, englishPluralSuffixes)) {
|
||||||
|
final String pluralKeyRoot = getPluralKeyRoot(key, englishPluralSuffixes);
|
||||||
|
englishPluralKeys.add(pluralKeyRoot);
|
||||||
|
} else {
|
||||||
|
englishKeys.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HashMap<Locale, Integer> foundKeys = new HashMap<>();
|
||||||
|
HashMap<Locale, Integer> foundPluralKeys = new HashMap<>();
|
||||||
|
|
||||||
|
for (Locale locale : locales) {
|
||||||
|
if (!locale.equals(Locale.ENGLISH)) {
|
||||||
|
Properties translatedMessages = new Properties();
|
||||||
|
translatedMessages.load(I18nTestClass.class.getClassLoader().getResourceAsStream("Messages_" + locale.toString() + ".properties"));
|
||||||
|
I18nTestClass translatedTestClass = getI18nTestClass(Locale.ENGLISH);
|
||||||
|
Set<String> translatedPluralSuffixes = translatedTestClass.getPluralSuffixes();
|
||||||
|
|
||||||
|
Set<String> translatedPluralKeys = new HashSet<>();
|
||||||
|
Set<String> translatedKeys = new HashSet<>();
|
||||||
|
|
||||||
|
for (Object objectKey : translatedMessages.keySet()) {
|
||||||
|
String key = (String) objectKey;
|
||||||
|
Object value = translatedMessages.get(objectKey);
|
||||||
|
if (
|
||||||
|
value instanceof String &&
|
||||||
|
!((String) value).trim().isEmpty()) {
|
||||||
|
if (isPluralKey(key, translatedPluralSuffixes)) {
|
||||||
|
final String pluralKeyRoot = getPluralKeyRoot(key, englishPluralSuffixes);
|
||||||
|
translatedPluralKeys.add(pluralKeyRoot);
|
||||||
|
} else {
|
||||||
|
translatedKeys.add(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<String> intersectionKeys = new HashSet<>(englishKeys);
|
||||||
|
intersectionKeys.retainAll(translatedKeys);
|
||||||
|
Set<String> intersectionPluralKeys = new HashSet<>(englishPluralKeys);
|
||||||
|
intersectionPluralKeys.retainAll(translatedPluralKeys);
|
||||||
|
|
||||||
|
Set<String> missingKeys = new HashSet<>(englishKeys);
|
||||||
|
Set<String> missingPluralKeys = new HashSet<>(englishPluralKeys);
|
||||||
|
|
||||||
|
missingKeys.removeAll(translatedKeys);
|
||||||
|
missingPluralKeys.removeAll(translatedPluralKeys);
|
||||||
|
|
||||||
|
foundKeys.put(locale, intersectionKeys.size());
|
||||||
|
foundPluralKeys.put(locale, intersectionPluralKeys.size());
|
||||||
|
|
||||||
|
for (String missingKey : missingKeys) {
|
||||||
|
System.err.println("Missing key for locale " + locale + ": " + missingKey);
|
||||||
|
}
|
||||||
|
for (String missingPluralKey : missingPluralKeys) {
|
||||||
|
System.err.println("Missing plural key for locale " + locale + ": " + missingPluralKey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Summary");
|
||||||
|
System.out.println("-------");
|
||||||
|
System.out.println("Single Phrases (Original Total=" + englishKeys.size() + ")");
|
||||||
|
System.out.println("Locale\tComplete #\tComplete %");
|
||||||
|
for (Locale locale : foundKeys.keySet()) {
|
||||||
|
int count = foundKeys.get(locale);
|
||||||
|
System.out.println(locale + "\t" + count + "\t" + getPercent( count, englishKeys.size()));
|
||||||
|
}
|
||||||
|
System.out.println("Plural Phrases (Original Total=" + englishPluralKeys.size() + ")");
|
||||||
|
System.out.println("Locale\tComplete #\tComplete %");
|
||||||
|
for (Locale locale : foundPluralKeys.keySet()) {
|
||||||
|
int count = foundPluralKeys.get(locale);
|
||||||
|
System.out.println(locale + "\t" + count + "\t" + getPercent( count, englishPluralKeys.size()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getPercent(int numerator, int denominator) {
|
||||||
|
return (int) (((double)numerator / denominator) * 100) + "%";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getPluralKeyRoot(String key, Set<String> pluralKeys) {
|
||||||
|
for (String pluralKey : pluralKeys) {
|
||||||
|
final String suffix = I18nBase.KEY_DELIMITER + pluralKey;
|
||||||
|
if (key.endsWith(suffix)) {
|
||||||
|
return key.substring(0, key.lastIndexOf(suffix));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException(key + " does not terminate with a plural suffix. Available: " + pluralKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isPluralKey(String key, Set<String> pluralKeys) {
|
||||||
|
for (String pluralKey : pluralKeys) {
|
||||||
|
if (key.endsWith(I18nBase.KEY_DELIMITER + pluralKey)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testConstantsCoverage() throws IllegalAccessException {
|
||||||
|
|
||||||
Field[] fields = I18nConstants.class.getDeclaredFields();
|
Field[] fields = I18nConstants.class.getDeclaredFields();
|
||||||
Map<Locale, I18nBase> testClassMap = new HashMap<>();
|
Map<Locale, I18nBase> testClassMap = new HashMap<>();
|
||||||
|
@ -49,7 +153,6 @@ public class I18nCoverageTest {
|
||||||
for (Locale locale : locales) {
|
for (Locale locale : locales) {
|
||||||
I18nBase base = testClassMap.get(locale);
|
I18nBase base = testClassMap.get(locale);
|
||||||
|
|
||||||
|
|
||||||
isSingularPhrase.put(locale, base.messageKeyExistsForLocale(message));
|
isSingularPhrase.put(locale, base.messageKeyExistsForLocale(message));
|
||||||
isPluralPhrase.put(locale, existsAsPluralPhrase(base, message));
|
isPluralPhrase.put(locale, existsAsPluralPhrase(base, message));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue