package org.geogebra.commands; import java.util.Locale; import org.geogebra.common.kernel.StringTemplate; import org.geogebra.common.kernel.commands.AlgebraProcessor; import org.geogebra.common.kernel.kernelND.GeoConicND; import org.geogebra.common.kernel.kernelND.GeoElementND; import org.geogebra.common.util.lang.Unicode; import org.geogebra.desktop.main.AppDNoGui; import org.geogebra.desktop.main.LocalizationD; import org.junit.Assert; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; public class AlgebraStyleTest extends Assert { static AppDNoGui app; static AlgebraProcessor ap; private static void checkRows(String def, int rows) { GeoElementND[] el = ap.processAlgebraCommandNoExceptionHandling(def, false, TestErrorHandler.INSTANCE, false, null); assertEquals(rows, el[0].needToShowBothRowsInAV() ? 2 : 1); } private static void checkEquation(String def, int mode, String check) { GeoElementND[] el = ap.processAlgebraCommandNoExceptionHandling(def, false, TestErrorHandler.INSTANCE, false, null); ((GeoConicND) el[0]).setToStringMode(mode); assertEquals(check.replace("^2", Unicode.Superscript_2 + ""), el[0].toValueString(StringTemplate.defaultTemplate)); } @Before public void resetSyntaxes(){ app.getKernel().clearConstruction(true); } @BeforeClass public static void setupApp() { app = new AppDNoGui(new LocalizationD(3), true); app.setLanguage(Locale.US); ap = app.getKernel().getAlgebraProcessor(); // make sure x=y is a line, not plane app.getGgbApi().setPerspective("1"); // Setting the general timeout to 11 seconds. Feel free to change this. app.getKernel().getApplication().getSettings().getCasSettings().setTimeoutMilliseconds(11000); } @Test public void twoRowsAlgebra() { checkRows("a=1", 1); checkRows("a+a", 2); checkRows("sqrt(x+a)", 2); checkRows("{a}", 2); checkRows("{x}", 1); checkRows("{x+a}", 2); checkRows("{{1}}", 1); checkRows("{{a}}", 2); checkRows("{{a}}+{{1}}", 2); checkRows("{x=y}", 2); checkRows("x=y", 2); checkRows("{y=x}", 1); checkRows("Sequence[100]", 2); } @Test public void checkEquationExplicit() { checkEquation("x^2+4*y^2=1", GeoConicND.EQUATION_EXPLICIT, "x^2 + 4y^2 = 1"); checkEquation("x^2+4*y^2-y+x*y=x +x -1", GeoConicND.EQUATION_EXPLICIT, "x^2 + x y + 4y^2 - 2x - y = -1"); checkEquation("-x^2=x +x -1", GeoConicND.EQUATION_EXPLICIT, "-x^2 - 2x = -1"); } @Test public void checkEquationVertex() { // ellipse: fallback to explicit checkNonParabolaFallback(GeoConicND.EQUATION_VERTEX); // three actual parabolas checkEquation("-x^2=x +x -1+y", GeoConicND.EQUATION_VERTEX, "y = -(x + 1)^2 +2"); checkEquation("x^2=x +x -1+y", GeoConicND.EQUATION_VERTEX, "y = (x - 1)^2"); checkEquation("y^2=y +y -1+x", GeoConicND.EQUATION_VERTEX, "(x - 0) = (y - 1)^2"); } @Test public void checkEquationSpecific() { // ellipse checkEquation("x^2+4*y^2=1", GeoConicND.EQUATION_SPECIFIC, "x^2 / 1 + y^2 / 0.25 = 1"); // hyperbola checkEquation("x^2-4*y^2=2x+2y+1", GeoConicND.EQUATION_SPECIFIC, "(x - 1)^2 / 1.75 - (y + 0.25)^2 / 0.44 = 1"); // double line checkEquation("-x^2=x +x -1", GeoConicND.EQUATION_SPECIFIC, "(-x - 2.41) (-x + 0.41) = 0"); // parabolas checkEquation("-x^2-x=x -1+y", GeoConicND.EQUATION_SPECIFIC, "x^2 = -2x - y + 1"); checkEquation("y^2=x +x -1+y", GeoConicND.EQUATION_SPECIFIC, "y^2 = 2x + y - 1"); checkEquation("(x+y)^2=x +x -1+y", GeoConicND.EQUATION_SPECIFIC, "x^2 + 2x y + y^2 - 2x - y = -1"); } @Test public void checkEquationConicform() { checkNonParabolaFallback(GeoConicND.EQUATION_CONICFORM); // parabolas checkEquation("-x^2-x=x -1+y", GeoConicND.EQUATION_CONICFORM, "-(y - 2) = (x + 1)^2"); checkEquation("y^2=x +x -1+y", GeoConicND.EQUATION_CONICFORM, "2(x - 0.38) = (y - 0.5)^2"); checkEquation("(x+y)^2=x +x -1+y", GeoConicND.EQUATION_CONICFORM, "x^2 + 2x y + y^2 - 2x - y = -1"); } @Test public void checkEquationParametric() { // ellipse checkEquation("x^2+4*y^2=1", GeoConicND.EQUATION_PARAMETRIC, "X = (0, 0) + (cos(t), 0.5 sin(t))"); // hyperbola checkEquation("x^2-4*y^2=2x+2y+1", GeoConicND.EQUATION_PARAMETRIC, "X = (1, -0.25) + (" + Unicode.PLUSMINUS + " 1.32 cosh(t), 0.66 sinh(t))"); // double line TODO wrong checkEquation("-x^2=x +x -1", GeoConicND.EQUATION_PARAMETRIC, "X = (-1 " + Unicode.PLUSMINUS + " 1.41, 0, 0) + " + Unicode.lambda + " (0, 1, 0)"); // parabolas checkEquation("-x^2-x=x -1+y", GeoConicND.EQUATION_PARAMETRIC, "X = (-1, 2) + (-0.5 t, -0.25 t^2)"); checkEquation("y^2=x +x -1+y", GeoConicND.EQUATION_PARAMETRIC, "X = (0.38, 0.5) + (0.5 t^2, t)"); checkEquation("(x+y)^2=x +x -1+y", GeoConicND.EQUATION_PARAMETRIC, "X = (0.81, -0.06) + (0.06 t^2 + 0.13 t, -0.06 t^2 + 0.13 t)"); } @Test public void checkEquationImplicit() { // ellipse checkEquation("x^2+4*y^2=1", GeoConicND.EQUATION_IMPLICIT, "x^2 + 4y^2 = 1"); // hyperbola checkEquation("x^2-4*y^2=2x+2y+1", GeoConicND.EQUATION_IMPLICIT, "x^2 - 4y^2 - 2x - 2y = 1"); // double line TODO wrong checkEquation("-x^2=x +x -1", GeoConicND.EQUATION_IMPLICIT, "-x^2 - 2x = -1"); // parabolas checkEquation("-x^2-x=x -1+y", GeoConicND.EQUATION_IMPLICIT, "-x^2 - 2x - y = -1"); checkEquation("y^2=x +x -1+y", GeoConicND.EQUATION_IMPLICIT, "y^2 - 2x - y = -1"); checkEquation("(x+y)^2=x +x -1+y", GeoConicND.EQUATION_IMPLICIT, "x^2 + 2x y + y^2 - 2x - y = -1"); } private static void checkNonParabolaFallback(int mode) { // ellipse checkEquation("x^2+4*y^2=1", mode, "x^2 + 4y^2 = 1"); // hyperbola checkEquation("x^2-4*y^2=2x+2y+1", mode, "x^2 - 4y^2 - 2x - 2y = 1"); // double line checkEquation("-x^2=x +x -1", mode, "-x^2 - 2x = -1"); } }