k8s.io/kube-openapi@v0.0.0-20240228011516-70dd3763d340/pkg/internal/third_party/go-json-experiment/json/token_test.go (about)

     1  // Copyright 2020 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package json
     6  
     7  import (
     8  	"math"
     9  	"reflect"
    10  	"testing"
    11  )
    12  
    13  func TestTokenStringAllocations(t *testing.T) {
    14  	if testing.CoverMode() != "" {
    15  		t.Skip("coverage mode breaks the compiler optimization this depends on")
    16  	}
    17  
    18  	tok := rawToken(`"hello"`)
    19  	var m map[string]bool
    20  	got := int(testing.AllocsPerRun(10, func() {
    21  		// This function uses tok.String() is a non-escaping manner
    22  		// (i.e., looking it up in a Go map). It should not allocate.
    23  		if m[tok.String()] {
    24  			panic("never executed")
    25  		}
    26  	}))
    27  	if got > 0 {
    28  		t.Errorf("Token.String allocated %d times, want 0", got)
    29  	}
    30  }
    31  
    32  func TestTokenAccessors(t *testing.T) {
    33  	type token struct {
    34  		Bool   bool
    35  		String string
    36  		Float  float64
    37  		Int    int64
    38  		Uint   uint64
    39  		Kind   Kind
    40  	}
    41  
    42  	tests := []struct {
    43  		in   Token
    44  		want token
    45  	}{
    46  		{Token{}, token{String: "<invalid json.Token>"}},
    47  		{Null, token{String: "null", Kind: 'n'}},
    48  		{False, token{Bool: false, String: "false", Kind: 'f'}},
    49  		{True, token{Bool: true, String: "true", Kind: 't'}},
    50  		{Bool(false), token{Bool: false, String: "false", Kind: 'f'}},
    51  		{Bool(true), token{Bool: true, String: "true", Kind: 't'}},
    52  		{ObjectStart, token{String: "{", Kind: '{'}},
    53  		{ObjectEnd, token{String: "}", Kind: '}'}},
    54  		{ArrayStart, token{String: "[", Kind: '['}},
    55  		{ArrayEnd, token{String: "]", Kind: ']'}},
    56  		{String(""), token{String: "", Kind: '"'}},
    57  		{String("hello, world!"), token{String: "hello, world!", Kind: '"'}},
    58  		{rawToken(`"hello, world!"`), token{String: "hello, world!", Kind: '"'}},
    59  		{Float(0), token{String: "0", Float: 0, Int: 0, Uint: 0, Kind: '0'}},
    60  		{Float(math.Copysign(0, -1)), token{String: "-0", Float: math.Copysign(0, -1), Int: 0, Uint: 0, Kind: '0'}},
    61  		{Float(math.NaN()), token{String: "NaN", Float: math.NaN(), Int: 0, Uint: 0, Kind: '"'}},
    62  		{Float(math.Inf(+1)), token{String: "Infinity", Float: math.Inf(+1), Kind: '"'}},
    63  		{Float(math.Inf(-1)), token{String: "-Infinity", Float: math.Inf(-1), Kind: '"'}},
    64  		{Int(minInt64), token{String: "-9223372036854775808", Float: minInt64, Int: minInt64, Uint: minUint64, Kind: '0'}},
    65  		{Int(minInt64 + 1), token{String: "-9223372036854775807", Float: minInt64 + 1, Int: minInt64 + 1, Uint: minUint64, Kind: '0'}},
    66  		{Int(-1), token{String: "-1", Float: -1, Int: -1, Uint: minUint64, Kind: '0'}},
    67  		{Int(0), token{String: "0", Float: 0, Int: 0, Uint: 0, Kind: '0'}},
    68  		{Int(+1), token{String: "1", Float: +1, Int: +1, Uint: +1, Kind: '0'}},
    69  		{Int(maxInt64 - 1), token{String: "9223372036854775806", Float: maxInt64 - 1, Int: maxInt64 - 1, Uint: maxInt64 - 1, Kind: '0'}},
    70  		{Int(maxInt64), token{String: "9223372036854775807", Float: maxInt64, Int: maxInt64, Uint: maxInt64, Kind: '0'}},
    71  		{Uint(minUint64), token{String: "0", Kind: '0'}},
    72  		{Uint(minUint64 + 1), token{String: "1", Float: minUint64 + 1, Int: minUint64 + 1, Uint: minUint64 + 1, Kind: '0'}},
    73  		{Uint(maxUint64 - 1), token{String: "18446744073709551614", Float: maxUint64 - 1, Int: maxInt64, Uint: maxUint64 - 1, Kind: '0'}},
    74  		{Uint(maxUint64), token{String: "18446744073709551615", Float: maxUint64, Int: maxInt64, Uint: maxUint64, Kind: '0'}},
    75  		{rawToken(`-0`), token{String: "-0", Float: math.Copysign(0, -1), Int: 0, Uint: 0, Kind: '0'}},
    76  		{rawToken(`1e1000`), token{String: "1e1000", Float: math.MaxFloat64, Int: maxInt64, Uint: maxUint64, Kind: '0'}},
    77  		{rawToken(`-1e1000`), token{String: "-1e1000", Float: -math.MaxFloat64, Int: minInt64, Uint: minUint64, Kind: '0'}},
    78  		{rawToken(`0.1`), token{String: "0.1", Float: 0.1, Int: 0, Uint: 0, Kind: '0'}},
    79  		{rawToken(`0.5`), token{String: "0.5", Float: 0.5, Int: 0, Uint: 0, Kind: '0'}},
    80  		{rawToken(`0.9`), token{String: "0.9", Float: 0.9, Int: 0, Uint: 0, Kind: '0'}},
    81  		{rawToken(`1.1`), token{String: "1.1", Float: 1.1, Int: 1, Uint: 1, Kind: '0'}},
    82  		{rawToken(`-0.1`), token{String: "-0.1", Float: -0.1, Int: 0, Uint: 0, Kind: '0'}},
    83  		{rawToken(`-0.5`), token{String: "-0.5", Float: -0.5, Int: 0, Uint: 0, Kind: '0'}},
    84  		{rawToken(`-0.9`), token{String: "-0.9", Float: -0.9, Int: 0, Uint: 0, Kind: '0'}},
    85  		{rawToken(`-1.1`), token{String: "-1.1", Float: -1.1, Int: -1, Uint: 0, Kind: '0'}},
    86  		{rawToken(`99999999999999999999`), token{String: "99999999999999999999", Float: 1e20 - 1, Int: maxInt64, Uint: maxUint64, Kind: '0'}},
    87  		{rawToken(`-99999999999999999999`), token{String: "-99999999999999999999", Float: -1e20 - 1, Int: minInt64, Uint: minUint64, Kind: '0'}},
    88  	}
    89  
    90  	for _, tt := range tests {
    91  		t.Run("", func(t *testing.T) {
    92  			got := token{
    93  				Bool: func() bool {
    94  					defer func() { recover() }()
    95  					return tt.in.Bool()
    96  				}(),
    97  				String: tt.in.String(),
    98  				Float: func() float64 {
    99  					defer func() { recover() }()
   100  					return tt.in.Float()
   101  				}(),
   102  				Int: func() int64 {
   103  					defer func() { recover() }()
   104  					return tt.in.Int()
   105  				}(),
   106  				Uint: func() uint64 {
   107  					defer func() { recover() }()
   108  					return tt.in.Uint()
   109  				}(),
   110  				Kind: tt.in.Kind(),
   111  			}
   112  
   113  			if got.Bool != tt.want.Bool {
   114  				t.Errorf("Token(%s).Bool() = %v, want %v", tt.in, got.Bool, tt.want.Bool)
   115  			}
   116  			if got.String != tt.want.String {
   117  				t.Errorf("Token(%s).String() = %v, want %v", tt.in, got.String, tt.want.String)
   118  			}
   119  			if math.Float64bits(got.Float) != math.Float64bits(tt.want.Float) {
   120  				t.Errorf("Token(%s).Float() = %v, want %v", tt.in, got.Float, tt.want.Float)
   121  			}
   122  			if got.Int != tt.want.Int {
   123  				t.Errorf("Token(%s).Int() = %v, want %v", tt.in, got.Int, tt.want.Int)
   124  			}
   125  			if got.Uint != tt.want.Uint {
   126  				t.Errorf("Token(%s).Uint() = %v, want %v", tt.in, got.Uint, tt.want.Uint)
   127  			}
   128  			if got.Kind != tt.want.Kind {
   129  				t.Errorf("Token(%s).Kind() = %v, want %v", tt.in, got.Kind, tt.want.Kind)
   130  			}
   131  		})
   132  	}
   133  }
   134  
   135  func TestTokenClone(t *testing.T) {
   136  	tests := []struct {
   137  		in           Token
   138  		wantExactRaw bool
   139  	}{
   140  		{Token{}, true},
   141  		{Null, true},
   142  		{False, true},
   143  		{True, true},
   144  		{ObjectStart, true},
   145  		{ObjectEnd, true},
   146  		{ArrayStart, true},
   147  		{ArrayEnd, true},
   148  		{String("hello, world!"), true},
   149  		{rawToken(`"hello, world!"`), false},
   150  		{Float(3.14159), true},
   151  		{rawToken(`3.14159`), false},
   152  	}
   153  
   154  	for _, tt := range tests {
   155  		t.Run("", func(t *testing.T) {
   156  			got := tt.in.Clone()
   157  			if !reflect.DeepEqual(got, tt.in) {
   158  				t.Errorf("Token(%s) == Token(%s).Clone() = false, want true", tt.in, tt.in)
   159  			}
   160  			gotExactRaw := got.raw == tt.in.raw
   161  			if gotExactRaw != tt.wantExactRaw {
   162  				t.Errorf("Token(%s).raw == Token(%s).Clone().raw = %v, want %v", tt.in, tt.in, gotExactRaw, tt.wantExactRaw)
   163  			}
   164  		})
   165  	}
   166  }