2
0
Fork 0
mirror of https://github.com/ii64/sonic.git synced 2026-06-21 00:46:43 +08:00
sonic/ast/iterator_test.go
Yi Duan 8405d84e31
feat: optimaze ast.Node API as container of generic values (#150)
* opt: only skip one value when call Iterator.HasNext()

* feat: V_NONE supports Set() and Add()

* feat: add node type V_ANY

* feat: ast.Node implements `json.Unmarshaler`

* fmt: use space instead of tab for indent

* feat: node V_ANY cast to Bool()\Int64()\Float64()\String()\Number()\Map()\Array()Interface()

* feat: V_NULL supports Set() and Add()

Co-authored-by: duanyi.aster <duanyi.aster@bytedance.com>
2021-12-09 15:43:51 +08:00

207 lines
No EOL
4.9 KiB
Go

/*
* Copyright 2021 ByteDance Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ast
import (
`fmt`
`strconv`
`testing`
)
func getTestIteratorSample() (string, int) {
var data []int
var v1 = ""
var v2 = ""
loop := _DEFAULT_NODE_CAP+1
for i:=0;i<loop;i++{
data = append(data, i*i)
v1 += strconv.Itoa(i)
v2 += `"k`+strconv.Itoa(i)+`":`+strconv.Itoa(i)
if i!=loop-1{
v1+=`,`
v2+=`,`
}
}
return `{"array":[`+v1+`], "object":{`+v2+`}}`, loop
}
func TestRawIterator(t *testing.T) {
str, loop := getTestIteratorSample()
fmt.Println(str)
root, err := NewSearcher(str).GetByPath("array")
if err != nil {
t.Fatal(err)
}
ai, _ := root.Values()
i := int64(0)
for ai.HasNext() {
v := &Node{}
if !ai.Next(v) {
t.Fatalf("no next")
}
x, _ := v.Int64()
if i < int64(loop) && x != i {
t.Fatalf("exp:%v, got:%v", i, v)
}
if i != int64(ai.Pos())-1 || i >= int64(ai.Len()) {
t.Fatal(i)
}
i++
}
if i != int64(loop) {
t.Fatal(i)
}
root, err = NewSearcher(str).GetByPath("object")
if err != nil {
t.Fatal(err)
}
mi, _ := root.Properties()
i = int64(0)
for mi.HasNext() {
v := &Pair{}
if !mi.Next(v) {
t.Fatalf("no next")
}
x, _ := v.Value.Int64()
if i < int64(loop) &&( x != i ||v.Key != fmt.Sprintf("k%d", i)) {
vv, _ := v.Value.Interface()
t.Fatalf("exp:%v, got:%v", i, vv)
}
if i != int64(mi.Pos())-1 || i >= int64(mi.Len()) {
t.Fatal(i)
}
i++
}
if i != int64(loop) {
t.Fatal(i)
}
}
func TestIterator(t *testing.T) {
str, loop := getTestIteratorSample()
fmt.Println(str)
root, err := NewParser(str).Parse()
if err != 0 {
t.Fatal(err)
}
ai, _ := root.Get("array").Values()
i := int64(0)
for ai.HasNext() {
v := &Node{}
if !ai.Next(v) {
t.Fatalf("no next")
}
x, _ := v.Int64()
if i < int64(loop) && x != i {
t.Fatalf("exp:%v, got:%v", i, v)
}
if i != int64(ai.Pos())-1 || i >= int64(ai.Len()) {
t.Fatal(i)
}
i++
}
if i != int64(loop) {
t.Fatal(i)
}
root, err = NewParser(str).Parse()
if err != 0 {
t.Fatal(err)
}
mi, _ := root.Get("object").Properties()
i = int64(0)
for mi.HasNext() {
v := &Pair{}
if !mi.Next(v) {
t.Fatalf("no next")
}
x, _ := v.Value.Int64()
if i < int64(loop) &&( x != i ||v.Key != fmt.Sprintf("k%d", i)) {
vv, _ := v.Value.Interface()
t.Fatalf("exp:%v, got:%v", i, vv)
}
if i != int64(mi.Pos())-1 || i >= int64(mi.Len()) {
t.Fatal(i)
}
i++
}
if i != int64(loop) {
t.Fatal(i)
}
}
func BenchmarkArrays(b *testing.B) {
for i:=0;i<b.N;i++{
root,err := NewSearcher(_TwitterJson).GetByPath("statuses",1,"entities","hashtags")
if err != nil {
b.Fatal(err)
}
a, _ := root.Array()
for _,v := range a {
_ = v
}
}
}
func BenchmarkListIterator(b *testing.B) {
for i:=0;i<b.N;i++{
root,err := NewSearcher(_TwitterJson).GetByPath("statuses",1,"entities","hashtags")
if err != nil {
b.Fatal(err)
}
it, _ := root.Values()
for it.HasNext() {
v := &Node{}
if !it.Next(v) {
b.Fatalf("no value")
}
}
}
}
func BenchmarkMap(b *testing.B) {
for i:=0;i<b.N;i++{
root,err := NewSearcher(_TwitterJson).GetByPath("statuses",1, "user")
if err != nil {
b.Fatal(err)
}
m, _ := root.Map()
for k,v := range m {
_ = v
_ = k
}
}
}
func BenchmarkObjectIterator(b *testing.B) {
for i:=0;i<b.N;i++{
root,err := NewSearcher(_TwitterJson).GetByPath("statuses",1, "user")
if err != nil {
b.Fatal(err)
}
it, _ := root.Properties()
for it.HasNext() {
v := &Pair{}
if !it.Next(v) {
b.Fatalf("no value")
}
}
}
}