...

Source file src/github.com/json-iterator/go/misc_tests/jsoniter_int_test.go

Documentation: github.com/json-iterator/go/misc_tests

     1  // +build go1.8
     2  
     3  package misc_tests
     4  
     5  import (
     6  	"bytes"
     7  	"encoding/json"
     8  	"io"
     9  	"io/ioutil"
    10  	"math/rand"
    11  	"strconv"
    12  	"testing"
    13  
    14  	"github.com/json-iterator/go"
    15  	"github.com/stretchr/testify/require"
    16  )
    17  
    18  func Test_read_uint64_invalid(t *testing.T) {
    19  	should := require.New(t)
    20  	iter := jsoniter.ParseString(jsoniter.ConfigDefault, ",")
    21  	iter.ReadUint64()
    22  	should.NotNil(iter.Error)
    23  }
    24  
    25  func Test_read_int32_array(t *testing.T) {
    26  	should := require.New(t)
    27  	input := `[123,456,789]`
    28  	val := make([]int32, 0)
    29  	jsoniter.UnmarshalFromString(input, &val)
    30  	should.Equal(3, len(val))
    31  }
    32  
    33  func Test_read_int64_array(t *testing.T) {
    34  	should := require.New(t)
    35  	input := `[123,456,789]`
    36  	val := make([]int64, 0)
    37  	jsoniter.UnmarshalFromString(input, &val)
    38  	should.Equal(3, len(val))
    39  }
    40  
    41  func Test_wrap_int(t *testing.T) {
    42  	should := require.New(t)
    43  	str, err := jsoniter.MarshalToString(jsoniter.WrapInt64(100))
    44  	should.Nil(err)
    45  	should.Equal("100", str)
    46  }
    47  
    48  func Test_write_val_int(t *testing.T) {
    49  	should := require.New(t)
    50  	buf := &bytes.Buffer{}
    51  	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
    52  	stream.WriteVal(1001)
    53  	stream.Flush()
    54  	should.Nil(stream.Error)
    55  	should.Equal("1001", buf.String())
    56  }
    57  
    58  func Test_write_val_int_ptr(t *testing.T) {
    59  	should := require.New(t)
    60  	buf := &bytes.Buffer{}
    61  	stream := jsoniter.NewStream(jsoniter.ConfigDefault, buf, 4096)
    62  	val := 1001
    63  	stream.WriteVal(&val)
    64  	stream.Flush()
    65  	should.Nil(stream.Error)
    66  	should.Equal("1001", buf.String())
    67  }
    68  
    69  func Test_float_as_int(t *testing.T) {
    70  	should := require.New(t)
    71  	var i int
    72  	should.NotNil(jsoniter.Unmarshal([]byte(`1.1`), &i))
    73  }
    74  
    75  // chunkedData is io.Reader which returns random amount of data in range [1, chunkedData.chunkSize].
    76  // It simulates chunked data on from HTTP server, which is commonly used by net/http package.
    77  type chunkedData struct {
    78  	chunkSize int
    79  	data      []byte
    80  	head      int
    81  }
    82  
    83  // Read is implementation of the io.Reader which returns random amount of data in range [1, chunkedData.chunkSize].
    84  func (c *chunkedData) Read(p []byte) (n int, err error) {
    85  	to := c.head + int(rand.Int31n(int32(c.chunkSize))+1)
    86  
    87  	// copy does not copy more data then p can consume
    88  	n = copy(p, c.data[c.head:to])
    89  	c.head = c.head + n
    90  	if c.head >= len(c.data) {
    91  		err = io.EOF
    92  	}
    93  	return n, err
    94  }
    95  
    96  // TestIterator_ReadInt_chunkedInput validates the behaviour of Iterator.ReadInt() method in where:
    97  // - it reads data from io.Reader,
    98  // - expected value is 0 (zero)
    99  // - Iterator.tail == Iterator.head
   100  // - Iterator.tail < len(Iterator.buf)
   101  // - value in buffer after Iterator.tail is presented from previous read and has '.' character.
   102  func TestIterator_ReadInt_chunkedInput(t *testing.T) {
   103  	should := require.New(t)
   104  
   105  	data := &chunkedData{
   106  		data: jsonFloatIntArray(t, 10),
   107  	}
   108  
   109  	// because this test is rely on randomness of chunkedData, we are doing multiple iterations to
   110  	// be sure, that we can hit a required case.
   111  	for data.chunkSize = 3; data.chunkSize <= len(data.data); data.chunkSize++ {
   112  		data.head = 0
   113  
   114  		iter := jsoniter.Parse(jsoniter.ConfigDefault, data, data.chunkSize)
   115  		i := 0
   116  		for iter.ReadArray() {
   117  			// every even item is float, let's just skip it.
   118  			if i%2 == 0 {
   119  				iter.Skip()
   120  				i++
   121  				continue
   122  			}
   123  
   124  			should.Zero(iter.ReadInt())
   125  			should.NoError(iter.Error)
   126  
   127  			i++
   128  		}
   129  	}
   130  }
   131  
   132  // jsonFloatIntArray generates JSON array where every
   133  //  - even item is float 0.1
   134  //  - odd item is integer 0
   135  //
   136  //  [0.1, 0, 0.1, 0]
   137  func jsonFloatIntArray(t *testing.T, numberOfItems int) []byte {
   138  	t.Helper()
   139  	numbers := make([]jsoniter.Any, numberOfItems)
   140  	for i := range numbers {
   141  		switch i % 2 {
   142  		case 0:
   143  			numbers[i] = jsoniter.WrapFloat64(0.1)
   144  		default:
   145  			numbers[i] = jsoniter.WrapInt64(0)
   146  		}
   147  	}
   148  
   149  	fixture, err := jsoniter.ConfigFastest.Marshal(numbers)
   150  	if err != nil {
   151  		panic(err)
   152  	}
   153  
   154  	b := &bytes.Buffer{}
   155  
   156  	require.NoError(
   157  		t,
   158  		json.Compact(b, fixture),
   159  		"json should be compactable",
   160  	)
   161  	return b.Bytes()
   162  }
   163  
   164  func Benchmark_jsoniter_encode_int(b *testing.B) {
   165  	stream := jsoniter.NewStream(jsoniter.ConfigDefault, ioutil.Discard, 64)
   166  	for n := 0; n < b.N; n++ {
   167  		stream.Reset(nil)
   168  		stream.WriteUint64(0xffffffff)
   169  	}
   170  }
   171  
   172  func Benchmark_itoa(b *testing.B) {
   173  	for n := 0; n < b.N; n++ {
   174  		strconv.FormatInt(0xffffffff, 10)
   175  	}
   176  }
   177  
   178  func Benchmark_jsoniter_int(b *testing.B) {
   179  	iter := jsoniter.NewIterator(jsoniter.ConfigDefault)
   180  	input := []byte(`100`)
   181  	for n := 0; n < b.N; n++ {
   182  		iter.ResetBytes(input)
   183  		iter.ReadInt64()
   184  	}
   185  }
   186  
   187  func Benchmark_json_int(b *testing.B) {
   188  	for n := 0; n < b.N; n++ {
   189  		result := int64(0)
   190  		json.Unmarshal([]byte(`-100`), &result)
   191  	}
   192  }
   193  

View as plain text