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 }