@Test public void when_deep_scanning_illegal_property_access_is_ignored() { Object result = JsonPath.parse("{\"x\": {\"foo\": {\"bar\": 4}}, \"y\": {\"foo\": 1}}").read("$..foo"); assertThat(result).asList().hasSize(2); result = JsonPath.parse("{\"x\": {\"foo\": {\"bar\": 4}}, \"y\": {\"foo\": 1}}").read("$..foo.bar"); assertThat(result).asList().containsOnly(4); result = JsonPath.parse("{\"x\": {\"foo\": {\"bar\": 4}}, \"y\": {\"foo\": 1}}").read("$..[*].foo.bar"); assertThat(result).asList().containsOnly(4); result = JsonPath.parse("{\"x\": {\"foo\": {\"baz\": 4}}, \"y\": {\"foo\": 1}}").read("$..[*].foo.bar"); assertThat(result).asList().isEmpty(); }
@Test public void when_deep_scanning_array_index_oob_is_ignored() { Object result = JsonPath.parse("{\"x\": [0,1,[0,1,2,3,10],null]}").read("$..[4]"); assertThat(result).asList().containsOnly(10); result = JsonPath.parse("{\"x\": [null,null,[0,1,2,3]], \"y\": [null,null,[0,1]]}").read("$..[2][3]"); assertThat(result).asList().containsOnly(3); }
@Test public void when_deep_scanning_illegal_predicate_is_ignored() { Object result = JsonPath.parse("{\"x\": {\"foo\": {\"bar\": 4}}, \"y\": {\"foo\": 1}}").read( "$..foo[?(@.bar)].bar"); assertThat(result).asList().containsOnly(4); result = JsonPath.parse("{\"x\": {\"foo\": {\"bar\": 4}}, \"y\": {\"foo\": 1}}").read( "$..[*]foo[?(@.bar)].bar"); assertThat(result).asList().containsOnly(4); }
@Test public void deep_scan_does_not_affect_non_leaf_multi_props() { // deep scan + multiprop is quite redundant scenario, but it's not forbidden, so we'd better check final String json = "{\"v\": [[{}, 1, {\"a\": {\"v\": 5}, \"b\": {\"v\": 4}, \"c\": {\"v\": 1, \"flag\": true}}]]}"; Object result = JsonPath.parse(json).read("$..['a', 'c'].v"); assertThat(result).asList().containsOnly(5, 1); result = JsonPath.parse(json).read("$..['a', 'c'][?(@.flag)].v"); assertThat(result).asList().containsOnly(1); }
@Test public void when_deep_scanning_null_subscription_is_ignored() { Object result = JsonPath.parse("{\"x\": [null,null,[0,1,2,3,null],null]}").read("$..[2][3]"); assertThat(result).asList().containsOnly(3); result = JsonPath.parse("{\"x\": [null,null,[0,1,2,3,null],null], \"y\": [0,1,null]}").read("$..[2][3]"); assertThat(result).asList().containsOnly(3); }
@Test public void when_deep_scanning_non_array_subscription_is_ignored() { Object result = JsonPath.parse("{\"x\": [0,1,[0,1,2,3,null],null]}").read("$..[2][3]"); assertThat(result).asList().containsOnly(3); result = JsonPath.parse("{\"x\": [0,1,[0,1,2,3,null],null], \"y\": [0,1,2]}").read("$..[2][3]"); assertThat(result).asList().containsOnly(3); result = JsonPath.parse("{\"x\": [0,1,[0,1,2],null], \"y\": [0,1,2]}").read("$..[2][3]"); assertThat(result).asList().isEmpty(); }
@Test public void multi_props_can_be_in_the_middle() { final String json = "{\"x\": [null, {\"a\": {\"v\": 5}, \"b\": {\"v\": 4}, \"c\": {\"v\": 1}}]}"; Object result = JsonPath.parse(json).read("$.x[1]['a', 'c'].v"); assertThat(result).asList().containsOnly(5, 1); result = JsonPath.parse(json).read("$.x[*]['a', 'c'].v"); assertThat(result).asList().containsOnly(5, 1); result = JsonPath.parse(json).read("$[*][*]['a', 'c'].v"); assertThat(result).asList().containsOnly(5, 1); result = JsonPath.parse(json).read("$.x[1]['d', 'a', 'c', 'm'].v"); assertThat(result).asList().containsOnly(5, 1); result = JsonPath.parse(json).read("$.x[*]['d', 'a', 'c', 'm'].v"); assertThat(result).asList().containsOnly(5, 1); }
@Test public void nonexistent_non_leaf_multi_props_ignored() { Object result = JsonPath.parse("{\"a\": {\"v\": 5}, \"b\": {\"v\": 4}, \"c\": {\"v\": 1}}").read( "$['d', 'a', 'c', 'm'].v"); assertThat(result).asList().containsOnly(5, 1); }
@Test public void multi_props_with_post_filter() { Object result = JsonPath.parse("{\"a\": {\"v\": 5}, \"b\": {\"v\": 4}, \"c\": {\"v\": 1, \"flag\": true}}").read( "$['a', 'c'][?(@.flag)].v"); assertThat(result).asList().containsOnly(1); }
@Test public void multi_props_can_be_non_leafs() { Object result = JsonPath.parse("{\"a\": {\"v\": 5}, \"b\": {\"v\": 4}, \"c\": {\"v\": 1}}").read( "$['a', 'c'].v"); assertThat(result).asList().containsOnly(5, 1); }
@Test public void require_single_property() { List json = new ArrayList() {{ add(singletonMap("a", "a0")); add(singletonMap("b", "b2")); }}; Configuration configuration = JSON_SMART_CONFIGURATION.addOptions(Option.REQUIRE_PROPERTIES); Object result = JsonPath.using(configuration).parse(json).read("$..a"); assertThat(result).asList().containsExactly("a0"); }
@Test public void require_single_property_ok() { List json = new ArrayList() {{ add(singletonMap("a", "a0")); add(singletonMap("a", "a1")); }}; Configuration configuration = JSON_SMART_CONFIGURATION.addOptions(Option.REQUIRE_PROPERTIES); Object result = JsonPath.using(configuration).parse(json).read("$..a"); assertThat(result).asList().containsExactly("a0","a1"); }
@Test public void when_deep_scanning_leaf_multi_props_work() { Object result = JsonPath.parse("[{\"a\": \"a-val\", \"b\": \"b-val\", \"c\": \"c-val\"}, [1, 5], {\"a\": \"a-val\"}]").read( "$..['a', 'c']"); // This is current deep scan semantics: only objects containing all properties specified in multiprops token are // considered. assertThat(result).asList().hasSize(1); result = ((List)result).get(0); assertThat(result).isInstanceOf(Map.class); assertThat((Map)result).hasSize(2).containsEntry("a", "a-val").containsEntry("c", "c-val"); // But this semantics changes when DEFAULT_PATH_LEAF_TO_NULL comes into play. Configuration conf = Configuration.defaultConfiguration().addOptions(Option.DEFAULT_PATH_LEAF_TO_NULL); result = using(conf).parse("[{\"a\": \"a-val\", \"b\": \"b-val\", \"c\": \"c-val\"}, [1, 5], {\"a\": \"a-val\"}]").read( "$..['a', 'c']"); // todo: deep equality test, but not tied to any json provider assertThat(result).asList().hasSize(2); for (final Object node : (List)result) { assertThat(node).isInstanceOf(Map.class); assertThat((Map)node).hasSize(2).containsEntry("a", "a-val"); } }
@Test public void when_deep_scanning_require_properties_is_ignored_on_scan_target() { final Configuration conf = Configuration.defaultConfiguration().addOptions(Option.REQUIRE_PROPERTIES); Object result = JsonPath.parse("[{\"x\": {\"foo\": {\"x\": 4}, \"x\": null}, \"y\": {\"x\": 1}}, {\"x\": []}]").read( "$..x"); assertThat(result).asList().hasSize(5); List<Integer> result1 = JsonPath.using(conf).parse("{\"foo\": {\"bar\": 4}}").read("$..foo.bar"); assertThat(result1).containsExactly(4); assertEvaluationThrows("{\"foo\": {\"baz\": 4}}", "$..foo.bar", PathNotFoundException.class, conf); }
@SafeVarargs private final void assertRenderingCommands(final List<RendererCommand> actualCommands, final Class<? extends RendererCommand>... expectedTypes) { assertThat(actualCommands).asList().hasOnlyElementsOfTypes(expectedTypes); Arrays.asList(expectedTypes).forEach(type -> assertThat(actualCommands).asList().filteredOn(type::isInstance).hasSize(1)); } }
@SafeVarargs private final void assertRenderingCommands(final List<RendererCommand> actualCommands, final Class<? extends RendererCommand>... expectedTypes) { assertThat(actualCommands).asList().hasOnlyElementsOfTypes(expectedTypes); Arrays.asList(expectedTypes).forEach(type -> assertThat(actualCommands).asList().filteredOn(type::isInstance).hasSize(1)); }
@SafeVarargs private final void assertRenderingCommands(final List<RendererCommand> actualCommands, final Class<? extends RendererCommand>... expectedTypes) { assertThat(actualCommands).asList().hasOnlyElementsOfTypes(expectedTypes); Arrays.asList(expectedTypes).forEach(type -> assertThat(actualCommands).asList().filteredOn(type::isInstance).hasSize(1)); } }
@SafeVarargs private final void assertRenderingCommands(final List<RendererCommand> actualCommands, final Class<? extends RendererCommand>... expectedTypes) { assertThat(actualCommands).asList().hasOnlyElementsOfTypes(expectedTypes); Arrays.asList(expectedTypes).forEach(type -> assertThat(actualCommands).asList().filteredOn(type::isInstance).hasSize(1)); }
@SafeVarargs private final void assertRenderingCommands(final List<GridRenderer.RendererCommand> actualCommands, final Class<? extends GridRenderer.RendererCommand>... expectedTypes) { assertThat(actualCommands).asList().hasOnlyElementsOfTypes(expectedTypes); Arrays.asList(expectedTypes).forEach(type -> assertThat(actualCommands).asList().filteredOn(type::isInstance).hasSize(1)); } }
@Test public void checkRenderHeaderWhenColumnsHaveNoMetaData() { column.getHeaderMetaData().clear(); final BaseGridRendererHelper.RenderingInformation ri = makeRenderingInformation(model); final GridHeaderRenderContext context = mock(GridHeaderRenderContext.class); final List<GridRenderer.RendererCommand> commands = renderer.renderHeader(model, context, rendererHelper, ri); assertThat(commands).isNotNull(); assertThat(commands).asList().hasSize(0); }