FileSizeFormatTest.java
/*
* 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.
*/
package org.apache.maven.cling.transfer;
import java.util.Locale;
import java.util.stream.Stream;
import org.apache.maven.api.services.MessageBuilder;
import org.apache.maven.cling.transfer.FileSizeFormat.ScaleUnit;
import org.apache.maven.impl.DefaultMessageBuilder;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class FileSizeFormatTest {
static Locale original;
@BeforeAll
static void beforeAll() {
original = Locale.getDefault();
Locale.setDefault(Locale.US);
}
@AfterAll
static void afterAll() {
Locale.setDefault(original);
}
@Test
void testNegativeSize() {
FileSizeFormat format = new FileSizeFormat();
assertThrows(IllegalArgumentException.class, () -> format.format(-100L));
}
static Stream<Arguments> sizeTestData() {
return Stream.of(
Arguments.of(0L, "0 B"),
Arguments.of(5L, "5 B"),
Arguments.of(10L, "10 B"),
Arguments.of(15L, "15 B"),
Arguments.of(999L, "999 B"),
Arguments.of(1000L, "1.0 kB"),
Arguments.of(5500L, "5.5 kB"),
Arguments.of(10L * 1000L, "10 kB"),
Arguments.of(15L * 1000L, "15 kB"),
Arguments.of(999L * 1000L, "999 kB"),
Arguments.of(1000L * 1000L, "1.0 MB"),
Arguments.of(5500L * 1000L, "5.5 MB"),
Arguments.of(10L * 1000L * 1000L, "10 MB"),
Arguments.of(15L * 1000L * 1000L, "15 MB"),
Arguments.of(999L * 1000L * 1000L, "999 MB"),
Arguments.of(1000L * 1000L * 1000L, "1.0 GB"),
Arguments.of(5500L * 1000L * 1000L, "5.5 GB"),
Arguments.of(10L * 1000L * 1000L * 1000L, "10 GB"),
Arguments.of(15L * 1000L * 1000L * 1000L, "15 GB"),
Arguments.of(1000L * 1000L * 1000L * 1000L, "1000 GB"));
}
@ParameterizedTest
@MethodSource("sizeTestData")
void testSize(long input, String expected) {
FileSizeFormat format = new FileSizeFormat();
assertEquals(expected, format.format(input));
}
static Stream<Arguments> sizeWithScaleUnitTestData() {
return Stream.of(
// 0 bytes
Arguments.of(0L, null, "0 B"),
Arguments.of(0L, ScaleUnit.BYTE, "0 B"),
Arguments.of(0L, ScaleUnit.KILOBYTE, "0 kB"),
Arguments.of(0L, ScaleUnit.MEGABYTE, "0 MB"),
Arguments.of(0L, ScaleUnit.GIGABYTE, "0 GB"),
// 5 bytes
Arguments.of(5L, null, "5 B"),
Arguments.of(5L, ScaleUnit.BYTE, "5 B"),
Arguments.of(5L, ScaleUnit.KILOBYTE, "0 kB"),
Arguments.of(5L, ScaleUnit.MEGABYTE, "0 MB"),
Arguments.of(5L, ScaleUnit.GIGABYTE, "0 GB"),
// 49 bytes
Arguments.of(49L, null, "49 B"),
Arguments.of(49L, ScaleUnit.BYTE, "49 B"),
Arguments.of(49L, ScaleUnit.KILOBYTE, "0 kB"),
Arguments.of(49L, ScaleUnit.MEGABYTE, "0 MB"),
Arguments.of(49L, ScaleUnit.GIGABYTE, "0 GB"),
// 50 bytes
Arguments.of(50L, null, "50 B"),
Arguments.of(50L, ScaleUnit.BYTE, "50 B"),
Arguments.of(50L, ScaleUnit.KILOBYTE, "0.1 kB"),
Arguments.of(50L, ScaleUnit.MEGABYTE, "0 MB"),
Arguments.of(50L, ScaleUnit.GIGABYTE, "0 GB"),
// 999 bytes
Arguments.of(999L, null, "999 B"),
Arguments.of(999L, ScaleUnit.BYTE, "999 B"),
Arguments.of(999L, ScaleUnit.KILOBYTE, "1.0 kB"),
Arguments.of(999L, ScaleUnit.MEGABYTE, "0 MB"),
Arguments.of(999L, ScaleUnit.GIGABYTE, "0 GB"),
// 1000 bytes
Arguments.of(1000L, null, "1.0 kB"),
Arguments.of(1000L, ScaleUnit.BYTE, "1000 B"),
Arguments.of(1000L, ScaleUnit.KILOBYTE, "1.0 kB"),
Arguments.of(1000L, ScaleUnit.MEGABYTE, "0 MB"),
Arguments.of(1000L, ScaleUnit.GIGABYTE, "0 GB"),
// 49 kilobytes
Arguments.of(49L * 1000L, null, "49 kB"),
Arguments.of(49L * 1000L, ScaleUnit.BYTE, "49000 B"),
Arguments.of(49L * 1000L, ScaleUnit.KILOBYTE, "49 kB"),
Arguments.of(49L * 1000L, ScaleUnit.MEGABYTE, "0 MB"),
Arguments.of(49L * 1000L, ScaleUnit.GIGABYTE, "0 GB"),
// 50 kilobytes
Arguments.of(50L * 1000L, null, "50 kB"),
Arguments.of(50L * 1000L, ScaleUnit.BYTE, "50000 B"),
Arguments.of(50L * 1000L, ScaleUnit.KILOBYTE, "50 kB"),
Arguments.of(50L * 1000L, ScaleUnit.MEGABYTE, "0.1 MB"),
Arguments.of(50L * 1000L, ScaleUnit.GIGABYTE, "0 GB"),
// 999 kilobytes
Arguments.of(999L * 1000L, null, "999 kB"),
Arguments.of(999L * 1000L, ScaleUnit.BYTE, "999000 B"),
Arguments.of(999L * 1000L, ScaleUnit.KILOBYTE, "999 kB"),
Arguments.of(999L * 1000L, ScaleUnit.MEGABYTE, "1.0 MB"),
Arguments.of(999L * 1000L, ScaleUnit.GIGABYTE, "0 GB"),
// 1000 kilobytes
Arguments.of(1000L * 1000L, null, "1.0 MB"),
Arguments.of(1000L * 1000L, ScaleUnit.BYTE, "1000000 B"),
Arguments.of(1000L * 1000L, ScaleUnit.KILOBYTE, "1000 kB"),
Arguments.of(1000L * 1000L, ScaleUnit.MEGABYTE, "1.0 MB"),
Arguments.of(1000L * 1000L, ScaleUnit.GIGABYTE, "0 GB"),
// 49 megabytes
Arguments.of(49L * 1000L * 1000L, null, "49 MB"),
Arguments.of(49L * 1000L * 1000L, ScaleUnit.BYTE, "49000000 B"),
Arguments.of(49L * 1000L * 1000L, ScaleUnit.KILOBYTE, "49000 kB"),
Arguments.of(49L * 1000L * 1000L, ScaleUnit.MEGABYTE, "49 MB"),
Arguments.of(49L * 1000L * 1000L, ScaleUnit.GIGABYTE, "0 GB"),
// 50 megabytes
Arguments.of(50L * 1000L * 1000L, null, "50 MB"),
Arguments.of(50L * 1000L * 1000L, ScaleUnit.BYTE, "50000000 B"),
Arguments.of(50L * 1000L * 1000L, ScaleUnit.KILOBYTE, "50000 kB"),
Arguments.of(50L * 1000L * 1000L, ScaleUnit.MEGABYTE, "50 MB"),
Arguments.of(50L * 1000L * 1000L, ScaleUnit.GIGABYTE, "0.1 GB"),
// 999 megabytes
Arguments.of(999L * 1000L * 1000L, null, "999 MB"));
}
@ParameterizedTest
@MethodSource("sizeWithScaleUnitTestData")
void testSizeWithSelectedScaleUnit(long input, ScaleUnit unit, String expected) {
FileSizeFormat format = new FileSizeFormat();
if (unit == null) {
assertEquals(expected, format.format(input));
} else {
assertEquals(expected, format.format(input, unit));
}
}
@Test
void testNegativeProgressedSize() {
FileSizeFormat format = new FileSizeFormat();
long negativeProgressedSize = -100L;
assertThrows(IllegalArgumentException.class, () -> format.formatProgress(negativeProgressedSize, 10L));
}
@Test
void testNegativeProgressedSizeBiggerThanSize() {
FileSizeFormat format = new FileSizeFormat();
assertThrows(IllegalArgumentException.class, () -> format.formatProgress(100L, 10L));
}
static Stream<Arguments> progressedSizeWithoutSizeTestData() {
return Stream.of(
Arguments.of(0L, "0 B"),
Arguments.of(1000L, "1.0 kB"),
Arguments.of(1000L * 1000L, "1.0 MB"),
Arguments.of(1000L * 1000L * 1000L, "1.0 GB"));
}
@ParameterizedTest
@MethodSource("progressedSizeWithoutSizeTestData")
void testProgressedSizeWithoutSize(long progressedSize, String expected) {
FileSizeFormat format = new FileSizeFormat();
assertEquals(expected, format.formatProgress(progressedSize, -1L));
}
static Stream<Arguments> progressedSizeWithSizeTestData() {
return Stream.of(
// Zero test
Arguments.of(0L, 0L, "0 B"),
// Bytes tests
Arguments.of(0L, 800L, "0/800 B"),
Arguments.of(400L, 800L, "400/800 B"),
Arguments.of(800L, 800L, "800 B"),
// Kilobytes tests
Arguments.of(0L, 8000L, "0/8.0 kB"),
Arguments.of(400L, 8000L, "0.4/8.0 kB"),
Arguments.of(4000L, 8000L, "4.0/8.0 kB"),
Arguments.of(8000L, 8000L, "8.0 kB"),
Arguments.of(8000L, 50000L, "8.0/50 kB"),
Arguments.of(16000L, 50000L, "16/50 kB"),
Arguments.of(50000L, 50000L, "50 kB"),
// Megabytes tests
Arguments.of(0L, 5000000L, "0/5.0 MB"),
Arguments.of(500000L, 5000000L, "0.5/5.0 MB"),
Arguments.of(1000000L, 5000000L, "1.0/5.0 MB"),
Arguments.of(5000000L, 5000000L, "5.0 MB"),
Arguments.of(5000000L, 15000000L, "5.0/15 MB"),
Arguments.of(15000000L, 15000000L, "15 MB"),
// Gigabytes tests
Arguments.of(0L, 500000000L, "0/500 MB"),
Arguments.of(1000000000L, 5000000000L, "1.0/5.0 GB"),
Arguments.of(5000000000L, 5000000000L, "5.0 GB"),
Arguments.of(5000000000L, 15000000000L, "5.0/15 GB"),
Arguments.of(15000000000L, 15000000000L, "15 GB"));
}
@ParameterizedTest
@MethodSource("progressedSizeWithSizeTestData")
void testProgressedSizeWithSize(long progressedSize, long totalSize, String expected) {
FileSizeFormat format = new FileSizeFormat();
assertEquals(expected, format.formatProgress(progressedSize, totalSize));
}
@Test
void testFormatRate() {
FileSizeFormat format = new FileSizeFormat();
// Test bytes per second
MessageBuilder builder = new DefaultMessageBuilder();
format.formatRate(builder, 5.0);
assertEquals("5.0 B/s", builder.build());
// Test kilobytes per second
builder = new DefaultMessageBuilder();
format.formatRate(builder, 5500.0);
assertEquals("5.5 kB/s", builder.build());
// Test megabytes per second
builder = new DefaultMessageBuilder();
format.formatRate(builder, 5500000.0);
assertEquals("5.5 MB/s", builder.build());
// Test gigabytes per second
builder = new DefaultMessageBuilder();
format.formatRate(builder, 5500000000.0);
assertEquals("5.5 GB/s", builder.build());
}
@Test
void testFormatRateThresholds() {
FileSizeFormat format = new FileSizeFormat();
// Test value less than 0.05
// Test exact unit thresholds
MessageBuilder builder = new DefaultMessageBuilder();
format.formatRate(builder, 45.0); // 45 B/s
assertEquals("45.0 B/s", builder.build());
// Test value greater than or equal to 10
builder = new DefaultMessageBuilder();
format.formatRate(builder, 15000.0); // 15 kB/s
assertEquals("15.0 kB/s", builder.build());
// Test value between 0.05 and 10
builder = new DefaultMessageBuilder();
format.formatRate(builder, 5500.0); // 5.5 kB/s
assertEquals("5.5 kB/s", builder.build());
// Test exact unit thresholds
builder = new DefaultMessageBuilder();
format.formatRate(builder, 1000.0); // 1 kB/s
assertEquals("1.0 kB/s", builder.build());
builder = new DefaultMessageBuilder();
format.formatRate(builder, 1000000.0); // 1 MB/s
assertEquals("1.0 MB/s", builder.build());
builder = new DefaultMessageBuilder();
format.formatRate(builder, 1000000000.0); // 1 GB/s
assertEquals("1.0 GB/s", builder.build());
}
@Test
void testFormatRateEdgeCases() {
FileSizeFormat format = new FileSizeFormat();
// Test zero rate
MessageBuilder builder = new DefaultMessageBuilder();
format.formatRate(builder, 0.0);
assertEquals("0.0 B/s", builder.build());
// Test rate at exactly 1000 (1 kB/s)
builder = new DefaultMessageBuilder();
format.formatRate(builder, 1000.0);
assertEquals("1.0 kB/s", builder.build());
// Test rate at exactly 1000000 (1 MB/s)
builder = new DefaultMessageBuilder();
format.formatRate(builder, 1000000.0);
assertEquals("1.0 MB/s", builder.build());
}
@Test
void testFormatRateLargeValues() {
FileSizeFormat format = new FileSizeFormat();
// Test large but valid rates
MessageBuilder builder = new DefaultMessageBuilder();
format.formatRate(builder, 5e12); // 5 TB/s
assertEquals("5000.0 GB/s", builder.build());
// Test very large rate
builder = new DefaultMessageBuilder();
format.formatRate(builder, 1e15); // 1 PB/s
assertEquals("1000000.0 GB/s", builder.build());
}
@Test
void testFormatRateInvalidValues() {
FileSizeFormat format = new FileSizeFormat();
// Test negative rate
MessageBuilder builder = new DefaultMessageBuilder();
format.formatRate(builder, -1.0);
assertEquals("? B/s", builder.build());
// Test NaN
builder = new DefaultMessageBuilder();
format.formatRate(builder, Double.NaN);
assertEquals("? B/s", builder.build());
// Test Infinity
builder = new DefaultMessageBuilder();
format.formatRate(builder, Double.POSITIVE_INFINITY);
assertEquals("? B/s", builder.build());
builder = new DefaultMessageBuilder();
format.formatRate(builder, Double.NEGATIVE_INFINITY);
assertEquals("? B/s", builder.build());
}
}