/* Copyright 2011 Toby D. Rule
This file is part of CompPad, an OpenOffice extension to provide live
mathematical and engineering calculations within a Writer document.
CompPad 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.
CompPad 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 CompPad. If not, see <http://www.gnu.org/licenses/>.
*/
package com.CompPad;
import com.CompPad.model.ComplexAmount;
import com.CompPad.model.Listener;
import com.CompPad.model.Operators;
import java.io.IOException;
import junit.framework.TestCase;
import com.CompPad.shell.Shell;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Not exactly a unit test, but testing basic integrated functionality of
* computational model.
* @author trule
*/
// how to test OOO classes?!
public class CompPadTest extends TestCase{
Shell testShell ;
Object o;
String setup[] = {
"a := 2",
"aa := -5", /* Testing negative operator */
"ax := 0.7",
"b := 3 m",
"b2 := 5 m",
"bb := 4 rad",
"c := 5 + 6 i",
"d := (7 + 8 i) m",
"d2 := (5 + 9 i ) m",
"dd := (7 + 8 i) rad",
"A:= matrix {1 # 2 ## 3 # 4 }",
"B:= A m",
"BB := A rad",
"C := A c",
"D := A d",
"v := matrix {7 ## 8}",
"vv := (9,10)" ,
"v_2 := matrix{7 ## 8 ## 9 ## 10}",
"v_3 := (7,8,9,10)",
"j := false","k := true",
"E1 := matrix {true#false ## false # true }",
"E2 := matrix {false # false##true # true }",
"e1 := matrix {true ## false }",
};
public CompPadTest(String testName) throws Exception {
super(testName);
}
@Override
protected void setUp() throws Exception {
super.setUp();
System.out.println ("setUp");
testShell = new Shell();
o = testShell.evaluate(setup);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
public void testSigFigs() throws Exception{
/* At least make sure it doesn't crash */
System.out.println("testSigFigs");
String expressions[] ={"setSigFigs(3)",
"%pi","1000000 %pi",
"setDecimalSeparator(\",\")",
"x:= 1,234", "x",
"100000 %pi ", "%pi over 100000","setSigFigs(10)","100000 %pi","%pi over 100000",
"round (1,23456;0,1)","A := 1,2 ; 2,3 ; 3,4",
"setDecimalSeparator(\".\")",
"setThousandsSeparator(\",\")"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testPlot() throws Exception{
/* At least make sure it doesn't crash */
System.out.println("testPlot");
String expressions[] ={
"x := 0 dotslow 10",
"A := (x, widevec{x^2})",
"B := (x, 10 x)",
"plotxy(A)", "plotxy(A,B)"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testRoundRand() throws Exception{
System.out.println("testing rounding and rand functions");
String expressions[] ={
/* remember to test comparison between boolean values */
"round(0.5,1)", /* Make sure 0.5 rounds to 1! */
"round 1, 0.3", /* This really shouldn't work! But it does as long
* as precedence is correct */
"round(a, 0.3)", "round(b,FOOT)",
"ceil(a,0.3)", "ceil(b,FOOT)",
"floor(a,0.3)","floor(b,FOOT)",
"round {widevec{A^2}} {A/3}",
"round(A,0.4)", "round({widevec{A^2}} , A/3)", "round(20.5,A)",
/* Need to fix parser so that
* if it is expecting more than one argument, it will
* wait for the separator rather than rely on
* precedence of that function
*
* SO - basically check precedence, OR if it is still expecting
* multiple args */
"ceil(A,0.4)","ceil({widevec{A^2}},A)", "ceil (20.5, A)",
"floor(A,0.4)","floor({widevec{A^2}},A)", "floor (20.5,A)",
"rand(0,0)","rand(2,3)",
"zeros(0,0)","zeros(2,3)",
"ones(0,0)","ones(2,3)",
"setSigFigs(6)", "%pi","setSigFigs(3)","%pi"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testComparison() throws Exception{
System.out.println("testComparison");
String expressions[] ={
/* remember to test comparison between boolean values */
"D1 := A d", "D2 := matrix {1 # 3 ## 2 # 4 } d",
"d > d2","d < d2", "d >= d2", "d <= d2", "{d = d2}=", "d <> d2",
"d > d","d < d", "d >= d", "d <= d", "d = d", "d <> d",
"{D1 = D2}=", "D1 <> D2", "D1 > D2","D1 < D2", "D1 >= D2", "D1 <= D2",
"{E1 = E2}=","E1 <> E2" // equals sign is treated as comparison when evaluated inside group.
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
((Exception)o).printStackTrace();
fail(o.toString());
}
}
public void testFunctionDef() throws Exception{
System.out.println("testing function definition");
String expressions[] ={
"f_1(x,y):=x + 2 y" , "f_1(1,2)" , "g_1 := f_1" , "g_1(3,4)",
"f_1(x,y):=sin x + cos y" ,
"f_2(x,y):=x^y",
"f_1(7,8) + f_2(7,8)",
"f_1(7,8) + 2 + f_2(7,8)",
/* we have to define a prototype with same number of arguments,
* otherwise it doesn't parse correctly. It is parsed when it is
* defined, so it needs to know to parse x as a function with two
* args. Otherwise it parses as a quantity x times a row vector.*/
"x(a,b):= \"dummy\"",
/* pass a function as an argument */
"h(x):= x(7,8)",
"h(f_1)",
"f(a,b):= 0","g(a,b):= 0", /* Dummy "prototype" functions */
"h_2(f,g):=f(1,2)+g(3,4)",
"h_2(f_1,f_2)",
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
/**
* Test of main method, of class TestFormulas.
*/
public void testTest() throws Exception{
System.out.println("testTest");
/* get real and imaginary components */
String expressions[] ={
"%% Expression with only a comment","x := 1","x =",
"{{bar x sub 1 ^ 2}} := 3 =","{{bar x sub 1 ^ 2}} =",
"Re(d)", "Im(d)", "d^\"*\"", "arg d","sgn d",
"Re(A d)","Im(A d)","(A d)^\"*\"", "arg (A d)","sgn (A d)"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
class TestListener implements Listener{
public void setValue(Object arg) throws Exception {
throw new UnsupportedOperationException("Not supported yet.");
}
public Object getValue() {
throw new UnsupportedOperationException("Not supported yet.");
}
public void refresh() {
throw new UnsupportedOperationException("Not supported yet.");
}
}
public void testAdd() throws Exception {
System.out.println("testAdd");
String expressions[] = {
"a + a", "a + c", "c + a",
"b + b", "b + d", "d + b",
"c + c",
"d+ d",
"a + A", "A + a",
"A + A",
"A + v"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testSub() throws Exception {
System.out.println("testSub");
String expressions[] = {
"a - a", "a - c", "c - a",
"b - b", "b - d", "d - b",
"c - c",
"d - d",
"a - A", "A - a",
"A - A",
"A - v", "v - A",
"- 5","- sin (a)" // test unary minus
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testMult() throws Exception {
System.out.println("testMult");
String expressions[] = {
"a a", "a * b", "b times a", "a c", "c a", "a d", "d a",
"a j","a k","j a","k a", /* boolean multiplication */
"b b", "b c", "c b", "b d", "d b",
"c c", "c d", "d c",
"d d","widevec{d d}",
"a A", "widevec{a A}","A a","widevec{A a}",
"widevec{A A}","widevec{ (A A ) A}",
"widevec{A v}", "widevec{v A}",
"A A", "A v", "vv A"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testDiv() throws Exception{
System.out.println("testDiv");
String expressions[] ={
"a / a","a over b", "b / a", "a / c", "c / a","a / d", "d / a ",
"b / b", "b / c", "c / b", "b / d", "d / b",
"c / c", "c / d", "d / c",
"d / d","widevec{d / d}",
"widevec{A / A}", "widevec{a / A}",
"widevec{A / v}", "widevec{v / A}",
"A / a", "widevec{A / a}"
//, "a / A", "A / A" // pseudoinverse not supported
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testPow() throws Exception{
System.out.println("testPow");
String expressions[] ={
"a ^ aa" , "a ^ c","- 2 ^ - 2",
"b ^ aa" , /* can't raise units to complex power */
"(b^3)^{1/3}","(d^3)^{1/3}",
"c ^ aa" , "c ^ c",
"d ^ aa" , /* can't raise units to complex power */
"widevec{A ^ aa}","widevec{aa ^ aa}",
"widevec{A^A}", "widevec{A ^ v}",
"widevec{v ^ A}" ,
"aa ^ A" , "A ^ aa"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testRoot() throws Exception{
System.out.println("testSqrt");
String expressions[] ={
"sqrt{(-2)^2}", // This was returning -2 at one time
"sqrt{a}", "sqrt(b^2)", "sqrt(c)", "sqrt(d^2)",
"widevec{sqrt(A)}","widevec{sqrt(a)}",
"nroot {3} {5}", "nroot {3} {b^3}",
"nroot {A} {aa}","widevec{nroot {A} {aa}}",
"widevec{nroot {aa} {A}}",
"widevec{nroot {A} {A}}",
"widevec{nroot{a} {a}}"
//"sqrt(A)" // This is a valid operation but JScience doesn't implement
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testAbs() throws Exception{
/* Absolute value */
System.out.println("testAbs");
String expressions[] ={
" left lline aa right rline ", "lline -a rline",
"lline -b rline ", "lline -c rline", "lline -d rline"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testConstants() throws Exception{
System.out.println("testConstants");
String expressions[] ={
"%pi",
"e",
"METER",
"FOOT"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testTrig() throws Exception{
System.out.println("testTrig");
String expressions[] ={
"sin(bb)","sin(c)","sin(BB)",
"cos(bb)","cos(c)","cos(BB)",
"tan(bb)","tan(c)","tan(BB)",
"sec(bb)","sec(c)","sec(BB)",
"cot(bb)","cot(c)","cot(BB)",
"csc(bb)","csc(c)","csc(BB)",
"sin2(bb)","sin2(c)","sin2(BB)",
"cos2(bb)","cos2(c)","cos2(BB)",
"tan2(bb)","tan2(c)","tan2(BB)",
"sec2(bb)","sec2(c)","sec2(BB)",
"cot2(bb)","cot2(c)","cot2(BB)",
"csc2(bb)","csc2(c)","csc2(BB)",
"asin(ax)","asin(widevec{A^-1})",
"acos(ax)","acos(widevec{A^-1})",
"atan(a)","atan(widevec{A^-1})",
"sin^-1 ax","sin^-1 c","sin^-1 ( widevec{A^-1})",
"cos^-1 ax","cos^-1 c","cos^-1 (widevec{A^-1})",
"tan^-1 a","tan^-1 c","tan^-1 (widevec{A^-1})",
"cot^-1 ax","cot^-1 c","cot^-1 (widevec{A^-1})",
"csc^-1 aa","csc^-1 c","csc^-1 (A)",
"sec^-1 aa","sec^-1 c","sec^-1 (A)"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testLogarithms() throws Exception{
System.out.println("testLogarithms");
String expressions[] ={
"ln (a)", "log_10 (a)","log_2 (a)",
"ln(A)","log_10 (A)","log_2 (a)"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testMatrix() throws Exception{
System.out.println("testTranspose");
/* Transpose, unity matrix */
String expressions[] ={
"A^T", "v^T", "vv^T",
"sizeOf A", "rows A", "columns A",
"matrix{1#2##3#4}" /* Make sure it allows no-space between */
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testMinMax() throws Exception{
System.out.println("testMinMax");
String expressions[] ={
"min(A)","min(B)","min(C)","min(D)",
"max(A)","max(B)","max(C)","max(D)"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testSum() throws Exception{
/* this is a vector operator. It will operate on row-
* or column- vectors. Will be applied row-wise to matrices */
System.out.println("testSum");
String expressions[] ={
"sum A"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testProd() throws Exception{
/* this is a vector operator. It will operate on row-
* or column- vectors. Will be applied row-wise to matrices */
System.out.println("testProd");
String expressions[] ={
"prod A"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testRange() throws Exception{
/* test ... */
System.out.println("testRange");
String expressions[] ={
"3 dotslow 7", "7 dotslow 3", " -3 dotslow 7 ", "7 dotslow -3"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testSubscript() throws Exception{
/* matrix subscripts */
System.out.println("testSubscript");
String expressions[] ={
"0 dotslow 3, 1 dotslow 4",
"A sub {1,1}", // comma does addrow
"A sub {0 dotslow 1, 0 dotslow 1}", // dotslow does addcolumn
"A sub {0 dotslow 1, 1}",
"A sub {0, 0 dotslow 1}",
"v sub 1",
"vv sub 1",
"v_2 sub {1 dotslow 2}",
"v_3 sub {2 dotslow 3}"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testMatrixConcatenate() throws Exception{
/* Adding rows and columns to a matrix */
System.out.println("testMatrixConcatenate");
String expressions[] ={
/* Horizontally, allow concatenating any two matrices,
* filling the mismatched elements with "null" */
"{A,A}", "{A,v}","{A,a}",
"{v,vv^T}", "{v^T,vv}","{v,vv}",
/* Vertically, only allow concatenating
* row vectors where A.n = v.n
* This syntax will probably change, to allow
* creating matrices of matrices. But for now it's
* convenient. */
"matrix {A ## vv}"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testBoolean() throws Exception{
System.out.println("testBoolean");
String expressions[] ={
"neg j", "j and k", "j or k",
"neg E1", "E1 and E2", "E1 or E2",
"e1 and E1", "e1 or E1",
"k and E2","k or E2"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testComplex() throws Exception{
System.out.println("testComplex");
/* get real and imaginary components */
String expressions[] ={
"Re(c)", "Im(c)", "c^\"*\"=", "arg c","sgn c",
"Re(d)", "Im(d)", "d^\"*\"", "arg d","sgn d",
"Re(A d)","Im(A d)","(A d)^\"*\"", "arg (A d)","sgn (A d)"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testColor() throws Exception{
/* At least make sure it doesn't crash */
System.out.println("testColor");
String expressions[] ={
"color red { %lambda_1 := 1 } ",
"color green{\u03bb_2 := 2}",
"color purple {%lambda_1}","color white {\u03bb_2 }",
"color blue {%lambda_1}","color white {\u03bb_2 }"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testSymbols() throws Exception{
/* At least make sure it doesn't crash */
System.out.println("testSymbols");
String expressions[] ={
"%lambda_1 := 1",
"\u03bb_2 := 2",
"%lambda_1","\u03bb_2"
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testOutput() throws Exception{
/* At least make sure it doesn't crash */
System.out.println("testOutput");
String expressions[] ={
"\"This is a string\""
};
o = testShell.evaluate(expressions);
if (Exception.class.isInstance(o)){
fail(o.toString());
}
}
public void testErrors (){
/* test that correct errors are thrown */
// UnitSystem="US" // this should be UnitSystem:="US"
// x= // variable not defined
//
fail ("test not implemented");
}
}