parser_test.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. package parser
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "strings"
  7. "testing"
  8. "github.com/stretchr/testify/assert"
  9. )
  10. func TestParser(t *testing.T) {
  11. input := `
  12. FROM model1
  13. ADAPTER adapter1
  14. LICENSE MIT
  15. PARAMETER param1 value1
  16. PARAMETER param2 value2
  17. TEMPLATE template1
  18. `
  19. reader := strings.NewReader(input)
  20. commands, err := Parse(reader)
  21. assert.Nil(t, err)
  22. expectedCommands := []Command{
  23. {Name: "model", Args: "model1"},
  24. {Name: "adapter", Args: "adapter1"},
  25. {Name: "license", Args: "MIT"},
  26. {Name: "param1", Args: "value1"},
  27. {Name: "param2", Args: "value2"},
  28. {Name: "template", Args: "template1"},
  29. }
  30. assert.Equal(t, expectedCommands, commands)
  31. }
  32. func TestParserNoFromLine(t *testing.T) {
  33. input := `
  34. PARAMETER param1 value1
  35. PARAMETER param2 value2
  36. `
  37. reader := strings.NewReader(input)
  38. _, err := Parse(reader)
  39. assert.ErrorContains(t, err, "no FROM line")
  40. }
  41. func TestParserParametersMissingValue(t *testing.T) {
  42. input := `
  43. FROM foo
  44. PARAMETER param1
  45. `
  46. reader := strings.NewReader(input)
  47. _, err := Parse(reader)
  48. assert.ErrorIs(t, err, io.ErrUnexpectedEOF)
  49. }
  50. func TestParserMessages(t *testing.T) {
  51. var cases = []struct {
  52. input string
  53. expected []Command
  54. err error
  55. }{
  56. {
  57. `
  58. FROM foo
  59. MESSAGE system You are a Parser. Always Parse things.
  60. `,
  61. []Command{
  62. {Name: "model", Args: "foo"},
  63. {Name: "message", Args: "system: You are a Parser. Always Parse things."},
  64. },
  65. nil,
  66. },
  67. {
  68. `
  69. FROM foo
  70. MESSAGE system You are a Parser. Always Parse things.
  71. MESSAGE user Hey there!
  72. MESSAGE assistant Hello, I want to parse all the things!
  73. `,
  74. []Command{
  75. {Name: "model", Args: "foo"},
  76. {Name: "message", Args: "system: You are a Parser. Always Parse things."},
  77. {Name: "message", Args: "user: Hey there!"},
  78. {Name: "message", Args: "assistant: Hello, I want to parse all the things!"},
  79. },
  80. nil,
  81. },
  82. {
  83. `
  84. FROM foo
  85. MESSAGE system """
  86. You are a multiline Parser. Always Parse things.
  87. """
  88. `,
  89. []Command{
  90. {Name: "model", Args: "foo"},
  91. {Name: "message", Args: "system: \nYou are a multiline Parser. Always Parse things.\n"},
  92. },
  93. nil,
  94. },
  95. {
  96. `
  97. FROM foo
  98. MESSAGE badguy I'm a bad guy!
  99. `,
  100. nil,
  101. errInvalidRole,
  102. },
  103. {
  104. `
  105. FROM foo
  106. MESSAGE system
  107. `,
  108. nil,
  109. io.ErrUnexpectedEOF,
  110. },
  111. {
  112. `
  113. FROM foo
  114. MESSAGE system`,
  115. nil,
  116. io.ErrUnexpectedEOF,
  117. },
  118. }
  119. for _, c := range cases {
  120. t.Run("", func(t *testing.T) {
  121. commands, err := Parse(strings.NewReader(c.input))
  122. assert.ErrorIs(t, err, c.err)
  123. assert.Equal(t, c.expected, commands)
  124. })
  125. }
  126. }
  127. func TestParserQuoted(t *testing.T) {
  128. var cases = []struct {
  129. multiline string
  130. expected []Command
  131. err error
  132. }{
  133. {
  134. `
  135. FROM foo
  136. TEMPLATE """
  137. This is a
  138. multiline template.
  139. """
  140. `,
  141. []Command{
  142. {Name: "model", Args: "foo"},
  143. {Name: "template", Args: "\nThis is a\nmultiline template.\n"},
  144. },
  145. nil,
  146. },
  147. {
  148. `
  149. FROM foo
  150. TEMPLATE """
  151. This is a
  152. multiline template."""
  153. `,
  154. []Command{
  155. {Name: "model", Args: "foo"},
  156. {Name: "template", Args: "\nThis is a\nmultiline template."},
  157. },
  158. nil,
  159. },
  160. {
  161. `
  162. FROM foo
  163. TEMPLATE """This is a
  164. multiline template."""
  165. `,
  166. []Command{
  167. {Name: "model", Args: "foo"},
  168. {Name: "template", Args: "This is a\nmultiline template."},
  169. },
  170. nil,
  171. },
  172. {
  173. `
  174. FROM foo
  175. TEMPLATE """This is a multiline template."""
  176. `,
  177. []Command{
  178. {Name: "model", Args: "foo"},
  179. {Name: "template", Args: "This is a multiline template."},
  180. },
  181. nil,
  182. },
  183. {
  184. `
  185. FROM foo
  186. TEMPLATE """This is a multiline template.""
  187. `,
  188. nil,
  189. io.ErrUnexpectedEOF,
  190. },
  191. {
  192. `
  193. FROM foo
  194. TEMPLATE "
  195. `,
  196. nil,
  197. io.ErrUnexpectedEOF,
  198. },
  199. {
  200. `
  201. FROM foo
  202. TEMPLATE """
  203. This is a multiline template with "quotes".
  204. """
  205. `,
  206. []Command{
  207. {Name: "model", Args: "foo"},
  208. {Name: "template", Args: "\nThis is a multiline template with \"quotes\".\n"},
  209. },
  210. nil,
  211. },
  212. {
  213. `
  214. FROM foo
  215. TEMPLATE """"""
  216. `,
  217. []Command{
  218. {Name: "model", Args: "foo"},
  219. {Name: "template", Args: ""},
  220. },
  221. nil,
  222. },
  223. {
  224. `
  225. FROM foo
  226. TEMPLATE ""
  227. `,
  228. []Command{
  229. {Name: "model", Args: "foo"},
  230. {Name: "template", Args: ""},
  231. },
  232. nil,
  233. },
  234. {
  235. `
  236. FROM foo
  237. TEMPLATE "'"
  238. `,
  239. []Command{
  240. {Name: "model", Args: "foo"},
  241. {Name: "template", Args: "'"},
  242. },
  243. nil,
  244. },
  245. }
  246. for _, c := range cases {
  247. t.Run("", func(t *testing.T) {
  248. commands, err := Parse(strings.NewReader(c.multiline))
  249. assert.ErrorIs(t, err, c.err)
  250. assert.Equal(t, c.expected, commands)
  251. })
  252. }
  253. }
  254. func TestParserParameters(t *testing.T) {
  255. var cases = []string{
  256. "numa true",
  257. "num_ctx 1",
  258. "num_batch 1",
  259. "num_gqa 1",
  260. "num_gpu 1",
  261. "main_gpu 1",
  262. "low_vram true",
  263. "f16_kv true",
  264. "logits_all true",
  265. "vocab_only true",
  266. "use_mmap true",
  267. "use_mlock true",
  268. "num_thread 1",
  269. "num_keep 1",
  270. "seed 1",
  271. "num_predict 1",
  272. "top_k 1",
  273. "top_p 1.0",
  274. "tfs_z 1.0",
  275. "typical_p 1.0",
  276. "repeat_last_n 1",
  277. "temperature 1.0",
  278. "repeat_penalty 1.0",
  279. "presence_penalty 1.0",
  280. "frequency_penalty 1.0",
  281. "mirostat 1",
  282. "mirostat_tau 1.0",
  283. "mirostat_eta 1.0",
  284. "penalize_newline true",
  285. "stop foo",
  286. }
  287. for _, c := range cases {
  288. t.Run(c, func(t *testing.T) {
  289. var b bytes.Buffer
  290. fmt.Fprintln(&b, "FROM foo")
  291. fmt.Fprintln(&b, "PARAMETER", c)
  292. t.Logf("input: %s", b.String())
  293. _, err := Parse(&b)
  294. assert.Nil(t, err)
  295. })
  296. }
  297. }
  298. func TestParserOnlyFrom(t *testing.T) {
  299. commands, err := Parse(strings.NewReader("FROM foo"))
  300. assert.Nil(t, err)
  301. expected := []Command{{Name: "model", Args: "foo"}}
  302. assert.Equal(t, expected, commands)
  303. }
  304. func TestParserComments(t *testing.T) {
  305. var cases = []struct {
  306. input string
  307. expected []Command
  308. }{
  309. {
  310. `
  311. # comment
  312. FROM foo
  313. `,
  314. []Command{
  315. {Name: "model", Args: "foo"},
  316. },
  317. },
  318. }
  319. for _, c := range cases {
  320. t.Run("", func(t *testing.T) {
  321. commands, err := Parse(strings.NewReader(c.input))
  322. assert.Nil(t, err)
  323. assert.Equal(t, c.expected, commands)
  324. })
  325. }
  326. }