...

Source file src/github.com/bytedance/sonic/ast/encode_test.go

Documentation: github.com/bytedance/sonic/ast

     1  /*
     2   * Copyright 2021 ByteDance Inc.
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  
    17  package ast
    18  
    19  import (
    20      `encoding/json`
    21      `runtime`
    22      `sync`
    23      `testing`
    24  
    25      `github.com/stretchr/testify/require`
    26  )
    27  
    28  func TestGC_Encode(t *testing.T) {
    29      if debugSyncGC {
    30          return
    31      }
    32      root, err := NewSearcher(_TwitterJson).GetByPath()
    33      if err != nil {
    34          t.Fatal(err)
    35      }
    36      root.LoadAll()
    37      _, err = root.MarshalJSON()
    38      if err != nil {
    39          t.Fatal(err)
    40      }
    41      wg := &sync.WaitGroup{}
    42      N := 10000
    43      for i:=0; i<N; i++ {
    44          wg.Add(1)
    45          go func (wg *sync.WaitGroup)  {
    46              defer wg.Done()
    47              root, err := NewSearcher(_TwitterJson).GetByPath()
    48              if err != nil {
    49                  t.Error(err)
    50                  return
    51              }
    52              root.Load()
    53              _, err = root.MarshalJSON()
    54              if err != nil {
    55                  t.Error(err)
    56                  return
    57              }
    58              runtime.GC()
    59          }(wg)
    60      }
    61      wg.Wait()
    62  }
    63  
    64  func TestEncodeNode(t *testing.T) {
    65      data := `{"a":[{},[],-0.1,true,false,null,""],"b":0,"c":true,"d":false,"e":null,"g":""}`
    66      root, e := NewSearcher(data).GetByPath()
    67      if e != nil {
    68          t.Fatal(root)
    69      }
    70      ret, err := root.MarshalJSON()
    71      if err != nil {
    72          t.Fatal(err)
    73      }
    74      if string(ret) != data {
    75          t.Fatal(string(ret))
    76      }
    77      root.skipAllKey()
    78      ret, err = root.MarshalJSON()
    79      if err != nil {
    80          t.Fatal(err)
    81      }
    82      if string(ret) != data {
    83          t.Fatal(string(ret))
    84      }
    85      root.loadAllKey()
    86      ret, err = root.MarshalJSON()
    87      if err != nil {
    88          t.Fatal(err)
    89      }
    90      if string(ret) != data {
    91          t.Fatal(string(ret))
    92      }
    93  }
    94  
    95  type SortableNode struct {
    96      sorted bool
    97  	*Node
    98  }
    99  
   100  func (j *SortableNode) UnmarshalJSON(data []byte) (error) {
   101      j.Node = new(Node)
   102  	return j.Node.UnmarshalJSON(data)
   103  }
   104  
   105  func (j *SortableNode) MarshalJSON() ([]byte, error) {
   106      if !j.sorted {
   107          j.Node.SortKeys(true)
   108          j.sorted = true
   109      }
   110  	return j.Node.MarshalJSON()
   111  }
   112  
   113  func TestMarshalSort(t *testing.T) {
   114      var data = `{"d":3,"a":{"c":1,"b":2},"e":null}`
   115      var obj map[string]*SortableNode
   116      require.NoError(t, json.Unmarshal([]byte(data), &obj))
   117      out, err := json.Marshal(obj)
   118      require.NoError(t, err)
   119      require.Equal(t, `{"a":{"b":2,"c":1},"d":3,"e":null}`, string(out))
   120      out, err = json.Marshal(obj)
   121      require.NoError(t, err)
   122      require.Equal(t, `{"a":{"b":2,"c":1},"d":3,"e":null}`, string(out))
   123  }
   124  
   125  func BenchmarkEncodeRaw_Sonic(b *testing.B) {
   126      data := _TwitterJson
   127      root, e := NewSearcher(data).GetByPath()
   128      if e != nil {
   129          b.Fatal(root)
   130      }
   131      _, err := root.MarshalJSON()
   132      if err != nil {
   133          b.Fatal(err)
   134      }
   135      b.SetBytes(int64(len(data)))
   136      b.ResetTimer()
   137      for i:=0; i<b.N; i++ {
   138          _, err := root.MarshalJSON()
   139          if err != nil {
   140              b.Fatal(err)
   141          }
   142      }
   143  }
   144  
   145  func BenchmarkEncodeSkip_Sonic(b *testing.B) {
   146      data := _TwitterJson
   147      root, e := NewParser(data).Parse()
   148      if e != 0 {
   149          b.Fatal(root)
   150      }
   151      root.skipAllKey()
   152      _, err := root.MarshalJSON()
   153      if err != nil {
   154          b.Fatal(err)
   155      }
   156      b.SetBytes(int64(len(data)))
   157      b.ResetTimer()
   158      for i:=0; i<b.N; i++ {
   159          _, err := root.MarshalJSON()
   160          if err != nil {
   161              b.Fatal(err)
   162          }
   163      }
   164  }
   165  
   166  func BenchmarkEncodeLoad_Sonic(b *testing.B) {
   167      data := _TwitterJson
   168      root, e := NewParser(data).Parse()
   169      if e != 0 {
   170          b.Fatal(root)
   171      }
   172      root.loadAllKey()
   173      _, err := root.MarshalJSON()
   174      if err != nil {
   175          b.Fatal(err)
   176      }
   177      b.SetBytes(int64(len(data)))
   178      b.ResetTimer()
   179      for i:=0; i<b.N; i++ {
   180          _, err := root.MarshalJSON()
   181          if err != nil {
   182              b.Fatal(err)
   183          }
   184      }
   185  }
   186  
   187  func TestEncodeNone(t *testing.T) {
   188      n := NewObject([]Pair{{Key:"a", Value:Node{}}})
   189      out, err := n.MarshalJSON()
   190      require.NoError(t, err)
   191      require.Equal(t, "{}", string(out))
   192      n = NewObject([]Pair{{Key:"a", Value:NewNull()}, {Key:"b", Value:Node{}}})
   193      out, err = n.MarshalJSON()
   194      require.NoError(t, err)
   195      require.Equal(t, `{"a":null}`, string(out))
   196  
   197      n = NewArray([]Node{Node{}})
   198      out, err = n.MarshalJSON()
   199      require.NoError(t, err)
   200      require.Equal(t, "[]", string(out))
   201      n = NewArray([]Node{NewNull(), Node{}})
   202      out, err = n.MarshalJSON()
   203      require.NoError(t, err)
   204      require.Equal(t, `[null]`, string(out))
   205  }
   206  

View as plain text