/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ca.mcmaster.cas.matlab2smt.test;

import ca.mcmaster.cas.matlab2smt.BooleanVariableType;
import ca.mcmaster.cas.matlab2smt.CVC3Generator;
import ca.mcmaster.cas.matlab2smt.CheckerGenerator;
import ca.mcmaster.cas.matlab2smt.FixedPointVariableType;
import ca.mcmaster.cas.matlab2smt.RealVariableType;
import ca.mcmaster.cas.matlab2smt.Variable;
import ca.mcmaster.cas.matlab2smt.VariableParser;
import static org.junit.Assert.*;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;


/**
 *
 * @author matthew
 */
@RunWith(JUnit4.class)
public class VariableParserTest {
    @Test
    public void testSimpleVariable() {
        VariableParser vars = new VariableParser("a");
        Variable a = vars.getVar("a");
        assertEquals("a", a.name());
        assertEquals(new RealVariableType(), a.type());
    }
    @Test
    public void testRealVariable() {
        VariableParser vars = new VariableParser("a: real");
        Variable a = vars.getVar("a");
        assertEquals("a", a.name());
        assertEquals(new RealVariableType(), a.type());
    }
    @Test
    public void testBooleanVariable() {
        VariableParser vars = new VariableParser("a: bool");
        Variable a = vars.getVar("a");
        assertEquals("a", a.name());
        assertEquals(new BooleanVariableType(), a.type());
    }
    @Test
    public void testFixedPointNoDecimalVariable() {
        VariableParser vars = new VariableParser("a: fixedt(1, 16)");
        Variable a = vars.getVar("a");
        FixedPointVariableType type = (FixedPointVariableType)a.type();
        assertEquals("a", a.name());
        assertNotNull(type);
        assertEquals(true, type.isSigned());
        assertEquals(16, type.digits());
        assertEquals(0, type.fractionPart());
        
        vars = new VariableParser("a: fixedt(0, 15, 4)");
        a = vars.getVar("a");
        type = (FixedPointVariableType)a.type();
        assertEquals("a", a.name());
        assertNotNull(type);
        assertEquals(false, type.isSigned());
        assertEquals(15, type.digits());
        assertEquals(4, type.fractionPart());
    }
    @Test
    public void testCaseInsensitivtySearch() {
        VariableParser vars = new VariableParser("a: ReAl");
        Variable a = vars.getVar("a");
        assertEquals("a", a.name());
        assertEquals(new RealVariableType(), a.type());
        
        vars = new VariableParser("A: REAL");
        a = vars.getVar("A");
        assertEquals("A", a.name());
        assertEquals(new RealVariableType(), a.type());
    }
    @Test
    public void testMultiVariableOutput() {
        VariableParser vars = new VariableParser("a,b");
        try {
            assertEquals("a:REAL;\nb:REAL\n;", vars.getCheckerOutput(generator));
        } catch(AssertionError e) {
            //Depending upon maps sort order, either a or be may be first.  Either is correct, so if the first test fails, retry with order reversed.
            assertEquals("b:REAL;\na:REAL;\n", vars.getCheckerOutput(generator));
        }
        
        vars = new VariableParser("a:fixedt(1,16,9),b");
        try {
            assertEquals("a:BITVECTOR(16);\nb:REAL\n;", vars.getCheckerOutput(generator));
        } catch(AssertionError e) {
            //Depending upon maps sort order, either a or be may be first.  Either is correct, so if the first test fails, retry with order reversed.
            assertEquals("b:REAL;\na:BITVECTOR(16);\n", vars.getCheckerOutput(generator));
        }
    }

    CheckerGenerator generator = new CVC3Generator();
}
