test coverage 개선

This commit is contained in:
freestrings 2019-06-26 18:19:52 +09:00
commit dde0d5dc2e
33 changed files with 364 additions and 93 deletions

View File

@ -14,7 +14,7 @@ branches:
matrix: matrix:
include: include:
- rust: nightly - rust: stable
os: linux os: linux
env: RUST_BACKTRACE=1 env: RUST_BACKTRACE=1
before_cache: | before_cache: |
@ -31,6 +31,7 @@ matrix:
- cargo test --verbose --all - cargo test --verbose --all
- cd wasm && cargo clippy -- -D warnings -A clippy::suspicious_else_formatting - cd wasm && cargo clippy -- -D warnings -A clippy::suspicious_else_formatting
- cd ../nodejs/native && cargo clippy -- -D warnings - cd ../nodejs/native && cargo clippy -- -D warnings
- cd ../../
after_success: | after_success: |
cargo tarpaulin --exclude-files nodejs wasm parser/mod.rs --out Xml cargo tarpaulin --exclude-files nodejs wasm parser/mod.rs --out Xml
bash <(curl -s https://codecov.io/bash) bash <(curl -s https://codecov.io/bash)
@ -79,3 +80,39 @@ matrix:
- npm install - npm install
script: script:
- npm test - npm test
- language: node_js
os: linux
node_js:
- '11'
- '10'
- '9'
- '8'
before_install:
- curl https://sh.rustup.rs -sSf > /tmp/rustup.sh
- 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:
- bash ./build-wasm.sh
- language: node_js
os: osx
node_js:
- '11'
- '10'
- '9'
- '8'
before_install:
- curl https://sh.rustup.rs -sSf > /tmp/rustup.sh
- 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:
- bash ./build-wasm.sh

View File

@ -24,9 +24,6 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", features = ["preserve_order"] } serde_json = { version = "1.0", features = ["preserve_order"] }
array_tool = "1.0.3" array_tool = "1.0.3"
[dev-dependencies]
bencher = "0.1.5"
[lib] [lib]
name = "jsonpath_lib" name = "jsonpath_lib"
path = "src/lib.rs" path = "src/lib.rs"

9
bench.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
set -e
#
# rustup default nightly
#
cargo bench --manifest-path ./benchmark/Cargo.toml

4
benchmark/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
.idea/*
.vscode
/target/
Cargo.lock

17
benchmark/Cargo.toml Normal file
View File

@ -0,0 +1,17 @@
[package]
name = "jsonpath_lib_benches"
version = "0.1.0"
authors = ["Changseok Han <freestrings@gmail.com>"]
description = "jsonpath_lib benchmark"
license = "MIT"
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", features = ["preserve_order"] }
jsonpath_lib = { path = "../" }
[dev-dependencies]
bencher = "0.1.5"
[[bin]]
name = "jsonpath_lib_benches"
path = "src/main.rs"

View File

@ -22,7 +22,7 @@ fn read_json(path: &str) -> String {
} }
fn get_string() -> String { fn get_string() -> String {
read_json("./benches/example.json") read_json("./example.json")
} }
fn get_json() -> Value { fn get_json() -> Value {

View File

@ -19,7 +19,7 @@ fn read_json(path: &str) -> String {
} }
fn get_string() -> String { fn get_string() -> String {
read_json("./benches/example.json") read_json("./example.json")
} }
fn get_json() -> Value { fn get_json() -> Value {

1
benchmark/src/main.rs Normal file
View File

@ -0,0 +1 @@
fn main() {}

View File

@ -11,7 +11,7 @@ WASM_BROWSER_PKG="${WASM}"/browser_pkg
WASM_NODEJS_PKG="${WASM}"/nodejs_pkg WASM_NODEJS_PKG="${WASM}"/nodejs_pkg
WASM_ALL_PKG="${WASM}"/all_pkg WASM_ALL_PKG="${WASM}"/all_pkg
WASM_TEST="${WASM}"/tests WASM_TEST="${WASM}"/tests
BENCHES="${DIR}"/benches BENCHES="${DIR}"/benchmark
BENCHES_JS="${BENCHES}"/javascript BENCHES_JS="${BENCHES}"/javascript
NODEJS="${DIR}"/nodejs NODEJS="${DIR}"/nodejs
DOCS="${DIR}"/docs DOCS="${DIR}"/docs

View File

@ -412,13 +412,8 @@ pub fn select_as<T: serde::de::DeserializeOwned>(
/// ``` /// ```
pub fn delete(value: Value, path: &str) -> Result<Value, JsonPathError> { pub fn delete(value: Value, path: &str) -> Result<Value, JsonPathError> {
let mut selector = SelectorMut::default(); let mut selector = SelectorMut::default();
let ret = selector let value = selector.str_path(path)?.value(value).delete()?;
.str_path(path)? Ok(value.take().unwrap_or(Value::Null))
.value(value)
.delete()?
.take()
.unwrap_or(Value::Null);
Ok(ret)
} }
/// Select JSON properties using a jsonpath and transform the result and then replace it. via closure that implements `FnMut` you can transform the selected results. /// Select JSON properties using a jsonpath and transform the result and then replace it. via closure that implements `FnMut` you can transform the selected results.
@ -468,11 +463,6 @@ where
F: FnMut(&Value) -> Value, F: FnMut(&Value) -> Value,
{ {
let mut selector = SelectorMut::default(); let mut selector = SelectorMut::default();
let ret = selector let value = selector.str_path(path)?.value(value).replace_with(fun)?;
.str_path(path)? Ok(value.take().unwrap_or(Value::Null))
.value(value)
.replace_with(fun)?
.take()
.unwrap_or(Value::Null);
Ok(ret)
} }

View File

@ -193,13 +193,14 @@ impl Parser {
fn boolean(tokenizer: &mut TokenReader) -> ParseResult<Node> { fn boolean(tokenizer: &mut TokenReader) -> ParseResult<Node> {
debug!("#boolean"); debug!("#boolean");
fn validation_bool_value(v: &str) -> bool {
let b = v.as_bytes();
!b.is_empty() && (b[0] == b't' || b[0] == b'T' || b[0] == b'f' || b[0] == b'F')
}
match tokenizer.next_token() { match tokenizer.next_token() {
Ok(Token::Key(_, ref v)) Ok(Token::Key(_, ref v)) if validation_bool_value(v) => {
if {
let b = v.as_bytes();
!b.is_empty() && (b[0] == b't' || b[0] == b'T' || b[0] == b'f' || b[0] == b'F')
} =>
{
Ok(Self::node(ParseToken::Bool(v.eq_ignore_ascii_case("true")))) Ok(Self::node(ParseToken::Bool(v.eq_ignore_ascii_case("true"))))
} }
_ => Err(tokenizer.err_msg()), _ => Err(tokenizer.err_msg()),
@ -229,10 +230,10 @@ impl Parser {
debug!("#array_quote_value"); debug!("#array_quote_value");
match tokenizer.next_token() { match tokenizer.next_token() {
Ok(Token::SingleQuoted(_, val)) | Ok(Token::DoubleQuoted(_, val)) => { Ok(Token::SingleQuoted(_, val)) | Ok(Token::DoubleQuoted(_, val)) => {
if !tokenizer.peek_is(COMMA) { if tokenizer.peek_is(COMMA) {
Ok(Self::node(ParseToken::Key(val)))
} else {
Self::array_keys(tokenizer, val) Self::array_keys(tokenizer, val)
} else {
Ok(Self::node(ParseToken::Key(val)))
} }
} }
_ => Err(tokenizer.err_msg()), _ => Err(tokenizer.err_msg()),

View File

@ -94,6 +94,7 @@ impl Token {
self.to_simple() == str_token self.to_simple() == str_token
} }
#[cfg_attr(tarpaulin, skip)]
fn to_simple(&self) -> &'static str { fn to_simple(&self) -> &'static str {
match self { match self {
Token::Absolute(_) => ABSOLUTE, Token::Absolute(_) => ABSOLUTE,

View File

@ -157,8 +157,8 @@ impl Cmp for CmpAnd {
v1 && v2 v1 && v2
} }
fn cmp_f64(&self, v1: f64, v2: f64) -> bool { fn cmp_f64(&self, _v1: f64, _v2: f64) -> bool {
v1 > 0_f64 && v2 > 0_f64 true
} }
fn cmp_string(&self, v1: &str, v2: &str) -> bool { fn cmp_string(&self, v1: &str, v2: &str) -> bool {
@ -177,8 +177,8 @@ impl Cmp for CmpOr {
v1 || v2 v1 || v2
} }
fn cmp_f64(&self, v1: f64, v2: f64) -> bool { fn cmp_f64(&self, _v1: f64, _v2: f64) -> bool {
v1 > 0_f64 || v2 > 0_f64 true
} }
fn cmp_string(&self, v1: &str, v2: &str) -> bool { fn cmp_string(&self, v1: &str, v2: &str) -> bool {
@ -190,7 +190,7 @@ impl Cmp for CmpOr {
} }
} }
#[derive(Debug)] #[derive(Debug, PartialEq)]
enum ExprTerm<'a> { enum ExprTerm<'a> {
String(String), String(String),
Number(Number), Number(Number),
@ -434,7 +434,7 @@ fn abs_index(n: isize, len: usize) -> usize {
} }
} }
#[derive(Debug)] #[derive(Debug, PartialEq)]
enum FilterKey { enum FilterKey {
String(String), String(String),
All, All,
@ -482,28 +482,25 @@ impl<'a, 'b> Selector<'a, 'b> {
pub fn str_path(&mut self, path: &str) -> Result<&mut Self, JsonPathError> { pub fn str_path(&mut self, path: &str) -> Result<&mut Self, JsonPathError> {
debug!("path : {}", path); debug!("path : {}", path);
self.node_ref.take();
if self.node_ref.is_some() {
self.node_ref.take();
}
self.node = Some(Parser::compile(path).map_err(JsonPathError::Path)?); self.node = Some(Parser::compile(path).map_err(JsonPathError::Path)?);
Ok(self) Ok(self)
} }
pub fn node_ref(&self) -> Option<&Node> { pub fn node_ref(&self) -> Option<&Node> {
if let Some(node) = &self.node { if let Some(node) = &self.node {
Some(node) return Some(node);
} else {
None
} }
if let Some(node) = &self.node_ref {
return Some(*node);
}
None
} }
pub fn compiled_path(&mut self, node: &'b Node) -> &mut Self { pub fn compiled_path(&mut self, node: &'b Node) -> &mut Self {
if self.node.is_some() { self.node.take();
self.node.take();
}
self.node_ref = Some(node); self.node_ref = Some(node);
self self
} }
@ -1195,3 +1192,212 @@ impl SelectorMut {
Ok(self) Ok(self)
} }
} }
#[cfg(test)]
mod select_inner_tests {
use serde_json::{Number, Value};
use select::{Cmp, CmpAnd, CmpEq, CmpGe, CmpGt, CmpLe, CmpLt, CmpNe, CmpOr, ExprTerm};
#[test]
fn to_f64_i64() {
let number = 0_i64;
let v: Value = serde_json::from_str(&format!("{}", number)).unwrap();
if let Value::Number(n) = v {
assert_eq!((super::to_f64(&n) - number as f64).abs() == 0_f64, true);
} else {
panic!();
}
}
#[test]
fn to_f64_f64() {
let number = 0.1_f64;
let v: Value = serde_json::from_str(&format!("{}", number)).unwrap();
if let Value::Number(n) = v {
assert_eq!((super::to_f64(&n) - number).abs() == 0_f64, true);
} else {
panic!();
}
}
#[test]
fn to_f64_u64() {
let number = u64::max_value();
let v: Value = serde_json::from_str(&format!("{}", number)).unwrap();
if let Value::Number(n) = v {
assert_eq!((super::to_f64(&n) - number as f64).abs() == 0_f64, true);
} else {
panic!();
}
}
#[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)]
);
}
#[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()));
}
}

View File

@ -13,7 +13,7 @@ fn array() {
select_and_then_compare( select_and_then_compare(
"$.school.friends[1, 2]", "$.school.friends[1, 2]",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!([ json!([
{"id": 1, "name": "Vincent Cannon" }, {"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"} {"id": 2, "name": "Gray Berry"}
@ -22,7 +22,7 @@ fn array() {
select_and_then_compare( select_and_then_compare(
"$.school.friends[1: ]", "$.school.friends[1: ]",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!([ json!([
{"id": 1, "name": "Vincent Cannon" }, {"id": 1, "name": "Vincent Cannon" },
{"id": 2, "name": "Gray Berry"} {"id": 2, "name": "Gray Berry"}
@ -31,7 +31,7 @@ fn array() {
select_and_then_compare( select_and_then_compare(
"$.school.friends[:-2]", "$.school.friends[:-2]",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!([ json!([
{"id": 0, "name": "Millicent Norman"} {"id": 0, "name": "Millicent Norman"}
]), ]),
@ -39,13 +39,13 @@ fn array() {
select_and_then_compare( select_and_then_compare(
"$..friends[2].name", "$..friends[2].name",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!(["Gray Berry", "Gray Berry"]), json!(["Gray Berry", "Gray Berry"]),
); );
select_and_then_compare( select_and_then_compare(
"$..friends[*].name", "$..friends[*].name",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!([ json!([
"Vincent Cannon", "Vincent Cannon",
"Gray Berry", "Gray Berry",
@ -57,19 +57,19 @@ fn array() {
select_and_then_compare( select_and_then_compare(
"$['school']['friends'][*].['name']", "$['school']['friends'][*].['name']",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!(["Millicent Norman", "Vincent Cannon", "Gray Berry"]), json!(["Millicent Norman", "Vincent Cannon", "Gray Berry"]),
); );
select_and_then_compare( select_and_then_compare(
"$['school']['friends'][0].['name']", "$['school']['friends'][0].['name']",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!(["Millicent Norman"]), json!(["Millicent Norman"]),
); );
select_and_then_compare( select_and_then_compare(
r#"$.["eyeColor", "name"]"#, r#"$.["eyeColor", "name"]"#,
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!(["blue", "Leonor Herman"]), json!(["blue", "Leonor Herman"]),
); );
} }
@ -80,7 +80,7 @@ fn return_type() {
select_and_then_compare( select_and_then_compare(
"$.school", "$.school",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!([{ json!([{
"friends": [ "friends": [
{"id": 0, "name": "Millicent Norman"}, {"id": 0, "name": "Millicent Norman"},
@ -92,7 +92,7 @@ fn return_type() {
select_and_then_compare( select_and_then_compare(
"$.school[?(@.friends[0])]", "$.school[?(@.friends[0])]",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!([{ json!([{
"friends": [ "friends": [
{"id": 0, "name": "Millicent Norman"}, {"id": 0, "name": "Millicent Norman"},
@ -104,7 +104,7 @@ fn return_type() {
select_and_then_compare( select_and_then_compare(
"$.school[?(@.friends[10])]", "$.school[?(@.friends[10])]",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!([{ json!([{
"friends": [ "friends": [
{"id": 0, "name": "Millicent Norman"}, {"id": 0, "name": "Millicent Norman"},
@ -116,7 +116,7 @@ fn return_type() {
select_and_then_compare( select_and_then_compare(
"$.school[?(1==1)]", "$.school[?(1==1)]",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!([{ json!([{
"friends": [ "friends": [
{"id": 0, "name": "Millicent Norman"}, {"id": 0, "name": "Millicent Norman"},
@ -128,7 +128,7 @@ fn return_type() {
select_and_then_compare( select_and_then_compare(
"$.school.friends[?(1==1)]", "$.school.friends[?(1==1)]",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!([[ json!([[
{"id": 0, "name": "Millicent Norman"}, {"id": 0, "name": "Millicent Norman"},
{"id": 1, "name": "Vincent Cannon" }, {"id": 1, "name": "Vincent Cannon" },
@ -143,7 +143,7 @@ fn op_default() {
select_and_then_compare( select_and_then_compare(
"$.school[?(@.friends == @.friends)]", "$.school[?(@.friends == @.friends)]",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!([{ json!([{
"friends": [ "friends": [
{"id": 0, "name": "Millicent Norman"}, {"id": 0, "name": "Millicent Norman"},
@ -155,7 +155,7 @@ fn op_default() {
select_and_then_compare( select_and_then_compare(
"$.friends[?(@.name)]", "$.friends[?(@.name)]",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!([ json!([
{ "id" : 1, "name" : "Vincent Cannon" }, { "id" : 1, "name" : "Vincent Cannon" },
{ "id" : 2, "name" : "Gray Berry" } { "id" : 2, "name" : "Gray Berry" }
@ -164,7 +164,7 @@ fn op_default() {
select_and_then_compare( select_and_then_compare(
"$.friends[?(@.id >= 2)]", "$.friends[?(@.id >= 2)]",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!([ json!([
{ "id" : 2, "name" : "Gray Berry" } { "id" : 2, "name" : "Gray Berry" }
]), ]),
@ -172,7 +172,7 @@ fn op_default() {
select_and_then_compare( select_and_then_compare(
"$.friends[?(@.id >= 2 || @.id == 1)]", "$.friends[?(@.id >= 2 || @.id == 1)]",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!([ json!([
{ "id" : 2, "name" : "Gray Berry" }, { "id" : 2, "name" : "Gray Berry" },
{ "id" : 1, "name" : "Vincent Cannon" } { "id" : 1, "name" : "Vincent Cannon" }
@ -181,25 +181,25 @@ fn op_default() {
select_and_then_compare( select_and_then_compare(
"$.friends[?( (@.id >= 2 || @.id == 1) && @.id == 0)]", "$.friends[?( (@.id >= 2 || @.id == 1) && @.id == 0)]",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!([Value::Null]), json!([Value::Null]),
); );
select_and_then_compare( select_and_then_compare(
"$..friends[?(@.id == $.index)].id", "$..friends[?(@.id == $.index)].id",
read_json("./benches/data_obj.json"), read_json("./benchmark/data_obj.json"),
json!([0, 0]), json!([0, 0]),
); );
select_and_then_compare( select_and_then_compare(
"$..book[?($.store.bicycle.price < @.price)].price", "$..book[?($.store.bicycle.price < @.price)].price",
read_json("./benches/example.json"), read_json("./benchmark/example.json"),
json!([22.99]), json!([22.99]),
); );
select_and_then_compare( select_and_then_compare(
"$..book[?( (@.price == 12.99 || @.category == 'reference') && @.price > 10)].price", "$..book[?( (@.price == 12.99 || @.category == 'reference') && @.price > 10)].price",
read_json("./benches/example.json"), read_json("./benchmark/example.json"),
json!([12.99]), json!([12.99]),
); );
@ -365,7 +365,7 @@ fn example() {
select_and_then_compare( select_and_then_compare(
r#"$.store.book[*].author"#, r#"$.store.book[*].author"#,
read_json("./benches/example.json"), read_json("./benchmark/example.json"),
json!([ json!([
"Nigel Rees", "Nigel Rees",
"Evelyn Waugh", "Evelyn Waugh",
@ -376,7 +376,7 @@ fn example() {
select_and_then_compare( select_and_then_compare(
r#"$..author"#, r#"$..author"#,
read_json("./benches/example.json"), read_json("./benchmark/example.json"),
json!([ json!([
"Nigel Rees", "Nigel Rees",
"Evelyn Waugh", "Evelyn Waugh",
@ -387,7 +387,7 @@ fn example() {
select_and_then_compare( select_and_then_compare(
r#"$.store.*"#, r#"$.store.*"#,
read_json("./benches/example.json"), read_json("./benchmark/example.json"),
json!([ json!([
[ [
{"category" : "reference", "author" : "Nigel Rees","title" : "Sayings of the Century", "price" : 8.95}, {"category" : "reference", "author" : "Nigel Rees","title" : "Sayings of the Century", "price" : 8.95},
@ -401,13 +401,13 @@ fn example() {
select_and_then_compare( select_and_then_compare(
r#"$.store..price"#, r#"$.store..price"#,
read_json("./benches/example.json"), read_json("./benchmark/example.json"),
json!([8.95, 12.99, 8.99, 22.99, 19.95]), json!([8.95, 12.99, 8.99, 22.99, 19.95]),
); );
select_and_then_compare( select_and_then_compare(
r#"$..book[2]"#, r#"$..book[2]"#,
read_json("./benches/example.json"), read_json("./benchmark/example.json"),
json!([ json!([
{ {
"category" : "fiction", "category" : "fiction",
@ -421,7 +421,7 @@ fn example() {
select_and_then_compare( select_and_then_compare(
r#"$..book[-2]"#, r#"$..book[-2]"#,
read_json("./benches/example.json"), read_json("./benchmark/example.json"),
json!([ json!([
{ {
"category" : "fiction", "category" : "fiction",
@ -435,7 +435,7 @@ fn example() {
select_and_then_compare( select_and_then_compare(
r#"$..book[0, 1]"#, r#"$..book[0, 1]"#,
read_json("./benches/example.json"), read_json("./benchmark/example.json"),
json!([ json!([
{ {
"category" : "reference", "category" : "reference",
@ -454,7 +454,7 @@ fn example() {
select_and_then_compare( select_and_then_compare(
r#"$..book[:2]"#, r#"$..book[:2]"#,
read_json("./benches/example.json"), read_json("./benchmark/example.json"),
json!([ json!([
{ {
"category" : "reference", "category" : "reference",
@ -473,7 +473,7 @@ fn example() {
select_and_then_compare( select_and_then_compare(
r#"$..book[2:]"#, r#"$..book[2:]"#,
read_json("./benches/example.json"), read_json("./benchmark/example.json"),
json!([ json!([
{ {
"category" : "fiction", "category" : "fiction",
@ -494,7 +494,7 @@ fn example() {
select_and_then_compare( select_and_then_compare(
r#"$..book[?(@.isbn)]"#, r#"$..book[?(@.isbn)]"#,
read_json("./benches/example.json"), read_json("./benchmark/example.json"),
json!([ json!([
{ {
"category" : "fiction", "category" : "fiction",
@ -515,7 +515,7 @@ fn example() {
select_and_then_compare( select_and_then_compare(
r#"$.store.book[?(@.price < 10)]"#, r#"$.store.book[?(@.price < 10)]"#,
read_json("./benches/example.json"), read_json("./benchmark/example.json"),
json!([ json!([
{ {
"category" : "reference", "category" : "reference",
@ -535,8 +535,8 @@ fn example() {
select_and_then_compare( select_and_then_compare(
r#"$..*"#, r#"$..*"#,
read_json("./benches/example.json"), read_json("./benchmark/example.json"),
read_json("./benches/giveme_every_thing_result.json"), read_json("./benchmark/giveme_every_thing_result.json"),
); );
} }
@ -651,7 +651,7 @@ fn all_filter() {
for path in &[r#"$..friends.*"#, r#"$[*].friends.*"#] { for path in &[r#"$..friends.*"#, r#"$[*].friends.*"#] {
select_and_then_compare( select_and_then_compare(
path, path,
read_json("./benches/data_array.json"), read_json("./benchmark/data_array.json"),
json!([ json!([
{ "id" : 0, "name" : "Millicent Norman" }, { "id" : 0, "name" : "Millicent Norman" },
{ "id" : 1, "name" : "Vincent Cannon" }, { "id" : 1, "name" : "Vincent Cannon" },

View File

@ -15,7 +15,7 @@ mod common;
fn compile() { fn compile() {
let compile_object = |path| { let compile_object = |path| {
let mut template = jsonpath::compile(path); let mut template = jsonpath::compile(path);
let json_obj = read_json("./benches/data_obj.json"); let json_obj = read_json("./benchmark/data_obj.json");
let json = template(&json_obj).unwrap(); let json = template(&json_obj).unwrap();
let ret = json!([ let ret = json!([
{"id": 2,"name": "Gray Berry"}, {"id": 2,"name": "Gray Berry"},
@ -26,7 +26,7 @@ fn compile() {
let compile_array = |path| { let compile_array = |path| {
let mut template = jsonpath::compile(path); let mut template = jsonpath::compile(path);
let json_obj = read_json("./benches/data_array.json"); let json_obj = read_json("./benchmark/data_array.json");
let json = template(&json_obj).unwrap(); let json = template(&json_obj).unwrap();
let ret = json!([ let ret = json!([
{"id": 2,"name": "Gray Berry"}, {"id": 2,"name": "Gray Berry"},
@ -59,7 +59,7 @@ fn selector() {
compare_result(json, target); compare_result(json, target);
}; };
let json_obj = read_json("./benches/data_obj.json"); let json_obj = read_json("./benchmark/data_obj.json");
let mut selector = jsonpath::selector(&json_obj); let mut selector = jsonpath::selector(&json_obj);
select( select(
@ -96,7 +96,7 @@ fn selector_as() {
assert_eq!(json, target); assert_eq!(json, target);
}; };
let json_obj = read_json("./benches/data_obj.json"); let json_obj = read_json("./benchmark/data_obj.json");
let mut selector = jsonpath::selector_as::<Friend>(&json_obj); let mut selector = jsonpath::selector_as::<Friend>(&json_obj);
select( select(
@ -129,7 +129,7 @@ fn selector_as() {
#[test] #[test]
fn select() { fn select() {
let json_obj = read_json("./benches/example.json"); let json_obj = read_json("./benchmark/example.json");
let json = jsonpath::select(&json_obj, "$..book[2]").unwrap(); let json = jsonpath::select(&json_obj, "$..book[2]").unwrap();
let ret = json!([{ let ret = json!([{
"category" : "fiction", "category" : "fiction",
@ -143,7 +143,7 @@ fn select() {
#[test] #[test]
fn select_str() { fn select_str() {
let json_str = read_contents("./benches/example.json"); let json_str = read_contents("./benchmark/example.json");
let result_str = jsonpath::select_as_str(&json_str, "$..book[2]").unwrap(); let result_str = jsonpath::select_as_str(&json_str, "$..book[2]").unwrap();
let ret = json!([{ let ret = json!([{
"category" : "fiction", "category" : "fiction",

View File

@ -482,7 +482,7 @@ fn readme_delete() {
#[test] #[test]
fn readme_delete2() { fn readme_delete2() {
let json_obj = common::read_json("./benches/example.json"); let json_obj = common::read_json("./benchmark/example.json");
let ret = jsonpath::delete(json_obj, "$.store.book").unwrap(); let ret = jsonpath::delete(json_obj, "$.store.book").unwrap();

View File

@ -3,7 +3,7 @@ extern crate jsonpath_lib as jsonpath;
extern crate serde_json; extern crate serde_json;
use common::{read_json, setup}; use common::{read_json, setup};
use jsonpath::{Selector, SelectorMut}; use jsonpath::{Selector, SelectorMut, Parser};
use serde_json::Value; use serde_json::Value;
mod common; mod common;
@ -18,7 +18,7 @@ fn selector_mut() {
let result = selector_mut let result = selector_mut
.str_path(r#"$.store..price"#) .str_path(r#"$.store..price"#)
.unwrap() .unwrap()
.value(read_json("./benches/example.json")) .value(read_json("./benchmark/example.json"))
.replace_with(&mut |v| { .replace_with(&mut |v| {
if let Value::Number(n) = v { if let Value::Number(n) = v {
nums.push(n.as_f64().unwrap()); nums.push(n.as_f64().unwrap());
@ -53,3 +53,11 @@ fn selector_mut() {
result result
); );
} }
#[test]
fn selector_node_ref() {
let node = Parser::compile("$.*").unwrap();
let mut selector = Selector::default();
selector.compiled_path(&node);
assert!(std::ptr::eq(selector.node_ref().unwrap(), &node));
}