errors_test.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // Copyright 2018 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. package errors
  5. import (
  6. "errors"
  7. "reflect"
  8. "strings"
  9. "testing"
  10. )
  11. func TestNonFatal(t *testing.T) {
  12. type (
  13. method = interface{} // merge | appendRequiredNotSet | appendInvalidUTF8
  14. merge struct {
  15. inErr error
  16. wantOk bool
  17. }
  18. appendRequiredNotSet struct{ inField string }
  19. appendInvalidUTF8 struct{ inField string }
  20. )
  21. tests := []struct {
  22. label string
  23. methods []method
  24. wantErr error
  25. }{{
  26. label: "IgnoreNil",
  27. methods: []method{
  28. merge{inErr: nil, wantOk: true},
  29. },
  30. }, {
  31. label: "IgnoreFatal",
  32. methods: []method{
  33. merge{inErr: errors.New("fatal error")},
  34. },
  35. }, {
  36. label: "MergeNonFatal",
  37. methods: []method{
  38. appendRequiredNotSet{"foo"},
  39. merge{inErr: customRequiredNotSetError{}, wantOk: true},
  40. appendInvalidUTF8{"bar"},
  41. merge{inErr: customInvalidUTF8Error{}, wantOk: true},
  42. merge{inErr: NonFatalErrors{
  43. requiredNotSetError("fizz"),
  44. invalidUTF8Error("buzz"),
  45. }, wantOk: true},
  46. merge{inErr: errors.New("fatal error")}, // not stored
  47. },
  48. wantErr: NonFatalErrors{
  49. requiredNotSetError("foo"),
  50. customRequiredNotSetError{},
  51. invalidUTF8Error("bar"),
  52. customInvalidUTF8Error{},
  53. requiredNotSetError("fizz"),
  54. invalidUTF8Error("buzz"),
  55. },
  56. }}
  57. for _, tt := range tests {
  58. t.Run(tt.label, func(t *testing.T) {
  59. var nerr NonFatal
  60. for _, m := range tt.methods {
  61. switch m := m.(type) {
  62. case merge:
  63. if gotOk := nerr.Merge(m.inErr); gotOk != m.wantOk {
  64. t.Errorf("Merge() = %v, want %v", gotOk, m.wantOk)
  65. }
  66. case appendRequiredNotSet:
  67. nerr.AppendRequiredNotSet(m.inField)
  68. case appendInvalidUTF8:
  69. nerr.AppendInvalidUTF8(m.inField)
  70. default:
  71. t.Fatalf("invalid method: %T", m)
  72. }
  73. }
  74. if !reflect.DeepEqual(nerr.E, tt.wantErr) {
  75. t.Errorf("NonFatal.E = %v, want %v", nerr.E, tt.wantErr)
  76. }
  77. })
  78. }
  79. }
  80. type customInvalidUTF8Error struct{}
  81. func (customInvalidUTF8Error) Error() string { return "invalid UTF-8 detected" }
  82. func (customInvalidUTF8Error) InvalidUTF8() bool { return true }
  83. type customRequiredNotSetError struct{}
  84. func (customRequiredNotSetError) Error() string { return "required field not set" }
  85. func (customRequiredNotSetError) RequiredNotSet() bool { return true }
  86. func TestNewPrefix(t *testing.T) {
  87. e1 := New("abc")
  88. got := e1.Error()
  89. if !strings.HasPrefix(got, "proto:") {
  90. t.Errorf("missing \"proto:\" prefix in %q", got)
  91. }
  92. if !strings.Contains(got, "abc") {
  93. t.Errorf("missing text \"abc\" in %q", got)
  94. }
  95. e2 := New("%v", e1)
  96. got = e2.Error()
  97. if !strings.HasPrefix(got, "proto:") {
  98. t.Errorf("missing \"proto:\" prefix in %q", got)
  99. }
  100. // Test to make sure prefix is removed from the embedded error.
  101. if strings.Contains(strings.TrimPrefix(got, "proto:"), "proto:") {
  102. t.Errorf("prefix \"proto:\" not elided in embedded error: %q", got)
  103. }
  104. }