;;;; i18n.test --- Exercise the i18n API. -*- coding: utf-8; mode: scheme; -*- ;;;; ;;;; Copyright (C) 2006, 2007, 2009, 2010, 2011, 2012, ;;;; 2013, 2014 Free Software Foundation, Inc. ;;;; Ludovic Courtès ;;;; ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either ;;;; version 3 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;;; Lesser General Public License for more details. ;;;; ;;;; You should have received a copy of the GNU Lesser General Public ;;;; License along with this library; if not, write to the Free Software ;;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA (define-module (test-suite i18n) #:use-module (ice-9 i18n) #:use-module (ice-9 format) #:use-module (srfi srfi-1) #:use-module (test-suite lib)) ;; Start from a pristine locale state. (setlocale LC_ALL "C") (define exception:locale-error (cons 'system-error "Failed to install locale")) (with-test-prefix "locale objects" (pass-if "make-locale (2 args)" (not (not (make-locale LC_ALL "C")))) (pass-if "make-locale (2 args, list)" (not (not (make-locale (list LC_COLLATE LC_NUMERIC) "C")))) (pass-if "make-locale (3 args)" (not (not (make-locale (list LC_COLLATE) "C" (make-locale (list LC_NUMERIC) "C"))))) (pass-if-exception "make-locale with unknown locale" exception:locale-error (make-locale LC_ALL "does-not-exist")) (pass-if "locale?" (and (locale? (make-locale (list LC_ALL) "C")) (locale? (make-locale (list LC_TIME LC_NUMERIC) "C" (make-locale (list LC_CTYPE) "C"))))) (pass-if "%global-locale" (and (locale? %global-locale)) (locale? (make-locale (list LC_MONETARY) "C" %global-locale)))) (with-test-prefix "text collation (English)" (pass-if "string-locale?" (under-french-locale-or-unresolved (lambda () (and (string-locale-ci? "HiVeR" "été" %french-locale))))) (pass-if "string-locale-ci<>? (wide strings)" (under-french-utf8-locale-or-unresolved (lambda () ;; One of the strings is UCS-4, the other is Latin-1. (and (string-locale-ci? "Œuf" "œdÈMe" %french-utf8-locale))))) (pass-if "string-locale-ci<>? (wide and narrow strings)" (under-french-utf8-locale-or-unresolved (lambda () ;; One of the strings is UCS-4, the other is Latin-1. (and (string-locale-ci>? "Œdème" "odyssée" %french-utf8-locale) (string-locale-ci?" (under-french-locale-or-unresolved (lambda () (and (char-locale-ci? #\h #\É %french-locale))))) (pass-if "char-locale-ci<>? (wide)" (under-french-utf8-locale-or-unresolved (lambda () (and (char-locale-ci? #\Œ #\e %french-utf8-locale)))))) (with-test-prefix "text collation (German)" (pass-if "string-locale-ci=?" (under-german-utf8-locale-or-unresolved (lambda () (let ((de (make-locale LC_ALL %german-utf8-locale-name))) (string-locale-ci=? "Straße" "STRASSE")))))) (with-test-prefix "text collation (Greek)" (pass-if "string-locale-ci=?" (under-greek-utf8-locale-or-unresolved (lambda () (let ((gr (make-locale LC_ALL %greek-utf8-locale-name))) (string-locale-ci=? "ΧΑΟΣ" "χαος" gr)))))) (with-test-prefix "character mapping" (pass-if "char-locale-downcase" (and (eqv? #\a (char-locale-downcase #\A)) (eqv? #\a (char-locale-downcase #\A (make-locale LC_ALL "C"))))) (pass-if "char-locale-upcase" (and (eqv? #\Z (char-locale-upcase #\z)) (eqv? #\Z (char-locale-upcase #\z (make-locale LC_ALL "C"))))) (pass-if "char-locale-titlecase" (and (eqv? #\T (char-locale-titlecase #\t)) (eqv? #\T (char-locale-titlecase #\t (make-locale LC_ALL "C"))))) (pass-if "char-locale-titlecase Dž" (and (eqv? #\762 (char-locale-titlecase #\763)) (eqv? #\762 (char-locale-titlecase #\763 (make-locale LC_ALL "C"))))) (pass-if "char-locale-upcase Turkish" (under-turkish-utf8-locale-or-unresolved (lambda () (eqv? #\İ (char-locale-upcase #\i %turkish-utf8-locale))))) (pass-if "char-locale-downcase Turkish" (under-turkish-utf8-locale-or-unresolved (lambda () (eqv? #\i (char-locale-downcase #\İ %turkish-utf8-locale)))))) (with-test-prefix "string mapping" (pass-if "string-locale-downcase" (and (string=? "a" (string-locale-downcase "A")) (string=? "a" (string-locale-downcase "A" (make-locale LC_ALL "C"))))) (pass-if "string-locale-upcase" (and (string=? "Z" (string-locale-upcase "z")) (string=? "Z" (string-locale-upcase "z" (make-locale LC_ALL "C"))))) (pass-if "string-locale-titlecase" (and (string=? "Hello, World" (string-locale-titlecase "hello, world")) (string=? "Hello, World" (string-locale-titlecase "hello, world" (make-locale LC_ALL "C"))))) (pass-if "string-locale-upcase German" (under-german-utf8-locale-or-unresolved (lambda () (let ((de (make-locale LC_ALL %german-utf8-locale-name))) (string=? "STRASSE" (string-locale-upcase "Straße" de)))))) (pass-if "string-locale-upcase Greek" (under-greek-utf8-locale-or-unresolved (lambda () (let ((el (make-locale LC_ALL %greek-utf8-locale-name))) (string=? "ΧΑΟΣ" (string-locale-upcase "χαος" el)))))) (pass-if "string-locale-upcase Greek (two sigmas)" (under-greek-utf8-locale-or-unresolved (lambda () (let ((el (make-locale LC_ALL %greek-utf8-locale-name))) (string=? "ΓΕΙΆ ΣΑΣ" (string-locale-upcase "Γειά σας" el)))))) (pass-if "string-locale-downcase Greek" (under-greek-utf8-locale-or-unresolved (lambda () (let ((el (make-locale LC_ALL %greek-utf8-locale-name))) (string=? "χαος" (string-locale-downcase "ΧΑΟΣ" el)))))) (pass-if "string-locale-downcase Greek (two sigmas)" (under-greek-utf8-locale-or-unresolved (lambda () (let ((el (make-locale LC_ALL %greek-utf8-locale-name))) (string=? "γειά σας" (string-locale-downcase "ΓΕΙΆ ΣΑΣ" el)))))) (pass-if "string-locale-upcase Turkish" (under-turkish-utf8-locale-or-unresolved (lambda () (string=? "İI" (string-locale-upcase "iı" %turkish-utf8-locale))))) (pass-if "string-locale-downcase Turkish" (under-turkish-utf8-locale-or-unresolved (lambda () (string=? "iı" (string-locale-downcase "İI" %turkish-utf8-locale)))))) (with-test-prefix "number parsing" (pass-if "locale-string->integer" (call-with-values (lambda () (locale-string->integer "123")) (lambda (result char-count) (and (equal? result 123) (equal? char-count 3))))) (pass-if "locale-string->inexact" (call-with-values (lambda () (locale-string->inexact "123.456" (make-locale (list LC_NUMERIC) "C"))) (lambda (result char-count) (and (equal? result 123.456) (equal? char-count 7))))) (pass-if "locale-string->inexact (French)" (under-french-locale-or-unresolved (lambda () (call-with-values (lambda () (locale-string->inexact "123,456" %french-locale)) (lambda (result char-count) (and (equal? result 123.456) (equal? char-count 7)))))))) ;;; ;;; `nl-langinfo' ;;; (setlocale LC_ALL "C") (define %c-locale (make-locale LC_ALL "C")) (define %english-days '("Sunday" "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday")) (define (every? . args) (not (not (apply every args)))) (with-test-prefix "nl-langinfo et al." (pass-if "locale-day (1 arg)" (every? equal? %english-days (map locale-day (map 1+ (iota 7))))) (pass-if "locale-day (2 args)" (every? equal? %english-days (map (lambda (day) (locale-day day %c-locale)) (map 1+ (iota 7))))) (pass-if "locale-day (2 args, using `%global-locale')" (every? equal? %english-days (map (lambda (day) (locale-day day %global-locale)) (map 1+ (iota 7))))) (pass-if "locale-day (French)" (under-french-locale-or-unresolved (lambda () (let ((result (locale-day 3 %french-locale))) (and (string? result) (string-ci=? result "mardi")))))) (pass-if "locale-day (French, using `%global-locale')" ;; Make sure `%global-locale' captures the current locale settings as ;; installed using `setlocale'. (under-french-locale-or-unresolved (lambda () (dynamic-wind (lambda () (setlocale LC_TIME %french-locale-name)) (lambda () (let* ((fr (make-locale (list LC_MONETARY) "C" %global-locale)) (result (locale-day 3 fr))) (setlocale LC_ALL "C") (and (string? result) (string-ci=? result "mardi")))) (lambda () (setlocale LC_ALL "C")))))) (pass-if "default locale" ;; Make sure the default locale does not capture the current locale ;; settings as installed using `setlocale'. The default locale should be ;; "C". (under-french-locale-or-unresolved (lambda () (dynamic-wind (lambda () (setlocale LC_ALL %french-locale-name)) (lambda () (let* ((locale (make-locale (list LC_MONETARY) "C")) (result (locale-day 3 locale))) (setlocale LC_ALL "C") (and (string? result) (string-ci=? result "Tuesday")))) (lambda () (setlocale LC_ALL "C"))))))) ;;; ;;; Numbers. ;;; (with-test-prefix "number->locale-string" ;; We assume the global locale is "C" at this point. (with-test-prefix "C" (pass-if "no thousand separator" ;; Unlike in English, the "C" locale has no thousand separator. ;; If this doesn't hold, the following tests will fail. (string=? "" (locale-thousands-separator))) (pass-if "integer" (string=? "123456" (number->locale-string 123456))) (pass-if "fraction" (string=? "1234.567" (number->locale-string 1234.567))) (pass-if "fraction, 1 digit" (string=? "1234.5" (number->locale-string 1234.567 1)))) (with-test-prefix "French" (pass-if "integer" (under-french-locale-or-unresolved (lambda () (let ((fr (make-locale LC_ALL %french-locale-name))) (string=? "123 456" (number->locale-string 123456 #t fr)))))) (pass-if "fraction" (under-french-locale-or-unresolved (lambda () (let ((fr (make-locale LC_ALL %french-locale-name))) (string=? "1 234,567" (number->locale-string 1234.567 #t fr)))))) (pass-if "fraction, 1 digit" (under-french-locale-or-unresolved (lambda () (let ((fr (make-locale LC_ALL %french-locale-name))) (string=? "1 234,5" (number->locale-string 1234.567 1 fr)))))))) (with-test-prefix "format ~h" ;; Some systems like Darwin lack the `GROUPING' nl_item, and thus ;; `locale-digit-grouping' defaults to '(); skip the tests in that ;; case. (with-test-prefix "French" (pass-if "12345.5678" (under-french-locale-or-unresolved (lambda () (if (null? (locale-digit-grouping %french-locale)) (throw 'unresolved) (string=? "12 345,6789" (format #f "~:h" 12345.6789 %french-locale))))))) (with-test-prefix "English" (pass-if "12345.5678" (under-american-english-locale-or-unresolved (lambda () (if (null? (locale-digit-grouping %american-english-locale)) (throw 'unresolved) (string=? "12,345.6789" (format #f "~:h" 12345.6789 %american-english-locale)))))))) (with-test-prefix "monetary-amount->locale-string" (with-test-prefix "French" (pass-if "integer" (under-french-locale-or-unresolved (lambda () (let ((fr (make-locale LC_ALL %french-locale-name))) (string=? "123 456 +EUR" (monetary-amount->locale-string 123456 #f fr)))))) (pass-if "fraction" (under-french-locale-or-unresolved (lambda () (let ((fr (make-locale LC_ALL %french-locale-name))) (string=? "1 234,56 EUR " (monetary-amount->locale-string 1234.567 #t fr))))))))