@@ -10,7 +10,46 @@ import (
1010 "testing"
1111)
1212
13- var json_data interface {}
13+ type Data struct {
14+ Store * Store `json:"store"`
15+ Expensive float64 `json:"expensive"`
16+ }
17+
18+ type Store struct {
19+ Book []Goods `json:"book"`
20+ Bicycle []Goods `json:"bicycle"`
21+ }
22+
23+ type Goods interface {
24+ GetPrice () float64
25+ }
26+
27+ type Book struct {
28+ Category string `json:"category,omitempty"`
29+ Author string `json:"author"`
30+ Title string `json:"title"`
31+ Price float64 `json:"price"`
32+ ISBN string `json:"isbn"`
33+ Tags []string `json:"-"`
34+ }
35+
36+ func (b * Book ) GetPrice () float64 {
37+ return b .Price
38+ }
39+
40+ type Bicycle struct {
41+ Color string `json:"colour"`
42+ Price float64
43+ }
44+
45+ func (b * Bicycle ) GetPrice () float64 {
46+ return b .Price
47+ }
48+
49+ var (
50+ json_data interface {}
51+ structData * Data
52+ )
1453
1554func init () {
1655 data := `
@@ -53,6 +92,51 @@ func init() {
5392}
5493`
5594 json .Unmarshal ([]byte (data ), & json_data )
95+
96+ structData = & Data {
97+ Store : & Store {
98+ Book : []Goods {
99+ & Book {
100+ Category : "reference" ,
101+ Author : "Nigel Rees" ,
102+ Title : "Sayings of the Century" ,
103+ Price : 8.95 ,
104+ },
105+ & Book {
106+ Category : "fiction" ,
107+ Author : "Evelyn Waugh" ,
108+ Title : "Sword of Honour" ,
109+ Price : 12.99 ,
110+ Tags : []string {"fiction" , "best-seller" , "best-deal" },
111+ },
112+ & Book {
113+ Category : "fiction" ,
114+ Author : "Herman Melville" ,
115+ Title : "Moby Dick" ,
116+ ISBN : "0-553-21311-3" ,
117+ Price : 8.99 ,
118+ },
119+ & Book {
120+ Category : "fiction" ,
121+ Author : "J. R. R. Tolkien" ,
122+ Title : "The Lord of the Rings" ,
123+ ISBN : "0-395-19395-8" ,
124+ Price : 22.99 ,
125+ },
126+ },
127+ Bicycle : []Goods {
128+ & Bicycle {
129+ Color : "red" ,
130+ Price : 19.95 ,
131+ },
132+ & Bicycle {
133+ Color : "brown" ,
134+ Price : 9.99 ,
135+ },
136+ },
137+ },
138+ Expensive : 10 ,
139+ }
56140}
57141
58142func Test_jsonpath_JsonPathLookup_1 (t * testing.T ) {
@@ -65,7 +149,7 @@ func Test_jsonpath_JsonPathLookup_1(t *testing.T) {
65149 // single index
66150 res , _ = JsonPathLookup (json_data , "$.store.book[0].price" )
67151 if res_v , ok := res .(float64 ); ok != true || res_v != 8.95 {
68- t .Errorf ("$.store.book[0].price should be 8.95" )
152+ t .Errorf ("$.store.book[0].price should be 8.95, received: %v" , res )
69153 }
70154
71155 // nagtive single index
@@ -114,6 +198,65 @@ func Test_jsonpath_JsonPathLookup_1(t *testing.T) {
114198 }
115199}
116200
201+ func Test_jsonpath_JsonPathLookup_structs_1 (t * testing.T ) {
202+ // key from root
203+ res , _ := JsonPathLookup (structData , "$.expensive" )
204+ if res_v , ok := res .(float64 ); ok != true || res_v != 10.0 {
205+ t .Errorf ("expensive should be 10" )
206+ }
207+
208+ // single index
209+ res , _ = JsonPathLookup (structData , "$.store.book[0].price" )
210+ if res_v , ok := res .(float64 ); ok != true || res_v != 8.95 {
211+ t .Errorf ("$.store.book[0].price should be 8.95, received: %v" , res )
212+ }
213+
214+ // nagtive single index
215+ res , _ = JsonPathLookup (structData , "$.store.book[-1].isbn" )
216+ if res_v , ok := res .(string ); ok != true || res_v != "0-395-19395-8" {
217+ t .Errorf ("$.store.book[-1].isbn should be \" 0-395-19395-8\" , received: %v" , res )
218+ }
219+
220+ // multiple index
221+ res , err := JsonPathLookup (structData , "$.store.book[0,1].price" )
222+ t .Log (err , res )
223+ if res_v , ok := res .([]interface {}); ok != true || res_v [0 ].(float64 ) != 8.95 || res_v [1 ].(float64 ) != 12.99 {
224+ t .Errorf ("exp: [8.95, 12.99], got: %v" , res )
225+ }
226+
227+ // multiple index
228+ res , err = JsonPathLookup (structData , "$.store.book[0,1].title" )
229+ t .Log (err , res )
230+ if res_v , ok := res .([]interface {}); ok != true {
231+ if res_v [0 ].(string ) != "Sayings of the Century" || res_v [1 ].(string ) != "Sword of Honour" {
232+ t .Errorf ("title are wrong: %v" , res )
233+ }
234+ }
235+
236+ // full array
237+ res , err = JsonPathLookup (structData , "$.store.book[0:].price" )
238+ t .Log (err , res )
239+ if res_v , ok := res .([]interface {}); ok != true || res_v [0 ].(float64 ) != 8.95 || res_v [1 ].(float64 ) != 12.99 || res_v [2 ].(float64 ) != 8.99 || res_v [3 ].(float64 ) != 22.99 {
240+ t .Errorf ("exp: [8.95, 12.99, 8.99, 22.99], got: %v" , res )
241+ }
242+
243+ // range
244+ res , err = JsonPathLookup (structData , "$.store.book[0:1].price" )
245+ t .Log (err , res )
246+ if res_v , ok := res .([]interface {}); ok != true || res_v [0 ].(float64 ) != 8.95 || res_v [1 ].(float64 ) != 12.99 {
247+ t .Errorf ("exp: [8.95, 12.99], got: %v" , res )
248+ }
249+
250+ // range
251+ res , err = JsonPathLookup (structData , "$.store.book[0:1].title" )
252+ t .Log (err , res )
253+ if res_v , ok := res .([]interface {}); ok != true {
254+ if res_v [0 ].(string ) != "Sayings of the Century" || res_v [1 ].(string ) != "Sword of Honour" {
255+ t .Errorf ("title are wrong: %v" , res )
256+ }
257+ }
258+ }
259+
117260func Test_jsonpath_JsonPathLookup_filter (t * testing.T ) {
118261 res , err := JsonPathLookup (json_data , "$.store.book[?(@.isbn)].isbn" )
119262 t .Log (err , res )
@@ -124,7 +267,7 @@ func Test_jsonpath_JsonPathLookup_filter(t *testing.T) {
124267 }
125268 }
126269
127- res , err = JsonPathLookup (json_data , "$.store.book[?(@.price > 10)].title " )
270+ res , err = JsonPathLookup (json_data , "$.store.book[?(@.price > 10)].Title " )
128271 t .Log (err , res )
129272 if res_v , ok := res .([]interface {}); ok != true {
130273 if res_v [0 ].(string ) != "Sword of Honour" || res_v [1 ].(string ) != "The Lord of the Rings" {
@@ -141,6 +284,17 @@ func Test_jsonpath_JsonPathLookup_filter(t *testing.T) {
141284 t .Log (err , res )
142285}
143286
287+ func Test_jsonpath_JsonPathLookup_struct_filter (t * testing.T ) {
288+ res , err := JsonPathLookup (structData , "$.store.book[?(@.isbn)].ISBN" )
289+ t .Log (err , res )
290+
291+ if res_v , ok := res .([]interface {}); ok != true {
292+ if res_v [0 ].(string ) != "0-553-21311-3" || res_v [1 ].(string ) != "0-395-19395-8" {
293+ t .Errorf ("error: %v" , res )
294+ }
295+ }
296+ }
297+
144298func Test_jsonpath_authors_of_all_books (t * testing.T ) {
145299 query := "store.book[*].author"
146300 expected := []string {
@@ -459,6 +613,45 @@ func Test_jsonpath_get_key(t *testing.T) {
459613 }
460614}
461615
616+ func Test_jsonpath_get_key_struct (t * testing.T ) {
617+ res , err := get_key (structData , "Store" )
618+ fmt .Println (err , res )
619+ if err != nil {
620+ t .Errorf ("failed to get struct key: %v" , err )
621+ return
622+ }
623+ if res_v , ok := res .(* Store ); ! ok || len (res_v .Bicycle ) != 2 || len (res_v .Book ) != 4 {
624+ t .Error ("get field of struct failed" )
625+ return
626+ }
627+
628+ res , err = get_key (structData , "hah" )
629+ if err == nil {
630+ t .Error ("failed to raise missing key error" )
631+ return
632+ }
633+
634+ res , err = get_key (structData , "store" )
635+ if err != nil {
636+ t .Errorf ("failed to get struct key: %v" , err )
637+ return
638+ }
639+ if res_v , ok := res .(* Store ); ! ok || len (res_v .Bicycle ) != 2 || len (res_v .Book ) != 4 {
640+ t .Error ("get field of struct by json tag name failed" )
641+ return
642+ }
643+
644+ res , err = get_key (structData .Store .Book [0 ], "Category" )
645+ if err != nil {
646+ t .Errorf ("failed to get field of struct masked by interface: %v" , err )
647+ return
648+ }
649+ if res .(string ) != "reference" {
650+ t .Errorf ("not expected value returned: %v" , res )
651+ return
652+ }
653+ }
654+
462655func Test_jsonpath_get_idx (t * testing.T ) {
463656 obj := []interface {}{1 , 2 , 3 , 4 }
464657 res , err := get_idx (obj , 0 )
0 commit comments