JsonBuilderFactoryTest.java
package redis.clients.jedis.json;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.util.Arrays;
import java.util.List;
import org.junit.jupiter.api.Test;
/**
* Unit tests for JsonBuilderFactory, specifically for the JSON_NUMBER_LIST builder that preserves
* numeric types (Long for integers, Double for decimals).
*/
public class JsonBuilderFactoryTest {
@Test
public void jsonNumberListPreservesLongTypes() {
// Simulates RESP3 response where Redis returns Long for integers
List<Object> input = Arrays.asList(1L, 2L, 3L, 100L);
List<Number> result = JsonBuilderFactory.JSON_NUMBER_LIST.build(input);
assertEquals(4, result.size());
for (Number n : result) {
assertTrue(n instanceof Long, "Expected Long but got " + n.getClass().getName());
}
assertEquals(1L, result.get(0));
assertEquals(2L, result.get(1));
assertEquals(3L, result.get(2));
assertEquals(100L, result.get(3));
}
@Test
public void jsonNumberListPreservesDoubleTypes() {
// Simulates RESP3 response where Redis returns Double for decimals
List<Object> input = Arrays.asList(1.5, 2.5, 3.14159, 100.0);
List<Number> result = JsonBuilderFactory.JSON_NUMBER_LIST.build(input);
assertEquals(4, result.size());
for (Number n : result) {
assertTrue(n instanceof Double, "Expected Double but got " + n.getClass().getName());
}
assertEquals(1.5, result.get(0));
assertEquals(2.5, result.get(1));
assertEquals(3.14159, result.get(2));
assertEquals(100.0, result.get(3));
}
@Test
public void jsonNumberListPreservesMixedTypes() {
// Simulates RESP3 response with mixed Long and Double values
List<Object> input = Arrays.asList(1L, 2.5, 3L, 4.0);
List<Number> result = JsonBuilderFactory.JSON_NUMBER_LIST.build(input);
assertEquals(4, result.size());
assertTrue(result.get(0) instanceof Long, "First element should be Long");
assertTrue(result.get(1) instanceof Double, "Second element should be Double");
assertTrue(result.get(2) instanceof Long, "Third element should be Long");
assertTrue(result.get(3) instanceof Double, "Fourth element should be Double");
assertEquals(1L, result.get(0));
assertEquals(2.5, result.get(1));
assertEquals(3L, result.get(2));
assertEquals(4.0, result.get(3));
}
@Test
public void jsonNumberListHandlesNullElements() {
// Simulates response with null values (for non-numeric JSON paths)
List<Object> input = Arrays.asList(null, 1L, null, 2.5);
List<Number> result = JsonBuilderFactory.JSON_NUMBER_LIST.build(input);
assertEquals(4, result.size());
assertNull(result.get(0));
assertEquals(1L, result.get(1));
assertNull(result.get(2));
assertEquals(2.5, result.get(3));
}
@Test
public void jsonNumberListHandlesNullInput() {
List<Number> result = JsonBuilderFactory.JSON_NUMBER_LIST.build(null);
assertNull(result);
}
@Test
public void jsonNumberListParsesStringIntegers() {
// Simulates RESP2 response where numbers come as byte arrays/strings
List<Object> input = Arrays.asList("1".getBytes(), "2".getBytes(), "100".getBytes());
List<Number> result = JsonBuilderFactory.JSON_NUMBER_LIST.build(input);
assertEquals(3, result.size());
for (Number n : result) {
assertTrue(n instanceof Long, "Parsed integer string should be Long");
}
assertEquals(1L, result.get(0));
assertEquals(2L, result.get(1));
assertEquals(100L, result.get(2));
}
@Test
public void jsonNumberListParsesStringDecimals() {
// Simulates RESP2 response where decimal numbers come as byte arrays/strings
List<Object> input = Arrays.asList("1.5".getBytes(), "2.5".getBytes(), "3.14159".getBytes());
List<Number> result = JsonBuilderFactory.JSON_NUMBER_LIST.build(input);
assertEquals(3, result.size());
for (Number n : result) {
assertTrue(n instanceof Double, "Parsed decimal string should be Double");
}
assertEquals(1.5, result.get(0));
assertEquals(2.5, result.get(1));
assertEquals(3.14159, result.get(2));
}
@Test
public void jsonNumberListParsesScientificNotation() {
// Test parsing of scientific notation numbers
List<Object> input = Arrays.asList("1e10".getBytes(), "2.5E-3".getBytes());
List<Number> result = JsonBuilderFactory.JSON_NUMBER_LIST.build(input);
assertEquals(2, result.size());
assertTrue(result.get(0) instanceof Double, "Scientific notation should be Double");
assertTrue(result.get(1) instanceof Double, "Scientific notation should be Double");
assertEquals(1e10, result.get(0));
assertEquals(2.5e-3, result.get(1));
}
@Test
public void jsonArrayOrDoubleListReturnsNumberListForListInput() {
// Test that JSON_ARRAY_OR_DOUBLE_LIST uses JSON_NUMBER_LIST for List input
List<Object> input = Arrays.asList(1L, 2.5, 3L);
Object result = JsonBuilderFactory.JSON_ARRAY_OR_NUMBER_LIST.build(input);
assertTrue(result instanceof List, "Result should be a List");
@SuppressWarnings("unchecked")
List<Number> numberList = (List<Number>) result;
assertEquals(3, numberList.size());
assertTrue(numberList.get(0) instanceof Long, "First element should be Long");
assertTrue(numberList.get(1) instanceof Double, "Second element should be Double");
assertTrue(numberList.get(2) instanceof Long, "Third element should be Long");
}
}