/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Copyright (C) 2010-2013 Marchand Eric <ricoh51@free.fr>
This file is part of Freegressi.
Freegressi is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Freegressi is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Freegressi. If not, see <http://www.gnu.org/licenses/>.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
package freegressi.tableur;
import freegressi.parser.Lexer;
import freegressi.parser.Parser;
import java.util.ArrayList;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* Test some expressions
* @author marchand
*/
public class TableurTest {
private static int nBons = 0, nTotal = 0;
private static double eps = 1e-15; // précision demandée lors des comparaisons de double
public TableurTest() {
}
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
/**
* Tests.
*/
@Test
public void testCalcule() {
System.out.println("******* calcule *******");
Tableur tableur = creerTableur();
testOk(tableur, "", 0, Double.NaN);
testOk(tableur, "1/0", 0, Double.NaN);
testOk(tableur, "+1", 0, 1.0);
testOk(tableur, "1+2", 0, 3.0);
testOk(tableur, "-2.0*3", 0, -6.0);
testOk(tableur, "1e3+.5e3",0,1500);
testOk(tableur, "(1)", 0, 1.0);
testOk(tableur, "(((1)))", 0, 1.0);
testOk(tableur, "(-((1)))", 0, -1.0);
testOk(tableur, "(((1)))", 0, 1.0);
testOk(tableur, "pi", 0, Math.PI);
testOk(tableur, "sin(pi)", 0, 0.0);
testOk(tableur, "sin(π)", 0, 0.0);
testOk(tableur, "2^3/2", 0, 4.0);
testOk(tableur, "4/2", 0, 2.0);
testOk(tableur, "1-(4/2)^(6/3)", 0, -3.0);
testOk(tableur, "sin(0)", 0, 0);
testOk(tableur, "sin(asin(0.8))", 0, 0.8);
testOk(tableur, "exp(1)", 0, Math.E);
testOk(tableur, "ln(exp(10))", 0, 10);
testOk(tableur, "cos(0)/2", 0, 0.5);
testOk(tableur, "ln(exp(3*cos(25)/(10^(6/sin(22))+7-ln(3/(45+8))-cos(3/(7+158))+2/(3-4)))-9/(3-5))", 0, 1.7986440284119471);
testOk(tableur, "mean(1,1+1,3)", 0, 2);
testOk(tableur, "mean(x+1)",0,5.5);
testOk(tableur, "mean(x, x, 4.5)", 0, 4.5);
testOk(tableur, "x", 1, 1);
testOk(tableur, "1+y", 1, 4);
testOk(tableur, "deriv(y+y+1,x)", 1, 4);
testOk(tableur, "deriv(1+2*z,x)", 2, 20);
testOk(tableur, "deriv(deriv(y,x),x)", 3, 0);
testOk(tableur, "deriv(x,x)",1,1);
testOk(tableur, "abs(-0.5)", 0, 0.5);
testOk(tableur, "NaN + 1", 0, Double.NaN);
testOk(tableur, "NaN - 1", 0, Double.NaN);
testOk(tableur, "+1", 0, 1.0);
testOk(tableur, "-1", 0, -1.0);
testOk(tableur, "ln(0)", 0, Double.NaN);
testOk(tableur, "1/tan(0)", 0, Double.NaN);
testErreur("=2", 1);
testErreur("*2", 1);
testErreur("(*(2))", 2);
testErreur(")2", 1);
testErreur("mean(1,1+,3)", 9);
testErreur("sin(2)1",7);
testErreur("mean(2)1",8);
testErreur("deriv(2,x)1",11);
testErreur("mean(2,)",7);
testErreur("log(2,3)",1);
testErreur("mean(x,,)", 7);
testErreur("(3,2)", 3);
testErreur("/1", 1);
testDependOf(tableur, "x", "y", true);
testDependOf(tableur, "x", "z", true);
testDependOf(tableur, "x", "w", true);
testDependOf(tableur, "y", "w", false);
testDependOf(tableur, "x", "t", true);
testColonnesDependantes(tableur, "x", "yztw");
testColonneModifiee(tableur);
System.out.println("Calcule : " + nBons + "/"+nTotal+" tests passés avec succès!");
}
private double evalueOk(Tableur tableur, String str, int index) {
ArrayList<Noeud> liste = new ArrayList<>();
try {
Lexer lex = new Lexer( new java.io.StringReader(str), liste );
lex.yylex();
} catch (Exception e) {
System.err.println("Erreur du lexer!");
}
Parser parser = new Parser(liste);
Noeud racine = parser.parser();
if (racine == null) {
return tableur.calcule(racine, index);
}
else {
if (racine.getType() == Sym.ERROR){
System.err.println("Erreur du lexer à la colonne : "+(racine.getColonne()+1));
return Double.NaN;
}
else if (racine.getType() == Sym.PARSER_ERROR) {
System.err.println("Erreur du parser à la colonne : "+(racine.getColonne()+1));
return Double.NaN;
}
else {
}
}
return tableur.calcule(racine, index);
}
private Noeud evalueErreur(String str) {
ArrayList<Noeud> liste = new ArrayList<>();
try {
Lexer lex = new Lexer( new java.io.StringReader(str), liste );
lex.yylex();
} catch (Exception e) {
System.err.println("Erreur du lexer!");
}
Parser parser = new Parser(liste);
Noeud racine = parser.parser();
if (racine == null) {
return null;
}
else {
if (racine.getType() == Sym.ERROR){
return racine;
}
else if (racine.getType() == Sym.PARSER_ERROR) {
return racine;
}
else {
}
}
return racine;
}
private Tableur creerTableur(){
Tableur tabl = new Tableur();
Colonne col1 = new Colonne(tabl, "x", "m");
for (int i = 0; i < 10; i++){
col1.ajoute((double)i);
}
tabl.ajouteColonne(col1);
Colonne col2 = new Colonne(tabl, "y", "m", "2*x+1", Sym.TypeVariable.VARIABLE_CALCULEE);
tabl.ajouteColonne(col2);
Colonne col3 = new Colonne(tabl, "z", "m", "2*x²+2*x+1", Sym.TypeVariable.VARIABLE_CALCULEE);
tabl.ajouteColonne(col3);
Colonne col4 = new Colonne(tabl, "t", "m", "z+1", Sym.TypeVariable.VARIABLE_CALCULEE);
tabl.ajouteColonne(col4);
Colonne col5 = new Colonne(tabl, "w", "m", "x", Sym.TypeVariable.VARIABLE_CALCULEE);
tabl.ajouteColonne(col5);
tabl.calculeTout(10);
return tabl;
}
private void testOk(Tableur tableur, String str, int index, double valeur) {
nTotal++;
double d = evalueOk(tableur, str, index);
boolean ok = true;
// test des valeurs spéciales
if ((Double.isNaN(d) && !Double.isNaN(valeur)) || (!Double.isNaN(d) && Double.isNaN(valeur))){
ok = false;
}
if ((!ok) || (d < valeur-eps || d > valeur+eps)) {
System.out.println("Erreur : \"" + str + "\" =/= " + valeur + " mais vaut " + d);
return ;
}
nBons++;
}
private void testErreur(String str, int colonneErreur) {
nTotal++;
Noeud racine = evalueErreur(str);
if (racine.getType() != Sym.ERROR && racine.getType() != Sym.PARSER_ERROR && racine.getType() != Sym.PARSER_COHERENCE_ERROR) {
System.out.println("Erreur : \"" + str + "\" ne donne pas d'erreur à la colonne " + colonneErreur);
return;
}
if (racine.getColonne()+1 != colonneErreur) {
System.out.println("Erreur : \"" + str + "\" ne donne pas d'erreur à la colonne "
+ colonneErreur + " mais à la colonne " + (racine .getColonne()+1));
return;
}
nBons++;
}
private void testDependOf(Tableur tableur, String var1, String var2, boolean depend){
nTotal++;
Colonne col2 = tableur.donneColonne(var2);
boolean dep = tableur.dependOf(var1, col2.getNoeud());
if (dep == depend){
nBons++;
}else{
System.out.println("Erreur : dépendance de " + var1 + " et "+ var2 + " =/= " + depend + " mais vaut " + dep);
}
}
private void testColonnesDependantes(Tableur tableur, String var1, String dependantes){
nTotal++;
ArrayList<Colonne> liste = tableur.donneListeColonnesDependantes(var1);
String dep = "";
for (Colonne col : liste){
dep += col.getColonneDescription().getNom();
}
if (dep.equals(dependantes)){
nBons++;
}else{
System.out.println("Erreur : dépendantes(\"" + var1 + "\") =/= " + dependantes + " mais vaut " + dep);
}
}
private void testColonneModifiee(Tableur tableur){
Colonne column = tableur.donneColonne("x");
tableur.modifieColonne(column, "x1", "", "");
//System.out.println("testColonneModifiée y : " + tableur.donneColonne("y").getColonneDescription().getExpression());
testDependOf(tableur, "x1", "y", true);
testColonnesDependantes(tableur, "x1", "yztw");
}
}