letter_test.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. // Copyright 2009 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. package unicode_test
  5. import (
  6. "flag"
  7. "fmt"
  8. "runtime"
  9. "sort"
  10. "strings"
  11. "testing"
  12. . "unicode"
  13. )
  14. var upperTest = []rune{
  15. 0x41,
  16. 0xc0,
  17. 0xd8,
  18. 0x100,
  19. 0x139,
  20. 0x14a,
  21. 0x178,
  22. 0x181,
  23. 0x376,
  24. 0x3cf,
  25. 0x13bd,
  26. 0x1f2a,
  27. 0x2102,
  28. 0x2c00,
  29. 0x2c10,
  30. 0x2c20,
  31. 0xa650,
  32. 0xa722,
  33. 0xff3a,
  34. 0x10400,
  35. 0x1d400,
  36. 0x1d7ca,
  37. }
  38. var notupperTest = []rune{
  39. 0x40,
  40. 0x5b,
  41. 0x61,
  42. 0x185,
  43. 0x1b0,
  44. 0x377,
  45. 0x387,
  46. 0x2150,
  47. 0xab7d,
  48. 0xffff,
  49. 0x10000,
  50. }
  51. var letterTest = []rune{
  52. 0x41,
  53. 0x61,
  54. 0xaa,
  55. 0xba,
  56. 0xc8,
  57. 0xdb,
  58. 0xf9,
  59. 0x2ec,
  60. 0x535,
  61. 0x620,
  62. 0x6e6,
  63. 0x93d,
  64. 0xa15,
  65. 0xb99,
  66. 0xdc0,
  67. 0xedd,
  68. 0x1000,
  69. 0x1200,
  70. 0x1312,
  71. 0x1401,
  72. 0x2c00,
  73. 0xa800,
  74. 0xf900,
  75. 0xfa30,
  76. 0xffda,
  77. 0xffdc,
  78. 0x10000,
  79. 0x10300,
  80. 0x10400,
  81. 0x20000,
  82. 0x2f800,
  83. 0x2fa1d,
  84. }
  85. var notletterTest = []rune{
  86. 0x20,
  87. 0x35,
  88. 0x375,
  89. 0x619,
  90. 0x700,
  91. 0x1885,
  92. 0xfffe,
  93. 0x1ffff,
  94. 0x10ffff,
  95. }
  96. // Contains all the special cased Latin-1 chars.
  97. var spaceTest = []rune{
  98. 0x09,
  99. 0x0a,
  100. 0x0b,
  101. 0x0c,
  102. 0x0d,
  103. 0x20,
  104. 0x85,
  105. 0xA0,
  106. 0x2000,
  107. 0x3000,
  108. }
  109. type caseT struct {
  110. cas int
  111. in, out rune
  112. }
  113. var caseTest = []caseT{
  114. // errors
  115. {-1, '\n', 0xFFFD},
  116. {UpperCase, -1, -1},
  117. {UpperCase, 1 << 30, 1 << 30},
  118. // ASCII (special-cased so test carefully)
  119. {UpperCase, '\n', '\n'},
  120. {UpperCase, 'a', 'A'},
  121. {UpperCase, 'A', 'A'},
  122. {UpperCase, '7', '7'},
  123. {LowerCase, '\n', '\n'},
  124. {LowerCase, 'a', 'a'},
  125. {LowerCase, 'A', 'a'},
  126. {LowerCase, '7', '7'},
  127. {TitleCase, '\n', '\n'},
  128. {TitleCase, 'a', 'A'},
  129. {TitleCase, 'A', 'A'},
  130. {TitleCase, '7', '7'},
  131. // Latin-1: easy to read the tests!
  132. {UpperCase, 0x80, 0x80},
  133. {UpperCase, 'Å', 'Å'},
  134. {UpperCase, 'å', 'Å'},
  135. {LowerCase, 0x80, 0x80},
  136. {LowerCase, 'Å', 'å'},
  137. {LowerCase, 'å', 'å'},
  138. {TitleCase, 0x80, 0x80},
  139. {TitleCase, 'Å', 'Å'},
  140. {TitleCase, 'å', 'Å'},
  141. // 0131;LATIN SMALL LETTER DOTLESS I;Ll;0;L;;;;;N;;;0049;;0049
  142. {UpperCase, 0x0131, 'I'},
  143. {LowerCase, 0x0131, 0x0131},
  144. {TitleCase, 0x0131, 'I'},
  145. // 0133;LATIN SMALL LIGATURE IJ;Ll;0;L;<compat> 0069 006A;;;;N;LATIN SMALL LETTER I J;;0132;;0132
  146. {UpperCase, 0x0133, 0x0132},
  147. {LowerCase, 0x0133, 0x0133},
  148. {TitleCase, 0x0133, 0x0132},
  149. // 212A;KELVIN SIGN;Lu;0;L;004B;;;;N;DEGREES KELVIN;;;006B;
  150. {UpperCase, 0x212A, 0x212A},
  151. {LowerCase, 0x212A, 'k'},
  152. {TitleCase, 0x212A, 0x212A},
  153. // From an UpperLower sequence
  154. // A640;CYRILLIC CAPITAL LETTER ZEMLYA;Lu;0;L;;;;;N;;;;A641;
  155. {UpperCase, 0xA640, 0xA640},
  156. {LowerCase, 0xA640, 0xA641},
  157. {TitleCase, 0xA640, 0xA640},
  158. // A641;CYRILLIC SMALL LETTER ZEMLYA;Ll;0;L;;;;;N;;;A640;;A640
  159. {UpperCase, 0xA641, 0xA640},
  160. {LowerCase, 0xA641, 0xA641},
  161. {TitleCase, 0xA641, 0xA640},
  162. // A64E;CYRILLIC CAPITAL LETTER NEUTRAL YER;Lu;0;L;;;;;N;;;;A64F;
  163. {UpperCase, 0xA64E, 0xA64E},
  164. {LowerCase, 0xA64E, 0xA64F},
  165. {TitleCase, 0xA64E, 0xA64E},
  166. // A65F;CYRILLIC SMALL LETTER YN;Ll;0;L;;;;;N;;;A65E;;A65E
  167. {UpperCase, 0xA65F, 0xA65E},
  168. {LowerCase, 0xA65F, 0xA65F},
  169. {TitleCase, 0xA65F, 0xA65E},
  170. // From another UpperLower sequence
  171. // 0139;LATIN CAPITAL LETTER L WITH ACUTE;Lu;0;L;004C 0301;;;;N;LATIN CAPITAL LETTER L ACUTE;;;013A;
  172. {UpperCase, 0x0139, 0x0139},
  173. {LowerCase, 0x0139, 0x013A},
  174. {TitleCase, 0x0139, 0x0139},
  175. // 013F;LATIN CAPITAL LETTER L WITH MIDDLE DOT;Lu;0;L;<compat> 004C 00B7;;;;N;;;;0140;
  176. {UpperCase, 0x013f, 0x013f},
  177. {LowerCase, 0x013f, 0x0140},
  178. {TitleCase, 0x013f, 0x013f},
  179. // 0148;LATIN SMALL LETTER N WITH CARON;Ll;0;L;006E 030C;;;;N;LATIN SMALL LETTER N HACEK;;0147;;0147
  180. {UpperCase, 0x0148, 0x0147},
  181. {LowerCase, 0x0148, 0x0148},
  182. {TitleCase, 0x0148, 0x0147},
  183. // Lowercase lower than uppercase.
  184. // AB78;CHEROKEE SMALL LETTER GE;Ll;0;L;;;;;N;;;13A8;;13A8
  185. {UpperCase, 0xab78, 0x13a8},
  186. {LowerCase, 0xab78, 0xab78},
  187. {TitleCase, 0xab78, 0x13a8},
  188. {UpperCase, 0x13a8, 0x13a8},
  189. {LowerCase, 0x13a8, 0xab78},
  190. {TitleCase, 0x13a8, 0x13a8},
  191. // Last block in the 5.1.0 table
  192. // 10400;DESERET CAPITAL LETTER LONG I;Lu;0;L;;;;;N;;;;10428;
  193. {UpperCase, 0x10400, 0x10400},
  194. {LowerCase, 0x10400, 0x10428},
  195. {TitleCase, 0x10400, 0x10400},
  196. // 10427;DESERET CAPITAL LETTER EW;Lu;0;L;;;;;N;;;;1044F;
  197. {UpperCase, 0x10427, 0x10427},
  198. {LowerCase, 0x10427, 0x1044F},
  199. {TitleCase, 0x10427, 0x10427},
  200. // 10428;DESERET SMALL LETTER LONG I;Ll;0;L;;;;;N;;;10400;;10400
  201. {UpperCase, 0x10428, 0x10400},
  202. {LowerCase, 0x10428, 0x10428},
  203. {TitleCase, 0x10428, 0x10400},
  204. // 1044F;DESERET SMALL LETTER EW;Ll;0;L;;;;;N;;;10427;;10427
  205. {UpperCase, 0x1044F, 0x10427},
  206. {LowerCase, 0x1044F, 0x1044F},
  207. {TitleCase, 0x1044F, 0x10427},
  208. // First one not in the 5.1.0 table
  209. // 10450;SHAVIAN LETTER PEEP;Lo;0;L;;;;;N;;;;;
  210. {UpperCase, 0x10450, 0x10450},
  211. {LowerCase, 0x10450, 0x10450},
  212. {TitleCase, 0x10450, 0x10450},
  213. // Non-letters with case.
  214. {LowerCase, 0x2161, 0x2171},
  215. {UpperCase, 0x0345, 0x0399},
  216. }
  217. func TestIsLetter(t *testing.T) {
  218. for _, r := range upperTest {
  219. if !IsLetter(r) {
  220. t.Errorf("IsLetter(U+%04X) = false, want true", r)
  221. }
  222. }
  223. for _, r := range letterTest {
  224. if !IsLetter(r) {
  225. t.Errorf("IsLetter(U+%04X) = false, want true", r)
  226. }
  227. }
  228. for _, r := range notletterTest {
  229. if IsLetter(r) {
  230. t.Errorf("IsLetter(U+%04X) = true, want false", r)
  231. }
  232. }
  233. }
  234. func TestIsUpper(t *testing.T) {
  235. for _, r := range upperTest {
  236. if !IsUpper(r) {
  237. t.Errorf("IsUpper(U+%04X) = false, want true", r)
  238. }
  239. }
  240. for _, r := range notupperTest {
  241. if IsUpper(r) {
  242. t.Errorf("IsUpper(U+%04X) = true, want false", r)
  243. }
  244. }
  245. for _, r := range notletterTest {
  246. if IsUpper(r) {
  247. t.Errorf("IsUpper(U+%04X) = true, want false", r)
  248. }
  249. }
  250. }
  251. func caseString(c int) string {
  252. switch c {
  253. case UpperCase:
  254. return "UpperCase"
  255. case LowerCase:
  256. return "LowerCase"
  257. case TitleCase:
  258. return "TitleCase"
  259. }
  260. return "ErrorCase"
  261. }
  262. func TestTo(t *testing.T) {
  263. for _, c := range caseTest {
  264. r := To(c.cas, c.in)
  265. if c.out != r {
  266. t.Errorf("To(U+%04X, %s) = U+%04X want U+%04X", c.in, caseString(c.cas), r, c.out)
  267. }
  268. }
  269. }
  270. func TestToUpperCase(t *testing.T) {
  271. for _, c := range caseTest {
  272. if c.cas != UpperCase {
  273. continue
  274. }
  275. r := ToUpper(c.in)
  276. if c.out != r {
  277. t.Errorf("ToUpper(U+%04X) = U+%04X want U+%04X", c.in, r, c.out)
  278. }
  279. }
  280. }
  281. func TestToLowerCase(t *testing.T) {
  282. for _, c := range caseTest {
  283. if c.cas != LowerCase {
  284. continue
  285. }
  286. r := ToLower(c.in)
  287. if c.out != r {
  288. t.Errorf("ToLower(U+%04X) = U+%04X want U+%04X", c.in, r, c.out)
  289. }
  290. }
  291. }
  292. func TestToTitleCase(t *testing.T) {
  293. for _, c := range caseTest {
  294. if c.cas != TitleCase {
  295. continue
  296. }
  297. r := ToTitle(c.in)
  298. if c.out != r {
  299. t.Errorf("ToTitle(U+%04X) = U+%04X want U+%04X", c.in, r, c.out)
  300. }
  301. }
  302. }
  303. func TestIsSpace(t *testing.T) {
  304. for _, c := range spaceTest {
  305. if !IsSpace(c) {
  306. t.Errorf("IsSpace(U+%04X) = false; want true", c)
  307. }
  308. }
  309. for _, c := range letterTest {
  310. if IsSpace(c) {
  311. t.Errorf("IsSpace(U+%04X) = true; want false", c)
  312. }
  313. }
  314. }
  315. // Check that the optimizations for IsLetter etc. agree with the tables.
  316. // We only need to check the Latin-1 range.
  317. func TestLetterOptimizations(t *testing.T) {
  318. for i := rune(0); i <= MaxLatin1; i++ {
  319. if Is(Letter, i) != IsLetter(i) {
  320. t.Errorf("IsLetter(U+%04X) disagrees with Is(Letter)", i)
  321. }
  322. if Is(Upper, i) != IsUpper(i) {
  323. t.Errorf("IsUpper(U+%04X) disagrees with Is(Upper)", i)
  324. }
  325. if Is(Lower, i) != IsLower(i) {
  326. t.Errorf("IsLower(U+%04X) disagrees with Is(Lower)", i)
  327. }
  328. if Is(Title, i) != IsTitle(i) {
  329. t.Errorf("IsTitle(U+%04X) disagrees with Is(Title)", i)
  330. }
  331. if Is(White_Space, i) != IsSpace(i) {
  332. t.Errorf("IsSpace(U+%04X) disagrees with Is(White_Space)", i)
  333. }
  334. if To(UpperCase, i) != ToUpper(i) {
  335. t.Errorf("ToUpper(U+%04X) disagrees with To(Upper)", i)
  336. }
  337. if To(LowerCase, i) != ToLower(i) {
  338. t.Errorf("ToLower(U+%04X) disagrees with To(Lower)", i)
  339. }
  340. if To(TitleCase, i) != ToTitle(i) {
  341. t.Errorf("ToTitle(U+%04X) disagrees with To(Title)", i)
  342. }
  343. }
  344. }
  345. func TestTurkishCase(t *testing.T) {
  346. lower := []rune("abcçdefgğhıijklmnoöprsştuüvyz")
  347. upper := []rune("ABCÇDEFGĞHIİJKLMNOÖPRSŞTUÜVYZ")
  348. for i, l := range lower {
  349. u := upper[i]
  350. if TurkishCase.ToLower(l) != l {
  351. t.Errorf("lower(U+%04X) is U+%04X not U+%04X", l, TurkishCase.ToLower(l), l)
  352. }
  353. if TurkishCase.ToUpper(u) != u {
  354. t.Errorf("upper(U+%04X) is U+%04X not U+%04X", u, TurkishCase.ToUpper(u), u)
  355. }
  356. if TurkishCase.ToUpper(l) != u {
  357. t.Errorf("upper(U+%04X) is U+%04X not U+%04X", l, TurkishCase.ToUpper(l), u)
  358. }
  359. if TurkishCase.ToLower(u) != l {
  360. t.Errorf("lower(U+%04X) is U+%04X not U+%04X", u, TurkishCase.ToLower(l), l)
  361. }
  362. if TurkishCase.ToTitle(u) != u {
  363. t.Errorf("title(U+%04X) is U+%04X not U+%04X", u, TurkishCase.ToTitle(u), u)
  364. }
  365. if TurkishCase.ToTitle(l) != u {
  366. t.Errorf("title(U+%04X) is U+%04X not U+%04X", l, TurkishCase.ToTitle(l), u)
  367. }
  368. }
  369. }
  370. var simpleFoldTests = []string{
  371. // SimpleFold(x) returns the next equivalent rune > x or wraps
  372. // around to smaller values.
  373. // Easy cases.
  374. "Aa",
  375. "δΔ",
  376. // ASCII special cases.
  377. "KkK",
  378. "Ssſ",
  379. // Non-ASCII special cases.
  380. "ρϱΡ",
  381. "ͅΙιι",
  382. // Extra special cases: has lower/upper but no case fold.
  383. "İ",
  384. "ı",
  385. // Upper comes before lower (Cherokee).
  386. "\u13b0\uab80",
  387. }
  388. func TestSimpleFold(t *testing.T) {
  389. for _, tt := range simpleFoldTests {
  390. cycle := []rune(tt)
  391. r := cycle[len(cycle)-1]
  392. for _, out := range cycle {
  393. if r := SimpleFold(r); r != out {
  394. t.Errorf("SimpleFold(%#U) = %#U, want %#U", r, r, out)
  395. }
  396. r = out
  397. }
  398. }
  399. if r := SimpleFold(-42); r != -42 {
  400. t.Errorf("SimpleFold(-42) = %v, want -42", r)
  401. }
  402. }
  403. // Running 'go test -calibrate' runs the calibration to find a plausible
  404. // cutoff point for linear search of a range list vs. binary search.
  405. // We create a fake table and then time how long it takes to do a
  406. // sequence of searches within that table, for all possible inputs
  407. // relative to the ranges (something before all, in each, between each, after all).
  408. // This assumes that all possible runes are equally likely.
  409. // In practice most runes are ASCII so this is a conservative estimate
  410. // of an effective cutoff value. In practice we could probably set it higher
  411. // than what this function recommends.
  412. var calibrate = flag.Bool("calibrate", false, "compute crossover for linear vs. binary search")
  413. func TestCalibrate(t *testing.T) {
  414. if !*calibrate {
  415. return
  416. }
  417. if runtime.GOARCH == "amd64" {
  418. fmt.Printf("warning: running calibration on %s\n", runtime.GOARCH)
  419. }
  420. // Find the point where binary search wins by more than 10%.
  421. // The 10% bias gives linear search an edge when they're close,
  422. // because on predominantly ASCII inputs linear search is even
  423. // better than our benchmarks measure.
  424. n := sort.Search(64, func(n int) bool {
  425. tab := fakeTable(n)
  426. blinear := func(b *testing.B) {
  427. tab := tab
  428. max := n*5 + 20
  429. for i := 0; i < b.N; i++ {
  430. for j := 0; j <= max; j++ {
  431. linear(tab, uint16(j))
  432. }
  433. }
  434. }
  435. bbinary := func(b *testing.B) {
  436. tab := tab
  437. max := n*5 + 20
  438. for i := 0; i < b.N; i++ {
  439. for j := 0; j <= max; j++ {
  440. binary(tab, uint16(j))
  441. }
  442. }
  443. }
  444. bmlinear := testing.Benchmark(blinear)
  445. bmbinary := testing.Benchmark(bbinary)
  446. fmt.Printf("n=%d: linear=%d binary=%d\n", n, bmlinear.NsPerOp(), bmbinary.NsPerOp())
  447. return bmlinear.NsPerOp()*100 > bmbinary.NsPerOp()*110
  448. })
  449. fmt.Printf("calibration: linear cutoff = %d\n", n)
  450. }
  451. func fakeTable(n int) []Range16 {
  452. var r16 []Range16
  453. for i := 0; i < n; i++ {
  454. r16 = append(r16, Range16{uint16(i*5 + 10), uint16(i*5 + 12), 1})
  455. }
  456. return r16
  457. }
  458. func linear(ranges []Range16, r uint16) bool {
  459. for i := range ranges {
  460. range_ := &ranges[i]
  461. if r < range_.Lo {
  462. return false
  463. }
  464. if r <= range_.Hi {
  465. return (r-range_.Lo)%range_.Stride == 0
  466. }
  467. }
  468. return false
  469. }
  470. func binary(ranges []Range16, r uint16) bool {
  471. // binary search over ranges
  472. lo := 0
  473. hi := len(ranges)
  474. for lo < hi {
  475. m := lo + (hi-lo)/2
  476. range_ := &ranges[m]
  477. if range_.Lo <= r && r <= range_.Hi {
  478. return (r-range_.Lo)%range_.Stride == 0
  479. }
  480. if r < range_.Lo {
  481. hi = m
  482. } else {
  483. lo = m + 1
  484. }
  485. }
  486. return false
  487. }
  488. func TestLatinOffset(t *testing.T) {
  489. var maps = []map[string]*RangeTable{
  490. Categories,
  491. FoldCategory,
  492. FoldScript,
  493. Properties,
  494. Scripts,
  495. }
  496. for _, m := range maps {
  497. for name, tab := range m {
  498. i := 0
  499. for i < len(tab.R16) && tab.R16[i].Hi <= MaxLatin1 {
  500. i++
  501. }
  502. if tab.LatinOffset != i {
  503. t.Errorf("%s: LatinOffset=%d, want %d", name, tab.LatinOffset, i)
  504. }
  505. }
  506. }
  507. }
  508. func TestSpecialCaseNoMapping(t *testing.T) {
  509. // Issue 25636
  510. // no change for rune 'A', zero delta, under upper/lower/title case change.
  511. var noChangeForCapitalA = CaseRange{'A', 'A', [MaxCase]rune{0, 0, 0}}
  512. got := strings.ToLowerSpecial(SpecialCase([]CaseRange{noChangeForCapitalA}), "ABC")
  513. want := "Abc"
  514. if got != want {
  515. t.Errorf("got %q; want %q", got, want)
  516. }
  517. }
  518. func TestNegativeRune(t *testing.T) {
  519. // Issue 43254
  520. // These tests cover negative rune handling by testing values which,
  521. // when cast to uint8 or uint16, look like a particular valid rune.
  522. // This package has Latin-1-specific optimizations, so we test all of
  523. // Latin-1 and representative non-Latin-1 values in the character
  524. // categories covered by IsGraphic, etc.
  525. nonLatin1 := []uint32{
  526. // Lu: LATIN CAPITAL LETTER A WITH MACRON
  527. 0x0100,
  528. // Ll: LATIN SMALL LETTER A WITH MACRON
  529. 0x0101,
  530. // Lt: LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
  531. 0x01C5,
  532. // M: COMBINING GRAVE ACCENT
  533. 0x0300,
  534. // Nd: ARABIC-INDIC DIGIT ZERO
  535. 0x0660,
  536. // P: GREEK QUESTION MARK
  537. 0x037E,
  538. // S: MODIFIER LETTER LEFT ARROWHEAD
  539. 0x02C2,
  540. // Z: OGHAM SPACE MARK
  541. 0x1680,
  542. }
  543. for i := 0; i < MaxLatin1+len(nonLatin1); i++ {
  544. base := uint32(i)
  545. if i >= MaxLatin1 {
  546. base = nonLatin1[i-MaxLatin1]
  547. }
  548. // Note r is negative, but uint8(r) == uint8(base) and
  549. // uint16(r) == uint16(base).
  550. r := rune(base - 1<<31)
  551. if Is(Letter, r) {
  552. t.Errorf("Is(Letter, 0x%x - 1<<31) = true, want false", base)
  553. }
  554. if IsControl(r) {
  555. t.Errorf("IsControl(0x%x - 1<<31) = true, want false", base)
  556. }
  557. if IsDigit(r) {
  558. t.Errorf("IsDigit(0x%x - 1<<31) = true, want false", base)
  559. }
  560. if IsGraphic(r) {
  561. t.Errorf("IsGraphic(0x%x - 1<<31) = true, want false", base)
  562. }
  563. if IsLetter(r) {
  564. t.Errorf("IsLetter(0x%x - 1<<31) = true, want false", base)
  565. }
  566. if IsLower(r) {
  567. t.Errorf("IsLower(0x%x - 1<<31) = true, want false", base)
  568. }
  569. if IsMark(r) {
  570. t.Errorf("IsMark(0x%x - 1<<31) = true, want false", base)
  571. }
  572. if IsNumber(r) {
  573. t.Errorf("IsNumber(0x%x - 1<<31) = true, want false", base)
  574. }
  575. if IsPrint(r) {
  576. t.Errorf("IsPrint(0x%x - 1<<31) = true, want false", base)
  577. }
  578. if IsPunct(r) {
  579. t.Errorf("IsPunct(0x%x - 1<<31) = true, want false", base)
  580. }
  581. if IsSpace(r) {
  582. t.Errorf("IsSpace(0x%x - 1<<31) = true, want false", base)
  583. }
  584. if IsSymbol(r) {
  585. t.Errorf("IsSymbol(0x%x - 1<<31) = true, want false", base)
  586. }
  587. if IsTitle(r) {
  588. t.Errorf("IsTitle(0x%x - 1<<31) = true, want false", base)
  589. }
  590. if IsUpper(r) {
  591. t.Errorf("IsUpper(0x%x - 1<<31) = true, want false", base)
  592. }
  593. }
  594. }