• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.fasterxml.jackson.databind.node;
2 
3 import java.util.Comparator;
4 
5 import com.fasterxml.jackson.core.*;
6 import com.fasterxml.jackson.core.io.SerializedString;
7 import com.fasterxml.jackson.databind.*;
8 import com.fasterxml.jackson.databind.testutil.NoCheckSubTypeValidator;
9 import com.fasterxml.jackson.databind.util.RawValue;
10 
11 /**
12  * Basic tests for {@link JsonNode} base class and some features
13  * of implementation classes
14  */
15 public class TestJsonNode extends NodeTestBase
16 {
17     private final ObjectMapper MAPPER = objectMapper();
18 
testBoolean()19     public void testBoolean() throws Exception
20     {
21         BooleanNode f = BooleanNode.getFalse();
22         assertNotNull(f);
23         assertTrue(f.isBoolean());
24         assertSame(f, BooleanNode.valueOf(false));
25         assertStandardEquals(f);
26         assertFalse(f.booleanValue());
27         assertFalse(f.asBoolean());
28         assertEquals("false", f.asText());
29         assertEquals(JsonToken.VALUE_FALSE, f.asToken());
30 
31         // and ditto for true
32         BooleanNode t = BooleanNode.getTrue();
33         assertNotNull(t);
34         assertTrue(t.isBoolean());
35         assertSame(t, BooleanNode.valueOf(true));
36         assertStandardEquals(t);
37         assertTrue(t.booleanValue());
38         assertTrue(t.asBoolean());
39         assertEquals("true", t.asText());
40         assertEquals(JsonToken.VALUE_TRUE, t.asToken());
41 
42         assertNodeNumbers(f, 0, 0.0);
43         assertNodeNumbers(t, 1, 1.0);
44 
45         JsonNode result = objectMapper().readTree("true\n");
46         assertFalse(result.isNull());
47         assertFalse(result.isNumber());
48         assertFalse(result.isTextual());
49         assertTrue(result.isBoolean());
50         assertType(result, BooleanNode.class);
51         assertTrue(result.booleanValue());
52         assertEquals("true", result.asText());
53         assertFalse(result.isMissingNode());
54 
55         // also, equality should work ok
56         assertEquals(result, BooleanNode.valueOf(true));
57         assertEquals(result, BooleanNode.getTrue());
58     }
59 
testBinary()60     public void testBinary() throws Exception
61     {
62         assertNull(BinaryNode.valueOf(null));
63         assertNull(BinaryNode.valueOf(null, 0, 0));
64 
65         BinaryNode empty = BinaryNode.valueOf(new byte[1], 0, 0);
66         assertSame(BinaryNode.EMPTY_BINARY_NODE, empty);
67         assertStandardEquals(empty);
68 
69         byte[] data = new byte[3];
70         data[1] = (byte) 3;
71         BinaryNode n = BinaryNode.valueOf(data, 1, 1);
72         data[2] = (byte) 3;
73         BinaryNode n2 = BinaryNode.valueOf(data, 2, 1);
74         assertTrue(n.equals(n2));
75         assertEquals("\"Aw==\"", n.toString());
76 
77         assertEquals("AAMD", new BinaryNode(data).asText());
78         assertNodeNumbersForNonNumeric(n);
79     }
80 
testPOJO()81     public void testPOJO()
82     {
83         POJONode n = new POJONode("x"); // not really a pojo but that's ok
84         assertStandardEquals(n);
85         assertEquals(n, new POJONode("x"));
86         assertEquals("x", n.asText());
87         // 10-Dec-2018, tatu: With 2.10, should serialize same as via ObjectMapper/ObjectWriter
88         assertEquals("\"x\"", n.toString());
89 
90         assertEquals(new POJONode(null), new POJONode(null));
91 
92         // default; non-numeric
93         assertNodeNumbersForNonNumeric(n);
94         // but if wrapping actual number, use it
95         assertNodeNumbers(new POJONode(Integer.valueOf(123)), 123, 123.0);
96     }
97 
98     // [databind#743]
testRawValue()99     public void testRawValue() throws Exception
100     {
101         ObjectNode root = MAPPER.createObjectNode();
102         root.putRawValue("a", new RawValue(new SerializedString("[1, 2, 3]")));
103 
104         assertEquals("{\"a\":[1, 2, 3]}", MAPPER.writeValueAsString(root));
105     }
106 
107     // [databind#790]
testCustomComparators()108     public void testCustomComparators() throws Exception
109     {
110         ObjectNode nestedObject1 = MAPPER.createObjectNode();
111         nestedObject1.put("value", 6);
112         ArrayNode nestedArray1 = MAPPER.createArrayNode();
113         nestedArray1.add(7);
114         ObjectNode root1 = MAPPER.createObjectNode();
115         root1.put("value", 5);
116         root1.set("nested_object", nestedObject1);
117         root1.set("nested_array", nestedArray1);
118 
119         ObjectNode nestedObject2 = MAPPER.createObjectNode();
120         nestedObject2.put("value", 6.9);
121         ArrayNode nestedArray2 = MAPPER.createArrayNode();
122         nestedArray2.add(7.0);
123         ObjectNode root2 = MAPPER.createObjectNode();
124         root2.put("value", 5.0);
125         root2.set("nested_object", nestedObject2);
126         root2.set("nested_array", nestedArray2);
127 
128         // default equals(): not strictly equal
129         assertFalse(root1.equals(root2));
130         assertFalse(root2.equals(root1));
131         assertTrue(root1.equals(root1));
132         assertTrue(root2.equals(root2));
133 
134         assertTrue(nestedArray1.equals(nestedArray1));
135         assertFalse(nestedArray1.equals(nestedArray2));
136         assertFalse(nestedArray2.equals(nestedArray1));
137 
138         // but. Custom comparator can make all the difference
139         Comparator<JsonNode> cmp = new Comparator<JsonNode>() {
140 
141             @Override
142             public int compare(JsonNode o1, JsonNode o2) {
143                 if (o1 instanceof ContainerNode || o2 instanceof ContainerNode) {
144                     fail("container nodes should be traversed, comparator should not be invoked");
145                 }
146                 if (o1.equals(o2)) {
147                     return 0;
148                 }
149                 if ((o1 instanceof NumericNode) && (o2 instanceof NumericNode)) {
150                     int d1 = ((NumericNode) o1).asInt();
151                     int d2 = ((NumericNode) o2).asInt();
152                     if (d1 == d2) { // strictly equals because it's integral value
153                         return 0;
154                     }
155                     if (d1 < d2) {
156                         return -1;
157                     }
158                     return 1;
159                 }
160                 return 0;
161             }
162         };
163         assertTrue(root1.equals(cmp, root2));
164         assertTrue(root2.equals(cmp, root1));
165         assertTrue(root1.equals(cmp, root1));
166         assertTrue(root2.equals(cmp, root2));
167 
168         ArrayNode array3 = MAPPER.createArrayNode();
169         array3.add(123);
170 
171         assertFalse(root2.equals(cmp, nestedArray1));
172         assertTrue(nestedArray1.equals(cmp, nestedArray1));
173         assertFalse(nestedArray1.equals(cmp, root2));
174         assertFalse(nestedArray1.equals(cmp, array3));
175     }
176 
177     // [databind#793]
testArrayWithDefaultTyping()178     public void testArrayWithDefaultTyping() throws Exception
179     {
180         ObjectMapper mapper = new ObjectMapper()
181             .activateDefaultTyping(NoCheckSubTypeValidator.instance);
182 
183         JsonNode array = mapper.readTree("[ 1, 2 ]");
184         assertTrue(array.isArray());
185         assertEquals(2, array.size());
186 
187         JsonNode obj = mapper.readTree("{ \"a\" : 2 }");
188         assertTrue(obj.isObject());
189         assertEquals(1, obj.size());
190         assertEquals(2, obj.path("a").asInt());
191     }
192 }
193