github.com/dgraph-io/simdjson-go@v0.3.0/stage2_build_tape_amd64_test.go (about)

     1  //+build !noasm
     2  //+build !appengine
     3  //+build gc
     4  
     5  /*
     6   * MinIO Cloud Storage, (C) 2020 MinIO, Inc.
     7   *
     8   * Licensed under the Apache License, Version 2.0 (the "License");
     9   * you may not use this file except in compliance with the License.
    10   * You may obtain a copy of the License at
    11   *
    12   *     http://www.apache.org/licenses/LICENSE-2.0
    13   *
    14   * Unless required by applicable law or agreed to in writing, software
    15   * distributed under the License is distributed on an "AS IS" BASIS,
    16   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    17   * See the License for the specific language governing permissions and
    18   * limitations under the License.
    19   */
    20  
    21  package simdjson
    22  
    23  import (
    24  	"testing"
    25  )
    26  
    27  func TestStage2BuildTape(t *testing.T) {
    28  
    29  	var floatHexRepresentation1 uint64 = 0x69066666666666
    30  	var floatHexRepresentation2 uint64 = 0x79066666666666
    31  
    32  	const nul = '\000'
    33  
    34  	testCases := []struct {
    35  		input    string
    36  		expected []struct {
    37  			c   byte
    38  			val uint64
    39  		}
    40  	}{
    41  		{
    42  			`{"a":"b","c":"dd"}`,
    43  			[]struct {
    44  				c   byte
    45  				val uint64
    46  			}{
    47  				{'r', 0xc},
    48  				{'{', 0xb},
    49  				{'"', 0x2},
    50  				{nul, 0x1},
    51  				{'"', 0x6},
    52  				{nul, 0x1},
    53  				{'"', 0xa},
    54  				{nul, 0x1},
    55  				{'"', 0xe},
    56  				{nul, 0x2},
    57  				{'}', 0x1},
    58  				{'r', 0x0},
    59  			},
    60  		},
    61  		{
    62  			`{"a":"b","c":{"d":"e"}}`,
    63  			[]struct {
    64  				c   byte
    65  				val uint64
    66  			}{
    67  				{'r', 0x10},
    68  				{'{', 0xf},
    69  				{'"', 0x2},
    70  				{nul, 0x1},
    71  				{'"', 0x6},
    72  				{nul, 0x1},
    73  				{'"', 0xa},
    74  				{nul, 0x1},
    75  				{'{', 0xe},
    76  				{'"', 0xf},
    77  				{nul, 0x1},
    78  				{'"', 0x13},
    79  				{nul, 0x1},
    80  				{'}', 0x8},
    81  				{'}', 0x1},
    82  				{'r', 0x0},
    83  			},
    84  		},
    85  		{
    86  			`{"a":"b","c":[{"d":"e"},{"f":"g"}]}`,
    87  			[]struct {
    88  				c   byte
    89  				val uint64
    90  			}{
    91  				{'r', 0x18},
    92  				{'{', 0x17},
    93  				{'"', 0x2},
    94  				{nul, 0x1},
    95  				{'"', 0x6},
    96  				{nul, 0x1},
    97  				{'"', 0xa},
    98  				{nul, 0x1},
    99  				{'[', 0x16},
   100  				{'{', 0xf},
   101  				{'"', 0x10},
   102  				{nul, 0x1},
   103  				{'"', 0x14},
   104  				{nul, 0x1},
   105  				{'}', 0x9},
   106  				{'{', 0x15},
   107  				{'"', 0x1a},
   108  				{nul, 0x1},
   109  				{'"', 0x1e},
   110  				{nul, 0x1},
   111  				{'}', 0xf},
   112  				{']', 0x8},
   113  				{'}', 0x1},
   114  				{'r', 0x0},
   115  			},
   116  		},
   117  		{
   118  			`{"a":true,"b":false,"c":null}   `, // without additional spaces, isValidNullAtom reads beyond buffer capacity
   119  			[]struct {
   120  				c   byte
   121  				val uint64
   122  			}{
   123  				{'r', 0xd},
   124  				{'{', 0xc},
   125  				{'"', 0x2},
   126  				{nul, 0x1},
   127  				{'t', 0x0},
   128  				{'"', 0xb},
   129  				{nul, 0x1},
   130  				{'f', 0x0},
   131  				{'"', 0x15},
   132  				{nul, 0x1},
   133  				{'n', 0x0},
   134  				{'}', 0x1},
   135  				{'r', 0x0},
   136  			},
   137  		},
   138  		{
   139  			`{"a":100,"b":200.2,"c":300,"d":400.4}`,
   140  			[]struct {
   141  				c   byte
   142  				val uint64
   143  			}{
   144  				{'r', 0x14},
   145  				{'{', 0x13},
   146  				{'"', 0x2},
   147  				{nul, 0x1},
   148  				{'l', 0x0},
   149  				{nul, 0x64}, // 100
   150  				{'"', 0xa},
   151  				{nul, 0x1},
   152  				{'d', 0x0},
   153  				{'@', floatHexRepresentation1}, // 200.2
   154  				{'"', 0x14},
   155  				{nul, 0x1},
   156  				{'l', 0x0},
   157  				{nul, 0x12c}, // 300
   158  				{'"', 0x1c},
   159  				{nul, 0x1},
   160  				{'d', 0x0},
   161  				{'@', floatHexRepresentation2}, // 400.4
   162  				{'}', 0x1},
   163  				{'r', 0x0},
   164  			},
   165  		},
   166  	}
   167  
   168  	for i, tc := range testCases {
   169  
   170  		pj := internalParsedJson{}
   171  
   172  		if err := pj.parseMessage([]byte(tc.input)); err != nil {
   173  			t.Errorf("TestStage2BuildTape(%d): got: %v want: nil", i, err)
   174  		}
   175  
   176  		if len(pj.Tape) != len(tc.expected) {
   177  			t.Errorf("TestStage2BuildTape(%d): got: %d want: %d", i, len(pj.Tape), len(tc.expected))
   178  		}
   179  
   180  		for ii, tp := range pj.Tape {
   181  			//c := "'" + string(byte(tp >> 56)) + "'"
   182  			//if byte(tp >> 56) == 0 {
   183  			//	c = "nul"
   184  			//}
   185  			//fmt.Printf("{%s, 0x%x},\n", c, tp&0xffffffffffffff)
   186  			expected := tc.expected[ii].val | (uint64(tc.expected[ii].c) << 56)
   187  			if !alwaysCopyStrings && tp != expected {
   188  				t.Errorf("TestStage2BuildTape(%d): got: %d want: %d", ii, tp, expected)
   189  			}
   190  		}
   191  	}
   192  }
   193  
   194  func TestIsValidTrueAtom(t *testing.T) {
   195  
   196  	testCases := []struct {
   197  		input    string
   198  		expected bool
   199  	}{
   200  		{"true    ", true},
   201  		{"true,   ", true},
   202  		{"true}   ", true},
   203  		{"true]   ", true},
   204  		{"treu    ", false}, // French for true, so perhaps should be true
   205  		{"true1   ", false},
   206  		{"truea   ", false},
   207  	}
   208  
   209  	for _, tc := range testCases {
   210  		same := isValidTrueAtom([]byte(tc.input))
   211  		if same != tc.expected {
   212  			t.Errorf("TestIsValidTrueAtom: got: %v want: %v", same, tc.expected)
   213  		}
   214  	}
   215  }
   216  
   217  func TestIsValidFalseAtom(t *testing.T) {
   218  
   219  	testCases := []struct {
   220  		input    string
   221  		expected bool
   222  	}{
   223  		{"false   ", true},
   224  		{"false,  ", true},
   225  		{"false}  ", true},
   226  		{"false]  ", true},
   227  		{"flase   ", false},
   228  		{"false1  ", false},
   229  		{"falsea  ", false},
   230  	}
   231  
   232  	for _, tc := range testCases {
   233  		same := isValidFalseAtom([]byte(tc.input))
   234  		if same != tc.expected {
   235  			t.Errorf("TestIsValidFalseAtom: got: %v want: %v", same, tc.expected)
   236  		}
   237  	}
   238  }
   239  
   240  func TestIsValidNullAtom(t *testing.T) {
   241  
   242  	testCases := []struct {
   243  		input    string
   244  		expected bool
   245  	}{
   246  		{"null    ", true},
   247  		{"null,   ", true},
   248  		{"null}   ", true},
   249  		{"null]   ", true},
   250  		{"nul     ", false},
   251  		{"null1   ", false},
   252  		{"nulla   ", false},
   253  	}
   254  
   255  	for _, tc := range testCases {
   256  		same := isValidNullAtom([]byte(tc.input))
   257  		if same != tc.expected {
   258  			t.Errorf("TestIsValidNullAtom: got: %v want: %v", same, tc.expected)
   259  		}
   260  	}
   261  }