github.com/minio/simdjson-go@v0.4.6-0.20231116094823-04d21cddf993/stage2_build_tape_amd64_test.go (about)

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