Skip to content

Commit 594a1c3

Browse files
author
meir
committed
added tests directory
1 parent 8aff440 commit 594a1c3

File tree

11 files changed

+1642
-69
lines changed

11 files changed

+1642
-69
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
name = "JsonPathCalculator"
2+
name = "jsonpath_calculator"
33
version = "0.1.0"
44
edition = "2021"
55

src/grammer.pest

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,25 @@
1-
literal = @{(!("."|"*"|"\""|"'"|"["|"]"|"="|" "|"("|")"|"{"|"}"|"|"|"<"|">"|"!"|"$") ~ ANY)+}
1+
literal = @{(!("."|"*"|"\""|"'"|"["|"]"|"="|" "|"("|")"|"{"|"}"|"|"|"<"|">"|"!") ~ ANY)+}
22

3-
string = _{"\"" ~ string_value ~ "\""}
4-
string_value = @{(!("\"") ~ ANY)+}
3+
string = _{("'" ~ (string_value) ~ "'") | ("\"" ~ (string_value) ~ "\"") | ("\"" ~ (string_value_escape_1) ~ "\"") | ("'" ~ (string_value_escape_2) ~ "'")}
4+
string_escape = @{"\\"}
5+
string_value = @{((!("\""|"\\"|"'") ~ ANY)+)*}
6+
string_value_escape_1 = @{((!("\""|"\\") ~ ANY)+ | string_escape ~ ("\"" | "\\"))*}
7+
string_value_escape_2 = @{((!("'"|"\\") ~ ANY)+ | string_escape ~ ("'" | "\\"))*}
58

69
string_list = {string ~ ("," ~ string)*}
710

11+
pos_number = @{ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* | ASCII_DIGIT}
812
number = @{"-"? ~ ASCII_NONZERO_DIGIT ~ ASCII_DIGIT* | "-"? ~ ASCII_DIGIT}
913

1014
decimal = @{number ~ ("." ~ ASCII_DIGIT+)?}
1115

1216
numbers_list = {number ~ ("," ~ number)*}
1317

14-
numbers_range = {full_range | right_range | all_range | left_range }
15-
right_range = {":" ~ number}
16-
all_range = {":"}
17-
left_range = {number ~ ":"}
18-
full_range = {number ~ ":" ~ number}
18+
numbers_range = {(full_range | right_range | all_range | left_range)}
19+
right_range = {":" ~ number ~ ((":" ~ pos_number) | ":")?}
20+
all_range = {":" ~ ((":" ~ pos_number) | ":")?}
21+
left_range = {number ~ ":" ~ ((":" ~ pos_number) | ":")?}
22+
full_range = {number ~ ":" ~ number ~ ((":" ~ pos_number) | ":")?}
1923

2024
from_current = {"@" ~ root?}
2125
from_root = {"$" ~ root?}
@@ -31,9 +35,13 @@ op = _{ge | gt | le | lt | eq | ne | re}
3135
ne = @{"!="}
3236
re = @{"=~"}
3337

34-
term = _{select_term | decimal | string}
38+
boolean = _{boolean_true | boolean_false}
39+
boolean_true = @{"true"}
40+
boolean_false = @{"false"}
3541

36-
single_filter = {term ~ op ~ term}
42+
term = _{select_term | decimal | string | boolean}
43+
44+
single_filter = {term ~ op ~ term | term}
3745

3846
filter_relation = _{and | or}
3947
and = {"&&"}

src/json_path.rs

Lines changed: 127 additions & 57 deletions
Large diffs are not rendered by default.

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ mod json_path_tests {
358358

359359
#[test]
360360
fn test_filter_with_full_scan() {
361-
verify_json!(path:"$..[?(@.code==\"2\")].code", json:[{"code":"1"},{"code":"2"}], results:["2", "2"]);
361+
verify_json!(path:"$..[?(@.code==\"2\")].code", json:[{"code":"1"},{"code":"2"}], results:["2"]);
362362
}
363363

364364
#[test]

tests/array_filter.rs

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
#[macro_use]
2+
extern crate serde_json;
3+
4+
use common::{read_json, select_and_then_compare, setup};
5+
6+
mod common;
7+
8+
#[test]
9+
fn array_range_default() {
10+
setup();
11+
12+
select_and_then_compare(
13+
"$.school.friends[1, 2]",
14+
read_json("./json_examples/data_obj.json"),
15+
json!([
16+
{"id": 1, "name": "Vincent Cannon" },
17+
{"id": 2, "name": "Gray Berry"}
18+
]),
19+
);
20+
}
21+
22+
#[test]
23+
fn array_range_all() {
24+
setup();
25+
26+
select_and_then_compare(
27+
"$[ : ]",
28+
json!(["first", "second"]),
29+
json!(["first", "second"]),
30+
);
31+
}
32+
33+
#[test]
34+
fn array_range_step_all() {
35+
setup();
36+
37+
select_and_then_compare(
38+
"$[::]",
39+
json!(["first", "second", "third", "forth", "fifth"]),
40+
json!(["first", "second", "third", "forth", "fifth"]),
41+
);
42+
}
43+
44+
#[test]
45+
fn array_range_step_only_step_value() {
46+
setup();
47+
48+
select_and_then_compare(
49+
"$[::2]",
50+
json!(["first", "second", "third", "forth", "fifth"]),
51+
json!(["first", "third", "fifth"]),
52+
);
53+
}
54+
55+
#[test]
56+
fn array_range_step_only_start_index() {
57+
setup();
58+
59+
select_and_then_compare(
60+
"$[1::]",
61+
json!(["first", "second", "third", "forth", "fifth"]),
62+
json!(["second", "third", "forth", "fifth"]),
63+
);
64+
}
65+
66+
#[test]
67+
fn array_range_step_empty_step_value() {
68+
setup();
69+
70+
select_and_then_compare(
71+
"$[1:2:]",
72+
json!(["first", "second", "third", "forth", "fifth"]),
73+
json!(["second"]),
74+
);
75+
}
76+
77+
#[test]
78+
fn array_range_step_empty_end_index() {
79+
setup();
80+
81+
select_and_then_compare(
82+
"$[1::2]",
83+
json!(["first", "second", "third", "forth", "fifth"]),
84+
json!(["second", "forth"]),
85+
);
86+
}
87+
88+
#[test]
89+
fn array_range_step_by_1() {
90+
setup();
91+
92+
select_and_then_compare(
93+
"$[0:3:1]",
94+
json!(["first", "second", "third", "forth", "fifth"]),
95+
json!(["first", "second", "third"]),
96+
);
97+
}
98+
99+
#[test]
100+
fn array_range_step_by_2() {
101+
setup();
102+
103+
select_and_then_compare(
104+
"$[0:3:2]",
105+
json!(["first", "second", "third", "forth", "fifth"]),
106+
json!(["first", "third"]),
107+
);
108+
}
109+
110+
#[test]
111+
fn array_range_only_negative_index() {
112+
setup();
113+
114+
select_and_then_compare(
115+
"$[-4:]",
116+
json!(["first", "second", "third"]),
117+
json!(["first", "second", "third"]),
118+
);
119+
}
120+
121+
#[test]
122+
fn array_range_only_end_index() {
123+
setup();
124+
125+
select_and_then_compare(
126+
"$[:4]",
127+
json!(["first", "second", "third"]),
128+
json!(["first", "second", "third"]),
129+
);
130+
}
131+
132+
#[test]
133+
fn array_range_only_from_index() {
134+
setup();
135+
136+
select_and_then_compare(
137+
"$.school.friends[1: ]",
138+
read_json("./json_examples/data_obj.json"),
139+
json!([
140+
{"id": 1, "name": "Vincent Cannon" },
141+
{"id": 2, "name": "Gray Berry"}
142+
]),
143+
);
144+
}
145+
146+
#[test]
147+
fn array_range_only_nagative_end_index() {
148+
setup();
149+
150+
select_and_then_compare(
151+
"$.school.friends[:-2]",
152+
read_json("./json_examples/data_obj.json"),
153+
json!([
154+
{"id": 0, "name": "Millicent Norman"}
155+
]),
156+
);
157+
}
158+
159+
#[test]
160+
fn array_index() {
161+
setup();
162+
163+
select_and_then_compare(
164+
"$..friends[2].name",
165+
read_json("./json_examples/data_obj.json"),
166+
json!(["Gray Berry", "Gray Berry"]),
167+
);
168+
}
169+
170+
#[test]
171+
fn array_all_index() {
172+
setup();
173+
174+
select_and_then_compare(
175+
"$..friends[*].name",
176+
read_json("./json_examples/data_obj.json"),
177+
json!([
178+
"Vincent Cannon",
179+
"Gray Berry",
180+
"Millicent Norman",
181+
"Vincent Cannon",
182+
"Gray Berry"
183+
]),
184+
);
185+
}
186+
187+
#[test]
188+
fn array_all_and_then_key() {
189+
setup();
190+
191+
select_and_then_compare(
192+
"$['school']['friends'][*].['name']",
193+
read_json("./json_examples/data_obj.json"),
194+
json!(["Millicent Norman", "Vincent Cannon", "Gray Berry"]),
195+
);
196+
}
197+
198+
#[test]
199+
fn array_index_and_then_key() {
200+
setup();
201+
202+
select_and_then_compare(
203+
"$['school']['friends'][0].['name']",
204+
read_json("./json_examples/data_obj.json"),
205+
json!(["Millicent Norman"]),
206+
);
207+
}
208+
209+
#[test]
210+
fn array_multiple_key() {
211+
setup();
212+
213+
select_and_then_compare(
214+
r#"$.["eyeColor", "name"]"#,
215+
read_json("./json_examples/data_obj.json"),
216+
json!(["blue", "Leonor Herman"]),
217+
);
218+
}
219+
220+
#[test]
221+
fn bugs40_bracket_notation_after_recursive_descent() {
222+
setup();
223+
224+
select_and_then_compare(
225+
"$..[0]",
226+
json!([
227+
"first",
228+
{
229+
"key": [
230+
"first nested",
231+
{
232+
"more": [
233+
{"nested": ["deepest", "second"]},
234+
["more", "values"]
235+
]
236+
}
237+
]
238+
}
239+
]),
240+
json!([
241+
"first",
242+
"first nested",
243+
{
244+
"nested" : [
245+
"deepest",
246+
"second"
247+
]
248+
},
249+
"deepest",
250+
"more"
251+
]),
252+
);
253+
}

tests/common.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
use std::io::Read;
2+
3+
use serde_json::Value;
4+
5+
use jsonpath_calculator::{
6+
create,
7+
compile,
8+
};
9+
10+
#[allow(dead_code)]
11+
pub fn setup() {}
12+
13+
#[allow(dead_code)]
14+
pub fn read_json(path: &str) -> Value {
15+
let mut f = std::fs::File::open(path).unwrap();
16+
let mut contents = String::new();
17+
f.read_to_string(&mut contents).unwrap();
18+
serde_json::from_str(&contents).unwrap()
19+
}
20+
21+
#[allow(dead_code)]
22+
pub fn read_contents(path: &str) -> String {
23+
let mut f = std::fs::File::open(path).unwrap();
24+
let mut contents = String::new();
25+
f.read_to_string(&mut contents).unwrap();
26+
contents
27+
}
28+
29+
#[allow(dead_code)]
30+
pub fn select_and_then_compare(path: &str, json: Value, target: Value) {
31+
let json_path = compile(path).unwrap();
32+
let calculator = create(&json_path);
33+
let result = calculator.calc(&json);
34+
35+
assert_eq!(
36+
result.iter().map(|v| v.clone().clone()).collect::<Vec<Value>>(),
37+
match target {
38+
Value::Array(vec) => vec,
39+
_ => panic!("Give me the Array!"),
40+
},
41+
"{}",
42+
path
43+
);
44+
45+
// let mut selector = Selector::default();
46+
// let result = selector
47+
// .str_path(path)
48+
// .unwrap()
49+
// .value(&json)
50+
// .select()
51+
// .unwrap();
52+
// assert_eq!(
53+
// result.iter().map(|v| v.clone().clone()).collect::<Vec<Value>>(),
54+
// match target {
55+
// Value::Array(vec) => vec,
56+
// _ => panic!("Give me the Array!"),
57+
// },
58+
// "{}",
59+
// path
60+
// );
61+
}
62+
63+
#[allow(dead_code)]
64+
pub fn compare_result(result: Vec<&Value>, target: Value) {
65+
let result = serde_json::to_value(result).unwrap();
66+
assert_eq!(result, target);
67+
}

0 commit comments

Comments
 (0)