JsonPointerTest.java
package com.fasterxml.jackson.core.jsonptr;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.core.JUnit5TestBase;
import com.fasterxml.jackson.core.JsonPointer;
import static org.junit.jupiter.api.Assertions.*;
class JsonPointerTest extends JUnit5TestBase
{
private final JsonPointer EMPTY_PTR = JsonPointer.empty();
@Test
void simplePath() throws Exception
{
final String INPUT = "/Image/15/name";
JsonPointer ptr = JsonPointer.compile(INPUT);
assertFalse(ptr.matches());
assertEquals(-1, ptr.getMatchingIndex());
assertEquals("Image", ptr.getMatchingProperty());
assertEquals("/Image/15", ptr.head().toString());
assertEquals(INPUT, ptr.toString());
ptr = ptr.tail();
assertNotNull(ptr);
assertFalse(ptr.matches());
assertEquals(15, ptr.getMatchingIndex());
assertEquals("15", ptr.getMatchingProperty());
assertEquals("/15/name", ptr.toString());
assertEquals("/15", ptr.head().toString());
assertEquals("", ptr.head().head().toString());
assertNull(ptr.head().head().head());
ptr = ptr.tail();
assertNotNull(ptr);
assertFalse(ptr.matches());
assertEquals(-1, ptr.getMatchingIndex());
assertEquals("name", ptr.getMatchingProperty());
assertEquals("/name", ptr.toString());
assertEquals("", ptr.head().toString());
assertSame(EMPTY_PTR, ptr.head());
// done!
ptr = ptr.tail();
assertTrue(ptr.matches());
assertNull(ptr.tail());
assertNull(ptr.head());
assertNull(ptr.getMatchingProperty());
assertEquals(-1, ptr.getMatchingIndex());
}
@Test
void simplePathLonger() throws Exception
{
final String INPUT = "/a/b/c/d/e/f/0";
JsonPointer ptr = JsonPointer.compile(INPUT);
assertFalse(ptr.matches());
assertEquals(-1, ptr.getMatchingIndex());
assertEquals("a", ptr.getMatchingProperty());
assertEquals("/a/b/c/d/e/f", ptr.head().toString());
assertEquals("/b/c/d/e/f/0", ptr.tail().toString());
assertEquals("/0", ptr.last().toString());
assertEquals(INPUT, ptr.toString());
}
@Test
void simpleTail() throws Exception
{
final String INPUT = "/root/leaf";
JsonPointer ptr = JsonPointer.compile(INPUT);
assertEquals("/leaf", ptr.tail().toString());
assertEquals("", ptr.tail().tail().toString());
}
@Test
void wonkyNumber173() throws Exception
{
JsonPointer ptr = JsonPointer.compile("/1e0");
assertFalse(ptr.matches());
}
// [core#176]: do not allow leading zeroes
@Test
void iZeroIndex() throws Exception
{
JsonPointer ptr = JsonPointer.compile("/0");
assertEquals(0, ptr.getMatchingIndex());
ptr = JsonPointer.compile("/00");
assertEquals(-1, ptr.getMatchingIndex());
}
@Test
void last()
{
String INPUT = "/Image/name";
JsonPointer ptr = JsonPointer.compile(INPUT);
JsonPointer leaf = ptr.last();
assertEquals("/name", leaf.toString());
assertEquals("name", leaf.getMatchingProperty());
INPUT = "/Image/15/name";
ptr = JsonPointer.compile(INPUT);
leaf = ptr.last();
assertEquals("/name", leaf.toString());
assertEquals("name", leaf.getMatchingProperty());
}
@Test
void emptyPointer()
{
assertSame(EMPTY_PTR, JsonPointer.compile(""));
assertEquals("", EMPTY_PTR.toString());
// As per [core#788], should NOT match Property with "empty String"
assertFalse(EMPTY_PTR.mayMatchProperty());
assertFalse(EMPTY_PTR.mayMatchElement());
assertEquals(-1, EMPTY_PTR.getMatchingIndex());
assertNull(EMPTY_PTR.getMatchingProperty());
}
@Test
void pointerWithEmptyPropertyName()
{
// note: this is acceptable, to match property in '{"":3}', for example
// and NOT same as what empty point, "", is.
JsonPointer ptr = JsonPointer.compile("/");
assertNotNull(ptr);
assertNotSame(EMPTY_PTR, ptr);
assertEquals("/", ptr.toString());
assertTrue(ptr.mayMatchProperty());
assertFalse(ptr.mayMatchElement());
assertEquals(-1, ptr.getMatchingIndex());
assertEquals("", ptr.getMatchingProperty());
assertTrue(ptr.matchesProperty(""));
assertFalse(ptr.matchesElement(0));
assertFalse(ptr.matchesElement(-1));
assertFalse(ptr.matchesProperty("1"));
}
// mostly for test coverage, really...
@Test
void equality() {
assertNotEquals(JsonPointer.empty(), JsonPointer.compile("/"));
assertEquals(JsonPointer.compile("/foo/3"), JsonPointer.compile("/foo/3"));
assertNotEquals(JsonPointer.empty(), JsonPointer.compile("/12"));
assertNotEquals(JsonPointer.compile("/12"), JsonPointer.empty());
assertEquals(JsonPointer.compile("/a/b/c").tail(),
JsonPointer.compile("/foo/b/c").tail());
JsonPointer abcDef = JsonPointer.compile("/abc/def");
JsonPointer def = JsonPointer.compile("/def");
assertEquals(abcDef.tail(), def);
assertEquals(def, abcDef.tail());
// expr != String
assertNotEquals("/", JsonPointer.empty());
}
@Test
void properties() {
assertTrue(JsonPointer.compile("/foo").mayMatchProperty());
assertFalse(JsonPointer.compile("/foo").mayMatchElement());
assertTrue(JsonPointer.compile("/12").mayMatchElement());
// Interestingly enough, since Json Pointer is just String, could
// ALSO match property with name "12"
assertTrue(JsonPointer.compile("/12").mayMatchProperty());
}
@Test
void append()
{
final String INPUT = "/Image/15/name";
final String APPEND = "/extension";
JsonPointer ptr = JsonPointer.compile(INPUT);
JsonPointer apd = JsonPointer.compile(APPEND);
JsonPointer appended = ptr.append(apd);
assertEquals("extension", appended.last().getMatchingProperty());
assertEquals("/Image/15/name/extension", appended.toString());
}
@Test
void appendWithFinalSlash()
{
final String INPUT = "/Image/15/name/";
final String APPEND = "/extension";
JsonPointer ptr = JsonPointer.compile(INPUT);
// 14-Dec-2023, tatu: Not sure WTH was slash being removed for...
assertEquals("/Image/15/name/", ptr.toString());
JsonPointer apd = JsonPointer.compile(APPEND);
JsonPointer appended = ptr.append(apd);
assertEquals("extension", appended.last().getMatchingProperty());
assertEquals("/Image/15/name//extension", appended.toString());
}
@Test
void appendProperty()
{
final String INPUT = "/Image/15/name";
final String APPEND_NO_SLASH = "extension";
final String APPEND_WITH_SLASH = "/extension~";
JsonPointer ptr = JsonPointer.compile(INPUT);
JsonPointer appendedNoSlash = ptr.appendProperty(APPEND_NO_SLASH);
JsonPointer appendedWithSlash = ptr.appendProperty(APPEND_WITH_SLASH);
assertEquals(APPEND_NO_SLASH, appendedNoSlash.last().getMatchingProperty());
assertEquals("/Image/15/name/extension", appendedNoSlash.toString());
assertEquals(APPEND_WITH_SLASH, appendedWithSlash.last().getMatchingProperty());
assertEquals("/Image/15/name/~1extension~0", appendedWithSlash.toString());
}
// [core#1145]: Escape property
@Test
void appendPropertyEmpty()
{
final String BASE = "/Image/72/src";
JsonPointer basePtr = JsonPointer.compile(BASE);
// Same as before 2.17
assertSame(basePtr, basePtr.appendProperty(null));
// but this is different:
JsonPointer sub = basePtr.appendProperty("");
assertNotSame(basePtr, sub);
assertEquals(BASE+"/", sub.toString());
}
@Test
void appendIndex()
{
final String INPUT = "/Image/15/name";
final int INDEX = 12;
JsonPointer ptr = JsonPointer.compile(INPUT);
JsonPointer appended = ptr.appendIndex(INDEX);
assertEquals(12, appended.last().getMatchingIndex());
}
@Test
void quotedPath() throws Exception
{
final String INPUT = "/w~1out/til~0de/~1ab";
JsonPointer ptr = JsonPointer.compile(INPUT);
assertFalse(ptr.matches());
assertEquals(-1, ptr.getMatchingIndex());
assertEquals("w/out", ptr.getMatchingProperty());
assertEquals("/w~1out/til~0de", ptr.head().toString());
assertEquals(INPUT, ptr.toString());
ptr = ptr.tail();
assertNotNull(ptr);
assertFalse(ptr.matches());
assertEquals(-1, ptr.getMatchingIndex());
assertEquals("til~de", ptr.getMatchingProperty());
assertEquals("/til~0de", ptr.head().toString());
assertEquals("/til~0de/~1ab", ptr.toString());
ptr = ptr.tail();
assertNotNull(ptr);
assertFalse(ptr.matches());
assertEquals(-1, ptr.getMatchingIndex());
assertEquals("/ab", ptr.getMatchingProperty());
assertEquals("/~1ab", ptr.toString());
assertEquals("", ptr.head().toString());
// done!
ptr = ptr.tail();
assertTrue(ptr.matches());
assertNull(ptr.tail());
}
// [core#133]
@Test
void longNumbers() throws Exception
{
final long LONG_ID = (Integer.MAX_VALUE) + 1L;
final String INPUT = "/User/"+LONG_ID;
JsonPointer ptr = JsonPointer.compile(INPUT);
assertEquals("User", ptr.getMatchingProperty());
assertEquals(INPUT, ptr.toString());
ptr = ptr.tail();
assertNotNull(ptr);
assertFalse(ptr.matches());
/* 14-Mar-2014, tatu: We do not support array indexes beyond 32-bit
* range; can still match textually of course.
*/
assertEquals(-1, ptr.getMatchingIndex());
assertEquals(String.valueOf(LONG_ID), ptr.getMatchingProperty());
// done!
ptr = ptr.tail();
assertTrue(ptr.matches());
assertNull(ptr.tail());
}
}