i18n.test 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. ;;;; i18n.test --- Exercise the i18n API. -*- coding: utf-8; mode: scheme; -*-
  2. ;;;;
  3. ;;;; Copyright (C) 2006, 2007, 2009, 2010, 2011, 2012,
  4. ;;;; 2013, 2014, 2015, 2016, 2017 Free Software Foundation, Inc.
  5. ;;;; Ludovic Courtès
  6. ;;;;
  7. ;;;; This library is free software; you can redistribute it and/or
  8. ;;;; modify it under the terms of the GNU Lesser General Public
  9. ;;;; License as published by the Free Software Foundation; either
  10. ;;;; version 3 of the License, or (at your option) any later version.
  11. ;;;;
  12. ;;;; This library is distributed in the hope that it will be useful,
  13. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. ;;;; Lesser General Public License for more details.
  16. ;;;;
  17. ;;;; You should have received a copy of the GNU Lesser General Public
  18. ;;;; License along with this library; if not, write to the Free Software
  19. ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. (define-module (test-suite i18n)
  21. #:use-module (ice-9 i18n)
  22. #:use-module (ice-9 format)
  23. #:use-module (srfi srfi-1)
  24. #:use-module (test-suite lib))
  25. ;; Start from a pristine locale state.
  26. (setlocale LC_ALL "C")
  27. (define exception:locale-error
  28. (cons 'system-error "Failed to install locale"))
  29. (with-test-prefix "locale objects"
  30. (pass-if "make-locale (2 args)"
  31. (not (not (make-locale LC_ALL "C"))))
  32. (pass-if "make-locale (2 args, list)"
  33. (not (not (make-locale (list LC_COLLATE LC_NUMERIC) "C"))))
  34. (pass-if "make-locale (3 args)"
  35. (not (not (make-locale (list LC_COLLATE) "C"
  36. (make-locale (list LC_NUMERIC) "C")))))
  37. (pass-if-exception "make-locale with unknown locale" exception:locale-error
  38. (make-locale LC_ALL "does-not-exist"))
  39. (pass-if "locale?"
  40. (and (locale? (make-locale (list LC_ALL) "C"))
  41. (locale? (make-locale (list LC_TIME LC_NUMERIC) "C"
  42. (make-locale (list LC_CTYPE) "C")))))
  43. (pass-if "%global-locale"
  44. (and (locale? %global-locale))
  45. (locale? (make-locale (list LC_MONETARY) "C"
  46. %global-locale))))
  47. (with-test-prefix "text collation (English)"
  48. (pass-if "string-locale<?"
  49. (and (string-locale<? "hello" "world")
  50. (string-locale<? "hello" "world"
  51. (make-locale (list LC_COLLATE) "C"))))
  52. (pass-if "char-locale<?"
  53. (and (char-locale<? #\a #\b)
  54. (char-locale<? #\a #\b (make-locale (list LC_COLLATE) "C"))))
  55. (pass-if "string-locale-ci=?"
  56. (and (string-locale-ci=? "Hello" "HELLO")
  57. (string-locale-ci=? "Hello" "HELLO"
  58. (make-locale (list LC_COLLATE) "C"))))
  59. (pass-if "string-locale-ci<?"
  60. (and (string-locale-ci<? "hello" "WORLD")
  61. (string-locale-ci<? "hello" "WORLD"
  62. (make-locale (list LC_COLLATE) "C")))))
  63. (define mingw?
  64. (string-contains %host-type "-mingw32"))
  65. (define %french-locale-name
  66. (if mingw?
  67. "fra_FRA.850"
  68. "fr_FR.iso88591")) ;"iso88591" is the "normalized codeset"
  69. ;; What we really want for the following locales is that they be Unicode
  70. ;; capable, not necessarily UTF-8, which Windows does not provide.
  71. (define %french-utf8-locale-name
  72. (if mingw?
  73. "fra_FRA.1252"
  74. "fr_FR.utf8")) ;"utf8" is the "normalized codeset"
  75. (define %turkish-utf8-locale-name
  76. (if mingw?
  77. "tur_TRK.1254"
  78. "tr_TR.utf8"))
  79. (define %german-utf8-locale-name
  80. (if mingw?
  81. "deu_DEU.1252"
  82. "de_DE.utf8"))
  83. (define %greek-utf8-locale-name
  84. (if mingw?
  85. "grc_ELL.1253"
  86. "el_GR.utf8"))
  87. (define %american-english-locale-name
  88. "en_US.utf8")
  89. (define %french-locale
  90. (false-if-exception
  91. (make-locale (list LC_CTYPE LC_COLLATE LC_NUMERIC LC_TIME)
  92. %french-locale-name)))
  93. (define %french-utf8-locale
  94. (false-if-exception
  95. (make-locale (list LC_CTYPE LC_COLLATE LC_NUMERIC LC_TIME)
  96. %french-utf8-locale-name)))
  97. (define %german-utf8-locale
  98. (false-if-exception
  99. (make-locale LC_ALL
  100. %german-utf8-locale-name)))
  101. (define %greek-utf8-locale
  102. (false-if-exception
  103. (make-locale LC_ALL
  104. %greek-utf8-locale-name)))
  105. (define %turkish-utf8-locale
  106. (false-if-exception
  107. (make-locale LC_ALL
  108. %turkish-utf8-locale-name)))
  109. (define %american-english-locale
  110. (false-if-exception
  111. (make-locale LC_ALL
  112. %american-english-locale-name)))
  113. (define (under-locale-or-unresolved locale thunk)
  114. ;; On non-GNU systems, an exception may be raised only when the locale is
  115. ;; actually used rather than at `make-locale'-time. Thus, we must guard
  116. ;; against both.
  117. (if locale
  118. (if (string-contains %host-type "-gnu")
  119. (thunk)
  120. (catch 'system-error thunk
  121. (lambda (key . args)
  122. (throw 'unresolved))))
  123. (throw 'unresolved)))
  124. (define (under-french-locale-or-unresolved thunk)
  125. (under-locale-or-unresolved %french-locale thunk))
  126. (define (under-french-utf8-locale-or-unresolved thunk)
  127. (under-locale-or-unresolved %french-utf8-locale thunk))
  128. (define (under-turkish-utf8-locale-or-unresolved thunk)
  129. ;; FreeBSD 8.2 and 9.1, Solaris 2.10, Darwin 8.11.0, Cygwin, and MinGW have
  130. ;; a broken tr_TR locale where `i' is mapped to uppercase `I'
  131. ;; instead of `İ', so disable tests on that platform.
  132. (if (or (string-contains %host-type "freebsd8")
  133. (string-contains %host-type "freebsd9")
  134. (string-contains %host-type "solaris2.10")
  135. (string-contains %host-type "darwin8")
  136. (string-contains %host-type "mingw32")
  137. (string-contains %host-type "cygwin"))
  138. (throw 'unresolved)
  139. (under-locale-or-unresolved %turkish-utf8-locale thunk)))
  140. (define (under-german-utf8-locale-or-unresolved thunk)
  141. (under-locale-or-unresolved %german-utf8-locale thunk))
  142. (define (under-greek-utf8-locale-or-unresolved thunk)
  143. (under-locale-or-unresolved %greek-utf8-locale thunk))
  144. (define (under-american-english-locale-or-unresolved thunk)
  145. (under-locale-or-unresolved %american-english-locale thunk))
  146. (with-test-prefix "text collation (French)"
  147. (pass-if "string-locale<?"
  148. (under-french-locale-or-unresolved
  149. (lambda ()
  150. (string-locale<? "été" "hiver" %french-locale))))
  151. (pass-if "char-locale<?"
  152. (under-french-locale-or-unresolved
  153. (lambda ()
  154. (char-locale<? #\é #\h %french-locale))))
  155. (pass-if "string-locale-ci=?"
  156. (under-french-locale-or-unresolved
  157. (lambda ()
  158. (string-locale-ci=? "ÉTÉ" "été" %french-locale))))
  159. (pass-if "string-locale-ci=? (2 args, wide strings)"
  160. (under-french-utf8-locale-or-unresolved
  161. (lambda ()
  162. ;; Note: Character `œ' is not part of Latin-1, so these are wide
  163. ;; strings.
  164. (dynamic-wind
  165. (lambda ()
  166. (setlocale LC_ALL %french-utf8-locale-name))
  167. (lambda ()
  168. (string-locale-ci=? "œuf" "ŒUF"))
  169. (lambda ()
  170. (setlocale LC_ALL "C"))))))
  171. (pass-if "string-locale-ci=? (3 args, wide strings)"
  172. (under-french-utf8-locale-or-unresolved
  173. (lambda ()
  174. (string-locale-ci=? "œuf" "ŒUF" %french-utf8-locale))))
  175. (pass-if "string-locale-ci<>?"
  176. (under-french-locale-or-unresolved
  177. (lambda ()
  178. (and (string-locale-ci<? "été" "Hiver" %french-locale)
  179. (string-locale-ci>? "HiVeR" "été" %french-locale)))))
  180. (pass-if "string-locale-ci<>? (wide strings)"
  181. (under-french-utf8-locale-or-unresolved
  182. (lambda ()
  183. ;; One of the strings is UCS-4, the other is Latin-1.
  184. (and (string-locale-ci<? "Œdème" "œuf" %french-utf8-locale)
  185. (string-locale-ci>? "Œuf" "œdÈMe" %french-utf8-locale)))))
  186. (pass-if "string-locale-ci<>? (wide and narrow strings)"
  187. (under-french-utf8-locale-or-unresolved
  188. (lambda ()
  189. ;; One of the strings is UCS-4, the other is Latin-1.
  190. (and (string-locale-ci>? "Œdème" "odyssée" %french-utf8-locale)
  191. (string-locale-ci<? "Odyssée" "œdème" %french-utf8-locale)))))
  192. (pass-if "char-locale-ci<>?"
  193. (under-french-locale-or-unresolved
  194. (lambda ()
  195. (and (char-locale-ci<? #\é #\H %french-locale)
  196. (char-locale-ci>? #\h #\É %french-locale)))))
  197. (pass-if "char-locale-ci<>? (wide)"
  198. (under-french-utf8-locale-or-unresolved
  199. (lambda ()
  200. (and (char-locale-ci<? #\o #\œ %french-utf8-locale)
  201. (char-locale-ci>? #\Œ #\e %french-utf8-locale))))))
  202. (with-test-prefix "text collation (German)"
  203. (pass-if "string-locale-ci=?"
  204. (under-german-utf8-locale-or-unresolved
  205. (lambda ()
  206. (let ((de (make-locale LC_ALL %german-utf8-locale-name)))
  207. (string-locale-ci=? "Straße" "STRASSE"))))))
  208. (with-test-prefix "text collation (Greek)"
  209. (pass-if "string-locale-ci=?"
  210. (under-greek-utf8-locale-or-unresolved
  211. (lambda ()
  212. (let ((gr (make-locale LC_ALL %greek-utf8-locale-name)))
  213. (string-locale-ci=? "ΧΑΟΣ" "χαος" gr))))))
  214. (with-test-prefix "text collation (Czech)"
  215. (pass-if "string-locale<? for 'ch'"
  216. (under-locale-or-unresolved
  217. "cs_CZ.utf8"
  218. (lambda ()
  219. ;; Czech sorts digraph 'ch' between 'h' and 'i'.
  220. ;;
  221. ;; GNU libc 2.22 gets this wrong:
  222. ;; <https://sourceware.org/bugzilla/show_bug.cgi?id=18589>. For
  223. ;; now, just skip it if it fails (XXX).
  224. (or (and (string-locale>? "chxxx" "cxxx")
  225. (string-locale>? "chxxx" "hxxx")
  226. (string-locale<? "chxxxx" "ixxx"))
  227. (throw 'unresolved))))))
  228. (with-test-prefix "character mapping"
  229. (pass-if "char-locale-downcase"
  230. (and (eqv? #\a (char-locale-downcase #\A))
  231. (eqv? #\a (char-locale-downcase #\A (make-locale LC_ALL "C")))))
  232. (pass-if "char-locale-upcase"
  233. (and (eqv? #\Z (char-locale-upcase #\z))
  234. (eqv? #\Z (char-locale-upcase #\z (make-locale LC_ALL "C")))))
  235. (pass-if "char-locale-titlecase"
  236. (and (eqv? #\T (char-locale-titlecase #\t))
  237. (eqv? #\T (char-locale-titlecase #\t (make-locale LC_ALL "C")))))
  238. (pass-if "char-locale-titlecase Dž"
  239. (and (eqv? #\762 (char-locale-titlecase #\763))
  240. (eqv? #\762 (char-locale-titlecase #\763 (make-locale LC_ALL "C")))))
  241. (pass-if "char-locale-upcase Turkish"
  242. (under-turkish-utf8-locale-or-unresolved
  243. (lambda ()
  244. (eqv? #\İ (char-locale-upcase #\i %turkish-utf8-locale)))))
  245. (pass-if "char-locale-downcase Turkish"
  246. (under-turkish-utf8-locale-or-unresolved
  247. (lambda ()
  248. (eqv? #\i (char-locale-downcase #\İ %turkish-utf8-locale))))))
  249. (with-test-prefix "string mapping"
  250. (pass-if "string-locale-downcase"
  251. (and (string=? "a" (string-locale-downcase "A"))
  252. (string=? "a" (string-locale-downcase "A" (make-locale LC_ALL "C")))))
  253. (pass-if "string-locale-upcase"
  254. (and (string=? "Z" (string-locale-upcase "z"))
  255. (string=? "Z" (string-locale-upcase "z" (make-locale LC_ALL "C")))))
  256. (pass-if "string-locale-titlecase"
  257. (and (string=? "Hello, World" (string-locale-titlecase "hello, world"))
  258. (string=? "Hello, World" (string-locale-titlecase
  259. "hello, world" (make-locale LC_ALL "C")))))
  260. (pass-if "string-locale-upcase German"
  261. (under-german-utf8-locale-or-unresolved
  262. (lambda ()
  263. (let ((de (make-locale LC_ALL %german-utf8-locale-name)))
  264. (string=? "STRASSE"
  265. (string-locale-upcase "Straße" de))))))
  266. (pass-if "string-locale-upcase Greek"
  267. (under-greek-utf8-locale-or-unresolved
  268. (lambda ()
  269. (let ((el (make-locale LC_ALL %greek-utf8-locale-name)))
  270. (string=? "ΧΑΟΣ"
  271. (string-locale-upcase "χαος" el))))))
  272. (pass-if "string-locale-upcase Greek (two sigmas)"
  273. (under-greek-utf8-locale-or-unresolved
  274. (lambda ()
  275. (let ((el (make-locale LC_ALL %greek-utf8-locale-name)))
  276. (string=? "ΓΕΙΆ ΣΑΣ"
  277. (string-locale-upcase "Γειά σας" el))))))
  278. (pass-if "string-locale-downcase Greek"
  279. (under-greek-utf8-locale-or-unresolved
  280. (lambda ()
  281. (let ((el (make-locale LC_ALL %greek-utf8-locale-name)))
  282. (string=? "χαος"
  283. (string-locale-downcase "ΧΑΟΣ" el))))))
  284. (pass-if "string-locale-downcase Greek (two sigmas)"
  285. (under-greek-utf8-locale-or-unresolved
  286. (lambda ()
  287. (let ((el (make-locale LC_ALL %greek-utf8-locale-name)))
  288. (string=? "γειά σας"
  289. (string-locale-downcase "ΓΕΙΆ ΣΑΣ" el))))))
  290. (pass-if "string-locale-upcase Turkish"
  291. (under-turkish-utf8-locale-or-unresolved
  292. (lambda ()
  293. (string=? "İI" (string-locale-upcase "iı" %turkish-utf8-locale)))))
  294. (pass-if "string-locale-downcase Turkish"
  295. (under-turkish-utf8-locale-or-unresolved
  296. (lambda ()
  297. (string=? "iı" (string-locale-downcase "İI" %turkish-utf8-locale))))))
  298. (with-test-prefix "number parsing"
  299. (pass-if "locale-string->integer"
  300. (call-with-values (lambda () (locale-string->integer "123"))
  301. (lambda (result char-count)
  302. (and (equal? result 123)
  303. (equal? char-count 3)))))
  304. (pass-if "locale-string->inexact"
  305. (call-with-values
  306. (lambda ()
  307. (locale-string->inexact "123.456"
  308. (make-locale (list LC_NUMERIC) "C")))
  309. (lambda (result char-count)
  310. (and (equal? result 123.456)
  311. (equal? char-count 7)))))
  312. (pass-if "locale-string->inexact (French)"
  313. (under-french-locale-or-unresolved
  314. (lambda ()
  315. (call-with-values
  316. (lambda ()
  317. (locale-string->inexact "123,456" %french-locale))
  318. (lambda (result char-count)
  319. (and (equal? result 123.456)
  320. (equal? char-count 7))))))))
  321. ;;;
  322. ;;; `nl-langinfo'
  323. ;;;
  324. (setlocale LC_ALL "C")
  325. (define %c-locale (make-locale LC_ALL "C"))
  326. (define %english-days
  327. '("Sunday" "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday"))
  328. (define (every? . args)
  329. (not (not (apply every args))))
  330. (with-test-prefix "nl-langinfo et al."
  331. (pass-if "locale-day (1 arg)"
  332. (every? equal?
  333. %english-days
  334. (map locale-day (map 1+ (iota 7)))))
  335. (pass-if "locale-day (2 args)"
  336. (every? equal?
  337. %english-days
  338. (map (lambda (day)
  339. (locale-day day %c-locale))
  340. (map 1+ (iota 7)))))
  341. (pass-if "locale-day (2 args, using `%global-locale')"
  342. (every? equal?
  343. %english-days
  344. (map (lambda (day)
  345. (locale-day day %global-locale))
  346. (map 1+ (iota 7)))))
  347. (pass-if "locale-day (French)"
  348. (under-french-locale-or-unresolved
  349. (lambda ()
  350. (let ((result (locale-day 3 %french-locale)))
  351. (and (string? result)
  352. (string-ci=? result "mardi"))))))
  353. (pass-if "locale-day (French, using `%global-locale')"
  354. ;; Make sure `%global-locale' captures the current locale settings as
  355. ;; installed using `setlocale'.
  356. (under-french-locale-or-unresolved
  357. (lambda ()
  358. (dynamic-wind
  359. (lambda ()
  360. (setlocale LC_TIME %french-locale-name))
  361. (lambda ()
  362. (let* ((fr (make-locale (list LC_MONETARY) "C" %global-locale))
  363. (result (locale-day 3 fr)))
  364. (setlocale LC_ALL "C")
  365. (and (string? result)
  366. (string-ci=? result "mardi"))))
  367. (lambda ()
  368. (setlocale LC_ALL "C"))))))
  369. (pass-if "default locale"
  370. ;; Make sure the default locale does not capture the current locale
  371. ;; settings as installed using `setlocale'. The default locale should be
  372. ;; "C".
  373. (under-french-locale-or-unresolved
  374. (lambda ()
  375. (dynamic-wind
  376. (lambda ()
  377. (setlocale LC_ALL %french-locale-name))
  378. (lambda ()
  379. (let* ((locale (make-locale (list LC_MONETARY) "C"))
  380. (result (locale-day 3 locale)))
  381. (setlocale LC_ALL "C")
  382. (and (string? result)
  383. (string-ci=? result "Tuesday"))))
  384. (lambda ()
  385. (setlocale LC_ALL "C")))))))
  386. ;;;
  387. ;;; Numbers.
  388. ;;;
  389. (with-test-prefix "number->locale-string"
  390. ;; We assume the global locale is "C" at this point.
  391. (with-test-prefix "C"
  392. (pass-if-equal "no thousand separator"
  393. ""
  394. ;; Unlike in English, the "C" locale has no thousand separator.
  395. ;; If this doesn't hold, the following tests will fail.
  396. (locale-thousands-separator))
  397. (pass-if-equal "integer"
  398. "123456"
  399. (number->locale-string 123456))
  400. (pass-if-equal "fraction"
  401. "1234.567"
  402. (number->locale-string 1234.567))
  403. (pass-if-equal "fraction, 1 digit"
  404. "1234.6"
  405. (number->locale-string 1234.567 1))
  406. (pass-if-equal "fraction, 10 digits"
  407. "0.0000300000"
  408. (number->locale-string .00003 10))
  409. (pass-if-equal "trailing zeros"
  410. "-10.00000"
  411. (number->locale-string -10.0 5))
  412. (pass-if-equal "positive inexact zero, 1 digit"
  413. "0.0"
  414. (number->locale-string .0 1)))
  415. (with-test-prefix "French"
  416. (pass-if-equal "integer"
  417. "123 456"
  418. (under-french-locale-or-unresolved
  419. (lambda ()
  420. (let ((fr (make-locale LC_ALL %french-locale-name)))
  421. (number->locale-string 123456 #t fr)))))
  422. (pass-if-equal "negative integer"
  423. "-1 234 567"
  424. (under-french-locale-or-unresolved
  425. (lambda ()
  426. (let ((fr (make-locale LC_ALL %french-locale-name)))
  427. (number->locale-string -1234567 #t fr)))))
  428. (pass-if-equal "fraction"
  429. "1 234,567"
  430. (under-french-locale-or-unresolved
  431. (lambda ()
  432. (let ((fr (make-locale LC_ALL %french-locale-name)))
  433. (number->locale-string 1234.567 #t fr)))))
  434. (pass-if-equal "fraction, 1 digit"
  435. "1 234,6"
  436. (under-french-locale-or-unresolved
  437. (lambda ()
  438. (let ((fr (make-locale LC_ALL %french-locale-name)))
  439. (number->locale-string 1234.567 1 fr)))))))
  440. (with-test-prefix "format ~h"
  441. ;; Some systems like Darwin lack the `GROUPING' nl_item, and thus
  442. ;; `locale-digit-grouping' defaults to '(); skip the tests in that
  443. ;; case.
  444. (with-test-prefix "French"
  445. (pass-if-equal "12345.678"
  446. "12 345,678"
  447. (under-french-locale-or-unresolved
  448. (lambda ()
  449. (if (null? (locale-digit-grouping %french-locale))
  450. (throw 'unresolved)
  451. (format #f "~:h" 12345.678 %french-locale))))))
  452. (with-test-prefix "English"
  453. (pass-if-equal "12345.678"
  454. "12,345.678"
  455. (under-american-english-locale-or-unresolved
  456. (lambda ()
  457. (if (null? (locale-digit-grouping %american-english-locale))
  458. (throw 'unresolved)
  459. (format #f "~:h" 12345.678
  460. %american-english-locale)))))))
  461. (with-test-prefix "monetary-amount->locale-string"
  462. (with-test-prefix "French"
  463. (pass-if-equal "integer"
  464. "123 456,00 +EUR"
  465. (under-french-locale-or-unresolved
  466. (lambda ()
  467. (let ((fr (make-locale LC_ALL %french-locale-name)))
  468. (monetary-amount->locale-string 123456 #f fr)))))
  469. (pass-if-equal "fraction"
  470. "1 234,57 EUR "
  471. (under-french-locale-or-unresolved
  472. (lambda ()
  473. (let ((fr (make-locale LC_ALL %french-locale-name)))
  474. (monetary-amount->locale-string 1234.567 #t fr)))))
  475. (pass-if-equal "positive inexact zero"
  476. "0,00 +EUR"
  477. (under-french-locale-or-unresolved
  478. (lambda ()
  479. (let ((fr (make-locale LC_ALL %french-locale-name)))
  480. (monetary-amount->locale-string 0. #f fr)))))
  481. (pass-if-equal "one cent"
  482. "0,01 EUR "
  483. (under-french-locale-or-unresolved
  484. (lambda ()
  485. (let ((fr (make-locale LC_ALL %french-locale-name)))
  486. (monetary-amount->locale-string .01 #t fr)))))
  487. (pass-if-equal "very little money"
  488. "0,00 EUR "
  489. (under-french-locale-or-unresolved
  490. (lambda ()
  491. (let ((fr (make-locale LC_ALL %french-locale-name)))
  492. (monetary-amount->locale-string .00003 #t fr)))))))