/*
* Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of Business Objects nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/*
* BasicCALServices_Test.java
* Creation date: Feb 24, 2005.
* By: Joseph Wong
*/
package org.openquark.cal.services;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import junit.extensions.TestSetup;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.openquark.cal.CALPlatformTestModuleNames;
import org.openquark.cal.compiler.AdjunctSource;
import org.openquark.cal.compiler.CompilerMessage;
import org.openquark.cal.compiler.CompilerMessageLogger;
import org.openquark.cal.compiler.CompilerTestUtilities;
import org.openquark.cal.compiler.MessageLogger;
import org.openquark.cal.compiler.QualifiedName;
import org.openquark.cal.compiler.Scope;
import org.openquark.cal.compiler.SourceModel;
import org.openquark.cal.compiler.SourceModelModuleSource;
import org.openquark.cal.compiler.SourceModelUtilities;
import org.openquark.cal.compiler.io.EntryPoint;
import org.openquark.cal.compiler.io.EntryPointSpec;
import org.openquark.cal.internal.machine.EntryPointImpl;
import org.openquark.cal.machine.CALExecutor;
import org.openquark.cal.module.Cal.Collections.CAL_Array;
import org.openquark.cal.module.Cal.Core.CAL_Prelude;
import org.openquark.cal.runtime.CALExecutorException;
import org.openquark.cal.runtime.MachineType;
/**
* A set of JUnit test cases for the BasicCALServices class from the services package.
*
* @author Joseph Wong
*/
public class BasicCALServices_Test extends TestCase {
private static final String Prelude_Num = CAL_Prelude.TypeClasses.Num.getQualifiedName();
/**
* A copy of CAL services for use in the test cases.
*/
private static BasicCALServices leccCALServices;
private static BasicCALServices gCALServices;
/**
* Set this flag to true if debugging output is desired regardless of
* whether a test fails or succeeds.
*/
private static final boolean SHOW_DEBUGGING_OUTPUT = false;
/**
* @return a test suite containing all the test cases for testing CAL source
* generation.
*/
public static Test suite() {
TestSuite suite = new TestSuite(BasicCALServices_Test.class);
return new TestSetup(suite) {
@Override
protected void setUp() {
oneTimeSetUp();
}
@Override
protected void tearDown() {
oneTimeTearDown();
}
};
}
/**
* Performs the setup for the test suite.
*/
private static void oneTimeSetUp() {
leccCALServices = CALServicesTestUtilities.getCommonCALServices(MachineType.LECC, "cal.platform.test.cws");
gCALServices = CALServicesTestUtilities.getCommonCALServices(MachineType.G, "cal.platform.test.cws");
}
/**
* Performs the tear down for the test suite.
*/
private static void oneTimeTearDown() {
leccCALServices = null;
gCALServices = null;
}
/**
* Constructor for BasicCALServices_Test.
*
* @param name
* the name of the test.
*/
public BasicCALServices_Test(String name) {
super(name);
}
/**
* Tests the finding of gems with a particular type through the method
* BasicCALServices.findGemsOfType().
*/
public void testFindGemsOfType() {
help_testFindGemsOfType(leccCALServices);
help_testFindGemsOfType(gCALServices);
}
private void help_testFindGemsOfType(BasicCALServices calServices) {
Collection<GemEntity> gems = calServices.findGemsOfType(CALServicesTestUtilities.DEFAULT_UNIT_TEST_MODULE, Prelude_Num + " a => a -> a -> a", true);
Iterator<GemEntity> it = gems.iterator();
boolean hasSubtract = false;
String lastGemQualifiedName = "";
while (it.hasNext()) {
GemEntity gem = it.next();
if (gem.getName().equals(CAL_Prelude.Functions.subtract)) {
hasSubtract = true;
}
String gemQualifiedName = gem.getName().getQualifiedName();
assertTrue(gemQualifiedName.compareToIgnoreCase(lastGemQualifiedName) >= 0);
lastGemQualifiedName = gemQualifiedName;
}
assertTrue(hasSubtract);
}
/**
* Tests the finding of gems with a particular return type through the method
* BasicCALServices.findGemsByReturnType().
*/
public void testFindGemsByReturnType() {
help_testFindGemsByReturnType(leccCALServices);
help_testFindGemsByReturnType(gCALServices);
}
private void help_testFindGemsByReturnType(BasicCALServices calServices) {
Collection<GemEntity> gems = calServices.findGemsByReturnType(CALServicesTestUtilities.DEFAULT_UNIT_TEST_MODULE, Prelude_Num + " a => a", true);
Iterator<GemEntity> it = gems.iterator();
boolean hasSubtract = false;
String lastGemQualifiedName = "";
while (it.hasNext()) {
GemEntity gem = it.next();
if (gem.getName().equals(CAL_Prelude.Functions.subtract)) {
hasSubtract = true;
}
String gemQualifiedName = gem.getName().getQualifiedName();
assertTrue(gemQualifiedName.compareToIgnoreCase(lastGemQualifiedName) >= 0);
lastGemQualifiedName = gemQualifiedName;
}
assertTrue(hasSubtract);
}
/**
* Runs the expression (1 :: Int) + (2 :: Int), and compares the result
* of BasicCALServices' runCode with the expected result, namely the
* java.lang.Integer representation of 3.
*/
public void testRunCode_IntReturnType() throws GemCompilationException, CALExecutorException {
help_testRunCode_IntReturnType(leccCALServices);
help_testRunCode_IntReturnType(gCALServices);
}
private void help_testRunCode_IntReturnType(BasicCALServices calServices) throws GemCompilationException, CALExecutorException {
assertEquals(new Integer(3),
CALServicesTestUtilities.runExpr(
"IntReturnType",
SourceModel.Expr.BinaryOp.Add.make(
SourceModel.Expr.makeIntValue(1), SourceModel.Expr.makeIntValue(2)),
calServices));
}
/**
* Runs the expression 1.0 + 2.0, and compares the result
* of BasicCALServices' runCode with the expected result, namely the
* java.lang.Double representation of 3.0.
*/
public void testRunCode_DoubleReturnType() throws GemCompilationException, CALExecutorException {
help_testRunCode_DoubleReturnType(leccCALServices);
help_testRunCode_DoubleReturnType(gCALServices);
}
private void help_testRunCode_DoubleReturnType(BasicCALServices calServices) throws GemCompilationException, CALExecutorException {
assertEquals(new Double(3.0),
CALServicesTestUtilities.runExpr(
"DoubleReturnType",
SourceModel.Expr.BinaryOp.Add.make(
SourceModel.Expr.makeDoubleValue(1.0), SourceModel.Expr.makeDoubleValue(2.0)),
calServices));
}
/**
* Runs the expression 'H', and compares the result
* of BasicCALServices' runCode with the expected result, namely the
* java.lang.Character representation of 'H'
*/
public void testRunCode_CharReturnType() throws GemCompilationException, CALExecutorException {
help_testRunCode_CharReturnType(leccCALServices);
help_testRunCode_CharReturnType(gCALServices);
}
private void help_testRunCode_CharReturnType(BasicCALServices calServices) throws GemCompilationException, CALExecutorException {
assertEquals(new Character('H'),
CALServicesTestUtilities.runExpr(
"CharReturnType",
SourceModel.Expr.Literal.Char.make('H'),
calServices));
}
/**
* Runs the expression "Hello World!", and compares the result
* of BasicCALServices' runCode with the expected result, namely the
* java string "Hello World!"
*/
public void testRunCode_StringReturnType() throws GemCompilationException, CALExecutorException {
help_testRunCode_StringReturnType(leccCALServices);
help_testRunCode_StringReturnType(gCALServices);
}
private void help_testRunCode_StringReturnType(BasicCALServices calServices) throws GemCompilationException, CALExecutorException {
assertEquals("Hello World!",
CALServicesTestUtilities.runExpr(
"StringReturnType",
SourceModel.Expr.Literal.StringLit.make("Hello World!"),
calServices));
}
/**
* Runs the expression [1 :: Int, 2 :: Int], and compares the result
* of BasicCALServices' runCode with the expected result, namely a
* java.util.List containing the elements 1 and 2 represented by
* java.lang.Integers.
*/
public void testRunCode_ListReturnType() throws GemCompilationException, CALExecutorException {
help_testRunCode_ListReturnType(leccCALServices);
help_testRunCode_ListReturnType(gCALServices);
}
private void help_testRunCode_ListReturnType(BasicCALServices calServices) throws GemCompilationException, CALExecutorException {
assertEquals(Arrays.asList(new Integer[] {new Integer(1), new Integer(2)}),
CALServicesTestUtilities.runExpr(
"ListReturnType",
SourceModel.Expr.List.make(new SourceModel.Expr[] {
SourceModel.Expr.makeIntValue(1), SourceModel.Expr.makeIntValue(2) }),
calServices));
}
/**
* Runs the expression Array_Tests.multiDimArray, and compares the result
* of ProrgamEvaluator's eval with the expected result, namely a java.util.List
* containing the 3 java.util.Lists of boxed integers: {1,2,3}, {4,5,6}, {7,8,9}.
*/
public void testProgramEvaluatorEval_MultiDimArray() throws CALExecutorException, GemCompilationException {
help_testProgramEvaluatorEval_MultiDimArray(leccCALServices);
help_testProgramEvaluatorEval_MultiDimArray(gCALServices);
}
private void help_testProgramEvaluatorEval_MultiDimArray(BasicCALServices calServices) throws CALExecutorException, GemCompilationException {
List<?> result = (List<?>) calServices.runFunction(
EntryPointSpec.make(QualifiedName.make(CALPlatformTestModuleNames.Array_Tests, "multiDimArray")), null);
List<?> expected = Arrays.asList(new Object[]{
Arrays.asList(new Object[]{new Integer(1), new Integer(2), new Integer(3)}),
Arrays.asList(new Object[]{new Integer(4), new Integer(5), new Integer(6)}),
Arrays.asList(new Object[]{new Integer(7), new Integer(8), new Integer(9)})});
assertEquals(expected.size(), result.size());
assertEquals(expected, result);
}
/**
* Runs the expression Array.outputPrimitive (Array.subscript Array_Tests.multiDimArray 0),
* and compares the result of ProrgamEvaluator's eval with the expected result, namely an int[]
* containing {1,2,3}.
*/
public void testProgramEvaluatorEval_OutputPrimtiveArray() throws CALExecutorException {
help_testProgramEvaluatorEval_OutputPrimitiveArray(leccCALServices);
help_testProgramEvaluatorEval_OutputPrimitiveArray(gCALServices);
}
private void help_testProgramEvaluatorEval_OutputPrimitiveArray(BasicCALServices calServices) throws CALExecutorException {
String functionName = "tempFunc";
CompilerMessageLogger logger = new MessageLogger();
EntryPoint entryPoint = calServices.getCompiler().getEntryPoint(
new AdjunctSource.FromSourceModel(SourceModel.FunctionDefn.Algebraic.make(
functionName, Scope.PRIVATE, null,
SourceModel.Expr.makeGemCall(CAL_Array.Functions.outputPrimitive,
SourceModel.Expr.makeGemCall(CAL_Array.Functions.subscript,
SourceModel.Expr.makeGemCall(QualifiedName.make(CALPlatformTestModuleNames.Array_Tests, "multiDimArray")),
SourceModel.Expr.makeIntValue(0))))),
EntryPointSpec.make(QualifiedName.make(CALPlatformTestModuleNames.Array_Tests, functionName)), CALPlatformTestModuleNames.Array_Tests, logger);
CALExecutor executor = calServices.getWorkspaceManager().makeExecutorWithNewContextAndDefaultProperties();
int[] result = (int[]) executor.exec(entryPoint, new Object[0]);
int[] expected = new int[]{1,2,3};
assertEquals(expected.length, result.length);
for (int i = 0; i < expected.length; i++) {
assertEquals(expected[i], result[i]);
}
}
/**
* Runs the expression (Array.subscript Array_Tests.multiDimArray 0),
* and compares the result of ProrgamEvaluator's eval with the expected result, namely a java.util.List
* containing the boxed integers {1,2,3}.
*/
public void testProgramEvaluatorEval_OutputNonPrimtiveArray() throws CALExecutorException {
help_testProgramEvaluatorEval_OutputNonPrimitiveArray(leccCALServices);
help_testProgramEvaluatorEval_OutputNonPrimitiveArray(gCALServices);
}
private void help_testProgramEvaluatorEval_OutputNonPrimitiveArray(BasicCALServices calServices) throws CALExecutorException {
String functionName = "tempFunc";
CompilerMessageLogger logger = new MessageLogger();
EntryPoint entryPoint = calServices.getCompiler().getEntryPoint(
new AdjunctSource.FromSourceModel(
SourceModel.FunctionDefn.Algebraic.make(
functionName, Scope.PRIVATE, null,
SourceModel.Expr.makeGemCall(CAL_Array.Functions.subscript,
SourceModel.Expr.makeGemCall(QualifiedName.make(CALPlatformTestModuleNames.Array_Tests, "multiDimArray")),
SourceModel.Expr.makeIntValue(0)))),
EntryPointSpec.make(QualifiedName.make(CALPlatformTestModuleNames.Array_Tests, functionName)), CALPlatformTestModuleNames.Array_Tests, logger);
CALExecutor executor = calServices.getWorkspaceManager().makeExecutorWithNewContextAndDefaultProperties();
List<?> result = (List<?>) executor.exec(entryPoint, new Object[0]);
List<?> expected = Arrays.asList(new Object[]{new Integer(1), new Integer(2), new Integer(3)});
assertEquals(expected.size(), result.size());
assertEquals(expected, result);
}
/**
* Tests the behavior of the compiler when a new module to be compiled specifies
* an unknown module as an import.
*/
public void testUnknownImport() {
help_testUnknownImport(leccCALServices);
help_testUnknownImport(gCALServices);
}
private void help_testUnknownImport(BasicCALServices calServices) {
MessageLogger logger = new MessageLogger();
SourceModelModuleSource moduleDefn = new SourceModelModuleSource(SourceModelUtilities.TextParsing.parseModuleDefnIntoSourceModel("module Foo; import Prelude; import UNKNOWN_Module;", logger));
assertEquals(logger.getNErrors(), 0);
calServices.addNewModule(moduleDefn, logger);
if (logger.getNErrors() > 0) {
List<CompilerMessage> messages = logger.getCompilerMessages();
for (int i = 0, n = messages.size(); i < n; i++) {
CompilerMessage message = messages.get(i);
if (CompilerTestUtilities.isInternalCodingError(message.getMessageKind())) {
fail("Unexpected: " + message);
}
}
} else {
fail("Expected error, but there were none.");
}
}
/**
* Tests the executor's handling of an entry point based on an enumeration data cons.
* @throws CALExecutorException
*/
public void testEnumDataConsEntryPoint() {
final EntryPoint gt = new EntryPointImpl(CAL_Prelude.DataConstructors.GT);
final CALExecutor executor = leccCALServices.getWorkspaceManager().makeExecutorWithNewContextAndDefaultProperties();
try {
executor.exec(gt, new Object[0]);
} catch (CALExecutorException e) {
assertTrue(e.getMessage().contains("Attempt to call getOpaqueValue() on class: org.openquark.cal.internal.runtime.lecc.RTData$CAL_Int"));
return;
}
fail("exception expected");
}
}