UNPKG

jsonpath-faster

Version:

Query JavaScript objects with JSONPath expressions. Compiles and caches JSONpath to JS

774 lines (773 loc) 21.2 kB
// automatically translated from node_modules/jsonpath/test/query.js const tap = require("tap"); var assert = require("assert"); var jp = require("../../").strict; var data = require("./data/store.json"); tap.test("query", async function () { tap.test("first-level member", async function () { var results = jp.nodes(data, "$.store"); tap.same(results, [ { path: ["$", "store"], value: data.store, }, ]); }); tap.test("authors of all books in the store", async function () { var results = jp.nodes(data, "$.store.book[*].author"); tap.same(results, [ { path: ["$", "store", "book", 0, "author"], value: "Nigel Rees", }, { path: ["$", "store", "book", 1, "author"], value: "Evelyn Waugh", }, { path: ["$", "store", "book", 2, "author"], value: "Herman Melville", }, { path: ["$", "store", "book", 3, "author"], value: "J. R. R. Tolkien", }, ]); }); tap.test("all authors", async function () { var results = jp.nodes(data, "$..author"); tap.same(results, [ { path: ["$", "store", "book", 0, "author"], value: "Nigel Rees", }, { path: ["$", "store", "book", 1, "author"], value: "Evelyn Waugh", }, { path: ["$", "store", "book", 2, "author"], value: "Herman Melville", }, { path: ["$", "store", "book", 3, "author"], value: "J. R. R. Tolkien", }, ]); }); tap.test( "all authors via subscript descendant string literal", async function () { var results = jp.nodes(data, "$..['author']"); tap.same(results, [ { path: ["$", "store", "book", 0, "author"], value: "Nigel Rees", }, { path: ["$", "store", "book", 1, "author"], value: "Evelyn Waugh", }, { path: ["$", "store", "book", 2, "author"], value: "Herman Melville", }, { path: ["$", "store", "book", 3, "author"], value: "J. R. R. Tolkien", }, ]); } ); tap.test("all things in store", async function () { var results = jp.nodes(data, "$.store.*"); tap.same(results, [ { path: ["$", "store", "book"], value: data.store.book, }, { path: ["$", "store", "bicycle"], value: data.store.bicycle, }, ]); }); tap.test("price of everything in the store", async function () { var results = jp.nodes(data, "$.store..price"); tap.same(results, [ { path: ["$", "store", "book", 0, "price"], value: 8.95, }, { path: ["$", "store", "book", 1, "price"], value: 12.99, }, { path: ["$", "store", "book", 2, "price"], value: 8.99, }, { path: ["$", "store", "book", 3, "price"], value: 22.99, }, { path: ["$", "store", "bicycle", "price"], value: 19.95, }, ]); }); tap.test("last book in order via expression", async function () { var results = jp.nodes(data, "$..book[(@.length-1)]"); tap.same(results, [ { path: ["$", "store", "book", 3], value: data.store.book[3], }, ]); }); tap.test("first two books via union", async function () { var results = jp.nodes(data, "$..book[0,1]"); tap.same(results, [ { path: ["$", "store", "book", 0], value: data.store.book[0], }, { path: ["$", "store", "book", 1], value: data.store.book[1], }, ]); }); tap.test("first two books via slice", async function () { var results = jp.nodes(data, "$..book[0:2]"); tap.same(results, [ { path: ["$", "store", "book", 0], value: data.store.book[0], }, { path: ["$", "store", "book", 1], value: data.store.book[1], }, ]); }); tap.test("filter all books with isbn number", async function () { var results = jp.nodes(data, "$..book[?(@.isbn)]"); tap.same(results, [ { path: ["$", "store", "book", 2], value: data.store.book[2], }, { path: ["$", "store", "book", 3], value: data.store.book[3], }, ]); }); tap.test("filter all books with a price less than 10", async function () { var results = jp.nodes(data, "$..book[?(@.price<10)]"); tap.same(results, [ { path: ["$", "store", "book", 0], value: data.store.book[0], }, { path: ["$", "store", "book", 2], value: data.store.book[2], }, ]); }); tap.test("first ten of all elements", async function () { var results = jp.nodes(data, "$..*", 10); tap.same(results, [ { path: ["$", "store"], value: data.store, }, { path: ["$", "store", "book"], value: data.store.book, }, { path: ["$", "store", "bicycle"], value: data.store.bicycle, }, { path: ["$", "store", "book", 0], value: data.store.book[0], }, { path: ["$", "store", "book", 1], value: data.store.book[1], }, { path: ["$", "store", "book", 2], value: data.store.book[2], }, { path: ["$", "store", "book", 3], value: data.store.book[3], }, { path: ["$", "store", "book", 0, "category"], value: "reference", }, { path: ["$", "store", "book", 0, "author"], value: "Nigel Rees", }, { path: ["$", "store", "book", 0, "title"], value: "Sayings of the Century", }, ]); }); tap.test("all elements", async function () { var results = jp.nodes(data, "$..*"); tap.same(results, [ { path: ["$", "store"], value: data.store, }, { path: ["$", "store", "book"], value: data.store.book, }, { path: ["$", "store", "bicycle"], value: data.store.bicycle, }, { path: ["$", "store", "book", 0], value: data.store.book[0], }, { path: ["$", "store", "book", 1], value: data.store.book[1], }, { path: ["$", "store", "book", 2], value: data.store.book[2], }, { path: ["$", "store", "book", 3], value: data.store.book[3], }, { path: ["$", "store", "book", 0, "category"], value: "reference", }, { path: ["$", "store", "book", 0, "author"], value: "Nigel Rees", }, { path: ["$", "store", "book", 0, "title"], value: "Sayings of the Century", }, { path: ["$", "store", "book", 0, "price"], value: 8.95, }, { path: ["$", "store", "book", 1, "category"], value: "fiction", }, { path: ["$", "store", "book", 1, "author"], value: "Evelyn Waugh", }, { path: ["$", "store", "book", 1, "title"], value: "Sword of Honour", }, { path: ["$", "store", "book", 1, "price"], value: 12.99, }, { path: ["$", "store", "book", 2, "category"], value: "fiction", }, { path: ["$", "store", "book", 2, "author"], value: "Herman Melville", }, { path: ["$", "store", "book", 2, "title"], value: "Moby Dick", }, { path: ["$", "store", "book", 2, "isbn"], value: "0-553-21311-3", }, { path: ["$", "store", "book", 2, "price"], value: 8.99, }, { path: ["$", "store", "book", 3, "category"], value: "fiction", }, { path: ["$", "store", "book", 3, "author"], value: "J. R. R. Tolkien", }, { path: ["$", "store", "book", 3, "title"], value: "The Lord of the Rings", }, { path: ["$", "store", "book", 3, "isbn"], value: "0-395-19395-8", }, { path: ["$", "store", "book", 3, "price"], value: 22.99, }, { path: ["$", "store", "bicycle", "color"], value: "red", }, { path: ["$", "store", "bicycle", "price"], value: 19.95, }, ]); }); tap.test("all elements via subscript wildcard", async function () { var results = jp.nodes(data, "$..*"); tap.same(jp.nodes(data, "$..[*]"), jp.nodes(data, "$..*")); }); tap.test("object subscript wildcard", async function () { var results = jp.query(data, "$.store[*]"); tap.same(results, [data.store.book, data.store.bicycle]); }); tap.test("no match returns empty array", async function () { var results = jp.nodes(data, "$..bookz"); tap.same(results, []); }); tap.test("member numeric literal gets first element", async function () { var results = jp.nodes(data, "$.store.book.0"); tap.same(results, [ { path: ["$", "store", "book", 0], value: data.store.book[0], }, ]); }); tap.test( "member numeric literal matches string-numeric key", async function () { var data = { authors: { 1: "Herman Melville", 2: "J. R. R. Tolkien", }, }; var results = jp.nodes(data, "$.authors.1"); tap.same(results, [ { path: ["$", "authors", 1], value: "Herman Melville", }, ]); } ); tap.test("descendant numeric literal gets first element", async function () { var results = jp.nodes(data, "$.store.book..0"); tap.same(results, [ { path: ["$", "store", "book", 0], value: data.store.book[0], }, ]); }); tap.test("root element gets us original obj", async function () { var results = jp.nodes(data, "$"); tap.same(results, [ { path: ["$"], value: data, }, ]); }); tap.test("subscript double-quoted string", async function () { var results = jp.nodes(data, '$["store"]'); tap.same(results, [ { path: ["$", "store"], value: data.store, }, ]); }); tap.test("subscript single-quoted string", async function () { var results = jp.nodes(data, "$['store']"); tap.same(results, [ { path: ["$", "store"], value: data.store, }, ]); }); tap.test("leading member component", async function () { var results = jp.nodes(data, "store"); tap.same(results, [ { path: ["$", "store"], value: data.store, }, ]); }); tap.test("union of three array slices", async function () { var results = jp.query(data, "$.store.book[0:1,1:2,2:3]"); tap.same(results, data.store.book.slice(0, 3)); }); tap.test("slice with step > 1", async function () { var results = jp.query(data, "$.store.book[0:4:2]"); tap.same(results, [data.store.book[0], data.store.book[2]]); }); tap.test("union of subscript string literal keys", async function () { var results = jp.nodes(data, "$.store['book','bicycle']"); tap.same(results, [ { path: ["$", "store", "book"], value: data.store.book, }, { path: ["$", "store", "bicycle"], value: data.store.bicycle, }, ]); }); tap.test("union of subscript string literal three keys", async function () { var results = jp.nodes(data, "$.store.book[0]['title','author','price']"); tap.same(results, [ { path: ["$", "store", "book", 0, "title"], value: data.store.book[0].title, }, { path: ["$", "store", "book", 0, "author"], value: data.store.book[0].author, }, { path: ["$", "store", "book", 0, "price"], value: data.store.book[0].price, }, ]); }); tap.test( "union of subscript integer three keys followed by member-child-identifier", async function () { var results = jp.nodes(data, "$.store.book[1,2,3]['title']"); tap.same(results, [ { path: ["$", "store", "book", 1, "title"], value: data.store.book[1].title, }, { path: ["$", "store", "book", 2, "title"], value: data.store.book[2].title, }, { path: ["$", "store", "book", 3, "title"], value: data.store.book[3].title, }, ]); } ); tap.test( "union of subscript integer three keys followed by union of subscript string literal three keys", async function () { var results = jp.nodes( data, "$.store.book[0,1,2,3]['title','author','price']" ); tap.same(results, [ { path: ["$", "store", "book", 0, "title"], value: data.store.book[0].title, }, { path: ["$", "store", "book", 0, "author"], value: data.store.book[0].author, }, { path: ["$", "store", "book", 0, "price"], value: data.store.book[0].price, }, { path: ["$", "store", "book", 1, "title"], value: data.store.book[1].title, }, { path: ["$", "store", "book", 1, "author"], value: data.store.book[1].author, }, { path: ["$", "store", "book", 1, "price"], value: data.store.book[1].price, }, { path: ["$", "store", "book", 2, "title"], value: data.store.book[2].title, }, { path: ["$", "store", "book", 2, "author"], value: data.store.book[2].author, }, { path: ["$", "store", "book", 2, "price"], value: data.store.book[2].price, }, { path: ["$", "store", "book", 3, "title"], value: data.store.book[3].title, }, { path: ["$", "store", "book", 3, "author"], value: data.store.book[3].author, }, { path: ["$", "store", "book", 3, "price"], value: data.store.book[3].price, }, ]); } ); tap.test( "union of subscript integer four keys, including an inexistent one, followed by union of subscript string literal three keys", async function () { var results = jp.nodes( data, "$.store.book[0,1,2,3,151]['title','author','price']" ); tap.same(results, [ { path: ["$", "store", "book", 0, "title"], value: data.store.book[0].title, }, { path: ["$", "store", "book", 0, "author"], value: data.store.book[0].author, }, { path: ["$", "store", "book", 0, "price"], value: data.store.book[0].price, }, { path: ["$", "store", "book", 1, "title"], value: data.store.book[1].title, }, { path: ["$", "store", "book", 1, "author"], value: data.store.book[1].author, }, { path: ["$", "store", "book", 1, "price"], value: data.store.book[1].price, }, { path: ["$", "store", "book", 2, "title"], value: data.store.book[2].title, }, { path: ["$", "store", "book", 2, "author"], value: data.store.book[2].author, }, { path: ["$", "store", "book", 2, "price"], value: data.store.book[2].price, }, { path: ["$", "store", "book", 3, "title"], value: data.store.book[3].title, }, { path: ["$", "store", "book", 3, "author"], value: data.store.book[3].author, }, { path: ["$", "store", "book", 3, "price"], value: data.store.book[3].price, }, ]); } ); tap.test( "union of subscript integer three keys followed by union of subscript string literal three keys, followed by inexistent literal key", async function () { var results = jp.nodes( data, "$.store.book[0,1,2,3]['title','author','price','fruit']" ); tap.same(results, [ { path: ["$", "store", "book", 0, "title"], value: data.store.book[0].title, }, { path: ["$", "store", "book", 0, "author"], value: data.store.book[0].author, }, { path: ["$", "store", "book", 0, "price"], value: data.store.book[0].price, }, { path: ["$", "store", "book", 1, "title"], value: data.store.book[1].title, }, { path: ["$", "store", "book", 1, "author"], value: data.store.book[1].author, }, { path: ["$", "store", "book", 1, "price"], value: data.store.book[1].price, }, { path: ["$", "store", "book", 2, "title"], value: data.store.book[2].title, }, { path: ["$", "store", "book", 2, "author"], value: data.store.book[2].author, }, { path: ["$", "store", "book", 2, "price"], value: data.store.book[2].price, }, { path: ["$", "store", "book", 3, "title"], value: data.store.book[3].title, }, { path: ["$", "store", "book", 3, "author"], value: data.store.book[3].author, }, { path: ["$", "store", "book", 3, "price"], value: data.store.book[3].price, }, ]); } ); tap.test( "union of subscript 4 array slices followed by union of subscript string literal three keys", async function () { var results = jp.nodes( data, "$.store.book[0:1,1:2,2:3,3:4]['title','author','price']" ); tap.same(results, [ { path: ["$", "store", "book", 0, "title"], value: data.store.book[0].title, }, { path: ["$", "store", "book", 0, "author"], value: data.store.book[0].author, }, { path: ["$", "store", "book", 0, "price"], value: data.store.book[0].price, }, { path: ["$", "store", "book", 1, "title"], value: data.store.book[1].title, }, { path: ["$", "store", "book", 1, "author"], value: data.store.book[1].author, }, { path: ["$", "store", "book", 1, "price"], value: data.store.book[1].price, }, { path: ["$", "store", "book", 2, "title"], value: data.store.book[2].title, }, { path: ["$", "store", "book", 2, "author"], value: data.store.book[2].author, }, { path: ["$", "store", "book", 2, "price"], value: data.store.book[2].price, }, { path: ["$", "store", "book", 3, "title"], value: data.store.book[3].title, }, { path: ["$", "store", "book", 3, "author"], value: data.store.book[3].author, }, { path: ["$", "store", "book", 3, "price"], value: data.store.book[3].price, }, ]); } ); tap.test("nested parentheses eval", async function () { var pathExpression = "$..book[?( @.price && (@.price + 20 || false) )]"; var results = jp.query(data, pathExpression); tap.same(results, data.store.book); }); tap.test("array indexes from 0 to 100", async function () { var data = []; for (var i = 0; i <= 100; ++i) data[i] = Math.random(); for (var i = 0; i <= 100; ++i) { var results = jp.query(data, "$[" + i.toString() + "]"); tap.same(results, [data[i]]); } }); tap.test("descendant subscript numeric literal", async function () { var data = [0, [1, 2, 3], [4, 5, 6]]; var results = jp.query(data, "$..[0]"); tap.same(results, [0, 1, 4]); }); tap.test("descendant subscript numeric literal", async function () { var data = [0, 1, [2, 3, 4], [5, 6, 7, [8, 9, 10]]]; var results = jp.query(data, "$..[0,1]"); tap.same(results, [0, 1, 2, 3, 5, 6, 8, 9]); }); tap.test("throws for no input", async function () { tap.throws(function () { jp.query(); }, /needs to be an object/); }); tap.test("throws for bad input", async function () { tap.throws(function () { jp.query("string", "string"); }, /needs to be an object/); }); tap.test("throws for bad input", async function () { tap.throws(function () { jp.query({}, null); }, /we need a path/); }); tap.test("throws for bad input", async function () { tap.throws(function () { jp.query({}, 42); }, /we need a path/); }); tap.test("union on objects", async function () { tap.same( jp.query( { a: 1, b: 2, c: null, }, '$..["a","b","c","d"]' ), [1, 2, null] ); }); });