/*
* 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.
*/
/*
* SourceModelUtilities_Test.java
* Creation date: Apr 15, 2005.
* By: Joseph Wong
*/
package org.openquark.cal.compiler;
import junit.framework.TestCase;
import org.openquark.cal.CALPlatformTestModuleNames;
import org.openquark.cal.compiler.SourceModel.Import;
import org.openquark.cal.compiler.SourceModel.TopLevelSourceElement;
import org.openquark.cal.module.Cal.Collections.CAL_Map;
import org.openquark.cal.module.Cal.Core.CAL_Bits;
import org.openquark.cal.module.Cal.Core.CAL_Prelude;
/**
* A set of JUnit test cases for verifying the correctness of the source model utility methods.
*
* @author Joseph Wong
*/
public class SourceModelUtilities_Test extends TestCase {
/**
* 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;
/**
* Constructor for SourceModelUtilities_Test.
*
* @param name
* the name of the test
*/
public SourceModelUtilities_Test(String name) {
super(name);
}
/**
* Tests the method SourceModelUtilities.TextParsing.parseExprIntoSourceModel
* to see whether it can properly handle and report on invalid source text.
*/
public void test_parseExpr_failureCase_invalidSourceText() {
assertNull(SourceModelUtilities.TextParsing.parseExprIntoSourceModel("$$$"));
MessageLogger logger = new MessageLogger();
SourceModelUtilities.TextParsing.parseExprIntoSourceModel("###", logger);
assertEquals(CompilerMessage.Severity.ERROR, logger.getMaxSeverity());
assertTrue(logger.getNErrors() > 0);
}
/**
* Tests the method SourceModelUtilities.TextParsing.parseAlgebraicFunctionDefnIntoSourceModel
* to see whether it can properly handle and report on invalid source text.
*/
public void test_parseFunctionDefn_failureCase_invalidSourceText() {
assertNull(SourceModelUtilities.TextParsing.parseAlgebraicFunctionDefnIntoSourceModel("foo = $$$;"));
MessageLogger logger = new MessageLogger();
SourceModelUtilities.TextParsing.parseAlgebraicFunctionDefnIntoSourceModel("foo = ###;", logger);
assertEquals(CompilerMessage.Severity.ERROR, logger.getMaxSeverity());
assertTrue(logger.getNErrors() > 0);
}
/**
* Tests the method SourceModelUtilities.TextParsing.parseModuleDefnIntoSourceModel
* to see whether it can properly handle and report on invalid source text.
*/
public void test_parseModuleDefn_failureCase_invalidSourceText() {
assertNull(SourceModelUtilities.TextParsing.parseModuleDefnIntoSourceModel("module Foo; import " + CAL_Prelude.MODULE_NAME + "; foo = $$$;"));
MessageLogger logger = new MessageLogger();
SourceModelUtilities.TextParsing.parseModuleDefnIntoSourceModel("module Foo; import " + CAL_Prelude.MODULE_NAME + "; foo = ###;", logger);
assertEquals(CompilerMessage.Severity.ERROR, logger.getMaxSeverity());
assertTrue(logger.getNErrors() > 0);
}
/**
* Tests the ImportAugmenter (and indirectly the SourceModelTraverser) for correctly
* handling a backquote operator with a qualified function name.
*/
public void test_importAugmenter_backquoteOperatorWithFunctionName() {
SourceModel.Import[] imports = SourceModelUtilities.ImportAugmenter.getRequiredImports(ModuleName.make("TestModule"), SourceModel.Expr.BinaryOp.BackquotedOperator.Var.make(SourceModel.Expr.Var.make(CAL_Bits.Functions.bitwiseAnd), SourceModel.Expr.makeIntValue(1), SourceModel.Expr.makeIntValue(2)));
boolean foundBits = false;
for (final Import requiredImport : imports) {
if (SourceModel.Name.Module.toModuleName(requiredImport.getImportedModuleName()).equals(CAL_Bits.MODULE_NAME)) {
foundBits = true;
}
}
assertTrue("The Bits module is not in the list of required imports", foundBits);
}
/**
* Tests the ImportAugmenter (and indirectly the SourceModelTraverser) for correctly
* handling a backquote operator with a qualified data constructor.
*/
public void test_importAugmenter_backquoteOperatorWithDataCons() {
SourceModel.Import[] imports = SourceModelUtilities.ImportAugmenter.getRequiredImports(ModuleName.make("TestModule"), SourceModel.Expr.BinaryOp.BackquotedOperator.DataCons.make(SourceModel.Expr.DataCons.make(CALPlatformTestModuleNames.LegacyTuple, "Tuple2"), SourceModel.Expr.makeIntValue(1), SourceModel.Expr.makeIntValue(2)));
boolean foundBits = false;
for (final Import requiredImport : imports) {
if (SourceModel.Name.Module.toModuleName(requiredImport.getImportedModuleName()).equals(CALPlatformTestModuleNames.LegacyTuple)) {
foundBits = true;
}
}
assertTrue("The " + CALPlatformTestModuleNames.LegacyTuple + " module is not in the list of required imports", foundBits);
}
/**
* Tests the ImportAugmenter for correctly handling a CALDoc checked reference appearing
* without the context keyword.
*/
public void test_importAugmenter_CALDocCheckedReferenceWithoutContext() {
SourceModel.Import[] imports = SourceModelUtilities.ImportAugmenter.getRequiredImports(
ModuleName.make("TestModule"),
SourceModel.CALDoc.CrossReference.WithoutContextCons.make(SourceModel.Name.WithoutContextCons.make(CAL_Map.MODULE_NAME, CAL_Map.TypeConstructors.Map.getUnqualifiedName()), true));
boolean foundMap = false;
for (final Import requiredImport : imports) {
if (SourceModel.Name.Module.toModuleName(requiredImport.getImportedModuleName()).equals(CAL_Map.MODULE_NAME)) {
foundMap = true;
}
}
// The import augmenter cannot handle references without context keywords, checked or unchecked,
// so no new imports should have been gathered.
assertFalse("The Map module is in the list of required imports, when it shouldn't be.", foundMap);
}
/**
* Tests the ImportAugmenter for correctly handling a CALDoc unchecked reference appearing
* without the context keyword.
*/
public void test_importAugmenter_CALDocUncheckedReferenceWithoutContext() {
SourceModel.Import[] imports = SourceModelUtilities.ImportAugmenter.getRequiredImports(
ModuleName.make("TestModule"),
SourceModel.CALDoc.CrossReference.WithoutContextCons.make(SourceModel.Name.WithoutContextCons.make(CAL_Map.MODULE_NAME, CAL_Map.TypeConstructors.Map.getUnqualifiedName()), false));
boolean foundMap = false;
for (final Import requiredImport : imports) {
if (SourceModel.Name.Module.toModuleName(requiredImport.getImportedModuleName()).equals(CAL_Map.MODULE_NAME)) {
foundMap = true;
}
}
assertFalse("The Map module is in the list of required imports, when it shouldn't be.", foundMap);
}
/**
* Tests the Enumeration generator for correctly generating a type constructor definition
* with the appropriate deriving clause, with all the derived instances (Eq, Ord, Bounded, Enum).
*/
public void testEnumerationGenerationForDerivingClause_AllDerivedInstances() {
SourceModelUtilities.Enumeration enumeration = new SourceModelUtilities.Enumeration(QualifiedName.make(ModuleName.make("TestModule"), "TestEnum"), Scope.PRIVATE, new String[] {"Foo", "Bar", "Baz"}, false);
SourceModel.TopLevelSourceElement[] elements = enumeration.toSourceElements();
boolean derivesEq = false;
boolean derivesOrd = false;
boolean derivesBounded = false;
boolean derivesEnum = false;
for (final TopLevelSourceElement element : elements) {
if (element instanceof SourceModel.TypeConstructorDefn) {
SourceModel.TypeConstructorDefn typeCons = (SourceModel.TypeConstructorDefn)element;
int nDerivingClauseTypeClassNames = typeCons.getNDerivingClauseTypeClassNames();
for (int j = 0; j < nDerivingClauseTypeClassNames; j++) {
SourceModel.Name.TypeClass name = typeCons.getDerivingClauseTypeClassName(j);
if (CAL_Prelude.MODULE_NAME.equals(SourceModel.Name.Module.maybeToModuleName(name.getModuleName()))) {
if (name.getUnqualifiedName().equals(CAL_Prelude.TypeClasses.Eq.getUnqualifiedName())) {
derivesEq = true;
} else if (name.getUnqualifiedName().equals(CAL_Prelude.TypeClasses.Ord.getUnqualifiedName())) {
derivesOrd = true;
} else if (name.getUnqualifiedName().equals(CAL_Prelude.TypeClasses.Bounded.getUnqualifiedName())) {
derivesBounded = true;
} else if (name.getUnqualifiedName().equals(CAL_Prelude.TypeClasses.Enum.getUnqualifiedName())) {
derivesEnum = true;
}
}
}
}
}
assertTrue("The generated enumeration does not derive Eq", derivesEq);
assertTrue("The generated enumeration does not derive Ord", derivesOrd);
assertTrue("The generated enumeration does not derive Bounded", derivesBounded);
assertTrue("The generated enumeration does not derive Enum", derivesEnum);
}
/**
* Tests the Enumeration generator for correctly generating a type constructor definition
* with the appropriate deriving clause, with only the Eq instance.
*/
public void testEnumerationGenerationForDerivingClause_EqInstanceOnly() {
SourceModelUtilities.Enumeration enumeration = new SourceModelUtilities.Enumeration(QualifiedName.make(ModuleName.make("TestModule"), "TestEnum"), Scope.PRIVATE, new String[] {"Foo", "Bar", "Baz"}, true);
SourceModel.TopLevelSourceElement[] elements = enumeration.toSourceElements();
boolean derivesEq = false;
boolean derivesOrd = false;
boolean derivesBounded = false;
boolean derivesEnum = false;
for (final TopLevelSourceElement element : elements) {
if (element instanceof SourceModel.TypeConstructorDefn) {
SourceModel.TypeConstructorDefn typeCons = (SourceModel.TypeConstructorDefn)element;
int nDerivingClauseTypeClassNames = typeCons.getNDerivingClauseTypeClassNames();
for (int j = 0; j < nDerivingClauseTypeClassNames; j++) {
SourceModel.Name.TypeClass name = typeCons.getDerivingClauseTypeClassName(j);
if (CAL_Prelude.MODULE_NAME.equals(SourceModel.Name.Module.maybeToModuleName(name.getModuleName()))) {
if (name.getUnqualifiedName().equals(CAL_Prelude.TypeClasses.Eq.getUnqualifiedName())) {
derivesEq = true;
} else if (name.getUnqualifiedName().equals(CAL_Prelude.TypeClasses.Ord.getUnqualifiedName())) {
derivesOrd = true;
} else if (name.getUnqualifiedName().equals(CAL_Prelude.TypeClasses.Bounded.getUnqualifiedName())) {
derivesBounded = true;
} else if (name.getUnqualifiedName().equals(CAL_Prelude.TypeClasses.Enum.getUnqualifiedName())) {
derivesEnum = true;
}
}
}
}
}
assertTrue("The generated enumeration does not derive Eq", derivesEq);
assertFalse("The generated enumeration derives Ord", derivesOrd);
assertFalse("The generated enumeration derives Bounded", derivesBounded);
assertFalse("The generated enumeration derives Enum", derivesEnum);
}
}