github.com/v2pro/plz@v0.0.0-20221028024117-e5f9aec5b631/test/go-spew/spew/internalunsafe_test.go (about)

     1  // Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
     2  
     3  // Permission to use, copy, modify, and distribute this software for any
     4  // purpose with or without fee is hereby granted, provided that the above
     5  // copyright notice and this permission notice appear in all copies.
     6  
     7  // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     8  // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     9  // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    10  // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    11  // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
    12  // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    13  // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
    14  
    15  // NOTE: Due to the following build constraints, this file will only be compiled
    16  // when the code is not running on Google App Engine, compiled by GopherJS, and
    17  // "-tags safe" is not added to the go build command line.  The "disableunsafe"
    18  // tag is deprecated and thus should not be used.
    19  // +build !js,!appengine,!safe,!disableunsafe
    20  
    21  /*
    22  This test file is part of the spew package rather than than the spew_test
    23  package because it needs access to internals to properly test certain cases
    24  which are not possible via the public interface since they should never happen.
    25  */
    26  
    27  package spew
    28  
    29  import (
    30  	"bytes"
    31  	"reflect"
    32  	"testing"
    33  	"unsafe"
    34  )
    35  
    36  // changeKind uses unsafe to intentionally change the kind of a reflect.Value to
    37  // the maximum kind value which does not exist.  This is needed to test the
    38  // fallback code which punts to the standard fmt library for new types that
    39  // might get added to the language.
    40  func changeKind(v *reflect.Value, readOnly bool) {
    41  	rvf := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + offsetFlag))
    42  	*rvf = *rvf | ((1<<flagKindWidth - 1) << flagKindShift)
    43  	if readOnly {
    44  		*rvf |= flagRO
    45  	} else {
    46  		*rvf &= ^uintptr(flagRO)
    47  	}
    48  }
    49  
    50  // TestAddedReflectValue tests functionaly of the dump and formatter code which
    51  // falls back to the standard fmt library for new types that might get added to
    52  // the language.
    53  func TestAddedReflectValue(t *testing.T) {
    54  	i := 1
    55  
    56  	// Dump using a reflect.Value that is exported.
    57  	v := reflect.ValueOf(int8(5))
    58  	changeKind(&v, false)
    59  	buf := new(bytes.Buffer)
    60  	d := dumpState{w: buf, cs: &Config}
    61  	d.dump(v)
    62  	s := buf.String()
    63  	want := "(int8) 5"
    64  	if s != want {
    65  		t.Errorf("TestAddedReflectValue #%d\n got: %s want: %s", i, s, want)
    66  	}
    67  	i++
    68  
    69  	// Dump using a reflect.Value that is not exported.
    70  	changeKind(&v, true)
    71  	buf.Reset()
    72  	d.dump(v)
    73  	s = buf.String()
    74  	want = "(int8) <int8 Value>"
    75  	if s != want {
    76  		t.Errorf("TestAddedReflectValue #%d\n got: %s want: %s", i, s, want)
    77  	}
    78  	i++
    79  
    80  	// Formatter using a reflect.Value that is exported.
    81  	changeKind(&v, false)
    82  	buf2 := new(dummyFmtState)
    83  	f := formatState{value: v, cs: &Config, fs: buf2}
    84  	f.format(v)
    85  	s = buf2.String()
    86  	want = "5"
    87  	if s != want {
    88  		t.Errorf("TestAddedReflectValue #%d got: %s want: %s", i, s, want)
    89  	}
    90  	i++
    91  
    92  	// Formatter using a reflect.Value that is not exported.
    93  	changeKind(&v, true)
    94  	buf2.Reset()
    95  	f = formatState{value: v, cs: &Config, fs: buf2}
    96  	f.format(v)
    97  	s = buf2.String()
    98  	want = "<int8 Value>"
    99  	if s != want {
   100  		t.Errorf("TestAddedReflectValue #%d got: %s want: %s", i, s, want)
   101  	}
   102  }