gtf_test.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. package sample
  2. import (
  3. "testing"
  4. )
  5. func TestGrammarParsing(t *testing.T) {
  6. tests := []struct {
  7. name string
  8. grammar map[string]string
  9. startRule string
  10. input string
  11. want bool
  12. }{
  13. {
  14. name: "simple object",
  15. grammar: map[string]string{
  16. "object": `"{" "}"`,
  17. },
  18. startRule: "object",
  19. input: "{}",
  20. want: true,
  21. },
  22. {
  23. name: "simple array",
  24. grammar: map[string]string{
  25. "array": `"[" "]"`,
  26. },
  27. startRule: "array",
  28. input: "[]",
  29. want: true,
  30. },
  31. {
  32. name: "character class",
  33. grammar: map[string]string{
  34. "digit": `[0-9]`,
  35. },
  36. startRule: "digit",
  37. input: "5",
  38. want: true,
  39. },
  40. {
  41. name: "alternation",
  42. grammar: map[string]string{
  43. "bool": `"true" | "false"`,
  44. },
  45. startRule: "bool",
  46. input: "true",
  47. want: true,
  48. },
  49. {
  50. name: "repetition",
  51. grammar: map[string]string{
  52. "digits": `[0-9]+`,
  53. },
  54. startRule: "digits",
  55. input: "123",
  56. want: true,
  57. },
  58. {
  59. name: "nested rules",
  60. grammar: map[string]string{
  61. "value": `object | array`,
  62. "object": `"{" "}"`,
  63. "array": `"[" "]"`,
  64. },
  65. startRule: "value",
  66. input: "{}",
  67. want: true,
  68. },
  69. }
  70. for _, tt := range tests {
  71. t.Run(tt.name, func(t *testing.T) {
  72. parser := NewParser(tt.grammar)
  73. machine, err := parser.Parse(tt.startRule)
  74. if err != nil {
  75. t.Fatalf("Parse() error = %v", err)
  76. }
  77. matcher := NewMatcher(machine)
  78. got, err := matcher.Match(tt.input)
  79. if err != nil {
  80. t.Fatalf("Match() error = %v", err)
  81. }
  82. if got != tt.want {
  83. t.Errorf("Match() = %v, want %v", got, tt.want)
  84. }
  85. })
  86. }
  87. }
  88. func TestJSONGrammar(t *testing.T) {
  89. tests := []struct {
  90. name string
  91. input string
  92. want bool
  93. }{
  94. {"empty object", "{}", true},
  95. {"empty array", "[]", true},
  96. {"simple string", `"hello"`, true},
  97. {"simple number", "123", true},
  98. {"simple boolean", "true", true},
  99. {"simple null", "null", true},
  100. {"object with string", `{"key": "value"}`, true},
  101. {"array with numbers", "[1, 2, 3]", true},
  102. {"nested object", `{"obj": {"key": "value"}}`, true},
  103. {"nested array", `[1, [2, 3], 4]`, true},
  104. {"invalid object", "{", false},
  105. {"invalid array", "[1, 2", false},
  106. {"invalid string", `"hello`, false},
  107. }
  108. parser := NewParser(DefaultGrammar)
  109. machine, err := parser.Parse("value")
  110. if err != nil {
  111. t.Fatalf("Parse() error = %v", err)
  112. }
  113. matcher := NewMatcher(machine)
  114. for _, tt := range tests {
  115. t.Run(tt.name, func(t *testing.T) {
  116. got, err := matcher.Match(tt.input)
  117. if tt.want {
  118. if err != nil {
  119. t.Errorf("Match() error = %v", err)
  120. }
  121. if !got {
  122. t.Errorf("Match() = false, want true")
  123. }
  124. } else {
  125. if err == nil && got {
  126. t.Errorf("Match() = true, want false")
  127. }
  128. }
  129. })
  130. }
  131. }