github.com/bytedance/sonic@v1.11.7-0.20240517092252-d2edb31b167b/ast/api_native_test.go (about) 1 //go:build (amd64 && go1.16 && !go1.23) || (arm64 && go1.20 && !go1.23) 2 // +build amd64,go1.16,!go1.23 arm64,go1.20,!go1.23 3 4 /* 5 * Copyright 2022 ByteDance Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package ast 21 22 import ( 23 `encoding/json` 24 `fmt` 25 `reflect` 26 `runtime` 27 `runtime/debug` 28 `testing` 29 30 `github.com/bytedance/sonic/encoder` 31 `github.com/stretchr/testify/require` 32 ) 33 34 func TestSortNodeTwitter(t *testing.T) { 35 if encoder.EnableFallback { 36 return 37 } 38 root, err := NewSearcher(_TwitterJson).GetByPath() 39 if err != nil { 40 t.Fatal(err) 41 } 42 obj, err := root.MapUseNumber() 43 if err != nil { 44 t.Fatal(err) 45 } 46 exp, err := encoder.Encode(obj, encoder.SortMapKeys|encoder.NoEncoderNewline) 47 if err != nil { 48 t.Fatal(err) 49 } 50 var expObj interface{} 51 require.NoError(t, json.Unmarshal(exp, &expObj)) 52 53 if err := root.SortKeys(true); err != nil { 54 t.Fatal(err) 55 } 56 act, err := root.MarshalJSON() 57 if err != nil { 58 t.Fatal(err) 59 } 60 var actObj interface{} 61 require.NoError(t, json.Unmarshal(act, &actObj)) 62 require.Equal(t, expObj, actObj) 63 require.Equal(t, len(exp), len(act)) 64 require.Equal(t, string(exp), string(act)) 65 } 66 67 func TestNodeAny(t *testing.T) { 68 empty := Node{} 69 _,err := empty.SetAny("any", map[string]interface{}{"a": []int{0}}) 70 if err != nil { 71 t.Fatal(err) 72 } 73 if m, err := empty.Get("any").Interface(); err != nil { 74 t.Fatal(err) 75 } else if v, ok := m.(map[string]interface{}); !ok { 76 t.Fatal(v) 77 } 78 if buf, err := empty.MarshalJSON(); err != nil { 79 t.Fatal(err) 80 } else if string(buf) != `{"any":{"a":[0]}}` { 81 t.Fatal(string(buf)) 82 } 83 if _, err := empty.Set("any2", Node{}); err != nil { 84 t.Fatal(err) 85 } 86 if err := empty.Get("any2").AddAny(nil); err != nil { 87 t.Fatal(err) 88 } 89 if buf, err := empty.MarshalJSON(); err != nil { 90 t.Fatal(err) 91 } else if string(buf) != `{"any":{"a":[0]},"any2":[null]}` { 92 t.Fatal(string(buf)) 93 } 94 if _, err := empty.Get("any2").SetAnyByIndex(0, NewNumber("-0.0")); err != nil { 95 t.Fatal(err) 96 } 97 if buf, err := empty.MarshalJSON(); err != nil { 98 t.Fatal(err) 99 } else if string(buf) != `{"any":{"a":[0]},"any2":[-0.0]}` { 100 t.Fatal(string(buf)) 101 } 102 } 103 104 105 func TestTypeCast2(t *testing.T) { 106 type tcase struct { 107 method string 108 node Node 109 exp interface{} 110 err error 111 } 112 var cases = []tcase{ 113 {"Raw", NewAny(""), "\"\"", nil}, 114 } 115 116 for i, c := range cases { 117 fmt.Println(i, c) 118 rt := reflect.ValueOf(&c.node) 119 m := rt.MethodByName(c.method) 120 rets := m.Call([]reflect.Value{}) 121 if len(rets) != 2 { 122 t.Fatal(i, rets) 123 } 124 require.Equal(t, c.exp, rets[0].Interface()) 125 v := rets[1].Interface(); 126 if v != c.err { 127 t.Fatal(i, v) 128 } 129 } 130 } 131 132 func TestStackAny(t *testing.T) { 133 var obj = stackObj() 134 any := NewAny(obj) 135 fmt.Printf("any: %#v\n", any) 136 runtime.GC() 137 debug.FreeOSMemory() 138 println("finish GC") 139 buf, err := any.MarshalJSON() 140 println("finish marshal") 141 if err != nil { 142 t.Fatal(err) 143 } 144 if string(buf) != "1" { 145 t.Fatal(string(buf)) 146 } 147 } 148 149 150 func Test_Export(t *testing.T) { 151 type args struct { 152 src string 153 path []interface{} 154 } 155 tests := []struct { 156 name string 157 args args 158 wantStart int 159 wantEnd int 160 wantTyp int 161 wantErr bool 162 wantValid bool 163 }{ 164 {"bool", args{`[true ,2]`, []interface{}{0}}, 1, 5, V_TRUE, false, true}, 165 {"bool", args{`[t2ue ,2]`, []interface{}{0}}, 1, 5, V_TRUE, false, false}, 166 {"number", args{`[1 ,2]`, []interface{}{0}}, 1, 2, V_NUMBER, false, true}, 167 {"number", args{`[1w ,2]`, []interface{}{0}}, 1, 3, V_NUMBER, false, false}, 168 {"string", args{`[" " ,2]`, []interface{}{0}}, 1, 4, V_STRING, false, true}, 169 {"string", args{`[" "] ,2]`, []interface{}{0}}, 1, 4, V_STRING, false, true}, 170 {"object", args{`[{"":""} ,2]`, []interface{}{0}}, 1, 8, V_OBJECT, false, true}, 171 {"object", args{`[{x} ,2]`, []interface{}{0}}, 1, 4, V_OBJECT, false, false}, 172 {"arrauy", args{`[[{}] ,2]`, []interface{}{0}}, 1, 5, V_ARRAY, false, true}, 173 {"arrauy", args{`[[xx] ,2]`, []interface{}{0}}, 1, 5, V_ARRAY, false, false}, 174 } 175 for _, tt := range tests { 176 t.Run(tt.name, func(t *testing.T) { 177 gotStart, gotEnd, gotTyp, err := _GetByPath(tt.args.src, tt.args.path...) 178 if (err != nil) != tt.wantErr { 179 t.Errorf("_GetByPath() error = %v, wantErr %v", err, tt.wantErr) 180 return 181 } 182 if gotStart != tt.wantStart { 183 t.Errorf("_GetByPath() gotStart = %v, want %v", gotStart, tt.wantStart) 184 } 185 if gotEnd != tt.wantEnd { 186 t.Errorf("_GetByPath() gotEnd = %v, want %v", gotEnd, tt.wantEnd) 187 } 188 if gotTyp != tt.wantTyp { 189 t.Errorf("_GetByPath() gotTyp = %v, want %v", gotTyp, tt.wantTyp) 190 } 191 gotStart, gotEnd, err = _SkipFast(tt.args.src, tt.wantStart) 192 if (err != nil) != tt.wantErr { 193 t.Errorf("_SkipFast() error = %v, wantErr %v", err, tt.wantErr) 194 return 195 } 196 if gotStart != tt.wantStart { 197 t.Errorf("_SkipFast() gotStart = %v, want %v", gotStart, tt.wantStart) 198 } 199 if gotEnd != tt.wantEnd { 200 t.Errorf("_SkipFast() gotEnd = %v, want %v", gotEnd, tt.wantEnd) 201 } 202 valid := _ValidSyntax(tt.args.src[tt.wantStart:tt.wantEnd]) 203 if valid != tt.wantValid { 204 t.Errorf("_ValidSyntax() gotValid = %v, want %v", valid, tt.wantValid) 205 } 206 }) 207 } 208 }