assertion.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. package assertion
  2. import (
  3. "fmt"
  4. "reflect"
  5. "github.com/onsi/gomega/types"
  6. )
  7. type Assertion struct {
  8. actualInput interface{}
  9. failWrapper *types.GomegaFailWrapper
  10. offset int
  11. extra []interface{}
  12. }
  13. func New(actualInput interface{}, failWrapper *types.GomegaFailWrapper, offset int, extra ...interface{}) *Assertion {
  14. return &Assertion{
  15. actualInput: actualInput,
  16. failWrapper: failWrapper,
  17. offset: offset,
  18. extra: extra,
  19. }
  20. }
  21. func (assertion *Assertion) Should(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
  22. assertion.failWrapper.TWithHelper.Helper()
  23. return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, true, optionalDescription...)
  24. }
  25. func (assertion *Assertion) ShouldNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
  26. assertion.failWrapper.TWithHelper.Helper()
  27. return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, false, optionalDescription...)
  28. }
  29. func (assertion *Assertion) To(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
  30. assertion.failWrapper.TWithHelper.Helper()
  31. return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, true, optionalDescription...)
  32. }
  33. func (assertion *Assertion) ToNot(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
  34. assertion.failWrapper.TWithHelper.Helper()
  35. return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, false, optionalDescription...)
  36. }
  37. func (assertion *Assertion) NotTo(matcher types.GomegaMatcher, optionalDescription ...interface{}) bool {
  38. assertion.failWrapper.TWithHelper.Helper()
  39. return assertion.vetExtras(optionalDescription...) && assertion.match(matcher, false, optionalDescription...)
  40. }
  41. func (assertion *Assertion) buildDescription(optionalDescription ...interface{}) string {
  42. switch len(optionalDescription) {
  43. case 0:
  44. return ""
  45. default:
  46. return fmt.Sprintf(optionalDescription[0].(string), optionalDescription[1:]...) + "\n"
  47. }
  48. }
  49. func (assertion *Assertion) match(matcher types.GomegaMatcher, desiredMatch bool, optionalDescription ...interface{}) bool {
  50. matches, err := matcher.Match(assertion.actualInput)
  51. description := assertion.buildDescription(optionalDescription...)
  52. assertion.failWrapper.TWithHelper.Helper()
  53. if err != nil {
  54. assertion.failWrapper.Fail(description+err.Error(), 2+assertion.offset)
  55. return false
  56. }
  57. if matches != desiredMatch {
  58. var message string
  59. if desiredMatch {
  60. message = matcher.FailureMessage(assertion.actualInput)
  61. } else {
  62. message = matcher.NegatedFailureMessage(assertion.actualInput)
  63. }
  64. assertion.failWrapper.Fail(description+message, 2+assertion.offset)
  65. return false
  66. }
  67. return true
  68. }
  69. func (assertion *Assertion) vetExtras(optionalDescription ...interface{}) bool {
  70. success, message := vetExtras(assertion.extra)
  71. if success {
  72. return true
  73. }
  74. description := assertion.buildDescription(optionalDescription...)
  75. assertion.failWrapper.TWithHelper.Helper()
  76. assertion.failWrapper.Fail(description+message, 2+assertion.offset)
  77. return false
  78. }
  79. func vetExtras(extras []interface{}) (bool, string) {
  80. for i, extra := range extras {
  81. if extra != nil {
  82. zeroValue := reflect.Zero(reflect.TypeOf(extra)).Interface()
  83. if !reflect.DeepEqual(zeroValue, extra) {
  84. message := fmt.Sprintf("Unexpected non-nil/non-zero extra argument at index %d:\n\t<%T>: %#v", i+1, extra, extra)
  85. return false, message
  86. }
  87. }
  88. }
  89. return true, ""
  90. }