bidiformatter_test.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651
  1. // Copyright 2009 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. goog.provide('goog.i18n.BidiFormatterTest');
  15. goog.setTestOnly('goog.i18n.BidiFormatterTest');
  16. goog.require('goog.html.SafeHtml');
  17. goog.require('goog.html.testing');
  18. goog.require('goog.i18n.BidiFormatter');
  19. goog.require('goog.i18n.bidi.Dir');
  20. goog.require('goog.i18n.bidi.Format');
  21. goog.require('goog.testing.jsunit');
  22. var LRM = goog.i18n.bidi.Format.LRM;
  23. var RLM = goog.i18n.bidi.Format.RLM;
  24. var LRE = goog.i18n.bidi.Format.LRE;
  25. var RLE = goog.i18n.bidi.Format.RLE;
  26. var PDF = goog.i18n.bidi.Format.PDF;
  27. var LTR = goog.i18n.bidi.Dir.LTR;
  28. var RTL = goog.i18n.bidi.Dir.RTL;
  29. var NEUTRAL = goog.i18n.bidi.Dir.NEUTRAL;
  30. var he = '\u05e0\u05e1';
  31. var en = 'abba';
  32. var html = '<';
  33. var longEn = 'abba sabba gabba ';
  34. var longHe = '\u05e0 \u05e1 \u05e0 ';
  35. var ltrFmt = new goog.i18n.BidiFormatter(LTR, false); // LTR context
  36. var rtlFmt = new goog.i18n.BidiFormatter(RTL, false); // RTL context
  37. var unkFmt = new goog.i18n.BidiFormatter(null, false); // unknown context
  38. function testGetContextDir() {
  39. assertEquals(null, unkFmt.getContextDir());
  40. assertEquals(null, new goog.i18n.BidiFormatter(NEUTRAL).getContextDir());
  41. assertEquals(LTR, ltrFmt.getContextDir());
  42. assertEquals(RTL, rtlFmt.getContextDir());
  43. }
  44. function testEstimateDirection() {
  45. assertEquals(NEUTRAL, ltrFmt.estimateDirection(''));
  46. assertEquals(NEUTRAL, rtlFmt.estimateDirection(''));
  47. assertEquals(NEUTRAL, unkFmt.estimateDirection(''));
  48. assertEquals(LTR, ltrFmt.estimateDirection(en));
  49. assertEquals(LTR, rtlFmt.estimateDirection(en));
  50. assertEquals(LTR, unkFmt.estimateDirection(en));
  51. assertEquals(RTL, ltrFmt.estimateDirection(he));
  52. assertEquals(RTL, rtlFmt.estimateDirection(he));
  53. assertEquals(RTL, unkFmt.estimateDirection(he));
  54. // Text contains HTML or HTML-escaping.
  55. assertEquals(
  56. LTR,
  57. ltrFmt.estimateDirection('<some sort of tag/>' + he + ' &amp;', false));
  58. assertEquals(
  59. RTL,
  60. ltrFmt.estimateDirection('<some sort of tag/>' + he + ' &amp;', true));
  61. }
  62. function testDirAttrValue() {
  63. assertEquals(
  64. 'overall dir is RTL, context dir is LTR', 'rtl',
  65. ltrFmt.dirAttrValue(he, true));
  66. assertEquals(
  67. 'overall dir and context dir are RTL', 'rtl',
  68. rtlFmt.dirAttrValue(he, true));
  69. assertEquals(
  70. 'overall dir is LTR, context dir is RTL', 'ltr',
  71. rtlFmt.dirAttrValue(en, true));
  72. assertEquals(
  73. 'overall dir and context dir are LTR', 'ltr',
  74. ltrFmt.dirAttrValue(en, true));
  75. // Input's directionality is neutral.
  76. assertEquals('ltr', ltrFmt.dirAttrValue('', true));
  77. assertEquals('rtl', rtlFmt.dirAttrValue('', true));
  78. assertEquals('ltr', unkFmt.dirAttrValue('', true));
  79. // Text contains HTML or HTML-escaping:
  80. assertEquals(
  81. 'rtl', ltrFmt.dirAttrValue(he + '<some sort of an HTML tag>', true));
  82. assertEquals(
  83. 'ltr', ltrFmt.dirAttrValue(he + '<some sort of an HTML tag>', false));
  84. }
  85. function testKnownDirAttrValue() {
  86. assertEquals('rtl', ltrFmt.knownDirAttrValue(RTL));
  87. assertEquals('rtl', rtlFmt.knownDirAttrValue(RTL));
  88. assertEquals('rtl', unkFmt.knownDirAttrValue(RTL));
  89. assertEquals('ltr', rtlFmt.knownDirAttrValue(LTR));
  90. assertEquals('ltr', ltrFmt.knownDirAttrValue(LTR));
  91. assertEquals('ltr', unkFmt.knownDirAttrValue(LTR));
  92. // Input directionality is neutral.
  93. assertEquals('ltr', ltrFmt.knownDirAttrValue(NEUTRAL));
  94. assertEquals('rtl', rtlFmt.knownDirAttrValue(NEUTRAL));
  95. assertEquals('ltr', unkFmt.knownDirAttrValue(NEUTRAL));
  96. }
  97. function testDirAttr() {
  98. assertEquals(
  99. 'overall dir (RTL) doesnt match context dir (LTR)', 'dir="rtl"',
  100. ltrFmt.dirAttr(he, true));
  101. assertEquals(
  102. 'overall dir (RTL) doesnt match context dir (unknown)', 'dir="rtl"',
  103. unkFmt.dirAttr(he, true));
  104. assertEquals(
  105. 'overall dir matches context dir (RTL)', '', rtlFmt.dirAttr(he, true));
  106. assertEquals(
  107. 'overall dir (LTR) doesnt match context dir (RTL)', 'dir="ltr"',
  108. rtlFmt.dirAttr(en, true));
  109. assertEquals(
  110. 'overall dir (LTR) doesnt match context dir (unknown)', 'dir="ltr"',
  111. unkFmt.dirAttr(en, true));
  112. assertEquals(
  113. 'overall dir matches context dir (LTR)', '', ltrFmt.dirAttr(en, true));
  114. assertEquals('neutral in RTL context', '', rtlFmt.dirAttr('.', true));
  115. assertEquals('neutral in LTR context', '', ltrFmt.dirAttr('.', true));
  116. assertEquals('neutral in unknown context', '', unkFmt.dirAttr('.', true));
  117. // Text contains HTML or HTML-escaping:
  118. assertEquals(
  119. 'dir="rtl"', ltrFmt.dirAttr(he + '<some sort of an HTML tag>', true));
  120. assertEquals('', ltrFmt.dirAttr(he + '<some sort of an HTML tag>', false));
  121. }
  122. function testKnownDirAttr() {
  123. assertEquals(
  124. 'overall dir (RTL) doesnt match context dir (LTR)', 'dir="rtl"',
  125. ltrFmt.knownDirAttr(RTL));
  126. assertEquals(
  127. 'overall dir matches context dir (RTL)', '', rtlFmt.knownDirAttr(RTL));
  128. assertEquals(
  129. 'overall dir (LTR) doesnt match context dir (RTL)', 'dir="ltr"',
  130. rtlFmt.knownDirAttr(LTR));
  131. assertEquals(
  132. 'overall dir matches context dir (LTR)', '', ltrFmt.knownDirAttr(LTR));
  133. }
  134. /**
  135. * @param {!goog.i18n.BidiFormatter} formatter
  136. * @param {string} html
  137. * @param {boolean=} opt_dirReset
  138. * @return {string}
  139. */
  140. function spanWrap(formatter, html, opt_dirReset) {
  141. return goog.html.SafeHtml.unwrap(formatter.spanWrapSafeHtml(
  142. goog.html.testing.newSafeHtmlForTest(html),
  143. opt_dirReset));
  144. }
  145. function testSpanWrap() {
  146. // alwaysSpan is false and opt_isHtml is true, unless specified otherwise.
  147. assertEquals(
  148. 'overall dir matches context dir (LTR), no dirReset', en,
  149. spanWrap(ltrFmt, en, false));
  150. assertEquals(
  151. 'overall dir matches context dir (LTR), dirReset', en,
  152. spanWrap(ltrFmt, en, true));
  153. assertEquals(
  154. 'overall dir matches context dir (RTL), no dirReset', he,
  155. spanWrap(rtlFmt, he, false));
  156. assertEquals(
  157. 'overall dir matches context dir (RTL), dirReset', he,
  158. spanWrap(rtlFmt, he, true));
  159. assertEquals(
  160. 'overall dir (RTL) doesnt match context dir (LTR), ' +
  161. 'no dirReset',
  162. '<span dir="rtl">' + he + '<\/span>', spanWrap(ltrFmt, he, false));
  163. assertEquals(
  164. 'overall dir (RTL) doesnt match context dir (LTR), dirReset',
  165. '<span dir="rtl">' + he + '<\/span>' + LRM,
  166. spanWrap(ltrFmt, he, true));
  167. assertEquals(
  168. 'overall dir (LTR) doesnt match context dir (RTL), ' +
  169. 'no dirReset',
  170. '<span dir="ltr">' + en + '<\/span>', spanWrap(rtlFmt, en, false));
  171. assertEquals(
  172. 'overall dir (LTR) doesnt match context dir (RTL), dirReset',
  173. '<span dir="ltr">' + en + '<\/span>' + RLM,
  174. spanWrap(rtlFmt, en, true));
  175. assertEquals(
  176. 'overall dir (LTR) doesnt match context dir (unknown), ' +
  177. 'no dirReset',
  178. '<span dir="ltr">' + en + '<\/span>', spanWrap(unkFmt, en, false));
  179. assertEquals(
  180. 'overall dir (RTL) doesnt match context dir (unknown), ' +
  181. 'dirReset',
  182. '<span dir="rtl">' + he + '<\/span>', spanWrap(unkFmt, he, true));
  183. assertEquals(
  184. 'overall dir (neutral) doesnt match context dir (LTR), ' +
  185. 'dirReset',
  186. '', spanWrap(ltrFmt, '', true));
  187. assertEquals(
  188. 'exit dir (but not overall dir) is opposite to context dir, ' +
  189. 'dirReset',
  190. longEn + he + html + LRM,
  191. spanWrap(ltrFmt, longEn + he + html, true));
  192. assertEquals(
  193. 'overall dir (but not exit dir) is opposite to context dir, ' +
  194. 'dirReset',
  195. '<span dir="ltr">' + longEn + he + '<\/span>' + RLM,
  196. spanWrap(rtlFmt, longEn + he, true));
  197. var ltrAlwaysSpanFmt = new goog.i18n.BidiFormatter(LTR, true);
  198. var rtlAlwaysSpanFmt = new goog.i18n.BidiFormatter(RTL, true);
  199. var unkAlwaysSpanFmt = new goog.i18n.BidiFormatter(null, true);
  200. assertEquals(
  201. 'alwaysSpan, overall dir matches context dir (LTR), ' +
  202. 'no dirReset',
  203. '<span>' + en + '<\/span>', spanWrap(ltrAlwaysSpanFmt, en, false));
  204. assertEquals(
  205. 'alwaysSpan, overall dir matches context dir (LTR), dirReset',
  206. '<span>' + en + '<\/span>', spanWrap(ltrAlwaysSpanFmt, en, true));
  207. assertEquals(
  208. 'alwaysSpan, overall dir matches context dir (RTL), ' +
  209. 'no dirReset',
  210. '<span>' + he + '<\/span>', spanWrap(rtlAlwaysSpanFmt, he, false));
  211. assertEquals(
  212. 'alwaysSpan, overall dir matches context dir (RTL), dirReset',
  213. '<span>' + he + '<\/span>', spanWrap(rtlAlwaysSpanFmt, he, true));
  214. assertEquals(
  215. 'alwaysSpan, overall dir (RTL) doesnt match ' +
  216. 'context dir (LTR), no dirReset',
  217. '<span dir="rtl">' + he + '<\/span>',
  218. spanWrap(ltrAlwaysSpanFmt, he, false));
  219. assertEquals(
  220. 'alwaysSpan, overall dir (RTL) doesnt match ' +
  221. 'context dir (LTR), dirReset',
  222. '<span dir="rtl">' + he + '<\/span>' + LRM,
  223. spanWrap(ltrAlwaysSpanFmt, he, true));
  224. assertEquals(
  225. 'alwaysSpan, overall dir (neutral) doesnt match ' +
  226. 'context dir (LTR), dirReset',
  227. '<span></span>', spanWrap(ltrAlwaysSpanFmt, '', true));
  228. }
  229. function testSpanWrapSafeHtml() {
  230. var html = goog.html.SafeHtml.htmlEscape('a');
  231. var wrapped = rtlFmt.spanWrapSafeHtml(html, false);
  232. assertHtmlEquals('<span dir="ltr">a</span>', wrapped);
  233. assertEquals(NEUTRAL, wrapped.getDirection());
  234. }
  235. /**
  236. * @param {!goog.i18n.BidiFormatter} formatter
  237. * @param {?goog.i18n.bidi.Dir} dir
  238. * @param {string} html
  239. * @return {string}
  240. */
  241. function spanWrapWithKnownDir(formatter, dir, html) {
  242. return goog.html.SafeHtml.unwrap(formatter.spanWrapSafeHtmlWithKnownDir(dir,
  243. goog.html.testing.newSafeHtmlForTest(html)));
  244. }
  245. function testSpanWrapWithKnownDir() {
  246. assertEquals(
  247. 'known LTR in LTR context', en, spanWrapWithKnownDir(ltrFmt, LTR, en));
  248. assertEquals(
  249. 'unknown LTR in LTR context', en, spanWrapWithKnownDir(ltrFmt, null, en));
  250. assertEquals(
  251. 'overall LTR but exit RTL in LTR context', he + LRM,
  252. spanWrapWithKnownDir(ltrFmt, LTR, he));
  253. assertEquals(
  254. 'known RTL in LTR context', '<span dir="rtl">' + he + '<\/span>' + LRM,
  255. spanWrapWithKnownDir(ltrFmt, RTL, he));
  256. assertEquals(
  257. 'unknown RTL in LTR context', '<span dir="rtl">' + he + '<\/span>' + LRM,
  258. spanWrapWithKnownDir(ltrFmt, null, he));
  259. assertEquals(
  260. 'overall RTL but exit LTR in LTR context',
  261. '<span dir="rtl">' + en + '<\/span>' + LRM,
  262. spanWrapWithKnownDir(ltrFmt, RTL, en));
  263. assertEquals(
  264. 'known neutral in LTR context', '.',
  265. spanWrapWithKnownDir(ltrFmt, NEUTRAL, '.'));
  266. assertEquals(
  267. 'unknown neutral in LTR context', '.',
  268. spanWrapWithKnownDir(ltrFmt, null, '.'));
  269. assertEquals(
  270. 'overall neutral but exit LTR in LTR context', en,
  271. spanWrapWithKnownDir(ltrFmt, NEUTRAL, en));
  272. assertEquals(
  273. 'overall neutral but exit RTL in LTR context', he + LRM,
  274. spanWrapWithKnownDir(ltrFmt, NEUTRAL, he));
  275. assertEquals(
  276. 'known RTL in RTL context', he, spanWrapWithKnownDir(rtlFmt, RTL, he));
  277. assertEquals(
  278. 'unknown RTL in RTL context', he, spanWrapWithKnownDir(rtlFmt, null, he));
  279. assertEquals(
  280. 'overall RTL but exit LTR in RTL context', en + RLM,
  281. spanWrapWithKnownDir(rtlFmt, RTL, en));
  282. assertEquals(
  283. 'known LTR in RTL context', '<span dir="ltr">' + en + '<\/span>' + RLM,
  284. spanWrapWithKnownDir(rtlFmt, LTR, en));
  285. assertEquals(
  286. 'unknown LTR in RTL context', '<span dir="ltr">' + en + '<\/span>' + RLM,
  287. spanWrapWithKnownDir(rtlFmt, null, en));
  288. assertEquals(
  289. 'LTR but exit RTL in RTL context',
  290. '<span dir="ltr">' + he + '<\/span>' + RLM,
  291. spanWrapWithKnownDir(rtlFmt, LTR, he));
  292. assertEquals(
  293. 'known neutral in RTL context', '.',
  294. spanWrapWithKnownDir(rtlFmt, NEUTRAL, '.'));
  295. assertEquals(
  296. 'unknown neutral in RTL context', '.',
  297. spanWrapWithKnownDir(rtlFmt, null, '.'));
  298. assertEquals(
  299. 'overall neutral but exit LTR in LTR context', he,
  300. spanWrapWithKnownDir(rtlFmt, NEUTRAL, he));
  301. assertEquals(
  302. 'overall neutral but exit RTL in LTR context', en + RLM,
  303. spanWrapWithKnownDir(rtlFmt, NEUTRAL, en));
  304. assertEquals(
  305. 'known RTL in unknown context', '<span dir="rtl">' + he + '<\/span>',
  306. spanWrapWithKnownDir(unkFmt, RTL, he));
  307. assertEquals(
  308. 'unknown RTL in unknown context', '<span dir="rtl">' + he + '<\/span>',
  309. spanWrapWithKnownDir(unkFmt, null, he));
  310. assertEquals(
  311. 'overall RTL but exit LTR in unknown context',
  312. '<span dir="rtl">' + en + '<\/span>',
  313. spanWrapWithKnownDir(unkFmt, RTL, en));
  314. assertEquals(
  315. 'known LTR in unknown context', '<span dir="ltr">' + en + '<\/span>',
  316. spanWrapWithKnownDir(unkFmt, LTR, en));
  317. assertEquals(
  318. 'unknown LTR in unknown context', '<span dir="ltr">' + en + '<\/span>',
  319. spanWrapWithKnownDir(unkFmt, null, en));
  320. assertEquals(
  321. 'LTR but exit RTL in unknown context',
  322. '<span dir="ltr">' + he + '<\/span>',
  323. spanWrapWithKnownDir(unkFmt, LTR, he));
  324. assertEquals(
  325. 'known neutral in unknown context', '.',
  326. spanWrapWithKnownDir(unkFmt, NEUTRAL, '.'));
  327. assertEquals(
  328. 'unknown neutral in unknown context', '.',
  329. spanWrapWithKnownDir(unkFmt, null, '.'));
  330. assertEquals(
  331. 'overall neutral but exit LTR in unknown context', he,
  332. spanWrapWithKnownDir(unkFmt, NEUTRAL, he));
  333. assertEquals(
  334. 'overall neutral but exit RTL in unknown context', en,
  335. spanWrapWithKnownDir(unkFmt, NEUTRAL, en));
  336. }
  337. function testSpanWrapSafeHtmlWithKnownDir() {
  338. var html = goog.html.SafeHtml.htmlEscape('a');
  339. assertHtmlEquals(
  340. '<span dir="ltr">a</span>',
  341. rtlFmt.spanWrapSafeHtmlWithKnownDir(LTR, html, false));
  342. }
  343. function testUnicodeWrap() {
  344. // opt_isHtml is true, unless specified otherwise.
  345. assertEquals(
  346. 'overall dir matches context dir (LTR), no dirReset', en,
  347. ltrFmt.unicodeWrap(en, true, false));
  348. assertEquals(
  349. 'overall dir matches context dir (LTR), dirReset', en,
  350. ltrFmt.unicodeWrap(en, true, true));
  351. assertEquals(
  352. 'overall dir matches context dir (RTL), no dirReset', he,
  353. rtlFmt.unicodeWrap(he, true, false));
  354. assertEquals(
  355. 'overall dir matches context dir (RTL), dirReset', he,
  356. rtlFmt.unicodeWrap(he, true, true));
  357. assertEquals(
  358. 'overall dir (RTL) doesnt match context dir (LTR), ' +
  359. 'no dirReset',
  360. RLE + he + PDF, ltrFmt.unicodeWrap(he, true, false));
  361. assertEquals(
  362. 'overall dir (RTL) doesnt match context dir (LTR), dirReset',
  363. RLE + he + PDF + LRM, ltrFmt.unicodeWrap(he, true, true));
  364. assertEquals(
  365. 'overall dir (LTR) doesnt match context dir (RTL), ' +
  366. 'no dirReset',
  367. LRE + en + PDF, rtlFmt.unicodeWrap(en, true, false));
  368. assertEquals(
  369. 'overall dir (LTR) doesnt match context dir (RTL), dirReset',
  370. LRE + en + PDF + RLM, rtlFmt.unicodeWrap(en, true, true));
  371. assertEquals(
  372. 'overall dir (LTR) doesnt match context dir (unknown), ' +
  373. 'no dirReset',
  374. LRE + en + PDF, unkFmt.unicodeWrap(en, true, false));
  375. assertEquals(
  376. 'overall dir (RTL) doesnt match context dir (unknown), ' +
  377. 'dirReset',
  378. RLE + he + PDF, unkFmt.unicodeWrap(he, true, true));
  379. assertEquals(
  380. 'overall dir (neutral) doesnt match context dir (LTR), ' +
  381. 'dirReset',
  382. '', ltrFmt.unicodeWrap('', true, true));
  383. assertEquals(
  384. 'exit dir (but not overall dir) is opposite to context dir, ' +
  385. 'dirReset',
  386. longEn + he + html + LRM,
  387. ltrFmt.unicodeWrap(longEn + he + html, true, true));
  388. assertEquals(
  389. 'overall dir (but not exit dir) is opposite to context dir, ' +
  390. 'dirReset',
  391. LRE + longEn + he + PDF + RLM,
  392. rtlFmt.unicodeWrap(longEn + he, true, true));
  393. }
  394. function testUnicodeWrapWithKnownDir() {
  395. assertEquals(
  396. 'known LTR in LTR context', en, ltrFmt.unicodeWrapWithKnownDir(LTR, en));
  397. assertEquals(
  398. 'unknown LTR in LTR context', en,
  399. ltrFmt.unicodeWrapWithKnownDir(null, en));
  400. assertEquals(
  401. 'overall LTR but exit RTL in LTR context', he + LRM,
  402. ltrFmt.unicodeWrapWithKnownDir(LTR, he));
  403. assertEquals(
  404. 'known RTL in LTR context', RLE + he + PDF + LRM,
  405. ltrFmt.unicodeWrapWithKnownDir(RTL, he));
  406. assertEquals(
  407. 'unknown RTL in LTR context', RLE + he + PDF + LRM,
  408. ltrFmt.unicodeWrapWithKnownDir(null, he));
  409. assertEquals(
  410. 'overall RTL but exit LTR in LTR context', RLE + en + PDF + LRM,
  411. ltrFmt.unicodeWrapWithKnownDir(RTL, en));
  412. assertEquals(
  413. 'known neutral in LTR context', '.',
  414. ltrFmt.unicodeWrapWithKnownDir(NEUTRAL, '.'));
  415. assertEquals(
  416. 'unknown neutral in LTR context', '.',
  417. ltrFmt.unicodeWrapWithKnownDir(null, '.'));
  418. assertEquals(
  419. 'overall neutral but exit LTR in LTR context', en,
  420. ltrFmt.unicodeWrapWithKnownDir(NEUTRAL, en));
  421. assertEquals(
  422. 'overall neutral but exit RTL in LTR context', he + LRM,
  423. ltrFmt.unicodeWrapWithKnownDir(NEUTRAL, he));
  424. assertEquals(
  425. 'known RTL in RTL context', he, rtlFmt.unicodeWrapWithKnownDir(RTL, he));
  426. assertEquals(
  427. 'unknown RTL in RTL context', he,
  428. rtlFmt.unicodeWrapWithKnownDir(null, he));
  429. assertEquals(
  430. 'overall RTL but exit LTR in RTL context', en + RLM,
  431. rtlFmt.unicodeWrapWithKnownDir(RTL, en));
  432. assertEquals(
  433. 'known LTR in RTL context', LRE + en + PDF + RLM,
  434. rtlFmt.unicodeWrapWithKnownDir(LTR, en));
  435. assertEquals(
  436. 'unknown LTR in RTL context', LRE + en + PDF + RLM,
  437. rtlFmt.unicodeWrapWithKnownDir(null, en));
  438. assertEquals(
  439. 'LTR but exit RTL in RTL context', LRE + he + PDF + RLM,
  440. rtlFmt.unicodeWrapWithKnownDir(LTR, he));
  441. assertEquals(
  442. 'known neutral in RTL context', '.',
  443. rtlFmt.unicodeWrapWithKnownDir(NEUTRAL, '.'));
  444. assertEquals(
  445. 'unknown neutral in RTL context', '.',
  446. rtlFmt.unicodeWrapWithKnownDir(null, '.'));
  447. assertEquals(
  448. 'overall neutral but exit LTR in LTR context', he,
  449. rtlFmt.unicodeWrapWithKnownDir(NEUTRAL, he));
  450. assertEquals(
  451. 'overall neutral but exit RTL in LTR context', en + RLM,
  452. rtlFmt.unicodeWrapWithKnownDir(NEUTRAL, en));
  453. assertEquals(
  454. 'known RTL in unknown context', RLE + he + PDF,
  455. unkFmt.unicodeWrapWithKnownDir(RTL, he));
  456. assertEquals(
  457. 'unknown RTL in unknown context', RLE + he + PDF,
  458. unkFmt.unicodeWrapWithKnownDir(null, he));
  459. assertEquals(
  460. 'overall RTL but exit LTR in unknown context', RLE + en + PDF,
  461. unkFmt.unicodeWrapWithKnownDir(RTL, en));
  462. assertEquals(
  463. 'known LTR in unknown context', LRE + en + PDF,
  464. unkFmt.unicodeWrapWithKnownDir(LTR, en));
  465. assertEquals(
  466. 'unknown LTR in unknown context', LRE + en + PDF,
  467. unkFmt.unicodeWrapWithKnownDir(null, en));
  468. assertEquals(
  469. 'LTR but exit RTL in unknown context', LRE + he + PDF,
  470. unkFmt.unicodeWrapWithKnownDir(LTR, he));
  471. assertEquals(
  472. 'known neutral in unknown context', '.',
  473. unkFmt.unicodeWrapWithKnownDir(NEUTRAL, '.'));
  474. assertEquals(
  475. 'unknown neutral in unknown context', '.',
  476. unkFmt.unicodeWrapWithKnownDir(null, '.'));
  477. assertEquals(
  478. 'overall neutral but exit LTR in unknown context', he,
  479. unkFmt.unicodeWrapWithKnownDir(NEUTRAL, he));
  480. assertEquals(
  481. 'overall neutral but exit RTL in unknown context', en,
  482. unkFmt.unicodeWrapWithKnownDir(NEUTRAL, en));
  483. }
  484. function testMarkAfter() {
  485. assertEquals(
  486. 'exit dir (RTL) is opposite to context dir (LTR)', LRM,
  487. ltrFmt.markAfter(longEn + he + html, true));
  488. assertEquals(
  489. 'exit dir (LTR) is opposite to context dir (RTL)', RLM,
  490. rtlFmt.markAfter(longHe + en, true));
  491. assertEquals(
  492. 'exit dir (LTR) doesnt match context dir (unknown)', '',
  493. unkFmt.markAfter(longEn + en, true));
  494. assertEquals(
  495. 'overall dir (RTL) is opposite to context dir (LTR)', LRM,
  496. ltrFmt.markAfter(longHe + en, true));
  497. assertEquals(
  498. 'overall dir (LTR) is opposite to context dir (RTL)', RLM,
  499. rtlFmt.markAfter(longEn + he, true));
  500. assertEquals(
  501. 'exit dir and overall dir match context dir (LTR)', '',
  502. ltrFmt.markAfter(longEn + he + html, false));
  503. assertEquals(
  504. 'exit dir and overall dir matches context dir (RTL)', '',
  505. rtlFmt.markAfter(longHe + he, true));
  506. }
  507. function testMarkAfterKnownDir() {
  508. assertEquals(
  509. 'known LTR in LTR context', '', ltrFmt.markAfterKnownDir(LTR, en));
  510. assertEquals(
  511. 'unknown LTR in LTR context', '', ltrFmt.markAfterKnownDir(null, en));
  512. assertEquals(
  513. 'overall LTR but exit RTL in LTR context', LRM,
  514. ltrFmt.markAfterKnownDir(LTR, he));
  515. assertEquals(
  516. 'known RTL in LTR context', LRM, ltrFmt.markAfterKnownDir(RTL, he));
  517. assertEquals(
  518. 'unknown RTL in LTR context', LRM, ltrFmt.markAfterKnownDir(null, he));
  519. assertEquals(
  520. 'overall RTL but exit LTR in LTR context', LRM,
  521. ltrFmt.markAfterKnownDir(RTL, en));
  522. assertEquals(
  523. 'known neutral in LTR context', '',
  524. ltrFmt.markAfterKnownDir(NEUTRAL, '.'));
  525. assertEquals(
  526. 'unknown neutral in LTR context', '',
  527. ltrFmt.markAfterKnownDir(null, '.'));
  528. assertEquals(
  529. 'overall neutral but exit LTR in LTR context', '',
  530. ltrFmt.markAfterKnownDir(NEUTRAL, en));
  531. assertEquals(
  532. 'overall neutral but exit RTL in LTR context', LRM,
  533. ltrFmt.markAfterKnownDir(NEUTRAL, he));
  534. assertEquals(
  535. 'known RTL in RTL context', '', rtlFmt.markAfterKnownDir(RTL, he));
  536. assertEquals(
  537. 'unknown RTL in RTL context', '', rtlFmt.markAfterKnownDir(null, he));
  538. assertEquals(
  539. 'overall RTL but exit LTR in RTL context', RLM,
  540. rtlFmt.markAfterKnownDir(RTL, en));
  541. assertEquals(
  542. 'known LTR in RTL context', RLM, rtlFmt.markAfterKnownDir(LTR, en));
  543. assertEquals(
  544. 'unknown LTR in RTL context', RLM, rtlFmt.markAfterKnownDir(null, en));
  545. assertEquals(
  546. 'LTR but exit RTL in RTL context', RLM,
  547. rtlFmt.markAfterKnownDir(LTR, he));
  548. assertEquals(
  549. 'known neutral in RTL context', '',
  550. rtlFmt.markAfterKnownDir(NEUTRAL, '.'));
  551. assertEquals(
  552. 'unknown neutral in RTL context', '',
  553. rtlFmt.markAfterKnownDir(null, '.'));
  554. assertEquals(
  555. 'overall neutral but exit LTR in LTR context', '',
  556. rtlFmt.markAfterKnownDir(NEUTRAL, he));
  557. assertEquals(
  558. 'overall neutral but exit RTL in LTR context', RLM,
  559. rtlFmt.markAfterKnownDir(NEUTRAL, en));
  560. assertEquals(
  561. 'known RTL in unknown context', '', unkFmt.markAfterKnownDir(RTL, he));
  562. assertEquals(
  563. 'unknown RTL in unknown context', '', unkFmt.markAfterKnownDir(null, he));
  564. assertEquals(
  565. 'overall RTL but exit LTR in unknown context', '',
  566. unkFmt.markAfterKnownDir(RTL, en));
  567. assertEquals(
  568. 'known LTR in unknown context', '', unkFmt.markAfterKnownDir(LTR, en));
  569. assertEquals(
  570. 'unknown LTR in unknown context', '', unkFmt.markAfterKnownDir(null, en));
  571. assertEquals(
  572. 'LTR but exit RTL in unknown context', '',
  573. unkFmt.markAfterKnownDir(LTR, he));
  574. assertEquals(
  575. 'known neutral in unknown context', '',
  576. unkFmt.markAfterKnownDir(NEUTRAL, '.'));
  577. assertEquals(
  578. 'unknown neutral in unknown context', '',
  579. unkFmt.markAfterKnownDir(null, '.'));
  580. assertEquals(
  581. 'overall neutral but exit LTR in unknown context', '',
  582. unkFmt.markAfterKnownDir(NEUTRAL, he));
  583. assertEquals(
  584. 'overall neutral but exit RTL in unknown context', '',
  585. unkFmt.markAfterKnownDir(NEUTRAL, en));
  586. }
  587. function testMark() {
  588. // Implicitly, also tests the constructor.
  589. assertEquals(LRM, (new goog.i18n.BidiFormatter(LTR)).mark());
  590. assertEquals('', (new goog.i18n.BidiFormatter(null)).mark());
  591. assertEquals('', (new goog.i18n.BidiFormatter(NEUTRAL)).mark());
  592. assertEquals(RLM, (new goog.i18n.BidiFormatter(RTL)).mark());
  593. assertEquals(RLM, (new goog.i18n.BidiFormatter(true)).mark());
  594. assertEquals(LRM, (new goog.i18n.BidiFormatter(false)).mark());
  595. }
  596. function testStartEdge() {
  597. assertEquals('left', ltrFmt.startEdge());
  598. assertEquals('left', unkFmt.startEdge());
  599. assertEquals('right', rtlFmt.startEdge());
  600. }
  601. function testEndEdge() {
  602. assertEquals('right', ltrFmt.endEdge());
  603. assertEquals('right', unkFmt.endEdge());
  604. assertEquals('left', rtlFmt.endEdge());
  605. }
  606. function assertHtmlEquals(expected, html) {
  607. assertEquals(expected, goog.html.SafeHtml.unwrap(html));
  608. }