Repository: maven Updated Branches: refs/heads/MNG-5977 5e553e653 -> 9c72005cc (forced update)
[MNG-5977] Improve output readability of our MavenTransferListener implementations * Applied a general decimal formatter which automatically scales file size between 1 and 1000 along with proper size and time units * The progress meter in the shell will now properly tell that a progress is going on and visually seperate parallel downloads with " | " * Optimized and reduced padding to the cases where it actually is necessary * Padding has to applied to very event which can succeed a progress update * Synchronize all calls to console to avoid race conditions where output is terminated by a carriage return only. If no sync is done, SLF4J or INIT/SUCCEEDED update can interleave and overwrite the progress while being shorter as the progress itself. * Reworked the file size formatter which now compacts the progress with the unit symbol, plus it scales to one decimal place only if the size is below 10. * Replaced the concurrent hash map with a synchronized linked hash map to retain order of the progress meter. It will behave now like a queue. Race conditions cannot be avoided if -T is employed since one does not have access to the output stream of a SLF4J backend to synchronize on. Add the amount of currently in download/upload progressing items to the Progress label. When running in debug mode, Maven displays the filename currently in progress. Work around a rounding bug existed upto Java 7 See http://stackoverflow.com/q/22797964/696632 and Oracle's bugfix announcement: http://www.oracle.com/technetwork/java/javase/8-compatibility-guide-2156366.html Project: http://git-wip-us.apache.org/repos/asf/maven/repo Commit: http://git-wip-us.apache.org/repos/asf/maven/commit/9c72005c Tree: http://git-wip-us.apache.org/repos/asf/maven/tree/9c72005c Diff: http://git-wip-us.apache.org/repos/asf/maven/diff/9c72005c Branch: refs/heads/MNG-5977 Commit: 9c72005ccd490a183152a65cffa1ecebfc4e7acd Parents: deefd93 Author: Michael Osipov <micha...@apache.org> Authored: Thu Feb 18 00:28:50 2016 +0100 Committer: Michael Osipov <micha...@apache.org> Committed: Sun Jan 22 22:23:43 2017 +0100 ---------------------------------------------------------------------- .../java/org/apache/maven/cli/MavenCli.java | 10 +- .../transfer/AbstractMavenTransferListener.java | 209 +++++++++++-- .../transfer/ConsoleMavenTransferListener.java | 110 ++++--- .../transfer/Slf4jMavenTransferListener.java | 38 +-- .../maven/cli/transfer/FileSizeFormatTest.java | 313 +++++++++++++++++++ 5 files changed, 594 insertions(+), 86 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/maven/blob/9c72005c/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java ---------------------------------------------------------------------- diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java index 176ce4d..2b9f099 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java @@ -1005,13 +1005,13 @@ public class MavenCli // present supplied by the user. The rule is that we only allow the execution of one ConfigurationProcessor. // If there is more than one then we execute the one supplied by the user, otherwise we execute the // the default SettingsXmlConfigurationProcessor. - // + // int userSuppliedConfigurationProcessorCount = configurationProcessors.size() - 1; if ( userSuppliedConfigurationProcessorCount == 0 ) { // - // Our settings.xml source is historically how we have configured Maven from the CLI so we are going to + // Our settings.xml source is historically how we have configured Maven from the CLI so we are going to // have to honour its existence forever. So let's run it. // configurationProcessors.get( SettingsXmlConfigurationProcessor.HINT ).process( cliRequest ); @@ -1288,7 +1288,7 @@ public class MavenCli // If we're logging to a file then we don't want the console transfer listener as it will spew // download progress all over the place // - transferListener = getConsoleTransferListener(); + transferListener = getConsoleTransferListener( cliRequest.commandLine.hasOption( CLIManager.DEBUG ) ); } else { @@ -1588,9 +1588,9 @@ public class MavenCli // Customizations available via the CLI // - protected TransferListener getConsoleTransferListener() + protected TransferListener getConsoleTransferListener( boolean printResourceNames ) { - return new ConsoleMavenTransferListener( System.out ); + return new ConsoleMavenTransferListener( System.out, printResourceNames ); } protected TransferListener getBatchTransferListener() http://git-wip-us.apache.org/repos/asf/maven/blob/9c72005c/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java ---------------------------------------------------------------------- diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java b/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java index 58b1a5d..d3cc636 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/transfer/AbstractMavenTransferListener.java @@ -24,6 +24,7 @@ import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.Locale; +import org.apache.commons.lang3.Validate; import org.eclipse.aether.transfer.AbstractTransferListener; import org.eclipse.aether.transfer.TransferCancelledException; import org.eclipse.aether.transfer.TransferEvent; @@ -33,6 +34,178 @@ public abstract class AbstractMavenTransferListener extends AbstractTransferListener { + // CHECKSTYLE_OFF: LineLength + /** + * Formats file size with the associated <a href="https://en.wikipedia.org/wiki/Metric_prefix">SI</a> prefix + * (GB, MB, kB) and using the patterns <code>#0.0</code> for numbers between 1 and 10 + * and <code>###0</code> for numbers between 10 and 1000+ by default. + * + * @see <a href="https://en.wikipedia.org/wiki/Metric_prefix">https://en.wikipedia.org/wiki/Metric_prefix</a> + * @see <a href="https://en.wikipedia.org/wiki/Binary_prefix">https://en.wikipedia.org/wiki/Binary_prefix</a> + * @see <a + * href="https://en.wikipedia.org/wiki/Octet_%28computing%29">https://en.wikipedia.org/wiki/Octet_(computing)</a> + */ + // CHECKSTYLE_ON: LineLength + // TODO Move me to Maven Shared Utils + static class FileSizeFormat + { + static enum ScaleUnit + { + BYTE + { + @Override + public long bytes() + { + return 1L; + } + + @Override + public String symbol() + { + return "B"; + } + }, + KILOBYTE + { + @Override + public long bytes() + { + return 1000L; + } + + @Override + public String symbol() + { + return "kB"; + } + }, + MEGABYTE + { + @Override + public long bytes() + { + return KILOBYTE.bytes() * KILOBYTE.bytes(); + } + + @Override + public String symbol() + { + return "MB"; + } + }, + GIGABYTE + { + @Override + public long bytes() + { + return MEGABYTE.bytes() * KILOBYTE.bytes(); + }; + + @Override + public String symbol() + { + return "GB"; + } + }; + + public abstract long bytes(); + public abstract String symbol(); + + public static ScaleUnit getScaleUnit( long size ) + { + Validate.isTrue( size >= 0L, "file size cannot be negative: %s", size ); + + if ( size >= GIGABYTE.bytes() ) + { + return GIGABYTE; + } + else if ( size >= MEGABYTE.bytes() ) + { + return MEGABYTE; + } + else if ( size >= KILOBYTE.bytes() ) + { + return KILOBYTE; + } + else + { + return BYTE; + } + } + } + + private DecimalFormat smallFormat; + private DecimalFormat largeFormat; + + public FileSizeFormat( Locale locale ) + { + smallFormat = new DecimalFormat( "#0.0", new DecimalFormatSymbols( locale ) ); + largeFormat = new DecimalFormat( "###0", new DecimalFormatSymbols( locale ) ); + } + + public String format( long size ) + { + return format( size, null ); + } + + public String format( long size, ScaleUnit unit ) + { + return format( size, unit, false ); + } + + public String format( long size, ScaleUnit unit, boolean omitSymbol ) + { + Validate.isTrue( size >= 0L, "file size cannot be negative: %s", size ); + + if ( unit == null ) + { + unit = ScaleUnit.getScaleUnit( size ); + } + + double scaledSize = (double) size / unit.bytes(); + String scaledSymbol = " " + unit.symbol(); + + if ( omitSymbol ) + { + scaledSymbol = ""; + } + + if ( unit == ScaleUnit.BYTE ) + { + return largeFormat.format( size ) + scaledSymbol; + } + + if ( scaledSize < 0.05 || scaledSize >= 10.0 ) + { + return largeFormat.format( scaledSize ) + scaledSymbol; + } + else + { + return smallFormat.format( scaledSize ) + scaledSymbol; + } + } + + public String formatProgress( long progressedSize, long size ) + { + Validate.isTrue( progressedSize >= 0L, "progressed file size cannot be negative: %s", progressedSize ); + Validate.isTrue( size >= 0L && progressedSize <= size || size < 0L, + "progressed file size cannot be greater than size: %s > %s", progressedSize, size ); + + if ( size >= 0L && progressedSize != size ) + { + ScaleUnit unit = ScaleUnit.getScaleUnit( size ); + String formattedProgressedSize = format( progressedSize, unit, true ); + String formattedSize = format( size, unit ); + + return formattedProgressedSize + "/" + formattedSize; + } + else + { + return format( progressedSize ); + } + } + } + protected PrintStream out; protected AbstractMavenTransferListener( PrintStream out ) @@ -43,9 +216,10 @@ public abstract class AbstractMavenTransferListener @Override public void transferInitiated( TransferEvent event ) { - String message = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading"; + String type = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading"; - out.println( message + ": " + event.getResource().getRepositoryUrl() + event.getResource().getResourceName() ); + TransferResource resource = event.getResource(); + out.println( type + ": " + resource.getRepositoryUrl() + resource.getResourceName() ); } @Override @@ -53,7 +227,7 @@ public abstract class AbstractMavenTransferListener throws TransferCancelledException { TransferResource resource = event.getResource(); - + // TODO This needs to be colorized out.println( "[WARNING] " + event.getException().getMessage() + " for " + resource.getRepositoryUrl() + resource.getResourceName() ); } @@ -63,28 +237,21 @@ public abstract class AbstractMavenTransferListener { TransferResource resource = event.getResource(); long contentLength = event.getTransferredBytes(); - if ( contentLength >= 0 ) - { - String type = ( event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded" ); - String len = contentLength >= 1024 ? toKB( contentLength ) + " KB" : contentLength + " B"; - String throughput = ""; - long duration = System.currentTimeMillis() - resource.getTransferStartTime(); - if ( duration > 0 ) - { - DecimalFormat format = new DecimalFormat( "0.0", new DecimalFormatSymbols( Locale.ENGLISH ) ); - double kbPerSec = ( contentLength / 1024.0 ) / ( duration / 1000.0 ); - throughput = " at " + format.format( kbPerSec ) + " KB/sec"; - } + FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH ); + String type = ( event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded" ); + String len = format.format( contentLength ); - out.println( type + ": " + resource.getRepositoryUrl() + resource.getResourceName() + " (" + len - + throughput + ")" ); + String throughput = ""; + long duration = System.currentTimeMillis() - resource.getTransferStartTime(); + if ( duration > 0L ) + { + double bytesPerSecond = contentLength / ( duration / 1000.0 ); + throughput = " at " + format.format( (long) bytesPerSecond ) + "/s"; } - } - protected long toKB( long bytes ) - { - return ( bytes + 1023 ) / 1024; + out.println( type + ": " + resource.getRepositoryUrl() + resource.getResourceName() + " (" + len + + throughput + ")" ); } } http://git-wip-us.apache.org/repos/asf/maven/blob/9c72005c/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java ---------------------------------------------------------------------- diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java b/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java index 5f87836..5af1821 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/transfer/ConsoleMavenTransferListener.java @@ -20,9 +20,13 @@ package org.apache.maven.cli.transfer; */ import java.io.PrintStream; +import java.util.Collections; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Locale; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; +import org.apache.commons.lang3.StringUtils; import org.eclipse.aether.transfer.TransferCancelledException; import org.eclipse.aether.transfer.TransferEvent; import org.eclipse.aether.transfer.TransferResource; @@ -36,32 +40,58 @@ public class ConsoleMavenTransferListener extends AbstractMavenTransferListener { - private Map<TransferResource, Long> downloads = new ConcurrentHashMap<>(); + private Map<TransferResource, Long> transfers = Collections.synchronizedMap( + new LinkedHashMap<TransferResource, Long>() ); + private boolean printResourceNames; private int lastLength; - public ConsoleMavenTransferListener( PrintStream out ) + public ConsoleMavenTransferListener( PrintStream out, boolean printResourceNames ) { super( out ); + this.printResourceNames = printResourceNames; } @Override - public void transferProgressed( TransferEvent event ) + public synchronized void transferInitiated( TransferEvent event ) + { + overridePreviousTransfer( event ); + + super.transferInitiated( event ); + } + + @Override + public synchronized void transferCorrupted( TransferEvent event ) + throws TransferCancelledException + { + overridePreviousTransfer( event ); + + super.transferCorrupted( event ); + } + + @Override + public synchronized void transferProgressed( TransferEvent event ) throws TransferCancelledException { TransferResource resource = event.getResource(); - downloads.put( resource, event.getTransferredBytes() ); + transfers.put( resource, event.getTransferredBytes() ); - StringBuilder buffer = new StringBuilder( 64 ); + StringBuilder buffer = new StringBuilder( 128 ); + buffer.append( "Progress (" ).append( transfers.size() ).append( "): " ); - for ( Map.Entry<TransferResource, Long> entry : downloads.entrySet() ) + synchronized( transfers ) { - long total = entry.getKey().getContentLength(); - Long complete = entry.getValue(); - // NOTE: This null check guards against http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6312056 - if ( complete != null ) + Iterator<Map.Entry<TransferResource, Long>> entries = transfers.entrySet().iterator(); + while ( entries.hasNext() ) { - buffer.append( getStatus( complete, total ) ).append( " " ); + Map.Entry<TransferResource, Long> entry = entries.next(); + long total = entry.getKey().getContentLength(); + Long complete = entry.getValue(); + buffer.append( getStatus( entry.getKey().getResourceName(), complete, total ) ); + if ( entries.hasNext() ) + { + buffer.append( " | " ); + } } } @@ -69,28 +99,29 @@ public class ConsoleMavenTransferListener lastLength = buffer.length(); pad( buffer, pad ); buffer.append( '\r' ); - out.print( buffer.toString() ); + out.flush(); } - private String getStatus( long complete, long total ) + private String getStatus( String resourceName, long complete, long total ) { - if ( total >= 1024 ) - { - return toKB( complete ) + "/" + toKB( total ) + " KB "; - } - else if ( total >= 0 ) - { - return complete + "/" + total + " B "; - } - else if ( complete >= 1024 ) + FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH ); + StringBuilder status = new StringBuilder(); + + if ( printResourceNames ) { - return toKB( complete ) + " KB "; + status.append( StringUtils.substringAfterLast( resourceName, "/" ) ); + status.append( " (" ); } - else + + status.append( format.formatProgress( complete, total ) ); + + if ( printResourceNames ) { - return complete + " B "; + status.append( ")" ); } + + return status.toString(); } private void pad( StringBuilder buffer, int spaces ) @@ -105,29 +136,34 @@ public class ConsoleMavenTransferListener } @Override - public void transferSucceeded( TransferEvent event ) + public synchronized void transferSucceeded( TransferEvent event ) { - transferCompleted( event ); + transfers.remove( event.getResource() ); + overridePreviousTransfer( event ); super.transferSucceeded( event ); } @Override - public void transferFailed( TransferEvent event ) + public synchronized void transferFailed( TransferEvent event ) { - transferCompleted( event ); + transfers.remove( event.getResource() ); + overridePreviousTransfer( event ); super.transferFailed( event ); } - private void transferCompleted( TransferEvent event ) + private void overridePreviousTransfer( TransferEvent event ) { - downloads.remove( event.getResource() ); - - StringBuilder buffer = new StringBuilder( 64 ); - pad( buffer, lastLength ); - buffer.append( '\r' ); - out.print( buffer.toString() ); + if ( lastLength > 0 ) + { + StringBuilder buffer = new StringBuilder( 128 ); + pad( buffer, lastLength ); + buffer.append( '\r' ); + out.print( buffer.toString() ); + out.flush(); + lastLength = 0; + } } } http://git-wip-us.apache.org/repos/asf/maven/blob/9c72005c/maven-embedder/src/main/java/org/apache/maven/cli/transfer/Slf4jMavenTransferListener.java ---------------------------------------------------------------------- diff --git a/maven-embedder/src/main/java/org/apache/maven/cli/transfer/Slf4jMavenTransferListener.java b/maven-embedder/src/main/java/org/apache/maven/cli/transfer/Slf4jMavenTransferListener.java index bb72db3..5bfb7b4 100644 --- a/maven-embedder/src/main/java/org/apache/maven/cli/transfer/Slf4jMavenTransferListener.java +++ b/maven-embedder/src/main/java/org/apache/maven/cli/transfer/Slf4jMavenTransferListener.java @@ -19,10 +19,9 @@ package org.apache.maven.cli.transfer; * under the License. */ -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; import java.util.Locale; +import org.apache.maven.cli.transfer.AbstractMavenTransferListener.FileSizeFormat; import org.eclipse.aether.transfer.AbstractTransferListener; import org.eclipse.aether.transfer.TransferCancelledException; import org.eclipse.aether.transfer.TransferEvent; @@ -50,9 +49,10 @@ public class Slf4jMavenTransferListener @Override public void transferInitiated( TransferEvent event ) { - String message = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading"; + String type = event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploading" : "Downloading"; - out.info( message + ": " + event.getResource().getRepositoryUrl() + event.getResource().getResourceName() ); + TransferResource resource = event.getResource(); + out.info( type + ": " + resource.getRepositoryUrl() + resource.getResourceName() ); } @Override @@ -60,7 +60,6 @@ public class Slf4jMavenTransferListener throws TransferCancelledException { TransferResource resource = event.getResource(); - out.warn( event.getException().getMessage() + " for " + resource.getRepositoryUrl() + resource.getResourceName() ); } @@ -70,28 +69,21 @@ public class Slf4jMavenTransferListener { TransferResource resource = event.getResource(); long contentLength = event.getTransferredBytes(); - if ( contentLength >= 0 ) - { - String type = ( event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded" ); - String len = contentLength >= 1024 ? toKB( contentLength ) + " KB" : contentLength + " B"; - String throughput = ""; - long duration = System.currentTimeMillis() - resource.getTransferStartTime(); - if ( duration > 0 ) - { - DecimalFormat format = new DecimalFormat( "0.0", new DecimalFormatSymbols( Locale.ENGLISH ) ); - double kbPerSec = ( contentLength / 1024.0 ) / ( duration / 1000.0 ); - throughput = " at " + format.format( kbPerSec ) + " KB/sec"; - } + FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH ); + String type = ( event.getRequestType() == TransferEvent.RequestType.PUT ? "Uploaded" : "Downloaded" ); + String len = format.format( contentLength ); - out.info( type + ": " + resource.getRepositoryUrl() + resource.getResourceName() + " (" + len - + throughput + ")" ); + String throughput = ""; + long duration = System.currentTimeMillis() - resource.getTransferStartTime(); + if ( duration > 0L ) + { + double bytesPerSecond = contentLength / ( duration / 1000.0 ); + throughput = " at " + format.format( (long) bytesPerSecond ) + "/s"; } - } - protected long toKB( long bytes ) - { - return ( bytes + 1023 ) / 1024; + out.info( type + ": " + resource.getRepositoryUrl() + resource.getResourceName() + " (" + len + + throughput + ")" ); } } http://git-wip-us.apache.org/repos/asf/maven/blob/9c72005c/maven-embedder/src/test/java/org/apache/maven/cli/transfer/FileSizeFormatTest.java ---------------------------------------------------------------------- diff --git a/maven-embedder/src/test/java/org/apache/maven/cli/transfer/FileSizeFormatTest.java b/maven-embedder/src/test/java/org/apache/maven/cli/transfer/FileSizeFormatTest.java new file mode 100644 index 0000000..43939d1 --- /dev/null +++ b/maven-embedder/src/test/java/org/apache/maven/cli/transfer/FileSizeFormatTest.java @@ -0,0 +1,313 @@ +package org.apache.maven.cli.transfer; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.Locale; + +import org.apache.commons.lang3.JavaVersion; +import org.apache.commons.lang3.SystemUtils; +import org.apache.maven.cli.transfer.AbstractMavenTransferListener.FileSizeFormat; +import org.apache.maven.cli.transfer.AbstractMavenTransferListener.FileSizeFormat.ScaleUnit; + +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +public class FileSizeFormatTest { + + @Test( expected = IllegalArgumentException.class ) + public void testNegativeSize() + { + FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH ); + + long negativeSize = -100L; + format.format( negativeSize ); + } + + @Test + public void testSize() + { + FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH ); + + long _0_bytes = 0L; + assertEquals( "0 B", format.format( _0_bytes ) ); + + long _5_bytes = 5L; + assertEquals( "5 B", format.format( _5_bytes ) ); + + long _10_bytes = 10L; + assertEquals( "10 B", format.format( _10_bytes ) ); + + long _15_bytes = 15L; + assertEquals( "15 B", format.format( _15_bytes ) ); + + long _999_bytes = 999L; + assertEquals( "999 B", format.format( _999_bytes ) ); + + long _1000_bytes = 1000L; + assertEquals( "1.0 kB", format.format( _1000_bytes ) ); + + long _5500_bytes = 5500L; + assertEquals( "5.5 kB", format.format( _5500_bytes ) ); + + long _10_kilobytes = 10L * 1000L; + assertEquals( "10 kB", format.format( _10_kilobytes ) ); + + long _15_kilobytes = 15L * 1000L; + assertEquals( "15 kB", format.format( _15_kilobytes ) ); + + long _999_kilobytes = 999L * 1000L; + assertEquals( "999 kB", format.format( _999_kilobytes ) ); + + long _1000_kilobytes = 1000L * 1000L; + assertEquals( "1.0 MB", format.format( _1000_kilobytes ) ); + + long _5500_kilobytes = 5500L * 1000L; + assertEquals( "5.5 MB", format.format( _5500_kilobytes ) ); + + long _10_megabytes = 10L * 1000L * 1000L; + assertEquals( "10 MB", format.format( _10_megabytes ) ); + + long _15_megabytes = 15L * 1000L * 1000L; + assertEquals( "15 MB", format.format( _15_megabytes ) ); + + long _999_megabytes = 999L * 1000L * 1000L; + assertEquals( "999 MB", format.format( _999_megabytes ) ); + + long _1000_megabytes = 1000L * 1000L * 1000L; + assertEquals( "1.0 GB", format.format( _1000_megabytes ) ); + + long _5500_megabytes = 5500L * 1000L * 1000L; + assertEquals( "5.5 GB", format.format( _5500_megabytes ) ); + + long _10_gigabytes = 10L * 1000L * 1000L * 1000L; + assertEquals( "10 GB", format.format( _10_gigabytes ) ); + + long _15_gigabytes = 15L * 1000L * 1000L * 1000L; + assertEquals( "15 GB", format.format( _15_gigabytes ) ); + + long _1000_gigabytes = 1000L * 1000L * 1000L * 1000L; + assertEquals( "1000 GB", format.format( _1000_gigabytes ) ); + } + + @Test + public void testSizeWithSelectedScaleUnit() + { + FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH ); + + long _0_bytes = 0L; + assertEquals( "0 B", format.format( _0_bytes ) ); + assertEquals( "0 B", format.format( _0_bytes, ScaleUnit.BYTE ) ); + assertEquals( "0 kB", format.format( _0_bytes, ScaleUnit.KILOBYTE ) ); + assertEquals( "0 MB", format.format( _0_bytes, ScaleUnit.MEGABYTE ) ); + assertEquals( "0 GB", format.format( _0_bytes, ScaleUnit.GIGABYTE ) ); + + long _5_bytes = 5L; + assertEquals( "5 B", format.format( _5_bytes ) ); + assertEquals( "5 B", format.format( _5_bytes, ScaleUnit.BYTE ) ); + assertEquals( "0 kB", format.format( _5_bytes, ScaleUnit.KILOBYTE ) ); + assertEquals( "0 MB", format.format( _5_bytes, ScaleUnit.MEGABYTE ) ); + assertEquals( "0 GB", format.format( _5_bytes, ScaleUnit.GIGABYTE ) ); + + + long _49_bytes = 49L; + assertEquals( "49 B", format.format( _49_bytes ) ); + assertEquals( "49 B", format.format( _49_bytes, ScaleUnit.BYTE ) ); + assertEquals( "0 kB", format.format( _49_bytes, ScaleUnit.KILOBYTE ) ); + assertEquals( "0 MB", format.format( _49_bytes, ScaleUnit.MEGABYTE ) ); + assertEquals( "0 GB", format.format( _49_bytes, ScaleUnit.GIGABYTE ) ); + + long _50_bytes = 50L; + assertEquals( "50 B", format.format( _50_bytes ) ); + assertEquals( "50 B", format.format( _50_bytes, ScaleUnit.BYTE ) ); + if ( SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) ) + { + assertEquals( "0.1 kB", format.format( _50_bytes, ScaleUnit.KILOBYTE ) ); + } + assertEquals( "0 MB", format.format( _50_bytes, ScaleUnit.MEGABYTE ) ); + assertEquals( "0 GB", format.format( _50_bytes, ScaleUnit.GIGABYTE ) ); + + long _999_bytes = 999L; + assertEquals( "999 B", format.format( _999_bytes ) ); + assertEquals( "999 B", format.format( _999_bytes, ScaleUnit.BYTE ) ); + assertEquals( "1.0 kB", format.format( _999_bytes, ScaleUnit.KILOBYTE ) ); + assertEquals( "0 MB", format.format( _999_bytes, ScaleUnit.MEGABYTE ) ); + assertEquals( "0 GB", format.format( _999_bytes, ScaleUnit.GIGABYTE ) ); + + long _1000_bytes = 1000L; + assertEquals( "1.0 kB", format.format( _1000_bytes ) ); + assertEquals( "1000 B", format.format( _1000_bytes, ScaleUnit.BYTE ) ); + assertEquals( "1.0 kB", format.format( _1000_bytes, ScaleUnit.KILOBYTE ) ); + assertEquals( "0 MB", format.format( _1000_bytes, ScaleUnit.MEGABYTE ) ); + assertEquals( "0 GB", format.format( _1000_bytes, ScaleUnit.GIGABYTE ) ); + + long _49_kilobytes = 49L * 1000L; + assertEquals( "49 kB", format.format( _49_kilobytes ) ); + assertEquals( "49000 B", format.format( _49_kilobytes, ScaleUnit.BYTE ) ); + assertEquals( "49 kB", format.format( _49_kilobytes, ScaleUnit.KILOBYTE ) ); + assertEquals( "0 MB", format.format( _49_kilobytes, ScaleUnit.MEGABYTE ) ); + assertEquals( "0 GB", format.format( _49_kilobytes, ScaleUnit.GIGABYTE ) ); + + long _50_kilobytes = 50L * 1000L; + assertEquals( "50 kB", format.format( _50_kilobytes ) ); + assertEquals( "50000 B", format.format( _50_kilobytes, ScaleUnit.BYTE ) ); + assertEquals( "50 kB", format.format( _50_kilobytes, ScaleUnit.KILOBYTE ) ); + if ( SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) ) + { + assertEquals( "0.1 MB", format.format( _50_kilobytes, ScaleUnit.MEGABYTE ) ); + } + assertEquals( "0 GB", format.format( _50_kilobytes, ScaleUnit.GIGABYTE ) ); + + long _999_kilobytes = 999L * 1000L; + assertEquals( "999 kB", format.format( _999_kilobytes ) ); + assertEquals( "999000 B", format.format( _999_kilobytes, ScaleUnit.BYTE ) ); + assertEquals( "999 kB", format.format( _999_kilobytes, ScaleUnit.KILOBYTE ) ); + assertEquals( "1.0 MB", format.format( _999_kilobytes, ScaleUnit.MEGABYTE ) ); + assertEquals( "0 GB", format.format( _999_kilobytes, ScaleUnit.GIGABYTE ) ); + + long _1000_kilobytes = 1000L * 1000L; + assertEquals( "1.0 MB", format.format( _1000_kilobytes ) ); + assertEquals( "1000000 B", format.format( _1000_kilobytes, ScaleUnit.BYTE ) ); + assertEquals( "1000 kB", format.format( _1000_kilobytes, ScaleUnit.KILOBYTE ) ); + assertEquals( "1.0 MB", format.format( _1000_kilobytes, ScaleUnit.MEGABYTE ) ); + assertEquals( "0 GB", format.format( _1000_kilobytes, ScaleUnit.GIGABYTE ) ); + + long _49_megabytes = 49L * 1000L * 1000L; + assertEquals( "49 MB", format.format( _49_megabytes ) ); + assertEquals( "49000000 B", format.format( _49_megabytes, ScaleUnit.BYTE ) ); + assertEquals( "49000 kB", format.format( _49_megabytes, ScaleUnit.KILOBYTE ) ); + assertEquals( "49 MB", format.format( _49_megabytes, ScaleUnit.MEGABYTE ) ); + assertEquals( "0 GB", format.format( _49_megabytes, ScaleUnit.GIGABYTE ) ); + + long _50_megabytes = 50L * 1000L * 1000L; + assertEquals( "50 MB", format.format( _50_megabytes ) ); + assertEquals( "50000000 B", format.format( _50_megabytes, ScaleUnit.BYTE ) ); + assertEquals( "50000 kB", format.format( _50_megabytes, ScaleUnit.KILOBYTE ) ); + assertEquals( "50 MB", format.format( _50_megabytes, ScaleUnit.MEGABYTE ) ); + if ( SystemUtils.isJavaVersionAtLeast( JavaVersion.JAVA_1_8 ) ) + { + assertEquals( "0.1 GB", format.format( _50_megabytes, ScaleUnit.GIGABYTE ) ); + } + + long _999_megabytes = 999L * 1000L * 1000L; + assertEquals( "999 MB", format.format( _999_megabytes ) ); + assertEquals( "999000000 B", format.format( _999_megabytes, ScaleUnit.BYTE ) ); + assertEquals( "999000 kB", format.format( _999_megabytes, ScaleUnit.KILOBYTE ) ); + assertEquals( "999 MB", format.format( _999_megabytes, ScaleUnit.MEGABYTE ) ); + assertEquals( "1.0 GB", format.format( _999_megabytes, ScaleUnit.GIGABYTE ) ); + + long _1000_megabytes = 1000L * 1000L * 1000L; + assertEquals( "1.0 GB", format.format( _1000_megabytes ) ); + assertEquals( "1000000000 B", format.format( _1000_megabytes, ScaleUnit.BYTE ) ); + assertEquals( "1000000 kB", format.format( _1000_megabytes, ScaleUnit.KILOBYTE ) ); + assertEquals( "1000 MB", format.format( _1000_megabytes, ScaleUnit.MEGABYTE ) ); + assertEquals( "1.0 GB", format.format( _1000_megabytes, ScaleUnit.GIGABYTE ) ); + } + + @Test( expected = IllegalArgumentException.class ) + public void testNegativeProgessedSize() + { + FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH ); + + long negativeProgessedSize = -100L; + format.formatProgress( negativeProgessedSize, 10L ); + } + + @Test( expected = IllegalArgumentException.class ) + public void testNegativeProgessedSizeBiggerThanSize() + { + FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH ); + + format.formatProgress( 100L, 10L ); + } + + @Test + public void testProgressedSizeWithoutSize() + { + FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH ); + + long _0_bytes = 0L; + assertEquals( "0 B", format.formatProgress( _0_bytes, -1L ) ); + + long _1000_bytes = 1000L; + assertEquals( "1.0 kB", format.formatProgress( _1000_bytes, -1L ) ); + + long _1000_kilobytes = 1000L * 1000L; + assertEquals( "1.0 MB", format.formatProgress( _1000_kilobytes, -1L ) ); + + long _1000_megabytes = 1000L * 1000L * 1000L; + assertEquals( "1.0 GB", format.formatProgress( _1000_megabytes, -1L ) ); + + } + + @Test + public void testProgressedBothZero() + { + FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH ); + + long _0_bytes = 0L; + assertEquals( "0 B", format.formatProgress( _0_bytes, _0_bytes ) ); + } + + @Test + public void testProgressedSizeWithSize() + { + FileSizeFormat format = new FileSizeFormat( Locale.ENGLISH ); + + long _0_bytes = 0L; + long _400_bytes = 400L; + long _800_bytes = 2L * _400_bytes; + assertEquals( "0/800 B", format.formatProgress( _0_bytes, _800_bytes ) ); + assertEquals( "400/800 B", format.formatProgress( _400_bytes, _800_bytes ) ); + assertEquals( "800 B", format.formatProgress( _800_bytes, _800_bytes ) ); + + long _4000_bytes = 4000L; + long _8000_bytes = 2L * _4000_bytes; + long _50_kilobytes = 50000L; + assertEquals( "0/8.0 kB", format.formatProgress( _0_bytes, _8000_bytes ) ); + assertEquals( "0.4/8.0 kB", format.formatProgress( _400_bytes, _8000_bytes ) ); + assertEquals( "4.0/8.0 kB", format.formatProgress( _4000_bytes, _8000_bytes ) ); + assertEquals( "8.0 kB", format.formatProgress( _8000_bytes, _8000_bytes ) ); + assertEquals( "8.0/50 kB", format.formatProgress( _8000_bytes, _50_kilobytes ) ); + assertEquals( "16/50 kB", format.formatProgress( 2L * _8000_bytes, _50_kilobytes ) ); + assertEquals( "50 kB", format.formatProgress( _50_kilobytes, _50_kilobytes ) ); + + long _500_kilobytes = 500000L; + long _1000_kilobytes = 2L * _500_kilobytes;; + long _5000_kilobytes = 5L * _1000_kilobytes; + long _15_megabytes = 3L * _5000_kilobytes; + assertEquals( "0/5.0 MB", format.formatProgress( _0_bytes, _5000_kilobytes ) ); + assertEquals( "0.5/5.0 MB", format.formatProgress( _500_kilobytes, _5000_kilobytes ) ); + assertEquals( "1.0/5.0 MB", format.formatProgress( _1000_kilobytes, _5000_kilobytes ) ); + assertEquals( "5.0 MB", format.formatProgress( _5000_kilobytes, _5000_kilobytes ) ); + assertEquals( "5.0/15 MB", format.formatProgress( _5000_kilobytes, _15_megabytes ) ); + assertEquals( "15 MB", format.formatProgress( _15_megabytes, _15_megabytes ) ); + + long _500_megabytes = 500000000L; + long _1000_megabytes = 2L * _500_megabytes; + long _5000_megabytes = 5L * _1000_megabytes; + long _15_gigabytes = 3L * _5000_megabytes; + assertEquals( "0/500 MB", format.formatProgress( _0_bytes, _500_megabytes ) ); + assertEquals( "1.0/5.0 GB", format.formatProgress( _1000_megabytes, _5000_megabytes ) ); + assertEquals( "5.0 GB", format.formatProgress( _5000_megabytes, _5000_megabytes ) ); + assertEquals( "5.0/15 GB", format.formatProgress( _5000_megabytes, _15_gigabytes ) ); + assertEquals( "15 GB", format.formatProgress( _15_gigabytes, _15_gigabytes ) ); + } + +}