You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

141 lines
3.6 KiB

  1. package logrus
  2. import (
  3. "bytes"
  4. "errors"
  5. "fmt"
  6. "strings"
  7. "testing"
  8. "time"
  9. )
  10. func TestFormatting(t *testing.T) {
  11. tf := &TextFormatter{DisableColors: true}
  12. testCases := []struct {
  13. value string
  14. expected string
  15. }{
  16. {`foo`, "time=\"0001-01-01T00:00:00Z\" level=panic test=foo\n"},
  17. }
  18. for _, tc := range testCases {
  19. b, _ := tf.Format(WithField("test", tc.value))
  20. if string(b) != tc.expected {
  21. t.Errorf("formatting expected for %q (result was %q instead of %q)", tc.value, string(b), tc.expected)
  22. }
  23. }
  24. }
  25. func TestQuoting(t *testing.T) {
  26. tf := &TextFormatter{DisableColors: true}
  27. checkQuoting := func(q bool, value interface{}) {
  28. b, _ := tf.Format(WithField("test", value))
  29. idx := bytes.Index(b, ([]byte)("test="))
  30. cont := bytes.Contains(b[idx+5:], []byte("\""))
  31. if cont != q {
  32. if q {
  33. t.Errorf("quoting expected for: %#v", value)
  34. } else {
  35. t.Errorf("quoting not expected for: %#v", value)
  36. }
  37. }
  38. }
  39. checkQuoting(false, "")
  40. checkQuoting(false, "abcd")
  41. checkQuoting(false, "v1.0")
  42. checkQuoting(false, "1234567890")
  43. checkQuoting(false, "/foobar")
  44. checkQuoting(false, "foo_bar")
  45. checkQuoting(false, "foo@bar")
  46. checkQuoting(false, "foobar^")
  47. checkQuoting(false, "+/-_^@f.oobar")
  48. checkQuoting(true, "foobar$")
  49. checkQuoting(true, "&foobar")
  50. checkQuoting(true, "x y")
  51. checkQuoting(true, "x,y")
  52. checkQuoting(false, errors.New("invalid"))
  53. checkQuoting(true, errors.New("invalid argument"))
  54. // Test for quoting empty fields.
  55. tf.QuoteEmptyFields = true
  56. checkQuoting(true, "")
  57. checkQuoting(false, "abcd")
  58. checkQuoting(true, errors.New("invalid argument"))
  59. }
  60. func TestEscaping(t *testing.T) {
  61. tf := &TextFormatter{DisableColors: true}
  62. testCases := []struct {
  63. value string
  64. expected string
  65. }{
  66. {`ba"r`, `ba\"r`},
  67. {`ba'r`, `ba'r`},
  68. }
  69. for _, tc := range testCases {
  70. b, _ := tf.Format(WithField("test", tc.value))
  71. if !bytes.Contains(b, []byte(tc.expected)) {
  72. t.Errorf("escaping expected for %q (result was %q instead of %q)", tc.value, string(b), tc.expected)
  73. }
  74. }
  75. }
  76. func TestEscaping_Interface(t *testing.T) {
  77. tf := &TextFormatter{DisableColors: true}
  78. ts := time.Now()
  79. testCases := []struct {
  80. value interface{}
  81. expected string
  82. }{
  83. {ts, fmt.Sprintf("\"%s\"", ts.String())},
  84. {errors.New("error: something went wrong"), "\"error: something went wrong\""},
  85. }
  86. for _, tc := range testCases {
  87. b, _ := tf.Format(WithField("test", tc.value))
  88. if !bytes.Contains(b, []byte(tc.expected)) {
  89. t.Errorf("escaping expected for %q (result was %q instead of %q)", tc.value, string(b), tc.expected)
  90. }
  91. }
  92. }
  93. func TestTimestampFormat(t *testing.T) {
  94. checkTimeStr := func(format string) {
  95. customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format}
  96. customStr, _ := customFormatter.Format(WithField("test", "test"))
  97. timeStart := bytes.Index(customStr, ([]byte)("time="))
  98. timeEnd := bytes.Index(customStr, ([]byte)("level="))
  99. timeStr := customStr[timeStart+5+len("\"") : timeEnd-1-len("\"")]
  100. if format == "" {
  101. format = time.RFC3339
  102. }
  103. _, e := time.Parse(format, (string)(timeStr))
  104. if e != nil {
  105. t.Errorf("time string \"%s\" did not match provided time format \"%s\": %s", timeStr, format, e)
  106. }
  107. }
  108. checkTimeStr("2006-01-02T15:04:05.000000000Z07:00")
  109. checkTimeStr("Mon Jan _2 15:04:05 2006")
  110. checkTimeStr("")
  111. }
  112. func TestDisableTimestampWithColoredOutput(t *testing.T) {
  113. tf := &TextFormatter{DisableTimestamp: true, ForceColors: true}
  114. b, _ := tf.Format(WithField("test", "test"))
  115. if strings.Contains(string(b), "[0000]") {
  116. t.Error("timestamp not expected when DisableTimestamp is true")
  117. }
  118. }
  119. // TODO add tests for sorting etc., this requires a parser for the text
  120. // formatter output.