Bundle ICU4J; create NlsMessages to format duration and and/or lists

Fixes IDEA-247854 Formats#formatDuration is not localizable

GitOrigin-RevId: adb56cac0ecc7c47a644887e3eb17e9ca26b47bd
This commit is contained in:
Tagir Valeev
2020-09-15 04:50:16 +00:00
committed by intellij-monorepo-bot
parent 067946105a
commit 390a408fa0
20 changed files with 321 additions and 46 deletions
+15
View File
@@ -0,0 +1,15 @@
<component name="libraryTable">
<library name="icu4j" type="repository">
<properties maven-id="com.ibm.icu:icu4j:67.1" />
<ANNOTATIONS>
<root url="file://$PROJECT_DIR$/community/lib/annotations/icu4j" />
</ANNOTATIONS>
<CLASSES>
<root url="jar://$MAVEN_REPOSITORY$/com/ibm/icu/icu4j/67.1/icu4j-67.1.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$MAVEN_REPOSITORY$/com/ibm/icu/icu4j/67.1/icu4j-67.1-sources.jar!/" />
</SOURCES>
</library>
</component>
@@ -8,6 +8,7 @@ import com.intellij.compiler.progress.CompilerMessagesService;
import com.intellij.compiler.progress.CompilerTask;
import com.intellij.compiler.server.BuildManager;
import com.intellij.compiler.server.DefaultMessageHandler;
import com.intellij.ide.nls.NlsMessages;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationListener;
import com.intellij.openapi.application.ApplicationManager;
@@ -558,7 +559,7 @@ public final class CompileDriver {
message = JavaCompilerBundle.message("status.all.up.to.date");
}
else {
String durationString = StringUtil.formatDurationApproximate(duration);
String durationString = NlsMessages.formatDurationApproximate(duration);
if (status == ExitStatus.SUCCESS) {
message = warningCount > 0
? JavaCompilerBundle.message("status.compilation.completed.successfully.with.warnings", warningCount, durationString)
@@ -16,9 +16,9 @@
package com.intellij.find.findUsages;
import com.intellij.analysis.AnalysisBundle;
import com.intellij.ide.nls.NlsMessages;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.search.SearchScope;
import org.jetbrains.annotations.NotNull;
@@ -92,12 +92,11 @@ public abstract class JavaFindUsagesOptions extends PersistentFindUsagesOptions
@NotNull
@Override
public final String generateUsagesString() {
String separator = " " + AnalysisBundle.message("find.usages.panel.title.separator") + " ";
LinkedHashSet<String> strings = new LinkedHashSet<>();
addUsageTypes(strings);
if (strings.isEmpty()) {
strings.add(AnalysisBundle.message("find.usages.panel.title.usages"));
return AnalysisBundle.message("find.usages.panel.title.usages");
}
return StringUtil.join(strings, separator);
return NlsMessages.formatOrList(strings);
}
}
@@ -4,6 +4,7 @@ package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.streamMigration.CollectMigration.CollectTerminal;
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.ide.nls.NlsMessages;
import com.intellij.java.JavaBundle;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
@@ -21,7 +22,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.Objects;
import java.util.function.Function;
import static com.intellij.util.ObjectUtils.tryCast;
@@ -137,9 +137,7 @@ public class FuseStreamOperationsInspection extends AbstractBaseJavaLocalInspect
if (newTerminal == null) return;
PsiElement nameElement = call.getMethodExpression().getReferenceNameElement();
if (nameElement == null) return;
String fusedSteps = newTerminal.fusedElements()
.mapLastOrElse(s -> StreamEx.of(", ", s), s -> StreamEx.of(" and ", s))
.flatMap(Function.identity()).skip(1).joining();
String fusedSteps = newTerminal.fusedElements().collect(NlsMessages.joiningAnd());
holder.registerProblem(nameElement,
JavaBundle.message("inspection.fuse.stream.operations.message", fusedSteps),
new FuseStreamOperationsFix(fusedSteps, myStrictMode));
@@ -1,4 +1,4 @@
// "Fuse ArrayList, 'sort' and 'toArray' into the Stream API chain" "true"
// "Fuse ArrayList, 'sort', and 'toArray' into the Stream API chain" "true"
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -1,4 +1,4 @@
// "Fuse ArrayList, 'sort' and 'toArray' into the Stream API chain" "true"
// "Fuse ArrayList, 'sort', and 'toArray' into the Stream API chain" "true"
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -2,6 +2,7 @@
package com.jetbrains.jsonSchema.impl;
import com.intellij.codeInspection.util.InspectionMessage;
import com.intellij.ide.nls.NlsMessages;
import com.intellij.json.JsonBundle;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.NlsSafe;
@@ -564,7 +565,7 @@ public final class JsonSchemaAnnotatorChecker implements JsonValidationHost {
if (commonIssueKind == JsonValidationError.FixableIssueKind.MissingProperty) {
String sets = errors.stream().map(e -> (JsonValidationError.MissingMultiplePropsIssueData)e.getIssueData())
.map(d -> d.getMessage(false)).collect(Collectors.joining(", or "));
.map(d -> d.getMessage(false)).collect(NlsMessages.joiningOr());
return new JsonValidationError(JsonBundle.message(
isOneOf ? "schema.validation.one.of.property.sets.required" : "schema.validation.at.least.one.of.property.sets.required", sets),
isOneOf ? JsonValidationError.FixableIssueKind.MissingOneOfProperty : JsonValidationError.FixableIssueKind.MissingAnyOfProperty,
@@ -944,7 +944,7 @@ public class JsonSchemaHighlightingTest extends JsonSchemaHighlightingTestBase {
public void testMissingMultipleAltPropertySets() throws Exception {
@Language("JSON") String schemaText = FileUtil.loadFile(new File(getTestDataPath() + "/avroSchema.json"));
doTest(schemaText, "<warning descr=\"One of the following property sets is required: properties 'type' = record, 'fields', 'name', or properties 'type' = enum, 'name', 'symbols', or properties 'type' = array, 'items', or properties 'type' = map, 'values', or properties 'type' = fixed, 'name', 'size'\">{\n" +
doTest(schemaText, "<warning descr=\"One of the following property sets is required: properties 'type' = record, 'fields', 'name', properties 'type' = enum, 'name', 'symbols', properties 'type' = array, 'items', properties 'type' = map, 'values', or properties 'type' = fixed, 'name', 'size'\">{\n" +
" \n" +
"}</warning>");
}
@@ -0,0 +1,8 @@
<root>
<item name='com.ibm.icu.text.ListFormatter java.lang.String format(java.util.Collection&lt;?&gt;)'>
<annotation name='org.jetbrains.annotations.Nls'/>
</item>
<item name='com.ibm.icu.text.MeasureFormat java.lang.String formatMeasures(com.ibm.icu.util.Measure...)'>
<annotation name='org.jetbrains.annotations.Nls'/>
</item>
</root>
@@ -11,7 +11,6 @@ default.path.evaluator.option=Tells reference provider how evaluate default path
error.cannot.resolve=Cannot resolve
error.cannot.resolve.file.or.dir=Cannot resolve {0} ''{1}''
error.cannot.resolve.default.message=Cannot resolve symbol ''{0}''
find.usages.panel.title.separator=or
find.usages.panel.title.usages=Usages
forward.dependencies.usage.view.initial.text=Select where to search in left tree and what to search in right tree.
forward.dependencies.usage.view.root.node.text=Usages of the right tree scope selection in the left tree scope selection
@@ -10,10 +10,7 @@ import com.intellij.psi.search.PredefinedSearchScopeProvider;
import com.intellij.psi.search.ProjectScope;
import com.intellij.psi.search.SearchRequestCollector;
import com.intellij.psi.search.SearchScope;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.*;
import java.util.List;
@@ -94,7 +91,7 @@ public class FindUsagesOptions implements Cloneable {
}
@NotNull
public String generateUsagesString() {
public @Nls String generateUsagesString() {
return AnalysisBundle.message("find.usages.panel.title.usages");
}
}
@@ -302,6 +302,8 @@ class CommunityLibraryLicenses {
new LibraryLicense(name: "Hunspell", libraryName: "com.gitlab.dumonts:hunspell:1.1.1",
license: "Apache 2.0", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.txt",
url: "https://gitlab.com/dumonts/hunspell-java"),
new LibraryLicense(name: "ICU4J", libraryName: "icu4j", license: "Unicode",
url: "http://site.icu-project.org/", licenseUrl: "http://www.unicode.org/copyright.html"),
new LibraryLicense(name: "imgscalr", libraryName: "imgscalr", license: "Apache 2.0",
licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.txt", url: "https://github.com/thebuzzmedia/imgscalr"),
new LibraryLicense(name: "Inconsolata", attachedTo: "intellij.platform.resources", version: "001.010", license: "OFL",
@@ -3,6 +3,7 @@ package com.intellij.build;
import com.intellij.build.events.*;
import com.intellij.icons.AllIcons;
import com.intellij.ide.nls.NlsMessages;
import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.util.treeView.PresentableNodeDescriptor;
import com.intellij.lang.LangBundle;
@@ -15,6 +16,7 @@ import com.intellij.ui.SimpleTextAttributes;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -152,17 +154,17 @@ public class ExecutionNode extends PresentableNodeDescriptor<ExecutionNode> {
// Note: invoked from the EDT.
@Nullable
public String getDuration() {
public @Nls String getDuration() {
if (startTime == endTime) return null;
if (isRunning()) {
long duration = startTime == 0 ? 0 : System.currentTimeMillis() - startTime;
if (duration > 1000) {
duration -= duration % 1000;
}
return StringUtil.formatDurationApproximate(duration);
return NlsMessages.formatDurationApproximate(duration);
}
else {
return isSkipped(myResult) ? null : StringUtil.formatDuration(endTime - startTime);
return isSkipped(myResult) ? null : NlsMessages.formatDuration(endTime - startTime);
}
}
@@ -46,5 +46,6 @@
<orderEntry type="library" name="rd-swing" level="project" />
<orderEntry type="library" name="fastutil-min" level="project" />
<orderEntry type="library" name="Trove4j" level="project" />
<orderEntry type="library" exported="" name="icu4j" level="project" />
</component>
</module>
@@ -0,0 +1,155 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide.nls;
import com.ibm.icu.number.FormattedNumber;
import com.ibm.icu.number.IntegerWidth;
import com.ibm.icu.number.LocalizedNumberFormatter;
import com.ibm.icu.number.NumberFormatter;
import com.ibm.icu.text.ListFormatter;
import com.ibm.icu.text.MeasureFormat;
import com.ibm.icu.util.Measure;
import com.ibm.icu.util.MeasureUnit;
import com.intellij.DynamicBundle;
import gnu.trove.TIntArrayList;
import gnu.trove.TLongArrayList;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.stream.Collector;
import java.util.stream.Collectors;
/**
* Utility methods to produce localized messages
*/
public class NlsMessages {
private static final MeasureUnit[] TIME_UNITS =
{MeasureUnit.MILLISECOND, MeasureUnit.SECOND, MeasureUnit.MINUTE, MeasureUnit.HOUR, MeasureUnit.DAY};
private static final long[] TIME_MULTIPLIERS = {1, 1000, 60, 60, 24};
/**
* @param list list of items
* @return localized string representation of all items in the list semantically joined via 'AND'
*/
public static @NotNull @Nls String formatAndList(Collection<?> list) {
return ListFormatter.getInstance(DynamicBundle.getLocale(), ListFormatter.Type.AND, ListFormatter.Width.WIDE).format(list);
}
/**
* @param list list of items
* @return localized string representation of all items in the list semantically joined via 'OR'
*/
public static @NotNull @Nls String formatOrList(Collection<?> list) {
return ListFormatter.getInstance(DynamicBundle.getLocale(), ListFormatter.Type.OR, ListFormatter.Width.WIDE).format(list);
}
/**
* @return a collector that collects a stream into the localized string that joins the stream elements into the and-list
*/
public static <T> @NotNull Collector<T, ?, @Nls String> joiningAnd() {
return Collectors.collectingAndThen(Collectors.toList(), NlsMessages::formatAndList);
}
/**
* @return a collector that collects a stream into the localized string that joins the stream elements into the or-list
*/
public static <T> @NotNull Collector<T, ?, @Nls String> joiningOr() {
return Collectors.collectingAndThen(Collectors.toList(), NlsMessages::formatOrList);
}
/**
* Formats duration given in milliseconds as a sum of time units with at most two units
* (example: {@code formatDuration(123456) = "2 m 3 s"}).
*/
@Contract(pure = true)
public static @NotNull @Nls String formatDurationApproximate(long duration) {
return formatDuration(duration, 2);
}
/**
* Formats duration given in milliseconds as a sum of time units (example: {@code formatDuration(123456, "") = "2m 3s 456ms"}).
* The result is localized according to the currently used language pack.
*/
@Contract(pure = true)
public static @NotNull @Nls String formatDuration(long duration) {
return formatDuration(duration, Integer.MAX_VALUE);
}
@Contract(pure = true)
private static @NotNull @Nls String formatDuration(long duration, int maxFragments) {
TLongArrayList unitValues = new TLongArrayList();
TIntArrayList unitIndices = new TIntArrayList();
long count = duration;
int i = 1;
for (; i < TIME_UNITS.length && count > 0; i++) {
long multiplier = TIME_MULTIPLIERS[i];
if (count < multiplier) break;
long remainder = count % multiplier;
count /= multiplier;
if (remainder != 0 || !unitValues.isEmpty()) {
unitValues.insert(0, remainder);
unitIndices.insert(0, i - 1);
}
}
unitValues.insert(0, count);
unitIndices.insert(0, i - 1);
if (unitValues.size() > maxFragments) {
int lastUnitIndex = unitIndices.get(maxFragments - 1);
long lastMultiplier = TIME_MULTIPLIERS[lastUnitIndex];
// Round up if needed
if (unitValues.get(maxFragments) > lastMultiplier / 2) {
long increment = lastMultiplier - unitValues.get(maxFragments);
for (int unit = lastUnitIndex - 1; unit > 0; unit--) {
increment *= TIME_MULTIPLIERS[unit];
}
return formatDuration(duration + increment, maxFragments);
}
}
MeasureFormat format = MeasureFormat.getInstance(DynamicBundle.getLocale(), MeasureFormat.FormatWidth.SHORT);
Measure[] measures = new Measure[Math.min(unitValues.size(), maxFragments)];
for (i = 0; i < measures.length; i++) {
measures[i] = new Measure(unitValues.get(i), TIME_UNITS[unitIndices.get(i)]);
}
return format.formatMeasures(measures);
}
private static final int[] PADDED_FORMATS = {3, 2, 2, 2, 1};
/**
* Formats duration given in milliseconds as a sum of padded time units, except the most significant unit
* E.g. 234523598 padded as "2d 03h 11m 04s 004ms" accordingly with zeros except "days" here.
* @param millis milliseconds
*/
@Contract(pure = true)
public static @NotNull @Nls String formatDurationPadded(long millis) {
long millisIn = 1;
int i;
for (i=1; i < TIME_MULTIPLIERS.length; i++) {
long multiplier = TIME_MULTIPLIERS[i];
millisIn *= multiplier;
if (millis < millisIn) {
break;
}
}
long d = millis;
LocalizedNumberFormatter formatter = NumberFormatter.withLocale(DynamicBundle.getLocale()).unitWidth(NumberFormatter.UnitWidth.NARROW);
List<FormattedNumber> result = new ArrayList<>();
for (i-=1; i >= 0; i--) {
long multiplier = i==TIME_MULTIPLIERS.length-1 ? 1 : TIME_MULTIPLIERS[i+1];
millisIn /= multiplier;
long value = d / millisIn;
d = d % millisIn;
IntegerWidth style = IntegerWidth.zeroFillTo(result.isEmpty() ? 1 : PADDED_FORMATS[i]); // do not pad the most significant unit
LocalizedNumberFormatter unitFormatter = formatter.unit(TIME_UNITS[i]).integerWidth(style);
result.add(unitFormatter.format(value));
}
return ListFormatter.getInstance(Locale.getDefault(), ListFormatter.Type.UNITS, ListFormatter.Width.NARROW).format(result);
}
}
@@ -4,6 +4,7 @@ package com.intellij.featureStatistics.actions;
import com.intellij.CommonBundle;
import com.intellij.featureStatistics.*;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.nls.NlsMessages;
import com.intellij.ide.util.TipUIUtil;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
@@ -12,7 +13,6 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Splitter;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.ScrollingUtil;
import com.intellij.ui.TableViewSpeedSearch;
@@ -41,7 +41,7 @@ public final class ShowFeatureUsageStatisticsDialog extends DialogWrapper {
private static final Comparator<FeatureDescriptor> LAST_USED_COMPARATOR =
(fd1, fd2) -> new Date(fd2.getLastTimeUsed()).compareTo(new Date(fd1.getLastTimeUsed()));
private static final ColumnInfo<FeatureDescriptor, String> DISPLAY_NAME = new ColumnInfo<FeatureDescriptor, String>(FeatureStatisticsBundle.message("feature.statistics.column.feature")) {
private static final ColumnInfo<FeatureDescriptor, String> DISPLAY_NAME = new ColumnInfo<>(FeatureStatisticsBundle.message("feature.statistics.column.feature")) {
@Override
public String valueOf(FeatureDescriptor featureDescriptor) {
return featureDescriptor.getDisplayName();
@@ -52,7 +52,7 @@ public final class ShowFeatureUsageStatisticsDialog extends DialogWrapper {
return DISPLAY_NAME_COMPARATOR;
}
};
private static final ColumnInfo<FeatureDescriptor, String> GROUP_NAME = new ColumnInfo<FeatureDescriptor, String>(FeatureStatisticsBundle.message("feature.statistics.column.group")) {
private static final ColumnInfo<FeatureDescriptor, String> GROUP_NAME = new ColumnInfo<>(FeatureStatisticsBundle.message("feature.statistics.column.group")) {
@Override
public String valueOf(FeatureDescriptor featureDescriptor) {
return getGroupName(featureDescriptor);
@@ -63,7 +63,7 @@ public final class ShowFeatureUsageStatisticsDialog extends DialogWrapper {
return GROUP_NAME_COMPARATOR;
}
};
private static final ColumnInfo<FeatureDescriptor, String> USED_TOTAL = new ColumnInfo<FeatureDescriptor, String>(FeatureStatisticsBundle.message("feature.statistics.column.usage.count")) {
private static final ColumnInfo<FeatureDescriptor, String> USED_TOTAL = new ColumnInfo<>(FeatureStatisticsBundle.message("feature.statistics.column.usage.count")) {
@Override
public String valueOf(FeatureDescriptor featureDescriptor) {
int count = featureDescriptor.getUsageCount();
@@ -75,7 +75,7 @@ public final class ShowFeatureUsageStatisticsDialog extends DialogWrapper {
return USAGE_COUNT_COMPARATOR;
}
};
private static final ColumnInfo<FeatureDescriptor, String> LAST_USED = new ColumnInfo<FeatureDescriptor, String>(FeatureStatisticsBundle.message("feature.statistics.column.last.used")) {
private static final ColumnInfo<FeatureDescriptor, String> LAST_USED = new ColumnInfo<>(FeatureStatisticsBundle.message("feature.statistics.column.last.used")) {
@Override
public String valueOf(FeatureDescriptor featureDescriptor) {
long tm = featureDescriptor.getLastTimeUsed();
@@ -130,7 +130,7 @@ public final class ShowFeatureUsageStatisticsDialog extends DialogWrapper {
features.add(registry.getFeatureDescriptor(id));
}
TableView<FeatureDescriptor> table = new TableView<>(new ListTableModel<>(COLUMNS, features, 0));
new TableViewSpeedSearch<FeatureDescriptor>(table) {
new TableViewSpeedSearch<>(table) {
@Override
protected String getItemText(@NotNull FeatureDescriptor element) {
return element.getDisplayName();
@@ -146,10 +146,10 @@ public final class ShowFeatureUsageStatisticsDialog extends DialogWrapper {
final String uptimeS = FeatureStatisticsBundle.message("feature.statistics.application.uptime",
ApplicationNamesInfo.getInstance().getFullProductName(),
StringUtil.formatDurationApproximate(uptime));
NlsMessages.formatDurationApproximate(uptime));
final String idleTimeS = FeatureStatisticsBundle.message("feature.statistics.application.idle.time",
StringUtil.formatDurationApproximate(idleTime));
NlsMessages.formatDurationApproximate(idleTime));
String labelText = uptimeS + ", " + idleTimeS;
CompletionStatistics stats = ((FeatureUsageTrackerImpl)FeatureUsageTracker.getInstance()).getCompletionStatistics();
@@ -0,0 +1,88 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.ide.nls;
import org.junit.Test;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.stream.Stream;
import static org.junit.Assert.assertEquals;
public class NlsMessagesTest {
@Test
public void testFormatAnd() {
assertEquals("Java, Kotlin, and Groovy", NlsMessages.formatAndList(Arrays.asList("Java", "Kotlin", "Groovy")));
}
@Test
public void testFormatOr() {
assertEquals("Java, Kotlin, or Groovy", NlsMessages.formatOrList(Arrays.asList("Java", "Kotlin", "Groovy")));
}
@Test
public void testJoiningAnd() {
assertEquals("Java, Kotlin, and Groovy", Stream.of("Java", "Kotlin", "Groovy").collect(NlsMessages.joiningAnd()));
}
@Test
public void testJoiningOr() {
assertEquals("Java, Kotlin, or Groovy", Stream.of("Java", "Kotlin", "Groovy").collect(NlsMessages.joiningOr()));
}
@Test
public void testFormatDuration() {
assertEquals("0 ms", NlsMessages.formatDuration(0));
assertEquals("1 ms", NlsMessages.formatDuration(1));
assertEquals("1 sec", NlsMessages.formatDuration(1000));
assertEquals("24 days, 20 hr, 31 min, 23 sec, 647 ms", NlsMessages.formatDuration(Integer.MAX_VALUE));
assertEquals("82 days, 17 hr, 24 min, 43 sec, 647 ms", NlsMessages.formatDuration(Integer.MAX_VALUE+5000000000L));
assertEquals("1 min, 0 sec, 100 ms", NlsMessages.formatDuration(60100));
assertEquals("1 sec, 234 ms", NlsMessages.formatDuration(1234));
assertEquals("12 sec, 345 ms", NlsMessages.formatDuration(12345));
assertEquals("2 min, 3 sec, 456 ms", NlsMessages.formatDuration(123456));
assertEquals("20 min, 34 sec, 567 ms", NlsMessages.formatDuration(1234567));
assertEquals("3 hr, 25 min, 45 sec, 678 ms", NlsMessages.formatDuration(12345678));
assertEquals("1 day, 10 hr, 17 min, 36 sec, 789 ms", NlsMessages.formatDuration(123456789));
assertEquals("14 days, 6 hr, 56 min, 7 sec, 890 ms", NlsMessages.formatDuration(1234567890));
assertEquals("39 days, 2 hr, 30 min, 6 sec, 101 ms", NlsMessages.formatDuration(3378606101L));
}
@Test
public void testFormatDurationApproximate() {
assertEquals("0 ms", NlsMessages.formatDurationApproximate(0));
assertEquals("59 sec, 999 ms", NlsMessages.formatDurationApproximate(60000 - 1));
assertEquals("1 min", NlsMessages.formatDurationApproximate(60000));
assertEquals("1 min, 0 sec", NlsMessages.formatDurationApproximate(60000 + 1));
assertEquals("2 min", NlsMessages.formatDurationApproximate(120000 - 1));
assertEquals("2 min", NlsMessages.formatDurationApproximate(120000));
assertEquals("2 min, 0 sec", NlsMessages.formatDurationApproximate(120000 + 1));
assertEquals("2 min, 0 sec", NlsMessages.formatDurationApproximate(120000 + 499));
assertEquals("2 min, 0 sec", NlsMessages.formatDurationApproximate(120000 + 500));
assertEquals("2 min, 1 sec", NlsMessages.formatDurationApproximate(120000 + 501));
assertEquals("2 min, 3 sec", NlsMessages.formatDurationApproximate(123000));
assertEquals("2 min, 4 sec", NlsMessages.formatDurationApproximate(123789));
assertEquals("2 min, 3 sec", NlsMessages.formatDurationApproximate(123456));
assertEquals("1 hr, 1 min", NlsMessages.formatDurationApproximate(3659009));
assertEquals("2 hr", NlsMessages.formatDurationApproximate(7199000));
assertEquals("1 day", NlsMessages.formatDurationApproximate((23 * 60 * 60 + 59 * 60 + 59) * 1000L));
assertEquals("391 days, 1 hr", NlsMessages.formatDurationApproximate(33786061001L));
}
@Test
public void testFormatDurationPadded() {
assertEquals("0ms", NlsMessages.formatDurationPadded(0));
assertEquals("1s 000ms", NlsMessages.formatDurationPadded(1000));
assertEquals("1s 001ms", NlsMessages.formatDurationPadded(1001));
assertEquals("2m 00s 000ms", NlsMessages.formatDurationPadded(TimeUnit.MINUTES.toMillis(2)));
assertEquals("2h 00m 00s 000ms", NlsMessages.formatDurationPadded(TimeUnit.HOURS.toMillis(2)));
assertEquals("2d 00h 00m 00s 000ms", NlsMessages.formatDurationPadded(TimeUnit.DAYS.toMillis(2)));
assertEquals("1,434,852d 16h 13m 50s 987ms", NlsMessages.formatDurationPadded(123971271230987L));
}
}
@@ -14,6 +14,7 @@ import com.intellij.execution.testframework.sm.runner.states.*;
import com.intellij.execution.testframework.sm.runner.ui.TestsPresentationUtil;
import com.intellij.execution.testframework.stacktrace.DiffHyperlink;
import com.intellij.ide.DataManager;
import com.intellij.ide.nls.NlsMessages;
import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.DumbService;
@@ -417,7 +418,7 @@ public class SMTestProxy extends AbstractTestProxy {
}
private String getDurationPaddedString() {
final Long duration = getDuration();
return duration != null ? StringUtil.formatDurationPadded(duration.longValue(), "\u2009") : null;
return duration != null ? NlsMessages.formatDurationPadded(duration.longValue()) : null;
}
@Override
@@ -1438,39 +1438,47 @@ public class StringUtil extends StringUtilRt {
return Formats.formatFileSize(fileSize, unitSeparator);
}
/** Formats duration given in milliseconds as a sum of time units (example: {@code formatDuration(123456) = "2 m 3 s 456 ms"}). */
/**
* Formats duration given in milliseconds as a sum of time units (example: {@code formatDuration(123456) = "2 m 3 s 456 ms"}).
* This method is intended to be used in non-localized contexts (primarily in log output).
* See com.intellij.ide.nls.NlsMessages for localized output.
*/
@Contract(pure = true)
public static @NotNull String formatDuration(long duration) {
public static @NotNull @NonNls String formatDuration(long duration) {
return Formats.formatDuration(duration);
}
/** Formats {@link Duration} as a sum of time units (calls {@link #formatDuration(long)} with duration converted to milliseconds) */
/**
* Formats {@link Duration} as a sum of time units (calls {@link #formatDuration(long)} with duration converted to milliseconds)
* This method is intended to be used in non-localized contexts (primarily in log output).
* See com.intellij.ide.nls.NlsMessages for localized output.
*/
@Contract(pure = true)
public static @NotNull String formatDuration(@NotNull Duration duration) {
public static @NotNull @NonNls String formatDuration(@NotNull Duration duration) {
return Formats.formatDuration(duration);
}
/** Formats duration given in milliseconds as a sum of time units (example: {@code formatDuration(123456, "") = "2m 3s 456ms"}). */
@Contract(pure = true)
public static @NotNull String formatDuration(long duration, @NotNull String unitSeparator) {
public static @NotNull @NonNls String formatDuration(long duration, @NotNull String unitSeparator) {
return Formats.formatDuration(duration, unitSeparator);
}
/**
* Formats duration given in milliseconds as a sum of padded time units, except the most significant unit
* E.g. 234523598 padded as "2 d 03 h 11 min 04 sec 004 ms" accordingly with zeros except "days" here.
* @deprecated use com.intellij.ide.nls.NlsMessages for localized output.
*/
@Contract(pure = true)
public static @NotNull String formatDurationPadded(long millis, @NotNull String unitSeparator) {
@Deprecated
public static @NotNull @NonNls String formatDurationPadded(long millis, @NotNull String unitSeparator) {
return Formats.formatDurationPadded(millis, unitSeparator);
}
/**
* Formats duration given in milliseconds as a sum of time units with at most two units
* (example: {@code formatDuration(123456) = "2 m 3 s"}).
* @deprecated use com.intellij.ide.nls.NlsMessages for localized output.
*/
@Contract(pure = true)
public static @NotNull String formatDurationApproximate(long duration) {
@Deprecated
public static @NotNull @NonNls String formatDurationApproximate(long duration) {
return Formats.formatDurationApproximate(duration);
}
@@ -85,10 +85,10 @@ public final class Formats {
private static final String[] PADDED_FORMATS = {"%03d", "%02d", "%02d", "%02d", "%d"};
/**
* Formats duration given in milliseconds as a sum of padded time units, except the most significant unit
* E.g. 234523598 padded as "2 d 03 h 11 min 04 sec 004 ms" accordingly with zeros except "days" here.
* @deprecated use com.intellij.ide.nls.NlsMessages for localized output.
*/
@Contract(pure = true)
@Deprecated
public static @NotNull String formatDurationPadded(long millis, @NotNull String unitSeparator) {
StringBuilder result = new StringBuilder();
@@ -115,10 +115,10 @@ public final class Formats {
}
/**
* Formats duration given in milliseconds as a sum of time units with at most two units
* (example: {@code formatDuration(123456) = "2 m 3 s"}).
* @deprecated use com.intellij.ide.nls.NlsMessages for localized output.
*/
@Contract(pure = true)
@Deprecated
public static @NotNull String formatDurationApproximate(long duration) {
return formatDuration(duration, " ", 2);
}