CppunitTest_sc_tiledrendering2: move to tiledrendering folder
[LibreOffice.git] / starmath / qa / cppunit / test_nodetotextvisitors.cxx
blob3a0f5570087052d71dcd58c4b9705afc63229614
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <sal/config.h>
11 #include <test/bootstrapfixture.hxx>
13 #include <vcl/virdev.hxx>
14 #include <sfx2/sfxmodelfactory.hxx>
15 #include <smdll.hxx>
17 #include <document.hxx>
18 #include <node.hxx>
19 #include <parse5.hxx>
20 #include <visitors.hxx>
21 #include <cursor.hxx>
23 #include "mock-visitor.hxx"
24 #include <memory>
26 typedef rtl::Reference<SmDocShell> SmDocShellRef;
28 namespace
30 class Test : public test::BootstrapFixture
32 public:
33 // init
34 virtual void setUp() override;
35 virtual void tearDown() override;
37 // tests
38 void SimpleUnaryOp();
39 void SimpleBinaryOp();
40 void SimpleRelationalOp();
41 void SimpleSetOp();
42 void SimpleFunctions();
43 void SimpleOperators();
44 void SimpleAttributes();
45 void SimpleMisc();
46 void SimpleBrackets();
47 void SimpleFormats();
48 void SimpleGreekChars();
49 void SimpleSpecialChars();
50 void testBinomInBinHor();
51 void testBinVerInUnary();
52 void testBinHorInSubSup();
53 void testUnaryInMixedNumberAsNumerator();
54 void testMiscEquivalent();
55 void testParser();
57 CPPUNIT_TEST_SUITE(Test);
58 CPPUNIT_TEST(SimpleUnaryOp);
59 CPPUNIT_TEST(SimpleBinaryOp);
60 CPPUNIT_TEST(SimpleRelationalOp);
61 CPPUNIT_TEST(SimpleSetOp);
62 CPPUNIT_TEST(SimpleFunctions);
63 CPPUNIT_TEST(SimpleOperators);
64 CPPUNIT_TEST(SimpleAttributes);
65 CPPUNIT_TEST(SimpleMisc);
66 CPPUNIT_TEST(SimpleBrackets);
67 CPPUNIT_TEST(SimpleFormats);
68 CPPUNIT_TEST(SimpleGreekChars);
69 CPPUNIT_TEST(SimpleSpecialChars);
70 CPPUNIT_TEST(testBinomInBinHor);
71 CPPUNIT_TEST(testBinVerInUnary);
72 CPPUNIT_TEST(testBinHorInSubSup);
73 CPPUNIT_TEST(testUnaryInMixedNumberAsNumerator);
74 CPPUNIT_TEST(testMiscEquivalent);
75 CPPUNIT_TEST(testParser);
76 CPPUNIT_TEST_SUITE_END();
78 private:
79 SmDocShellRef xDocShRef;
80 void parseandparseagain(const char* input, const char* test_name);
81 void ParseAndCheck(const char* input, const char* expected, const char* test_name);
82 void ParseAndCompare(const char* formula1, const char* formula2, const char* test_name);
85 void Test::setUp()
87 BootstrapFixture::setUp();
89 SmGlobals::ensure();
91 xDocShRef = new SmDocShell(SfxModelFlags::EMBEDDED_OBJECT);
92 xDocShRef->DoInitNew();
95 void Test::tearDown()
97 xDocShRef->DoClose();
98 xDocShRef.clear();
99 BootstrapFixture::tearDown();
103 * Most of the formula commands in this file came from:
104 * http://wiki.openoffice.org/wiki/Template:Math_commands_reference
105 * which was licensed with a
106 * Creative Common Attribution 3.0 license and written by:
107 * Jeanweber, Weegreenblobbie, Jdpipe, TJFrazier, Ysangkok, B michaelsen, Spellbreaker
110 void Test::SimpleUnaryOp()
112 parseandparseagain("+1", "Positive (plus)");
113 parseandparseagain("-2", "Negative (minus)");
114 parseandparseagain("+-3", "Plus/minus");
115 parseandparseagain("-+4", "Minus/plus");
116 parseandparseagain("neg a", "Boolean 'not'");
117 parseandparseagain("fact a", "Factorial");
118 parseandparseagain("- { 1 over 2 }", "BinVer in Unary 1");
119 ParseAndCheck("- { 1 over 2 }", "- { 1 over 2 }", "BinVer in Unary 1");
120 parseandparseagain("{- { 1 over 2 } }", "BinVer in Unary 2");
121 parseandparseagain("- 1 over 2", "Unary in BinVer as numerator 1");
122 parseandparseagain("{ - 1 } over 2", "Unary in BinVer as numerator 2");
123 parseandparseagain("1 over - 2", "Unary in BinVer as denominator 1");
124 parseandparseagain("1 over { - 2 }", "Unary in BinVer as denominator 2");
125 parseandparseagain("2 { - 1 over 2 }", "Mixed number with Unary in denominator 1");
126 parseandparseagain("2 { - 1 } over 2", "Mixed number with Unary in denominator 2");
127 parseandparseagain("- 1 + 2", "Unary in BinHor");
130 void Test::SimpleBinaryOp()
132 parseandparseagain("a + b", "Addition");
133 parseandparseagain("a cdot b", "Dot product");
134 parseandparseagain("a times b", "Cross product");
135 parseandparseagain("a * b", "Multiplication (asterisk)");
136 parseandparseagain("a and b", "Boolean 'and'");
137 parseandparseagain("a - b", "Subtraction");
138 parseandparseagain("a over b", "Division (as a fraction)");
139 parseandparseagain("a div b", "Division (as an operator)");
140 parseandparseagain("a / b", "Division (with a slash)");
141 parseandparseagain("a or b", "Boolean 'or'");
142 parseandparseagain("a circ b", "Concatenation");
145 void Test::SimpleRelationalOp()
147 parseandparseagain("a = b", "Is equal");
148 parseandparseagain("a <> b", "Is not equal");
149 parseandparseagain("a approx 2", "Approximately");
150 parseandparseagain("a divides b", "Divides");
151 parseandparseagain("a ndivides b", "Does not divide");
152 parseandparseagain("a < 2", "Less than");
153 parseandparseagain("a > 2", "Greater than");
154 parseandparseagain("a simeq b", "Similar to or equal");
155 parseandparseagain("a parallel b", "Parallel");
156 parseandparseagain("a ortho b", "Orthogonal to");
157 parseandparseagain("a leslant b", "Less than or equal to");
158 parseandparseagain("a geslant b", "Greater than or equal to");
159 parseandparseagain("a sim b", "Similar to");
160 parseandparseagain("a equiv b", "Congruent");
161 parseandparseagain("a <= b", "Less than or equal to");
162 parseandparseagain("a >= b", "Greater than or equal to");
163 parseandparseagain("a prop b", "Proportional");
164 parseandparseagain("a toward b", "Toward");
165 parseandparseagain("a dlarrow b", "Arrow left");
166 parseandparseagain("a dlrarrow b", "Double arrow left and right");
167 parseandparseagain("drarrow b", "Arrow right");
170 void Test::SimpleSetOp()
172 parseandparseagain("a in B", "Is in");
173 parseandparseagain("a notin B", "Is not in");
174 parseandparseagain("A owns b", "Owns");
175 parseandparseagain("emptyset", "Empty set");
176 parseandparseagain("A intersection B", "Intersection");
177 parseandparseagain("A union B", "Union");
178 parseandparseagain("A setminus B", "Difference");
179 parseandparseagain("A slash B", "Quotient");
180 parseandparseagain("aleph", "Aleph");
181 parseandparseagain("A subset B", "Subset");
182 parseandparseagain("A subseteq B", "Subset or equal to");
183 parseandparseagain("A supset B", "Superset");
184 parseandparseagain("A supseteq B", "Superset or equal to");
185 parseandparseagain("A nsubset B", "Not subset");
186 parseandparseagain("A nsubseteq B", "Not subset or equal");
187 parseandparseagain("A nsupset B", "Not superset");
188 parseandparseagain("A nsupseteq B", "Not superset or equal");
189 parseandparseagain("setN", "Set of natural numbers");
190 parseandparseagain("setZ", "Set of integers");
191 parseandparseagain("setQ", "Set of rational numbers");
192 parseandparseagain("setR", "Set of real numbers");
193 parseandparseagain("setC", "Set of complex numbers");
196 void Test::SimpleFunctions()
198 parseandparseagain("func e^{a}", "Exponential");
199 parseandparseagain("ln(a)", "Natural logarithm");
200 parseandparseagain("exp(a)", "Exponential function");
201 parseandparseagain("log(a)", "Logarithm");
202 parseandparseagain("a^{b}", "Power");
203 parseandparseagain("sin(a)", "Sine");
204 parseandparseagain("cos(a)", "Cosine");
205 parseandparseagain("tan(a)", "Tangent");
206 parseandparseagain("cot(a)", "Cotangent");
207 parseandparseagain("sqrt{a}", "Square root");
208 parseandparseagain("arcsin(a)", "Arcsine");
209 parseandparseagain("arccos(a)", "Arccosine");
210 parseandparseagain("arctan(a)", "Arctangent");
211 parseandparseagain("arccot(a)", "Arc cotangent");
212 parseandparseagain("nroot{a}{b}", "nth root");
213 parseandparseagain("sinh(a)", "Hyperbolic sine");
214 parseandparseagain("cosh(a)", "Hyperbolic cosine");
215 parseandparseagain("tanh(a)", "Hyperbolic tangent");
216 parseandparseagain("coth(a)", "Hyperbolic cotangent");
217 parseandparseagain("abs{a}", "Absolute value");
218 parseandparseagain("arsinh(a)", "Arc hyperbolic sine");
219 parseandparseagain("arcosh(a)", "Arc hyperbolic cosine");
220 parseandparseagain("artanh(a)", "Arc hyperbolic tangent");
221 parseandparseagain("arcoth(a)", "Arc hyperbolic cotangent");
224 void Test::SimpleOperators()
226 parseandparseagain("lim{a}", "Limit");
227 parseandparseagain("sum{a}", "Sum");
228 parseandparseagain("prod{a}", "Product");
229 parseandparseagain("coprod{a}", "Coproduct");
230 parseandparseagain("int from {r_0} to {r_t} a",
231 "Upper and lower bounds shown with integral (from & to)");
232 ParseAndCheck("int csup {r_0} csub {r_t} a", "int csup { r _ 0 } csub { r _ t } a",
233 "Upper and lower bounds shown with integral (csub & csup)");
234 ParseAndCheck("sum csup { size 8 { x - 1 } } csub { size 8 a } b",
235 "sum csup { size 8 { x - 1 } } csub { size 8 a } b",
236 "Sum with sized upper and lower bounds");
237 parseandparseagain("int{a}", "Integral");
238 parseandparseagain("intd_{1}^{2}{x dx}", "Dynamically-sized integral");
239 parseandparseagain("iint{a}", "Double integral");
240 parseandparseagain("iiint{a}", "Triple integral");
241 parseandparseagain("sum from{3}b", "Lower bound shown with summation symbol");
242 parseandparseagain("lint a", "Contour integral");
243 parseandparseagain("llint a", "Double curved integral");
244 parseandparseagain("lllint a", "Triple curved integral");
245 parseandparseagain("prod from {i=1} to {n} {(i+1)}", "Product with range");
246 ParseAndCheck("%Ux2135", "%Ux2135", "fdo#77831");
249 void Test::SimpleAttributes()
251 parseandparseagain("acute a", "Acute accent");
252 parseandparseagain("grave a", "Grave accent");
253 parseandparseagain("check a", "Reverse circumflex");
254 parseandparseagain("breve a", "Breve");
255 parseandparseagain("circle a", "Circle");
256 parseandparseagain("vec a", "Vector arrow");
257 parseandparseagain("harpoon a", "Harpoon");
258 parseandparseagain("tilde a", "Tilde");
259 parseandparseagain("hat a", "Circumflex");
260 parseandparseagain("bar a", "Line above");
261 parseandparseagain("dot a", "Dot");
262 parseandparseagain("widevec abc", "Wide vector arrow");
263 parseandparseagain("wideharpoon abc", "Wide harpoon");
264 parseandparseagain("widetilde abc", "Wide tilde");
265 parseandparseagain("widehat abc", "Wide circumflex");
266 parseandparseagain("ddot a", "Double dot");
267 parseandparseagain("overline abc", "Line over");
268 parseandparseagain("underline abc", "Line under");
269 parseandparseagain("overstrike abc", "Line through");
270 parseandparseagain("dddot a", "Triple dot");
271 parseandparseagain("phantom a", "Transparent (useful to get a placeholder of a given size)");
272 parseandparseagain("bold a", "Bold font");
273 parseandparseagain("ital a", "Italic font");
274 parseandparseagain("nitalic a", "Roman (non-italic) font 1");
275 parseandparseagain("\"a\"", "Roman (non-italic) font 2");
276 parseandparseagain("size 16 qv", "Resize font");
277 parseandparseagain("font sans qv", "Sans serif font");
278 parseandparseagain("font serif qv", "Serif font");
279 parseandparseagain("font fixed qv", "Fixed font");
280 parseandparseagain("color cyan qv", "Cyan color");
281 parseandparseagain("color yellow qv", "Yellow color");
282 parseandparseagain("color white qv", "White color");
283 parseandparseagain("color green qv", "Green color");
284 parseandparseagain("color blue qv", "Blue color");
285 parseandparseagain("color red qv", "Red color");
286 parseandparseagain("color green X qv", "Green color changes back");
287 parseandparseagain("color green {X qv}", "Green color, more than one item");
290 void Test::SimpleMisc()
292 parseandparseagain("infinity", "Infinity");
293 parseandparseagain("partial", "Partial");
294 parseandparseagain("nabla", "Nabla");
295 parseandparseagain("exists", "There exists");
296 parseandparseagain("notexists", "There not exists");
297 parseandparseagain("forall", "For all");
298 parseandparseagain("hbar", "H bar");
299 parseandparseagain("lambdabar", "Lambda bar");
300 parseandparseagain("re", "Real part");
301 parseandparseagain("im", "Imaginary part");
302 parseandparseagain("wp", "Weierstrass p");
303 parseandparseagain("leftarrow", "Left arrow");
304 parseandparseagain("rightarrow", "Right arrow");
305 parseandparseagain("uparrow", "Up arrow");
306 parseandparseagain("downarrow", "Down arrow");
307 parseandparseagain("dotslow", "Dots at bottom");
308 parseandparseagain("dotsaxis", "Dots at middle");
309 parseandparseagain("dotsvert", "Dots vertical");
310 parseandparseagain("dotsup", "Dots diagonal upward");
311 parseandparseagain("dotsdown", "Dots diagonal downward");
314 void Test::SimpleBrackets()
316 parseandparseagain("(a)", "Round Brackets");
317 parseandparseagain("[b]", "Square Brackets");
318 parseandparseagain("ldbracket c rdbracket", "Double Square Brackets");
319 parseandparseagain("lline a rline", "Single line or absolute");
320 parseandparseagain("abs a", "Single line or absolute 2");
321 parseandparseagain("ldline a rdline", "Double line");
322 parseandparseagain("lbrace w rbrace", "Braces");
323 parseandparseagain("left lbrace stack{0, n <> 0 # 1, n = 1} right none", "Single left brace");
324 parseandparseagain("langle d rangle", "Angle Brackets");
325 parseandparseagain("langle a mline b rangle", "Operator Brackets");
326 parseandparseagain("{a}", "Group brackets (used for program control)");
327 parseandparseagain("left ( stack{a # b # z} right )", "Round brackets scalable");
328 parseandparseagain("left [ stack{x # y} right ]", "Square brackets scalable");
329 parseandparseagain("left ldbracket c right rdbracket", "Double square brackets scalable");
330 parseandparseagain("left lline a right rline", "Line scalable");
331 parseandparseagain("left ldline d right rdline", "Double line scalable");
332 parseandparseagain("left lbrace e right rbrace", "Brace scalable");
333 parseandparseagain("left langle f right rangle", "Angle bracket scalable");
334 parseandparseagain("left langle g mline h right rangle", "Operator brackets scalable");
335 parseandparseagain("{a} overbrace b", "Over brace scalable");
336 parseandparseagain("{b} underbrace a", "Under brace scalable");
339 void Test::SimpleFormats()
341 parseandparseagain("a lsup{b}", "Left superscript");
342 parseandparseagain("a csup{b}", "Center superscript");
343 parseandparseagain("a^{b}", "Right superscript");
344 parseandparseagain("a lsub{b}", "Left subscript");
345 parseandparseagain("a csub{b}", "Center subscript");
346 parseandparseagain("a_{b}", "Right subscript");
347 parseandparseagain("stack { Hello world # alignl (a) }", "Align character to left");
348 parseandparseagain("stack{Hello world # alignc(a)}", "Align character to center");
349 parseandparseagain("stack { Hello world # alignr(a)}", "Align character to right");
350 parseandparseagain("binom{a}{b}", "Vertical stack of 2");
351 parseandparseagain("stack{a # b # z}", "Vertical stack, more than 2");
352 parseandparseagain("matrix{a # b ## c # d}", "Matrix");
353 parseandparseagain("matrix{a # \"=\" # alignl{b} ## {} # \"=\" # alignl{c+1}}",
354 "Equations aligned at '=' (using 'matrix') ");
355 parseandparseagain("stack{alignl{a} = b # alignl{phantom{a} = c+1}}",
356 "Equations aligned at '=' (using 'phantom') ");
357 parseandparseagain("asldkfjo newline sadkfj", "New line");
358 parseandparseagain("stuff `stuff", "Small gap (grave)");
359 parseandparseagain("stuff~stuff", "Large gap (tilde)");
362 void Test::SimpleGreekChars()
364 parseandparseagain("%ALPHA", "Capital alpha");
365 parseandparseagain("%BETA", "Capital beta");
366 parseandparseagain("%CHI", "Capital chi");
367 parseandparseagain("%DELTA", "Capital delta");
368 parseandparseagain("%EPSILON", "Capital epsilon");
369 parseandparseagain("%ETA", "Capital eta");
370 parseandparseagain("%GAMMA", "Capital gamma");
371 parseandparseagain("%IOTA", "Capital iota");
372 parseandparseagain("%LAMBDA", "Capital lambda");
373 parseandparseagain("%MU", "Capital mu");
374 parseandparseagain("%NU", "Capital nu");
375 parseandparseagain("%OMEGA", "Capital omega");
376 parseandparseagain("%OMICRON", "Capital omicron");
377 parseandparseagain("%PHI", "Capital phi");
378 parseandparseagain("%PI", "Capital pi");
379 parseandparseagain("%PSI", "Capital psi");
380 parseandparseagain("%RHO", "Capital rho");
381 parseandparseagain("%SIGMA", "Capital sigma");
382 parseandparseagain("%TAU", "Capital tau");
383 parseandparseagain("%THETA", "Capital theta");
384 parseandparseagain("%UPSILON", "Capital upsilon");
385 parseandparseagain("%XI", "Capital xi");
386 parseandparseagain("%ZETA", "Capital zeta");
387 parseandparseagain("%alpha", "lowercase alpha");
388 parseandparseagain("%beta", "lowercase beta");
389 parseandparseagain("%chi", "lowercase chi");
390 parseandparseagain("%delta", "lowercase delta");
391 parseandparseagain("%epsilon", "lowercase epsilon");
392 parseandparseagain("%eta", "lowercase eta");
393 parseandparseagain("%gamma", "lowercase gamma");
394 parseandparseagain("%iota", "lowercase iota");
395 parseandparseagain("%kappa", "lowercase kappa");
396 parseandparseagain("%lambda", "lowercase lambda");
397 parseandparseagain("%mu", "lowercase mu");
398 parseandparseagain("%nu", "lowercase nu");
399 parseandparseagain("%omega", "lowercase omega");
400 parseandparseagain("%omicron", "lowercase omicron");
401 parseandparseagain("%phi", "lowercase phi");
402 parseandparseagain("%pi", "lowercase pi");
403 parseandparseagain("%psi", "lowercase psi");
404 parseandparseagain("%rho", "lowercase rho");
405 parseandparseagain("%sigma", "lowercase sigma");
406 parseandparseagain("%tau", "lowercase tau");
407 parseandparseagain("%theta", "lowercase theta");
408 parseandparseagain("%upsilon", "lowercase upsilon");
409 parseandparseagain("%varepsilon", "Varepsilon");
410 parseandparseagain("%varphi", "Varphi");
411 parseandparseagain("%varpi", "Varpi");
412 parseandparseagain("%varrho", "Varrho");
413 parseandparseagain("%varsigma", "Varsigma");
414 parseandparseagain("%vartheta", "Vartheta");
415 parseandparseagain("%xi", "lowercase xi");
416 parseandparseagain("%zeta", "lowercase zeta");
419 void Test::SimpleSpecialChars()
421 parseandparseagain("%and", "And");
422 parseandparseagain("%angle", "Angle");
423 parseandparseagain("%element", "Element");
424 parseandparseagain("%identical", "Identical");
425 parseandparseagain("%infinite", "Infinite");
426 parseandparseagain("%noelement", "No element");
427 parseandparseagain("%notequal", "Not equal");
428 parseandparseagain("%or", "Or");
429 parseandparseagain("%perthousand", "Per thousand");
430 parseandparseagain("%strictlygreaterthan", "Strictly greater than");
431 parseandparseagain("%strictlylessthan", "Strictly less than");
432 parseandparseagain("%tendto", "Tend to");
435 /* This test takes a formula command, parses it, converts the node to text,
436 * parses it again, converts it to text again, and compares the values.
437 * Doing this doesn't prove that it is correct, but it should prove that the
438 * meaning of the original command is not being changed.
440 void Test::parseandparseagain(const char* formula, const char* test_name)
442 OUString output1, output2;
444 // parse 1
445 OUString input = OUString::createFromAscii(formula);
446 auto pNode1 = SmParser5().ParseExpression(input);
447 pNode1->Prepare(xDocShRef->GetFormat(), *xDocShRef, 0);
448 SmNodeToTextVisitor(pNode1.get(), output1);
450 // parse 2
451 auto pNode2 = SmParser5().ParseExpression(output1);
452 pNode2->Prepare(xDocShRef->GetFormat(), *xDocShRef, 0);
453 SmNodeToTextVisitor(pNode2.get(), output2);
455 // compare
456 CPPUNIT_ASSERT_EQUAL_MESSAGE(test_name, output1, output2);
458 // auxiliary test for Accept()
459 std::unique_ptr<MockVisitor> mv(new MockVisitor);
460 pNode1->Accept(mv.get());
461 pNode2->Accept(mv.get());
464 void Test::ParseAndCheck(const char* formula, const char* expected, const char* test_name)
466 OUString sOutput;
468 // parse
469 OUString sInput = OUString::createFromAscii(formula);
470 auto pNode = SmParser5().ParseExpression(sInput);
471 pNode->Prepare(xDocShRef->GetFormat(), *xDocShRef, 0);
472 SmNodeToTextVisitor(pNode.get(), sOutput);
474 // compare
475 OUString sExpected = OUString::createFromAscii(expected);
476 CPPUNIT_ASSERT_EQUAL_MESSAGE(test_name, sExpected, sOutput);
478 // auxiliary test for Accept()
479 std::unique_ptr<MockVisitor> mv(new MockVisitor);
480 pNode->Accept(mv.get());
483 // Parse two formula commands and verify that they give the same output
484 void Test::ParseAndCompare(const char* formula1, const char* formula2, const char* test_name)
486 OUString sOutput1, sOutput2;
488 // parse formula1
489 OUString sInput1(formula1, strlen(formula1), RTL_TEXTENCODING_UTF8);
490 auto pNode1 = SmParser5().ParseExpression(sInput1);
491 pNode1->Prepare(xDocShRef->GetFormat(), *xDocShRef, 0);
492 SmNodeToTextVisitor(pNode1.get(), sOutput1);
494 // parse formula2
495 OUString sInput2(formula2, strlen(formula2), RTL_TEXTENCODING_UTF8);
496 auto pNode2 = SmParser5().ParseExpression(sInput2);
497 pNode2->Prepare(xDocShRef->GetFormat(), *xDocShRef, 0);
498 SmNodeToTextVisitor(pNode2.get(), sOutput2);
500 CPPUNIT_ASSERT_EQUAL_MESSAGE(test_name, sOutput1, sOutput2);
502 // auxiliary test for Accept()
503 std::unique_ptr<MockVisitor> mv(new MockVisitor);
504 pNode1->Accept(mv.get());
505 pNode2->Accept(mv.get());
508 void Test::testBinomInBinHor()
510 OUString sInput, sExpected;
512 // set up a binom (table) node
513 sInput += "binom a b + c";
514 auto pTree = SmParser5().Parse(sInput);
515 pTree->Prepare(xDocShRef->GetFormat(), *xDocShRef, 0);
517 SmCursor aCursor(pTree.get(), xDocShRef.get());
518 ScopedVclPtrInstance<VirtualDevice> pOutputDevice;
520 // move forward (more than) enough places to be at the end
521 int i;
522 for (i = 0; i < 8; ++i)
523 aCursor.Move(pOutputDevice, MoveRight);
525 // tack +d on the end, which will put the binom into an SmBinHorNode
526 aCursor.InsertElement(PlusElement);
527 aCursor.InsertText(u"d"_ustr);
529 sExpected += "{ { binom a { b + c } } + d }";
530 CPPUNIT_ASSERT_EQUAL_MESSAGE("Binom Node in BinHor Node", sExpected, xDocShRef->GetText());
533 void Test::testBinVerInUnary()
535 OUString sInput, sExpected;
537 // set up a unary operator with operand
538 sInput += "- 1";
539 auto pTree = SmParser5().Parse(sInput);
540 pTree->Prepare(xDocShRef->GetFormat(), *xDocShRef, 0);
542 SmCursor aCursor(pTree.get(), xDocShRef.get());
543 ScopedVclPtrInstance<VirtualDevice> pOutputDevice;
545 // move forward (more than) enough places to be at the end
546 int i;
547 for (i = 0; i < 3; ++i)
548 aCursor.Move(pOutputDevice, MoveRight);
550 // select the operand
551 aCursor.Move(pOutputDevice, MoveLeft, false);
552 // set up a fraction
553 aCursor.InsertFraction();
554 aCursor.Move(pOutputDevice, MoveDown);
555 aCursor.InsertText(u"2"_ustr);
557 sExpected += "- { 1 over 2 }";
558 CPPUNIT_ASSERT_EQUAL_MESSAGE("Binary Vertical in Unary Operator", sExpected,
559 xDocShRef->GetText());
562 void Test::testBinHorInSubSup()
564 // set up a blank formula
565 auto pTree = SmParser5().Parse(OUString());
566 pTree->Prepare(xDocShRef->GetFormat(), *xDocShRef, 0);
568 SmCursor aCursor(pTree.get(), xDocShRef.get());
569 ScopedVclPtrInstance<VirtualDevice> pOutputDevice;
571 // Insert an RSup expression with a BinHor for the exponent
572 aCursor.InsertText(u"a"_ustr);
573 aCursor.InsertSubSup(RSUP);
574 aCursor.InsertText(u"b"_ustr);
575 aCursor.InsertElement(PlusElement);
576 aCursor.InsertText(u"c"_ustr);
578 // Move to the end and add d to the expression
579 aCursor.Move(pOutputDevice, MoveRight);
580 aCursor.InsertElement(PlusElement);
581 aCursor.InsertText(u"d"_ustr);
583 CPPUNIT_ASSERT_EQUAL_MESSAGE("BinHor in SubSup", u"{ a ^ { b + c } + d }"_ustr,
584 xDocShRef->GetText());
587 void Test::testUnaryInMixedNumberAsNumerator()
589 // set up a unary operator
590 auto pTree = SmParser5().Parse(u"- 1"_ustr);
591 pTree->Prepare(xDocShRef->GetFormat(), *xDocShRef, 0);
593 SmCursor aCursor(pTree.get(), xDocShRef.get());
594 ScopedVclPtrInstance<VirtualDevice> pOutputDevice;
596 // move forward (more than) enough places to be at the end
597 for (size_t i = 0; i < 3; ++i)
598 aCursor.Move(pOutputDevice, MoveRight);
600 // Select the whole Unary Horizontal Node
601 aCursor.Move(pOutputDevice, MoveLeft, false);
602 aCursor.Move(pOutputDevice, MoveLeft, false);
604 // Set up a fraction
605 aCursor.InsertFraction();
606 aCursor.Move(pOutputDevice, MoveDown);
607 aCursor.InsertText(u"2"_ustr);
609 // Move left and turn this into a mixed number
610 // (bad form, but this could happen right?)
611 aCursor.Move(pOutputDevice, MoveLeft);
612 aCursor.Move(pOutputDevice, MoveLeft);
613 aCursor.InsertText(u"2"_ustr);
615 // move forward (more than) enough places to be at the end
616 for (size_t i = 0; i < 8; ++i)
617 aCursor.Move(pOutputDevice, MoveRight);
619 // add 4 to the end
620 aCursor.InsertElement(PlusElement);
621 aCursor.InsertText(u"4"_ustr);
623 CPPUNIT_ASSERT_EQUAL_MESSAGE("Unary in mixed number as Numerator",
624 u"{ 2 { { - 1 over 2 } + 4 } }"_ustr, xDocShRef->GetText());
627 void Test::testMiscEquivalent()
629 // fdo#55853
630 ParseAndCompare("2x", "2 x", "Number times variable");
631 ParseAndCompare("3x^2", "3 x^2", "Number times power");
633 // i#11752 and fdo#55853
634 ParseAndCompare("x_2n", "x_{2 n}", "Number times variable in subscript");
635 ParseAndCompare("x^2n", "x^{2 n}", "Number times variable in supscript");
637 // fdo#66081
638 ParseAndCompare("{x}", "x", "Variable in brace");
639 ParseAndCompare("{{x+{{y}}}}", "x+y", "Nested braces");
641 // check non-BMP Unicode char
642 ParseAndCompare("{\xf0\x9d\x91\x8e}", "\xf0\x9d\x91\x8e", "non-BMP variable in brace");
643 ParseAndCompare("{ \xf0\x9d\x91\x8e }", "\xf0\x9d\x91\x8e", "non-BMP variable in brace");
645 // tdf#88320
646 ParseAndCompare("A_1,B_2", "A_{1},B_2",
647 "Comma between a digit and non-digit delimits subscript");
649 //tdf#97164
650 ParseAndCompare("100 %", "100\"%\"", "Percent symbol at the end");
653 void Test::testParser()
655 OUString sOutput;
656 auto pNode = SmParser5().ParseExpression(u"{ \U0001D44E }"_ustr); // non-BMP Unicode
657 pNode->Prepare(xDocShRef->GetFormat(), *xDocShRef, 0);
658 SmNodeToTextVisitor(pNode.get(), sOutput);
659 CPPUNIT_ASSERT_EQUAL(u"\U0001D44E"_ustr, sOutput);
662 CPPUNIT_TEST_SUITE_REGISTRATION(Test);
665 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */