bidirule9.0.0_test.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. // Copyright 2016 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build !go1.10
  5. package bidirule
  6. import (
  7. "golang.org/x/text/transform"
  8. "golang.org/x/text/unicode/bidi"
  9. )
  10. var testCases = [][]ruleTest{
  11. // Go-specific rules.
  12. // Invalid UTF-8 is invalid.
  13. 0: []ruleTest{{
  14. in: "",
  15. dir: bidi.LeftToRight,
  16. }, {
  17. in: "\x80",
  18. dir: bidi.LeftToRight,
  19. err: ErrInvalid,
  20. n: 0,
  21. }, {
  22. in: "\xcc",
  23. dir: bidi.LeftToRight,
  24. err: ErrInvalid,
  25. n: 0,
  26. }, {
  27. in: "abc\x80",
  28. dir: bidi.LeftToRight,
  29. err: ErrInvalid,
  30. n: 3,
  31. }, {
  32. in: "abc\xcc",
  33. dir: bidi.LeftToRight,
  34. err: ErrInvalid,
  35. n: 3,
  36. }, {
  37. in: "abc\xccdef",
  38. dir: bidi.LeftToRight,
  39. err: ErrInvalid,
  40. n: 3,
  41. }, {
  42. in: "\xccdef",
  43. dir: bidi.LeftToRight,
  44. err: ErrInvalid,
  45. n: 0,
  46. }, {
  47. in: strR + "\x80",
  48. dir: bidi.RightToLeft,
  49. err: ErrInvalid,
  50. n: len(strR),
  51. }, {
  52. in: strR + "\xcc",
  53. dir: bidi.RightToLeft,
  54. err: ErrInvalid,
  55. n: len(strR),
  56. }, {
  57. in: strAL + "\xcc" + strR,
  58. dir: bidi.RightToLeft,
  59. err: ErrInvalid,
  60. n: len(strAL),
  61. }, {
  62. in: "\xcc" + strR,
  63. dir: bidi.RightToLeft,
  64. err: ErrInvalid,
  65. n: 0,
  66. }},
  67. // Rule 2.1: The first character must be a character with Bidi property L,
  68. // R, or AL. If it has the R or AL property, it is an RTL label; if it has
  69. // the L property, it is an LTR label.
  70. 1: []ruleTest{{
  71. in: strL,
  72. dir: bidi.LeftToRight,
  73. }, {
  74. in: strR,
  75. dir: bidi.RightToLeft,
  76. }, {
  77. in: strAL,
  78. dir: bidi.RightToLeft,
  79. }, {
  80. in: strAN,
  81. dir: bidi.RightToLeft,
  82. err: ErrInvalid,
  83. }, {
  84. in: strEN,
  85. dir: bidi.LeftToRight,
  86. err: nil, // not an RTL string
  87. }, {
  88. in: strES,
  89. dir: bidi.LeftToRight,
  90. err: nil, // not an RTL string
  91. }, {
  92. in: strET,
  93. dir: bidi.LeftToRight,
  94. err: nil, // not an RTL string
  95. }, {
  96. in: strCS,
  97. dir: bidi.LeftToRight,
  98. err: nil, // not an RTL string
  99. }, {
  100. in: strNSM,
  101. dir: bidi.LeftToRight,
  102. err: nil, // not an RTL string
  103. }, {
  104. in: strBN,
  105. dir: bidi.LeftToRight,
  106. err: nil, // not an RTL string
  107. }, {
  108. in: strB,
  109. dir: bidi.LeftToRight,
  110. err: nil, // not an RTL string
  111. }, {
  112. in: strS,
  113. dir: bidi.LeftToRight,
  114. err: nil, // not an RTL string
  115. }, {
  116. in: strWS,
  117. dir: bidi.LeftToRight,
  118. err: nil, // not an RTL string
  119. }, {
  120. in: strON,
  121. dir: bidi.LeftToRight,
  122. err: nil, // not an RTL string
  123. }, {
  124. in: strEN + strR,
  125. dir: bidi.RightToLeft,
  126. err: ErrInvalid,
  127. n: 3,
  128. }, {
  129. in: strES + strR,
  130. dir: bidi.RightToLeft,
  131. err: ErrInvalid,
  132. n: 2,
  133. }, {
  134. in: strET + strR,
  135. dir: bidi.RightToLeft,
  136. err: ErrInvalid,
  137. n: 1,
  138. }, {
  139. in: strCS + strR,
  140. dir: bidi.RightToLeft,
  141. err: ErrInvalid,
  142. n: 1,
  143. }, {
  144. in: strNSM + strR,
  145. dir: bidi.RightToLeft,
  146. err: ErrInvalid,
  147. n: 2,
  148. }, {
  149. in: strBN + strR,
  150. dir: bidi.RightToLeft,
  151. err: ErrInvalid,
  152. n: 3,
  153. }, {
  154. in: strB + strR,
  155. dir: bidi.RightToLeft,
  156. err: ErrInvalid,
  157. n: 3,
  158. }, {
  159. in: strS + strR,
  160. dir: bidi.RightToLeft,
  161. err: ErrInvalid,
  162. n: 1,
  163. }, {
  164. in: strWS + strR,
  165. dir: bidi.RightToLeft,
  166. err: ErrInvalid,
  167. n: 1,
  168. }, {
  169. in: strON + strR,
  170. dir: bidi.RightToLeft,
  171. err: ErrInvalid,
  172. n: 1,
  173. }},
  174. // Rule 2.2: In an RTL label, only characters with the Bidi properties R,
  175. // AL, AN, EN, ES, CS, ET, ON, BN, or NSM are allowed.
  176. 2: []ruleTest{{
  177. in: strR + strR + strAL,
  178. dir: bidi.RightToLeft,
  179. }, {
  180. in: strR + strAL + strR,
  181. dir: bidi.RightToLeft,
  182. }, {
  183. in: strR + strAN + strAL,
  184. dir: bidi.RightToLeft,
  185. }, {
  186. in: strR + strEN + strR,
  187. dir: bidi.RightToLeft,
  188. }, {
  189. in: strR + strES + strR,
  190. dir: bidi.RightToLeft,
  191. }, {
  192. in: strR + strCS + strR,
  193. dir: bidi.RightToLeft,
  194. }, {
  195. in: strR + strET + strAL,
  196. dir: bidi.RightToLeft,
  197. }, {
  198. in: strR + strON + strR,
  199. dir: bidi.RightToLeft,
  200. }, {
  201. in: strR + strBN + strR,
  202. dir: bidi.RightToLeft,
  203. }, {
  204. in: strR + strNSM + strAL,
  205. dir: bidi.RightToLeft,
  206. }, {
  207. in: strR + strL + strR,
  208. dir: bidi.RightToLeft,
  209. n: len(strR),
  210. err: ErrInvalid,
  211. }, {
  212. in: strR + strB + strR,
  213. dir: bidi.RightToLeft,
  214. n: len(strR),
  215. err: ErrInvalid,
  216. }, {
  217. in: strR + strS + strAL,
  218. dir: bidi.RightToLeft,
  219. n: len(strR),
  220. err: ErrInvalid,
  221. }, {
  222. in: strR + strWS + strAL,
  223. dir: bidi.RightToLeft,
  224. n: len(strR),
  225. err: ErrInvalid,
  226. }, {
  227. in: strAL + strR + strAL,
  228. dir: bidi.RightToLeft,
  229. }, {
  230. in: strAL + strAL + strR,
  231. dir: bidi.RightToLeft,
  232. }, {
  233. in: strAL + strAN + strAL,
  234. dir: bidi.RightToLeft,
  235. }, {
  236. in: strAL + strEN + strR,
  237. dir: bidi.RightToLeft,
  238. }, {
  239. in: strAL + strES + strR,
  240. dir: bidi.RightToLeft,
  241. }, {
  242. in: strAL + strCS + strR,
  243. dir: bidi.RightToLeft,
  244. }, {
  245. in: strAL + strET + strAL,
  246. dir: bidi.RightToLeft,
  247. }, {
  248. in: strAL + strON + strR,
  249. dir: bidi.RightToLeft,
  250. }, {
  251. in: strAL + strBN + strR,
  252. dir: bidi.RightToLeft,
  253. }, {
  254. in: strAL + strNSM + strAL,
  255. dir: bidi.RightToLeft,
  256. }, {
  257. in: strAL + strL + strR,
  258. dir: bidi.RightToLeft,
  259. n: len(strAL),
  260. err: ErrInvalid,
  261. }, {
  262. in: strAL + strB + strR,
  263. dir: bidi.RightToLeft,
  264. n: len(strAL),
  265. err: ErrInvalid,
  266. }, {
  267. in: strAL + strS + strAL,
  268. dir: bidi.RightToLeft,
  269. n: len(strAL),
  270. err: ErrInvalid,
  271. }, {
  272. in: strAL + strWS + strAL,
  273. dir: bidi.RightToLeft,
  274. n: len(strAL),
  275. err: ErrInvalid,
  276. }},
  277. // Rule 2.3: In an RTL label, the end of the label must be a character with
  278. // Bidi property R, AL, EN, or AN, followed by zero or more characters with
  279. // Bidi property NSM.
  280. 3: []ruleTest{{
  281. in: strR + strNSM,
  282. dir: bidi.RightToLeft,
  283. }, {
  284. in: strR + strR,
  285. dir: bidi.RightToLeft,
  286. }, {
  287. in: strR + strAL + strNSM,
  288. dir: bidi.RightToLeft,
  289. }, {
  290. in: strR + strEN + strNSM + strNSM,
  291. dir: bidi.RightToLeft,
  292. }, {
  293. in: strR + strAN,
  294. dir: bidi.RightToLeft,
  295. }, {
  296. in: strR + strES + strNSM,
  297. dir: bidi.RightToLeft,
  298. n: len(strR + strES + strNSM),
  299. err: ErrInvalid,
  300. }, {
  301. in: strR + strCS + strNSM + strNSM,
  302. dir: bidi.RightToLeft,
  303. n: len(strR + strCS + strNSM + strNSM),
  304. err: ErrInvalid,
  305. }, {
  306. in: strR + strET,
  307. dir: bidi.RightToLeft,
  308. n: len(strR + strET),
  309. err: ErrInvalid,
  310. }, {
  311. in: strR + strON + strNSM,
  312. dir: bidi.RightToLeft,
  313. n: len(strR + strON + strNSM),
  314. err: ErrInvalid,
  315. }, {
  316. in: strR + strBN + strNSM + strNSM,
  317. dir: bidi.RightToLeft,
  318. n: len(strR + strBN + strNSM + strNSM),
  319. err: ErrInvalid,
  320. }, {
  321. in: strR + strL + strNSM,
  322. dir: bidi.RightToLeft,
  323. n: len(strR),
  324. err: ErrInvalid,
  325. }, {
  326. in: strR + strB + strNSM + strNSM,
  327. dir: bidi.RightToLeft,
  328. n: len(strR),
  329. err: ErrInvalid,
  330. }, {
  331. in: strR + strS,
  332. dir: bidi.RightToLeft,
  333. n: len(strR),
  334. err: ErrInvalid,
  335. }, {
  336. in: strR + strWS,
  337. dir: bidi.RightToLeft,
  338. n: len(strR),
  339. err: ErrInvalid,
  340. }, {
  341. in: strAL + strNSM,
  342. dir: bidi.RightToLeft,
  343. }, {
  344. in: strAL + strR,
  345. dir: bidi.RightToLeft,
  346. }, {
  347. in: strAL + strAL + strNSM,
  348. dir: bidi.RightToLeft,
  349. }, {
  350. in: strAL + strEN + strNSM + strNSM,
  351. dir: bidi.RightToLeft,
  352. }, {
  353. in: strAL + strAN,
  354. dir: bidi.RightToLeft,
  355. }, {
  356. in: strAL + strES + strNSM,
  357. dir: bidi.RightToLeft,
  358. n: len(strAL + strES + strNSM),
  359. err: ErrInvalid,
  360. }, {
  361. in: strAL + strCS + strNSM + strNSM,
  362. dir: bidi.RightToLeft,
  363. n: len(strAL + strCS + strNSM + strNSM),
  364. err: ErrInvalid,
  365. }, {
  366. in: strAL + strET,
  367. dir: bidi.RightToLeft,
  368. n: len(strAL + strET),
  369. err: ErrInvalid,
  370. }, {
  371. in: strAL + strON + strNSM,
  372. dir: bidi.RightToLeft,
  373. n: len(strAL + strON + strNSM),
  374. err: ErrInvalid,
  375. }, {
  376. in: strAL + strBN + strNSM + strNSM,
  377. dir: bidi.RightToLeft,
  378. n: len(strAL + strBN + strNSM + strNSM),
  379. err: ErrInvalid,
  380. }, {
  381. in: strAL + strL + strNSM,
  382. dir: bidi.RightToLeft,
  383. n: len(strAL),
  384. err: ErrInvalid,
  385. }, {
  386. in: strAL + strB + strNSM + strNSM,
  387. dir: bidi.RightToLeft,
  388. n: len(strAL),
  389. err: ErrInvalid,
  390. }, {
  391. in: strAL + strS,
  392. dir: bidi.RightToLeft,
  393. n: len(strAL),
  394. err: ErrInvalid,
  395. }, {
  396. in: strAL + strWS,
  397. dir: bidi.RightToLeft,
  398. n: len(strAL),
  399. err: ErrInvalid,
  400. }},
  401. // Rule 2.4: In an RTL label, if an EN is present, no AN may be present,
  402. // and vice versa.
  403. 4: []ruleTest{{
  404. in: strR + strEN + strAN,
  405. dir: bidi.RightToLeft,
  406. n: len(strR + strEN),
  407. err: ErrInvalid,
  408. }, {
  409. in: strR + strAN + strEN + strNSM,
  410. dir: bidi.RightToLeft,
  411. n: len(strR + strAN),
  412. err: ErrInvalid,
  413. }, {
  414. in: strAL + strEN + strAN,
  415. dir: bidi.RightToLeft,
  416. n: len(strAL + strEN),
  417. err: ErrInvalid,
  418. }, {
  419. in: strAL + strAN + strEN + strNSM,
  420. dir: bidi.RightToLeft,
  421. n: len(strAL + strAN),
  422. err: ErrInvalid,
  423. }},
  424. // Rule 2.5: In an LTR label, only characters with the Bidi properties L,
  425. // EN, ES, CS, ET, ON, BN, or NSM are allowed.
  426. 5: []ruleTest{{
  427. in: strL + strL + strL,
  428. dir: bidi.LeftToRight,
  429. }, {
  430. in: strL + strEN + strL,
  431. dir: bidi.LeftToRight,
  432. }, {
  433. in: strL + strES + strL,
  434. dir: bidi.LeftToRight,
  435. }, {
  436. in: strL + strCS + strL,
  437. dir: bidi.LeftToRight,
  438. }, {
  439. in: strL + strET + strL,
  440. dir: bidi.LeftToRight,
  441. }, {
  442. in: strL + strON + strL,
  443. dir: bidi.LeftToRight,
  444. }, {
  445. in: strL + strBN + strL,
  446. dir: bidi.LeftToRight,
  447. }, {
  448. in: strL + strNSM + strL,
  449. dir: bidi.LeftToRight,
  450. }, {
  451. in: strL + strR + strL,
  452. dir: bidi.RightToLeft,
  453. n: len(strL),
  454. err: ErrInvalid,
  455. }, {
  456. in: strL + strAL + strL,
  457. dir: bidi.RightToLeft,
  458. n: len(strL),
  459. err: ErrInvalid,
  460. }, {
  461. in: strL + strAN + strL,
  462. dir: bidi.RightToLeft,
  463. n: len(strL),
  464. err: ErrInvalid,
  465. }, {
  466. in: strL + strB + strL,
  467. dir: bidi.LeftToRight,
  468. n: len(strL + strAN + strL),
  469. err: nil,
  470. }, {
  471. in: strL + strB + strL + strR,
  472. dir: bidi.RightToLeft,
  473. n: len(strL + strB + strL),
  474. err: ErrInvalid,
  475. }, {
  476. in: strL + strS + strL,
  477. dir: bidi.LeftToRight,
  478. n: len(strL + strS + strL),
  479. err: nil,
  480. }, {
  481. in: strL + strS + strL + strR,
  482. dir: bidi.RightToLeft,
  483. n: len(strL + strS + strL),
  484. err: ErrInvalid,
  485. }, {
  486. in: strL + strWS + strL,
  487. dir: bidi.LeftToRight,
  488. n: len(strL + strWS + strL),
  489. err: nil,
  490. }, {
  491. in: strL + strWS + strL + strR,
  492. dir: bidi.RightToLeft,
  493. n: len(strL + strWS + strL),
  494. err: ErrInvalid,
  495. }},
  496. // Rule 2.6: In an LTR label, the end of the label must be a character with
  497. // Bidi property L or EN, followed by zero or more characters with Bidi
  498. // property NSM.
  499. 6: []ruleTest{{
  500. in: strL,
  501. dir: bidi.LeftToRight,
  502. }, {
  503. in: strL + strNSM,
  504. dir: bidi.LeftToRight,
  505. }, {
  506. in: strL + strNSM + strNSM,
  507. dir: bidi.LeftToRight,
  508. }, {
  509. in: strL + strEN,
  510. dir: bidi.LeftToRight,
  511. }, {
  512. in: strL + strEN + strNSM,
  513. dir: bidi.LeftToRight,
  514. }, {
  515. in: strL + strEN + strNSM + strNSM,
  516. dir: bidi.LeftToRight,
  517. }, {
  518. in: strL + strES,
  519. dir: bidi.LeftToRight,
  520. n: len(strL + strES),
  521. err: nil,
  522. }, {
  523. in: strL + strES + strR,
  524. dir: bidi.RightToLeft,
  525. n: len(strL + strES),
  526. err: ErrInvalid,
  527. }, {
  528. in: strL + strCS,
  529. dir: bidi.LeftToRight,
  530. n: len(strL + strCS),
  531. err: nil,
  532. }, {
  533. in: strL + strCS + strR,
  534. dir: bidi.RightToLeft,
  535. n: len(strL + strCS),
  536. err: ErrInvalid,
  537. }, {
  538. in: strL + strET,
  539. dir: bidi.LeftToRight,
  540. n: len(strL + strET),
  541. err: nil,
  542. }, {
  543. in: strL + strET + strR,
  544. dir: bidi.RightToLeft,
  545. n: len(strL + strET),
  546. err: ErrInvalid,
  547. }, {
  548. in: strL + strON,
  549. dir: bidi.LeftToRight,
  550. n: len(strL + strON),
  551. err: nil,
  552. }, {
  553. in: strL + strON + strR,
  554. dir: bidi.RightToLeft,
  555. n: len(strL + strON),
  556. err: ErrInvalid,
  557. }, {
  558. in: strL + strBN,
  559. dir: bidi.LeftToRight,
  560. n: len(strL + strBN),
  561. err: nil,
  562. }, {
  563. in: strL + strBN + strR,
  564. dir: bidi.RightToLeft,
  565. n: len(strL + strBN),
  566. err: ErrInvalid,
  567. }, {
  568. in: strL + strR,
  569. dir: bidi.RightToLeft,
  570. n: len(strL),
  571. err: ErrInvalid,
  572. }, {
  573. in: strL + strAL,
  574. dir: bidi.RightToLeft,
  575. n: len(strL),
  576. err: ErrInvalid,
  577. }, {
  578. in: strL + strAN,
  579. dir: bidi.RightToLeft,
  580. n: len(strL),
  581. err: ErrInvalid,
  582. }, {
  583. in: strL + strB,
  584. dir: bidi.LeftToRight,
  585. n: len(strL + strB),
  586. err: nil,
  587. }, {
  588. in: strL + strB + strR,
  589. dir: bidi.RightToLeft,
  590. n: len(strL + strB),
  591. err: ErrInvalid,
  592. }, {
  593. in: strL + strB,
  594. dir: bidi.LeftToRight,
  595. n: len(strL + strB),
  596. err: nil,
  597. }, {
  598. in: strL + strB + strR,
  599. dir: bidi.RightToLeft,
  600. n: len(strL + strB),
  601. err: ErrInvalid,
  602. }, {
  603. in: strL + strB,
  604. dir: bidi.LeftToRight,
  605. n: len(strL + strB),
  606. err: nil,
  607. }, {
  608. in: strL + strB + strR,
  609. dir: bidi.RightToLeft,
  610. n: len(strL + strB),
  611. err: ErrInvalid,
  612. }},
  613. // Incremental processing.
  614. 9: []ruleTest{{
  615. in: "e\u0301", // é
  616. dir: bidi.LeftToRight,
  617. pSrc: 2,
  618. nSrc: 1,
  619. err0: transform.ErrShortSrc,
  620. }, {
  621. in: "e\u1000f", // é
  622. dir: bidi.LeftToRight,
  623. pSrc: 3,
  624. nSrc: 1,
  625. err0: transform.ErrShortSrc,
  626. }, {
  627. // Remain invalid once invalid.
  628. in: strR + "ab",
  629. dir: bidi.RightToLeft,
  630. n: len(strR),
  631. err: ErrInvalid,
  632. pSrc: len(strR) + 1,
  633. nSrc: len(strR),
  634. err0: ErrInvalid,
  635. }, {
  636. // Short destination
  637. in: "abcdefghij",
  638. dir: bidi.LeftToRight,
  639. pSrc: 10,
  640. szDst: 5,
  641. nSrc: 5,
  642. err0: transform.ErrShortDst,
  643. }, {
  644. // Short destination splitting input rune
  645. in: "e\u0301",
  646. dir: bidi.LeftToRight,
  647. pSrc: 3,
  648. szDst: 2,
  649. nSrc: 1,
  650. err0: transform.ErrShortDst,
  651. }},
  652. }