blob: d5554130ab7d15812bbeed93e20ecd9a72017910 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011 NumberFour AG
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* NumberFour AG - initial API and Implementation (Alex Panchenko)
*******************************************************************************/
package org.eclipse.dltk.javascript.core.tests.typeinfo;
import java.text.ParseException;
import junit.framework.TestCase;
import org.eclipse.dltk.internal.javascript.ti.JSDocProblem;
import org.eclipse.dltk.javascript.core.Types;
import org.eclipse.dltk.javascript.typeinfo.JSDocParseException;
import org.eclipse.dltk.javascript.typeinfo.JSDocTypeParser;
import org.eclipse.dltk.javascript.typeinfo.model.ArrayType;
import org.eclipse.dltk.javascript.typeinfo.model.ClassType;
import org.eclipse.dltk.javascript.typeinfo.model.FunctionType;
import org.eclipse.dltk.javascript.typeinfo.model.JSType;
import org.eclipse.dltk.javascript.typeinfo.model.ParameterKind;
import org.eclipse.dltk.javascript.typeinfo.model.RecordMember;
import org.eclipse.dltk.javascript.typeinfo.model.RecordType;
import org.eclipse.dltk.javascript.typeinfo.model.SimpleType;
import org.eclipse.dltk.javascript.typeinfo.model.UnionType;
import org.eclipse.emf.common.util.EList;
@SuppressWarnings("restriction")
public class JSDocTypeParserTests extends TestCase {
private JSType parse(String expression) {
try {
return new JSDocTypeParser().parse(expression);
} catch (ParseException e) {
System.out.println(expression);
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < e.getErrorOffset(); ++i)
sb.append(' ');
sb.append("^^^ ").append(e.getMessage());
System.out.println(sb.toString());
throw new RuntimeException(e);
}
}
private ParseException parseError(String expression) {
try {
new JSDocTypeParser().parse(expression);
fail("parse(" + expression + ") is expected to fail");
return null;// fail() never returns
} catch (ParseException e) {
return e;
}
}
private static void assertRef(final String expected, JSType type) {
assertEquals(expected, ((SimpleType) type).getTarget().getName());
}
public void testSimple() {
JSType type = parse("String");
assertRef("String", type);
}
public void testSimpleTranslated() {
JSType type = parse("string");
assertRef("String", type);
}
public void testSimpleParentheses() {
JSType type = parse("( string )");
assertRef("String", type);
}
public void testParenthesesError() {
final String expression = "(string";
final ParseException exception = parseError(expression);
assertEquals(") expected", exception.getMessage());
assertEquals(expression.length(), exception.getErrorOffset());
}
public void testUnexpectedContentError() {
final String expression = "string)))";
final ParseException exception = parseError(expression);
assertEquals("Unexpected )))", exception.getMessage());
assertEquals(expression.length() - 3, exception.getErrorOffset());
}
public void testClassOfNumber() {
final String expression = "Class<Number>";
final ClassType type = (ClassType) parse(expression);
assertSame(Types.NUMBER, type.getTarget());
}
public void testClassOfSomething() {
final String expression = "Class<Something>";
final ClassType type = (ClassType) parse(expression);
assertEquals("Something", type.getTarget().getName());
}
public void testWrongClassParameterization() {
final String expression = "Class<Array<Number>>";
final JSDocParseException exception = (JSDocParseException) parseError(expression);
assertEquals(JSDocProblem.WRONG_TYPE_PARAMETERIZATION,
exception.problemId);
assertEquals("Class cannot be parameterized with ArrayType",
exception.getMessage());
}
public void testArray() {
JSType type = parse("Array.<String>");
assertRef("String", ((ArrayType) type).getItemType());
}
public void testUnionType() {
UnionType type = (UnionType) parse("String|Number");
assertEquals(2, type.getTargets().size());
assertRef("String", type.getTargets().get(0));
assertRef("Number", type.getTargets().get(1));
}
public void testUnionParenthesesType() {
UnionType type = (UnionType) parse("(String | Number)");
assertEquals(2, type.getTargets().size());
assertRef("String", type.getTargets().get(0));
assertRef("Number", type.getTargets().get(1));
}
public void testRecordType() {
final RecordType type = (RecordType) parse("{ astring : String , anumber : Number }");
assertEquals(2, type.getMembers().size());
assertEquals("astring", type.getMembers().get(0).getName());
assertRef("String", type.getMembers().get(0).getType());
assertEquals("anumber", type.getMembers().get(1).getName());
assertRef("Number", type.getMembers().get(1).getType());
}
public void testRecordTypeWithOptionalBrackets() {
final RecordType type = (RecordType) parse("{astring:String, [anumber]:Number}");
assertEquals(2, type.getMembers().size());
assertEquals("astring", type.getMembers().get(0).getName());
assertRef("String", type.getMembers().get(0).getType());
assertEquals("anumber", type.getMembers().get(1).getName());
assertRef("Number", type.getMembers().get(1).getType());
assertTrue(((RecordMember) type.getMembers().get(1)).isOptional());
}
public void testRecordTypeWithOptionalClosureStyle() {
final RecordType type = (RecordType) parse("{astring:String,anumber:Number=}");
assertEquals(2, type.getMembers().size());
assertEquals("astring", type.getMembers().get(0).getName());
assertRef("String", type.getMembers().get(0).getType());
assertEquals("anumber", type.getMembers().get(1).getName());
assertRef("Number", type.getMembers().get(1).getType());
assertTrue(((RecordMember) type.getMembers().get(1)).isOptional());
}
public void testRecordTypeWithLiteralQuotedProperties() {
final RecordType type = (RecordType) parse("{'a-string':String, anumber:Number=}");
assertEquals(1, type.getMembers().size());
assertEquals("anumber", type.getMembers().get(0).getName());
assertRef("Number", type.getMembers().get(0).getType());
assertTrue(((RecordMember) type.getMembers().get(0)).isOptional());
}
public void testFunctionType1() {
final FunctionType type = (FunctionType) parse("function():String");
assertEquals(0, type.getParameters().size());
assertRef("String", type.getReturnType());
}
public void testFunctionType2() {
final FunctionType type = (FunctionType) parse("function(String)");
assertEquals(1, type.getParameters().size());
assertRef("String", type.getParameters().get(0).getType());
assertNull(type.getReturnType());
}
public void testFunctionType3() {
final FunctionType type = (FunctionType) parse("function( String ) : Number");
assertEquals(1, type.getParameters().size());
assertRef("String", type.getParameters().get(0).getType());
assertRef("Number", type.getReturnType());
}
public void testFunctionTypeVarArgs() {
final FunctionType type = (FunctionType) parse("function(string, ...[number]): number");
assertEquals(2, type.getParameters().size());
assertRef("String", type.getParameters().get(0).getType());
assertRef("Number", type.getParameters().get(1).getType());
assertEquals(ParameterKind.VARARGS, type.getParameters().get(1)
.getKind());
assertRef("Number", type.getReturnType());
}
public void testUnitonWithFunction1() {
final UnionType type = (UnionType) parse("String|function(Number):Number|String");
final EList<JSType> parts = type.getTargets();
assertEquals(3, parts.size());
final SimpleType part0 = (SimpleType) parts.get(0);
assertEquals("String", part0.getName());
final FunctionType part1 = (FunctionType) parts.get(1);
assertEquals("Number", part1.getReturnType().getName());
final SimpleType part2 = (SimpleType) parts.get(2);
assertEquals("String", part2.getName());
}
public void testUnitonWithFunction2() {
final UnionType type = (UnionType) parse("String|function(Number):(Number|String)");
final EList<JSType> parts = type.getTargets();
assertEquals(2, parts.size());
final SimpleType part0 = (SimpleType) parts.get(0);
assertEquals("String", part0.getName());
final FunctionType part1 = (FunctionType) parts.get(1);
final UnionType resultType = (UnionType) part1.getReturnType();
assertEquals(2, resultType.getTargets().size());
assertEquals("Number", resultType.getTargets().get(0).getName());
assertEquals("String", resultType.getTargets().get(1).getName());
}
}