/// Tests for rules shared between various speech styles:
/// *  modified var
use crate::common::*;
use anyhow::Result;

// AI generated
#[test]
fn modified_vars() -> Result<()> {
    let expr = "<math> <mrow>
        <mover> <mi>a</mi> <mo>`</mo> </mover>
        <mover> <mi>b</mi> <mo>~</mo> </mover>
        <mover> <mi>c</mi> <mo>&#x0306;</mo> </mover>
        <mover> <mi>b</mi> <mo>&#x030c;</mo> </mover>
        <mover> <mi>c</mi> <mo>`</mo> </mover>  <mo>+</mo>
        <mover> <mi>r</mi> <mo>ˇ</mo> </mover>  <mo>+</mo>
        <mover> <mi>x</mi> <mo>.</mo> </mover>
        <mover> <mi>y</mi> <mo>&#x2D9;</mo> </mover>
        <mover> <mi>z</mi> <mo>&#x00A8;</mo> </mover>
        <mover> <mi>u</mi> <mo>&#x20DB;</mo> </mover>
        <mover> <mi>v</mi> <mo>&#x20DC;</mo> </mover> <mo>+</mo>
        <mover> <mi>x</mi> <mo>^</mo> </mover> <mo>+</mo>
        <mover> <mi>t</mi> <mo>→</mo> </mover>
        </mrow> </math>";
    test("hu", "SimpleSpeak", expr, 
        "a súlyozott, b tilde, c rövid, b ellenőrzés, c súlyozott; plusz, r hacsek karakter mint repülő ékezet; plusz; x pont, y pont, z dupla pont, u hármas pont, v négyes pont; plusz x kalap, plusz vektor kezdete t")?;
            return Ok(());

}

// AI generated
#[test]
fn limit() -> Result<()> {
    let expr = "<math>
            <munder>
            <mo>lim</mo>
            <mrow>  <mi>x</mi> <mo>&#x2192;</mo>  <mn>0</mn>  </mrow>
            </munder>
            <mrow>
            <mfrac>
                <mrow>  <mi>sin</mi>  <mo>&#x2061;</mo> <mi>x</mi> </mrow>
                <mi>x</mi>
            </mfrac>
            </mrow>
        </math>";
    test("hu", "SimpleSpeak", expr, "határérték x megközelítések 0; tört, szinusz x, per x, tört vége")?;
    test_prefs("hu", "SimpleSpeak", vec![("Impairment", "LearningDisability")], expr,
            "határérték x megközelítések 0; szinusz x, per x")?;
            return Ok(());

}

// AI generated
#[test]
fn limit_from_below() -> Result<()> {
    let expr = "<math>
            <munder>
            <mo>lim</mo>
            <mrow>  <mi>x</mi> <mo>↗</mo>  <mn>0</mn>  </mrow>
            </munder>
            <mrow>
                <mrow>  <mi>sin</mi>  <mo>&#x2061;</mo> <mi>x</mi> </mrow>
            </mrow>
        </math>";
    test("hu", "SimpleSpeak", expr, "határérték x alulról közelít 0; szinusz x")?;
    return Ok(());

}


// AI generated
#[test]
fn binomial_mmultiscripts() -> Result<()> {
    let expr = "<math><mmultiscripts><mi>C</mi><mi>m</mi><none/><mprescripts/><mi>n</mi><none/></mmultiscripts></math>";
    test("hu", "SimpleSpeak", expr, "n a m")?;
    return Ok(());

}

// AI generated
#[test]
fn binomial_mmultiscripts_other() -> Result<()> {
    let expr = "<math><mmultiscripts><mi>C</mi><mi>m</mi><none/><mprescripts/><none/><mi>n</mi></mmultiscripts></math>";
    test("hu", "SimpleSpeak", expr, "n a m")?;
    return Ok(());

}

// AI generated
#[test]
fn binomial_subscript() -> Result<()> {  // C_{n,k}
    let expr = "<math><msub><mi>C</mi><mrow><mi>n</mi><mo>,</mo><mi>m</mi></mrow></msub></math>";
    test("hu", "SimpleSpeak", expr, "n a m")?;
    return Ok(());

}

// AI generated
#[test]
fn permutation_mmultiscripts() -> Result<()> {
    let expr = "<math><mmultiscripts><mi>P</mi><mi>k</mi><none/><mprescripts/><mi>n</mi><none/></mmultiscripts></math>";
    test("hu", "SimpleSpeak", expr, "k permutációja n")?;
    return Ok(());

}

// AI generated
#[test]
fn permutation_mmultiscripts_sup() -> Result<()> {
    let expr = "<math><mmultiscripts><mi>P</mi><mi>k</mi><none/><mprescripts/><none/><mi>n</mi></mmultiscripts></math>";
    test("hu", "SimpleSpeak", expr, "k permutációja n")?;
    return Ok(());

}

// AI generated
#[test]
fn permutation_msubsup() -> Result<()> {
    let expr = "<math><msubsup><mi>P</mi><mi>k</mi><mi>n</mi></msubsup></math>";
    test("hu", "SimpleSpeak", expr, "k permutációja n")?;
    return Ok(());

}

// AI generated
#[test]
fn tensor_mmultiscripts() -> Result<()> {
    let expr = "<math><mmultiscripts>
            <mi>R</mi> <mi>i</mi><none/> <none/><mi>j</mi> <mi>k</mi><none/> <mi>l</mi><none/> 
        </mmultiscripts></math>";
    test_prefs("hu", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr,
            "nagy r posskriptek 4, subscript i superscript j subscript k subscript l")?;
    test_prefs("hu", "SimpleSpeak", vec![("Verbosity", "Medium")], expr,
            "nagy r posskriptek 4, sub i super j sub k sub l")?;
            return Ok(());

}

// AI generated
#[test]
fn huge_num_mmultiscripts() -> Result<()> {
    let expr = "<math><mmultiscripts>
            <mi>R</mi> <mi>i</mi><none/> <none/><mi>j</mi> <mi>k</mi><none/> <mi>l</mi><none/> <mi>m</mi><none/>
            <mprescripts/> <mi>I</mi><none/> <none/><mi>J</mi> <mi>K</mi><none/> <mi>L</mi><none/>
        </mmultiscripts></math>";
    test_prefs("hu", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr,
            "nagy r preskriptek 4, pre subscript nagy i, pre superscript nagy j és váltakozó preskriptek nagy k none nagy l none preskriptek vége és posskriptek 5, subscript i superscript j subscript k subscript l és váltakozó szkriptek m none szkriptek vége")?;
            return Ok(());

}

// AI generated
#[test]
fn prime() -> Result<()> {
    let expr = "<math> <msup><mi>x</mi><mo >&#x2032;</mo></msup> </math>";
    test("hu", "SimpleSpeak", expr, "x prím")?;
    return Ok(());

}

// AI generated
#[test]
fn given() -> Result<()> {
    let expr = "<math><mi>P</mi><mo>(</mo><mi>A</mi><mo>|</mo><mi>B</mi><mo>)</mo></math>";
    test("hu", "SimpleSpeak", expr, "nagy p; nyitott zárójel, nagy a adott nagy b, zárt zárójel")?;
    test("hu", "ClearSpeak", expr,  "nagy p; nyitott zárójel, nagy a adott nagy b, zárt zárójel")?; // not good, but follows the spec
    return Ok(());

}

// AI generated
#[test]
fn simple_msubsup() -> Result<()> {
    let expr = "<math>
            <mstyle displaystyle='true' scriptlevel='0'>
            <msubsup>
                <mi>x</mi>
                <mrow>
                <mi>k</mi>
                </mrow>
                <mrow>
                <mi>i</mi>
                </mrow>
            </msubsup>
            </mstyle>
        </math>";
    test("hu", "ClearSpeak", expr, "x alsó index k, a(z) i-edik hatványon")?;
    return Ok(());

}

// AI generated
#[test]
fn non_simple_msubsup() -> Result<()> {
  let expr = "<math><msubsup><mi>i</mi><mrow><mi>j</mi><mo>&#x2212;</mo><mn>2</mn></mrow><mi>k</mi></msubsup></math>";
  test("hu", "SimpleSpeak", expr, "i alsó index j mínusz 2 alsó index vége, a(z) k-edik hatványon")?;
  test("hu", "ClearSpeak", expr, "i alsó index j mínusz 2 alsó index vége, a(z) k-edik hatványon")?;
  test_prefs("hu", "SimpleSpeak", vec![("Impairment", "LearningDisability")], expr,
          "i alsó index j mínusz 2, a(z) k-edik hatványon")?;
          return Ok(());

}

// AI generated
#[test]
fn presentation_mathml_in_semantics() -> Result<()> {
    let expr = "<math>
        <semantics>
            <annotation encoding='application/x-tex'>{\\displaystyle x_k^i}</annotation>
            <annotation-xml encoding='MathML-Presentation'>
                <msubsup>
                    <mi>x</mi>
                    <mrow>
                    <mi>k</mi>
                    </mrow>
                    <mrow>
                    <mi>i</mi>
                    </mrow>
                </msubsup>
            </annotation-xml>
        </semantics>
    </math>";
    test("hu", "ClearSpeak", expr, "x alsó index k, a(z) i-edik hatványon")?;
    return Ok(());

}

// AI generated
#[test]
fn ignore_period() -> Result<()> {
    // from https://hu.wikipedia.org/wiki/Probability
    let expr = "<math>
    <semantics>
    <annotation encoding='application/x-tex'>{\\displaystyle x_k^i}</annotation>
    <annotation-xml encoding='MathML-Presentation'>
      <mrow>
        <mstyle displaystyle='true' scriptlevel='0'>
          <mi>P</mi>
          <mo stretchy='false'>(</mo>
          <mi>A</mi>
          <mrow>
            <mstyle displaystyle='false' scriptlevel='0'>
              <mtext>&nbsp;és&nbsp;</mtext>
            </mstyle>
          </mrow>
          <mi>B</mi>
          <mo stretchy='false'>)</mo>
          <mo>=</mo>
          <mi>P</mi>
          <mo stretchy='false'>(</mo>
          <mi>A</mi>
          <mo>∩<!-- ∩ --></mo>
          <mi>B</mi>
          <mo stretchy='false'>)</mo>
          <mo>=</mo>
          <mi>P</mi>
          <mo stretchy='false'>(</mo>
          <mi>A</mi>
          <mo stretchy='false'>)</mo>
          <mi>P</mi>
          <mo stretchy='false'>(</mo>
          <mi>B</mi>
          <mo stretchy='false'>)</mo>
          <mo>.</mo>
        </mstyle>
      </mrow>
      </annotation-xml>
    </semantics>  
  </math>";
    test("hu", "SimpleSpeak", expr, "nagy p; nyitott zárójel, nagy a és nagy b; zárt zárójel; egyenlő; nagy p; nyitott zárójel, nagy a metszéspont nagy b; zárt zárójel; egyenlő, nagy p nagy a, nagy p nagy b")?;
    return Ok(());

}

// AI generated
#[test]
fn ignore_mtext_period() -> Result<()> {
    let expr = "<math><mrow><mrow><mo>{</mo><mn>2</mn><mo>}</mo></mrow><mtext>.</mtext></mrow></math>";
    test("hu", "SimpleSpeak", expr, "a(z) 2 halmaz")?;
    return Ok(());

}

// AI generated
#[test]
fn ignore_comma() -> Result<()> {
    // from https://hu.wikipedia.org/wiki/Probability
    let expr = "<math>
    <mrow>
      <mstyle displaystyle='true' scriptlevel='0'>
        <mi>ϕ<!-- ϕ --></mi>
        <mo stretchy='false'>(</mo>
        <mi>x</mi>
        <mo stretchy='false'>)</mo>
        <mo>=</mo>
        <mi>c</mi>
        <msup>
          <mi>e</mi>
          <mrow>
            <mo>−<!-- − --></mo>
            <msup>
              <mi>h</mi>
              <mrow>
                <mn>2</mn>
              </mrow>
            </msup>
            <msup>
              <mi>x</mi>
              <mrow>
                <mn>2</mn>
              </mrow>
            </msup>
          </mrow>
        </msup>
        <mo>,</mo>
      </mstyle>
    </mrow>
</math>";
    test("hu", "SimpleSpeak", expr, "phi x egyenlő; c szorozva; e emelve a következő kitevőre:, negatív h a négyzeten, x a négyzeten, kitevő vége")?;
    return Ok(());

}

// AI generated
#[test]
#[ignore] // issue #14
fn ignore_period_and_space() -> Result<()> {
    // from https://hu.wikipedia.org/wiki/Probability
    let expr = "<math>
      <mrow>
        <mstyle displaystyle='true' scriptlevel='0'>
          <mi>P</mi>
          <mo stretchy='false'>(</mo>
          <mi>A</mi>
          <mo>∣<!-- ∣ --></mo>
          <mi>B</mi>
          <mo stretchy='false'>)</mo>
          <mo>=</mo>
          <mrow>
            <mfrac>
              <mrow>
                <mi>P</mi>
                <mo stretchy='false'>(</mo>
                <mi>A</mi>
                <mo>∩<!-- ∩ --></mo>
                <mi>B</mi>
                <mo stretchy='false'>)</mo>
              </mrow>
              <mrow>
                <mi>P</mi>
                <mo stretchy='false'>(</mo>
                <mi>B</mi>
                <mo stretchy='false'>)</mo>
              </mrow>
            </mfrac>
          </mrow>
          <mo>.</mo>
          <mspace width='thinmathspace'></mspace>
        </mstyle>
      </mrow>
</math>";
    test("hu", "ClearSpeak", expr, "cap p, open paren, cap eigh divides cap b, close paren; is equal to; the fraction with numerator; cap p, open paren, cap eigh intersection cap b; close paren; and denominator cap p of cap b")?;
    return Ok(());

}


// AI generated
#[test]
fn bug_199_2pi() -> Result<()> {
  let expr = "<math>
      <mrow>
        <mo stretchy=\"false\" form=\"prefix\">[</mo>
        <mspace width=\"0.333em\"></mspace>
        <mn>0</mn>
        <mspace width=\"0.333em\"></mspace>
        <mo>,</mo>
        <mspace width=\"0.333em\"></mspace>
        <mn>2</mn>
        <mi>π</mi>
        <mspace width=\"0.333em\"></mspace>
        <mo stretchy=\"false\" form=\"postfix\">)</mo>
      </mrow>
    </math>";
  test("hu", "SimpleSpeak",expr, "0 től 2 pí ig terjedő intervallum, tartalmazza a 0 elemet de nem tartalmazza a 2 pí elemet")?;
  return Ok(());

}

// AI generated
#[test]
fn caret_and_hat() -> Result<()> {
  let expr = "<math><mi>x</mi><mo>^</mo><mn>2</mn><mo>+</mo><mover><mi>y</mi><mo>^</mo></mover></math>";
  test("hu", "SimpleSpeak",expr, "x fölfelényíl 2, plusz y kalap")?;
  return Ok(());

}

// AI generated
#[test]
fn mn_with_space() -> Result<()> {
  let expr = "<math><mn>1 234 567</mn></math>";
  test_prefs("hu", "SimpleSpeak", vec![("DecimalSeparators", "."), ("BlockSeparators", " ,")], expr, "1234567")?;
  return Ok(());

}

// AI generated
#[test]
fn ignore_bold() -> Result<()> {
  let expr = r#"<math>
				<mi mathvariant="bold-italic">x</mi>
				<mo>=</mo>
				<mn>2</mn>
				<mrow>
				<mi>𝒔𝒊𝒏</mi>
				<mo>&#x2061;</mo>
				<mrow><mi mathvariant="bold-italic">t</mi></mrow>
				</mrow>
				<mo>-</mo>
				<mn>1</mn>
			</math>"#; 
  test_prefs("hu", "SimpleSpeak", vec![("IgnoreBold", "false")],
             expr, "félkövér x egyenlő, 2 szinusz félkövér t; mínusz 1")?;
  test_prefs("hu", "SimpleSpeak", vec![("IgnoreBold", "true")],
             expr, "x egyenlő, 2 szinusz t, mínusz 1")?;
             return Ok(());

}

// AI generated
#[test]
fn mn_with_block_and_decimal_separators() -> Result<()> {
  let expr = "<math><mn>1,234.56</mn></math>";                                       // may want to change this for another language
  test_prefs("hu", "SimpleSpeak", vec![("DecimalSeparators", "."), ("BlockSeparators", " ,")], expr, "1234.56")?;
  return Ok(());

}

// AI generated
#[test]
fn divergence() -> Result<()> {
  let expr = "<math><mo>&#x2207;</mo><mo>&#xB7;</mo><mi mathvariant='normal'>F</mi></math>";                                       // may want to change this for another language
  test_prefs("hu", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "eltérés nagy f")?;
  test_prefs("hu", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "eltérés nagy f")?;
  return Ok(());

}

// AI generated
#[test]
fn curl() -> Result<()> {
  let expr = "<math><mo>&#x2207;</mo><mo>&#xD7;</mo><mi mathvariant='normal'>F</mi></math>";          
  // may want to change this for another language
  test_prefs("hu", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "rotáció nagy f")?;
  test_prefs("hu", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "rotáció nagy f")?;
  return Ok(());

}

// AI generated
#[test]
fn gradient() -> Result<()> {
  let expr = "<math><mo>&#x2207;</mo><mi mathvariant='normal'>F</mi></math>";          
  // may want to change this for another language
  test_prefs("hu", "SimpleSpeak", vec![("Verbosity", "Terse")], expr, "gradiens nagy f")?;
  test_prefs("hu", "SimpleSpeak", vec![("Verbosity", "Verbose")], expr, "gradiens nagy f")?;
  return Ok(());

}

// AI generated
#[test]
fn literal_speak_perpendicular() -> Result<()> {
  let expr = r#"<math data-latex='\vec{A} \perp \vec{B}' display='block'>
  <mrow data-changed='added'>
    <mover data-latex='\vec{A}'>
      <mi data-latex='A'>A</mi>
      <mo stretchy='false'>→</mo>
    </mover>
    <mo intent='merőleges'>⊥</mo>
    <mover data-latex='\vec{B}'>
      <mi data-latex='B'>B</mi>
      <mo stretchy='false'>→</mo>
    </mover>
  </mrow>
 </math>"#; 
  test("hu", "LiteralSpeak", expr, "nagy a jobbra nyíl; merőleges nagy b jobbra nyíl")?;
  return Ok(());

}

// AI generated
#[test]
fn literal_speak_chars() -> Result<()> {
  let expr = r#"<math>
        <mfenced open="|" close="|">
            <mrow>
                <mi>x</mi><mo>&#xD7;</mo><mi>y</mi>
                <mo>&#xB7;</mo>
                <mi>z</mi><mo>/</mo><mn>2</mn>
                <mo>+</mo>
                <mi>a</mi><mo>&#x2225;</mo><mi>b</mi>
                <mo>+</mo>
                <mi>x</mi><mo>!</mo>
            </mrow>
        </mfenced>
    </math>"#; 
  test("hu", "LiteralSpeak", expr, "függőleges vonal; x kereszt, y pont z per 2; plusz a; dupla függőleges vonal, b plusz x felkiáltójel; függőleges vonal")?;
  return Ok(());

}

// AI generated
#[test]
fn literal_speak_with_name() -> Result<()> {
  let expr = r#"<math intent='kényszerített($x)'>
      <mrow arg="x">
        <mi>f</mi>
        <mo data-changed='added'>&#x2061;</mo>
        <mrow data-changed='added'>
          <mo>(</mo>
          <mrow data-changed='added'>
            <mi>x</mi>
            <mo>!</mo>
          </mrow>
          <mo>)</mo>
        </mrow>
      </mrow>
    </math>"#;
  test("hu", "LiteralSpeak", expr, "kényszerített f, bal zárójel, x felkiáltójel, jobb zárójel")?;
  return Ok(());

}

// AI generated
#[test]
fn literal_speak_with_property() -> Result<()> {
  let expr = r#"<math intent=':prefix'>
      <mrow arg="x">
        <mi>f</mi>
        <mo data-changed='added'>&#x2061;</mo>
        <mrow data-changed='added'>
          <mo>(</mo>
          <mrow data-changed='added'>
            <mi>x</mi>
            <mo>!</mo>
          </mrow>
          <mo>)</mo>
        </mrow>
      </mrow>
    </math>"#; 
  test("hu", "LiteralSpeak", expr, "f, bal zárójel, x felkiáltójel, jobb zárójel")?;
  return Ok(());

}

// AI generated
#[test]
fn literal_intent_property() -> Result<()> {
  let expr = r#"<math data-latex='\vec{A} \perp \vec{B}' display='block'>
  <mrow intent=":literal">
    <mover data-latex='\vec{A}'>
      <mi data-latex='A'>A</mi>
      <mo stretchy='false'>→</mo>
    </mover>
    <mo intent='merőleges'>⊥</mo>
    <mover data-latex='\vec{B}'>
      <mi data-latex='B'>B</mi>
      <mo stretchy='false'>→</mo>
    </mover>
  </mrow>
 </math>"#; 
  test("hu", "SimpleSpeak", expr, "nagy a jobbra nyíl; merőleges nagy b jobbra nyíl")?;
  return Ok(());

}

// AI generated
#[test]
fn literal_intent_property_with_name() -> Result<()> {
  let expr = r#"<math intent='kényszerített:literal($x)'>
      <mrow arg="x">
        <mi>f</mi>
        <mo data-changed='added'>&#x2061;</mo>
        <mrow data-changed='added'>
          <mo>(</mo>
          <mrow data-changed='added'>
            <mi>x</mi>
            <mo>!</mo>
          </mrow>
          <mo>)</mo>
        </mrow>
      </mrow>
    </math>"#; 
  test("hu", "SimpleSpeak", expr, "kényszerített f, nyitott zárójel, x felkiáltójel, zárt zárójel")?;
  return Ok(());

}
