LayoutUtilsTest.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. /*
  2. * Copyright (C) 2015 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "LayoutUtils.h"
  17. #include <gtest/gtest.h>
  18. #include "UnicodeUtils.h"
  19. namespace minikin {
  20. void ExpectNextWordBreakForCache(size_t offset_in, const char* query_str) {
  21. const size_t BUF_SIZE = 256U;
  22. uint16_t buf[BUF_SIZE];
  23. size_t expected_breakpoint = 0U;
  24. size_t size = 0U;
  25. ParseUnicode(buf, BUF_SIZE, query_str, &size, &expected_breakpoint);
  26. EXPECT_EQ(expected_breakpoint, getNextWordBreakForCache(U16StringPiece(buf, size), offset_in))
  27. << "Expected position is [" << query_str << "] from offset " << offset_in;
  28. }
  29. void ExpectPrevWordBreakForCache(size_t offset_in, const char* query_str) {
  30. const size_t BUF_SIZE = 256U;
  31. uint16_t buf[BUF_SIZE];
  32. size_t expected_breakpoint = 0U;
  33. size_t size = 0U;
  34. ParseUnicode(buf, BUF_SIZE, query_str, &size, &expected_breakpoint);
  35. EXPECT_EQ(expected_breakpoint, getPrevWordBreakForCache(U16StringPiece(buf, size), offset_in))
  36. << "Expected position is [" << query_str << "] from offset " << offset_in;
  37. }
  38. TEST(WordBreakTest, goNextWordBreakTest) {
  39. ExpectNextWordBreakForCache(0, "|");
  40. // Continue for spaces.
  41. ExpectNextWordBreakForCache(0, "'a' 'b' 'c' 'd' |");
  42. ExpectNextWordBreakForCache(1, "'a' 'b' 'c' 'd' |");
  43. ExpectNextWordBreakForCache(2, "'a' 'b' 'c' 'd' |");
  44. ExpectNextWordBreakForCache(3, "'a' 'b' 'c' 'd' |");
  45. ExpectNextWordBreakForCache(4, "'a' 'b' 'c' 'd' |");
  46. ExpectNextWordBreakForCache(1000, "'a' 'b' 'c' 'd' |");
  47. // Space makes word break.
  48. ExpectNextWordBreakForCache(0, "'a' 'b' | U+0020 'c' 'd'");
  49. ExpectNextWordBreakForCache(1, "'a' 'b' | U+0020 'c' 'd'");
  50. ExpectNextWordBreakForCache(2, "'a' 'b' U+0020 | 'c' 'd'");
  51. ExpectNextWordBreakForCache(3, "'a' 'b' U+0020 'c' 'd' |");
  52. ExpectNextWordBreakForCache(4, "'a' 'b' U+0020 'c' 'd' |");
  53. ExpectNextWordBreakForCache(5, "'a' 'b' U+0020 'c' 'd' |");
  54. ExpectNextWordBreakForCache(1000, "'a' 'b' U+0020 'c' 'd' |");
  55. ExpectNextWordBreakForCache(0, "'a' 'b' | U+2000 'c' 'd'");
  56. ExpectNextWordBreakForCache(1, "'a' 'b' | U+2000 'c' 'd'");
  57. ExpectNextWordBreakForCache(2, "'a' 'b' U+2000 | 'c' 'd'");
  58. ExpectNextWordBreakForCache(3, "'a' 'b' U+2000 'c' 'd' |");
  59. ExpectNextWordBreakForCache(4, "'a' 'b' U+2000 'c' 'd' |");
  60. ExpectNextWordBreakForCache(5, "'a' 'b' U+2000 'c' 'd' |");
  61. ExpectNextWordBreakForCache(1000, "'a' 'b' U+2000 'c' 'd' |");
  62. ExpectNextWordBreakForCache(0, "'a' 'b' | U+2000 U+2000 'c' 'd'");
  63. ExpectNextWordBreakForCache(1, "'a' 'b' | U+2000 U+2000 'c' 'd'");
  64. ExpectNextWordBreakForCache(2, "'a' 'b' U+2000 | U+2000 'c' 'd'");
  65. ExpectNextWordBreakForCache(3, "'a' 'b' U+2000 U+2000 | 'c' 'd'");
  66. ExpectNextWordBreakForCache(4, "'a' 'b' U+2000 U+2000 'c' 'd' |");
  67. ExpectNextWordBreakForCache(5, "'a' 'b' U+2000 U+2000 'c' 'd' |");
  68. ExpectNextWordBreakForCache(6, "'a' 'b' U+2000 U+2000 'c' 'd' |");
  69. ExpectNextWordBreakForCache(1000, "'a' 'b' U+2000 U+2000 'c' 'd' |");
  70. // CJK ideographs makes word break.
  71. ExpectNextWordBreakForCache(0, "U+4E00 | U+4E00 U+4E00 U+4E00 U+4E00");
  72. ExpectNextWordBreakForCache(1, "U+4E00 U+4E00 | U+4E00 U+4E00 U+4E00");
  73. ExpectNextWordBreakForCache(2, "U+4E00 U+4E00 U+4E00 | U+4E00 U+4E00");
  74. ExpectNextWordBreakForCache(3, "U+4E00 U+4E00 U+4E00 U+4E00 | U+4E00");
  75. ExpectNextWordBreakForCache(4, "U+4E00 U+4E00 U+4E00 U+4E00 U+4E00 |");
  76. ExpectNextWordBreakForCache(5, "U+4E00 U+4E00 U+4E00 U+4E00 U+4E00 |");
  77. ExpectNextWordBreakForCache(1000, "U+4E00 U+4E00 U+4E00 U+4E00 U+4E00 |");
  78. ExpectNextWordBreakForCache(0, "U+4E00 | U+4E8C U+4E09 U+56DB U+4E94");
  79. ExpectNextWordBreakForCache(1, "U+4E00 U+4E8C | U+4E09 U+56DB U+4E94");
  80. ExpectNextWordBreakForCache(2, "U+4E00 U+4E8C U+4E09 | U+56DB U+4E94");
  81. ExpectNextWordBreakForCache(3, "U+4E00 U+4E8C U+4E09 U+56DB | U+4E94");
  82. ExpectNextWordBreakForCache(4, "U+4E00 U+4E8C U+4E09 U+56DB U+4E94 |");
  83. ExpectNextWordBreakForCache(5, "U+4E00 U+4E8C U+4E09 U+56DB U+4E94 |");
  84. ExpectNextWordBreakForCache(1000, "U+4E00 U+4E8C U+4E09 U+56DB U+4E94 |");
  85. ExpectNextWordBreakForCache(0, "U+4E00 'a' 'b' | U+2000 'c' U+4E00");
  86. ExpectNextWordBreakForCache(1, "U+4E00 'a' 'b' | U+2000 'c' U+4E00");
  87. ExpectNextWordBreakForCache(2, "U+4E00 'a' 'b' | U+2000 'c' U+4E00");
  88. ExpectNextWordBreakForCache(3, "U+4E00 'a' 'b' U+2000 | 'c' U+4E00");
  89. ExpectNextWordBreakForCache(4, "U+4E00 'a' 'b' U+2000 'c' | U+4E00");
  90. ExpectNextWordBreakForCache(5, "U+4E00 'a' 'b' U+2000 'c' U+4E00 |");
  91. ExpectNextWordBreakForCache(1000, "U+4E00 'a' 'b' U+2000 'c' U+4E00 |");
  92. // Continue if trailing characters is Unicode combining characters.
  93. ExpectNextWordBreakForCache(0, "U+4E00 U+0332 | U+4E00");
  94. ExpectNextWordBreakForCache(1, "U+4E00 U+0332 | U+4E00");
  95. ExpectNextWordBreakForCache(2, "U+4E00 U+0332 U+4E00 |");
  96. ExpectNextWordBreakForCache(3, "U+4E00 U+0332 U+4E00 |");
  97. ExpectNextWordBreakForCache(1000, "U+4E00 U+0332 U+4E00 |");
  98. // Surrogate pairs.
  99. ExpectNextWordBreakForCache(0, "U+1F60D U+1F618 |");
  100. ExpectNextWordBreakForCache(1, "U+1F60D U+1F618 |");
  101. ExpectNextWordBreakForCache(2, "U+1F60D U+1F618 |");
  102. ExpectNextWordBreakForCache(3, "U+1F60D U+1F618 |");
  103. ExpectNextWordBreakForCache(4, "U+1F60D U+1F618 |");
  104. ExpectNextWordBreakForCache(1000, "U+1F60D U+1F618 |");
  105. // Broken surrogate pairs.
  106. // U+D84D is leading surrogate but there is no trailing surrogate for it.
  107. ExpectNextWordBreakForCache(0, "U+D84D U+1F618 |");
  108. ExpectNextWordBreakForCache(1, "U+D84D U+1F618 |");
  109. ExpectNextWordBreakForCache(2, "U+D84D U+1F618 |");
  110. ExpectNextWordBreakForCache(3, "U+D84D U+1F618 |");
  111. ExpectNextWordBreakForCache(1000, "U+D84D U+1F618 |");
  112. ExpectNextWordBreakForCache(0, "U+1F618 U+D84D |");
  113. ExpectNextWordBreakForCache(1, "U+1F618 U+D84D |");
  114. ExpectNextWordBreakForCache(2, "U+1F618 U+D84D |");
  115. ExpectNextWordBreakForCache(3, "U+1F618 U+D84D |");
  116. ExpectNextWordBreakForCache(1000, "U+1F618 U+D84D |");
  117. // U+DE0D is trailing surrogate but there is no leading surrogate for it.
  118. ExpectNextWordBreakForCache(0, "U+DE0D U+1F618 |");
  119. ExpectNextWordBreakForCache(1, "U+DE0D U+1F618 |");
  120. ExpectNextWordBreakForCache(2, "U+DE0D U+1F618 |");
  121. ExpectNextWordBreakForCache(3, "U+DE0D U+1F618 |");
  122. ExpectNextWordBreakForCache(1000, "U+DE0D U+1F618 |");
  123. ExpectNextWordBreakForCache(0, "U+1F618 U+DE0D |");
  124. ExpectNextWordBreakForCache(1, "U+1F618 U+DE0D |");
  125. ExpectNextWordBreakForCache(2, "U+1F618 U+DE0D |");
  126. ExpectNextWordBreakForCache(3, "U+1F618 U+DE0D |");
  127. ExpectNextWordBreakForCache(1000, "U+1F618 U+DE0D |");
  128. // Regional indicator pair. U+1F1FA U+1F1F8 is US national flag.
  129. ExpectNextWordBreakForCache(0, "U+1F1FA U+1F1F8 |");
  130. ExpectNextWordBreakForCache(1, "U+1F1FA U+1F1F8 |");
  131. ExpectNextWordBreakForCache(2, "U+1F1FA U+1F1F8 |");
  132. ExpectNextWordBreakForCache(1000, "U+1F1FA U+1F1F8 |");
  133. // Tone marks.
  134. // CJK ideographic char + Tone mark + CJK ideographic char
  135. ExpectNextWordBreakForCache(0, "U+4444 U+302D | U+4444");
  136. ExpectNextWordBreakForCache(1, "U+4444 U+302D | U+4444");
  137. ExpectNextWordBreakForCache(2, "U+4444 U+302D U+4444 |");
  138. ExpectNextWordBreakForCache(3, "U+4444 U+302D U+4444 |");
  139. ExpectNextWordBreakForCache(1000, "U+4444 U+302D U+4444 |");
  140. // Variation Selectors.
  141. // CJK Ideographic char + Variation Selector(VS1) + CJK Ideographic char
  142. ExpectNextWordBreakForCache(0, "U+845B U+FE00 | U+845B");
  143. ExpectNextWordBreakForCache(1, "U+845B U+FE00 | U+845B");
  144. ExpectNextWordBreakForCache(2, "U+845B U+FE00 U+845B |");
  145. ExpectNextWordBreakForCache(3, "U+845B U+FE00 U+845B |");
  146. ExpectNextWordBreakForCache(1000, "U+845B U+FE00 U+845B |");
  147. // CJK Ideographic char + Variation Selector(VS17) + CJK Ideographic char
  148. ExpectNextWordBreakForCache(0, "U+845B U+E0100 | U+845B");
  149. ExpectNextWordBreakForCache(1, "U+845B U+E0100 | U+845B");
  150. ExpectNextWordBreakForCache(2, "U+845B U+E0100 | U+845B");
  151. ExpectNextWordBreakForCache(3, "U+845B U+E0100 U+845B |");
  152. ExpectNextWordBreakForCache(4, "U+845B U+E0100 U+845B |");
  153. ExpectNextWordBreakForCache(5, "U+845B U+E0100 U+845B |");
  154. ExpectNextWordBreakForCache(1000, "U+845B U+E0100 U+845B |");
  155. // CJK ideographic char + Tone mark + Variation Character(VS1)
  156. ExpectNextWordBreakForCache(0, "U+4444 U+302D U+FE00 | U+4444");
  157. ExpectNextWordBreakForCache(1, "U+4444 U+302D U+FE00 | U+4444");
  158. ExpectNextWordBreakForCache(2, "U+4444 U+302D U+FE00 | U+4444");
  159. ExpectNextWordBreakForCache(3, "U+4444 U+302D U+FE00 U+4444 |");
  160. ExpectNextWordBreakForCache(4, "U+4444 U+302D U+FE00 U+4444 |");
  161. ExpectNextWordBreakForCache(1000, "U+4444 U+302D U+FE00 U+4444 |");
  162. // CJK ideographic char + Tone mark + Variation Character(VS17)
  163. ExpectNextWordBreakForCache(0, "U+4444 U+302D U+E0100 | U+4444");
  164. ExpectNextWordBreakForCache(1, "U+4444 U+302D U+E0100 | U+4444");
  165. ExpectNextWordBreakForCache(2, "U+4444 U+302D U+E0100 | U+4444");
  166. ExpectNextWordBreakForCache(3, "U+4444 U+302D U+E0100 | U+4444");
  167. ExpectNextWordBreakForCache(4, "U+4444 U+302D U+E0100 U+4444 |");
  168. ExpectNextWordBreakForCache(5, "U+4444 U+302D U+E0100 U+4444 |");
  169. ExpectNextWordBreakForCache(1000, "U+4444 U+302D U+E0100 U+4444 |");
  170. // CJK ideographic char + Variation Character(VS1) + Tone mark
  171. ExpectNextWordBreakForCache(0, "U+4444 U+FE00 U+302D | U+4444");
  172. ExpectNextWordBreakForCache(1, "U+4444 U+FE00 U+302D | U+4444");
  173. ExpectNextWordBreakForCache(2, "U+4444 U+FE00 U+302D | U+4444");
  174. ExpectNextWordBreakForCache(3, "U+4444 U+FE00 U+302D U+4444 |");
  175. ExpectNextWordBreakForCache(4, "U+4444 U+FE00 U+302D U+4444 |");
  176. ExpectNextWordBreakForCache(1000, "U+4444 U+FE00 U+302D U+4444 |");
  177. // CJK ideographic char + Variation Character(VS17) + Tone mark
  178. ExpectNextWordBreakForCache(0, "U+4444 U+E0100 U+302D | U+4444");
  179. ExpectNextWordBreakForCache(1, "U+4444 U+E0100 U+302D | U+4444");
  180. ExpectNextWordBreakForCache(2, "U+4444 U+E0100 U+302D | U+4444");
  181. ExpectNextWordBreakForCache(3, "U+4444 U+E0100 U+302D | U+4444");
  182. ExpectNextWordBreakForCache(4, "U+4444 U+E0100 U+302D U+4444 |");
  183. ExpectNextWordBreakForCache(5, "U+4444 U+E0100 U+302D U+4444 |");
  184. ExpectNextWordBreakForCache(1000, "U+4444 U+E0100 U+302D U+4444 |");
  185. // Following test cases are unusual usage of variation selectors and tone
  186. // marks for caching up the further behavior changes, e.g. index of bounds
  187. // or crashes. Please feel free to update the test expectations if the
  188. // behavior change makes sense to you.
  189. // Isolated Tone marks and Variation Selectors
  190. ExpectNextWordBreakForCache(0, "U+FE00 |");
  191. ExpectNextWordBreakForCache(1, "U+FE00 |");
  192. ExpectNextWordBreakForCache(1000, "U+FE00 |");
  193. ExpectNextWordBreakForCache(0, "U+E0100 |");
  194. ExpectNextWordBreakForCache(1000, "U+E0100 |");
  195. ExpectNextWordBreakForCache(0, "U+302D |");
  196. ExpectNextWordBreakForCache(1000, "U+302D |");
  197. // CJK Ideographic char + Variation Selector(VS1) + Variation Selector(VS1)
  198. ExpectNextWordBreakForCache(0, "U+845B U+FE00 U+FE00 | U+845B");
  199. ExpectNextWordBreakForCache(1, "U+845B U+FE00 U+FE00 | U+845B");
  200. ExpectNextWordBreakForCache(2, "U+845B U+FE00 U+FE00 | U+845B");
  201. ExpectNextWordBreakForCache(3, "U+845B U+FE00 U+FE00 U+845B |");
  202. ExpectNextWordBreakForCache(4, "U+845B U+FE00 U+FE00 U+845B |");
  203. ExpectNextWordBreakForCache(1000, "U+845B U+FE00 U+FE00 U+845B |");
  204. // CJK Ideographic char + Variation Selector(VS17) + Variation Selector(VS17)
  205. ExpectNextWordBreakForCache(0, "U+845B U+E0100 U+E0100 | U+845B");
  206. ExpectNextWordBreakForCache(1, "U+845B U+E0100 U+E0100 | U+845B");
  207. ExpectNextWordBreakForCache(2, "U+845B U+E0100 U+E0100 | U+845B");
  208. ExpectNextWordBreakForCache(3, "U+845B U+E0100 U+E0100 | U+845B");
  209. ExpectNextWordBreakForCache(4, "U+845B U+E0100 U+E0100 | U+845B");
  210. ExpectNextWordBreakForCache(5, "U+845B U+E0100 U+E0100 U+845B |");
  211. ExpectNextWordBreakForCache(6, "U+845B U+E0100 U+E0100 U+845B |");
  212. ExpectNextWordBreakForCache(1000, "U+845B U+E0100 U+E0100 U+845B |");
  213. // CJK Ideographic char + Variation Selector(VS1) + Variation Selector(VS17)
  214. ExpectNextWordBreakForCache(0, "U+845B U+FE00 U+E0100 | U+845B");
  215. ExpectNextWordBreakForCache(1, "U+845B U+FE00 U+E0100 | U+845B");
  216. ExpectNextWordBreakForCache(2, "U+845B U+FE00 U+E0100 | U+845B");
  217. ExpectNextWordBreakForCache(3, "U+845B U+FE00 U+E0100 | U+845B");
  218. ExpectNextWordBreakForCache(4, "U+845B U+FE00 U+E0100 U+845B |");
  219. ExpectNextWordBreakForCache(5, "U+845B U+FE00 U+E0100 U+845B |");
  220. ExpectNextWordBreakForCache(1000, "U+845B U+FE00 U+E0100 U+845B |");
  221. // CJK Ideographic char + Variation Selector(VS17) + Variation Selector(VS1)
  222. ExpectNextWordBreakForCache(0, "U+845B U+E0100 U+FE00 | U+845B");
  223. ExpectNextWordBreakForCache(1, "U+845B U+E0100 U+FE00 | U+845B");
  224. ExpectNextWordBreakForCache(2, "U+845B U+E0100 U+FE00 | U+845B");
  225. ExpectNextWordBreakForCache(3, "U+845B U+E0100 U+FE00 | U+845B");
  226. ExpectNextWordBreakForCache(4, "U+845B U+E0100 U+FE00 U+845B |");
  227. ExpectNextWordBreakForCache(5, "U+845B U+E0100 U+FE00 U+845B |");
  228. ExpectNextWordBreakForCache(1000, "U+845B U+E0100 U+FE00 U+845B |");
  229. // Tone mark. + Tone mark
  230. ExpectNextWordBreakForCache(0, "U+4444 U+302D U+302D | U+4444");
  231. ExpectNextWordBreakForCache(1, "U+4444 U+302D U+302D | U+4444");
  232. ExpectNextWordBreakForCache(2, "U+4444 U+302D U+302D | U+4444");
  233. ExpectNextWordBreakForCache(3, "U+4444 U+302D U+302D U+4444 |");
  234. ExpectNextWordBreakForCache(4, "U+4444 U+302D U+302D U+4444 |");
  235. ExpectNextWordBreakForCache(1000, "U+4444 U+302D U+302D U+4444 |");
  236. }
  237. TEST(WordBreakTest, goPrevWordBreakTest) {
  238. ExpectPrevWordBreakForCache(0, "|");
  239. // Continue for spaces.
  240. ExpectPrevWordBreakForCache(0, "| 'a' 'b' 'c' 'd'");
  241. ExpectPrevWordBreakForCache(1, "| 'a' 'b' 'c' 'd'");
  242. ExpectPrevWordBreakForCache(2, "| 'a' 'b' 'c' 'd'");
  243. ExpectPrevWordBreakForCache(3, "| 'a' 'b' 'c' 'd'");
  244. ExpectPrevWordBreakForCache(4, "| 'a' 'b' 'c' 'd'");
  245. ExpectPrevWordBreakForCache(1000, "| 'a' 'b' 'c' 'd'");
  246. // Space makes word break.
  247. ExpectPrevWordBreakForCache(0, "| 'a' 'b' U+0020 'c' 'd'");
  248. ExpectPrevWordBreakForCache(1, "| 'a' 'b' U+0020 'c' 'd'");
  249. ExpectPrevWordBreakForCache(2, "| 'a' 'b' U+0020 'c' 'd'");
  250. ExpectPrevWordBreakForCache(3, "'a' 'b' | U+0020 'c' 'd'");
  251. ExpectPrevWordBreakForCache(4, "'a' 'b' U+0020 | 'c' 'd'");
  252. ExpectPrevWordBreakForCache(5, "'a' 'b' U+0020 | 'c' 'd'");
  253. ExpectPrevWordBreakForCache(1000, "'a' 'b' U+0020 | 'c' 'd'");
  254. ExpectPrevWordBreakForCache(0, "| 'a' 'b' U+2000 'c' 'd'");
  255. ExpectPrevWordBreakForCache(1, "| 'a' 'b' U+2000 'c' 'd'");
  256. ExpectPrevWordBreakForCache(2, "| 'a' 'b' U+2000 'c' 'd'");
  257. ExpectPrevWordBreakForCache(3, "'a' 'b' | U+2000 'c' 'd'");
  258. ExpectPrevWordBreakForCache(4, "'a' 'b' U+2000 | 'c' 'd'");
  259. ExpectPrevWordBreakForCache(5, "'a' 'b' U+2000 | 'c' 'd'");
  260. ExpectPrevWordBreakForCache(1000, "'a' 'b' U+2000 | 'c' 'd'");
  261. ExpectPrevWordBreakForCache(0, "| 'a' 'b' U+2000 U+2000 'c' 'd'");
  262. ExpectPrevWordBreakForCache(1, "| 'a' 'b' U+2000 U+2000 'c' 'd'");
  263. ExpectPrevWordBreakForCache(2, "| 'a' 'b' U+2000 U+2000 'c' 'd'");
  264. ExpectPrevWordBreakForCache(3, "'a' 'b' | U+2000 U+2000 'c' 'd'");
  265. ExpectPrevWordBreakForCache(4, "'a' 'b' U+2000 | U+2000 'c' 'd'");
  266. ExpectPrevWordBreakForCache(5, "'a' 'b' U+2000 U+2000 | 'c' 'd'");
  267. ExpectPrevWordBreakForCache(6, "'a' 'b' U+2000 U+2000 | 'c' 'd'");
  268. ExpectPrevWordBreakForCache(1000, "'a' 'b' U+2000 U+2000 | 'c' 'd'");
  269. // CJK ideographs makes word break.
  270. ExpectPrevWordBreakForCache(0, "| U+4E00 U+4E00 U+4E00 U+4E00 U+4E00");
  271. ExpectPrevWordBreakForCache(1, "| U+4E00 U+4E00 U+4E00 U+4E00 U+4E00");
  272. ExpectPrevWordBreakForCache(2, "U+4E00 | U+4E00 U+4E00 U+4E00 U+4E00");
  273. ExpectPrevWordBreakForCache(3, "U+4E00 U+4E00 | U+4E00 U+4E00 U+4E00");
  274. ExpectPrevWordBreakForCache(4, "U+4E00 U+4E00 U+4E00 | U+4E00 U+4E00");
  275. ExpectPrevWordBreakForCache(5, "U+4E00 U+4E00 U+4E00 U+4E00 | U+4E00");
  276. ExpectPrevWordBreakForCache(1000, "U+4E00 U+4E00 U+4E00 U+4E00 | U+4E00");
  277. ExpectPrevWordBreakForCache(0, "| U+4E00 U+4E8C U+4E09 U+56DB U+4E94");
  278. ExpectPrevWordBreakForCache(1, "| U+4E00 U+4E8C U+4E09 U+56DB U+4E94");
  279. ExpectPrevWordBreakForCache(2, "U+4E00 | U+4E8C U+4E09 U+56DB U+4E94");
  280. ExpectPrevWordBreakForCache(3, "U+4E00 U+4E8C | U+4E09 U+56DB U+4E94");
  281. ExpectPrevWordBreakForCache(4, "U+4E00 U+4E8C U+4E09 | U+56DB U+4E94");
  282. ExpectPrevWordBreakForCache(5, "U+4E00 U+4E8C U+4E09 U+56DB | U+4E94");
  283. ExpectPrevWordBreakForCache(1000, "U+4E00 U+4E8C U+4E09 U+56DB | U+4E94");
  284. // Mixed case.
  285. ExpectPrevWordBreakForCache(0, "| U+4E00 'a' 'b' U+2000 'c' U+4E00");
  286. ExpectPrevWordBreakForCache(1, "| U+4E00 'a' 'b' U+2000 'c' U+4E00");
  287. ExpectPrevWordBreakForCache(2, "| U+4E00 'a' 'b' U+2000 'c' U+4E00");
  288. ExpectPrevWordBreakForCache(3, "| U+4E00 'a' 'b' U+2000 'c' U+4E00");
  289. ExpectPrevWordBreakForCache(4, "U+4E00 'a' 'b' | U+2000 'c' U+4E00");
  290. ExpectPrevWordBreakForCache(5, "U+4E00 'a' 'b' U+2000 | 'c' U+4E00");
  291. ExpectPrevWordBreakForCache(6, "U+4E00 'a' 'b' U+2000 'c' | U+4E00");
  292. ExpectPrevWordBreakForCache(1000, "U+4E00 'a' 'b' U+2000 'c' | U+4E00");
  293. // Continue if trailing characters is Unicode combining characters.
  294. ExpectPrevWordBreakForCache(0, "| U+4E00 U+0332 U+4E00");
  295. ExpectPrevWordBreakForCache(1, "| U+4E00 U+0332 U+4E00");
  296. ExpectPrevWordBreakForCache(2, "| U+4E00 U+0332 U+4E00");
  297. ExpectPrevWordBreakForCache(3, "U+4E00 U+0332 | U+4E00");
  298. ExpectPrevWordBreakForCache(1000, "U+4E00 U+0332 | U+4E00");
  299. // Surrogate pairs.
  300. ExpectPrevWordBreakForCache(0, "| U+1F60D U+1F618");
  301. ExpectPrevWordBreakForCache(1, "| U+1F60D U+1F618");
  302. ExpectPrevWordBreakForCache(2, "| U+1F60D U+1F618");
  303. ExpectPrevWordBreakForCache(3, "| U+1F60D U+1F618");
  304. ExpectPrevWordBreakForCache(4, "| U+1F60D U+1F618");
  305. ExpectPrevWordBreakForCache(1000, "| U+1F60D U+1F618");
  306. // Broken surrogate pairs.
  307. // U+D84D is leading surrogate but there is no trailing surrogate for it.
  308. ExpectPrevWordBreakForCache(0, "| U+D84D U+1F618");
  309. ExpectPrevWordBreakForCache(1, "| U+D84D U+1F618");
  310. ExpectPrevWordBreakForCache(2, "| U+D84D U+1F618");
  311. ExpectPrevWordBreakForCache(3, "| U+D84D U+1F618");
  312. ExpectPrevWordBreakForCache(1000, "| U+D84D U+1F618");
  313. ExpectPrevWordBreakForCache(0, "| U+1F618 U+D84D");
  314. ExpectPrevWordBreakForCache(1, "| U+1F618 U+D84D");
  315. ExpectPrevWordBreakForCache(2, "| U+1F618 U+D84D");
  316. ExpectPrevWordBreakForCache(3, "| U+1F618 U+D84D");
  317. ExpectPrevWordBreakForCache(1000, "| U+1F618 U+D84D");
  318. // U+DE0D is trailing surrogate but there is no leading surrogate for it.
  319. ExpectPrevWordBreakForCache(0, "| U+DE0D U+1F618");
  320. ExpectPrevWordBreakForCache(1, "| U+DE0D U+1F618");
  321. ExpectPrevWordBreakForCache(2, "| U+DE0D U+1F618");
  322. ExpectPrevWordBreakForCache(3, "| U+DE0D U+1F618");
  323. ExpectPrevWordBreakForCache(1000, "| U+DE0D U+1F618");
  324. ExpectPrevWordBreakForCache(0, "| U+1F618 U+DE0D");
  325. ExpectPrevWordBreakForCache(1, "| U+1F618 U+DE0D");
  326. ExpectPrevWordBreakForCache(2, "| U+1F618 U+DE0D");
  327. ExpectPrevWordBreakForCache(3, "| U+1F618 U+DE0D");
  328. ExpectPrevWordBreakForCache(1000, "| U+1F618 U+DE0D");
  329. // Regional indicator pair. U+1F1FA U+1F1F8 is US national flag.
  330. ExpectPrevWordBreakForCache(0, "| U+1F1FA U+1F1F8");
  331. ExpectPrevWordBreakForCache(1, "| U+1F1FA U+1F1F8");
  332. ExpectPrevWordBreakForCache(2, "| U+1F1FA U+1F1F8");
  333. ExpectPrevWordBreakForCache(1000, "| U+1F1FA U+1F1F8");
  334. // Tone marks.
  335. // CJK ideographic char + Tone mark + CJK ideographic char
  336. ExpectPrevWordBreakForCache(0, "| U+4444 U+302D U+4444");
  337. ExpectPrevWordBreakForCache(1, "| U+4444 U+302D U+4444");
  338. ExpectPrevWordBreakForCache(2, "| U+4444 U+302D U+4444");
  339. ExpectPrevWordBreakForCache(3, "U+4444 U+302D | U+4444");
  340. ExpectPrevWordBreakForCache(1000, "U+4444 U+302D | U+4444");
  341. // Variation Selectors.
  342. // CJK Ideographic char + Variation Selector(VS1) + CJK Ideographic char
  343. ExpectPrevWordBreakForCache(0, "| U+845B U+FE00 U+845B");
  344. ExpectPrevWordBreakForCache(1, "| U+845B U+FE00 U+845B");
  345. ExpectPrevWordBreakForCache(2, "| U+845B U+FE00 U+845B");
  346. ExpectPrevWordBreakForCache(3, "U+845B U+FE00 | U+845B");
  347. ExpectPrevWordBreakForCache(1000, "U+845B U+FE00 | U+845B");
  348. // CJK Ideographic char + Variation Selector(VS17) + CJK Ideographic char
  349. ExpectPrevWordBreakForCache(0, "| U+845B U+E0100 U+845B");
  350. ExpectPrevWordBreakForCache(1, "| U+845B U+E0100 U+845B");
  351. ExpectPrevWordBreakForCache(2, "| U+845B U+E0100 U+845B");
  352. ExpectPrevWordBreakForCache(3, "| U+845B U+E0100 U+845B");
  353. ExpectPrevWordBreakForCache(4, "U+845B U+E0100 | U+845B");
  354. ExpectPrevWordBreakForCache(5, "U+845B U+E0100 | U+845B");
  355. ExpectPrevWordBreakForCache(1000, "U+845B U+E0100 | U+845B");
  356. // CJK ideographic char + Tone mark + Variation Character(VS1)
  357. ExpectPrevWordBreakForCache(0, "| U+4444 U+302D U+FE00 U+4444");
  358. ExpectPrevWordBreakForCache(1, "| U+4444 U+302D U+FE00 U+4444");
  359. ExpectPrevWordBreakForCache(2, "| U+4444 U+302D U+FE00 U+4444");
  360. ExpectPrevWordBreakForCache(3, "| U+4444 U+302D U+FE00 U+4444");
  361. ExpectPrevWordBreakForCache(4, "U+4444 U+302D U+FE00 | U+4444");
  362. ExpectPrevWordBreakForCache(1000, "U+4444 U+302D U+FE00 | U+4444");
  363. // CJK ideographic char + Tone mark + Variation Character(VS17)
  364. ExpectPrevWordBreakForCache(0, "| U+4444 U+302D U+E0100 U+4444");
  365. ExpectPrevWordBreakForCache(1, "| U+4444 U+302D U+E0100 U+4444");
  366. ExpectPrevWordBreakForCache(2, "| U+4444 U+302D U+E0100 U+4444");
  367. ExpectPrevWordBreakForCache(3, "| U+4444 U+302D U+E0100 U+4444");
  368. ExpectPrevWordBreakForCache(4, "| U+4444 U+302D U+E0100 U+4444");
  369. ExpectPrevWordBreakForCache(5, "U+4444 U+302D U+E0100 | U+4444");
  370. ExpectPrevWordBreakForCache(1000, "U+4444 U+302D U+E0100 | U+4444");
  371. // CJK ideographic char + Variation Character(VS1) + Tone mark
  372. ExpectPrevWordBreakForCache(0, "| U+4444 U+FE00 U+302D U+4444");
  373. ExpectPrevWordBreakForCache(1, "| U+4444 U+FE00 U+302D U+4444");
  374. ExpectPrevWordBreakForCache(2, "| U+4444 U+FE00 U+302D U+4444");
  375. ExpectPrevWordBreakForCache(3, "| U+4444 U+FE00 U+302D U+4444");
  376. ExpectPrevWordBreakForCache(4, "U+4444 U+FE00 U+302D | U+4444");
  377. ExpectPrevWordBreakForCache(1000, "U+4444 U+FE00 U+302D | U+4444");
  378. // CJK ideographic char + Variation Character(VS17) + Tone mark
  379. ExpectPrevWordBreakForCache(0, "| U+4444 U+E0100 U+302D U+4444");
  380. ExpectPrevWordBreakForCache(1, "| U+4444 U+E0100 U+302D U+4444");
  381. ExpectPrevWordBreakForCache(2, "| U+4444 U+E0100 U+302D U+4444");
  382. ExpectPrevWordBreakForCache(3, "| U+4444 U+E0100 U+302D U+4444");
  383. ExpectPrevWordBreakForCache(4, "| U+4444 U+E0100 U+302D U+4444");
  384. ExpectPrevWordBreakForCache(5, "U+4444 U+E0100 U+302D | U+4444");
  385. ExpectPrevWordBreakForCache(1000, "U+4444 U+E0100 U+302D | U+4444");
  386. // Following test cases are unusual usage of variation selectors and tone
  387. // marks for caching up the further behavior changes, e.g. index of bounds
  388. // or crashes. Please feel free to update the test expectations if the
  389. // behavior change makes sense to you.
  390. // Isolated Tone marks and Variation Selectors
  391. ExpectPrevWordBreakForCache(0, "| U+FE00");
  392. ExpectPrevWordBreakForCache(1, "| U+FE00");
  393. ExpectPrevWordBreakForCache(1000, "| U+FE00");
  394. ExpectPrevWordBreakForCache(0, "| U+E0100");
  395. ExpectPrevWordBreakForCache(1000, "| U+E0100");
  396. ExpectPrevWordBreakForCache(0, "| U+302D");
  397. ExpectPrevWordBreakForCache(1000, "| U+302D");
  398. // CJK Ideographic char + Variation Selector(VS1) + Variation Selector(VS1)
  399. ExpectPrevWordBreakForCache(0, "| U+845B U+FE00 U+FE00 U+845B");
  400. ExpectPrevWordBreakForCache(1, "| U+845B U+FE00 U+FE00 U+845B");
  401. ExpectPrevWordBreakForCache(2, "| U+845B U+FE00 U+FE00 U+845B");
  402. ExpectPrevWordBreakForCache(3, "| U+845B U+FE00 U+FE00 U+845B");
  403. ExpectPrevWordBreakForCache(4, "U+845B U+FE00 U+FE00 | U+845B");
  404. ExpectPrevWordBreakForCache(1000, "U+845B U+FE00 U+FE00 | U+845B");
  405. // CJK Ideographic char + Variation Selector(VS17) + Variation Selector(VS17)
  406. ExpectPrevWordBreakForCache(0, "| U+845B U+E0100 U+E0100 U+845B");
  407. ExpectPrevWordBreakForCache(1, "| U+845B U+E0100 U+E0100 U+845B");
  408. ExpectPrevWordBreakForCache(2, "| U+845B U+E0100 U+E0100 U+845B");
  409. ExpectPrevWordBreakForCache(3, "| U+845B U+E0100 U+E0100 U+845B");
  410. ExpectPrevWordBreakForCache(4, "| U+845B U+E0100 U+E0100 U+845B");
  411. ExpectPrevWordBreakForCache(5, "| U+845B U+E0100 U+E0100 U+845B");
  412. ExpectPrevWordBreakForCache(6, "U+845B U+E0100 U+E0100 | U+845B");
  413. ExpectPrevWordBreakForCache(1000, "U+845B U+E0100 U+E0100 | U+845B");
  414. // CJK Ideographic char + Variation Selector(VS1) + Variation Selector(VS17)
  415. ExpectPrevWordBreakForCache(0, "| U+845B U+FE00 U+E0100 U+845B");
  416. ExpectPrevWordBreakForCache(1, "| U+845B U+FE00 U+E0100 U+845B");
  417. ExpectPrevWordBreakForCache(2, "| U+845B U+FE00 U+E0100 U+845B");
  418. ExpectPrevWordBreakForCache(3, "| U+845B U+FE00 U+E0100 U+845B");
  419. ExpectPrevWordBreakForCache(4, "| U+845B U+FE00 U+E0100 U+845B");
  420. ExpectPrevWordBreakForCache(5, "U+845B U+FE00 U+E0100 | U+845B");
  421. ExpectPrevWordBreakForCache(1000, "U+845B U+FE00 U+E0100 | U+845B");
  422. // CJK Ideographic char + Variation Selector(VS17) + Variation Selector(VS1)
  423. ExpectPrevWordBreakForCache(0, "| U+845B U+E0100 U+FE00 U+845B");
  424. ExpectPrevWordBreakForCache(1, "| U+845B U+E0100 U+FE00 U+845B");
  425. ExpectPrevWordBreakForCache(2, "| U+845B U+E0100 U+FE00 U+845B");
  426. ExpectPrevWordBreakForCache(3, "| U+845B U+E0100 U+FE00 U+845B");
  427. ExpectPrevWordBreakForCache(4, "| U+845B U+E0100 U+FE00 U+845B");
  428. ExpectPrevWordBreakForCache(5, "U+845B U+E0100 U+FE00 | U+845B");
  429. ExpectPrevWordBreakForCache(1000, "U+845B U+E0100 U+FE00 | U+845B");
  430. // Tone mark. + Tone mark
  431. ExpectPrevWordBreakForCache(0, "| U+4444 U+302D U+302D U+4444");
  432. ExpectPrevWordBreakForCache(1, "| U+4444 U+302D U+302D U+4444");
  433. ExpectPrevWordBreakForCache(2, "| U+4444 U+302D U+302D U+4444");
  434. ExpectPrevWordBreakForCache(3, "| U+4444 U+302D U+302D U+4444");
  435. ExpectPrevWordBreakForCache(4, "U+4444 U+302D U+302D | U+4444");
  436. ExpectPrevWordBreakForCache(1000, "U+4444 U+302D U+302D | U+4444");
  437. }
  438. } // namespace minikin