bidirule10.0.0_test.go 13 KB

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