text_test.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. package stdlib_test
  2. import (
  3. "regexp"
  4. "testing"
  5. "github.com/d5/tengo/v2"
  6. )
  7. func TestTextRE(t *testing.T) {
  8. // re_match(pattern, text)
  9. for _, d := range []struct {
  10. pattern string
  11. text string
  12. }{
  13. {"abc", ""},
  14. {"abc", "abc"},
  15. {"a", "abc"},
  16. {"b", "abc"},
  17. {"^a", "abc"},
  18. {"^b", "abc"},
  19. } {
  20. expected := regexp.MustCompile(d.pattern).MatchString(d.text)
  21. module(t, "text").call("re_match", d.pattern, d.text).
  22. expect(expected, "pattern: %q, src: %q", d.pattern, d.text)
  23. module(t, "text").call("re_compile", d.pattern).call("match", d.text).
  24. expect(expected, "patter: %q, src: %q", d.pattern, d.text)
  25. }
  26. // re_find(pattern, text)
  27. for _, d := range []struct {
  28. pattern string
  29. text string
  30. expected interface{}
  31. }{
  32. {"a(b)", "", tengo.UndefinedValue},
  33. {"a(b)", "ab", ARR{
  34. ARR{
  35. IMAP{"text": "ab", "begin": 0, "end": 2},
  36. IMAP{"text": "b", "begin": 1, "end": 2},
  37. },
  38. }},
  39. {"a(bc)d", "abcdefgabcd", ARR{
  40. ARR{
  41. IMAP{"text": "abcd", "begin": 0, "end": 4},
  42. IMAP{"text": "bc", "begin": 1, "end": 3},
  43. },
  44. }},
  45. {"(a)b(c)d", "abcdefgabcd", ARR{
  46. ARR{
  47. IMAP{"text": "abcd", "begin": 0, "end": 4},
  48. IMAP{"text": "a", "begin": 0, "end": 1},
  49. IMAP{"text": "c", "begin": 2, "end": 3},
  50. },
  51. }},
  52. } {
  53. module(t, "text").call("re_find", d.pattern, d.text).
  54. expect(d.expected, "pattern: %q, text: %q", d.pattern, d.text)
  55. module(t, "text").call("re_compile", d.pattern).call("find", d.text).
  56. expect(d.expected, "pattern: %q, text: %q", d.pattern, d.text)
  57. }
  58. // re_find(pattern, text, count))
  59. for _, d := range []struct {
  60. pattern string
  61. text string
  62. count int
  63. expected interface{}
  64. }{
  65. {"a(b)", "", -1, tengo.UndefinedValue},
  66. {"a(b)", "ab", -1, ARR{
  67. ARR{
  68. IMAP{"text": "ab", "begin": 0, "end": 2},
  69. IMAP{"text": "b", "begin": 1, "end": 2},
  70. },
  71. }},
  72. {"a(bc)d", "abcdefgabcd", -1, ARR{
  73. ARR{
  74. IMAP{"text": "abcd", "begin": 0, "end": 4},
  75. IMAP{"text": "bc", "begin": 1, "end": 3},
  76. },
  77. ARR{
  78. IMAP{"text": "abcd", "begin": 7, "end": 11},
  79. IMAP{"text": "bc", "begin": 8, "end": 10},
  80. },
  81. }},
  82. {"(a)b(c)d", "abcdefgabcd", -1, ARR{
  83. ARR{
  84. IMAP{"text": "abcd", "begin": 0, "end": 4},
  85. IMAP{"text": "a", "begin": 0, "end": 1},
  86. IMAP{"text": "c", "begin": 2, "end": 3},
  87. },
  88. ARR{
  89. IMAP{"text": "abcd", "begin": 7, "end": 11},
  90. IMAP{"text": "a", "begin": 7, "end": 8},
  91. IMAP{"text": "c", "begin": 9, "end": 10},
  92. },
  93. }},
  94. {"(a)b(c)d", "abcdefgabcd", 0, tengo.UndefinedValue},
  95. {"(a)b(c)d", "abcdefgabcd", 1, ARR{
  96. ARR{
  97. IMAP{"text": "abcd", "begin": 0, "end": 4},
  98. IMAP{"text": "a", "begin": 0, "end": 1},
  99. IMAP{"text": "c", "begin": 2, "end": 3},
  100. },
  101. }},
  102. } {
  103. module(t, "text").call("re_find", d.pattern, d.text, d.count).
  104. expect(d.expected, "pattern: %q, text: %q", d.pattern, d.text)
  105. module(t, "text").call("re_compile", d.pattern).
  106. call("find", d.text, d.count).
  107. expect(d.expected, "pattern: %q, text: %q", d.pattern, d.text)
  108. }
  109. // re_replace(pattern, text, repl)
  110. for _, d := range []struct {
  111. pattern string
  112. text string
  113. repl string
  114. }{
  115. {"a", "", "b"},
  116. {"a", "a", "b"},
  117. {"a", "acac", "b"},
  118. {"b", "acac", "x"},
  119. {"a", "acac", "123"},
  120. {"ac", "acac", "99"},
  121. {"ac$", "acac", "foo"},
  122. {"a(b)", "ababab", "$1"},
  123. {"a(b)(c)", "abcabcabc", "$2$1"},
  124. {"(a(b)c)", "abcabcabc", "$1$2"},
  125. {"(일(2)삼)", "일2삼12삼일23", "$1$2"},
  126. {"((일)(2)3)", "일23\n일이3\n일23", "$1$2$3"},
  127. {"(a(b)c)", "abc\nabc\nabc", "$1$2"},
  128. } {
  129. expected := regexp.MustCompile(d.pattern).
  130. ReplaceAllString(d.text, d.repl)
  131. module(t, "text").call("re_replace", d.pattern, d.text, d.repl).
  132. expect(expected, "pattern: %q, text: %q, repl: %q",
  133. d.pattern, d.text, d.repl)
  134. module(t, "text").call("re_compile", d.pattern).
  135. call("replace", d.text, d.repl).
  136. expect(expected, "pattern: %q, text: %q, repl: %q",
  137. d.pattern, d.text, d.repl)
  138. }
  139. // re_split(pattern, text)
  140. for _, d := range []struct {
  141. pattern string
  142. text string
  143. }{
  144. {"a", ""},
  145. {"a", "abcabc"},
  146. {"ab", "abcabc"},
  147. {"^a", "abcabc"},
  148. } {
  149. var expected []interface{}
  150. for _, ex := range regexp.MustCompile(d.pattern).Split(d.text, -1) {
  151. expected = append(expected, ex)
  152. }
  153. module(t, "text").call("re_split", d.pattern, d.text).
  154. expect(expected, "pattern: %q, text: %q", d.pattern, d.text)
  155. module(t, "text").call("re_compile", d.pattern).call("split", d.text).
  156. expect(expected, "pattern: %q, text: %q", d.pattern, d.text)
  157. }
  158. // re_split(pattern, text, count))
  159. for _, d := range []struct {
  160. pattern string
  161. text string
  162. count int
  163. }{
  164. {"a", "", -1},
  165. {"a", "abcabc", -1},
  166. {"ab", "abcabc", -1},
  167. {"^a", "abcabc", -1},
  168. {"a", "abcabc", 0},
  169. {"a", "abcabc", 1},
  170. {"a", "abcabc", 2},
  171. {"a", "abcabc", 3},
  172. {"b", "abcabc", 1},
  173. {"b", "abcabc", 2},
  174. {"b", "abcabc", 3},
  175. } {
  176. var expected []interface{}
  177. for _, ex := range regexp.MustCompile(d.pattern).Split(d.text, d.count) {
  178. expected = append(expected, ex)
  179. }
  180. module(t, "text").call("re_split", d.pattern, d.text, d.count).
  181. expect(expected, "pattern: %q, text: %q", d.pattern, d.text)
  182. module(t, "text").call("re_compile", d.pattern).
  183. call("split", d.text, d.count).
  184. expect(expected, "pattern: %q, text: %q", d.pattern, d.text)
  185. }
  186. }
  187. func TestText(t *testing.T) {
  188. module(t, "text").call("compare", "", "").expect(0)
  189. module(t, "text").call("compare", "", "a").expect(-1)
  190. module(t, "text").call("compare", "a", "").expect(1)
  191. module(t, "text").call("compare", "a", "a").expect(0)
  192. module(t, "text").call("compare", "a", "b").expect(-1)
  193. module(t, "text").call("compare", "b", "a").expect(1)
  194. module(t, "text").call("compare", "abcde", "abcde").expect(0)
  195. module(t, "text").call("compare", "abcde", "abcdf").expect(-1)
  196. module(t, "text").call("compare", "abcdf", "abcde").expect(1)
  197. module(t, "text").call("contains", "", "").expect(true)
  198. module(t, "text").call("contains", "", "a").expect(false)
  199. module(t, "text").call("contains", "a", "").expect(true)
  200. module(t, "text").call("contains", "a", "a").expect(true)
  201. module(t, "text").call("contains", "abcde", "a").expect(true)
  202. module(t, "text").call("contains", "abcde", "abcde").expect(true)
  203. module(t, "text").call("contains", "abc", "abcde").expect(false)
  204. module(t, "text").call("contains", "ab cd", "bc").expect(false)
  205. module(t, "text").call("replace", "", "", "", -1).expect("")
  206. module(t, "text").call("replace", "abcd", "a", "x", -1).expect("xbcd")
  207. module(t, "text").call("replace", "aaaa", "a", "x", -1).expect("xxxx")
  208. module(t, "text").call("replace", "aaaa", "a", "x", 0).expect("aaaa")
  209. module(t, "text").call("replace", "aaaa", "a", "x", 2).expect("xxaa")
  210. module(t, "text").call("replace", "abcd", "bc", "x", -1).expect("axd")
  211. module(t, "text").call("format_bool", true).expect("true")
  212. module(t, "text").call("format_bool", false).expect("false")
  213. module(t, "text").call("format_float", -19.84, 'f', -1, 64).expect("-19.84")
  214. module(t, "text").call("format_int", -1984, 10).expect("-1984")
  215. module(t, "text").call("format_int", 1984, 8).expect("3700")
  216. module(t, "text").call("parse_bool", "true").expect(true)
  217. module(t, "text").call("parse_bool", "0").expect(false)
  218. module(t, "text").call("parse_float", "-19.84", 64).expect(-19.84)
  219. module(t, "text").call("parse_int", "-1984", 10, 64).expect(-1984)
  220. }
  221. func TestReplaceLimit(t *testing.T) {
  222. curMaxStringLen := tengo.MaxStringLen
  223. defer func() { tengo.MaxStringLen = curMaxStringLen }()
  224. tengo.MaxStringLen = 12
  225. module(t, "text").call("replace", "123456789012", "1", "x", -1).
  226. expect("x234567890x2")
  227. module(t, "text").call("replace", "123456789012", "12", "x", -1).
  228. expect("x34567890x")
  229. module(t, "text").call("replace", "123456789012", "1", "xy", -1).
  230. expectError()
  231. module(t, "text").call("replace", "123456789012", "0", "xy", -1).
  232. expectError()
  233. module(t, "text").call("replace", "123456789012", "012", "xyz", -1).
  234. expect("123456789xyz")
  235. module(t, "text").call("replace", "123456789012", "012", "xyzz", -1).
  236. expectError()
  237. module(t, "text").call("re_replace", "1", "123456789012", "x").
  238. expect("x234567890x2")
  239. module(t, "text").call("re_replace", "12", "123456789012", "x").
  240. expect("x34567890x")
  241. module(t, "text").call("re_replace", "1", "123456789012", "xy").
  242. expectError()
  243. module(t, "text").call("re_replace", "1(2)", "123456789012", "x$1").
  244. expect("x234567890x2")
  245. module(t, "text").call("re_replace", "(1)(2)", "123456789012", "$2$1").
  246. expect("213456789021")
  247. module(t, "text").call("re_replace", "(1)(2)", "123456789012", "${2}${1}x").
  248. expectError()
  249. }
  250. func TestTextRepeat(t *testing.T) {
  251. curMaxStringLen := tengo.MaxStringLen
  252. defer func() { tengo.MaxStringLen = curMaxStringLen }()
  253. tengo.MaxStringLen = 12
  254. module(t, "text").call("repeat", "1234", "3").
  255. expect("123412341234")
  256. module(t, "text").call("repeat", "1234", "4").
  257. expectError()
  258. module(t, "text").call("repeat", "1", "12").
  259. expect("111111111111")
  260. module(t, "text").call("repeat", "1", "13").
  261. expectError()
  262. }
  263. func TestSubstr(t *testing.T) {
  264. module(t, "text").call("substr", "", 0, 0).expect("")
  265. module(t, "text").call("substr", "abcdef", 0, 3).expect("abc")
  266. module(t, "text").call("substr", "abcdef", 0, 6).expect("abcdef")
  267. module(t, "text").call("substr", "abcdef", 0, 10).expect("abcdef")
  268. module(t, "text").call("substr", "abcdef", -10, 10).expect("abcdef")
  269. module(t, "text").call("substr", "abcdef", 0).expect("abcdef")
  270. module(t, "text").call("substr", "abcdef", 3).expect("def")
  271. module(t, "text").call("substr", "", 10, 0).expectError()
  272. module(t, "text").call("substr", "", "10", 0).expectError()
  273. module(t, "text").call("substr", "", 10, "0").expectError()
  274. module(t, "text").call("substr", "", "10", "0").expectError()
  275. module(t, "text").call("substr", 0, 0, 1).expect("0")
  276. module(t, "text").call("substr", 123, 0, 1).expect("1")
  277. module(t, "text").call("substr", 123.456, 4, 7).expect("456")
  278. }
  279. func TestPadLeft(t *testing.T) {
  280. module(t, "text").call("pad_left", "ab", 7, 0).expect("00000ab")
  281. module(t, "text").call("pad_right", "ab", 7, 0).expect("ab00000")
  282. module(t, "text").call("pad_left", "ab", 7, "+-").expect("-+-+-ab")
  283. module(t, "text").call("pad_right", "ab", 7, "+-").expect("ab+-+-+")
  284. }