diff --git a/Rules/Languages/fr/ClearSpeak_Rules.yaml b/Rules/Languages/fr/ClearSpeak_Rules.yaml
index 18e9cd91..92f65e55 100644
--- a/Rules/Languages/fr/ClearSpeak_Rules.yaml
+++ b/Rules/Languages/fr/ClearSpeak_Rules.yaml
@@ -35,15 +35,15 @@
- test:
if: "$Verbosity!='Terse'"
then: [T: "la"] # phrase('the' square root of 25)
+ - T: "racine carrée" # phrase(8 is the 'square root' of 64)
- test:
- if: "$ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd'"
+ - if: "$ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd'"
then:
- bookmark: "*[1]/@id"
- test:
if: "parent::*[self::m:minus and count(*)=1]"
- then: [T: "négatif"] # phrase(minus 4 is a 'negative' number)
- else: [T: "positif"] # phrase(10 is a 'positive' number)
- - T: "racine carrée" # phrase(8 is the 'square root' of 64)
+ then: [T: "négative"] # phrase(minus 4 is a 'negative' number)
+ else: [T: "positive"] # phrase(10 is a 'positive' number)
- test:
if: "$Verbosity!='Terse'"
then: [T: "de"] # phrase(the square root 'of' 5)
@@ -66,16 +66,6 @@
- test:
if: "$Verbosity!='Terse'"
then: [T: "la"] # phrase(6 is 'the' square root of 36)
- - test:
- if: "$ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd'"
- then:
- - test:
- if: "parent::*[(self::m:minus or self::m:plus) and count(*)=1]"
- then: [bookmark: "parent/@id"]
- - test:
- if: "parent::m:minus"
- then: [T: "négatif"] # phrase(minus 6 is a 'negative' number)
- else: [T: "positif"] # phrase(10 is a 'positive' number)
- test:
if: "*[2][self::m:mn and not(contains(., '.'))]"
then_test:
@@ -83,15 +73,25 @@
then: [T: "racine carrée"] # phrase(5 is the 'square root' of 25)
- else_if: "*[2][.='3']"
then: [T: "racine cubique"] # phrase(5 is the 'cube root' of 625)
- - else: [x: "ToOrdinal(*[2])", T: "racine"] # phrase(the square 'root' of 25)
+ - else: [T: "racine", x: "ToOrdinal(*[2])"] # phrase(the square 'root' of 25)
else:
+ - T: "racine" # phrase(the square 'root' of 36)
- test:
if: "*[2][self::m:mi][string-length(.)=1]"
then:
- x: "*[2]"
- pronounce: [text: "-ième", ipa: "jɛm", sapi5: "ieme", eloquence: "ieme"]
else: [x: "*[2]"]
- - T: "racine" # phrase(the square 'root' of 36)
+ - test:
+ if: "$ClearSpeak_Roots = 'PosNegSqRoot' or $ClearSpeak_Roots = 'PosNegSqRootEnd'"
+ then:
+ - test:
+ if: "parent::*[(self::m:minus or self::m:plus) and count(*)=1]"
+ then: [bookmark: "parent/@id"]
+ - test:
+ if: "parent::m:minus"
+ then: [T: "négative"] # phrase(minus 6 is a 'negative' number)
+ else: [T: "positive"] # phrase(10 is a 'positive' number)
- test:
if: "$Verbosity!='Terse'"
then: [T: "de"] # phrase(the square root 'of' 36)
@@ -236,11 +236,11 @@
replace:
- test:
if: "$ClearSpeak_Trig = 'TrigInverse'"
- then: [x: "*[1]", bookmark: "*[2]/@id", T: "l'inverse"] # phrase(8 over 5 is the 'inverse' of 5 over 8)
+ then: [x: "*[1]", bookmark: "*[2]/@id", T: "inverse"] # phrase(8 over 5 is the 'inverse' of 5 over 8)
else_test:
if: "$ClearSpeak_Trig = 'ArcTrig'"
then: [bookmark: "*[2]/@id", T: "arc", x: "*[1]"] # phrase(the 'arc' of a circle)
- else: [bookmark: "*[2]/@id", T: "l'inverse", x: "*[1]"] # default/Auto # phrase(8 over 5 is the 'inverse' of 5 over 8)
+ else: [x: "*[1]", bookmark: "*[2]/@id", T: "inverse"] # default/Auto # phrase(8 over 5 is the 'inverse' of 5 over 8)
- name: function-squared-or-cubed
tag: power
@@ -263,12 +263,17 @@
- test:
if: "$Verbosity!='Terse'"
then: [T: "la"] # phrase('the' third power of 2)
- - bookmark: "*[2]/@id"
- test:
if: "*[2][self::m:mn][not(contains(., '.'))]"
- then: [x: "ToOrdinal(*[2])"]
- else: [x: "*[2]"]
- - T: "puissance de" # phrase(the third 'power of' 6)
+ then:
+ - bookmark: "*[2]/@id"
+ - x: "ToOrdinal(*[2])"
+ - T: "puissance" # phrase(the third 'power' of 6)
+ else:
+ - T: "puissance" # phrase(the third 'power' of 6)
+ - bookmark: "*[2]/@id"
+ - x: "*[2]"
+ - T: "de" # phrase(the third power 'of' 6)
- pause: short
- x: "*[1]"
@@ -279,7 +284,7 @@
- "*[2][self::m:power or self::m:power or self::m:mrow[m:power]]"
replace:
- x: "*[1]"
- - T: "à la puissance de" # phrase(5 'raised to the exponent' x plus 1)
+ - T: "élevé à l'exposant" # phrase(5 'raised to the exponent' x plus 1)
- pause: short
- x: "*[2]"
- pause: short
@@ -290,7 +295,7 @@
match: "$ClearSpeak_Exponents = 'AfterPower'"
replace:
- x: "*[1]"
- - T: "à la puissance de" # phrase(x is 'raised to the power' 4)
+ - T: "élevé à la puissance" # phrase(x is 'raised to the power' 4)
- x: "*[2]"
- pause: short
@@ -312,31 +317,52 @@
- name: simple-integer
tag: power
- match: "*[2][self::m:mn][not(contains(., '.'))]"
+ match: "*[2][self::m:mn][not(contains(., $DecimalSeparators))]"
replace:
- x: "*[1]"
- - T: "à la" # phrase(2 raised 'to the' power 7)
+ - test:
+ if: "$ClearSpeak_Exponents = 'Ordinal' and *[2][.>0]"
+ then: [T: "au"] # phrase(x 'au' deuxième)
+ else: [T: "à la"] # phrase(2 raised 'à la' puissance or deuxième puissance)
- test:
if: "*[2][.>0]"
- then: [x: "ToOrdinal(*[2])"]
- else: [x: "*[2]"]
+ then:
+ - x: "ToOrdinal(*[2])"
+ - test:
+ if: "$ClearSpeak_Exponents != 'Ordinal'"
+ then: [T: "puissance"] # phrase(2 raised to the 'power' 7)
+ else:
+ - test:
+ if: "$ClearSpeak_Exponents != 'Ordinal'"
+ then: [T: "puissance"] # phrase(2 raised to the 'power' 7)
+ - x: "*[2]"
+
+- name: simple-decimal
+ tag: power
+ match: "*[2][self::m:mn][contains(., $DecimalSeparators)]"
+ replace:
+ - x: "*[1]"
- test:
- if: "$ClearSpeak_Exponents != 'Ordinal'"
- then: [T: "puissance"] # phrase(2 raised to the 'power' 7)
+ if: "$ClearSpeak_Exponents = 'AfterPower'"
+ then: [T: "à la puissance de"] # phrase(x 'raised to the power' 5.0)
+ else: [T: "à la puissance"] # phrase(x 'raised to the power' 5.0)
+ - x: "*[2]"
- name: simple-negative-integer
tag: power
match:
- "*[2][self::m:minus and count(*)=1 and "
- - " *[1][self::m:mn][not(contains(., '.'))]"
+ - " *[1][self::m:mn][not(contains(., $DecimalSeparators))]"
- " ]"
replace:
- x: "*[1]"
- - T: "à la" # phrase(2 raised 'to the' power 7)
- - x: "*[2]"
- test:
- if: "$ClearSpeak_Exponents != 'Ordinal'"
- then: [T: "puissance"] # phrase(2 raised to the 'power' 7)
+ - if: "$ClearSpeak_Exponents = 'AfterPower'"
+ then: [T: "élevé à la puissance"] # phrase(3 'raised to the power' negative 2)
+ - else_if: "$ClearSpeak_Exponents = 'Ordinal'"
+ then: [T: "à la"] # phrase(3 'to the' negative 2)
+ else: [T: "à la puissance"] # phrase(3 'to the power' negative 2)
+ - x: "*[2]"
- name: simple-var
tag: power
@@ -373,9 +399,8 @@
- " ]"
replace:
- x: "*[1]"
- - T: "élevé à la" # phrase(x 'raised to the' second power)
+ - T: "élevé à la puissance" # phrase(x 'raised to the' second power)
- x: "*[2]"
- - T: "puissance" # phrase(x raised to the second 'power')
- # - [xxx]^n
name: nested-negative-squared-or-cubed
@@ -394,9 +419,8 @@
- " ]"
replace:
- x: "*[1]"
- - T: "élevé à la" # phrase(x 'raised to the' second power)
+ - T: "élevé à la puissance"
- x: "*[2]"
- - T: "puissance" # phrase(x raised to the second 'power')
- # [xxx] var^n
name: nested-var-squared-or-cubed
@@ -417,9 +441,8 @@
- " ]"
replace:
- x: "*[1]"
- - T: "élevé à la" # phrase(x 'raised to the' second power)
+ - T: "élevé à la puissance"
- x: "*[2]"
- - T: "puissance" # phrase(x raised to the second 'power')
- # -[xxx] var^n
name: nested-negative-var-squared-or-cubed
@@ -442,9 +465,8 @@
- " ]"
replace:
- x: "*[1]"
- - T: "élevé à la" # phrase(x 'raised to the' second power)
+ - T: "élevé à la puissance"
- x: "*[2]"
- - T: "puissance" # phrase(x raised to the second 'power')
- name: default-exponent-power
tag: power
@@ -463,9 +485,8 @@
match: "."
replace:
- x: "*[1]"
- - T: "élevé à la" # phrase(x 'raised to the' second power)
+ - T: "élevé à la puissance" # phrase(x 'raised to the power')
- x: "*[2]"
- - T: "puissance" # phrase(x raised to the second 'power')
#
# Some rules on mrows
@@ -501,14 +522,14 @@
then:
- test:
if: "$Verbosity!='Terse'"
- then: [T: "l'"] # phrase('the' empty set)
- - T: "ensemble vide" # phrase(the 'empty set')
+ then: [T: "l'ensemble vide"] # phrase('the empty set')
+ else: [T: "ensemble vide"] # phrase('empty set')
- else_if: "count(*[1]/*)=3 and *[1]/*[2][self::m:mo][.=':' or .='|' or .='∣']"
then:
- test:
if: "$Verbosity!='Terse'"
- then: [T: "l'"] # phrase('the' set of all integers)
- - T: "ensemble de" # phrase(this is a 'set of' numbers)
+ then: [T: "l'ensemble de"] # phrase('the set of' all integers)
+ else: [T: "ensemble de"] # phrase(this is a 'set of' numbers)
- test:
if: "$ClearSpeak_Sets != 'woAll'"
then: [T: "tous"] # phrase(the set of 'all' integers)
@@ -521,8 +542,8 @@
then:
- test:
if: "$Verbosity!='Terse'"
- then: [T: "l'"] # phrase('the' set of integers)
- - T: "ensemble" # phrase(this is a 'set' of integers)
+ then: [T: "l'ensemble"] # phrase('the set' of integers)
+ else: [T: "ensemble"] # phrase(this is a 'set' of integers)
- x: "*[1]"
- # intervals are controlled by a ClearSpeak Preference -- parens/brackets don't have to match, so we avoid IsBracketed
@@ -536,7 +557,7 @@
tag: [open-interval, open-closed-interval, closed-interval, closed-open-interval]
match: "."
replace:
- - T: "l'invervalle de" # phrase('the interval from' a to b)
+ - T: "l'intervalle de" # phrase('the interval from' a to b)
- x: "*[1]"
- T: "à" # phrase(the interval from a 'to' b)
- x: "*[2]"
@@ -546,8 +567,8 @@
then:
- test:
if: "starts-with(name(.), 'open')"
- then: [T: "sans"] # phrase(the interval from a to b 'not' including b)
- - T: "inclure" # phrase(the interval from a to b not 'including' b)
+ then: [T: "n'incluant pas"] # phrase(the interval from a to b 'not including' b)
+ else: [T: "incluant"] # phrase(the interval from a to b 'including' b)
- x: "*[1]"
# logic to deal with [not] arg #1
- test:
@@ -568,8 +589,8 @@
then:
- test:
if: "name(.) = 'open-interval' or name(.) = 'closed-open-interval'"
- then: [T: "n'"] # phrase(the interval 'not' including a)
- - T: "incluant pas" # phrase(the interval not 'including' a)
+ then: [T: "n'incluant pas"] # phrase(the interval 'not including' a)
+ else: [T: "incluant"] # phrase(the interval 'including' a)
- x: "*[2]"
# onto the [not] [including]... part
@@ -611,7 +632,7 @@
- bookmark: "@id"
- test:
if: "$Verbosity!='Terse' and not(IsNode(following-sibling::*[2],'simple'))"
- then: [T: "la"] # phrase('the' square root of 25)
+ then: [T: "le"] # phrase('the' square root of 25)
- test:
- if: ".='log'"
then: [T: "logarithme"]
@@ -647,8 +668,8 @@
then: [T: "étape"] # phrase(this is the first 'step' of three steps)
# else 'None -- don't say anything'
- test:
- - if: "$LineCount != 1"
- then: [CT: "s"] # plural # phrase(shown by the letter 's')
+ - if: "$LineCount != 1 and not(($ClearSpeak_MultiLineLabel = 'Auto' and self::m:piecewise) or $ClearSpeak_MultiLineLabel = 'Case')"
+ then: [CT: "s"] # plural (but not for 'cas' which is invariable in French)
- pause: short
- x: "*"
- pause: long
diff --git a/Rules/Languages/fr/SharedRules/default.yaml b/Rules/Languages/fr/SharedRules/default.yaml
index f365c0d3..0a92249d 100644
--- a/Rules/Languages/fr/SharedRules/default.yaml
+++ b/Rules/Languages/fr/SharedRules/default.yaml
@@ -477,19 +477,18 @@
- test:
if: ".[ contains(concat(' ', normalize-space(@notation), ' '), ' left ') or contains(concat(' ', normalize-space(@notation), ' '), ' right ') or contains(@notation,'top') or contains(@notation,'bottom') ]"
then:
- - T: "line on" # phrase(draw a straight 'line' on the page)
- test:
if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' left ')]"
- then: [T: "gauche", pause: short] # phrase(line on 'left' of the expression)
+ then: [T: "ligne à gauche", pause: short] # phrase('line on left' of the expression)
- test:
if: ".[contains(concat(' ', normalize-space(@notation), ' '), ' right ')]"
- then: [T: "droite", pause: short] # phrase(line on 'right' of the expression)
+ then: [T: "ligne à droite", pause: short] # phrase('line on right' of the expression)
- test:
if: ".[contains(@notation,'top')]"
- then: [T: "dessus", pause: short] # phrase(line on 'top' of the expression)
+ then: [T: "ligne au dessus", pause: short] # phrase('line on top' of the expression)
- test:
if: ".[contains(@notation,'bottom')]"
- then: [T: "dessous", pause: short] # phrase(line on the 'bottom' of the expression)
+ then: [T: "ligne en dessous", pause: short] # phrase('line on the bottom' of the expression)
- test:
if: ".[ contains(@notation,'updiagonalstrike') or contains(@notation,'downdiagonalstrike') or contains(@notation,'verticalstrike') or contains(@notation,'horizontalstrike') ]"
then:
@@ -509,7 +508,7 @@
- test:
if: ".[contains(@notation,'horizontalstrike')]"
then: [T: "horizontale", pause: short] # phrase(the line is 'horizontal')
- - T: "cross out" # phrase(please 'cross out' the incorrect answer)
+ - T: "barré" # phrase(please 'cross out' the incorrect answer)
- pause: short
- test:
if: ".[contains(@notation,'uparrow')]"
@@ -562,7 +561,7 @@
- test:
if: ".[contains(@notation,'radical')]"
then: [T: "racine carrée", pause: short] # phrase(5 is the 'square root' of 25)
- - T: "enclosing" # phrase(parentheses are 'enclosing' part of the equation)
+ - T: "contenant" # phrase(parentheses are 'enclosing' part of the equation)
- test:
if: "*[self::m:mtext and .=' ']"
then: [T: "espace"] # otherwise there is complete silence # phrase(there is a 'space' between the words)
diff --git a/Rules/Languages/fr/SharedRules/general.yaml b/Rules/Languages/fr/SharedRules/general.yaml
index ac4bf5b7..7c459a16 100644
--- a/Rules/Languages/fr/SharedRules/general.yaml
+++ b/Rules/Languages/fr/SharedRules/general.yaml
@@ -88,7 +88,7 @@
replace:
- x: "*[1]"
- pause: auto
- - T: "évalués à" # phrase(results were 'evaluated at' a given point)
+ - T: "évalué à" # phrase(results were 'evaluated at' a given point)
- pause: auto
- x: "*[2]"
@@ -98,7 +98,7 @@
replace:
- x: "*[1]"
- pause: auto
- - T: "évalués à" # phrase(results were 'evaluated at' this point)
+ - T: "évalué à" # phrase(results were 'evaluated at' this point)
- pause: auto
- x: "*[3]"
- T: "moins la même expression évaluée à" # phrase(this result is 'minus the same expression evaluated at' an earlier point)
diff --git a/Rules/Languages/fr/definitions.yaml b/Rules/Languages/fr/definitions.yaml
index a7f9558e..c2e822d5 100644
--- a/Rules/Languages/fr/definitions.yaml
+++ b/Rules/Languages/fr/definitions.yaml
@@ -293,13 +293,13 @@
]
- NumbersOrdinalOnes: [
- "zéroième", "premier", "deuxième", "troisième", "quatrième", "cinquième", "sixième", "septième", "huitième", "neuvième",
+ "zéroième", "et unième", "deuxième", "troisième", "quatrième", "cinquième", "sixième", "septième", "huitième", "neuvième",
"dixième", "onzième", "douzième", "treizième", "quatorzième", "quinzième", "seizième",
"dix-septième", "dix-huitième", "dix-neuvième"
]
- NumbersOrdinalPluralOnes: [
- "zéroièmes", "premiers", "deuxièmes", "troisièmes", "quatrièmes", "cinquièmes", "sixièmes", "septièmes", "huitièmes", "neuvièmes",
+ "zéroièmes", "et unièmes", "deuxièmes", "troisièmes", "quatrièmes", "cinquièmes", "sixièmes", "septièmes", "huitièmes", "neuvièmes",
"dixièmes", "onzièmes", "douzièmes", "treizièmes", "quatorzièmes", "quinzièmes", "seizièmes",
"dix-septièmes", "dix-huitièmes", "dix-neuvièmes"
]
diff --git a/Rules/Languages/fr/unicode-full.yaml b/Rules/Languages/fr/unicode-full.yaml
index d0f65adb..844f1fe8 100644
--- a/Rules/Languages/fr/unicode-full.yaml
+++ b/Rules/Languages/fr/unicode-full.yaml
@@ -311,7 +311,7 @@
else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn'
if: "count(following-sibling::*) = 0"
then: [t: "et ainsi de suite"] # (en: 'and so on', DeepL translation)
- else: [t: "points de suspension"] # (en: 'and so on up to')
+ else: [t: "et ainsi de suite jusqu'à"] # (en: 'and so on up to')
- "‰": [t: "symbole pour mille"] # 0x2030 (en: 'per mille')
- "‱": [t: "symbole pour dix mille"] # 0x2031 (en: 'per ten thousand')
diff --git a/Rules/Languages/fr/unicode.yaml b/Rules/Languages/fr/unicode.yaml
index b1542a69..b5999380 100644
--- a/Rules/Languages/fr/unicode.yaml
+++ b/Rules/Languages/fr/unicode.yaml
@@ -284,7 +284,7 @@
else_test: # must have $ClearSpeak_Ellipses = 'AndSoOn'
if: "count(following-sibling::*) = 0"
then: [T: "et ainsi de suite"] # (en: 'and so on', DeepL translation)
- else: [T: "points de suspension"] # (en: 'and so on up to')
+ else: [T: "et ainsi de suite jusqu'à"] # (en: 'and so on up to')
- "": # 0x2061
- test:
@@ -364,12 +364,12 @@
if: "../../self::m:set or ../../../self::m:set" # inside a set
then_test:
- if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'In'
- then: [T: "en"] # (en: 'in', DeepL translation)
+ then: [T: "dans"] # (en: 'in', DeepL translation)
- else_if: $ClearSpeak_SetMemberSymbol = 'Member'
then: [T: "membre de"] # (en: 'member of', DeepL translation)
- else_if: $ClearSpeak_SetMemberSymbol = 'Element'
then: [T: "élément de"] # (en: 'element of', DeepL translation)
- - else: [T: "appartient à"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to')
+ - else: [T: "appartenant à"] # $ClearSpeak_SetMemberSymbol = 'Belongs' (en: 'belonging to')
else_test:
- if: $ClearSpeak_SetMemberSymbol = 'Auto' or $ClearSpeak_SetMemberSymbol = 'Member'
then: [T: "est membre de"] # (en: 'is a member of', DeepL translation)
diff --git a/tests/Languages/fr.rs b/tests/Languages/fr.rs
index eadb0d41..059ef9d8 100644
--- a/tests/Languages/fr.rs
+++ b/tests/Languages/fr.rs
@@ -1,5 +1,17 @@
#![allow(non_snake_case)]
+mod ClearSpeak {
+ mod functions;
+ mod large_ops;
+ mod menclose;
+ mod mfrac;
+ mod mroot;
+ mod msup;
+ mod multiline;
+ mod sets;
+ mod symbols_and_adornments;
+}
+
mod SimpleSpeak {
mod functions;
mod geometry;
diff --git a/tests/Languages/fr/ClearSpeak/functions.rs b/tests/Languages/fr/ClearSpeak/functions.rs
new file mode 100644
index 00000000..58495983
--- /dev/null
+++ b/tests/Languages/fr/ClearSpeak/functions.rs
@@ -0,0 +1,566 @@
+/// Tests for:
+/// * functions including trig functions, logs, and functions to powers
+/// * implied times/functional call and explicit times/function call
+/// * parens
+/// These are all intertwined, so they are in one file
+use crate::common::*;
+use anyhow::Result;
+
+#[test]
+fn trig_names() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "sinus x plus cosinus y plus tangente z plus sécante alpha, plus cosécante phi, plus cotangente phi")?;
+ return Ok(());
+
+}
+
+#[test]
+fn hyperbolic_trig_names() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "sinus hyperbolique de x, plus \
+ cosinus hyperbolique de y, plus \
+ tangente hyperbolique de z, plus, \
+ sécante hyperbolique de alpha, plus, \
+ cosécante hyperbolique de phi, plus, \
+ cotangente hyperbolique de phi")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn inverse_trig() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "sinus inverse de x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn inverse_trig_trig_inverse() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Trig", "TrigInverse",expr,
+ "tangente inverse de x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn inverse_trig_arc() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Trig", "ArcTrig",expr,
+ "arc cosinus hyperbolique de x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn trig_squared() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "sinus au carré de x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn trig_cubed() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "tangente au cube de x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn trig_fourth() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "la quatrième puissance de, sécante de x")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn trig_power_other() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "la puissance n moins 1 de, sinus hyperbolique de x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn simple_log() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "logarithme x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn normal_log() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "le logarithme de, parenthèse gauche, x plus y, parenthèse droite")?;
+ return Ok(());
+
+}
+
+#[test]
+fn simple_log_with_base() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "le log en base b, de x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn normal_log_with_base() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "le log en base b, de, parenthèse gauche, x plus y, parenthèse droite")?;
+ return Ok(());
+
+}
+
+#[test]
+fn simple_ln() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "l n x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn normal_ln() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "le l n de, parenthèse gauche, x plus y, parenthèse droite")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn simple_natural_log() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Log", "LnAsNaturalLog",expr,
+ "logarithme naturel x")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn natural_log() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Log", "LnAsNaturalLog",expr,
+ "le logarithme naturel de, parenthèse gauche, x plus y, parenthèse droite")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn explicit_function_call_with_parens() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "t de x")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn explicit_times_with_parens() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "t fois x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn explicit_function_call() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "t de x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn explicit_times() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "t x")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn test_functions_none_pref() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Functions", "None",expr,
+ "le logarithme de, parenthèse gauche, x plus y, parenthèse droite; plus; f fois, parenthèse gauche, x plus y, parenthèse droite")?;
+ return Ok(());
+
+}
+
+#[test]
+fn test_functions_none_pref_multiple_args() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Functions", "None",expr,
+ "b majuscule fois, parenthèse gauche, 2 virgule, 6, parenthèse droite")?;
+ return Ok(());
+
+}
+
+
+/*
+ * Tests for times
+ */
+#[test]
+fn no_times_binomial() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "x y")?;
+ return Ok(());
+
+}
+
+#[test]
+fn times_following_paren() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "2 fois 3")?;
+ return Ok(());
+
+}
+
+#[test]
+fn times_preceding_paren() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "2 fois 3")?;
+ return Ok(());
+
+}
+
+#[test]
+fn times_sqrt() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "la racine carrée de a; fois la racine carrée de b; est égal à, la racine carrée de a b")?;
+ return Ok(());
+
+}
+
+#[test]
+fn more_implied_times() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_ImpliedTimes", "MoreImpliedTimes",expr,
+ "parenthèse gauche, 2 fois x, parenthèse droite au carré")?;
+ return Ok(());
+
+}
+
+#[test]
+fn explicit_times_more_implied_times() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_ImpliedTimes", "MoreImpliedTimes",expr, "t fois x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn explicit_times_none_simple_right() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_ImpliedTimes", "None",
+ expr, "2, crochet ouvrant 3 crochet fermant")?;
+ return Ok(());
+
+}
+
+#[test]
+fn explicit_times_none_simple_left() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_ImpliedTimes", "None",
+ expr, "parenthèse gauche, 2 moins 1, parenthèse droite; x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn explicit_times_none_superscript() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak_prefs("fr",
+ vec![("ClearSpeak_ImpliedTimes", "None"), ("ClearSpeak_Functions", "None")],
+ expr, "f, parenthèse gauche x parenthèse droite; est égal à; x au carré, parenthèse gauche, x plus 1, parenthèse droite")?;
+ return Ok(());
+
+}
+
+/*
+ * Tests for parens
+ */
+ #[test]
+ fn no_parens_number() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "25 fois x")?;
+ return Ok(());
+
+ }
+
+ #[test]
+ fn no_parens_monomial() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "b, parenthèse gauche, x y parenthèse droite")?;
+ return Ok(());
+
+ }
+
+ #[test]
+ fn no_parens_negative_number() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "2 plus moins 2")?;
+ return Ok(());
+
+ }
+
+
+ #[test]
+ fn no_parens_negative_number_with_var() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "moins 2 x plus 1")?;
+ return Ok(());
+
+ }
+
+ #[test]
+ fn parens_superscript() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "parenthèse gauche, 2 x parenthèse droite au carré")?;
+ return Ok(());
+
+ }
+
+ #[test]
+ fn no_parens_fraction() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "2 plus 1 demi")?;
+ return Ok(());
+
+ }
+
+
+ // Tests for the ten types of intervals in ClearSpeak
+ #[test]
+ fn parens_interval_open_open() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Paren", "Interval",expr,
+ "l'intervalle de c à d, n'incluant pas c ou d")?;
+ return Ok(());
+
+}
+
+#[test]
+ fn parens_interval_closed_open() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Paren", "Interval ",expr,
+ "l'intervalle de c à d, incluant c mais n'incluant pas d")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn parens_interval_open_closed() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Paren", "Interval ",expr,
+ "l'intervalle de c à d, n'incluant pas c mais incluant d")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn parens_interval_closed_closed() -> Result<()> {
+ let expr = "";
+test_ClearSpeak("fr", "ClearSpeak_Paren", "Interval ",expr,
+"l'intervalle de c à d, incluant c et d")?;
+return Ok(());
+
+}
+
+ #[test]
+ fn parens_interval_neg_infinity_open_open() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Paren", "Interval ",expr,
+ "l'intervalle de moins infini à d, n'incluant pas d")?;
+ return Ok(());
+
+}
+
+ #[test]
+ fn parens_interval_neg_infinity_closed_open() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Paren", "Interval ",expr,
+ "l'intervalle de moins infini à d, incluant d")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn parens_interval_open_open_infinity() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Paren", "Interval ",expr,
+ "l'intervalle de c à infini, n'incluant pas c")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn parens_interval_closed_open_infinity() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Paren", "Interval ",expr,
+"l'intervalle de c à infini, incluant c")?;
+return Ok(());
+
+}
+
+#[test]
+fn parens_interval_neg_infinity_to_infinity() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Paren", "Interval ",expr,
+ "l'intervalle de moins infini à infini")?;
+ return Ok(());
+
+}
+
+#[test]
+fn parens_interval_neg_infinity_to_pos_infinity() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Paren", "Interval ",expr,
+ "l'intervalle de moins infini à plus infini")?;
+ return Ok(());
+
+}
diff --git a/tests/Languages/fr/ClearSpeak/large_ops.rs b/tests/Languages/fr/ClearSpeak/large_ops.rs
new file mode 100644
index 00000000..3d262a00
--- /dev/null
+++ b/tests/Languages/fr/ClearSpeak/large_ops.rs
@@ -0,0 +1,235 @@
+use crate::common::*;
+use anyhow::Result;
+
+#[test]
+fn sum_both() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "la sommation de n est égal à 1, à 10 de n")?;
+ return Ok(());
+
+}
+
+#[test]
+fn sum_under() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "la sommation sur s majuscule de i")?;
+ return Ok(());
+
+}
+#[test]
+fn sum_both_msubsup() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "la sommation de n est égal à 1, à 10 de n")?;
+ return Ok(());
+
+}
+
+#[test]
+fn sum_sub() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "la sommation sur s majuscule de i")?;
+ return Ok(());
+
+}
+
+#[test]
+fn sum() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "la sommation de a indice i")?;
+ return Ok(());
+
+}
+
+#[test]
+fn product_both() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "le produit de n est égal à 1, à 10 de n")?;
+ return Ok(());
+
+}
+
+#[test]
+fn product_under() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "le produit sur s majuscule de i")?;
+ return Ok(());
+
+}
+
+#[test]
+fn product() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "le produit de a indice i")?;
+ return Ok(());
+
+}
+
+#[test]
+fn intersection_both() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "l'intersection de i est égal à 1, à 10 de; s majuscule indice i")?;
+ return Ok(());
+
+}
+
+#[test]
+fn intersection_under() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "l'intersection sur c majuscule de; s majuscule indice i")?;
+ return Ok(());
+
+}
+
+#[test]
+fn intersection() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "l'intersection de s majuscule indice i")?;
+ return Ok(());
+
+}
+
+#[test]
+fn union_both() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "l'union de i est égal à 1, à 10 de; s majuscule indice i")?;
+ return Ok(());
+
+}
+
+#[test]
+fn union_under() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "l'union sur c majuscule de, s majuscule indice i")?;
+ return Ok(());
+
+}
+
+#[test]
+fn union() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "l'union de s majuscule indice i")?;
+ return Ok(());
+
+}
+
+#[test]
+fn integral_both() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "l'intégrale de 0, à 1 de, f de x; d x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn integral_under() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "l'intégrale sur les nombres réels de; f de x d x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn integral() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "l'intégrale de f de x d x")?;
+ return Ok(());
+
+}
\ No newline at end of file
diff --git a/tests/Languages/fr/ClearSpeak/menclose.rs b/tests/Languages/fr/ClearSpeak/menclose.rs
new file mode 100644
index 00000000..e131440f
--- /dev/null
+++ b/tests/Languages/fr/ClearSpeak/menclose.rs
@@ -0,0 +1,242 @@
+use crate::common::*;
+use anyhow::Result;
+
+#[test]
+fn menclose_actuarial() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "symbole actuariel, contenant 3 plus 2 i fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_box() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "case, rond, contenant 3 plus 2 i fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_left() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "ligne à gauche, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_right() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "ligne à droite, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_top_bottom() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "ligne au dessus, ligne en dessous, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_updiagonalstrike() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "diagonale vers le haut, barré, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_downdiagonalstrike() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "diagonale vers le bas, barré, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_cross_out() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "x, barré, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_vertical_horizontal_strike() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "verticale, horizontale, barré, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_leftarrow() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "flèche vers la gauche, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_right_up_down_arrow() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "flèche vers le haut, flèche vers le bas, flèche vers la droite, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_northeastarrow() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "flèche nord-est, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_other_single_arrows() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "flèche sud-est, flèche sud-ouest, flèche nord-ouest, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_northwestsoutheastarrow() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "flèche diagonale vers le bas à double extrémité, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_other_double_arrows() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "flèche verticale à double extrémité, flèche horizontale à double extrémité, flèche diagonale vers le haut à double extrémité, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_madrub() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "symbole factoriel arabe, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_phasorangle() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "angle de phaseur, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_circle_phasorangle() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "rond, angle de phaseur, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_longdiv() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "symbole de division longue, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_longdiv_default() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "symbole de division longue, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_longdiv_empty_string() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "symbole de division longue, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_longdiv_whitespace_string() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "symbole de division longue, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn menclose_radical() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "racine carrée, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
+
+#[test]
+fn simple_speak_menclose_top_bottom() -> Result<()> {
+ let expr = "";
+ test("fr", "SimpleSpeak", expr, "ligne au dessus, ligne en dessous, contenant 3 demis fin d'encadrement")?;
+ return Ok(());
+
+}
diff --git a/tests/Languages/fr/ClearSpeak/mfrac.rs b/tests/Languages/fr/ClearSpeak/mfrac.rs
new file mode 100644
index 00000000..fdaf1218
--- /dev/null
+++ b/tests/Languages/fr/ClearSpeak/mfrac.rs
@@ -0,0 +1,313 @@
+/// Tests for fractions
+/// includes simple fractions and more complex fractions
+/// also tests mixed fractions (implicit and explicit)
+use crate::common::*;
+use anyhow::Result;
+
+#[test]
+fn common_fraction_half() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "1 demi")?;
+ return Ok(());
+
+}
+
+#[test]
+fn common_fraction_thirds() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "2 tiers")?;
+ return Ok(());
+
+}
+
+#[test]
+fn common_fraction_tenths() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, "17 dixièmes")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Ordinal")], expr, "17 dixièmes")?;
+ return Ok(());
+
+}
+
+#[test]
+#[allow(non_snake_case)]
+fn not_ClearSpeak_common_fraction_tenths() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, "89 sur 10")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Ordinal")], expr, "89 dixièmes")?;
+ return Ok(());
+
+}
+
+#[test]
+fn non_simple_fraction() -> Result<()> {
+ let expr = "
+ ";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, "la fraction avec numérateur; x plus y; et dénominateur x moins y")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Ordinal")], expr, "la fraction avec numérateur; x plus y; et dénominateur x moins y")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Over")], expr, "x plus y sur x moins y")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "FracOver")], expr, "la fraction x plus y sur x moins y")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "General")], expr, "la fraction avec numérateur; x plus y; et dénominateur x moins y")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "EndFrac")], expr, "la fraction avec numérateur; x plus y; et dénominateur x moins y; fin de fraction")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "GeneralEndFrac")], expr, "la fraction avec numérateur; x plus y; et dénominateur x moins y; fin de fraction")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "OverEndFrac")], expr, "x plus y sur x moins y, fin de fraction")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Per")], expr, "x plus y par x moins y")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Verbose"),("ClearSpeak_Fractions", "Auto")], expr, "la fraction avec numérateur; x plus y; et dénominateur x moins y; fin de fraction")?;
+ return Ok(());
+
+}
+
+#[test]
+fn frac_with_units() -> Result<()> {
+ let expr = "
+ ";
+ test("fr", "ClearSpeak", expr, "62 milles par heure")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn mixed_number() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "3 et 1 demi")?;
+ return Ok(());
+
+}
+
+#[test]
+fn explicit_mixed_number() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "3 et 1 huitième")?;
+ return Ok(());
+
+}
+
+#[test]
+fn mixed_number_big() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "3 et 7 sur 83")?;
+ return Ok(());
+
+}
+
+#[test]
+fn simple_text() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "rise sur run")?;
+ return Ok(());
+
+}
+
+#[test]
+fn number_and_text() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "2 miles sur 3 gallons")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn nested_simple_fractions() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("ClearSpeak_Fractions", "Auto")], expr, "1 demi sur 2 tiers")?;
+ test_prefs("fr", "ClearSpeak", vec![("ClearSpeak_Fractions", "Ordinal")], expr, "1 demi sur 2 tiers")?;
+ test_prefs("fr", "ClearSpeak", vec![("ClearSpeak_Fractions", "Over")], expr, "1 sur 2 sur 2 sur 3")?;
+ test_prefs("fr", "ClearSpeak", vec![("ClearSpeak_Fractions", "FracOver")], expr,
+ "la fraction la fraction 1 sur 2 sur la fraction 2 sur 3")?;
+ test_prefs("fr", "ClearSpeak", vec![("ClearSpeak_Fractions", "General")], expr,
+ "la fraction avec numérateur la fraction avec numérateur 1; et dénominateur 2; et dénominateur la fraction avec numérateur 2; et dénominateur 3")?;
+ test_prefs("fr", "ClearSpeak", vec![("ClearSpeak_Fractions", "EndFrac")], expr, "1 demi sur 2 tiers")?;
+ test_prefs("fr", "ClearSpeak", vec![("ClearSpeak_Fractions", "GeneralEndFrac")], expr,
+ "la fraction avec numérateur la fraction avec numérateur 1; et dénominateur 2; fin de fraction; et dénominateur la fraction avec numérateur 2; et dénominateur 3; fin de fraction; fin de fraction")?;
+ test_prefs("fr", "ClearSpeak", vec![("ClearSpeak_Fractions", "OverEndFrac")], expr,
+ "1 sur 2, fin de fraction, sur 2 sur 3, fin de fraction; fin de fraction")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn semi_nested_fraction() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "2 tiers x sur 6")?;
+ return Ok(());
+
+}
+
+#[test]
+fn general_nested_fraction() -> Result<()> {
+ let expr = "
+
+ ";
+ test("fr", "ClearSpeak", expr, "la fraction avec numérateur; 10 sur n; et dénominateur 2 sur n")?;
+ return Ok(());
+
+}
+
+#[test]
+fn complex_nested_fraction() -> Result<()> {
+ let expr = "
+
+ ";
+ test("fr", "ClearSpeak", expr, "la fraction avec numérateur; la fraction avec numérateur; n plus 10; et dénominateur n; et dénominateur 2 sur n")?;
+ return Ok(());
+
+}
+
+#[test]
+fn simple_function() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, "f de x sur 2")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Verbose"), ("ClearSpeak_Fractions", "Auto")], expr, "f de x sur 2, fin de fraction")?;
+ return Ok(());
+
+}
+
+#[test]
+fn function_over_function() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr, "f de x sur g de x")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Verbose"), ("ClearSpeak_Fractions", "Auto")], expr, "f de x sur g de x, fin de fraction")?;
+ return Ok(());
+
+}
+
+#[test]
+fn non_simple_function_over_function() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Fractions", "Auto")], expr,
+ "la fraction avec numérateur; f de, parenthèse gauche, x plus 1, parenthèse droite; et dénominateur g de x")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Verbose"), ("ClearSpeak_Fractions", "Auto")], expr,
+ "la fraction avec numérateur; f de, parenthèse gauche, x plus 1, parenthèse droite; et dénominateur g de x; fin de fraction")?;
+ return Ok(());
+
+}
+
+#[test]
+fn binomial() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "2 fois 7 parmi 3")?;
+ return Ok(());
+
+}
diff --git a/tests/Languages/fr/ClearSpeak/mroot.rs b/tests/Languages/fr/ClearSpeak/mroot.rs
new file mode 100644
index 00000000..df2209fe
--- /dev/null
+++ b/tests/Languages/fr/ClearSpeak/mroot.rs
@@ -0,0 +1,163 @@
+use crate::common::*;
+use anyhow::Result;
+
+#[test]
+fn msqrt_simple() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "la racine carrée de x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn msqrt_simple_end_root() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Roots", "RootEnd", expr, "la racine carrée de x, fin de racine")?;
+ return Ok(());
+
+}
+
+#[test]
+fn msqrt_simple_positive() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Roots", "PosNegSqRoot", expr, "la racine carrée positive de x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn msqrt_simple_pos_end_root() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Roots", "PosNegSqRootEnd", expr, "la racine carrée positive de x, fin de racine")?;
+ return Ok(());
+
+}
+
+#[test]
+fn msqrt_simple_pos_end_with_neg_root() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Roots", "PosNegSqRootEnd", expr,
+ "la racine carrée négative de x, fin de racine; moins, la racine cubique positive de x, fin de racine")?;
+ return Ok(());
+
+}
+
+#[test]
+fn mroot_simple_pos_end_with_neg_root() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Roots", "PosNegSqRoot", expr,
+ "la racine cubique négative de x; moins la racine carrée positive de x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn neg_without_root() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "moins x moins y")?;
+ return Ok(());
+
+}
+
+#[test]
+fn msqrt() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "la racine carrée de x plus y")?;
+ return Ok(());
+
+}
+
+#[test]
+fn mroot_as_square_root() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "la racine carrée de x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn cube_root() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "la racine cubique de x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn ordinal_root() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "la racine neuvième de x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn simple_mi_root() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "la racine n-ième de x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn mroot_simple_pos_end_root() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Roots", "PosNegSqRootEnd", expr, "la racine t-ième positive de x, fin de racine")?;
+ return Ok(());
+
+}
+
+#[test]
+fn mroot_simple_end_root() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Roots", "RootEnd", expr, "la racine vingt et unième de x plus y, fin de racine")?;
+ return Ok(());
+
+}
+
+#[test]
+fn simple_fraction_power() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "la racine 1 tiers de x")?;
+ return Ok(());
+
+}
diff --git a/tests/Languages/fr/ClearSpeak/msup.rs b/tests/Languages/fr/ClearSpeak/msup.rs
new file mode 100644
index 00000000..9ed84738
--- /dev/null
+++ b/tests/Languages/fr/ClearSpeak/msup.rs
@@ -0,0 +1,382 @@
+/// Tests for superscripts
+/// simple superscripts
+/// complex/nested superscripts
+use crate::common::*;
+use anyhow::Result;
+
+#[test]
+fn squared() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "x au carré")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "x au deuxième")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "x à la deuxième puissance")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "x élevé à la puissance 2")?;
+
+ return Ok(());
+
+}
+
+#[test]
+fn cubed() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "x au cube")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "x au troisième")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "x à la troisième puissance")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "x élevé à la puissance 3")?;
+ return Ok(());
+
+}
+
+#[test]
+fn ordinal_power() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 à la cinquième puissance")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 au cinquième")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 à la cinquième puissance")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 élevé à la puissance 5")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn zero_power() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 à la puissance 0")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 à la 0")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 à la puissance 0")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 élevé à la puissance 0")?;
+ return Ok(());
+
+}
+
+#[test]
+fn simple_mi_power() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "4 à la x-ième puissance")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "4 à la x-ième")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "4 à la x-ième puissance")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "4 élevé à la puissance x")?;
+ return Ok(());
+
+}
+
+#[test]
+fn decimal_power() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 à la puissance 5,0")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 à la puissance 5,0")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 à la puissance 5,0")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 élevé à la puissance 5,0")?;
+ return Ok(());
+
+}
+
+#[test]
+fn non_simple_power() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 élevé à la puissance y plus 2")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 élevé à la puissance y plus 2")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 élevé à la puissance y plus 2")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 élevé à la puissance y plus 2")?;
+ return Ok(());
+
+}
+
+#[test]
+fn negative_power() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 à la puissance moins 2")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 à la moins 2")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 à la puissance moins 2")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 élevé à la puissance moins 2")?;
+ return Ok(());
+
+}
+
+#[test]
+fn simple_fraction_power() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "x élevé à la puissance 1 tiers")?;
+ return Ok(());
+
+}
+
+#[test]
+fn nested_squared_power_with_coef() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 élevé à la puissance 2 x au carré")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 élevé à l'exposant, 2 x au deuxième, fin de l'exposant")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 élevé à l'exposant, 2 x à la deuxième puissance, fin de l'exposant")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 élevé à l'exposant, 2 x élevé à la puissance 2; fin de l'exposant")?;
+
+ return Ok(());
+
+}
+
+#[test]
+fn nested_squared_power_with_neg_coef() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "3 élevé à la puissance moins 2 x au carré")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn nested_cubed_power() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "y élevé à la puissance 4 cinquièmes au cube")?;
+ return Ok(());
+
+}
+
+#[test]
+fn nested_cubed_power_with_neg_base() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "y élevé à la puissance moins 4 cinquièmes au cube")?;
+ return Ok(());
+
+}
+
+#[test]
+fn nested_number_times_squared() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "e élevé à la puissance 1 demi x au carré")?;
+ return Ok(());
+
+}
+
+#[test]
+fn nested_negative_number_times_squared() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "e élevé à la puissance moins 1 demi x au carré")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "e élevé à l'exposant, moins 1 demi x au deuxième, fin de l'exposant")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "e élevé à l'exposant, moins 1 demi x à la deuxième puissance, fin de l'exposant")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "e élevé à l'exposant, moins 1 demi x élevé à la puissance 2; fin de l'exposant")?;
+ return Ok(());
+
+}
+
+#[test]
+fn nested_expr_to_tenth() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 élevé à l'exposant, 3 à la dixième puissance, fin de l'exposant")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 élevé à l'exposant, 3 au dixième, fin de l'exposant")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 élevé à l'exposant, 3 à la dixième puissance, fin de l'exposant")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 élevé à l'exposant, 3 élevé à la puissance 10; fin de l'exposant")?;
+
+ return Ok(());
+
+}
+
+#[test]
+fn nested_non_simple_squared_exp() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr, "3 élevé à l'exposant, parenthèse gauche, x plus 1, parenthèse droite au carré, fin de l'exposant")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr, "3 élevé à l'exposant, parenthèse gauche, x plus 1, parenthèse droite au deuxième, fin de l'exposant")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr, "3 élevé à l'exposant, parenthèse gauche, x plus 1, parenthèse droite à la deuxième puissance, fin de l'exposant")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr, "3 élevé à l'exposant, parenthèse gauche, x plus 1, parenthèse droite élevé à la puissance 2; fin de l'exposant")?;
+ return Ok(());
+
+}
+
+#[test]
+fn nested_default_power() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "t élevé à l'exposant, 4 cinquièmes à la n-ième puissance, fin de l'exposant")?;
+ return Ok(());
+
+}
+
+#[test]
+fn nested_complex_power() -> Result<()> {
+ let expr = "";
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Auto")], expr,
+ "e élevé à l'exposant, moins 1 demi fois; parenthèse gauche; la fraction avec numérateur; x moins mû; et dénominateur sigma; parenthèse droite au carré, fin de l'exposant")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "Ordinal")], expr,
+ "e élevé à l'exposant, moins 1 demi fois; parenthèse gauche; la fraction avec numérateur; x moins mû; et dénominateur sigma; parenthèse droite au deuxième, fin de l'exposant")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "OrdinalPower")], expr,
+ "e élevé à l'exposant, moins 1 demi fois; parenthèse gauche; la fraction avec numérateur; x moins mû; et dénominateur sigma; parenthèse droite à la deuxième puissance, fin de l'exposant")?;
+ test_prefs("fr", "ClearSpeak", vec![("Verbosity", "Medium"), ("ClearSpeak_Exponents", "AfterPower")], expr,
+ "e élevé à l'exposant, moins 1 demi fois; parenthèse gauche; la fraction avec numérateur; x moins mû; et dénominateur sigma; parenthèse droite élevé à la puissance 2; fin de l'exposant")?;
+ return Ok(());
+
+}
+
+#[test]
+fn default_power() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "t élevé à la puissance la fraction avec numérateur; b plus 1; et dénominateur 3")?;
+ return Ok(());
+
+}
diff --git a/tests/Languages/fr/ClearSpeak/multiline.rs b/tests/Languages/fr/ClearSpeak/multiline.rs
new file mode 100644
index 00000000..bbe7af46
--- /dev/null
+++ b/tests/Languages/fr/ClearSpeak/multiline.rs
@@ -0,0 +1,192 @@
+use crate::common::*;
+use anyhow::Result;
+
+
+#[test]
+fn case_1() -> Result<()> {
+ let expr = "
+ ";
+ test_ClearSpeak("fr", "ClearSpeak_MultiLineLabel", "Auto", expr,
+ "f de x est égal à; 3 cas; \
+ cas 1; moins 1 si x est inférieur à 0; \
+ cas 2; 0 si x est égal à 0; \
+ cas 3; 1 si x est supérieur à 0"
+ )?;
+ return Ok(());
+}
+
+#[test]
+fn equation_auto() -> Result<()> {
+ let expr = "
+ ";
+ test_ClearSpeak("fr", "ClearSpeak_MultiLineLabel", "Auto", expr,
+ "2 lignes; \
+ ligne 1; x plus y, est égal à 7; \
+ ligne 2; 2 x plus 3 y; est égal à 17")?;
+ return Ok(());
+}
+
+
+#[test]
+fn equation_plus_at_start() -> Result<()> {
+ let expr = "
+ ";
+ test_ClearSpeak("fr", "ClearSpeak_MultiLineLabel", "Auto", expr, "2 lignes; \
+ ligne 1; x plus y est égal à 7; \
+ ligne 2; 2 x, plus 3 y, est égal à 17")?;
+ return Ok(());
+}
+
+#[test]
+fn equation_case() -> Result<()> {
+ let expr = "
+ ";
+ test_ClearSpeak("fr", "ClearSpeak_MultiLineLabel", "Case", expr,
+ "2 cas; cas 1; x plus y, est égal à 7; cas 2; 2 x plus 3 y; est égal à 17")?;
+ return Ok(());
+}
+
+#[test]
+fn equation_constraint() -> Result<()> {
+ let expr = "
+ ";
+ test_ClearSpeak("fr", "ClearSpeak_MultiLineLabel", "Constraint", expr, "2 contraintes; \
+ contrainte 1; x plus y, est égal à 7; \
+ contrainte 2; 2 x plus 3 y; est égal à 17")?;
+ return Ok(());
+}
+
+#[test]
+fn equation_equation() -> Result<()> {
+ let expr = "
+ ";
+ test_ClearSpeak("fr", "ClearSpeak_MultiLineLabel", "Equation", expr, "2 équations; \
+ équation 1; x plus y, est égal à 7; \
+ équation 2; 2 x plus 3 y; est égal à 17")?;
+ return Ok(());
+}
+
+#[test]
+fn equation_line() -> Result<()> {
+ let expr = "
+ ";
+ test_ClearSpeak("fr", "ClearSpeak_MultiLineLabel", "Line", expr, "2 lignes; \
+ ligne 1; x plus y, est égal à 7; \
+ ligne 2; 2 x plus 3 y; est égal à 17")?;
+ return Ok(());
+}
+
+#[test]
+fn equation_none() -> Result<()> {
+ let expr = "
+ ";
+ test_ClearSpeak("fr", "ClearSpeak_MultiLineLabel", "None", expr,
+ "2 lignes; \
+ x plus y, est égal à 7; \
+ 2 x plus 3 y; est égal à 17")?;
+ return Ok(());
+}
+
+#[test]
+fn equation_row() -> Result<()> {
+ let expr = "
+ ";
+ test_ClearSpeak("fr", "ClearSpeak_MultiLineLabel", "Row", expr, "2 rangées; \
+ rangée 1; x plus y, est égal à 7; \
+ rangée 2; 2 x plus 3 y; est égal à 17")?;
+ return Ok(());
+}
+
+#[test]
+fn equation_step() -> Result<()> {
+ let expr = "
+ ";
+ test_ClearSpeak("fr", "ClearSpeak_MultiLineLabel", "Step", expr, "2 étapes; \
+ étape 1; x plus y, est égal à 7; \
+ étape 2; 2 x plus 3 y; est égal à 17")?;
+ return Ok(());
+}
+
+#[test]
+fn continued_row() -> Result<()> {
+ let expr = "";
+test("fr", "SimpleSpeak", expr,
+ "2 équations; équation 1; x est égal à y plus 1; équation 2; y est égal à 1")?;
+ return Ok(());
+}
diff --git a/tests/Languages/fr/ClearSpeak/sets.rs b/tests/Languages/fr/ClearSpeak/sets.rs
new file mode 100644
index 00000000..4b180c1b
--- /dev/null
+++ b/tests/Languages/fr/ClearSpeak/sets.rs
@@ -0,0 +1,531 @@
+use crate::common::*;
+use anyhow::Result;
+
+#[test]
+fn complex() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "les nombres complexes")?;
+ return Ok(());
+
+}
+
+#[test]
+fn natural() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "les nombres naturels")?;
+ return Ok(());
+
+}
+
+#[test]
+fn rationals() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "les nombres rationnels")?;
+ return Ok(());
+
+}
+
+#[test]
+fn reals() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "les nombres réels")?;
+ return Ok(());
+
+}
+
+#[test]
+fn integers() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "les nombres entiers")?;
+ return Ok(());
+
+}
+
+
+
+#[test]
+fn msup_complex() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "C 2")?;
+ return Ok(());
+
+}
+
+#[test]
+fn msup_natural() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "N 2")?;
+ return Ok(());
+
+}
+
+#[test]
+fn msup_rationals() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "Q 2")?;
+ return Ok(());
+
+}
+
+#[test]
+fn msup_reals() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "R 3")?;
+ return Ok(());
+
+}
+
+#[test]
+fn msup_integers() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "Z 4")?;
+ return Ok(());
+
+}
+
+#[test]
+fn msup_positive_integers() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "les nombres entiers positifs")?;
+ return Ok(());
+
+}
+
+#[test]
+fn msup_negative_integers() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "les nombres entiers négatifs")?;
+ return Ok(());
+
+}
+
+#[test]
+fn msup_positive_rationals() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "les nombres rationnels positifs")?;
+ return Ok(());
+
+}
+
+#[test]
+fn msup_negative_rationals() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "les nombres rationnels négatifs")?;
+ return Ok(());
+
+}
+
+#[test]
+fn empty_set() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "l'ensemble vide")?;
+ return Ok(());
+
+}
+
+#[test]
+fn single_element_set() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "l'ensemble 12")?;
+ return Ok(());
+
+}
+
+#[test]
+fn multiple_element_set() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "l'ensemble 5 virgule, 10 virgule, 15")?;
+ return Ok(());
+
+}
+
+#[test]
+fn set_with_colon() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "l'ensemble de tous x tel que x est supérieur à 2")?;
+ return Ok(());
+
+}
+
+#[test]
+fn set_with_bar() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "l'ensemble de tous x tel que x est supérieur à 2")?;
+ return Ok(());
+
+}
+
+#[test]
+fn element_alone() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "3 plus 2 i, n'est pas membre de, les nombres réels")?;
+ return Ok(());
+
+}
+
+#[test]
+fn element_under_sum() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr,
+ "la sommation sur i est membre de les nombres entiers de; la fraction avec numérateur 1; et dénominateur i au carré")?;
+ return Ok(());
+
+}
+
+#[test]
+fn complicated_set_with_colon() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "l'ensemble de tous x dans les nombres entiers tel que 2 est inférieur à x est inférieur à 7")?;
+ return Ok(());
+
+}
+
+#[test]
+fn complicated_set_with_mtext() -> Result<()> {
+ // as of 8/5/21, parsing of "|" is problematic in the example, so are needed for this test
+ let expr = "";
+ test("fr", "ClearSpeak", expr,
+ "l'ensemble de tous x dans les nombres naturels tel que x est un nombre pair")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn set_with_bar_member() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_SetMemberSymbol", "Member",
+ expr, "l'ensemble de tous x membre de les nombres entiers tel que x est supérieur à 5")?;
+ return Ok(());
+
+}
+
+#[test]
+fn element_alone_member() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_SetMemberSymbol", "Member",
+ expr, "3 plus 2 i, n'est pas membre de, les nombres réels")?;
+ return Ok(());
+
+}
+
+#[test]
+fn element_under_sum_member() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_SetMemberSymbol", "Member",
+ expr, "la sommation sur i est membre de les nombres entiers de; la fraction avec numérateur 1; et dénominateur i au carré")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn set_with_bar_element() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_SetMemberSymbol", "Element",
+ expr, "l'ensemble de tous x élément de les nombres entiers tel que x est supérieur à 5")?;
+ return Ok(());
+
+}
+
+#[test]
+fn element_alone_element() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_SetMemberSymbol", "Element",
+ expr, "3 plus 2 i, n'est pas un élément de, les nombres réels")?;
+ return Ok(());
+
+}
+
+#[test]
+fn element_under_sum_element() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_SetMemberSymbol", "Element",
+ expr, "la sommation sur i est un élément de, les nombres entiers de; la fraction avec numérateur 1; et dénominateur i au carré")?;
+ return Ok(());
+
+}
+
+#[test]
+fn set_with_bar_in() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_SetMemberSymbol", "In",
+ expr, "l'ensemble de tous x dans les nombres entiers tel que x est supérieur à 5")?;
+ return Ok(());
+
+}
+
+#[test]
+fn element_alone_in() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_SetMemberSymbol", "In",
+ expr, "3 plus 2 i, n'est pas dans les nombres réels")?;
+ return Ok(());
+
+}
+
+#[test]
+fn element_under_sum_in() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_SetMemberSymbol", "In",
+ expr, "la sommation sur i est dans les nombres entiers de; la fraction avec numérateur 1; et dénominateur i au carré")?;
+ return Ok(());
+
+}
+
+#[test]
+fn set_with_bar_belongs() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_SetMemberSymbol", "Belongs",
+ expr, "l'ensemble de tous x appartenant à les nombres entiers tel que x est supérieur à 5")?;
+ return Ok(());
+
+}
+
+#[test]
+fn element_alone_belongs() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_SetMemberSymbol", "Belongs",
+ expr, "3 plus 2 i, n'appartient pas à, les nombres réels")?;
+ return Ok(());
+
+}
+
+#[test]
+fn element_under_sum_belongs() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_SetMemberSymbol", "Belongs",
+ expr, "la sommation sur i appartient à les nombres entiers de; la fraction avec numérateur 1; et dénominateur i au carré")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn set_member_woall() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak_prefs("fr", vec![("ClearSpeak_SetMemberSymbol", "Member"), ("ClearSpeak_Sets", "woAll")],
+ expr, "l'ensemble de x membre de les nombres entiers tel que x est supérieur à 5")?;
+ return Ok(());
+
+}
+
+#[test]
+fn multiple_element_set_woall() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Sets", "woAll", expr, "l'ensemble 5 virgule, 10 virgule, 15")?;
+ return Ok(());
+
+}
+
+#[test]
+fn multiple_element_set_silent_bracket() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Sets", "SilentBracket", expr, "5 virgule, 10 virgule, 15")?;
+ return Ok(());
+
+ }
+
+#[test]
+fn silent_bracket() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Sets", "SilentBracket", expr,
+ "l'ensemble de tous x tel que x est supérieur à 2")?;
+ return Ok(());
+
+ }
+
diff --git a/tests/Languages/fr/ClearSpeak/symbols_and_adornments.rs b/tests/Languages/fr/ClearSpeak/symbols_and_adornments.rs
new file mode 100644
index 00000000..aa39c9d0
--- /dev/null
+++ b/tests/Languages/fr/ClearSpeak/symbols_and_adornments.rs
@@ -0,0 +1,377 @@
+use crate::common::*;
+use anyhow::Result;
+
+#[test]
+fn multiplication() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "2 fois 3")?;
+ return Ok(());
+
+}
+
+#[test]
+fn multiplication_by() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_MultSymbolX", "By", expr, "2 par 3")?;
+ return Ok(());
+
+}
+
+#[test]
+fn multiplication_cross() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_MultSymbolX", "Cross", expr, "u multiplié par v")?;
+ return Ok(());
+
+}
+
+#[test]
+fn ellipses_auto_start() -> Result<()> {
+ let expr = "";
+ test("fr", "ClearSpeak", expr, "point point point virgule, moins 2 virgule, moins 1 virgule, 0")?;
+ return Ok(());
+
+}
+
+#[test]
+fn ellipses_auto_end() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Ellipses", "Auto", expr, "1 virgule, 2 virgule, 3 virgule, point point point")?;
+ return Ok(());
+
+}
+
+#[test]
+fn ellipses_auto_middle() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Ellipses", "Auto", expr,
+ "1 virgule, 2 virgule, 3 virgule, point point point virgule, 20")?;
+ return Ok(());
+
+}
+
+#[test]
+fn ellipses_auto_both() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Ellipses", "Auto", expr,
+ "point point point virgule, moins 2 virgule, moins 1 virgule, 0 virgule, 1 virgule, 2 virgule, point point point")?;
+ return Ok(());
+
+}
+
+#[test]
+fn ellipses_and_so_on_start() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Ellipses", "AndSoOn", expr, "point point point virgule, moins 2 virgule, moins 1 virgule, 0")?;
+ return Ok(());
+
+}
+
+#[test]
+fn ellipses_and_so_on_end() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Ellipses", "AndSoOn", expr, "1 virgule, 2 virgule, 3 et ainsi de suite")?;
+ return Ok(());
+
+}
+
+#[test]
+fn ellipses_and_so_on_middle() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Ellipses", "AndSoOn", expr,
+ "1 virgule, 2 virgule, 3 et ainsi de suite jusqu'à, 20")?;
+ return Ok(());
+
+}
+
+#[test]
+fn ellipses_and_so_on_both() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_Ellipses", "AndSoOn", expr,
+ "point point point virgule, moins 2 virgule, moins 1 virgule, 0 virgule, 1 virgule, 2 virgule, point point point")?;
+ return Ok(());
+
+}
+
+#[test]
+fn vertical_line_auto() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_VerticalLine", "Auto", expr,
+ "3 divise 6")?;
+ return Ok(());
+
+}
+
+#[test]
+fn vertical_line_divides() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_VerticalLine", "Divides", expr,
+ "3 divise 6")?;
+ return Ok(());
+
+}
+
+ #[test]
+ fn vertical_line_given() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_VerticalLine", "Given", expr,
+ "3 sachant 6")?;
+ return Ok(());
+
+ }
+
+ #[test]
+ fn vertical_line_probability_given() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak_prefs("fr", vec![("ClearSpeak_VerticalLine", "Given"), ("ClearSpeak_ImpliedTimes", "None")]
+ , expr, "p majuscule; parenthèse gauche, a majuscule sachant b majuscule; parenthèse droite")?;
+ return Ok(());
+ }
+
+#[test]
+fn vertical_line_set() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_VerticalLine", "Auto", expr,
+ "l'ensemble de tous x tel que x est supérieur à 0")?;
+ return Ok(());
+
+}
+
+
+#[test]
+fn vertical_line_set_such_that() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_VerticalLine", "SuchThat", expr,
+ "l'ensemble de tous x tel que x est supérieur à 0")?;
+ return Ok(());
+
+}
+
+#[test]
+fn vertical_line_set_given() -> Result<()> {
+ let expr = "";
+ // the rules for set will override all the options -- ClearSpeak spec should be clarified
+ test_ClearSpeak("fr", "ClearSpeak_VerticalLine", "Given", expr,
+ "l'ensemble de tous x tel que x est supérieur à 0")?;
+ return Ok(());
+
+}
+
+#[test]
+fn vertical_line_set_and_abs() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_VerticalLine", "Auto", expr,
+ "l'ensemble de tous x tel que la valeur absolue de x; est supérieur à 2")?;
+ return Ok(());
+
+}
+
+#[test]
+fn vertical_line_evaluated_at() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_VerticalLine", "Auto", expr,
+ "f de x évalué à, x est égal à 5")?;
+ return Ok(());
+
+}
+
+#[test]
+fn vertical_line_evaluated_at_both() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_VerticalLine", "Auto", expr,
+ "x au carré plus x, évalué à 1 moins la même expression évaluée à 0")?;
+ return Ok(());
+
+}
+#[test]
+fn vertical_line_evaluated_at_divides() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_VerticalLine", "Divides", expr,
+ "f de x évalué à, x est égal à 5")?;
+ return Ok(());
+
+}
+
+#[test]
+fn vertical_line_evaluated_at_both_given() -> Result<()> {
+ let expr = "";
+ test_ClearSpeak("fr", "ClearSpeak_VerticalLine", "Given", expr,
+ "x au carré plus x, évalué à 1 moins la même expression évaluée à 0")?;
+ return Ok(());
+
+}
\ No newline at end of file