33 Commits

Author SHA1 Message Date
49179464f6 fix build script 2020-04-15 10:09:19 +09:00
81bbf47545 Bump up npm dependencies 2020-04-14 12:07:50 +09:00
55e8088111 Bump up 0.2.5 2020-04-14 11:53:34 +09:00
c1d4c78da9 build wasm 2020-04-14 11:33:31 +09:00
75c28fc73d close #43 2020-04-14 11:09:57 +09:00
1512e9b72f Failure to match "$..['']", "$..['ref']", but succeeds on $..ref #43 2020-04-14 11:09:14 +09:00
a168c46c04 Failure to match "$..['']", "$..['ref']", but succeeds on $..ref #43 2020-04-14 11:09:14 +09:00
83a170eb08 Bump acorn from 6.1.1 to 6.4.1 in /wasm/examples/browser
Bumps [acorn](https://github.com/acornjs/acorn) from 6.1.1 to 6.4.1.
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/6.1.1...6.4.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-04-07 09:49:53 +09:00
710f7ad544 close #39 2020-03-24 13:06:23 +09:00
74e79e6330 Empty result for filter expression returns array of null #39 2020-03-23 23:53:26 +09:00
ec92c95a69 Merge branch 'feature/code_cleanup' 2020-03-23 23:21:32 +09:00
da7cf723de fix clippy error 2020-03-23 23:03:19 +09:00
c99879cfbb filter, collector 정리 2020-03-23 22:50:08 +09:00
7991bba51d cmp, expr_term 분리 2020-03-22 23:48:24 +09:00
b8c82a9126 walk류 함수를 ValueWalker로 옮김 2020-03-22 23:22:53 +09:00
ba31b48c73 close #40 2020-03-22 22:36:26 +09:00
e9f69cd2b9 Bracket notation after recursive descent does not recurse #40 - fix clippy error 2020-03-22 22:34:47 +09:00
241a7f482d Bracket notation after recursive descent does not recurse #40 2020-03-22 22:25:07 +09:00
67cc6447a8 Bump acorn from 6.1.1 to 6.4.1 in /wasm/www_bench
Bumps [acorn](https://github.com/acornjs/acorn) from 6.1.1 to 6.4.1.
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/6.1.1...6.4.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-03-20 10:57:31 +09:00
9bc4b81f33 Bump acorn from 6.1.1 to 6.4.1 in /wasm/www
Bumps [acorn](https://github.com/acornjs/acorn) from 6.1.1 to 6.4.1.
- [Release notes](https://github.com/acornjs/acorn/releases)
- [Commits](https://github.com/acornjs/acorn/compare/6.1.1...6.4.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-03-20 10:57:08 +09:00
0d4d82fd49 close #38 2020-03-20 10:19:26 +09:00
de46a66148 Bracket notation not supported inside filter expression #38 - fix clippy error 2020-03-16 00:55:42 +09:00
ef52c63bc8 Bracket notation not supported inside filter expression #38 - add unit test 2020-03-16 00:50:51 +09:00
d618e60e13 Bracket notation not supported inside filter expression #38 2020-03-10 23:24:07 +09:00
a6f742e3ad 다중패스 필터 안되는 문제 수정 2020-03-10 23:22:35 +09:00
6f20013076 close #37 2020-02-23 20:43:31 +09:00
218321a4bd fix return_type_for_child_object_not_matched 2020-02-23 19:18:13 +09:00
d855c17899 split unit-tests 2020-02-23 14:45:14 +09:00
4919a03c6b fix clippy error 2020-02-16 22:43:39 +09:00
7a07bc7744 Remove useless code 2020-02-16 22:16:22 +09:00
32eef3f7c7 Restore wrong commit 2020-02-16 13:19:32 +09:00
b736c962d2 close #35 2020-02-16 13:17:44 +09:00
accd08139f Negative slice out of bounds does not return values #35 2020-02-16 13:14:31 +09:00
45 changed files with 5974 additions and 10437 deletions

View File

@ -1,12 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="filter" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package jsonpath_lib --test filter &quot;&quot;" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="false" />
<option name="backtrace" value="SHORT" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<envs />
<method v="2" />
</configuration>
</component>

View File

@ -1,12 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="lib" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package jsonpath_lib --test lib &quot;&quot;" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="false" />
<option name="backtrace" value="SHORT" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<envs />
<method v="2" />
</configuration>
</component>

View File

@ -1,12 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="mutable" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package jsonpath_lib --test mutable &quot;&quot;" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="false" />
<option name="backtrace" value="SHORT" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<envs />
<method v="2" />
</configuration>
</component>

View File

@ -1,12 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="readme" type="CargoCommandRunConfiguration" factoryName="Cargo Command">
<option name="channel" value="DEFAULT" />
<option name="command" value="test --package jsonpath_lib --test readme &quot;&quot;" />
<option name="allFeatures" value="false" />
<option name="nocapture" value="false" />
<option name="backtrace" value="SHORT" />
<option name="workingDirectory" value="file://$PROJECT_DIR$" />
<envs />
<method v="2" />
</configuration>
</component>

View File

@ -24,15 +24,9 @@ matrix:
before_script:
- rustup component add clippy
script:
- cargo clean
- cargo clippy -- -D warnings
- cargo build --verbose --all
- cargo clippy --all-targets --all-features -- -D warnings -A clippy::cognitive_complexity
- cargo test --verbose --all
- cd wasm && cargo clippy -- -D warnings -A clippy::suspicious_else_formatting
- cd ../../
- ./clippy.sh
after_success: |
cargo tarpaulin --exclude-files nodejs wasm parser/mod.rs --out Xml
cargo tarpaulin --exclude-files wasm parser/mod.rs --out Xml
bash <(curl -s https://codecov.io/bash)
- rust: stable
os: osx
@ -53,8 +47,6 @@ matrix:
- sh /tmp/rustup.sh -y
- export PATH="$HOME/.cargo/bin:$PATH"
- source "$HOME/.cargo/env"
- node -v
- npm -v
before_script:
- curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f
script:
@ -71,8 +63,6 @@ matrix:
- sh /tmp/rustup.sh -y
- export PATH="$HOME/.cargo/bin:$PATH"
- source "$HOME/.cargo/env"
- node -v
- npm -v
before_script:
- curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh -s -- -f
script:

View File

@ -1,19 +1,18 @@
[package]
name = "jsonpath_lib"
version = "0.2.4"
version = "0.2.5"
authors = ["Changseok Han <freestrings@gmail.com>"]
description = "It is JsonPath engine written in Rust. it provide a similar API interface in Webassembly and Javascript too. - Webassembly Demo: https://freestrings.github.io/jsonpath"
readme = "README.md"
keywords = ["jsonpath", "json", "webassembly", "nodejs", "query"]
keywords = ["jsonpath", "json", "webassembly", "lua", "query"]
categories = ['wasm', "parser-implementations", "api-bindings"]
repository = "https://github.com/freestrings/jsonpath"
documentation = "https://docs.rs/jsonpath_lib/0.2.4/jsonpath_lib"
documentation = "https://docs.rs/jsonpath_lib/0.2.5/jsonpath_lib"
license = "MIT"
categories = ["parsing"]
[badges]
travis-ci = { repository = "freestrings/jsonpath", branch = "master" }
@ -29,6 +28,6 @@ name = "jsonpath_lib"
path = "src/lib.rs"
crate-type = ["cdylib", "rlib"]
[profile.release]
#[profile.release]
#debug = true
#lto = false

View File

@ -5,7 +5,7 @@
![npm](https://img.shields.io/npm/v/jsonpath-wasm.svg?label=npm%20%60jsonpath-wasm%60)
![Codecov](https://img.shields.io/codecov/c/github/freestrings/jsonpath.svg?token=92c41b4e7cf04a9cbebc08f68c5da615)
`Rust` 버전 [JsonPath](https://goessner.net/articles/JsonPath/) 구현이다. `Webassembly``Javascript`에서도 유사한 API 인터페이스를 제공 한다.
`Rust` 버전 [JsonPath](https://goessner.net/articles/JsonPath/) 구현으로 `Webassembly``Javascript`에서도 유사한 API 인터페이스를 제공 한다.
It is JsonPath [JsonPath](https://goessner.net/articles/JsonPath/) engine written in `Rust`. it provide a similar API interface in `Webassembly` and` Javascript` too.

View File

@ -1,222 +0,0 @@
{
"name": "jsonpath-benches",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"JSONSelect": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/JSONSelect/-/JSONSelect-0.4.0.tgz",
"integrity": "sha1-oI7cxn6z/L6Z7WMIVTRKDPKCu40="
},
"cjson": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/cjson/-/cjson-0.2.1.tgz",
"integrity": "sha1-c82KrWXZ4VBfmvF0TTt5wVJ2gqU="
},
"colors": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/colors/-/colors-0.5.1.tgz",
"integrity": "sha1-fQAj6usVTo7p/Oddy5I9DtFmd3Q="
},
"deep-is": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
},
"ebnf-parser": {
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/ebnf-parser/-/ebnf-parser-0.1.10.tgz",
"integrity": "sha1-zR9rpHfFY4xAyX7ZtXLbW6tdgzE="
},
"escodegen": {
"version": "0.0.21",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-0.0.21.tgz",
"integrity": "sha1-U9ZSz6EDA4gnlFilJmxf/HCcY8M=",
"requires": {
"esprima": "~1.0.2",
"estraverse": "~0.0.4",
"source-map": ">= 0.1.2"
},
"dependencies": {
"esprima": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
"integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0="
}
}
},
"esprima": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.2.tgz",
"integrity": "sha1-dqD9Zvz+FU/SkmZ9wmQBl1CxZXs="
},
"estraverse": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-0.0.4.tgz",
"integrity": "sha1-AaCTLf7ldGhKWYr1pnw7+bZCjbI="
},
"esutils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
},
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
},
"jison": {
"version": "0.4.13",
"resolved": "https://registry.npmjs.org/jison/-/jison-0.4.13.tgz",
"integrity": "sha1-kEFwfWIkE2f1iDRTK58ZwsNvrHg=",
"requires": {
"JSONSelect": "0.4.0",
"cjson": "~0.2.1",
"ebnf-parser": "~0.1.9",
"escodegen": "0.0.21",
"esprima": "1.0.x",
"jison-lex": "0.2.x",
"lex-parser": "~0.1.3",
"nomnom": "1.5.2"
},
"dependencies": {
"esprima": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-1.0.4.tgz",
"integrity": "sha1-n1V+CPw7TSbs6d00+Pv0drYlha0="
}
}
},
"jison-lex": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/jison-lex/-/jison-lex-0.2.1.tgz",
"integrity": "sha1-rEuBXozOUTLrErXfz+jXB7iETf4=",
"requires": {
"lex-parser": "0.1.x",
"nomnom": "1.5.2"
}
},
"jsonpath": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/jsonpath/-/jsonpath-1.0.1.tgz",
"integrity": "sha512-HY5kSg82LHIs0r0h9gYBwpNc1w1qGY0qJ7al01W1bJltsN2lp+mjjA/a79gXWuvD6Xf8oPkD2d5uKMZQXTGzqA==",
"requires": {
"esprima": "1.2.2",
"jison": "0.4.13",
"static-eval": "2.0.2",
"underscore": "1.7.0"
}
},
"levn": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"requires": {
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2"
}
},
"lex-parser": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/lex-parser/-/lex-parser-0.1.4.tgz",
"integrity": "sha1-ZMTwJfF/1Tv7RXY/rrFvAVp0dVA="
},
"nomnom": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.5.2.tgz",
"integrity": "sha1-9DRUSKhTz71cDSYyDyR3qwUm/i8=",
"requires": {
"colors": "0.5.x",
"underscore": "1.1.x"
},
"dependencies": {
"underscore": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.1.7.tgz",
"integrity": "sha1-QLq4S60Z0jAJbo1u9ii/8FXYPbA="
}
}
},
"optionator": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
"integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
"requires": {
"deep-is": "~0.1.3",
"fast-levenshtein": "~2.0.4",
"levn": "~0.3.0",
"prelude-ls": "~1.1.2",
"type-check": "~0.3.2",
"wordwrap": "~1.0.0"
}
},
"prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
"integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
},
"source-map": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz",
"integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==",
"optional": true
},
"static-eval": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/static-eval/-/static-eval-2.0.2.tgz",
"integrity": "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg==",
"requires": {
"escodegen": "^1.8.1"
},
"dependencies": {
"escodegen": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz",
"integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==",
"requires": {
"esprima": "^3.1.3",
"estraverse": "^4.2.0",
"esutils": "^2.0.2",
"optionator": "^0.8.1",
"source-map": "~0.6.1"
}
},
"esprima": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
"integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM="
},
"estraverse": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
"integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM="
},
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"optional": true
}
}
},
"type-check": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
"requires": {
"prelude-ls": "~1.1.2"
}
},
"underscore": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz",
"integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk="
},
"wordwrap": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
}
}
}

View File

@ -7,9 +7,8 @@ DIR="$(pwd)"
WASM="${DIR}"/wasm
WASM_WWW="${WASM}"/www
WASM_WWW_BENCH="${WASM}"/www_bench
WASM_BROWSER_PKG="${WASM}"/browser_pkg
WASM_NODEJS_PKG="${WASM}"/nodejs_pkg
WASM_ALL_PKG="${WASM}"/all_pkg
WASM_WEB_PKG="${WASM}"/web_pkg
WASM_TEST="${WASM}"/tests
DOCS="${DIR}"/docs
DOCS_BENCH="${DOCS}"/bench
@ -19,6 +18,8 @@ __msg () {
}
__cargo_clean () {
rm -f "${DIR}"/Cargo.lock
rm -f "${WASM}"/Cargo.lock
cd "${WASM}" && cargo clean && \
cd "${DIR}" && cargo clean
}
@ -27,78 +28,64 @@ echo
__msg "clean wasm"
rm -rf \
"${WASM_NODEJS_PKG}" \
"${WASM_BROWSER_PKG}" \
"${WASM_ALL_PKG}" \
"${WASM_WWW}"/node_modules \
"${WASM_WWW_BENCH}"/node_modules \
"${WASM_WEB_PKG}" \
"${WASM_WWW}"/dist \
"${WASM_WWW}"/node_modules \
"${WASM_WWW}"/package-lock.json \
"${WASM_WWW_BENCH}"/dist \
"${WASM_TEST}"/node_modules
"${WASM_WWW_BENCH}"/node_modules \
"${WASM_WWW_BENCH}"/package-lock.json \
"${WASM_TEST}"/node_modules \
"${WASM_TEST}"/package-lock.json
if [ "$1" = "all" ]; then
__msg "clean all wasm"
__cargo_clean
fi
__msg "clean cargo clean"
__cargo_clean
echo
wasm_pack_version=$(wasm-pack -V)
__msg "wasm-pack: ${wasm_pack_version}"
echo
__msg "wasm-pack nodejs"
cd "${WASM}" && wasm-pack build --release --target "nodejs" --out-dir "${WASM_NODEJS_PKG}"
__msg "npm install: wasm"
cd "${WASM_WWW}" && npm install
__msg "npm install: wasm_bench"
cd "${WASM_WWW_BENCH}" && npm install
__msg "npm install: wasm test"
cd "${WASM_TEST}" && npm install
cd "${WASM_TEST}" && npm install "${WASM_NODEJS_PKG}" && npm install
echo
echo
__msg "wasm-pack"
cd "${WASM}" && \
wasm-pack build --release --target=nodejs --out-dir "${WASM_NODEJS_PKG}"
cd "${WASM}" && \
wasm-pack build --release --target=browser --out-dir "${WASM_BROWSER_PKG}"
# && \
# wasm-pack test --chrome --firefox --headless
__msg "wasm npm packaging"
cp -r "${WASM_BROWSER_PKG}" "${WASM_ALL_PKG}/" && \
sed "s/require[\(]'\.\/jsonpath_wasm_bg/require\('\.\/jsonpath_wasm_nodejs/" "${WASM_NODEJS_PKG}/jsonpath_wasm.js" \
> "${WASM_ALL_PKG}/jsonpath_wasm_main.js" && \
sed "s/require[\(]'\.\/jsonpath_wasm/require\('\.\/jsonpath_wasm_main/" "${WASM_NODEJS_PKG}/jsonpath_wasm_bg.js" \
> "${WASM_ALL_PKG}/jsonpath_wasm_nodejs.js" && \
jq ".files += [\"jsonpath_wasm_nodejs.js\"]" ${WASM_ALL_PKG}/package.json \
| jq ".main = \"jsonpath_wasm_main.js\"" \
| jq ".keywords += [\"jsonpath\", \"json\", \"webassembly\", \"parsing\", \"rust\"]" \
> ${WASM_ALL_PKG}/temp.json && \
mv -v "${WASM_ALL_PKG}/temp.json" "${WASM_ALL_PKG}/package.json" && \
cd "${WASM_ALL_PKG}" && npm link
echo
__msg "link"
cd "${WASM_WWW}" && \
npm link jsonpath-wasm
cd "${WASM_WWW_BENCH}" && \
npm link jsonpath-wasm
cd "${WASM_TEST}" && \
npm link jsonpath-wasm
echo
echo
__msg "wasm test"
cd "${WASM_TEST}" && npm test
if [ "$1" = "all" ] || [ "$1" = "docs" ]; then
echo
__msg "docs"
cd "${WASM_WWW}" && \
npm run build &&
rm -f "${DOCS}"/*.js "${DOCS}"/*.wasm "${DOCS}"/*.html && \
cp "${WASM_WWW}"/dist/*.* "${DOCS}"/
if [ "$1" = "docs" ]; then
echo
__msg "wasm-pack web"
cd "${WASM}" && wasm-pack build --release --out-dir "${WASM_WEB_PKG}"
cd "${WASM_WWW_BENCH}" && \
npm run build &&
rm -f "${DOCS_BENCH}"/*.js "${DOCS_BENCH}"/*.wasm "${DOCS_BENCH}"/*.html && \
cp "${WASM_WWW_BENCH}"/dist/*.* "${DOCS_BENCH}"/
echo
__msg "jsonpath-wasm npm link"
cd "${WASM_WEB_PKG}" && npm link
__msg "npm install: wasm"
cd "${WASM_WWW}" && npm install
__msg "npm install: wasm_bench"
cd "${WASM_WWW_BENCH}" && npm install
echo
__msg "link"
cd "${WASM_WWW}" && npm link jsonpath-wasm
cd "${WASM_WWW_BENCH}" && npm link jsonpath-wasm
echo
__msg "docs"
cd "${WASM_WWW}" && \
npm run build &&
rm -f "${DOCS}"/*.js "${DOCS}"/*.wasm "${DOCS}"/*.html && \
cp "${WASM_WWW}"/dist/*.* "${DOCS}"/
cd "${WASM_WWW_BENCH}" && \
npm run build &&
rm -f "${DOCS_BENCH}"/*.js "${DOCS_BENCH}"/*.wasm "${DOCS_BENCH}"/*.html && \
cp "${WASM_WWW_BENCH}"/dist/*.* "${DOCS_BENCH}"/
fi
__msg "wasm done"

132
build.sh
View File

@ -1,132 +0,0 @@
#!/bin/bash
set -e
# project_root
DIR="$(pwd)"
WASM="${DIR}"/wasm
WASM_WWW="${WASM}"/www
WASM_WWW_BENCH="${WASM}"/www_bench
WASM_BROWSER_PKG="${WASM}"/browser_pkg
WASM_NODEJS_PKG="${WASM}"/nodejs_pkg
WASM_ALL_PKG="${WASM}"/all_pkg
WASM_TEST="${WASM}"/tests
BENCHES="${DIR}"/benchmark
BENCHES_JS="${BENCHES}"/javascript
NODEJS="${DIR}"/nodejs
DOCS="${DIR}"/docs
DOCS_BENCH="${DOCS}"/bench
__msg () {
echo ">>>>>>>>>>$1<<<<<<<<<<"
}
__cargo_clean () {
cd "${BENCHES}"/bench_bin && cargo clean && \
cd "${NODEJS}"/native && cargo clean && \
cd "${WASM}" && cargo clean && \
cd "${DIR}" && cargo clean
}
if [ "$1" = "clippy" ]
then
echo
__msg "clippy"
cargo clippy -- -D warnings && \
cargo clippy --all-targets --all-features -- -D warnings -A clippy::cognitive_complexity && \
cd "${WASM}" && cargo clippy -- -A clippy::suspicious_else_formatting && \
cd "${NODEJS}" && cargo clippy
fi
echo
__msg "clean"
rm -rf \
"${WASM_NODEJS_PKG}" \
"${WASM_BROWSER_PKG}" \
"${WASM_ALL_PKG}" \
"${BENCHES_JS}"/node_modules \
"${NODEJS}"/node_modules \
"${WASM_WWW}"/node_modules \
"${WASM_WWW_BENCH}"/node_modules \
"${WASM_WWW}"/dist \
"${WASM_WWW_BENCH}"/dist \
"${WASM_TEST}"/node_modules
if [ "$1" = "all" ]; then
__msg "clean targets"
__cargo_clean
fi
__msg "npm install: wasm"
cd "${WASM_WWW}" && npm install
__msg "npm install: wasm_bench"
cd "${WASM_WWW_BENCH}" && npm install
__msg "npm install: nodejs"
cd "${NODEJS}" && npm install
__msg "npm install: benches_js"
cd "${BENCHES_JS}" && npm install
__msg "npm install: wasm test"
cd "${WASM_TEST}" && npm install
echo
echo
__msg "nodejs test"
cd "${NODEJS}" && npm test
echo
echo
__msg "wasm-pack"
cd "${WASM}" && \
wasm-pack build --release --target=nodejs --out-dir "${WASM_NODEJS_PKG}"
cd "${WASM}" && \
wasm-pack build --release --target=browser --out-dir "${WASM_BROWSER_PKG}"
# && \
# wasm-pack test --chrome --firefox --headless
__msg "wasm npm packaging"
cp -r "${WASM_BROWSER_PKG}" "${WASM_ALL_PKG}/" && \
sed "s/require[\(]'\.\/jsonpath_wasm_bg/require\('\.\/jsonpath_wasm_nodejs/" "${WASM_NODEJS_PKG}/jsonpath_wasm.js" \
> "${WASM_ALL_PKG}/jsonpath_wasm_main.js" && \
sed "s/require[\(]'\.\/jsonpath_wasm/require\('\.\/jsonpath_wasm_main/" "${WASM_NODEJS_PKG}/jsonpath_wasm_bg.js" \
> "${WASM_ALL_PKG}/jsonpath_wasm_nodejs.js" && \
jq ".files += [\"jsonpath_wasm_nodejs.js\"]" ${WASM_ALL_PKG}/package.json \
| jq ".main = \"jsonpath_wasm_main.js\"" \
| jq ".keywords += [\"jsonpath\", \"json\", \"webassembly\", \"parsing\", \"rust\"]" \
> ${WASM_ALL_PKG}/temp.json && \
mv -v "${WASM_ALL_PKG}/temp.json" "${WASM_ALL_PKG}/package.json" && \
cd "${WASM_ALL_PKG}" && npm link
echo
__msg "link"
cd "${WASM_WWW}" && \
npm link jsonpath-wasm
cd "${WASM_WWW_BENCH}" && \
npm link jsonpath-wasm
cd "${BENCHES_JS}" && \
npm link jsonpath-wasm
cd "${WASM_TEST}" && \
npm link jsonpath-wasm
echo
echo
__msg "wasm test"
cd "${WASM_TEST}" && npm test
echo
__msg "docs"
cd "${WASM_WWW}" && \
npm run build &&
rm -f "${DOCS}"/*.js "${DOCS}"/*.wasm "${DOCS}"/*.html && \
cp "${WASM_WWW}"/dist/*.* "${DOCS}"/
cd "${WASM_WWW_BENCH}" && \
npm run build &&
rm -f "${DOCS_BENCH}"/*.js "${DOCS_BENCH}"/*.wasm "${DOCS_BENCH}"/*.html && \
cp "${WASM_WWW_BENCH}"/dist/*.* "${DOCS_BENCH}"/
__msg "done"

11
clippy.sh Executable file
View File

@ -0,0 +1,11 @@
#!/usr/bin/env bash
set -e
cargo clean
cargo clippy -- -D warnings
cargo build --verbose --all
cargo clippy --all-targets --all-features -- -D warnings -A clippy::cognitive_complexity
cargo test --verbose --all
cd wasm && cargo clippy -- -D warnings -A clippy::suspicious_else_formatting
cd ../

File diff suppressed because one or more lines are too long

38
docs/1.bootstrap.js Normal file

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

View File

@ -10,7 +10,7 @@
/******/ var moduleId, chunkId, i = 0, resolves = [];
/******/ for(;i < chunkIds.length; i++) {
/******/ chunkId = chunkIds[i];
/******/ if(installedChunks[chunkId]) {
/******/ if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {
/******/ resolves.push(installedChunks[chunkId][0]);
/******/ }
/******/ installedChunks[chunkId] = 0;
@ -52,53 +52,53 @@
/******/ function promiseResolve() { return Promise.resolve(); }
/******/
/******/ var wasmImportObjects = {
/******/ "../all_pkg/jsonpath_wasm_bg.wasm": function() {
/******/ "../web_pkg/jsonpath_wasm_bg.wasm": function() {
/******/ return {
/******/ "./jsonpath_wasm": {
/******/ "./jsonpath_wasm.js": {
/******/ "__wbindgen_json_parse": function(p0i32,p1i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_json_parse"](p0i32,p1i32);
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_json_parse"](p0i32,p1i32);
/******/ },
/******/ "__wbindgen_json_serialize": function(p0i32,p1i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_json_serialize"](p0i32,p1i32);
/******/ },
/******/ "__wbg_error_bb0b0e541b3bff31": function(p0i32,p1i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbg_error_bb0b0e541b3bff31"](p0i32,p1i32);
/******/ },
/******/ "__wbindgen_object_drop_ref": function(p0i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_object_drop_ref"](p0i32);
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_json_serialize"](p0i32,p1i32);
/******/ },
/******/ "__wbindgen_cb_forget": function(p0i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_cb_forget"](p0i32);
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_cb_forget"](p0i32);
/******/ },
/******/ "__wbindgen_string_new": function(p0i32,p1i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_string_new"](p0i32,p1i32);
/******/ "__wbg_error_e7d3e8dbb31828c8": function(p0i32,p1i32) {
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbg_error_e7d3e8dbb31828c8"](p0i32,p1i32);
/******/ },
/******/ "__wbg_call_88d2a6153573084e": function(p0i32,p1i32,p2i32,p3i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbg_call_88d2a6153573084e"](p0i32,p1i32,p2i32,p3i32);
/******/ },
/******/ "__wbindgen_is_string": function(p0i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_is_string"](p0i32);
/******/ },
/******/ "__wbindgen_string_get": function(p0i32,p1i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_string_get"](p0i32,p1i32);
/******/ "__wbindgen_object_drop_ref": function(p0i32) {
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_object_drop_ref"](p0i32);
/******/ },
/******/ "__wbindgen_object_clone_ref": function(p0i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_object_clone_ref"](p0i32);
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_object_clone_ref"](p0i32);
/******/ },
/******/ "__wbindgen_string_new": function(p0i32,p1i32) {
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_string_new"](p0i32,p1i32);
/******/ },
/******/ "__wbg_call_1ad0eb4a7ab279eb": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbg_call_1ad0eb4a7ab279eb"](p0i32,p1i32,p2i32);
/******/ },
/******/ "__wbindgen_is_string": function(p0i32) {
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_is_string"](p0i32);
/******/ },
/******/ "__wbindgen_string_get": function(p0i32,p1i32) {
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_string_get"](p0i32,p1i32);
/******/ },
/******/ "__wbindgen_debug_string": function(p0i32,p1i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_debug_string"](p0i32,p1i32);
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_debug_string"](p0i32,p1i32);
/******/ },
/******/ "__wbindgen_throw": function(p0i32,p1i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_throw"](p0i32,p1i32);
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_throw"](p0i32,p1i32);
/******/ },
/******/ "__wbindgen_rethrow": function(p0i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_rethrow"](p0i32);
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_rethrow"](p0i32);
/******/ },
/******/ "__wbindgen_closure_wrapper115": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_closure_wrapper115"](p0i32,p1i32,p2i32);
/******/ "__wbindgen_closure_wrapper28": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_closure_wrapper28"](p0i32,p1i32,p2i32);
/******/ },
/******/ "__wbindgen_closure_wrapper117": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_closure_wrapper117"](p0i32,p1i32,p2i32);
/******/ "__wbindgen_closure_wrapper26": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_closure_wrapper26"](p0i32,p1i32,p2i32);
/******/ }
/******/ }
/******/ };
@ -161,6 +161,8 @@
/******/ }
/******/ script.src = jsonpScriptSrc(chunkId);
/******/
/******/ // create error before stack unwound to get useful stacktrace later
/******/ var error = new Error();
/******/ onScriptComplete = function (event) {
/******/ // avoid mem leaks in IE.
/******/ script.onerror = script.onload = null;
@ -170,7 +172,8 @@
/******/ if(chunk) {
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
/******/ var realSrc = event && event.target && event.target.src;
/******/ var error = new Error('Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')');
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
/******/ error.name = 'ChunkLoadError';
/******/ error.type = errorType;
/******/ error.request = realSrc;
/******/ chunk[1](error);
@ -188,7 +191,7 @@
/******/
/******/ // Fetch + compile chunk loading for webassembly
/******/
/******/ var wasmModules = {"0":["../all_pkg/jsonpath_wasm_bg.wasm"]}[chunkId] || [];
/******/ var wasmModules = {"1":["../web_pkg/jsonpath_wasm_bg.wasm"]}[chunkId] || [];
/******/
/******/ wasmModules.forEach(function(wasmModuleId) {
/******/ var installedWasmModuleData = installedWasmModules[wasmModuleId];
@ -198,7 +201,7 @@
/******/ promises.push(installedWasmModuleData);
/******/ else {
/******/ var importObject = wasmImportObjects[wasmModuleId]();
/******/ var req = fetch(__webpack_require__.p + "" + {"../all_pkg/jsonpath_wasm_bg.wasm":"33fd09cf53124f20b1e8"}[wasmModuleId] + ".module.wasm");
/******/ var req = fetch(__webpack_require__.p + "" + {"../web_pkg/jsonpath_wasm_bg.wasm":"a9530753c3f0aa3c5ead"}[wasmModuleId] + ".module.wasm");
/******/ var promise;
/******/ if(importObject instanceof Promise && typeof WebAssembly.compileStreaming === 'function') {
/******/ promise = Promise.all([WebAssembly.compileStreaming(req), importObject]).then(function(items) {
@ -299,7 +302,7 @@
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
eval("// A dependency graph that contains any wasm must all be imported\n// asynchronously. This `bootstrap.js` file does the single async import, so\n// that no one else needs to worry about it again.\nPromise.all(/*! import() */[__webpack_require__.e(1), __webpack_require__.e(0)]).then(__webpack_require__.bind(null, /*! ./index.js */ \"./index.js\"))\n .catch(e => console.error(\"Error importing `index.js`:\", e));\n\n//# sourceURL=webpack:///./bootstrap.js?");
eval("// A dependency graph that contains any wasm must all be imported\n// asynchronously. This `bootstrap.js` file does the single async import, so\n// that no one else needs to worry about it again.\nPromise.all(/*! import() */[__webpack_require__.e(0), __webpack_require__.e(1)]).then(__webpack_require__.bind(null, /*! ./index.js */ \"./index.js\"))\n .catch(e => console.error(\"Error importing `index.js`:\", e));\n\n//# sourceURL=webpack:///./bootstrap.js?");
/***/ })

71
docs/bootstrap.js vendored
View File

@ -10,7 +10,7 @@
/******/ var moduleId, chunkId, i = 0, resolves = [];
/******/ for(;i < chunkIds.length; i++) {
/******/ chunkId = chunkIds[i];
/******/ if(installedChunks[chunkId]) {
/******/ if(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {
/******/ resolves.push(installedChunks[chunkId][0]);
/******/ }
/******/ installedChunks[chunkId] = 0;
@ -52,53 +52,53 @@
/******/ function promiseResolve() { return Promise.resolve(); }
/******/
/******/ var wasmImportObjects = {
/******/ "../all_pkg/jsonpath_wasm_bg.wasm": function() {
/******/ "../web_pkg/jsonpath_wasm_bg.wasm": function() {
/******/ return {
/******/ "./jsonpath_wasm": {
/******/ "./jsonpath_wasm.js": {
/******/ "__wbindgen_json_parse": function(p0i32,p1i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_json_parse"](p0i32,p1i32);
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_json_parse"](p0i32,p1i32);
/******/ },
/******/ "__wbindgen_json_serialize": function(p0i32,p1i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_json_serialize"](p0i32,p1i32);
/******/ },
/******/ "__wbg_error_bb0b0e541b3bff31": function(p0i32,p1i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbg_error_bb0b0e541b3bff31"](p0i32,p1i32);
/******/ },
/******/ "__wbindgen_object_drop_ref": function(p0i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_object_drop_ref"](p0i32);
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_json_serialize"](p0i32,p1i32);
/******/ },
/******/ "__wbindgen_cb_forget": function(p0i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_cb_forget"](p0i32);
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_cb_forget"](p0i32);
/******/ },
/******/ "__wbindgen_string_new": function(p0i32,p1i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_string_new"](p0i32,p1i32);
/******/ "__wbg_error_e7d3e8dbb31828c8": function(p0i32,p1i32) {
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbg_error_e7d3e8dbb31828c8"](p0i32,p1i32);
/******/ },
/******/ "__wbg_call_88d2a6153573084e": function(p0i32,p1i32,p2i32,p3i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbg_call_88d2a6153573084e"](p0i32,p1i32,p2i32,p3i32);
/******/ },
/******/ "__wbindgen_is_string": function(p0i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_is_string"](p0i32);
/******/ },
/******/ "__wbindgen_string_get": function(p0i32,p1i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_string_get"](p0i32,p1i32);
/******/ "__wbindgen_object_drop_ref": function(p0i32) {
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_object_drop_ref"](p0i32);
/******/ },
/******/ "__wbindgen_object_clone_ref": function(p0i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_object_clone_ref"](p0i32);
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_object_clone_ref"](p0i32);
/******/ },
/******/ "__wbindgen_string_new": function(p0i32,p1i32) {
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_string_new"](p0i32,p1i32);
/******/ },
/******/ "__wbg_call_1ad0eb4a7ab279eb": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbg_call_1ad0eb4a7ab279eb"](p0i32,p1i32,p2i32);
/******/ },
/******/ "__wbindgen_is_string": function(p0i32) {
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_is_string"](p0i32);
/******/ },
/******/ "__wbindgen_string_get": function(p0i32,p1i32) {
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_string_get"](p0i32,p1i32);
/******/ },
/******/ "__wbindgen_debug_string": function(p0i32,p1i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_debug_string"](p0i32,p1i32);
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_debug_string"](p0i32,p1i32);
/******/ },
/******/ "__wbindgen_throw": function(p0i32,p1i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_throw"](p0i32,p1i32);
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_throw"](p0i32,p1i32);
/******/ },
/******/ "__wbindgen_rethrow": function(p0i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_rethrow"](p0i32);
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_rethrow"](p0i32);
/******/ },
/******/ "__wbindgen_closure_wrapper115": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_closure_wrapper115"](p0i32,p1i32,p2i32);
/******/ "__wbindgen_closure_wrapper28": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_closure_wrapper28"](p0i32,p1i32,p2i32);
/******/ },
/******/ "__wbindgen_closure_wrapper117": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../all_pkg/jsonpath_wasm.js"].exports["__wbindgen_closure_wrapper117"](p0i32,p1i32,p2i32);
/******/ "__wbindgen_closure_wrapper26": function(p0i32,p1i32,p2i32) {
/******/ return installedModules["../web_pkg/jsonpath_wasm.js"].exports["__wbindgen_closure_wrapper26"](p0i32,p1i32,p2i32);
/******/ }
/******/ }
/******/ };
@ -161,6 +161,8 @@
/******/ }
/******/ script.src = jsonpScriptSrc(chunkId);
/******/
/******/ // create error before stack unwound to get useful stacktrace later
/******/ var error = new Error();
/******/ onScriptComplete = function (event) {
/******/ // avoid mem leaks in IE.
/******/ script.onerror = script.onload = null;
@ -170,7 +172,8 @@
/******/ if(chunk) {
/******/ var errorType = event && (event.type === 'load' ? 'missing' : event.type);
/******/ var realSrc = event && event.target && event.target.src;
/******/ var error = new Error('Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')');
/******/ error.message = 'Loading chunk ' + chunkId + ' failed.\n(' + errorType + ': ' + realSrc + ')';
/******/ error.name = 'ChunkLoadError';
/******/ error.type = errorType;
/******/ error.request = realSrc;
/******/ chunk[1](error);
@ -188,7 +191,7 @@
/******/
/******/ // Fetch + compile chunk loading for webassembly
/******/
/******/ var wasmModules = {"0":["../all_pkg/jsonpath_wasm_bg.wasm"]}[chunkId] || [];
/******/ var wasmModules = {"1":["../web_pkg/jsonpath_wasm_bg.wasm"]}[chunkId] || [];
/******/
/******/ wasmModules.forEach(function(wasmModuleId) {
/******/ var installedWasmModuleData = installedWasmModules[wasmModuleId];
@ -198,7 +201,7 @@
/******/ promises.push(installedWasmModuleData);
/******/ else {
/******/ var importObject = wasmImportObjects[wasmModuleId]();
/******/ var req = fetch(__webpack_require__.p + "" + {"../all_pkg/jsonpath_wasm_bg.wasm":"33fd09cf53124f20b1e8"}[wasmModuleId] + ".module.wasm");
/******/ var req = fetch(__webpack_require__.p + "" + {"../web_pkg/jsonpath_wasm_bg.wasm":"a9530753c3f0aa3c5ead"}[wasmModuleId] + ".module.wasm");
/******/ var promise;
/******/ if(importObject instanceof Promise && typeof WebAssembly.compileStreaming === 'function') {
/******/ promise = Promise.all([WebAssembly.compileStreaming(req), importObject]).then(function(items) {
@ -299,7 +302,7 @@
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
eval("// A dependency graph that contains any wasm must all be imported\n// asynchronously. This `bootstrap.js` file does the single async import, so\n// that no one else needs to worry about it again.\n__webpack_require__.e(/*! import() */ 0).then(__webpack_require__.bind(null, /*! ./index.js */ \"./index.js\"))\n .catch(e => console.error(\"Error importing `index.js`:\", e));\n\n\n//# sourceURL=webpack:///./bootstrap.js?");
eval("// A dependency graph that contains any wasm must all be imported\n// asynchronously. This `bootstrap.js` file does the single async import, so\n// that no one else needs to worry about it again.\nPromise.all(/*! import() */[__webpack_require__.e(0), __webpack_require__.e(1)]).then(__webpack_require__.bind(null, /*! ./index.js */ \"./index.js\"))\n .catch(e => console.error(\"Error importing `index.js`:\", e));\n\n\n//# sourceURL=webpack:///./bootstrap.js?");
/***/ })

View File

@ -13,8 +13,8 @@ mod utils {
use std::str::FromStr;
pub fn string_to_num<F, S: FromStr>(string: &str, msg_handler: F) -> Result<S, String>
where
F: Fn() -> String,
where
F: Fn() -> String,
{
match string.parse() {
Ok(n) => Ok(n),
@ -209,7 +209,8 @@ impl Parser {
fn array_keys(tokenizer: &mut TokenReader, first_key: String) -> ParseResult<Node> {
let mut keys = vec![first_key];
while tokenizer.peek_is(COMMA) {
while let Ok(Token::Comma(_)) = tokenizer.peek_token() {
Self::eat_token(tokenizer);
Self::eat_whitespace(tokenizer);
@ -230,7 +231,7 @@ impl Parser {
debug!("#array_quote_value");
match tokenizer.next_token() {
Ok(Token::SingleQuoted(_, val)) | Ok(Token::DoubleQuoted(_, val)) => {
if tokenizer.peek_is(COMMA) {
if let Ok(Token::Comma(_)) = tokenizer.peek_token() {
Self::array_keys(tokenizer, val)
} else {
Ok(Self::node(ParseToken::Key(val)))
@ -529,41 +530,35 @@ impl Parser {
fn term(tokenizer: &mut TokenReader) -> ParseResult<Node> {
debug!("#term");
if tokenizer.peek_is(AT) {
Self::eat_token(tokenizer);
let node = Self::node(ParseToken::Relative);
match tokenizer.peek_token() {
Ok(Token::At(_)) => {
Self::eat_token(tokenizer);
let node = Self::node(ParseToken::Relative);
return match tokenizer.peek_token() {
Ok(Token::Whitespace(_, _)) => {
Self::eat_whitespace(tokenizer);
Ok(node)
match tokenizer.peek_token() {
Ok(Token::Whitespace(_, _)) => {
Self::eat_whitespace(tokenizer);
Ok(node)
}
_ => Self::paths(node, tokenizer),
}
_ => Self::paths(node, tokenizer),
};
}
Ok(Token::Absolute(_)) => {
Self::json_path(tokenizer)
},
Ok(Token::DoubleQuoted(_, _)) | Ok(Token::SingleQuoted(_, _)) => {
Self::array_quote_value(tokenizer)
},
Ok(Token::Key(_, key)) => {
match key.as_bytes()[0] {
b'-' | b'0'..=b'9' => Self::term_num(tokenizer),
_ => Self::boolean(tokenizer),
}
}
_ => {
Err(tokenizer.err_msg())
}
}
if tokenizer.peek_is(ABSOLUTE) {
return Self::json_path(tokenizer);
}
if tokenizer.peek_is(DOUBLE_QUOTE) || tokenizer.peek_is(SINGLE_QUOTE) {
return Self::array_quote_value(tokenizer);
}
if tokenizer.peek_is(KEY) {
let key = if let Ok(Token::Key(_, k)) = tokenizer.peek_token() {
k.clone()
} else {
unreachable!()
};
return match key.as_bytes()[0] {
b'-' | b'0'..=b'9' => Self::term_num(tokenizer),
_ => Self::boolean(tokenizer),
};
}
Err(tokenizer.err_msg())
}
fn op(prev: Node, tokenizer: &mut TokenReader) -> ParseResult<Node> {
@ -610,7 +605,7 @@ impl Parser {
fn close_token(ret: Node, token: Token, tokenizer: &mut TokenReader) -> ParseResult<Node> {
debug!("#close_token");
match tokenizer.next_token() {
Ok(ref t) if t.partial_eq(token) => Ok(ret),
Ok(ref t) if t.is_match_token_type(token) => Ok(ret),
_ => Err(tokenizer.err_msg()),
}
}
@ -817,6 +812,25 @@ mod parser_tests {
])
);
assert_eq!(
run("$.$a"),
Ok(vec![
ParseToken::Absolute,
ParseToken::In,
ParseToken::Key("$a".to_owned())
])
);
assert_eq!(
run("$.['$a']"),
Ok(vec![
ParseToken::Absolute,
ParseToken::Array,
ParseToken::Key("$a".to_owned()),
ParseToken::ArrayEof,
])
);
if run("$.").is_ok() {
panic!();
}

View File

@ -2,30 +2,6 @@ use std::result::Result;
use super::path_reader::{PathReader, ReaderError};
pub const ABSOLUTE: &str = "$";
pub const DOT: &str = ".";
pub const AT: &str = "@";
pub const OPEN_ARRAY: &str = "[";
pub const CLOSE_ARRAY: &str = "]";
pub const ASTERISK: &str = "*";
pub const QUESTION: &str = "?";
pub const COMMA: &str = ",";
pub const SPLIT: &str = ":";
pub const OPEN_PARENTHESIS: &str = "(";
pub const CLOSE_PARENTHESIS: &str = ")";
pub const KEY: &str = "Key";
pub const DOUBLE_QUOTE: &str = "\"";
pub const SINGLE_QUOTE: &str = "'";
pub const EQUAL: &str = "==";
pub const GREATER_OR_EQUAL: &str = ">=";
pub const GREATER: &str = ">";
pub const LITTLE: &str = "<";
pub const LITTLE_OR_EQUAL: &str = "<=";
pub const NOT_EQUAL: &str = "!=";
pub const AND: &str = "&&";
pub const OR: &str = "||";
pub const WHITESPACE: &str = " ";
const CH_DOLLA: char = '$';
const CH_DOT: char = '.';
const CH_ASTERISK: char = '*';
@ -86,61 +62,104 @@ pub enum Token {
}
impl Token {
pub fn partial_eq(&self, other: Token) -> bool {
self.to_simple() == other.to_simple()
}
pub fn simple_eq(&self, str_token: &str) -> bool {
self.to_simple() == str_token
}
#[cfg_attr(tarpaulin, skip)]
fn to_simple(&self) -> &'static str {
pub fn is_match_token_type(&self, other: Token) -> bool {
match self {
Token::Absolute(_) => ABSOLUTE,
Token::Dot(_) => DOT,
Token::At(_) => AT,
Token::OpenArray(_) => OPEN_ARRAY,
Token::CloseArray(_) => CLOSE_ARRAY,
Token::Asterisk(_) => ASTERISK,
Token::Question(_) => QUESTION,
Token::Comma(_) => COMMA,
Token::Split(_) => SPLIT,
Token::OpenParenthesis(_) => OPEN_PARENTHESIS,
Token::CloseParenthesis(_) => CLOSE_PARENTHESIS,
Token::Key(_, _) => KEY,
Token::DoubleQuoted(_, _) => DOUBLE_QUOTE,
Token::SingleQuoted(_, _) => SINGLE_QUOTE,
Token::Equal(_) => EQUAL,
Token::GreaterOrEqual(_) => GREATER_OR_EQUAL,
Token::Greater(_) => GREATER,
Token::Little(_) => LITTLE,
Token::LittleOrEqual(_) => LITTLE_OR_EQUAL,
Token::NotEqual(_) => NOT_EQUAL,
Token::And(_) => AND,
Token::Or(_) => OR,
Token::Whitespace(_, _) => WHITESPACE,
Token::Absolute(_) => match other {
Token::Absolute(_) => true,
_ => false
},
Token::Dot(_) => match other {
Token::Dot(_) => true,
_ => false
},
Token::At(_) => match other {
Token::At(_) => true,
_ => false
},
Token::OpenArray(_) => match other {
Token::OpenArray(_) => true,
_ => false
},
Token::CloseArray(_) => match other {
Token::CloseArray(_) => true,
_ => false
},
Token::Asterisk(_) => match other {
Token::Asterisk(_) => true,
_ => false
},
Token::Question(_) => match other {
Token::Question(_) => true,
_ => false
},
Token::Comma(_) => match other {
Token::Comma(_) => true,
_ => false
},
Token::Split(_) => match other {
Token::Split(_) => true,
_ => false
},
Token::OpenParenthesis(_) => match other {
Token::OpenParenthesis(_) => true,
_ => false
},
Token::CloseParenthesis(_) => match other {
Token::CloseParenthesis(_) => true,
_ => false
},
Token::Key(_, _) => match other {
Token::Key(_, _) => true,
_ => false
},
Token::DoubleQuoted(_, _) => match other {
Token::DoubleQuoted(_, _) => true,
_ => false
},
Token::SingleQuoted(_, _) => match other {
Token::SingleQuoted(_, _) => true,
_ => false
},
Token::Equal(_) => match other {
Token::Equal(_) => true,
_ => false
},
Token::GreaterOrEqual(_) => match other {
Token::GreaterOrEqual(_) => true,
_ => false
},
Token::Greater(_) => match other {
Token::Greater(_) => true,
_ => false
},
Token::Little(_) => match other {
Token::Little(_) => true,
_ => false
},
Token::LittleOrEqual(_) => match other {
Token::LittleOrEqual(_) => true,
_ => false
},
Token::NotEqual(_) => match other {
Token::NotEqual(_) => true,
_ => false
},
Token::And(_) => match other {
Token::And(_) => true,
_ => false
},
Token::Or(_) => match other {
Token::Or(_) => true,
_ => false
},
Token::Whitespace(_, _) => match other {
Token::Whitespace(_, _) => true,
_ => false
},
}
}
}
fn simple_matched_token(ch: char, pos: usize) -> Option<Token> {
match ch {
CH_DOLLA => Some(Token::Absolute(pos)),
CH_DOT => Some(Token::Dot(pos)),
CH_ASTERISK => Some(Token::Asterisk(pos)),
CH_LARRAY => Some(Token::OpenArray(pos)),
CH_RARRAY => Some(Token::CloseArray(pos)),
CH_LPAREN => Some(Token::OpenParenthesis(pos)),
CH_RPAREN => Some(Token::CloseParenthesis(pos)),
CH_AT => Some(Token::At(pos)),
CH_QUESTION => Some(Token::Question(pos)),
CH_COMMA => Some(Token::Comma(pos)),
CH_SEMICOLON => Some(Token::Split(pos)),
_ => None,
}
}
pub struct Tokenizer<'a> {
input: PathReader<'a>,
}
@ -153,6 +172,37 @@ impl<'a> Tokenizer<'a> {
}
}
fn dolla(&mut self, pos: usize, ch: char) -> Result<Token, TokenError> {
let fun = |c: &char| match c {
&CH_DOT
| &CH_ASTERISK
| &CH_LARRAY
| &CH_RARRAY
| &CH_LPAREN
| &CH_RPAREN
| &CH_AT
| &CH_QUESTION
| &CH_COMMA
| &CH_SEMICOLON
| &CH_LITTLE
| &CH_GREATER
| &CH_EQUAL
| &CH_AMPERSAND
| &CH_PIPE
| &CH_EXCLAMATION
=> false,
_ => !c.is_whitespace(),
};
let (_, mut vec) = self.input.take_while(fun).map_err(to_token_error)?;
vec.insert(0, ch);
if vec.len() == 1 {
Ok(Token::Absolute(pos))
} else {
Ok(Token::Key(pos, vec))
}
}
fn quote(&mut self, ch: char) -> Result<String, TokenError> {
let (_, mut val) = self
.input
@ -261,17 +311,25 @@ impl<'a> Tokenizer<'a> {
}
fn other(&mut self, pos: usize, ch: char) -> Result<Token, TokenError> {
let fun = |c: &char| match simple_matched_token(*c, pos) {
Some(_) => false,
_ if c == &CH_LITTLE
|| c == &CH_GREATER
|| c == &CH_EQUAL
|| c == &CH_AMPERSAND
|| c == &CH_PIPE
|| c == &CH_EXCLAMATION =>
{
false
}
let fun = |c: &char| match c {
&CH_DOLLA
| &CH_DOT
| &CH_ASTERISK
| &CH_LARRAY
| &CH_RARRAY
| &CH_LPAREN
| &CH_RPAREN
| &CH_AT
| &CH_QUESTION
| &CH_COMMA
| &CH_SEMICOLON
| &CH_LITTLE
| &CH_GREATER
| &CH_EQUAL
| &CH_AMPERSAND
| &CH_PIPE
| &CH_EXCLAMATION
=> false,
_ => !c.is_whitespace(),
};
let (_, mut vec) = self.input.take_while(fun).map_err(to_token_error)?;
@ -281,20 +339,28 @@ impl<'a> Tokenizer<'a> {
pub fn next_token(&mut self) -> Result<Token, TokenError> {
let (pos, ch) = self.input.next_char().map_err(to_token_error)?;
match simple_matched_token(ch, pos) {
Some(t) => Ok(t),
None => match ch {
CH_SINGLE_QUOTE => self.single_quote(pos, ch),
CH_DOUBLE_QUOTE => self.double_quote(pos, ch),
CH_EQUAL => self.equal(pos, ch),
CH_GREATER => self.greater(pos, ch),
CH_LITTLE => self.little(pos, ch),
CH_AMPERSAND => self.and(pos, ch),
CH_PIPE => self.or(pos, ch),
CH_EXCLAMATION => self.not_equal(pos, ch),
_ if ch.is_whitespace() => self.whitespace(pos, ch),
_ => self.other(pos, ch),
},
match ch {
CH_DOLLA => self.dolla(pos, ch),
CH_DOT => Ok(Token::Dot(pos)),
CH_ASTERISK => Ok(Token::Asterisk(pos)),
CH_LARRAY => Ok(Token::OpenArray(pos)),
CH_RARRAY => Ok(Token::CloseArray(pos)),
CH_LPAREN => Ok(Token::OpenParenthesis(pos)),
CH_RPAREN => Ok(Token::CloseParenthesis(pos)),
CH_AT => Ok(Token::At(pos)),
CH_QUESTION => Ok(Token::Question(pos)),
CH_COMMA => Ok(Token::Comma(pos)),
CH_SEMICOLON => Ok(Token::Split(pos)),
CH_SINGLE_QUOTE => self.single_quote(pos, ch),
CH_DOUBLE_QUOTE => self.double_quote(pos, ch),
CH_EQUAL => self.equal(pos, ch),
CH_GREATER => self.greater(pos, ch),
CH_LITTLE => self.little(pos, ch),
CH_AMPERSAND => self.and(pos, ch),
CH_PIPE => self.or(pos, ch),
CH_EXCLAMATION => self.not_equal(pos, ch),
_ if ch.is_whitespace() => self.whitespace(pos, ch),
_ => self.other(pos, ch),
}
}
@ -333,13 +399,6 @@ impl<'a> TokenReader<'a> {
}
}
pub fn peek_is(&self, simple_token: &str) -> bool {
match self.peek_token() {
Ok(t) => t.simple_eq(simple_token),
_ => false,
}
}
pub fn peek_token(&self) -> Result<&Token, TokenError> {
match self.tokens.last() {
Some((_, t)) => {

335
src/select/cmp.rs Normal file
View File

@ -0,0 +1,335 @@
use array_tool::vec::{Intersect, Union};
use serde_json::Value;
pub(super) trait Cmp {
fn cmp_bool(&self, v1: bool, v2: bool) -> bool;
fn cmp_f64(&self, v1: f64, v2: f64) -> bool;
fn cmp_string(&self, v1: &str, v2: &str) -> bool;
fn cmp_json<'a>(&self, v1: &[&'a Value], v2: &[&'a Value]) -> Vec<&'a Value>;
fn default(&self) -> bool {
false
}
}
pub(super) struct CmpEq;
impl Cmp for CmpEq {
fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
v1 == v2
}
fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
(v1 - v2).abs() == 0_f64
}
fn cmp_string(&self, v1: &str, v2: &str) -> bool {
v1 == v2
}
fn cmp_json<'a>(&self, v1: &[&'a Value], v2: &[&'a Value]) -> Vec<&'a Value> {
v1.to_vec().intersect(v2.to_vec())
}
}
pub(super) struct CmpNe;
impl Cmp for CmpNe {
fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
v1 != v2
}
fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
(v1 - v2).abs() != 0_f64
}
fn cmp_string(&self, v1: &str, v2: &str) -> bool {
v1 != v2
}
fn cmp_json<'a>(&self, v1: &[&'a Value], v2: &[&'a Value]) -> Vec<&'a Value> {
v1.to_vec().intersect_if(v2.to_vec(), |a, b| a != b)
}
}
pub(super) struct CmpGt;
impl Cmp for CmpGt {
fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
v1 & !v2
}
fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
v1 > v2
}
fn cmp_string(&self, v1: &str, v2: &str) -> bool {
v1 > v2
}
fn cmp_json<'a>(&self, _: &[&'a Value], _: &[&'a Value]) -> Vec<&'a Value> {
Vec::new()
}
}
pub(super) struct CmpGe;
impl Cmp for CmpGe {
fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
v1 >= v2
}
fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
v1 >= v2
}
fn cmp_string(&self, v1: &str, v2: &str) -> bool {
v1 >= v2
}
fn cmp_json<'a>(&self, _: &[&'a Value], _: &[&'a Value]) -> Vec<&'a Value> {
Vec::new()
}
}
pub(super) struct CmpLt;
impl Cmp for CmpLt {
fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
!v1 & v2
}
fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
v1 < v2
}
fn cmp_string(&self, v1: &str, v2: &str) -> bool {
v1 < v2
}
fn cmp_json<'a>(&self, _: &[&'a Value], _: &[&'a Value]) -> Vec<&'a Value> {
Vec::new()
}
}
pub(super) struct CmpLe;
impl Cmp for CmpLe {
fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
v1 <= v2
}
fn cmp_f64(&self, v1: f64, v2: f64) -> bool {
v1 <= v2
}
fn cmp_string(&self, v1: &str, v2: &str) -> bool {
v1 <= v2
}
fn cmp_json<'a>(&self, _: &[&'a Value], _: &[&'a Value]) -> Vec<&'a Value> {
Vec::new()
}
}
pub(super) struct CmpAnd;
impl Cmp for CmpAnd {
fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
v1 && v2
}
fn cmp_f64(&self, _v1: f64, _v2: f64) -> bool {
true
}
fn cmp_string(&self, v1: &str, v2: &str) -> bool {
!v1.is_empty() && !v2.is_empty()
}
fn cmp_json<'a>(&self, v1: &[&'a Value], v2: &[&'a Value]) -> Vec<&'a Value> {
v1.to_vec().intersect(v2.to_vec())
}
}
pub(super) struct CmpOr;
impl Cmp for CmpOr {
fn cmp_bool(&self, v1: bool, v2: bool) -> bool {
v1 || v2
}
fn cmp_f64(&self, _v1: f64, _v2: f64) -> bool {
true
}
fn cmp_string(&self, v1: &str, v2: &str) -> bool {
!v1.is_empty() || !v2.is_empty()
}
fn cmp_json<'a>(&self, v1: &[&'a Value], v2: &[&'a Value]) -> Vec<&'a Value> {
v1.to_vec().union(v2.to_vec())
}
}
#[cfg(test)]
mod cmp_inner_tests {
use serde_json::Value;
use select::cmp::*;
#[test]
fn cmp_eq() {
let cmp_fn = CmpEq;
assert_eq!(cmp_fn.default(), false);
assert_eq!(cmp_fn.cmp_bool(true, false), false);
assert_eq!(cmp_fn.cmp_bool(true, true), true);
assert_eq!(cmp_fn.cmp_f64(0.1, 0.1), true);
assert_eq!(cmp_fn.cmp_f64(0.1, 0.2), false);
assert_eq!(cmp_fn.cmp_string("1", "1"), true);
assert_eq!(cmp_fn.cmp_string("1", "2"), false);
}
#[test]
fn cmp_ne() {
let cmp_fn = CmpNe;
assert_eq!(cmp_fn.default(), false);
assert_eq!(cmp_fn.cmp_bool(true, false), true);
assert_eq!(cmp_fn.cmp_bool(true, true), false);
assert_eq!(cmp_fn.cmp_f64(0.1, 0.1), false);
assert_eq!(cmp_fn.cmp_f64(0.1, 0.2), true);
assert_eq!(cmp_fn.cmp_string("1", "1"), false);
assert_eq!(cmp_fn.cmp_string("1", "2"), true);
}
#[test]
fn cmp_gt() {
let cmp_fn = CmpGt;
assert_eq!(cmp_fn.default(), false);
assert_eq!(cmp_fn.cmp_bool(true, false), true);
assert_eq!(cmp_fn.cmp_bool(true, true), false);
assert_eq!(cmp_fn.cmp_f64(0.2, 0.1), true);
assert_eq!(cmp_fn.cmp_f64(0.1, 0.2), false);
assert_eq!(cmp_fn.cmp_string("a", "a"), false);
assert_eq!(cmp_fn.cmp_string("b", "a"), true);
assert_eq!(cmp_fn.cmp_string("1", "2"), false);
}
#[test]
fn cmp_ge() {
let cmp_fn = CmpGe;
assert_eq!(cmp_fn.default(), false);
assert_eq!(cmp_fn.cmp_bool(true, false), true);
assert_eq!(cmp_fn.cmp_bool(true, true), true);
assert_eq!(cmp_fn.cmp_f64(0.2, 0.1), true);
assert_eq!(cmp_fn.cmp_f64(0.1, 0.1), true);
assert_eq!(cmp_fn.cmp_f64(0.1, 0.2), false);
assert_eq!(cmp_fn.cmp_string("1", "1"), true);
assert_eq!(cmp_fn.cmp_string("ab", "a"), true);
assert_eq!(cmp_fn.cmp_string("1", "2"), false);
}
#[test]
fn cmp_lt() {
let cmp_fn = CmpLt;
assert_eq!(cmp_fn.default(), false);
assert_eq!(cmp_fn.cmp_bool(true, false), false);
assert_eq!(cmp_fn.cmp_bool(false, true), true);
assert_eq!(cmp_fn.cmp_bool(true, true), false);
assert_eq!(cmp_fn.cmp_bool(false, false), false);
assert_eq!(cmp_fn.cmp_f64(0.1, 0.2), true);
assert_eq!(cmp_fn.cmp_f64(0.1, 0.1), false);
assert_eq!(cmp_fn.cmp_f64(0.2, 0.1), false);
assert_eq!(cmp_fn.cmp_string("a", "a"), false);
assert_eq!(cmp_fn.cmp_string("ab", "b"), true);
assert_eq!(cmp_fn.cmp_string("1", "2"), true);
}
#[test]
fn cmp_le() {
let cmp_fn = CmpLe;
assert_eq!(cmp_fn.default(), false);
assert_eq!(cmp_fn.cmp_bool(true, false), false);
assert_eq!(cmp_fn.cmp_bool(false, true), true);
assert_eq!(cmp_fn.cmp_bool(true, true), true);
assert_eq!(cmp_fn.cmp_bool(false, false), true);
assert_eq!(cmp_fn.cmp_f64(0.1, 0.2), true);
assert_eq!(cmp_fn.cmp_f64(0.1, 0.1), true);
assert_eq!(cmp_fn.cmp_f64(0.2, 0.1), false);
assert_eq!(cmp_fn.cmp_string("a", "a"), true);
assert_eq!(cmp_fn.cmp_string("ab", "b"), true);
assert_eq!(cmp_fn.cmp_string("abd", "abc"), false);
assert_eq!(cmp_fn.cmp_string("1", "2"), true);
}
#[test]
fn cmp_and() {
let cmp_fn = CmpAnd;
assert_eq!(cmp_fn.default(), false);
assert_eq!(cmp_fn.cmp_bool(true, false), false);
assert_eq!(cmp_fn.cmp_bool(false, true), false);
assert_eq!(cmp_fn.cmp_bool(true, true), true);
assert_eq!(cmp_fn.cmp_bool(false, false), false);
assert_eq!(cmp_fn.cmp_f64(0.0, 0.0), true);
assert_eq!(cmp_fn.cmp_string("a", "a"), true);
}
#[test]
fn cmp_or() {
let cmp_fn = CmpOr;
assert_eq!(cmp_fn.default(), false);
assert_eq!(cmp_fn.cmp_bool(true, false), true);
assert_eq!(cmp_fn.cmp_bool(false, true), true);
assert_eq!(cmp_fn.cmp_bool(true, true), true);
assert_eq!(cmp_fn.cmp_bool(false, false), false);
assert_eq!(cmp_fn.cmp_f64(0.0, 0.0), true);
assert_eq!(cmp_fn.cmp_string("a", "a"), true);
}
#[test]
fn cmp_json() {
let v1 = Value::Bool(true);
let v2 = Value::String("1".to_string());
let left = [&v1, &v2];
let right = [&v1, &v2];
let empty: Vec<&Value> = Vec::new();
assert_eq!(CmpEq.cmp_json(&left, &right), left.to_vec());
assert_eq!(CmpNe.cmp_json(&left, &right), left.to_vec());
assert_eq!(CmpGt.cmp_json(&left, &right), empty);
assert_eq!(CmpGe.cmp_json(&left, &right), empty);
assert_eq!(CmpLt.cmp_json(&left, &right), empty);
assert_eq!(CmpLe.cmp_json(&left, &right), empty);
assert_eq!(CmpAnd.cmp_json(&left, &right), left.to_vec());
assert_eq!(CmpOr.cmp_json(&left, &right), left.to_vec());
assert_eq!(
CmpEq.cmp_json(&[&Value::Bool(true)], &[&Value::Bool(true)]),
vec![&Value::Bool(true)]
);
assert_eq!(
CmpEq.cmp_json(&[&Value::Bool(true)], &[&Value::Bool(false)]),
empty
);
assert_eq!(
CmpNe.cmp_json(&[&Value::Bool(true)], &[&Value::Bool(true)]),
empty
);
assert_eq!(
CmpNe.cmp_json(&[&Value::Bool(false)], &[&Value::Bool(true)]),
vec![&Value::Bool(false)]
);
assert_eq!(
CmpAnd.cmp_json(&[&Value::Bool(true)], &[&Value::Bool(true)]),
vec![&Value::Bool(true)]
);
assert_eq!(
CmpOr.cmp_json(&[&Value::Bool(true)], &[&Value::Bool(false)]),
vec![&Value::Bool(true), &Value::Bool(false)]
);
}
}

227
src/select/expr_term.rs Normal file
View File

@ -0,0 +1,227 @@
use serde_json::{Number, Value};
use select::cmp::*;
use select::{FilterKey, to_f64};
#[derive(Debug, PartialEq)]
pub(super) enum ExprTerm<'a> {
String(String),
Number(Number),
Bool(bool),
Json(Option<Vec<&'a Value>>, Option<FilterKey>, Vec<&'a Value>),
}
impl<'a> ExprTerm<'a> {
fn cmp<C1: Cmp, C2: Cmp>(
&self,
other: &Self,
cmp_fn: &C1,
reverse_cmp_fn: &C2,
) -> ExprTerm<'a> {
match &self {
ExprTerm::String(s1) => match &other {
ExprTerm::String(s2) => ExprTerm::Bool(cmp_fn.cmp_string(s1, s2)),
ExprTerm::Json(_, _, _) => other.cmp(&self, reverse_cmp_fn, cmp_fn),
_ => ExprTerm::Bool(cmp_fn.default()),
},
ExprTerm::Number(n1) => match &other {
ExprTerm::Number(n2) => ExprTerm::Bool(cmp_fn.cmp_f64(to_f64(n1), to_f64(n2))),
ExprTerm::Json(_, _, _) => other.cmp(&self, reverse_cmp_fn, cmp_fn),
_ => ExprTerm::Bool(cmp_fn.default()),
},
ExprTerm::Bool(b1) => match &other {
ExprTerm::Bool(b2) => ExprTerm::Bool(cmp_fn.cmp_bool(*b1, *b2)),
ExprTerm::Json(_, _, _) => other.cmp(&self, reverse_cmp_fn, cmp_fn),
_ => ExprTerm::Bool(cmp_fn.default()),
},
ExprTerm::Json(rel, fk1, vec1) => {
let ret: Vec<&Value> = match &other {
ExprTerm::String(s2) => vec1
.iter()
.filter(|v1| match v1 {
Value::String(s1) => cmp_fn.cmp_string(s1, s2),
Value::Object(map1) => {
if let Some(FilterKey::String(k)) = fk1 {
if let Some(Value::String(s1)) = map1.get(k) {
return cmp_fn.cmp_string(s1, s2);
}
}
cmp_fn.default()
}
_ => cmp_fn.default(),
})
.cloned()
.collect(),
ExprTerm::Number(n2) => vec1
.iter()
.filter(|v1| match v1 {
Value::Number(n1) => cmp_fn.cmp_f64(to_f64(n1), to_f64(n2)),
Value::Object(map1) => {
if let Some(FilterKey::String(k)) = fk1 {
if let Some(Value::Number(n1)) = map1.get(k) {
return cmp_fn.cmp_f64(to_f64(n1), to_f64(n2));
}
}
cmp_fn.default()
}
_ => cmp_fn.default(),
})
.cloned()
.collect(),
ExprTerm::Bool(b2) => vec1
.iter()
.filter(|v1| match v1 {
Value::Bool(b1) => cmp_fn.cmp_bool(*b1, *b2),
Value::Object(map1) => {
if let Some(FilterKey::String(k)) = fk1 {
if let Some(Value::Bool(b1)) = map1.get(k) {
return cmp_fn.cmp_bool(*b1, *b2);
}
}
cmp_fn.default()
}
_ => cmp_fn.default(),
})
.cloned()
.collect(),
ExprTerm::Json(parent, _, vec2) => {
if let Some(vec1) = rel {
cmp_fn.cmp_json(vec1, vec2)
} else if let Some(vec2) = parent {
cmp_fn.cmp_json(vec1, vec2)
} else {
cmp_fn.cmp_json(vec1, vec2)
}
}
};
if ret.is_empty() {
ExprTerm::Bool(cmp_fn.default())
} else if let Some(rel) = rel {
if let ExprTerm::Json(_, _, _) = &other {
ExprTerm::Json(Some(rel.to_vec()), None, ret)
} else {
let mut tmp = Vec::new();
for rel_value in rel {
if let Value::Object(map) = rel_value {
for map_value in map.values() {
for result_value in &ret {
if map_value.eq(*result_value) {
tmp.push(*rel_value);
}
}
}
}
}
ExprTerm::Json(Some(tmp), None, ret)
}
} else {
ExprTerm::Json(None, None, ret)
}
}
}
}
pub fn eq(&self, other: &Self, ret: &mut Option<ExprTerm<'a>>) {
debug!("eq - {:?} : {:?}", &self, &other);
let _ = ret.take();
let tmp = self.cmp(other, &CmpEq, &CmpEq);
debug!("eq = {:?}", tmp);
*ret = Some(tmp);
}
pub fn ne(&self, other: &Self, ret: &mut Option<ExprTerm<'a>>) {
debug!("ne - {:?} : {:?}", &self, &other);
let _ = ret.take();
let tmp = self.cmp(other, &CmpNe, &CmpNe);
debug!("ne = {:?}", tmp);
*ret = Some(tmp);
}
pub fn gt(&self, other: &Self, ret: &mut Option<ExprTerm<'a>>) {
debug!("gt - {:?} : {:?}", &self, &other);
let _ = ret.take();
let tmp = self.cmp(other, &CmpGt, &CmpLt);
debug!("gt = {:?}", tmp);
*ret = Some(tmp);
}
pub fn ge(&self, other: &Self, ret: &mut Option<ExprTerm<'a>>) {
debug!("ge - {:?} : {:?}", &self, &other);
let _ = ret.take();
let tmp = self.cmp(other, &CmpGe, &CmpLe);
debug!("ge = {:?}", tmp);
*ret = Some(tmp);
}
pub fn lt(&self, other: &Self, ret: &mut Option<ExprTerm<'a>>) {
debug!("lt - {:?} : {:?}", &self, &other);
let _ = ret.take();
let tmp = self.cmp(other, &CmpLt, &CmpGt);
debug!("lt = {:?}", tmp);
*ret = Some(tmp);
}
pub fn le(&self, other: &Self, ret: &mut Option<ExprTerm<'a>>) {
debug!("le - {:?} : {:?}", &self, &other);
let _ = ret.take();
let tmp = self.cmp(other, &CmpLe, &CmpGe);
debug!("le = {:?}", tmp);
*ret = Some(tmp);
}
pub fn and(&self, other: &Self, ret: &mut Option<ExprTerm<'a>>) {
debug!("and - {:?} : {:?}", &self, &other);
let _ = ret.take();
let tmp = self.cmp(other, &CmpAnd, &CmpAnd);
debug!("and = {:?}", tmp);
*ret = Some(tmp);
}
pub fn or(&self, other: &Self, ret: &mut Option<ExprTerm<'a>>) {
debug!("or - {:?} : {:?}", &self, &other);
let _ = ret.take();
let tmp = self.cmp(other, &CmpOr, &CmpOr);
debug!("or = {:?}", tmp);
*ret = Some(tmp);
}
}
impl<'a> Into<ExprTerm<'a>> for &Vec<&'a Value> {
fn into(self) -> ExprTerm<'a> {
if self.len() == 1 {
match &self[0] {
Value::Number(v) => return ExprTerm::Number(v.clone()),
Value::String(v) => return ExprTerm::String(v.clone()),
Value::Bool(v) => return ExprTerm::Bool(*v),
_ => {}
}
}
ExprTerm::Json(None, None, self.to_vec())
}
}
#[cfg(test)]
mod expr_term_inner_tests {
use serde_json::{Number, Value};
use select::expr_term::ExprTerm;
#[test]
fn value_vec_into() {
let v = Value::Bool(true);
let vec = &vec![&v];
let term: ExprTerm = vec.into();
assert_eq!(term, ExprTerm::Bool(true));
let v = Value::String("a".to_string());
let vec = &vec![&v];
let term: ExprTerm = vec.into();
assert_eq!(term, ExprTerm::String("a".to_string()));
let v = serde_json::from_str("1.0").unwrap();
let vec = &vec![&v];
let term: ExprTerm = vec.into();
assert_eq!(term, ExprTerm::Number(Number::from_f64(1.0).unwrap()));
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,99 @@
use serde_json::Value;
use std::collections::HashSet;
pub(super) struct ValueWalker;
impl<'a> ValueWalker {
pub fn all_with_num(vec: &[&'a Value], tmp: &mut Vec<&'a Value>, index: f64) {
Self::walk(vec, tmp, &|v| if v.is_array() {
if let Some(item) = v.get(index as usize) {
Some(vec![item])
} else {
None
}
} else {
None
});
}
pub fn all_with_str(vec: &[&'a Value], tmp: &mut Vec<&'a Value>, key: &str, is_filter: bool) {
if is_filter {
Self::walk(vec, tmp, &|v| match v {
Value::Object(map) if map.contains_key(key) => Some(vec![v]),
_ => None,
});
} else {
Self::walk(vec, tmp, &|v| match v {
Value::Object(map) => match map.get(key) {
Some(v) => Some(vec![v]),
_ => None,
},
_ => None,
});
}
}
pub fn all(vec: &[&'a Value], tmp: &mut Vec<&'a Value>) {
Self::walk(vec, tmp, &|v| match v {
Value::Array(vec) => Some(vec.iter().collect()),
Value::Object(map) => {
let mut tmp = Vec::new();
for (_, v) in map {
tmp.push(v);
}
Some(tmp)
}
_ => None,
});
}
fn walk<F>(vec: &[&'a Value], tmp: &mut Vec<&'a Value>, fun: &F) where F: Fn(&Value) -> Option<Vec<&Value>> {
for v in vec {
Self::_walk(v, tmp, fun);
}
}
fn _walk<F>(v: &'a Value, tmp: &mut Vec<&'a Value>, fun: &F) where F: Fn(&Value) -> Option<Vec<&Value>> {
if let Some(mut ret) = fun(v) {
tmp.append(&mut ret);
}
match v {
Value::Array(vec) => {
for v in vec {
Self::_walk(v, tmp, fun);
}
}
Value::Object(map) => {
for (_, v) in map {
Self::_walk(&v, tmp, fun);
}
}
_ => {}
}
}
pub fn walk_dedup(v: &'a Value,
tmp: &mut Vec<&'a Value>,
key: &str,
visited: &mut HashSet<*const Value>, ) {
match v {
Value::Object(map) => {
if map.contains_key(key) {
let ptr = v as *const Value;
if !visited.contains(&ptr) {
visited.insert(ptr);
tmp.push(v)
}
}
}
Value::Array(vec) => {
for v in vec {
Self::walk_dedup(v, tmp, key, visited);
}
}
_ => {}
}
}
}

253
tests/array_filter.rs Normal file
View File

@ -0,0 +1,253 @@
#[macro_use]
extern crate serde_json;
use common::{read_json, select_and_then_compare, setup};
mod common;
#[test]
fn array_range_default() {
setup();
select_and_then_compare(
"$.school.friends[1, 2]",
read_json("./benchmark/data_obj.json"),
json!([
{"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"}
]),
);
}
#[test]
fn array_range_all() {
setup();
select_and_then_compare(
"$[ : ]",
json!(["first", "second"]),
json!(["first", "second"]),
);
}
#[test]
fn array_range_step_all() {
setup();
select_and_then_compare(
"$[::]",
json!(["first", "second", "third", "forth", "fifth"]),
json!(["first", "second", "third", "forth", "fifth"]),
);
}
#[test]
fn array_range_step_only_step_value() {
setup();
select_and_then_compare(
"$[::2]",
json!(["first", "second", "third", "forth", "fifth"]),
json!(["first", "third", "fifth"]),
);
}
#[test]
fn array_range_step_only_start_index() {
setup();
select_and_then_compare(
"$[1::]",
json!(["first", "second", "third", "forth", "fifth"]),
json!(["second", "third", "forth", "fifth"]),
);
}
#[test]
fn array_range_step_empty_step_value() {
setup();
select_and_then_compare(
"$[1:2:]",
json!(["first", "second", "third", "forth", "fifth"]),
json!(["second"]),
);
}
#[test]
fn array_range_step_empty_end_index() {
setup();
select_and_then_compare(
"$[1::2]",
json!(["first", "second", "third", "forth", "fifth"]),
json!(["second", "forth"]),
);
}
#[test]
fn array_range_step_by_1() {
setup();
select_and_then_compare(
"$[0:3:1]",
json!(["first", "second", "third", "forth", "fifth"]),
json!(["first", "second", "third"]),
);
}
#[test]
fn array_range_step_by_2() {
setup();
select_and_then_compare(
"$[0:3:2]",
json!(["first", "second", "third", "forth", "fifth"]),
json!(["first", "third"]),
);
}
#[test]
fn array_range_only_negative_index() {
setup();
select_and_then_compare(
"$[-4:]",
json!(["first", "second", "third"]),
json!(["first", "second", "third"]),
);
}
#[test]
fn array_range_only_end_index() {
setup();
select_and_then_compare(
"$[:4]",
json!(["first", "second", "third"]),
json!(["first", "second", "third"]),
);
}
#[test]
fn array_range_only_from_index() {
setup();
select_and_then_compare(
"$.school.friends[1: ]",
read_json("./benchmark/data_obj.json"),
json!([
{"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"}
]),
);
}
#[test]
fn array_range_only_nagative_end_index() {
setup();
select_and_then_compare(
"$.school.friends[:-2]",
read_json("./benchmark/data_obj.json"),
json!([
{"id": 0, "name": "Millicent Norman"}
]),
);
}
#[test]
fn array_index() {
setup();
select_and_then_compare(
"$..friends[2].name",
read_json("./benchmark/data_obj.json"),
json!(["Gray Berry", "Gray Berry"]),
);
}
#[test]
fn array_all_index() {
setup();
select_and_then_compare(
"$..friends[*].name",
read_json("./benchmark/data_obj.json"),
json!([
"Vincent Cannon",
"Gray Berry",
"Millicent Norman",
"Vincent Cannon",
"Gray Berry"
]),
);
}
#[test]
fn array_all_and_then_key() {
setup();
select_and_then_compare(
"$['school']['friends'][*].['name']",
read_json("./benchmark/data_obj.json"),
json!(["Millicent Norman", "Vincent Cannon", "Gray Berry"]),
);
}
#[test]
fn array_index_and_then_key() {
setup();
select_and_then_compare(
"$['school']['friends'][0].['name']",
read_json("./benchmark/data_obj.json"),
json!(["Millicent Norman"]),
);
}
#[test]
fn array_multiple_key() {
setup();
select_and_then_compare(
r#"$.["eyeColor", "name"]"#,
read_json("./benchmark/data_obj.json"),
json!(["blue", "Leonor Herman"]),
);
}
#[test]
fn bugs40_bracket_notation_after_recursive_descent() {
setup();
select_and_then_compare(
"$..[0]",
json!([
"first",
{
"key": [
"first nested",
{
"more": [
{"nested": ["deepest", "second"]},
["more", "values"]
]
}
]
}
]),
json!([
"first",
"first nested",
{
"nested" : [
"deepest",
"second"
]
},
"deepest",
"more"
]),
);
}

View File

@ -1,609 +1,10 @@
#[macro_use]
extern crate serde_json;
use serde_json::Value;
use common::{read_json, select_and_then_compare, setup};
mod common;
#[test]
fn array() {
setup();
select_and_then_compare(
"$.school.friends[1, 2]",
read_json("./benchmark/data_obj.json"),
json!([
{"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"}
]),
);
select_and_then_compare(
"$.school.friends[1: ]",
read_json("./benchmark/data_obj.json"),
json!([
{"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"}
]),
);
select_and_then_compare(
"$.school.friends[:-2]",
read_json("./benchmark/data_obj.json"),
json!([
{"id": 0, "name": "Millicent Norman"}
]),
);
select_and_then_compare(
"$..friends[2].name",
read_json("./benchmark/data_obj.json"),
json!(["Gray Berry", "Gray Berry"]),
);
select_and_then_compare(
"$..friends[*].name",
read_json("./benchmark/data_obj.json"),
json!([
"Vincent Cannon",
"Gray Berry",
"Millicent Norman",
"Vincent Cannon",
"Gray Berry"
]),
);
select_and_then_compare(
"$['school']['friends'][*].['name']",
read_json("./benchmark/data_obj.json"),
json!(["Millicent Norman", "Vincent Cannon", "Gray Berry"]),
);
select_and_then_compare(
"$['school']['friends'][0].['name']",
read_json("./benchmark/data_obj.json"),
json!(["Millicent Norman"]),
);
select_and_then_compare(
r#"$.["eyeColor", "name"]"#,
read_json("./benchmark/data_obj.json"),
json!(["blue", "Leonor Herman"]),
);
}
#[test]
fn return_type() {
setup();
select_and_then_compare(
"$.school",
read_json("./benchmark/data_obj.json"),
json!([{
"friends": [
{"id": 0, "name": "Millicent Norman"},
{"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"}
]
}]),
);
select_and_then_compare(
"$.school[?(@.friends[0])]",
read_json("./benchmark/data_obj.json"),
json!([{
"friends": [
{"id": 0, "name": "Millicent Norman"},
{"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"}
]
}]),
);
select_and_then_compare(
"$.school[?(@.friends[10])]",
read_json("./benchmark/data_obj.json"),
json!([{
"friends": [
{"id": 0, "name": "Millicent Norman"},
{"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"}
]
}]),
);
select_and_then_compare(
"$.school[?(1==1)]",
read_json("./benchmark/data_obj.json"),
json!([{
"friends": [
{"id": 0, "name": "Millicent Norman"},
{"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"}
]
}]),
);
select_and_then_compare(
"$.school.friends[?(1==1)]",
read_json("./benchmark/data_obj.json"),
json!([[
{"id": 0, "name": "Millicent Norman"},
{"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"}
]]),
);
}
#[test]
fn op_default() {
setup();
// select_and_then_compare(
// "$.school[?(@.friends == @.friends)]",
// read_json("./benchmark/data_obj.json"),
// json!([{
// "friends": [
// {"id": 0, "name": "Millicent Norman"},
// {"id": 1, "name": "Vincent Cannon" },
// {"id": 2, "name": "Gray Berry"}
// ]
// }]),
// );
//
// select_and_then_compare(
// "$.friends[?(@.name)]",
// read_json("./benchmark/data_obj.json"),
// json!([
// { "id" : 1, "name" : "Vincent Cannon" },
// { "id" : 2, "name" : "Gray Berry" }
// ]),
// );
//
// select_and_then_compare(
// "$.friends[?(@.id >= 2)]",
// read_json("./benchmark/data_obj.json"),
// json!([
// { "id" : 2, "name" : "Gray Berry" }
// ]),
// );
//
// select_and_then_compare(
// "$.friends[?(@.id >= 2 || @.id == 1)]",
// read_json("./benchmark/data_obj.json"),
// json!([
// { "id" : 2, "name" : "Gray Berry" },
// { "id" : 1, "name" : "Vincent Cannon" }
// ]),
// );
//
// select_and_then_compare(
// "$.friends[?( (@.id >= 2 || @.id == 1) && @.id == 0)]",
// read_json("./benchmark/data_obj.json"),
// json!([Value::Null]),
// );
//
// select_and_then_compare(
// "$..friends[?(@.id == $.index)].id",
// read_json("./benchmark/data_obj.json"),
// json!([0, 0]),
// );
//
// select_and_then_compare(
// "$..book[?($.store.bicycle.price < @.price)].price",
// read_json("./benchmark/example.json"),
// json!([22.99]),
// );
//
// select_and_then_compare(
// "$..book[?( (@.price == 12.99 || @.category == 'reference') && @.price > 10)].price",
// read_json("./benchmark/example.json"),
// json!([12.99]),
// );
//
// select_and_then_compare(
// "$..[?(@.age > 40)]",
// json!([
// { "name": "이름1", "age": 40, "phone": "+33 12341234" },
// { "name": "이름2", "age": 42, "phone": "++44 12341234" }
// ]),
// json!([
// { "name" : "이름2", "age" : 42, "phone" : "++44 12341234" }
// ]),
// );
select_and_then_compare(
"$..[?(@.age >= 30)]",
json!({
"school": {
"friends": [
{"name": "친구1", "age": 20},
{"name": "친구2", "age": 20}
]
},
"friends": [
{"name": "친구3", "age": 30},
{"name": "친구4"}
]}),
json!([
{ "name" : "친구3", "age" : 30 }
]),
);
}
#[test]
fn op_number() {
setup();
select_and_then_compare("$.[?(@.a == 1)]", json!({ "a": 1 }), json!([{ "a": 1 }]));
select_and_then_compare("$.[?(@.a != 2)]", json!({ "a": 1 }), json!([{ "a": 1 }]));
select_and_then_compare("$.[?(@.a < 2)]", json!({ "a": 1 }), json!([{ "a": 1 }]));
select_and_then_compare("$.[?(@.a <= 1)]", json!({ "a": 1 }), json!([{ "a": 1 }]));
select_and_then_compare("$.[?(@.a > 0)]", json!({ "a": 1 }), json!([{ "a": 1 }]));
select_and_then_compare("$.[?(@.a >= 0)]", json!({ "a": 1 }), json!([{ "a": 1 }]));
}
#[test]
fn op_string() {
setup();
select_and_then_compare(
r#"$.[?(@.a == "b")]"#,
json!({ "a": "b" }),
json!([{ "a": "b" }]),
);
select_and_then_compare(
r#"$.[?(@.a != "c")]"#,
json!({ "a": "b" }),
json!([{ "a": "b" }]),
);
select_and_then_compare(
r#"$.[?(@.a < "b")]"#,
json!({ "a": "b" }),
json!([Value::Null]),
);
select_and_then_compare(
r#"$.[?(@.a <= "b")]"#,
json!({ "a": "b" }),
json!([{ "a": "b" }]),
);
select_and_then_compare(
r#"$.[?(@.a > "b")]"#,
json!({ "a": "b" }),
json!([Value::Null]),
);
select_and_then_compare(
r#"$.[?(@.a >= "b")]"#,
json!({ "a": "b" }),
json!([{ "a": "b" }]),
);
}
#[test]
fn op_object() {
setup();
select_and_then_compare(
r#"$.[?(@.a == @.c)]"#,
json!({"a": { "1": 1 }, "b": { "2": 2 }, "c": { "1": 1 }}),
json!([{"a": { "1": 1 }, "b": { "2": 2 }, "c": { "1": 1 }}]),
);
select_and_then_compare(
r#"$.[?(@.a != @.c)]"#,
json!({"a": { "1": 1 }, "b": { "2": 2 }, "c": { "1": 1 }}),
json!([Value::Null]),
);
select_and_then_compare(
r#"$.[?(@.a < @.c)]"#,
json!({"a": { "1": 1 }, "b": { "2": 2 }, "c": { "1": 1 }}),
json!([Value::Null]),
);
select_and_then_compare(
r#"$.[?(@.a <= @.c)]"#,
json!({"a": { "1": 1 }, "b": { "2": 2 }, "c": { "1": 1 }}),
json!([Value::Null]),
);
select_and_then_compare(
r#"$.[?(@.a > @.c)]"#,
json!({"a": { "1": 1 }, "b": { "2": 2 }, "c": { "1": 1 }}),
json!([Value::Null]),
);
select_and_then_compare(
r#"$.[?(@.a >= @.c)]"#,
json!({"a": { "1": 1 }, "b": { "2": 2 }, "c": { "1": 1 }}),
json!([Value::Null]),
);
}
#[test]
fn op_complex() {
setup();
select_and_then_compare(
r#"$.[?(1 == @.a)]"#,
json!({ "a": { "b": 1 } }),
json!([Value::Null]),
);
select_and_then_compare(
r#"$.[?("1" != @.a)]"#,
json!({ "a": { "b": 1 } }),
json!([Value::Null]),
);
select_and_then_compare(
r#"$.[?(@.a <= 1)]"#,
json!({ "a": { "b": 1 } }),
json!([Value::Null]),
);
select_and_then_compare(
r#"$.[?(@.a > "1")]"#,
json!({ "a": { "b": 1 } }),
json!([Value::Null]),
);
}
#[test]
fn op_compare() {
setup();
for path in [
r#"$[?("1" == 1)]"#,
r#"$[?(1 == "1")]"#,
r#"$[?(true == 1)]"#,
r#"$[?(@ == 1)]"#,
]
.iter()
{
select_and_then_compare(path, json!({}), json!([Value::Null]));
}
}
#[test]
fn example() {
setup();
select_and_then_compare(
r#"$.store.book[*].author"#,
read_json("./benchmark/example.json"),
json!([
"Nigel Rees",
"Evelyn Waugh",
"Herman Melville",
"J. R. R. Tolkien"
]),
);
select_and_then_compare(
r#"$..author"#,
read_json("./benchmark/example.json"),
json!([
"Nigel Rees",
"Evelyn Waugh",
"Herman Melville",
"J. R. R. Tolkien"
]),
);
select_and_then_compare(
r#"$.store.*"#,
read_json("./benchmark/example.json"),
json!([
[
{"category" : "reference", "author" : "Nigel Rees","title" : "Sayings of the Century", "price" : 8.95},
{"category" : "fiction", "author" : "Evelyn Waugh","title" : "Sword of Honour","price" : 12.99},
{"category" : "fiction", "author" : "Herman Melville","title" : "Moby Dick","isbn" : "0-553-21311-3","price" : 8.99},
{"category" : "fiction", "author" : "J. R. R. Tolkien","title" : "The Lord of the Rings","isbn" : "0-395-19395-8","price" : 22.99}
],
{"color" : "red","price" : 19.95},
]),
);
select_and_then_compare(
r#"$.store..price"#,
read_json("./benchmark/example.json"),
json!([8.95, 12.99, 8.99, 22.99, 19.95]),
);
select_and_then_compare(
r#"$..book[2]"#,
read_json("./benchmark/example.json"),
json!([
{
"category" : "fiction",
"author" : "Herman Melville",
"title" : "Moby Dick",
"isbn" : "0-553-21311-3",
"price" : 8.99
}
]),
);
select_and_then_compare(
r#"$..book[-2]"#,
read_json("./benchmark/example.json"),
json!([
{
"category" : "fiction",
"author" : "Herman Melville",
"title" : "Moby Dick",
"isbn" : "0-553-21311-3",
"price" : 8.99
}
]),
);
select_and_then_compare(
r#"$..book[0, 1]"#,
read_json("./benchmark/example.json"),
json!([
{
"category" : "reference",
"author" : "Nigel Rees",
"title" : "Sayings of the Century",
"price" : 8.95
},
{
"category" : "fiction",
"author" : "Evelyn Waugh",
"title" : "Sword of Honour",
"price" : 12.99
}
]),
);
select_and_then_compare(
r#"$..book[:2]"#,
read_json("./benchmark/example.json"),
json!([
{
"category" : "reference",
"author" : "Nigel Rees",
"title" : "Sayings of the Century",
"price" : 8.95
},
{
"category" : "fiction",
"author" : "Evelyn Waugh",
"title" : "Sword of Honour",
"price" : 12.99
}
]),
);
select_and_then_compare(
r#"$..book[2:]"#,
read_json("./benchmark/example.json"),
json!([
{
"category" : "fiction",
"author" : "Herman Melville",
"title" : "Moby Dick",
"isbn" : "0-553-21311-3",
"price" : 8.99
},
{
"category" : "fiction",
"author" : "J. R. R. Tolkien",
"title" : "The Lord of the Rings",
"isbn" : "0-395-19395-8",
"price" : 22.99
}
]),
);
select_and_then_compare(
r#"$..book[?(@.isbn)]"#,
read_json("./benchmark/example.json"),
json!([
{
"category" : "fiction",
"author" : "Herman Melville",
"title" : "Moby Dick",
"isbn" : "0-553-21311-3",
"price" : 8.99
},
{
"category" : "fiction",
"author" : "J. R. R. Tolkien",
"title" : "The Lord of the Rings",
"isbn" : "0-395-19395-8",
"price" : 22.99
}
]),
);
select_and_then_compare(
r#"$.store.book[?(@.price < 10)]"#,
read_json("./benchmark/example.json"),
json!([
{
"category" : "reference",
"author" : "Nigel Rees",
"title" : "Sayings of the Century",
"price" : 8.95
},
{
"category" : "fiction",
"author" : "Herman Melville",
"title" : "Moby Dick",
"isbn" : "0-553-21311-3",
"price" : 8.99
}
]),
);
select_and_then_compare(
r#"$..*"#,
read_json("./benchmark/example.json"),
read_json("./benchmark/giveme_every_thing_result.json"),
);
}
#[test]
fn filer_same_obj() {
setup();
select_and_then_compare(
r#"$..[?(@.a == 1)]"#,
json!({
"a": 1,
"b" : {"a": 1},
"c" : {"a": 1}
}),
json!([
{"a": 1},
{"a": 1}
]),
);
}
#[test]
fn range() {
setup();
select_and_then_compare(
"$[ : ]",
json!(["first", "second"]),
json!(["first", "second"]),
);
select_and_then_compare(
"$[::]",
json!(["first", "second", "third", "forth", "fifth"]),
json!(["first", "second", "third", "forth", "fifth"]),
);
select_and_then_compare(
"$[::2]",
json!(["first", "second", "third", "forth", "fifth"]),
json!(["first", "third", "fifth"]),
);
select_and_then_compare(
"$[1::]",
json!(["first", "second", "third", "forth", "fifth"]),
json!(["second", "third", "forth", "fifth"]),
);
select_and_then_compare(
"$[1:2:]",
json!(["first", "second", "third", "forth", "fifth"]),
json!(["second"]),
);
select_and_then_compare(
"$[1::2]",
json!(["first", "second", "third", "forth", "fifth"]),
json!(["second", "forth"]),
);
select_and_then_compare(
"$[0:3:1]",
json!(["first", "second", "third", "forth", "fifth"]),
json!(["first", "second", "third"]),
);
select_and_then_compare(
"$[0:3:2]",
json!(["first", "second", "third", "forth", "fifth"]),
json!(["first", "third"]),
);
}
#[test]
fn quote() {
setup();
@ -621,7 +22,7 @@ fn quote() {
}
#[test]
fn all_filter() {
fn filter_next_all() {
setup();
for path in &[r#"$.*"#, r#"$[*]"#] {
@ -631,6 +32,11 @@ fn all_filter() {
json!(["string", 42, { "key": "value" }, [0, 1]]),
);
}
}
#[test]
fn filter_all() {
setup();
for path in &[r#"$..*"#, r#"$..[*]"#] {
select_and_then_compare(
@ -639,6 +45,11 @@ fn all_filter() {
json!([ "string", 42, { "key" : "value" }, [ 0, 1 ], "value", 0, 1 ]),
);
}
}
#[test]
fn filter_array_next_all() {
setup();
for path in &[r#"$.*.*"#, r#"$[*].*"#, r#"$.*[*]"#, r#"$[*][*]"#] {
select_and_then_compare(
@ -647,6 +58,11 @@ fn all_filter() {
json!(["value", 0, 1]),
);
}
}
#[test]
fn filter_all_complex() {
setup();
for path in &[r#"$..friends.*"#, r#"$[*].friends.*"#] {
select_and_then_compare(
@ -665,8 +81,9 @@ fn all_filter() {
}
#[test]
fn current_path() {
fn filter_parent_with_matched_child() {
setup();
select_and_then_compare(
"$.a[?(@.b.c == 1)]",
json!({
@ -684,6 +101,11 @@ fn current_path() {
}
]),
);
}
#[test]
fn filter_parent_exist_child() {
setup();
select_and_then_compare(
"$.a[?(@.b.c)]",
@ -705,7 +127,23 @@ fn current_path() {
}
#[test]
fn bugs33() {
fn filter_parent_paths() {
setup();
select_and_then_compare(
"$[?(@.key.subKey == 'subKey2')]",
json!([
{"key": {"seq": 1, "subKey": "subKey1"}},
{"key": {"seq": 2, "subKey": "subKey2"}},
{"key": 42},
{"some": "value"}
]),
json!([{"key": {"seq": 2, "subKey": "subKey2"}}]),
);
}
#[test]
fn bugs33_exist_in_all() {
setup();
select_and_then_compare(
@ -728,6 +166,11 @@ fn bugs33() {
}
]),
);
}
#[test]
fn bugs33_exist_left_in_all_with_and_condition() {
setup();
select_and_then_compare(
"$..[?(@.first && @.first.second)]",
@ -749,6 +192,11 @@ fn bugs33() {
}
]),
);
}
#[test]
fn bugs33_exist_right_in_all_with_and_condition() {
setup();
select_and_then_compare(
"$..[?(@.b.c.d && @.b)]",
@ -775,4 +223,58 @@ fn bugs33() {
}
]),
);
}
#[test]
fn bugs38_array_notation_in_filter() {
setup();
select_and_then_compare(
"$[?(@['key']==42)]",
json!([
{"key": 0},
{"key": 42},
{"key": -1},
{"key": 41},
{"key": 43},
{"key": 42.0001},
{"key": 41.9999},
{"key": 100},
{"some": "value"}
]),
json!([{"key": 42}]),
);
select_and_then_compare(
"$[?(@['key'].subKey == 'subKey2')]",
json!([
{"key": {"seq": 1, "subKey": "subKey1"}},
{"key": {"seq": 2, "subKey": "subKey2"}},
{"key": 42},
{"some": "value"}
]),
json!([{"key": {"seq": 2, "subKey": "subKey2"}}]),
);
select_and_then_compare(
"$[?(@['key']['subKey'] == 'subKey2')]",
json!([
{"key": {"seq": 1, "subKey": "subKey1"}},
{"key": {"seq": 2, "subKey": "subKey2"}},
{"key": 42},
{"some": "value"}
]),
json!([{"key": {"seq": 2, "subKey": "subKey2"}}]),
);
select_and_then_compare(
"$..key[?(@['subKey'] == 'subKey2')]",
json!([
{"key": {"seq": 1, "subKey": "subKey1"}},
{"key": {"seq": 2, "subKey": "subKey2"}},
{"key": 42},
{"some": "value"}
]),
json!([{"seq": 2, "subKey": "subKey2"}]),
);
}

242
tests/jsonpath_examples.rs Normal file
View File

@ -0,0 +1,242 @@
#[macro_use]
extern crate serde_json;
use common::{read_json, select_and_then_compare, setup};
mod common;
#[test]
fn example_authros_of_all_books() {
setup();
select_and_then_compare(
r#"$.store.book[*].author"#,
read_json("./benchmark/example.json"),
json!([
"Nigel Rees",
"Evelyn Waugh",
"Herman Melville",
"J. R. R. Tolkien"
]),
);
}
#[test]
fn all_authors() {
setup();
select_and_then_compare(
r#"$..author"#,
read_json("./benchmark/example.json"),
json!([
"Nigel Rees",
"Evelyn Waugh",
"Herman Melville",
"J. R. R. Tolkien"
]),
);
}
#[test]
fn all_things_both_books_and_bicycles() {
setup();
select_and_then_compare(
r#"$.store.*"#,
read_json("./benchmark/example.json"),
json!([
[
{"category" : "reference", "author" : "Nigel Rees","title" : "Sayings of the Century", "price" : 8.95},
{"category" : "fiction", "author" : "Evelyn Waugh","title" : "Sword of Honour","price" : 12.99},
{"category" : "fiction", "author" : "Herman Melville","title" : "Moby Dick","isbn" : "0-553-21311-3","price" : 8.99},
{"category" : "fiction", "author" : "J. R. R. Tolkien","title" : "The Lord of the Rings","isbn" : "0-395-19395-8","price" : 22.99}
],
{"color" : "red","price" : 19.95},
]),
);
}
#[test]
fn the_price_of_everything() {
setup();
select_and_then_compare(
r#"$.store..price"#,
read_json("./benchmark/example.json"),
json!([8.95, 12.99, 8.99, 22.99, 19.95]),
);
}
#[test]
fn the_third_book() {
setup();
select_and_then_compare(
r#"$..book[2]"#,
read_json("./benchmark/example.json"),
json!([
{
"category" : "fiction",
"author" : "Herman Melville",
"title" : "Moby Dick",
"isbn" : "0-553-21311-3",
"price" : 8.99
}
]),
);
}
#[test]
fn the_second_to_last_book() {
setup();
select_and_then_compare(
r#"$..book[-2]"#,
read_json("./benchmark/example.json"),
json!([
{
"category" : "fiction",
"author" : "Herman Melville",
"title" : "Moby Dick",
"isbn" : "0-553-21311-3",
"price" : 8.99
}
]),
);
}
#[test]
fn the_first_two_books() {
setup();
select_and_then_compare(
r#"$..book[0, 1]"#,
read_json("./benchmark/example.json"),
json!([
{
"category" : "reference",
"author" : "Nigel Rees",
"title" : "Sayings of the Century",
"price" : 8.95
},
{
"category" : "fiction",
"author" : "Evelyn Waugh",
"title" : "Sword of Honour",
"price" : 12.99
}
]),
);
}
#[test]
fn all_books_from_index_0_inclusive_until_index_2_exclusive() {
setup();
select_and_then_compare(
r#"$..book[:2]"#,
read_json("./benchmark/example.json"),
json!([
{
"category" : "reference",
"author" : "Nigel Rees",
"title" : "Sayings of the Century",
"price" : 8.95
},
{
"category" : "fiction",
"author" : "Evelyn Waugh",
"title" : "Sword of Honour",
"price" : 12.99
}
]),
);
}
#[test]
fn all_books_from_index_1_inclusive_until_index_2_exclusive() {
setup();
select_and_then_compare(
r#"$..book[2:]"#,
read_json("./benchmark/example.json"),
json!([
{
"category" : "fiction",
"author" : "Herman Melville",
"title" : "Moby Dick",
"isbn" : "0-553-21311-3",
"price" : 8.99
},
{
"category" : "fiction",
"author" : "J. R. R. Tolkien",
"title" : "The Lord of the Rings",
"isbn" : "0-395-19395-8",
"price" : 22.99
}
]),
);
}
#[test]
fn all_books_with_an_isbn_number() {
setup();
select_and_then_compare(
r#"$..book[?(@.isbn)]"#,
read_json("./benchmark/example.json"),
json!([
{
"category" : "fiction",
"author" : "Herman Melville",
"title" : "Moby Dick",
"isbn" : "0-553-21311-3",
"price" : 8.99
},
{
"category" : "fiction",
"author" : "J. R. R. Tolkien",
"title" : "The Lord of the Rings",
"isbn" : "0-395-19395-8",
"price" : 22.99
}
]),
);
}
#[test]
fn all_books_in_store_cheaper_than_10() {
setup();
select_and_then_compare(
r#"$.store.book[?(@.price < 10)]"#,
read_json("./benchmark/example.json"),
json!([
{
"category" : "reference",
"author" : "Nigel Rees",
"title" : "Sayings of the Century",
"price" : 8.95
},
{
"category" : "fiction",
"author" : "Herman Melville",
"title" : "Moby Dick",
"isbn" : "0-553-21311-3",
"price" : 8.99
}
]),
);
}
#[test]
fn give_me_every_thing() {
setup();
select_and_then_compare(
r#"$..*"#,
read_json("./benchmark/example.json"),
read_json("./benchmark/giveme_every_thing_result.json"),
);
}

376
tests/op.rs Normal file
View File

@ -0,0 +1,376 @@
#[macro_use]
extern crate serde_json;
use common::{read_json, select_and_then_compare, setup};
mod common;
#[test]
fn op_object_eq() {
setup();
select_and_then_compare(
"$.school[?(@.friends == @.friends)]",
read_json("./benchmark/data_obj.json"),
json!([{
"friends": [
{"id": 0, "name": "Millicent Norman"},
{"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"}
]
}]),
);
}
#[test]
fn op_object_ge() {
setup();
select_and_then_compare(
"$.friends[?(@.id >= 2)]",
read_json("./benchmark/data_obj.json"),
json!([
{ "id" : 2, "name" : "Gray Berry" }
]),
);
}
#[test]
fn op_object_or_default() {
setup();
select_and_then_compare(
"$.friends[?(@.id >= 2 || @.id == 1)]",
read_json("./benchmark/data_obj.json"),
json!([
{ "id" : 2, "name" : "Gray Berry" },
{ "id" : 1, "name" : "Vincent Cannon" }
]),
);
}
#[test]
fn op_object_and_or() {
setup();
select_and_then_compare(
"$.friends[?( (@.id >= 2 || @.id == 1) && @.id == 0)]",
read_json("./benchmark/data_obj.json"),
json!([]),
);
}
#[test]
fn op_result_type() {
setup();
select_and_then_compare(
"$..friends[?(@.id == $.index)].id",
read_json("./benchmark/data_obj.json"),
json!([0, 0]),
);
}
#[test]
fn op_absolute_path_result_type() {
setup();
select_and_then_compare(
"$..book[?($.store.bicycle.price < @.price)].price",
read_json("./benchmark/example.json"),
json!([22.99]),
);
}
#[test]
fn op_complicated() {
setup();
select_and_then_compare(
"$..book[?( (@.price == 12.99 || @.category == 'reference') && @.price > 10)].price",
read_json("./benchmark/example.json"),
json!([12.99]),
);
}
#[test]
fn op_gt() {
setup();
select_and_then_compare(
"$..[?(@.age > 40)]",
json!([
{ "name": "이름1", "age": 40, "phone": "+33 12341234" },
{ "name": "이름2", "age": 42, "phone": "++44 12341234" }
]),
json!([
{ "name" : "이름2", "age" : 42, "phone" : "++44 12341234" }
]),
);
}
#[test]
fn op_ge() {
setup();
select_and_then_compare(
"$..[?(@.age >= 30)]",
json!({
"school": {
"friends": [
{"name": "친구1", "age": 20},
{"name": "친구2", "age": 20}
]
},
"friends": [
{"name": "친구3", "age": 30},
{"name": "친구4"}
]}),
json!([
{ "name" : "친구3", "age" : 30 }
]),
);
}
#[test]
fn op_eq_for_number() {
setup();
select_and_then_compare("$.[?(@.a == 1)]", json!({ "a": 1 }), json!([{ "a": 1 }]));
}
#[test]
fn op_ne_for_number() {
setup();
select_and_then_compare("$.[?(@.a != 2)]", json!({ "a": 1 }), json!([{ "a": 1 }]));
}
#[test]
fn op_lt_for_number() {
setup();
select_and_then_compare("$.[?(@.a < 2)]", json!({ "a": 1 }), json!([{ "a": 1 }]));
}
#[test]
fn op_le_for_number() {
setup();
select_and_then_compare("$.[?(@.a <= 1)]", json!({ "a": 1 }), json!([{ "a": 1 }]));
}
#[test]
fn op_gt_for_number() {
setup();
select_and_then_compare("$.[?(@.a > 0)]", json!({ "a": 1 }), json!([{ "a": 1 }]));
}
#[test]
fn op_ge_for_number() {
setup();
select_and_then_compare("$.[?(@.a >= 0)]", json!({ "a": 1 }), json!([{ "a": 1 }]));
}
#[test]
fn op_eq_for_string_value() {
setup();
select_and_then_compare(
r#"$.[?(@.a == "b")]"#, json!({ "a": "b" }), json!([{ "a": "b" }]),
);
}
#[test]
fn op_ne_for_string_value() {
setup();
select_and_then_compare(
r#"$.[?(@.a != "c")]"#, json!({ "a": "b" }), json!([{ "a": "b" }]),
);
}
#[test]
fn op_lt_for_string_value() {
setup();
select_and_then_compare(
r#"$.[?(@.a < "b")]"#, json!({ "a": "b" }), json!([]),
);
}
#[test]
fn op_le_for_string_value() {
setup();
select_and_then_compare(
r#"$.[?(@.a <= "b")]"#, json!({ "a": "b" }), json!([{ "a": "b" }]),
);
}
#[test]
fn op_gt_for_string_value() {
setup();
select_and_then_compare(
r#"$.[?(@.a > "b")]"#, json!({ "a": "b" }), json!([]),
);
}
#[test]
fn op_ge_for_string_value() {
setup();
select_and_then_compare(
r#"$.[?(@.a >= "b")]"#, json!({ "a": "b" }), json!([{ "a": "b" }]),
);
}
#[test]
fn op_eq_for_object_value() {
setup();
select_and_then_compare(
r#"$.[?(@.a == @.c)]"#,
json!({"a": { "1": 1 }, "b": { "2": 2 }, "c": { "1": 1 }}),
json!([{"a": { "1": 1 }, "b": { "2": 2 }, "c": { "1": 1 }}]),
);
}
#[test]
fn op_ne_for_object_value() {
setup();
select_and_then_compare(
r#"$.[?(@.a != @.c)]"#,
json!({"a": { "1": 1 }, "b": { "2": 2 }, "c": { "1": 1 }}),
json!([]),
);
}
#[test]
fn op_lt_for_object_value() {
setup();
select_and_then_compare(
r#"$.[?(@.a < @.c)]"#,
json!({"a": { "1": 1 }, "b": { "2": 2 }, "c": { "1": 1 }}),
json!([]),
);
}
#[test]
fn op_le_for_object_value() {
setup();
select_and_then_compare(
r#"$.[?(@.a <= @.c)]"#,
json!({"a": { "1": 1 }, "b": { "2": 2 }, "c": { "1": 1 }}),
json!([]),
);
}
#[test]
fn op_gt_for_object_value() {
setup();
select_and_then_compare(
r#"$.[?(@.a > @.c)]"#,
json!({"a": { "1": 1 }, "b": { "2": 2 }, "c": { "1": 1 }}),
json!([]),
);
}
#[test]
fn op_ge_for_object_value() {
setup();
select_and_then_compare(
r#"$.[?(@.a >= @.c)]"#,
json!({"a": { "1": 1 }, "b": { "2": 2 }, "c": { "1": 1 }}),
json!([]),
);
}
#[test]
fn op_eq_for_complex_value() {
setup();
select_and_then_compare(
r#"$.[?(1 == @.a)]"#,
json!({ "a": { "b": 1 } }),
json!([]),
);
}
#[test]
fn op_ne_for_complex_value() {
setup();
select_and_then_compare(
r#"$.[?("1" != @.a)]"#,
json!({ "a": { "b": 1 } }),
json!([]),
);
}
#[test]
fn op_le_for_complex_value() {
setup();
select_and_then_compare(
r#"$.[?(@.a <= 1)]"#,
json!({ "a": { "b": 1 } }),
json!([]),
);
}
#[test]
fn op_gt_for_complex_value() {
setup();
select_and_then_compare(
r#"$.[?(@.a > "1")]"#,
json!({ "a": { "b": 1 } }),
json!([]),
);
}
#[test]
fn op_compare_different_types() {
setup();
for path in [
r#"$[?("1" == 1)]"#,
r#"$[?(1 == "1")]"#,
r#"$[?(true == 1)]"#,
r#"$[?(@ == 1)]"#,
]
.iter()
{
select_and_then_compare(path, json!({}), json!([]));
}
}
#[test]
fn op_for_same_type() {
setup();
select_and_then_compare(
r#"$..[?(@.a == 1)]"#,
json!({
"a": 1,
"b" : {"a": 1},
"c" : {"a": 1}
}),
json!([
{"a": 1},
{"a": 1}
]),
);
}

115
tests/paths.rs Normal file
View File

@ -0,0 +1,115 @@
#[macro_use]
extern crate serde_json;
use common::{select_and_then_compare, setup};
mod common;
#[test]
fn dolla_token_in_path() {
setup();
select_and_then_compare(
"$..$ref",
json!({
"Junk1": "This is a test to illustrate use of '$' in the attr for the expression $..['$ref'] ",
"$ref": "Match Root",
"Subset1":[
{"Junk2": "Data...",
"$ref": "Match Subset1"
}
],
"hierachy1":{
"hierachy2.1":{
"hierachy2.1.1":{ "$ref":"Match 2.1.1"},
"hierachy2.1.2":{ "ref":"Match 2.1.2"},
"hierachy2.1.3":{ "ref":"No Match 2.1.3"},
"hierachy2.1.4":{ "$ref":"Match 2.1.4"},
"hierachy2.1.5":{ "ref":"No Match 2.1.5"}
},
"hierachy2.2":{
"hierachy2.2.1":{ "ref":"No Match 2.2.1"},
"hierachy2.2.2":{ "$ref":"Match 2.2.2"},
"hierachy2.2.3":{ "ref":"No Match 2.2.3"},
"hierachy2.2.4":{ "ref":"No Match 2.2.5"},
"hierachy2.2.5":{ "$ref":"Match 2.2.5"}
},
"hierachy2.3":{
"hierachy2.3.1":{ "ref":"No Match 2.3.1"},
"hierachy2.3.2":{ "ref":"No Match 2.3.2"},
"hierachy2.3.3":{ "ref":"No Match 2.3.3"},
"hierachy2.3.4":{ "ref":"No Match 2.3.4"},
"hierachy2.3.5":{ "ref":"No Match 2.3.5"},
"hierachy2.3.6":{
"hierachy2.3.6.1":{ "$ref":"Match 2.3.6.1"},
"hierachy2.3.6.2":{ "ref":"No Match 2.3.6.2"},
"hierachy2.3.6.3":{ "ref":"No Match 2.3.6.3"},
"hierachy2.3.6.4":{ "ref":"No Match 2.3.6.4"},
"hierachy2.3.6.5":{ "ref":"No Match 2.3.6.5"}
}
}
}
}),
json!([
"Match Root",
"Match Subset1",
"Match 2.1.1",
"Match 2.1.4",
"Match 2.2.2",
"Match 2.2.5",
"Match 2.3.6.1"
]),
);
select_and_then_compare(
"$..['$ref']",
json!({
"Junk1": "This is a test to illustrate use of '$' in the attr for the expression $..['$ref'] ",
"$ref": "Match Root",
"Subset1":[
{"Junk2": "Data...",
"$ref": "Match Subset1"
}
],
"hierachy1":{
"hierachy2.1":{
"hierachy2.1.1":{ "$ref":"Match 2.1.1"},
"hierachy2.1.2":{ "ref":"Match 2.1.2"},
"hierachy2.1.3":{ "ref":"No Match 2.1.3"},
"hierachy2.1.4":{ "$ref":"Match 2.1.4"},
"hierachy2.1.5":{ "ref":"No Match 2.1.5"}
},
"hierachy2.2":{
"hierachy2.2.1":{ "ref":"No Match 2.2.1"},
"hierachy2.2.2":{ "$ref":"Match 2.2.2"},
"hierachy2.2.3":{ "ref":"No Match 2.2.3"},
"hierachy2.2.4":{ "ref":"No Match 2.2.5"},
"hierachy2.2.5":{ "$ref":"Match 2.2.5"}
},
"hierachy2.3":{
"hierachy2.3.1":{ "ref":"No Match 2.3.1"},
"hierachy2.3.2":{ "ref":"No Match 2.3.2"},
"hierachy2.3.3":{ "ref":"No Match 2.3.3"},
"hierachy2.3.4":{ "ref":"No Match 2.3.4"},
"hierachy2.3.5":{ "ref":"No Match 2.3.5"},
"hierachy2.3.6":{
"hierachy2.3.6.1":{ "$ref":"Match 2.3.6.1"},
"hierachy2.3.6.2":{ "ref":"No Match 2.3.6.2"},
"hierachy2.3.6.3":{ "ref":"No Match 2.3.6.3"},
"hierachy2.3.6.4":{ "ref":"No Match 2.3.6.4"},
"hierachy2.3.6.5":{ "ref":"No Match 2.3.6.5"}
}
}
}
}),
json!([
"Match Root",
"Match Subset1",
"Match 2.1.1",
"Match 2.1.4",
"Match 2.2.2",
"Match 2.2.5",
"Match 2.3.6.1"
]),
);
}

108
tests/return_type.rs Normal file
View File

@ -0,0 +1,108 @@
#[macro_use]
extern crate serde_json;
use common::{read_json, select_and_then_compare, setup};
mod common;
#[test]
fn return_type_for_single_object() {
setup();
select_and_then_compare(
"$.school",
read_json("./benchmark/data_obj.json"),
json!([{
"friends": [
{"id": 0, "name": "Millicent Norman"},
{"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"}
]
}]),
);
}
#[test]
fn return_type_for_single_object_key_matched() {
setup();
select_and_then_compare(
"$.friends[?(@.name)]",
read_json("./benchmark/data_obj.json"),
json!([
{ "id" : 1, "name" : "Vincent Cannon" },
{ "id" : 2, "name" : "Gray Berry" }
]),
);
}
#[test]
fn return_type_for_child_object_matched() {
setup();
select_and_then_compare(
"$.school[?(@.friends[0])]",
read_json("./benchmark/data_obj.json"),
json!([{
"friends": [
{"id": 0, "name": "Millicent Norman"},
{"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"}
]
}]),
);
}
#[test]
fn return_type_for_child_object_not_matched() {
setup();
select_and_then_compare(
"$.school[?(@.friends[10])]",
read_json("./benchmark/data_obj.json"),
json!([]),
);
}
#[test]
fn return_type_for_object_filter_true() {
setup();
select_and_then_compare(
"$.school[?(1==1)]",
read_json("./benchmark/data_obj.json"),
json!([{
"friends": [
{"id": 0, "name": "Millicent Norman"},
{"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"}
]
}]),
);
}
#[test]
fn return_type_for_array_filter_true() {
setup();
select_and_then_compare(
"$.school.friends[?(1==1)]",
read_json("./benchmark/data_obj.json"),
json!([[
{"id": 0, "name": "Millicent Norman"},
{"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"}
]]),
);
}
#[test]
fn return_type_empty() {
setup();
select_and_then_compare(
"$[?(@.key==43)]",
json!([{"key": 42}]),
json!([]),
);
}

View File

@ -1,6 +1,6 @@
[package]
name = "jsonpath-wasm"
version = "0.2.4"
version = "0.2.5"
authors = ["Changseok Han <freestrings@gmail.com>"]
description = "It is Webassembly version of jsonpath_lib that is JsonPath engine written in Rust - Demo: https://freestrings.github.io/jsonpath"
keywords = ["jsonpath", "json", "webassembly", "parsing", "rust"]

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +0,0 @@
{
"name": "jsonpath-wasm-nodejs-example",
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"jsonpath-wasm": {
"version": "0.2.4",
"resolved": "https://registry.npmjs.org/jsonpath-wasm/-/jsonpath-wasm-0.2.4.tgz",
"integrity": "sha512-sxvPEFMpAoNjxUQOkJmVyE3dKX7v4ebX5TkWKguyHteZpHJKlMQbgPKFYL0X3SIU7wAstpOl6hVODLThVmJf1w=="
}
}
}

View File

@ -0,0 +1,15 @@
events { }
http {
include mime.types;
types {
application/wasm wasm;
}
server {
listen 80;
location / {
root /usr/share/nginx/html;
try_files $uri $uri/ /index.html =404;
}
}
}

6
wasm/nginx_conf/run.sh Executable file
View File

@ -0,0 +1,6 @@
#!/usr/bin/env bash
docker run -it --rm -p 8000:80 \
-v $(pwd)/../../docs:/usr/share/nginx/html \
-v $(pwd)/nginx.conf:/etc/nginx/nginx.conf \
nginx

View File

@ -85,22 +85,44 @@
}
},
"cliui": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
"integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
"integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
"dev": true,
"requires": {
"string-width": "^2.1.1",
"strip-ansi": "^4.0.0",
"wrap-ansi": "^2.0.0"
"string-width": "^3.1.0",
"strip-ansi": "^5.2.0",
"wrap-ansi": "^5.1.0"
},
"dependencies": {
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
"string-width": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
"dev": true,
"requires": {
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
}
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": {
"ansi-regex": "^4.1.0"
}
}
}
},
"code-point-at": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
"dev": true
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
@ -122,19 +144,6 @@
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
},
"cross-spawn": {
"version": "6.0.5",
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
"integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
"dev": true,
"requires": {
"nice-try": "^1.0.4",
"path-key": "^2.0.1",
"semver": "^5.5.0",
"shebang-command": "^1.2.0",
"which": "^1.2.9"
}
},
"debug": {
"version": "3.2.6",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
@ -171,33 +180,29 @@
"integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
"dev": true
},
"end-of-stream": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
"dev": true,
"requires": {
"once": "^1.4.0"
}
},
"es-abstract": {
"version": "1.13.0",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
"integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
"version": "1.17.5",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz",
"integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==",
"dev": true,
"requires": {
"es-to-primitive": "^1.2.0",
"es-to-primitive": "^1.2.1",
"function-bind": "^1.1.1",
"has": "^1.0.3",
"is-callable": "^1.1.4",
"is-regex": "^1.0.4",
"object-keys": "^1.0.12"
"has-symbols": "^1.0.1",
"is-callable": "^1.1.5",
"is-regex": "^1.0.5",
"object-inspect": "^1.7.0",
"object-keys": "^1.1.1",
"object.assign": "^4.1.0",
"string.prototype.trimleft": "^2.1.1",
"string.prototype.trimright": "^2.1.1"
}
},
"es-to-primitive": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
"integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
"integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
"dev": true,
"requires": {
"is-callable": "^1.1.4",
@ -217,21 +222,6 @@
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
"dev": true
},
"execa": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
"integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
"dev": true,
"requires": {
"cross-spawn": "^6.0.0",
"get-stream": "^4.0.0",
"is-stream": "^1.1.0",
"npm-run-path": "^2.0.0",
"p-finally": "^1.0.0",
"signal-exit": "^3.0.0",
"strip-eof": "^1.0.0"
}
},
"find-up": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
@ -268,15 +258,6 @@
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true
},
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
"integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
"dev": true,
"requires": {
"pump": "^3.0.0"
}
},
"glob": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
@ -313,9 +294,9 @@
"dev": true
},
"has-symbols": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
"integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
"integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
"dev": true
},
"he": {
@ -335,33 +316,27 @@
}
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
"dev": true
},
"invert-kv": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz",
"integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"is-buffer": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz",
"integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==",
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz",
"integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==",
"dev": true
},
"is-callable": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
"integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
"integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
"dev": true
},
"is-date-object": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
"integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
"dev": true
},
"is-fullwidth-code-point": {
@ -371,27 +346,21 @@
"dev": true
},
"is-regex": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
"integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
"dev": true,
"requires": {
"has": "^1.0.1"
"has": "^1.0.3"
}
},
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
"dev": true
},
"is-symbol": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz",
"integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==",
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
"integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
"dev": true,
"requires": {
"has-symbols": "^1.0.0"
"has-symbols": "^1.0.1"
}
},
"isexe": {
@ -411,20 +380,9 @@
}
},
"jsonpath-wasm": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/jsonpath-wasm/-/jsonpath-wasm-0.1.3.tgz",
"integrity": "sha512-c9A8bxQSzHWu52KPDSWjW9MxdhVOZ8J8Gpi3TjD5H4XMcpiGtDNi6Pm9gYb+TgcRynA6hHD5YTmRfaN6vTiSLg==",
"version": "file:../nodejs_pkg",
"dev": true
},
"lcid": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
"integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==",
"dev": true,
"requires": {
"invert-kv": "^2.0.0"
}
},
"locate-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
@ -436,9 +394,9 @@
}
},
"lodash": {
"version": "4.17.14",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.14.tgz",
"integrity": "sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw==",
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
},
"log-symbols": {
@ -450,32 +408,6 @@
"chalk": "^2.0.1"
}
},
"map-age-cleaner": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz",
"integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==",
"dev": true,
"requires": {
"p-defer": "^1.0.0"
}
},
"mem": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz",
"integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==",
"dev": true,
"requires": {
"map-age-cleaner": "^0.1.1",
"mimic-fn": "^2.0.0",
"p-is-promise": "^2.0.0"
}
},
"mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"dev": true
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@ -486,24 +418,24 @@
}
},
"minimist": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true
},
"mkdirp": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz",
"integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==",
"dev": true,
"requires": {
"minimist": "0.0.8"
"minimist": "^1.2.5"
}
},
"mocha": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-6.1.4.tgz",
"integrity": "sha512-PN8CIy4RXsIoxoFJzS4QNnCH4psUCPWc4/rPrst/ecSJJbLBkubMiyGCP2Kj/9YnWbotFqAoeXyXMucj7gwCFg==",
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz",
"integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==",
"dev": true,
"requires": {
"ansi-colors": "3.2.3",
@ -518,7 +450,7 @@
"js-yaml": "3.13.1",
"log-symbols": "2.2.0",
"minimatch": "3.0.4",
"mkdirp": "0.5.1",
"mkdirp": "0.5.4",
"ms": "2.1.1",
"node-environment-flags": "1.0.5",
"object.assign": "4.1.0",
@ -526,9 +458,9 @@
"supports-color": "6.0.0",
"which": "1.3.1",
"wide-align": "1.1.3",
"yargs": "13.2.2",
"yargs-parser": "13.0.0",
"yargs-unparser": "1.5.0"
"yargs": "13.3.2",
"yargs-parser": "13.1.2",
"yargs-unparser": "1.6.0"
}
},
"ms": {
@ -537,12 +469,6 @@
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
"dev": true
},
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
"integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
"dev": true
},
"node-environment-flags": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz",
@ -553,19 +479,10 @@
"semver": "^5.7.0"
}
},
"npm-run-path": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
"integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
"dev": true,
"requires": {
"path-key": "^2.0.0"
}
},
"number-is-nan": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
"object-inspect": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
"integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
"dev": true
},
"object-keys": {
@ -587,13 +504,13 @@
}
},
"object.getownpropertydescriptors": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
"integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz",
"integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==",
"dev": true,
"requires": {
"define-properties": "^1.1.2",
"es-abstract": "^1.5.1"
"define-properties": "^1.1.3",
"es-abstract": "^1.17.0-next.1"
}
},
"once": {
@ -605,39 +522,10 @@
"wrappy": "1"
}
},
"os-locale": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz",
"integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==",
"dev": true,
"requires": {
"execa": "^1.0.0",
"lcid": "^2.0.0",
"mem": "^4.0.0"
}
},
"p-defer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
"integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=",
"dev": true
},
"p-finally": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
"integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
"dev": true
},
"p-is-promise": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz",
"integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==",
"dev": true
},
"p-limit": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
"integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
"dev": true,
"requires": {
"p-try": "^2.0.0"
@ -670,22 +558,6 @@
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
},
"path-key": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
"integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
"dev": true
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@ -699,9 +571,9 @@
"dev": true
},
"semver": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
"dev": true
},
"set-blocking": {
@ -710,27 +582,6 @@
"integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
"dev": true
},
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
"integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
"dev": true,
"requires": {
"shebang-regex": "^1.0.0"
}
},
"shebang-regex": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
"dev": true
},
"signal-exit": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
"dev": true
},
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
@ -747,6 +598,48 @@
"strip-ansi": "^4.0.0"
}
},
"string.prototype.trimend": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
"integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.5"
}
},
"string.prototype.trimleft": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz",
"integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.5",
"string.prototype.trimstart": "^1.0.0"
}
},
"string.prototype.trimright": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz",
"integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.5",
"string.prototype.trimend": "^1.0.0"
}
},
"string.prototype.trimstart": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
"integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
"dev": true,
"requires": {
"define-properties": "^1.1.3",
"es-abstract": "^1.17.5"
}
},
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
@ -756,12 +649,6 @@
"ansi-regex": "^3.0.0"
}
},
"strip-eof": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
"dev": true
},
"strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
@ -802,48 +689,40 @@
}
},
"wrap-ansi": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
"integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
"dev": true,
"requires": {
"string-width": "^1.0.1",
"strip-ansi": "^3.0.1"
"ansi-styles": "^3.2.0",
"string-width": "^3.0.0",
"strip-ansi": "^5.0.0"
},
"dependencies": {
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
"dev": true
},
"is-fullwidth-code-point": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"dev": true,
"requires": {
"number-is-nan": "^1.0.0"
}
},
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
"integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
"dev": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
"strip-ansi": "^3.0.0"
"emoji-regex": "^7.0.1",
"is-fullwidth-code-point": "^2.0.0",
"strip-ansi": "^5.1.0"
}
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
"dev": true,
"requires": {
"ansi-regex": "^2.0.0"
"ansi-regex": "^4.1.0"
}
}
}
@ -861,22 +740,21 @@
"dev": true
},
"yargs": {
"version": "13.2.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz",
"integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==",
"version": "13.3.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz",
"integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==",
"dev": true,
"requires": {
"cliui": "^4.0.0",
"cliui": "^5.0.0",
"find-up": "^3.0.0",
"get-caller-file": "^2.0.1",
"os-locale": "^3.1.0",
"require-directory": "^2.1.1",
"require-main-filename": "^2.0.0",
"set-blocking": "^2.0.0",
"string-width": "^3.0.0",
"which-module": "^2.0.0",
"y18n": "^4.0.0",
"yargs-parser": "^13.0.0"
"yargs-parser": "^13.1.2"
},
"dependencies": {
"ansi-regex": {
@ -908,9 +786,9 @@
}
},
"yargs-parser": {
"version": "13.0.0",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz",
"integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==",
"version": "13.1.2",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
"integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
"dev": true,
"requires": {
"camelcase": "^5.0.0",
@ -918,58 +796,14 @@
}
},
"yargs-unparser": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz",
"integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz",
"integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==",
"dev": true,
"requires": {
"flat": "^4.1.0",
"lodash": "^4.17.11",
"yargs": "^12.0.5"
},
"dependencies": {
"get-caller-file": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
"integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
"dev": true
},
"require-main-filename": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
"integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
"dev": true
},
"yargs": {
"version": "12.0.5",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz",
"integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==",
"dev": true,
"requires": {
"cliui": "^4.0.0",
"decamelize": "^1.2.0",
"find-up": "^3.0.0",
"get-caller-file": "^1.0.1",
"os-locale": "^3.0.0",
"require-directory": "^2.1.1",
"require-main-filename": "^1.0.1",
"set-blocking": "^2.0.0",
"string-width": "^2.0.0",
"which-module": "^2.0.0",
"y18n": "^3.2.1 || ^4.0.0",
"yargs-parser": "^11.1.1"
}
},
"yargs-parser": {
"version": "11.1.1",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz",
"integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==",
"dev": true,
"requires": {
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
}
"lodash": "^4.17.15",
"yargs": "^13.3.0"
}
}
}

View File

@ -8,7 +8,7 @@
"test": "mocha"
},
"devDependencies": {
"jsonpath-wasm": "*",
"jsonpath-wasm": "file:../nodejs_pkg",
"mocha": "^6.1.4"
}
}

View File

@ -935,4 +935,70 @@ describe('ISSUE test', () => {
done();
});
it('Failure to match "$..[\'$ref\']", "$..[\'ref\']", but succeeds on "$..ref" #43', (done) => {
function select(json, expected, paths) {
for (var i = 0 ; i < paths.length ; i++) {
let result = jsonpath.select(json, paths[i]);
if (JSON.stringify(result) !== JSON.stringify(expected)) {
throw Error("Error: " + paths[i] + ", " + result);
}
}
}
select(
{
"Junk1": "This is a test to illustrate use of '$' in the attr for the expression $..['$ref'] ",
"$ref": "Match Root",
"Subset1":[
{"Junk2": "Data...",
"$ref": "Match Subset1"
}
],
"hierachy1":{
"hierachy2.1":{
"hierachy2.1.1":{ "$ref":"Match 2.1.1"},
"hierachy2.1.2":{ "ref":"Match 2.1.2"},
"hierachy2.1.3":{ "ref":"No Match 2.1.3"},
"hierachy2.1.4":{ "$ref":"Match 2.1.4"},
"hierachy2.1.5":{ "ref":"No Match 2.1.5"}
},
"hierachy2.2":{
"hierachy2.2.1":{ "ref":"No Match 2.2.1"},
"hierachy2.2.2":{ "$ref":"Match 2.2.2"},
"hierachy2.2.3":{ "ref":"No Match 2.2.3"},
"hierachy2.2.4":{ "ref":"No Match 2.2.5"},
"hierachy2.2.5":{ "$ref":"Match 2.2.5"}
},
"hierachy2.3":{
"hierachy2.3.1":{ "ref":"No Match 2.3.1"},
"hierachy2.3.2":{ "ref":"No Match 2.3.2"},
"hierachy2.3.3":{ "ref":"No Match 2.3.3"},
"hierachy2.3.4":{ "ref":"No Match 2.3.4"},
"hierachy2.3.5":{ "ref":"No Match 2.3.5"},
"hierachy2.3.6":{
"hierachy2.3.6.1":{ "$ref":"Match 2.3.6.1"},
"hierachy2.3.6.2":{ "ref":"No Match 2.3.6.2"},
"hierachy2.3.6.3":{ "ref":"No Match 2.3.6.3"},
"hierachy2.3.6.4":{ "ref":"No Match 2.3.6.4"},
"hierachy2.3.6.5":{ "ref":"No Match 2.3.6.5"}
}
}
}
},
[
"Match Root",
"Match Subset1",
"Match 2.1.1",
"Match 2.1.4",
"Match 2.2.2",
"Match 2.2.5",
"Match 2.3.6.1"
],
["$..$ref", "$..['$ref']"]
);
done();
});
});

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,13 @@
{
"name": "jsonpath-wasm-evaluator",
"version": "0.2.0",
"version": "0.1.0",
"main": "index.js",
"scripts": {
"build": "webpack --config webpack.config.js",
"start": "webpack-dev-server"
},
"devDependencies": {
"copy-webpack-plugin": "^5.0.1",
"copy-webpack-plugin": "^5.1.1",
"webpack": "^4.29.6",
"webpack-cli": "^3.3.0",
"webpack-dev-server": "^3.2.1"

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{
"name": "jsonpath-wasm-bench",
"version": "0.2.0",
"version": "0.1.0",
"main": "index.js",
"scripts": {
"build": "webpack --config webpack.config.js",