Package kiss.test

Source Code of kiss.test.ExpressionTests

package kiss.test;

import static org.junit.Assert.*;
import kiss.lang.Analyser;
import kiss.lang.Expression;
import kiss.lang.Type;
import kiss.lang.expression.Application;
import kiss.lang.expression.Constant;
import kiss.lang.expression.Def;
import kiss.lang.expression.Do;
import kiss.lang.expression.If;
import kiss.lang.expression.Lambda;
import kiss.lang.expression.Let;
import kiss.lang.expression.Lookup;
import kiss.lang.expression.Loop;
import kiss.lang.impl.KissException;
import kiss.lang.impl.KissUtils;
import kiss.lang.type.Anything;
import kiss.lang.type.FunctionType;

import org.junit.Test;

import clojure.lang.IFn;
import clojure.lang.IPersistentSet;
import clojure.lang.ISeq;
import clojure.lang.PersistentHashSet;
import clojure.lang.Symbol;

public class ExpressionTests {
 
  static final Expression[] testExprs={
    Constant.create(null),
    Constant.create("friend"),
    Let.create(Symbol.intern("foo"), Constant.create(3), Lookup.create("foo")),
    Lambda.IDENTITY,
    Lookup.create("foo"),
    If.create(Constant.create(null), Constant.create(1), Constant.create(2)),
    Loop.create(new Symbol[] {Symbol.intern("foo")},
          new Expression[] {Constant.create(3)},
          Constant.create(4)),
    Do.create(Constant.create(1)),
    Do.create(Constant.create(1),Lookup.create("foo")),
    Application.create(Lambda.IDENTITY, Constant.create(3))
  };
 
  @Test
  public void testIdentity() {
    Lambda id=Lambda.IDENTITY;
    FunctionType ft=(FunctionType) id.getType();
    assertEquals(Anything.INSTANCE,ft.getReturnType());
    IFn fn=(IFn) id.eval();
    assertEquals(1,fn.invoke(1));
    assertTrue(ft.checkInstance(fn));
  }
 
  @Test
  public void testSpecialise() {
    for (Expression e:testExprs) {
      Type ert=e.getType();
      Expression se=e.specialise(e.getType());
      assertTrue("Specialise has widened return type!! "+e, ert.contains(se.getType()));
    }
  }
 
  @Test
  public void testSubstitutions() {
    for (Expression e:testExprs) {
      try {
        IPersistentSet free=e.accumulateFreeSymbols(PersistentHashSet.EMPTY);
        if (free.count()==0) {
          Object result=e.eval(); // should work
          assertTrue(e.getType().checkInstance(result));
        } else {
          try {
            e.eval();
            fail();
          } catch (KissException t) {
            // OK!
          }
        }       
      } catch (Throwable t) {
        throw new KissException("Error testing expression "+e,t);
      }
    }
  }
 
  @Test
  public void testProperties() {
    for (Expression e:testExprs) {
      try {
        e.validate();   
      } catch (Throwable t) {
        throw new KissException("Error testing expression "+e,t);
      }
    }   
  }
 
  @Test
  public void testConstants() {
    assertNull(Constant.create(null).eval());
    assertEquals(1,Constant.create(1).eval());
    assertEquals("foo",Constant.create("foo").eval());
  }
 
  @Test
  public void testOptimisations() {
    checkConstant(1,Constant.create(1));
    checkConstant(2,If.create(Constant.create(1),Constant.create(2),Constant.create(3)));
    checkConstant(3,Do.create(Constant.create(1),Constant.create(2),Constant.create(3)));
    checkConstant(3,Let.create(Symbol.create("foo"),Constant.create(3),Lookup.create("foo")));
  }
 
  @Test
  public void testLet() {
    assertEquals(10L, KissUtils.eval("(let [a 10 b a] b)"));
  }
 
  @Test
  public void testInstanceOf() {
    assertTrue(Analyser.analyse(KissUtils.read("(instance? Integer 2)")).isConstant());
    assertEquals("foo", KissUtils.eval("(if (instance? Long 3) \"foo\" \"bar\")"));
  }
 
  @Test
  public void testNotConstant() {
    checkNotConstant(Lookup.create("foo"));
    checkNotConstant(Def.create(Symbol.intern("foo"),Constant.create(1)));
  }
 
  private void checkNotConstant(Expression x) {
    Expression opt=x.optimise();
    assertFalse("Expression is constant: "+x,opt.isConstant());
  }
 
  private void checkConstant(Object expected,Expression x) {
    Expression opt=x.optimise();
    assertTrue("Expression not constant: "+x,opt.isConstant());
    assertEquals(expected,opt.eval());
  }

  @Test
  public void testIf() {
    assertEquals(2,If.create(Constant.create(null), Constant.create(1), Constant.create(2)).eval());
   
    ISeq s=KissUtils.createSeq(Symbol.intern("if"),Symbol.intern("nil"),1,2);
    Expression x=Analyser.analyse(s);
    assertEquals(2,x.eval());

  }
}
TOP

Related Classes of kiss.test.ExpressionTests

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.