Fix a problem with French translation

The locale file didn't contain correct punctuation for SimpleDateFormat.

Wrote a test that catches these regressions in the future.
This test failed before the fix to locale_FR.yml

Affects issues:
- Fixed #3658
This commit is contained in:
Aurora Lahtela 2024-06-09 10:23:22 +03:00
parent c8fee67f10
commit ac3bffb484
4 changed files with 79 additions and 2 deletions

View File

@ -215,7 +215,7 @@ public class LocaleSystem implements SubSystem {
} }
} }
private Optional<Locale> loadSettingLocale() { public Optional<Locale> loadSettingLocale() {
try { try {
String setting = config.get(PluginSettings.LOCALE); String setting = config.get(PluginSettings.LOCALE);
if ("write-all".equalsIgnoreCase(setting)) { if ("write-all".equalsIgnoreCase(setting)) {

View File

@ -905,7 +905,7 @@ plugin:
loadedServerInfo: "Identifiant de serveur chargé : ${0}" loadedServerInfo: "Identifiant de serveur chargé : ${0}"
loadingServerInfo: "Chargement des informations d'identification du serveur" loadingServerInfo: "Chargement des informations d'identification du serveur"
no: "Non" no: "Non"
today: "Aujourd'hui" today: "'Aujourd''hui'"
unavailable: "Indisponible" unavailable: "Indisponible"
unknown: "Inconnu" unknown: "Inconnu"
yes: "Oui" yes: "Oui"

View File

@ -0,0 +1,71 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.delivery.formatting;
import com.djrapitops.plan.delivery.formatting.time.SecondFormatter;
import com.djrapitops.plan.delivery.formatting.time.YearFormatter;
import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.config.paths.FormatSettings;
import com.djrapitops.plan.settings.config.paths.PluginSettings;
import com.djrapitops.plan.settings.locale.LangCode;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.LocaleSystem;
import extension.FullSystemExtension;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.extension.ExtendWith;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
/**
* Tests against formatting issues.
*
* @author AuroraLS3
*/
@ExtendWith(FullSystemExtension.class)
class FormattersTest {
@TestFactory
@DisplayName("Locale for recent day names does not cause formatting issues.")
Stream<DynamicTest> localeFormatRegressionTest(PlanConfig config, LocaleSystem localeSystem) {
config.set(FormatSettings.DATE_RECENT_DAYS, true);
config.set(FormatSettings.DATE_FULL, "MMM d YYYY, HH:mm:ss");
config.set(FormatSettings.DATE_NO_SECONDS, "MMM d YYYY, HH:mm");
config.set(FormatSettings.DATE_RECENT_DAYS_PATTERN, "MMM d YYYY");
return Arrays.stream(LangCode.values())
.filter(langCode -> langCode != LangCode.CUSTOM)
.map(langCode ->
DynamicTest.dynamicTest("Lang " + langCode.name() + " does not cause formatting issues with plugin.generic.today or plugin.generic.yesterday lang keys.", () -> {
config.set(PluginSettings.LOCALE, langCode.name());
Locale locale = localeSystem.loadSettingLocale().orElseThrow(() -> new AssertionError("Could not load " + langCode + "locale"));
YearFormatter yearFormatter = new YearFormatter(config, locale);
SecondFormatter secondFormatter = new SecondFormatter(config, locale);
long today = System.currentTimeMillis();
assertDoesNotThrow(() -> yearFormatter.apply(today), "plugin.generic.today is causing Formatting issues for lang " + langCode);
assertDoesNotThrow(() -> secondFormatter.apply(today), "plugin.generic.today is causing Formatting issues for lang " + langCode);
long yesterday = today - TimeUnit.DAYS.toMillis(1L) - 1000L;
assertDoesNotThrow(() -> yearFormatter.apply(yesterday), "plugin.generic.yesterday is causing Formatting issues for lang " + langCode);
assertDoesNotThrow(() -> secondFormatter.apply(yesterday), "plugin.generic.yesterday is causing Formatting issues for lang " + langCode);
})
);
}
}

View File

@ -20,11 +20,13 @@ import com.djrapitops.plan.PlanSystem;
import com.djrapitops.plan.commands.PlanCommand; import com.djrapitops.plan.commands.PlanCommand;
import com.djrapitops.plan.delivery.DeliveryUtilities; import com.djrapitops.plan.delivery.DeliveryUtilities;
import com.djrapitops.plan.delivery.export.Exporter; import com.djrapitops.plan.delivery.export.Exporter;
import com.djrapitops.plan.delivery.formatting.Formatters;
import com.djrapitops.plan.delivery.webserver.Addresses; import com.djrapitops.plan.delivery.webserver.Addresses;
import com.djrapitops.plan.identification.ServerUUID; import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.settings.ConfigSystem; import com.djrapitops.plan.settings.ConfigSystem;
import com.djrapitops.plan.settings.config.PlanConfig; import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.config.paths.WebserverSettings; import com.djrapitops.plan.settings.config.paths.WebserverSettings;
import com.djrapitops.plan.settings.locale.LocaleSystem;
import com.djrapitops.plan.storage.database.Database; import com.djrapitops.plan.storage.database.Database;
import com.djrapitops.plan.storage.file.PlanFiles; import com.djrapitops.plan.storage.file.PlanFiles;
import com.djrapitops.plan.storage.file.PublicHtmlFiles; import com.djrapitops.plan.storage.file.PublicHtmlFiles;
@ -57,6 +59,8 @@ public class FullSystemExtension implements ParameterResolver, BeforeAllCallback
private final Map<Class, Supplier> parameterResolvers; private final Map<Class, Supplier> parameterResolvers;
public FullSystemExtension() { public FullSystemExtension() {
// You can't use method references here because planSystem is null when this method is initialized.
this.parameterResolvers = Maps.builder(Class.class, Supplier.class) this.parameterResolvers = Maps.builder(Class.class, Supplier.class)
.put(PlanSystem.class, () -> planSystem) .put(PlanSystem.class, () -> planSystem)
.put(PlanFiles.class, () -> planSystem.getPlanFiles()) .put(PlanFiles.class, () -> planSystem.getPlanFiles())
@ -79,6 +83,8 @@ public class FullSystemExtension implements ParameterResolver, BeforeAllCallback
}) })
.put(Database.class, () -> planSystem.getDatabaseSystem().getDatabase()) .put(Database.class, () -> planSystem.getDatabaseSystem().getDatabase())
.put(DeliveryUtilities.class, () -> planSystem.getDeliveryUtilities()) .put(DeliveryUtilities.class, () -> planSystem.getDeliveryUtilities())
.put(Formatters.class, () -> planSystem.getDeliveryUtilities().getFormatters())
.put(LocaleSystem.class, () -> planSystem.getLocaleSystem())
.put(Addresses.class, () -> planSystem.getDeliveryUtilities().getAddresses()) .put(Addresses.class, () -> planSystem.getDeliveryUtilities().getAddresses())
.put(PublicHtmlFiles.class, () -> planSystem.getDeliveryUtilities().getPublicHtmlFiles()) .put(PublicHtmlFiles.class, () -> planSystem.getDeliveryUtilities().getPublicHtmlFiles())
.put(Webserver.class, () -> planSystem.getWebServerSystem().getWebServer()) .put(Webserver.class, () -> planSystem.getWebServerSystem().getWebServer())