summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean Forget <J2N-FORGET@orange.fr>2021-07-23 15:26:40 +0200
committerLars Ingebrigtsen <larsi@gnus.org>2021-07-23 15:26:45 +0200
commit6a3b89f9df85d0718e55d460164ff65e7bdd823e (patch)
tree724a4b059e01b81acfcca7b9bb49b67481ab3faa
parentaa5437493b1ca539409495ecdc54cf420ea110b9 (diff)
downloademacs-6a3b89f9df85d0718e55d460164ff65e7bdd823e.tar.gz
Add more support for the French Revolutionary Calendar
* lisp/calendar/cal-french.el (calendar-french-feasts-array): New variable (bug#19174). (calendar-french-trim-feast): New function. (calendar-french-date-string, calendar-french-goto-date): (calendar-french-goto-date): Use them. http://datetime.mongueurs.net/Histoire/s-c/01-g.en.html https://metacpan.org/pod/DateTime::Calendar::FrenchRevolutionary#Internet
-rw-r--r--lisp/calendar/cal-french.el192
-rw-r--r--test/lisp/calendar/cal-french-tests.el113
2 files changed, 284 insertions, 21 deletions
diff --git a/lisp/calendar/cal-french.el b/lisp/calendar/cal-french.el
index 639bae700cc..cc18a2a5d8e 100644
--- a/lisp/calendar/cal-french.el
+++ b/lisp/calendar/cal-french.el
@@ -40,12 +40,13 @@
(defconst calendar-french-month-name-array
["Vendémiaire" "Brumaire" "Frimaire" "Nivôse" "Pluviôse" "Ventôse"
- "Germinal" "Floréal" "Prairial" "Messidor" "Thermidor" "Fructidor"]
+ "Germinal" "Floréal" "Prairial" "Messidor" "Thermidor" "Fructidor"
+ "jour complémentaire"]
"Array of month names in the French calendar.")
(defconst calendar-french-day-name-array
["Primidi" "Duodi" "Tridi" "Quartidi" "Quintidi" "Sextidi" "Septidi"
- "Octidi" "Nonidi" "Decadi"]
+ "Octidi" "Nonidi" "Décadi"]
"Array of day names in the French calendar.")
(define-obsolete-variable-alias 'calendar-french-multibyte-special-days-array
@@ -56,6 +57,144 @@
"de la Révolution"]
"Array of special day names in the French calendar.")
+(defconst calendar-french-feasts-array
+ [;; Vendémiaire
+ "du Raisin" "du Safran" "de la Châtaigne"
+ "de la Colchique" "du Cheval" "de la Balsamine"
+ "de la Carotte" "de l'Amarante" "du Panais"
+ "de la Cuve" "de la Pomme de terre" "de l'Immortelle"
+ "du Potiron" "du Réséda" "de l'Âne"
+ "de la Belle de nuit" "de la Citrouille" "du Sarrasin"
+ "du Tournesol" "du Pressoir" "du Chanvre"
+ "de la Pêche" "du Navet" "de l'Amaryllis"
+ "du Bœuf" "de l'Aubergine" "du Piment"
+ "de la Tomate" "de l'Orge" "du Tonneau"
+ ;; Brumaire
+ "de la Pomme" "du Céleri" "de la Poire"
+ "de la Betterave" "de l'Oie" "de l'Héliotrope"
+ "de la Figue" "de la Scorsonère" "de l'Alisier"
+ "de la Charrue" "du Salsifis" "de la Macre"
+ "du Topinambour" "de l'Endive" "du Dindon"
+ "du Chervis" "du Cresson" "de la Dentelaire"
+ "de la Grenade" "de la Herse" "de la Bacchante"
+ "de l'Azerole" "de la Garance" "de l'Orange"
+ "du Faisan" "de la Pistache" "du Macjon"
+ "du Coing" "du Cormier" "du Rouleau"
+ ;; Frimaire
+ "de la Raiponce" "du Turneps" "de la Chicorée"
+ "de la Nèfle" "du Cochon" "de la Mâche"
+ "du Chou-fleur" "du Miel" "du Genièvre"
+ "de la Pioche" "de la Cire" "du Raifort"
+ "du Cèdre" "du Sapin" "du Chevreuil"
+ "de l'Ajonc" "du Cyprès" "du Lierre"
+ "de la Sabine" "du Hoyau" "de l'Érable-sucre"
+ "de la Bruyère" "du Roseau" "de l'Oseille"
+ "du Grillon" "du Pignon" "du Liège"
+ "de la Truffe" "de l'Olive" "de la Pelle"
+ ;; Nivôse
+ "de la Tourbe" "de la Houille" "du Bitume"
+ "du Soufre" "du Chien" "de la Lave"
+ "de la Terre végétale" "du Fumier" "du Salpêtre"
+ "du Fléau" "du Granit" "de l'Argile"
+ "de l'Ardoise" "du Grès" "du Lapin"
+ "du Silex" "de la Marne" "de la Pierre à chaux"
+ "du Marbre" "du Van" "de la Pierre à plâtre"
+ "du Sel" "du Fer" "du Cuivre"
+ "du Chat" "de l'Étain" "du Plomb"
+ "du Zinc" "du Mercure" "du Crible"
+ ;; Pluviôse
+ "de la Lauréole" "de la Mousse" "du Fragon"
+ "du Perce-neige" "du Taureau" "du Laurier-thym"
+ "de l'Amadouvier" "du Mézéréon" "du Peuplier"
+ "de la Cognée" "de l'Ellébore" "du Brocoli"
+ "du Laurier" "de l'Avelinier" "de la Vache"
+ "du Buis" "du Lichen" "de l'If"
+ "de la Pulmonaire" "de la Serpette" "du Thlaspi"
+ "du Thymelé" "du Chiendent" "de la Traînasse"
+ "du Lièvre" "de la Guède" "du Noisetier"
+ "du Cyclamen" "de la Chélidoine" "du Traîneau"
+ ;; Ventôse
+ "du Tussilage" "du Cornouiller" "du Violier"
+ "du Troène" "du Bouc" "de l'Asaret"
+ "de l'Alaterne" "de la Violette" "du Marsault"
+ "de la Bêche" "du Narcisse" "de l'Orme"
+ "de la Fumeterre" "du Vélar" "de la Chèvre"
+ "de l'Épinard" "du Doronic" "du Mouron"
+ "du Cerfeuil" "du Cordeau" "de la Mandragore"
+ "du Persil" "du Cochléaria" "de la Pâquerette"
+ "du Thon" "du Pissenlit" "de la Sylvie"
+ "du Capillaire" "du Frêne" "du Plantoir"
+ ;; Germinal
+ "de la Primevère" "du Platane" "de l'Asperge"
+ "de la Tulipe" "de la Poule" "de la Blette"
+ "du Bouleau" "de la Jonquille" "de l'Aulne"
+ "du Couvoir" "de la Pervenche" "du Charme"
+ "de la Morille" "du Hêtre" "de l'Abeille"
+ "de la Laitue" "du Mélèze" "de la Ciguë"
+ "du Radis" "de la Ruche" "du Gainier"
+ "de la Romaine" "du Marronnier" "de la Roquette"
+ "du Pigeon" "du Lilas" "de l'Anémone"
+ "de la Pensée" "de la Myrtille" "du Greffoir"
+ ;; Floréal
+ "de la Rose" "du Chêne" "de la Fougère"
+ "de l'Aubépine" "du Rossignol" "de l'Ancolie"
+ "du Muguet" "du Champignon" "de la Jacinthe"
+ "du Rateau" "de la Rhubarbe" "du Sainfoin"
+ "du Bâton-d'or" "du Chamérisier" "du Ver à soie"
+ "de la Consoude" "de la Pimprenelle" "de la Corbeille-d'or"
+ "de l'Arroche" "du Sarcloir" "du Statice"
+ "de la Fritillaire" "de la Bourrache" "de la Valériane"
+ "de la Carpe" "du Fusain" "de la Civette"
+ "de la Buglosse" "du Sénevé" "de la Houlette"
+ ;; Prairial
+ "de la Luzerne" "de l'Hémérocalle" "du Trèfle"
+ "de l'Angélique" "du Canard" "de la Mélisse"
+ "du Fromental" "du Martagon" "du Serpolet"
+ "de la Faux" "de la Fraise" "de la Bétoine"
+ "du Pois" "de l'Acacia" "de la Caille"
+ "de l'Œillet" "du Sureau" "du Pavot"
+ "du Tilleul" "de la Fourche" "du Barbeau"
+ "de la Camomille" "du Chèvrefeuille" "du Caille-lait"
+ "de la Tanche" "du Jasmin" "de la Verveine"
+ "du Thym" "de la Pivoine" "du Chariot"
+ ;; Messidor
+ "du Seigle" "de l'Avoine" "de l'Oignon"
+ "de la Véronique" "du Mulet" "du Romarin"
+ "du Concombre" "de l'Échalotte" "de l'Absinthe"
+ "de la Faucille" "de la Coriandre" "de l'Artichaut"
+ "de la Giroflée" "de la Lavande" "du Chamois"
+ "du Tabac" "de la Groseille" "de la Gesse"
+ "de la Cerise" "du Parc" "de la Menthe"
+ "du Cumin" "du Haricot" "de l'Orcanète"
+ "de la Pintade" "de la Sauge" "de l'Ail"
+ "de la Vesce" "du Blé" "de la Chalémie"
+ ;; Thermidor
+ "de l'Épautre" "du Bouillon-blanc" "du Melon"
+ "de l'Ivraie" "du Bélier" "de la Prèle"
+ "de l'Armoise" "du Carthame" "de la Mûre"
+ "de l'Arrosoir" "du Panis" "du Salicor"
+ "de l'Abricot" "du Basilic" "de la Brebis"
+ "de la Guimauve" "du Lin" "de l'Amande"
+ "de la Gentiane" "de l'Écluse" "de la Carline"
+ "du Câprier" "de la Lentille" "de l'Aunée"
+ "de la Loutre" "de la Myrte" "du Colza"
+ "du Lupin" "du Coton" "du Moulin"
+ ;; Fructidor
+ "de la Prune" "du Millet" "du Lycoperdon"
+ "de l'Escourgeon" "du Saumon" "de la Tubéreuse"
+ "du Sucrion" "de l'Apocyn" "de la Réglisse"
+ "de l'Échelle" "de la Pastèque" "du Fenouil"
+ "de l'Épine-vinette" "de la Noix" "de la Truite"
+ "du Citron" "de la Cardère" "du Nerprun"
+ "du Tagette" "de la Hotte" "de l'Églantier"
+ "de la Noisette" "du Houblon" "du Sorgho"
+ "de l'Écrevisse" "de la Bagarade" "de la Verge-d'or"
+ "du Maïs" "du Marron" "du Panier"
+ ;; jour complémentaire
+ "de la Vertu" "du Génie" "du Travail"
+ "de la Raison" "des Récompenses" "de la Révolution"]
+ "Array of day feasts in the French calendar.")
+
(defun calendar-french-accents-p ()
(declare (obsolete nil "28.1"))
t)
@@ -75,6 +214,16 @@
(declare (obsolete "use the variable of the same name instead" "28.1"))
calendar-french-special-days-array)
+(defun calendar-french-trim-feast (feast)
+ "Remove the article from the feast, e.g. \"du Raisin\" -> \"Raisin\"
+or \"de la Vertu\" -> \"Vertu\""
+ (cond
+ ((equal (substring feast 0 3) "du ") (substring feast 3))
+ ((equal (substring feast 0 6) "de la ") (substring feast 6))
+ ((equal (substring feast 0 5) "de l'") (substring feast 5))
+ ((equal (substring feast 0 4) "des ") (substring feast 4))
+ (t feast)))
+
(defun calendar-french-leap-year-p (year)
"True if YEAR is a leap year on the French Revolutionary calendar.
For Gregorian years 1793 to 1805, the years of actual operation of the
@@ -162,14 +311,13 @@ Defaults to today's date if DATE is not given."
(d (calendar-extract-day french-date)))
(cond
((< y 1) "")
- ((= m 13) (format "Jour %s de l'Année %d de la Révolution"
- (aref calendar-french-special-days-array (1- d))
- y))
(t (format
- "%d %s an %d de la Révolution"
+ "%s %d %s an %d de la Révolution, jour %s"
+ (aref calendar-french-day-name-array (% (1- d) 10))
d
(aref calendar-french-month-name-array (1- m))
- y)))))
+ y
+ (aref calendar-french-feasts-array (+ -31 (* 30 m) d)))))))
;;;###cal-autoload
(defun calendar-french-print-date ()
@@ -186,7 +334,7 @@ Defaults to today's date if DATE is not given."
Echo French Revolutionary date unless NOECHO is non-nil."
(interactive
(let* ((months calendar-french-month-name-array)
- (special-days calendar-french-special-days-array)
+ (feasts calendar-french-feasts-array)
(year (progn
(calendar-read-sexp
"Année de la Révolution (>0)"
@@ -199,29 +347,31 @@ Echo French Revolutionary date unless NOECHO is non-nil."
(mapcar 'list
(append months
(if (calendar-french-leap-year-p year)
- (mapcar
- (lambda (x) (concat "Jour " x))
- calendar-french-special-days-array)
+ (mapcar #'calendar-french-trim-feast feasts)
(reverse
(cdr ; we don't want rev. day in a non-leap yr
(reverse
- (mapcar
- (lambda (x)
- (concat "Jour " x))
- special-days))))))))
+ (mapcar #'calendar-french-trim-feast
+ feasts))))))))
(completion-ignore-case t)
(month (cdr (assoc-string
(completing-read
- "Mois ou Sansculottide: "
+ "Mois ou \"jour complémentaire\" ou fête: "
month-list
nil t)
(calendar-make-alist month-list 1 'car) t)))
- (day (if (> month 12)
- (- month 12)
+ (last-day (calendar-french-last-day-of-month (min month 13) year))
+ (day (if (> month 13)
+ (- month 13)
(calendar-read-sexp
- "Jour (1-30)"
- (lambda (x) (and (<= 1 x) (<= x 30))))))
- (month (if (> month 12) 13 month)))
+ (format "Jour (1-%d): " last-day)
+ (lambda (x) (<= 1 x last-day)))))
+ ;; All days in Vendémiaire and numbered 1 to 365 e.g., "Pomme"
+ ;; gives 31 Vendémiaire automatically normalized to 1 Brumaire
+ ;; "Céleri" gives 32 Vnd normalized to 2 Bru, "Raiponce" gives
+ ;; 61 Vnd normalized to 1 Frimaire, etc until "Récompences" which
+ ;; gives 365 Vnd normalized to 5 jour complémentaire.
+ (month (if (> month 13) 1 month)))
(list (list month day year))))
(calendar-goto-date (calendar-gregorian-from-absolute
(calendar-french-to-absolute date)))
diff --git a/test/lisp/calendar/cal-french-tests.el b/test/lisp/calendar/cal-french-tests.el
new file mode 100644
index 00000000000..ab62c1e6fc1
--- /dev/null
+++ b/test/lisp/calendar/cal-french-tests.el
@@ -0,0 +1,113 @@
+;;; cal-french-tests.el --- tests for cal-french.el -*- lexical-binding: t -*-
+
+;; Copyright (C) 2021 Free Software Foundation, Inc.
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; GNU Emacs 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 General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Code:
+
+(require 'ert)
+(require 'cal-french)
+
+(defconst cal-french-test-cases
+ '(
+ (1792 9 22 "Primidi 1 Vendémiaire an 1 de la Révolution, jour du Raisin")
+ (1793 10 23 "Duodi 2 Brumaire an 2 de la Révolution, jour du Céleri")
+ (1794 7 27 "Nonidi 9 Thermidor an 2 de la Révolution, jour de la Mûre")
+ (1794 11 23 "Tridi 3 Frimaire an 3 de la Révolution, jour de la Chicorée")
+ (1795 10 5 "Tridi 13 Vendémiaire an 4 de la Révolution, jour du Potiron")
+ (1795 12 25 "Quartidi 4 Nivôse an 4 de la Révolution, jour du Soufre")
+ (1797 1 24 "Quintidi 5 Pluviôse an 5 de la Révolution, jour du Taureau")
+ (1798 2 24 "Sextidi 6 Ventôse an 6 de la Révolution, jour de l'Asaret")
+ (1799 11 9 "Octidi 18 Brumaire an 8 de la Révolution, jour de la Dentelaire")
+ (1801 3 29 "Octidi 8 Germinal an 9 de la Révolution, jour de la Jonquille")
+ (1804 4 30 "Décadi 10 Floréal an 12 de la Révolution, jour du Rateau")
+ (1807 6 1 "Duodi 12 Prairial an 15 de la Révolution, jour de la Bétoine")
+ (1810 7 3 "Quartidi 14 Messidor an 18 de la Révolution, jour de la Lavande")
+ (1813 8 4 "Sextidi 16 Thermidor an 21 de la Révolution, jour de la Guimauve")
+ (1816 9 4 "Octidi 18 Fructidor an 24 de la Révolution, jour du Nerprun")
+ (2000 1 1 "Duodi 12 Nivôse an 208 de la Révolution, jour de l'Argile")
+ (2021 7 11 "Tridi 23 Messidor an 229 de la Révolution, jour du Haricot")
+ (2001 5 11 "Duodi 22 Floréal an 209 de la Révolution, jour de la Fritillaire")
+ (1792 9 22 "Primidi 1 Vendémiaire an 1 de la Révolution, jour du Raisin")
+ (1793 9 21 "Quintidi 5 jour complémentaire an 1 de la Révolution, jour des Récompenses")
+ (1793 9 22 "Primidi 1 Vendémiaire an 2 de la Révolution, jour du Raisin")
+ (1794 9 21 "Quintidi 5 jour complémentaire an 2 de la Révolution, jour des Récompenses")
+ (1794 9 22 "Primidi 1 Vendémiaire an 3 de la Révolution, jour du Raisin")
+ (1795 9 22 "Sextidi 6 jour complémentaire an 3 de la Révolution, jour de la Révolution")
+ (1795 9 23 "Primidi 1 Vendémiaire an 4 de la Révolution, jour du Raisin")
+ (1796 9 21 "Quintidi 5 jour complémentaire an 4 de la Révolution, jour des Récompenses")
+ (1796 9 22 "Primidi 1 Vendémiaire an 5 de la Révolution, jour du Raisin")
+ (1797 9 21 "Quintidi 5 jour complémentaire an 5 de la Révolution, jour des Récompenses")
+ (1797 9 22 "Primidi 1 Vendémiaire an 6 de la Révolution, jour du Raisin")
+ (1799 9 22 "Sextidi 6 jour complémentaire an 7 de la Révolution, jour de la Révolution")
+ (1799 9 23 "Primidi 1 Vendémiaire an 8 de la Révolution, jour du Raisin")
+ (1800 9 22 "Quintidi 5 jour complémentaire an 8 de la Révolution, jour des Récompenses")
+ (1800 9 23 "Primidi 1 Vendémiaire an 9 de la Révolution, jour du Raisin")
+ (1801 9 22 "Quintidi 5 jour complémentaire an 9 de la Révolution, jour des Récompenses")
+ (1801 9 23 "Primidi 1 Vendémiaire an 10 de la Révolution, jour du Raisin")
+ (1823 9 22 "Quintidi 5 jour complémentaire an 31 de la Révolution, jour des Récompenses")
+ (1823 9 23 "Primidi 1 Vendémiaire an 32 de la Révolution, jour du Raisin")
+ (1824 9 22 "Sextidi 6 jour complémentaire an 32 de la Révolution, jour de la Révolution")
+ (1824 9 23 "Primidi 1 Vendémiaire an 33 de la Révolution, jour du Raisin")
+ (1825 9 22 "Quintidi 5 jour complémentaire an 33 de la Révolution, jour des Récompenses")
+ (1825 9 23 "Primidi 1 Vendémiaire an 34 de la Révolution, jour du Raisin")
+ (1892 9 21 "Quintidi 5 jour complémentaire an 100 de la Révolution, jour des Récompenses")
+ (1892 9 22 "Primidi 1 Vendémiaire an 101 de la Révolution, jour du Raisin")
+ (1900 9 22 "Sextidi 6 jour complémentaire an 108 de la Révolution, jour de la Révolution")
+ (1900 9 23 "Primidi 1 Vendémiaire an 109 de la Révolution, jour du Raisin")
+ (1992 9 21 "Quintidi 5 jour complémentaire an 200 de la Révolution, jour des Récompenses")
+ (1992 9 22 "Primidi 1 Vendémiaire an 201 de la Révolution, jour du Raisin")
+ (2000 9 21 "Sextidi 6 jour complémentaire an 208 de la Révolution, jour de la Révolution")
+ (2000 9 22 "Primidi 1 Vendémiaire an 209 de la Révolution, jour du Raisin")
+ (2092 9 20 "Quintidi 5 jour complémentaire an 300 de la Révolution, jour des Récompenses")
+ (2092 9 21 "Primidi 1 Vendémiaire an 301 de la Révolution, jour du Raisin")
+ (2100 9 21 "Sextidi 6 jour complémentaire an 308 de la Révolution, jour de la Révolution")
+ (2100 9 22 "Primidi 1 Vendémiaire an 309 de la Révolution, jour du Raisin")
+ (2192 9 21 "Sextidi 6 jour complémentaire an 400 de la Révolution, jour de la Révolution")
+ (2192 9 22 "Primidi 1 Vendémiaire an 401 de la Révolution, jour du Raisin")
+ (2193 9 21 "Quintidi 5 jour complémentaire an 401 de la Révolution, jour des Récompenses")
+ (2199 9 22 "Primidi 1 Vendémiaire an 408 de la Révolution, jour du Raisin")
+ (2200 9 22 "Sextidi 6 jour complémentaire an 408 de la Révolution, jour de la Révolution")
+ (2791 9 23 "Primidi 1 Vendémiaire an 1000 de la Révolution, jour du Raisin")
+ (2792 9 22 "Primidi 1 Vendémiaire an 1001 de la Révolution, jour du Raisin")
+ (3000 1 1 "Duodi 12 Nivôse an 1208 de la Révolution, jour de l'Argile")
+ (3001 1 1 "Primidi 11 Nivôse an 1209 de la Révolution, jour du Granit")
+ (3791 9 22 "Primidi 1 Vendémiaire an 2000 de la Révolution, jour du Raisin")
+ (3792 9 22 "Primidi 1 Vendémiaire an 2001 de la Révolution, jour du Raisin")
+ (4000 1 1 "Duodi 12 Nivôse an 2208 de la Révolution, jour de l'Argile")
+ (4001 1 1 "Duodi 12 Nivôse an 2209 de la Révolution, jour de l'Argile")
+ (4320 9 10 "Quartidi 24 Fructidor an 2528 de la Révolution, jour du Sorgho")
+ (4320 9 11 "Quintidi 25 Fructidor an 2528 de la Révolution, jour de l'Écrevisse")
+ (4791 9 23 "Primidi 1 Vendémiaire an 3000 de la Révolution, jour du Raisin")
+ (4792 9 22 "Primidi 1 Vendémiaire an 3001 de la Révolution, jour du Raisin")
+ (5000 1 1 "Duodi 12 Nivôse an 3208 de la Révolution, jour de l'Argile")
+ (5001 1 1 "Primidi 11 Nivôse an 3209 de la Révolution, jour du Granit")
+ (5791 9 22 "Primidi 1 Vendémiaire an 4000 de la Révolution, jour du Raisin")
+ (5792 9 21 "Primidi 1 Vendémiaire an 4001 de la Révolution, jour du Raisin")
+ (6000 1 1 "Tridi 13 Nivôse an 4208 de la Révolution, jour de l'Ardoise")
+ (6001 1 1 "Tridi 13 Nivôse an 4209 de la Révolution, jour de l'Ardoise")
+ (6791 9 22 "Primidi 1 Vendémiaire an 5000 de la Révolution, jour du Raisin")
+ (6792 9 21 "Primidi 1 Vendémiaire an 5001 de la Révolution, jour du Raisin")
+ (7791 9 21 "Primidi 1 Vendémiaire an 6000 de la Révolution, jour du Raisin")
+ (7792 9 21 "Primidi 1 Vendémiaire an 6001 de la Révolution, jour du Raisin")
+ ))
+
+(ert-deftest cal-french-tests ()
+ (pcase-dolist (`(,y ,m ,d ,str) cal-french-test-cases)
+ (should (equal (calendar-french-date-string (list m d y)) str))))
+
+(provide 'cal-french-tests)