internalunsafe_test.go 3.2 KB

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