assertion.go 3.1 KB

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