org.sonar.test.i18n.BundleSynchronizedMatcher Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sonar-testing-harness Show documentation
Show all versions of sonar-testing-harness Show documentation
Open source platform for continuous inspection of code quality
/*
* SonarQube
* Copyright (C) 2009-2023 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.test.i18n;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Properties;
import java.util.SortedMap;
import java.util.TreeMap;
import org.apache.commons.io.IOUtils;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class BundleSynchronizedMatcher extends BaseMatcher {
public static final String L10N_PATH = "/org/sonar/l10n/";
private String bundleName;
private SortedMap missingKeys;
private SortedMap additionalKeys;
@Override
public boolean matches(Object arg0) {
if (!(arg0 instanceof String)) {
return false;
}
bundleName = (String) arg0;
// Find the bundle that needs to be verified
InputStream bundleInputStream = getBundleFileInputStream(bundleName);
// Find the default bundle which the provided one should be compared to
InputStream defaultBundleInputStream = getDefaultBundleFileInputStream(bundleName);
// and now let's compare!
try {
// search for missing keys
missingKeys = retrieveMissingTranslations(bundleInputStream, defaultBundleInputStream);
// and now for additional keys
bundleInputStream = getBundleFileInputStream(bundleName);
defaultBundleInputStream = getDefaultBundleFileInputStream(bundleName);
additionalKeys = retrieveMissingTranslations(defaultBundleInputStream, bundleInputStream);
// And fail only if there are missing keys
return missingKeys.isEmpty();
} catch (IOException e) {
fail("An error occurred while reading the bundles: " + e.getMessage());
return false;
} finally {
IOUtils.closeQuietly(bundleInputStream);
IOUtils.closeQuietly(defaultBundleInputStream);
}
}
@Override
public void describeTo(Description description) {
// report file
File dumpFile = new File("build/l10n/" + bundleName + ".report.txt");
// prepare message
StringBuilder details = prepareDetailsMessage(dumpFile);
description.appendText(details.toString());
// print report in target directory
printReport(dumpFile, details.toString());
}
private StringBuilder prepareDetailsMessage(File dumpFile) {
StringBuilder details = new StringBuilder("\n=======================\n'");
details.append(bundleName);
details.append("' is not up-to-date.");
print("\n\n Missing translations are:", missingKeys, details);
print("\n\nThe following translations do not exist in the reference bundle:", additionalKeys, details);
details.append("\n\nSee report file located at: ");
details.append(dumpFile.getAbsolutePath());
details.append("\n=======================");
return details;
}
private static void print(String title, SortedMap translations, StringBuilder to) {
if (!translations.isEmpty()) {
to.append(title);
for (Map.Entry entry : translations.entrySet()) {
to.append("\n").append(entry.getKey()).append("=").append(entry.getValue());
}
}
}
private void printReport(File dumpFile, String details) {
if (dumpFile.exists()) {
dumpFile.delete();
}
dumpFile.getParentFile().mkdirs();
try (Writer writer = new OutputStreamWriter(new FileOutputStream(dumpFile), StandardCharsets.UTF_8)) {
writer.write(details);
} catch (IOException e) {
throw new IllegalStateException("Unable to write the report to 'target/l10n/" + bundleName + ".report.txt'", e);
}
}
protected static SortedMap retrieveMissingTranslations(InputStream bundle, InputStream referenceBundle) throws IOException {
SortedMap missingKeys = new TreeMap<>();
Properties bundleProps = loadProperties(bundle);
Properties referenceProperties = loadProperties(referenceBundle);
for (Map.Entry