tokenize_test.go 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package tokenize
  2. import "fmt"
  3. import "testing"
  4. func Test_tokenize(t *testing.T) {
  5. var test_cases = []struct {
  6. test_str string
  7. want_result tokenizeResult
  8. }{
  9. // emptiness
  10. {"", tokenizeResult{tokens: []string{}}},
  11. // unquoted whitespace
  12. {" ", tokenizeResult{tokens: []string{}}},
  13. {"\t", tokenizeResult{tokens: []string{}}},
  14. {"\n", tokenizeResult{tokens: []string{}}},
  15. {" \t\n", tokenizeResult{tokens: []string{}}},
  16. {" \tfoo", tokenizeResult{tokens: []string{"foo"}}},
  17. {"foo ", tokenizeResult{tokens: []string{"foo"}}},
  18. {"foo bar", tokenizeResult{tokens: []string{"foo", "bar"}}},
  19. {"foo\nbar", tokenizeResult{tokens: []string{"foo", "bar"}}},
  20. {"foo\tbar", tokenizeResult{tokens: []string{"foo", "bar"}}},
  21. // single quotes
  22. {"'", tokenizeResult{tokens: []string{}, code: tokenizeResultCodeMissingEndSingleQuote}},
  23. {"''", tokenizeResult{tokens: []string{""}}},
  24. {"fo''o", tokenizeResult{tokens: []string{"foo"}}},
  25. {"foo '' bar", tokenizeResult{tokens: []string{"foo", "", "bar"}}},
  26. {"foo 'and' bar", tokenizeResult{tokens: []string{"foo", "and", "bar"}}},
  27. {"foo '\\\t\n' bar", tokenizeResult{tokens: []string{"foo", "\\\t\n", "bar"}}},
  28. {"foo ' space bar '", tokenizeResult{tokens: []string{"foo", " space bar "}}},
  29. {"foo 'John \"Spaceman\" Doe'", tokenizeResult{tokens: []string{"foo", "John \"Spaceman\" Doe"}}},
  30. // double quotes
  31. {"\"", tokenizeResult{tokens: []string{}, code: tokenizeResultCodeMissingEndDoubleQuote}},
  32. {"\"\"", tokenizeResult{tokens: []string{""}}},
  33. {"fo\"\"o", tokenizeResult{tokens: []string{"foo"}}},
  34. {"foo \"\" bar", tokenizeResult{tokens: []string{"foo", "", "bar"}}},
  35. {"foo \"and\" bar", tokenizeResult{tokens: []string{"foo", "and", "bar"}}},
  36. {"foo \"\\\t\n\" bar", tokenizeResult{tokens: []string{"foo", "\\\t\n", "bar"}}},
  37. {"foo \" space bar \"", tokenizeResult{tokens: []string{"foo", " space bar "}}},
  38. {"foo \"Joe's lunch\"", tokenizeResult{tokens: []string{"foo", "Joe's lunch"}}},
  39. //
  40. }
  41. for _, tc := range test_cases {
  42. t.Run(fmt.Sprintf("%q", tc.test_str), func(t *testing.T) {
  43. have_result := tokenize(tc.test_str)
  44. if have_result.code != tc.want_result.code {
  45. t.Errorf("unexpected result .code: got %s, want %s in %v", have_result.code, tc.want_result.code, have_result)
  46. return
  47. }
  48. if have_result.err_loc != tc.want_result.err_loc {
  49. t.Errorf("unexpected result .err_loc: got %d, want %d in %v", have_result.err_loc, tc.want_result.err_loc, have_result)
  50. return
  51. }
  52. if len(have_result.tokens) != len(tc.want_result.tokens) {
  53. t.Errorf("unexpected number of result .tokens: got %d, want %d in %v", len(have_result.tokens), len(tc.want_result.tokens), have_result)
  54. return
  55. }
  56. for i := range have_result.tokens {
  57. if have_result.tokens[i] == tc.want_result.tokens[i] {
  58. continue
  59. }
  60. t.Errorf("unexpected token in result .tokens[%d]: got %q, want %q in %v", i, have_result.tokens[i], tc.want_result.tokens[i], have_result)
  61. return
  62. }
  63. })
  64. }
  65. }
  66. func Test_reader_tossUntilNeitherOf(t *testing.T) {
  67. var test_cases = []struct {
  68. test_data string
  69. test_needles string
  70. test_startpos uint
  71. want_endpos uint
  72. want_ok bool
  73. }{
  74. {"", "", 0, 0, false},
  75. {"", "x", 0, 0, false},
  76. {"", "xy", 0, 0, false},
  77. {"x", "", 0, 0, false},
  78. {"x", "x", 0, 1, true},
  79. {"x", "xy", 0, 1, true},
  80. {"x", "yx", 0, 1, true},
  81. {"xa", "x", 0, 1, true},
  82. {"xa", "xy", 0, 1, true},
  83. {"xa", "yx", 0, 1, true},
  84. {"xya", "x", 0, 1, true},
  85. {"xya", "xy", 0, 2, true},
  86. {"xya", "yx", 0, 2, true},
  87. {"xxya", "x", 1, 2, true},
  88. {"xxya", "xy", 1, 3, true},
  89. {"xxya", "yx", 1, 3, true},
  90. }
  91. for _, tc := range test_cases {
  92. t.Run(fmt.Sprintf("%q[%d:]-%q", tc.test_data, tc.test_startpos, tc.test_needles), func(t *testing.T) {
  93. test_reader := reader{data: tc.test_data}
  94. test_reader.pos = tc.test_startpos
  95. have_ok := test_reader.tossUntilNeitherOf(tc.test_needles)
  96. if test_reader.pos != tc.want_endpos {
  97. t.Errorf("unexpected position after toss: got %d, want %d", test_reader.pos, tc.want_endpos)
  98. return
  99. }
  100. if have_ok != tc.want_ok {
  101. t.Errorf("unexpected ok: got %v, want %v", have_ok, tc.want_ok)
  102. return
  103. }
  104. })
  105. }
  106. }