template_test.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. package fasttemplate
  2. import (
  3. "bytes"
  4. "io"
  5. "testing"
  6. )
  7. func TestEmptyTemplate(t *testing.T) {
  8. tpl := New("", "[", "]")
  9. s := tpl.ExecuteString(map[string]interface{}{"foo": "bar", "aaa": "bbb"})
  10. if s != "" {
  11. t.Fatalf("unexpected string returned %q. Expected empty string", s)
  12. }
  13. }
  14. func TestEmptyTagStart(t *testing.T) {
  15. expectPanic(t, func() { NewTemplate("foobar", "", "]") })
  16. }
  17. func TestEmptyTagEnd(t *testing.T) {
  18. expectPanic(t, func() { NewTemplate("foobar", "[", "") })
  19. }
  20. func TestNoTags(t *testing.T) {
  21. template := "foobar"
  22. tpl := New(template, "[", "]")
  23. s := tpl.ExecuteString(map[string]interface{}{"foo": "bar", "aaa": "bbb"})
  24. if s != template {
  25. t.Fatalf("unexpected template value %q. Expected %q", s, template)
  26. }
  27. }
  28. func TestEmptyTagName(t *testing.T) {
  29. template := "foo[]bar"
  30. tpl := New(template, "[", "]")
  31. s := tpl.ExecuteString(map[string]interface{}{"": "111", "aaa": "bbb"})
  32. result := "foo111bar"
  33. if s != result {
  34. t.Fatalf("unexpected template value %q. Expected %q", s, result)
  35. }
  36. }
  37. func TestOnlyTag(t *testing.T) {
  38. template := "[foo]"
  39. tpl := New(template, "[", "]")
  40. s := tpl.ExecuteString(map[string]interface{}{"foo": "111", "aaa": "bbb"})
  41. result := "111"
  42. if s != result {
  43. t.Fatalf("unexpected template value %q. Expected %q", s, result)
  44. }
  45. }
  46. func TestStartWithTag(t *testing.T) {
  47. template := "[foo]barbaz"
  48. tpl := New(template, "[", "]")
  49. s := tpl.ExecuteString(map[string]interface{}{"foo": "111", "aaa": "bbb"})
  50. result := "111barbaz"
  51. if s != result {
  52. t.Fatalf("unexpected template value %q. Expected %q", s, result)
  53. }
  54. }
  55. func TestEndWithTag(t *testing.T) {
  56. template := "foobar[foo]"
  57. tpl := New(template, "[", "]")
  58. s := tpl.ExecuteString(map[string]interface{}{"foo": "111", "aaa": "bbb"})
  59. result := "foobar111"
  60. if s != result {
  61. t.Fatalf("unexpected template value %q. Expected %q", s, result)
  62. }
  63. }
  64. func TestTemplateReset(t *testing.T) {
  65. template := "foo{bar}baz"
  66. tpl := New(template, "{", "}")
  67. s := tpl.ExecuteString(map[string]interface{}{"bar": "111"})
  68. result := "foo111baz"
  69. if s != result {
  70. t.Fatalf("unexpected template value %q. Expected %q", s, result)
  71. }
  72. template = "[xxxyyyzz"
  73. if err := tpl.Reset(template, "[", "]"); err == nil {
  74. t.Fatalf("expecting error for unclosed tag on %q", template)
  75. }
  76. template = "[xxx]yyy[zz]"
  77. if err := tpl.Reset(template, "[", "]"); err != nil {
  78. t.Fatalf("unexpected error: %s", err)
  79. }
  80. s = tpl.ExecuteString(map[string]interface{}{"xxx": "11", "zz": "2222"})
  81. result = "11yyy2222"
  82. if s != result {
  83. t.Fatalf("unexpected template value %q. Expected %q", s, result)
  84. }
  85. }
  86. func TestDuplicateTags(t *testing.T) {
  87. template := "[foo]bar[foo][foo]baz"
  88. tpl := New(template, "[", "]")
  89. s := tpl.ExecuteString(map[string]interface{}{"foo": "111", "aaa": "bbb"})
  90. result := "111bar111111baz"
  91. if s != result {
  92. t.Fatalf("unexpected template value %q. Expected %q", s, result)
  93. }
  94. }
  95. func TestMultipleTags(t *testing.T) {
  96. template := "foo[foo]aa[aaa]ccc"
  97. tpl := New(template, "[", "]")
  98. s := tpl.ExecuteString(map[string]interface{}{"foo": "111", "aaa": "bbb"})
  99. result := "foo111aabbbccc"
  100. if s != result {
  101. t.Fatalf("unexpected template value %q. Expected %q", s, result)
  102. }
  103. }
  104. func TestLongDelimiter(t *testing.T) {
  105. template := "foo{{{foo}}}bar"
  106. tpl := New(template, "{{{", "}}}")
  107. s := tpl.ExecuteString(map[string]interface{}{"foo": "111", "aaa": "bbb"})
  108. result := "foo111bar"
  109. if s != result {
  110. t.Fatalf("unexpected template value %q. Expected %q", s, result)
  111. }
  112. }
  113. func TestIdenticalDelimiter(t *testing.T) {
  114. template := "foo@foo@foo@aaa@"
  115. tpl := New(template, "@", "@")
  116. s := tpl.ExecuteString(map[string]interface{}{"foo": "111", "aaa": "bbb"})
  117. result := "foo111foobbb"
  118. if s != result {
  119. t.Fatalf("unexpected template value %q. Expected %q", s, result)
  120. }
  121. }
  122. func TestDlimitersWithDistinctSize(t *testing.T) {
  123. template := "foo<?phpaaa?>bar<?phpzzz?>"
  124. tpl := New(template, "<?php", "?>")
  125. s := tpl.ExecuteString(map[string]interface{}{"zzz": "111", "aaa": "bbb"})
  126. result := "foobbbbar111"
  127. if s != result {
  128. t.Fatalf("unexpected template value %q. Expected %q", s, result)
  129. }
  130. }
  131. func TestEmptyValue(t *testing.T) {
  132. template := "foobar[foo]"
  133. tpl := New(template, "[", "]")
  134. s := tpl.ExecuteString(map[string]interface{}{"foo": "", "aaa": "bbb"})
  135. result := "foobar"
  136. if s != result {
  137. t.Fatalf("unexpected template value %q. Expected %q", s, result)
  138. }
  139. }
  140. func TestNoValue(t *testing.T) {
  141. template := "foobar[foo]x[aaa]"
  142. tpl := New(template, "[", "]")
  143. s := tpl.ExecuteString(map[string]interface{}{"aaa": "bbb"})
  144. result := "foobarxbbb"
  145. if s != result {
  146. t.Fatalf("unexpected template value %q. Expected %q", s, result)
  147. }
  148. }
  149. func TestNoEndDelimiter(t *testing.T) {
  150. template := "foobar[foo"
  151. _, err := NewTemplate(template, "[", "]")
  152. if err == nil {
  153. t.Fatalf("expected non-nil error. got nil")
  154. }
  155. expectPanic(t, func() { New(template, "[", "]") })
  156. }
  157. func TestUnsupportedValue(t *testing.T) {
  158. template := "foobar[foo]"
  159. tpl := New(template, "[", "]")
  160. expectPanic(t, func() {
  161. tpl.ExecuteString(map[string]interface{}{"foo": 123, "aaa": "bbb"})
  162. })
  163. }
  164. func TestMixedValues(t *testing.T) {
  165. template := "foo[foo]bar[bar]baz[baz]"
  166. tpl := New(template, "[", "]")
  167. s := tpl.ExecuteString(map[string]interface{}{
  168. "foo": "111",
  169. "bar": []byte("bbb"),
  170. "baz": TagFunc(func(w io.Writer, tag string) (int, error) { return w.Write([]byte(tag)) }),
  171. })
  172. result := "foo111barbbbbazbaz"
  173. if s != result {
  174. t.Fatalf("unexpected template value %q. Expected %q", s, result)
  175. }
  176. }
  177. func TestExecuteFunc(t *testing.T) {
  178. testExecuteFunc(t, "", "")
  179. testExecuteFunc(t, "a", "a")
  180. testExecuteFunc(t, "abc", "abc")
  181. testExecuteFunc(t, "{foo}", "xxxx")
  182. testExecuteFunc(t, "a{foo}", "axxxx")
  183. testExecuteFunc(t, "{foo}a", "xxxxa")
  184. testExecuteFunc(t, "a{foo}bc", "axxxxbc")
  185. testExecuteFunc(t, "{foo}{foo}", "xxxxxxxx")
  186. testExecuteFunc(t, "{foo}bar{foo}", "xxxxbarxxxx")
  187. // unclosed tag
  188. testExecuteFunc(t, "{unclosed", "{unclosed")
  189. testExecuteFunc(t, "{{unclosed", "{{unclosed")
  190. testExecuteFunc(t, "{un{closed", "{un{closed")
  191. // test unknown tag
  192. testExecuteFunc(t, "{unknown}", "zz")
  193. testExecuteFunc(t, "{foo}q{unexpected}{missing}bar{foo}", "xxxxqzzzzbarxxxx")
  194. }
  195. func testExecuteFunc(t *testing.T, template, expectedOutput string) {
  196. var bb bytes.Buffer
  197. ExecuteFunc(template, "{", "}", &bb, func(w io.Writer, tag string) (int, error) {
  198. if tag == "foo" {
  199. return w.Write([]byte("xxxx"))
  200. }
  201. return w.Write([]byte("zz"))
  202. })
  203. output := string(bb.Bytes())
  204. if output != expectedOutput {
  205. t.Fatalf("unexpected output for template=%q: %q. Expected %q", template, output, expectedOutput)
  206. }
  207. }
  208. func TestExecute(t *testing.T) {
  209. testExecute(t, "", "")
  210. testExecute(t, "a", "a")
  211. testExecute(t, "abc", "abc")
  212. testExecute(t, "{foo}", "xxxx")
  213. testExecute(t, "a{foo}", "axxxx")
  214. testExecute(t, "{foo}a", "xxxxa")
  215. testExecute(t, "a{foo}bc", "axxxxbc")
  216. testExecute(t, "{foo}{foo}", "xxxxxxxx")
  217. testExecute(t, "{foo}bar{foo}", "xxxxbarxxxx")
  218. // unclosed tag
  219. testExecute(t, "{unclosed", "{unclosed")
  220. testExecute(t, "{{unclosed", "{{unclosed")
  221. testExecute(t, "{un{closed", "{un{closed")
  222. // test unknown tag
  223. testExecute(t, "{unknown}", "")
  224. testExecute(t, "{foo}q{unexpected}{missing}bar{foo}", "xxxxqbarxxxx")
  225. }
  226. func testExecute(t *testing.T, template, expectedOutput string) {
  227. var bb bytes.Buffer
  228. Execute(template, "{", "}", &bb, map[string]interface{}{"foo": "xxxx"})
  229. output := string(bb.Bytes())
  230. if output != expectedOutput {
  231. t.Fatalf("unexpected output for template=%q: %q. Expected %q", template, output, expectedOutput)
  232. }
  233. }
  234. func TestExecuteString(t *testing.T) {
  235. testExecuteString(t, "", "")
  236. testExecuteString(t, "a", "a")
  237. testExecuteString(t, "abc", "abc")
  238. testExecuteString(t, "{foo}", "xxxx")
  239. testExecuteString(t, "a{foo}", "axxxx")
  240. testExecuteString(t, "{foo}a", "xxxxa")
  241. testExecuteString(t, "a{foo}bc", "axxxxbc")
  242. testExecuteString(t, "{foo}{foo}", "xxxxxxxx")
  243. testExecuteString(t, "{foo}bar{foo}", "xxxxbarxxxx")
  244. // unclosed tag
  245. testExecuteString(t, "{unclosed", "{unclosed")
  246. testExecuteString(t, "{{unclosed", "{{unclosed")
  247. testExecuteString(t, "{un{closed", "{un{closed")
  248. // test unknown tag
  249. testExecuteString(t, "{unknown}", "")
  250. testExecuteString(t, "{foo}q{unexpected}{missing}bar{foo}", "xxxxqbarxxxx")
  251. }
  252. func testExecuteString(t *testing.T, template, expectedOutput string) {
  253. output := ExecuteString(template, "{", "}", map[string]interface{}{"foo": "xxxx"})
  254. if output != expectedOutput {
  255. t.Fatalf("unexpected output for template=%q: %q. Expected %q", template, output, expectedOutput)
  256. }
  257. }
  258. func expectPanic(t *testing.T, f func()) {
  259. defer func() {
  260. if r := recover(); r == nil {
  261. t.Fatalf("missing panic")
  262. }
  263. }()
  264. f()
  265. }