Skip to content

Commit c8d2da3

Browse files
committed
test(compression): Improve test coverage for LZW and ArithmeticCoding
1 parent 8555eb6 commit c8d2da3

File tree

3 files changed

+67
-4
lines changed

3 files changed

+67
-4
lines changed

src/main/java/com/thealgorithms/compression/ArithmeticCoding.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,5 @@ public static Map<Character, Symbol> calculateProbabilities(String text) {
153153
* Helper class to store the probability range [low, high) for a symbol.
154154
*/
155155
public record Symbol(BigDecimal low, BigDecimal high) {
156-
157156
}
158157
}

src/test/java/com/thealgorithms/compression/ArithmeticCodingTest.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
import static org.junit.jupiter.api.Assertions.assertTrue;
77

88
import java.math.BigDecimal;
9+
import java.util.HashMap;
910
import java.util.Map;
10-
1111
import org.junit.jupiter.api.Test;
1212

1313
class ArithmeticCodingTest {
@@ -116,4 +116,39 @@ void testProbabilityTableCalculation() {
116116
assertTrue(symbol.low().compareTo(symbol.high()) < 0);
117117
}
118118
}
119+
120+
@Test
121+
void testDecompressionWithMismatchedProbabilityTable() {
122+
// Test decompression with a probability table that doesn't match the original
123+
String original = "ABCD";
124+
BigDecimal compressed = ArithmeticCoding.compress(original);
125+
126+
// Create a different probability table (for "XYZ" instead of "ABCD")
127+
Map<Character, ArithmeticCoding.Symbol> wrongProbTable = ArithmeticCoding.calculateProbabilities("XYZ");
128+
129+
// Decompression with wrong probability table should produce incorrect output
130+
String decompressed = ArithmeticCoding.decompress(compressed, original.length(), wrongProbTable);
131+
132+
// The decompressed string will be different from original (likely all 'X', 'Y', or 'Z')
133+
// This tests the edge case where the compressed value doesn't fall into expected ranges
134+
assertNotNull(decompressed);
135+
assertEquals(original.length(), decompressed.length());
136+
}
137+
138+
@Test
139+
void testDecompressionWithValueOutsideSymbolRanges() {
140+
// Create a custom probability table
141+
Map<Character, ArithmeticCoding.Symbol> probTable = new HashMap<>();
142+
probTable.put('A', new ArithmeticCoding.Symbol(new BigDecimal("0.0"), new BigDecimal("0.5")));
143+
probTable.put('B', new ArithmeticCoding.Symbol(new BigDecimal("0.5"), new BigDecimal("1.0")));
144+
145+
// Use a compressed value that should decode properly
146+
BigDecimal compressed = new BigDecimal("0.25"); // Falls in 'A' range
147+
148+
String decompressed = ArithmeticCoding.decompress(compressed, 3, probTable);
149+
150+
// Verify decompression completes (even if result might not be meaningful)
151+
assertNotNull(decompressed);
152+
assertEquals(3, decompressed.length());
153+
}
119154
}

src/test/java/com/thealgorithms/compression/LZWTest.java

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package com.thealgorithms.compression;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
45
import static org.junit.jupiter.api.Assertions.assertTrue;
56

7+
import java.util.ArrayList;
68
import java.util.Collections;
79
import java.util.List;
8-
910
import org.junit.jupiter.api.Test;
1011

1112
class LZWTest {
@@ -75,4 +76,32 @@ void testSymmetry() {
7576
String decompressed2 = LZW.decompress(compressed2);
7677
assertEquals(original2, decompressed2);
7778
}
78-
}
79+
80+
@Test
81+
void testInvalidCompressedData() {
82+
// Test that decompressing with an invalid code throws IllegalArgumentException
83+
// Create a list with a code that doesn't exist in the dictionary
84+
List<Integer> invalidCompressed = new ArrayList<>();
85+
invalidCompressed.add(65); // 'A' - valid
86+
invalidCompressed.add(999); // Invalid code (not in dictionary)
87+
88+
// This should throw IllegalArgumentException with message "Bad compressed k: 999"
89+
IllegalArgumentException exception = assertThrows(
90+
IllegalArgumentException.class,
91+
() -> LZW.decompress(invalidCompressed)
92+
);
93+
94+
assertTrue(exception.getMessage().contains("Bad compressed k: 999"));
95+
}
96+
97+
@Test
98+
void testDecompressionWithGapInDictionary() {
99+
// Test with codes that skip dictionary entries
100+
List<Integer> invalidCompressed = new ArrayList<>();
101+
invalidCompressed.add(84); // 'T' - valid
102+
invalidCompressed.add(500); // Way beyond current dictionary size
103+
104+
// This should throw IllegalArgumentException
105+
assertThrows(IllegalArgumentException.class, () -> LZW.decompress(invalidCompressed));
106+
}
107+
}

0 commit comments

Comments
 (0)