Skip to content
This repository has been archived by the owner on Feb 13, 2024. It is now read-only.

Commit

Permalink
SONAR-2693 the list of missing translations must be copyable and must…
Browse files Browse the repository at this point in the history
… contain english values
  • Loading branch information
simonbrandhof committed Sep 16, 2011
1 parent 1e6739d commit fd82677
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 53 deletions.
Expand Up @@ -19,29 +19,22 @@
*/
package org.sonar.test.i18n;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collection;
import java.util.Properties;
import java.util.Set;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.io.IOUtils;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.sonar.test.TestUtils;

import com.google.common.collect.Lists;
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;

public class BundleSynchronizedMatcher extends BaseMatcher<String> {

Expand All @@ -54,8 +47,8 @@ public class BundleSynchronizedMatcher extends BaseMatcher<String> {
// we use this variable to be able to unit test this class without looking at the real Github core bundles that change all the time
private String remote_file_path;
private String bundleName;
private Collection<String> missingKeys;
private Collection<String> nonExistingKeys;
private SortedMap<String, String> missingKeys;
private SortedMap<String, String> nonExistingKeys;

public BundleSynchronizedMatcher(String sonarVersion) {
this(sonarVersion, GITHUB_RAW_FILE_PATH);
Expand All @@ -67,7 +60,7 @@ public BundleSynchronizedMatcher(String sonarVersion, String remote_file_path) {
}

public boolean matches(Object arg0) {
if ( !(arg0 instanceof String)) {
if (!(arg0 instanceof String)) {
return false;
}
bundleName = (String) arg0;
Expand All @@ -86,8 +79,8 @@ public boolean matches(Object arg0) {

// and now let's compare
try {
missingKeys = retrieveMissingKeys(bundle, defaultBundle);
nonExistingKeys = retrieveMissingKeys(defaultBundle, bundle);
missingKeys = retrieveMissingTranslations(bundle, defaultBundle);
nonExistingKeys = retrieveMissingTranslations(defaultBundle, bundle);
return missingKeys.isEmpty() && nonExistingKeys.isEmpty();
} catch (IOException e) {
fail("An error occured while reading the bundles: " + e.getMessage());
Expand All @@ -111,23 +104,22 @@ private StringBuilder prepareDetailsMessage(File dumpFile) {
StringBuilder details = new StringBuilder("\n=======================\n'");
details.append(bundleName);
details.append("' is not synchronized.");
if ( !missingKeys.isEmpty()) {
details.append("\n\n Missing keys are:");
for (String key : missingKeys) {
details.append("\n\t- " + key);
}
}
if ( !nonExistingKeys.isEmpty()) {
details.append("\n\nThe following keys do not exist in the default bundle:");
for (String key : nonExistingKeys) {
details.append("\n\t- " + key);
}
}
print("\n\n Missing translations are:", missingKeys, details);
print("\n\nThe following translations do not exist in the reference bundle:", nonExistingKeys, details);
details.append("\n\nSee report file located at: " + dumpFile.getAbsolutePath());
details.append("\n=======================");
return details;
}

private void print(String title, SortedMap<String, String> translations, StringBuilder to) {
if (!translations.isEmpty()) {
to.append(title);
for (Map.Entry<String, String> 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();
Expand All @@ -144,26 +136,34 @@ private void printReport(File dumpFile, String details) {
}
}

protected Collection<String> retrieveMissingKeys(File bundle, File defaultBundle) throws IOException {
Collection<String> missingKeys = Lists.newArrayList();

Properties bundleProps = new Properties();
bundleProps.load(new FileInputStream(bundle));
Set<Object> bundleKeys = bundleProps.keySet();
protected SortedMap<String, String> retrieveMissingTranslations(File bundle, File referenceBundle) throws IOException {
SortedMap<String, String> missingKeys = Maps.newTreeMap();

Properties defaultBundleProps = new Properties();
defaultBundleProps.load(new FileInputStream(defaultBundle));
Set<Object> defaultBundleKeys = defaultBundleProps.keySet();
Properties bundleProps = loadProperties(bundle);
Properties referenceProperties = loadProperties(referenceBundle);

for (Object key : defaultBundleKeys) {
if ( !bundleKeys.contains(key)) {
missingKeys.add(key.toString());
for (Map.Entry<Object, Object> entry : referenceProperties.entrySet()) {
String key = (String) entry.getKey();
if (!bundleProps.containsKey(key)) {
missingKeys.put(key, (String) entry.getValue());
}
}

return missingKeys;
}

private Properties loadProperties(File f) throws IOException {
Properties props = new Properties();
FileInputStream input = new FileInputStream(f);
try {
props.load(input);
return props;

} finally {
IOUtils.closeQuietly(input);
}
}

protected File getBundleFileFromGithub(String defaultBundleName) {
File localBundle = new File("target/l10n/download/" + defaultBundleName);
try {
Expand Down
Expand Up @@ -29,6 +29,7 @@

import java.io.File;
import java.util.Collection;
import java.util.SortedMap;

import org.junit.Before;
import org.junit.Test;
Expand All @@ -55,14 +56,14 @@ public void testBundlesInsideSonarPlugin() {
assertThat("myPlugin_fr.properties", isBundleUpToDate());
assertTrue(new File("target/l10n/myPlugin_fr.properties.report.txt").exists());
} catch (AssertionError e) {
assertThat(e.getMessage(), containsString("Missing keys are:\n\t- second.prop"));
assertThat(e.getMessage(), containsString("Missing translations are:\nsecond.prop"));
}
// unnecessary many keys
try {
assertThat("myPlugin_fr_QB.properties", isBundleUpToDate());
assertTrue(new File("target/l10n/myPlugin_fr_QB.properties.report.txt").exists());
} catch (AssertionError e) {
assertThat(e.getMessage(), containsString("The following keys do not exist in the default bundle:\n\t- fourth.prop"));
assertThat(e.getMessage(), containsString("The following translations do not exist in the reference bundle:\nfourth.prop"));
}
}

Expand All @@ -75,7 +76,7 @@ public void testBundlesOfLanguagePack() {
try {
assertThat("core_fr.properties", new BundleSynchronizedMatcher(null, GITHUB_RAW_FILE_PATH));
} catch (AssertionError e) {
assertThat(e.getMessage(), containsString("Missing keys are:\n\t- second.prop"));
assertThat(e.getMessage(), containsString("Missing translations are:\nsecond.prop"));
}
}

Expand Down Expand Up @@ -120,11 +121,11 @@ public void testRetrieveMissingKeys() throws Exception {
File frBundle = TestUtils.getResource(BundleSynchronizedMatcher.L10N_PATH + "myPlugin_fr.properties");
File qbBundle = TestUtils.getResource(BundleSynchronizedMatcher.L10N_PATH + "myPlugin_fr_QB.properties");

Collection<String> diffs = matcher.retrieveMissingKeys(frBundle, defaultBundle);
SortedMap<String, String> diffs = matcher.retrieveMissingTranslations(frBundle, defaultBundle);
assertThat(diffs.size(), is(1));
assertThat(diffs, hasItem("second.prop"));
assertThat(diffs.keySet(), hasItem("second.prop"));

diffs = matcher.retrieveMissingKeys(qbBundle, defaultBundle);
diffs = matcher.retrieveMissingTranslations(qbBundle, defaultBundle);
assertThat(diffs.size(), is(0));
}

Expand Down

0 comments on commit fd82677

Please sign in to comment.