subject.go 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package unit
  2. import (
  3. "bytes"
  4. "fmt"
  5. "runtime"
  6. "strings"
  7. )
  8. type Subject struct {
  9. assert *Assertion
  10. name string
  11. }
  12. func NewSubject(assert *Assertion) *Subject {
  13. return &Subject{
  14. assert: assert,
  15. name: "",
  16. }
  17. }
  18. // decorate prefixes the string with the file and line of the call site
  19. // and inserts the final newline if needed and indentation tabs for formatting.
  20. func decorate(s string) string {
  21. _, file, line, ok := runtime.Caller(3)
  22. if strings.Contains(file, "testing") {
  23. _, file, line, ok = runtime.Caller(4)
  24. }
  25. if ok {
  26. // Truncate file name at last file name separator.
  27. if index := strings.LastIndex(file, "/"); index >= 0 {
  28. file = file[index+1:]
  29. } else if index = strings.LastIndex(file, "\\"); index >= 0 {
  30. file = file[index+1:]
  31. }
  32. } else {
  33. file = "???"
  34. line = 1
  35. }
  36. buf := new(bytes.Buffer)
  37. // Every line is indented at least one tab.
  38. buf.WriteString(" ")
  39. fmt.Fprintf(buf, "%s:%d: ", file, line)
  40. lines := strings.Split(s, "\n")
  41. if l := len(lines); l > 1 && lines[l-1] == "" {
  42. lines = lines[:l-1]
  43. }
  44. for i, line := range lines {
  45. if i > 0 {
  46. // Second and subsequent lines are indented an extra tab.
  47. buf.WriteString("\n\t\t")
  48. }
  49. buf.WriteString(line)
  50. }
  51. buf.WriteByte('\n')
  52. return buf.String()
  53. }
  54. func (subject *Subject) FailWithMessage(message string) {
  55. fmt.Println(decorate(message))
  56. subject.assert.t.Fail()
  57. }
  58. func (subject *Subject) Named(name string) {
  59. subject.name = name
  60. }
  61. func (subject *Subject) DisplayString(value string) string {
  62. if len(value) == 0 {
  63. value = "unknown"
  64. }
  65. if len(subject.name) == 0 {
  66. return "<" + value + ">"
  67. }
  68. return subject.name + "(<" + value + ">)"
  69. }