GraphQL API and utilities for the rpdata project
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.

225 lines
6.9 KiB

  1. package parsers_test
  2. import (
  3. "fmt"
  4. "git.aiterp.net/rpdata/api/models"
  5. "git.aiterp.net/rpdata/api/services/parsers"
  6. "github.com/stretchr/testify/assert"
  7. "strings"
  8. "testing"
  9. "time"
  10. )
  11. func TestMircPost(t *testing.T) {
  12. table := []struct {
  13. Input string
  14. TS string
  15. Kind string
  16. Nick string
  17. Text string
  18. }{
  19. {
  20. "[12:34] * Stuff does things.",
  21. "12:34:00", "action", "Stuff", "does things.",
  22. },
  23. {
  24. "[12:34] <Stuff> Things said.",
  25. "12:34:00", "text", "Stuff", "Things said.",
  26. },
  27. {
  28. "[13:36:59] <Stuff> Things said.",
  29. "13:36:59", "text", "Stuff", "Things said.",
  30. },
  31. {
  32. "[23:59] <=Scene=> Scenery and such.",
  33. "23:59:00", "scene", "=Scene=", "Scenery and such.",
  34. },
  35. {
  36. "[01:10:11] * =Scene= Scenery and such from the forum or mIRC using my old script.",
  37. "01:10:11", "scene", "=Scene=", "Scenery and such from the forum or mIRC using my old script.",
  38. },
  39. }
  40. for i, row := range table {
  41. t.Run(fmt.Sprintf("Row_%d", i), func(t *testing.T) {
  42. post, err := parsers.MircPost(row.Input, time.Now(), models.Post{})
  43. if err != nil {
  44. t.Fatal("Could not parse post:", err)
  45. }
  46. assert.Equal(t, row.TS, post.Time.Format("15:04:05"), "Timestamps should match.")
  47. assert.Equal(t, row.Kind, post.Kind, "Kinds should match.")
  48. assert.Equal(t, row.Nick, post.Nick, "Kinds should match.")
  49. assert.Equal(t, row.Text, post.Text, "Kinds should match.")
  50. })
  51. }
  52. }
  53. func TestMircPostErrors(t *testing.T) {
  54. table := []struct {
  55. Input string
  56. Err string
  57. }{
  58. {"[12:34] <Stuff> Things said.", ""},
  59. {"[12:34] >Stuff> Things said.", "line is neither action nor text post"},
  60. {"12:34] <Stuff> Things said.", "no timestamp"},
  61. {"* Stuff Things said.", "no timestamp"},
  62. {"", "no timestamp"},
  63. {"[12:34 <Stuff> Things said.", "incomplete timestamp"},
  64. {"[TE:XT] <Stuff> Things said.", "invalid number in timestamp"},
  65. {"[10] <Stuff> Things said.", "invalid timestamp"},
  66. {"[12:34:56:789] <Stuff> Things said.", ""},
  67. {"[12:34:56.789] <Stuff> Things said.", "invalid number in timestamp"},
  68. {"[12:34] <Stuff>", "post is empty"},
  69. {"[12:34] * Stuff", "post is empty"},
  70. {"[12:34] =Scene=", "line is neither action nor text post"},
  71. {"[12:34] <=Scene=>", "post is empty"},
  72. }
  73. for i, row := range table {
  74. t.Run(fmt.Sprintf("Row_%d", i), func(t *testing.T) {
  75. _, err := parsers.MircPost(row.Input, time.Now(), models.Post{})
  76. errProblem := ""
  77. if err != nil {
  78. if e2, ok := err.(*parsers.ParseError); ok {
  79. errProblem = e2.Problem
  80. } else {
  81. errProblem = err.Error()
  82. }
  83. }
  84. assert.Equal(t, row.Err, errProblem, "Error should match")
  85. })
  86. }
  87. }
  88. func TestMircPostNextDay(t *testing.T) {
  89. table := []struct {
  90. Prev time.Time
  91. TS string
  92. Time time.Time
  93. }{
  94. {Prev: parseDate(t, "2019-01-12 12:00:00"), TS: "12:01", Time: parseDate(t, "2019-01-12 12:01:00")},
  95. {Prev: parseDate(t, "2019-04-08 23:51:59"), TS: "00:09", Time: parseDate(t, "2019-04-09 00:09:00")},
  96. {Prev: parseDate(t, "2019-01-12 12:00:00"), TS: "11:29:59", Time: parseDate(t, "2019-01-13 11:29:59")},
  97. }
  98. for i, row := range table {
  99. t.Run(fmt.Sprintf("Row_%d", i), func(t *testing.T) {
  100. input := fmt.Sprintf("[%s] * Stuff does things.", row.TS)
  101. post, err := parsers.MircPost(input, row.Prev, models.Post{Time: row.Prev})
  102. if err != nil {
  103. t.Fatal("Could not parse post:", err)
  104. }
  105. assert.Equal(t, row.Time, post.Time)
  106. })
  107. }
  108. }
  109. func TestMircPostDayPerPostBug(t *testing.T) {
  110. startDate := parseDate(t, "2019-07-20 23:25:00")
  111. table := []struct {
  112. TS string
  113. Time time.Time
  114. }{
  115. {TS: "23:25", Time: parseDate(t, "2019-07-20 23:25:00")},
  116. {TS: "23:45", Time: parseDate(t, "2019-07-20 23:45:00")},
  117. {TS: "23:59", Time: parseDate(t, "2019-07-20 23:59:00")},
  118. {TS: "00:00", Time: parseDate(t, "2019-07-21 00:00:00")},
  119. {TS: "00:03", Time: parseDate(t, "2019-07-21 00:03:00")},
  120. {TS: "00:06", Time: parseDate(t, "2019-07-21 00:06:00")},
  121. {TS: "12:00", Time: parseDate(t, "2019-07-21 12:00:00")},
  122. {TS: "22:00", Time: parseDate(t, "2019-07-21 22:00:00")},
  123. {TS: "23:55", Time: parseDate(t, "2019-07-21 23:55:00")},
  124. {TS: "00:05", Time: parseDate(t, "2019-07-22 00:05:00")},
  125. }
  126. prev := startDate
  127. for i, row := range table {
  128. t.Run(fmt.Sprintf("Row_%d", i), func(t *testing.T) {
  129. input := fmt.Sprintf("[%s] * Test post content.", row.TS)
  130. post, err := parsers.MircPost(input, startDate, models.Post{Time: prev})
  131. if err != nil {
  132. t.Fatal("Could not parse post:", err)
  133. }
  134. prev = post.Time
  135. assert.Equal(t, row.Time, post.Time)
  136. })
  137. }
  138. }
  139. func TestMircLog(t *testing.T) {
  140. parsed, err := parsers.MircLog(testLog, parseDate(t, "2018-05-11 00:00:00"), false)
  141. if err != nil {
  142. t.Fatal("ParseLog", err)
  143. }
  144. assert.Equal(t, testLogPosts, parsed.Posts)
  145. assert.Equal(t, parsed.Posts[0].Time, parsed.Log.Date, "Log's date should be the first post's.")
  146. }
  147. func TestMircLogErrors(t *testing.T) {
  148. _, err1 := parsers.MircLog("\n\n\n\n\n \n\t\r\n", time.Time{}, false)
  149. _, err2 := parsers.MircLog("\n\n\n\n\n[14:57]* Stuff \n\t\r\n", time.Time{}, true)
  150. assert.Equal(t, parsers.ErrEmptyLog, err1)
  151. assert.True(t, parsers.IsParseError(err2))
  152. }
  153. func parseDate(t *testing.T, date string) time.Time {
  154. result, err := time.Parse("2006-01-02 15:04:05", date)
  155. if err != nil {
  156. if t != nil {
  157. t.Fatal("Could not parse date", date, err)
  158. } else {
  159. panic("Could not parse date: " + err.Error())
  160. }
  161. }
  162. return result
  163. }
  164. var testLog = strings.Join([]string{
  165. "[11:21] * Va`ynna_Atana returns to the apartment at the end of another long day. She hangs up her jacket and a green scarf next to the door before going straight to the bathroom; she leaves the door open, though. She walked home with Uvena this time, but the two parted ways downstairs.",
  166. "",
  167. "[11:21] <=Scene=> The weather outside is not pleasant in the slightest. The storm is still going on, visibility is reduced and the worst gusts of wind can be felt inside the apartment as a faint shudder. ",
  168. "",
  169. "[11:",
  170. " [11:27] <Test> Stuff and things.",
  171. }, "\r\n")
  172. var testLogPosts = []*models.Post{
  173. {
  174. ID: "UNASSIGNED",
  175. LogID: "UNASSIGNED",
  176. Time: parseDate(nil, "2018-05-11 11:21:00"),
  177. Kind: "action",
  178. Nick: "Va`ynna_Atana",
  179. Position: 1,
  180. Text: "returns to the apartment at the end of another long day. She hangs up her jacket and a green scarf next to the door before going straight to the bathroom; she leaves the door open, though. She walked home with Uvena this time, but the two parted ways downstairs.",
  181. },
  182. {
  183. ID: "UNASSIGNED",
  184. LogID: "UNASSIGNED",
  185. Time: parseDate(nil, "2018-05-11 11:21:00"),
  186. Kind: "scene",
  187. Nick: "=Scene=",
  188. Position: 2,
  189. Text: "The weather outside is not pleasant in the slightest. The storm is still going on, visibility is reduced and the worst gusts of wind can be felt inside the apartment as a faint shudder.",
  190. },
  191. {
  192. ID: "UNASSIGNED",
  193. LogID: "UNASSIGNED",
  194. Time: parseDate(nil, "2018-05-11 11:27:00"),
  195. Kind: "text",
  196. Nick: "Test",
  197. Position: 3,
  198. Text: "Stuff and things.",
  199. },
  200. }