package me.tomassetti.turin.compiler; import com.google.common.collect.ImmutableList; import me.tomassetti.turin.definitions.TypeDefinition; import me.tomassetti.turin.resolvers.ComposedSymbolResolver; import me.tomassetti.turin.resolvers.SymbolResolver; import me.tomassetti.turin.resolvers.jdk.ReflectionTypeDefinitionFactory; import me.tomassetti.turin.parser.ast.FormalParameterNode; import me.tomassetti.turin.parser.ast.Node; import me.tomassetti.turin.parser.ast.TurinTypeDefinition; import me.tomassetti.turin.parser.ast.TypeDefinitionNode; import me.tomassetti.turin.parser.ast.expressions.ActualParam; import me.tomassetti.turin.parser.ast.expressions.Expression; import me.tomassetti.turin.parser.ast.expressions.literals.IntLiteral; import me.tomassetti.turin.parser.ast.typeusage.PrimitiveTypeUsageNode; import me.tomassetti.turin.parser.ast.typeusage.TypeUsageNode; import me.tomassetti.turin.symbols.FormalParameterSymbol; import me.tomassetti.turin.typesystem.ReferenceTypeUsage; import me.tomassetti.turin.util.Either; import org.easymock.EasyMock; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.easymock.PowerMock; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; import java.util.Collections; import java.util.List; import java.util.Optional; import static me.tomassetti.turin.compiler.ParamUtils.*; import static org.junit.Assert.*; import static org.easymock.EasyMock.*; @RunWith(PowerMockRunner.class) @PrepareForTest(TurinTypeDefinition.class) public class ParamUtilsTest { private ActualParam n1 = new ActualParam("n1", new IntLiteral(1)); private ActualParam n2 = new ActualParam("n2", new IntLiteral(2)); private ActualParam u1 = new ActualParam(new IntLiteral(3)); private ActualParam u2 = new ActualParam(new IntLiteral(4)); private FormalParameterNode fd1 = new FormalParameterNode(PrimitiveTypeUsageNode.createInt(), "fd1", Optional.of(new IntLiteral(1))); private FormalParameterNode fd2 = new FormalParameterNode(PrimitiveTypeUsageNode.createInt(), "fd2", Optional.of(new IntLiteral(1))); private FormalParameterNode fn1 = new FormalParameterNode(PrimitiveTypeUsageNode.createInt(), "fn1"); private FormalParameterNode fn2 = new FormalParameterNode(PrimitiveTypeUsageNode.createInt(), "fn2"); @Test public void verifyOrderOnlyOneNamedParam() { assertEquals(true, ParamUtils.verifyOrder(ImmutableList.of(n1))); } @Test public void verifyOrderNamedParamFollowingUnnamedParam() { assertEquals(true, verifyOrder(ImmutableList.of(u1, n1))); } @Test public void verifyOrderUnnamedParamFollowingNamedParam() { assertEquals(false, verifyOrder(ImmutableList.of(n1, u1))); } @Test public void verifyOrderUnnamedParamBetweenNamedParams() { assertEquals(false, verifyOrder(ImmutableList.of(n1, u1, n2))); } @Test public void verifyOrderNamedParamBetweenUnnamedParams() { assertEquals(false, verifyOrder(ImmutableList.of(u1, n1, u2))); } @Test public void testUnnamedParams() { assertEquals(ImmutableList.of(u1, u2), unnamedParams(ImmutableList.of(u1, n1, u2, n2))); } @Test public void testNamedParams() { assertEquals(ImmutableList.of(n1, n2), namedParams(ImmutableList.of(u1, n1, u2, n2))); } @Test public void testhasDefaultParams() { assertEquals(false, hasDefaultParams(ImmutableList.of())); assertEquals(false, hasDefaultParams(ImmutableList.of(fn1, fn2))); assertEquals(true, hasDefaultParams(ImmutableList.of(fn1, fd1, fn2))); assertEquals(true, hasDefaultParams(ImmutableList.of(fd1, fn1, fn2))); assertEquals(true, hasDefaultParams(ImmutableList.of(fn1, fn2, fd1))); } private static SymbolResolver DUMMY_RESOLVER = new ComposedSymbolResolver(Collections.emptyList()); @Test public void testGetterNameBoolean() { assertEquals("isFoo", ParamUtils.getterName(new FormalParameterNode(PrimitiveTypeUsageNode.createBoolean(), "foo"), DUMMY_RESOLVER)); assertEquals("isA", ParamUtils.getterName(new FormalParameterNode(PrimitiveTypeUsageNode.createBoolean(), "a"), DUMMY_RESOLVER)); } @Test public void testGetterNameNotBoolean() { SymbolResolver resolver = new ComposedSymbolResolver(Collections.emptyList()); assertEquals("getFoo", ParamUtils.getterName(new FormalParameterSymbol(new ReferenceTypeUsage(ReflectionTypeDefinitionFactory.getInstance().getTypeDefinition(Boolean.class, resolver)), "foo"), DUMMY_RESOLVER)); assertEquals("getFoo", ParamUtils.getterName(new FormalParameterSymbol(ReferenceTypeUsage.STRING(resolver), "foo"), DUMMY_RESOLVER)); assertEquals("getA", ParamUtils.getterName(new FormalParameterSymbol(ReferenceTypeUsage.STRING(resolver), "a"), DUMMY_RESOLVER)); } @Test public void testDesugarizeAsteriskParamWhichIsNotAReference() { List<FormalParameterNode> formalParameters = ImmutableList.of(fn1, fn2, fd2, fd2); Expression value = createMock(Expression.class); SymbolResolver resolver = createMock(SymbolResolver.class); TypeUsageNode typeOfAsteriskParam = createMock(TypeUsageNode.class); expect(value.calcType()).andReturn(typeOfAsteriskParam); expect(typeOfAsteriskParam.isReference()).andReturn(false); Node parent = new IntLiteral(3); // it does not really matter replay(value, resolver, typeOfAsteriskParam); Either<String, List<ActualParam>> res = desugarizeAsteriskParam(formalParameters, value, resolver, parent); assertEquals(true, res.isLeft()); verify(value, resolver, typeOfAsteriskParam); } @Test public void testDesugarizeAsteriskParamWithAllTheParamsAvailable() { List<FormalParameterNode> formalParameters = ImmutableList.of(fn1, fn2, fd1, fd2); Expression value = createMock(Expression.class); value.setParent(EasyMock.anyObject()); value.setParent(EasyMock.anyObject()); value.setParent(EasyMock.anyObject()); value.setParent(EasyMock.anyObject()); SymbolResolver resolver = createMock(SymbolResolver.class); ReferenceTypeUsage typeUsageOfAsteriskParam = createMock(ReferenceTypeUsage.class); expect(value.calcType()).andReturn(typeUsageOfAsteriskParam); expect(typeUsageOfAsteriskParam.isReference()).andReturn(true); expect(typeUsageOfAsteriskParam.asReferenceTypeUsage()).andReturn(typeUsageOfAsteriskParam); TypeDefinition typeOfAsteriskParam = PowerMock.createMock(TypeDefinitionNode.class); expect(typeUsageOfAsteriskParam.getTypeDefinition()).andReturn(typeOfAsteriskParam); expect(typeOfAsteriskParam.hasMethodFor("getFn1", Collections.emptyList(), false)).andReturn(true); expect(typeOfAsteriskParam.hasMethodFor("getFn2", Collections.emptyList(), false)).andReturn(true); expect(typeOfAsteriskParam.hasMethodFor("getFd1", Collections.emptyList(), false)).andReturn(true); expect(typeOfAsteriskParam.hasMethodFor("getFd2", Collections.emptyList(),false)).andReturn(true); Node parent = new IntLiteral(3); // it does not really matter replay(value, resolver, typeUsageOfAsteriskParam); PowerMock.replay(typeOfAsteriskParam); Either<String, List<ActualParam>> res = desugarizeAsteriskParam(formalParameters, value, resolver, parent); assertEquals(true, res.isRight()); // 2 + the map for default params assertEquals(3, res.getRight().size()); verify(value, resolver, typeUsageOfAsteriskParam); PowerMock.verify(typeOfAsteriskParam); } @Test public void testDesugarizeAsteriskParamWithOnlyNonDefaultAvailable() { List<FormalParameterNode> formalParameters = ImmutableList.of(fn1, fn2, fd1, fd2); Expression value = createMock(Expression.class); value.setParent(EasyMock.anyObject()); value.setParent(EasyMock.anyObject()); value.setParent(EasyMock.anyObject()); value.setParent(EasyMock.anyObject()); SymbolResolver resolver = createMock(SymbolResolver.class); ReferenceTypeUsage typeUsageOfAsteriskParam = createMock(ReferenceTypeUsage.class); expect(value.calcType()).andReturn(typeUsageOfAsteriskParam); expect(typeUsageOfAsteriskParam.isReference()).andReturn(true); expect(typeUsageOfAsteriskParam.asReferenceTypeUsage()).andReturn(typeUsageOfAsteriskParam); TypeDefinition typeOfAsteriskParam = PowerMock.createMock(TypeDefinitionNode.class); expect(typeUsageOfAsteriskParam.getTypeDefinition()).andReturn(typeOfAsteriskParam); expect(typeOfAsteriskParam.hasMethodFor("getFn1", Collections.emptyList(), false)).andReturn(true); expect(typeOfAsteriskParam.hasMethodFor("getFn2", Collections.emptyList(), false)).andReturn(true); expect(typeOfAsteriskParam.hasMethodFor("getFd1", Collections.emptyList(), false)).andReturn(false); expect(typeOfAsteriskParam.hasMethodFor("getFd2", Collections.emptyList(), false)).andReturn(false); Node parent = new IntLiteral(3); // it does not really matter replay(value, resolver, typeUsageOfAsteriskParam); PowerMock.replay(typeOfAsteriskParam); Either<String, List<ActualParam>> res = desugarizeAsteriskParam(formalParameters, value, resolver, parent); assertEquals(true, res.isRight()); // 2 + the map for default params assertEquals(3, res.getRight().size()); verify(value, resolver, typeUsageOfAsteriskParam); PowerMock.verify(typeOfAsteriskParam); } @Test public void testDesugarizeAsteriskParamWithMissingNonDefault() { List<FormalParameterNode> formalParameters = ImmutableList.of(fn1, fn2, fd1, fd2); Expression value = createMock(Expression.class); value.setParent(EasyMock.anyObject()); value.setParent(EasyMock.anyObject()); SymbolResolver resolver = createMock(SymbolResolver.class); ReferenceTypeUsage typeUsageOfAsteriskParam = createMock(ReferenceTypeUsage.class); expect(value.calcType()).andReturn(typeUsageOfAsteriskParam); expect(typeUsageOfAsteriskParam.isReference()).andReturn(true); expect(typeUsageOfAsteriskParam.asReferenceTypeUsage()).andReturn(typeUsageOfAsteriskParam); TypeDefinition typeOfAsteriskParam = PowerMock.createMock(TypeDefinitionNode.class); expect(typeUsageOfAsteriskParam.getTypeDefinition()).andReturn(typeOfAsteriskParam); expect(typeOfAsteriskParam.hasMethodFor("getFn1", Collections.emptyList(), false)).andReturn(true); expect(typeOfAsteriskParam.hasMethodFor("getFn2", Collections.emptyList(), false)).andReturn(false); Node parent = new IntLiteral(3); // it does not really matter replay(value, resolver, typeUsageOfAsteriskParam); PowerMock.replay(typeOfAsteriskParam); Either<String, List<ActualParam>> res = desugarizeAsteriskParam(formalParameters, value, resolver, parent); assertEquals(true, res.isLeft()); verify(value, resolver, typeUsageOfAsteriskParam); PowerMock.verify(typeOfAsteriskParam); } }