bidirule9.0.0_test.go 13 KB

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