Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 48 additions & 21 deletions src/test/interpreter/VisitorUnitTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,22 @@
import interpreter.antlr.MineScriptParser;
import interpreter.types.*;
import interpreter.utils.MockTerminalNode;
import interpreter.utils.MockToken;
import org.antlr.v4.runtime.Token;
import org.jetbrains.annotations.NotNull;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;

@ExtendWith(MockitoExtension.class)
Expand All @@ -23,22 +28,26 @@ class VisitorUnitTest {

@Spy private final Visitor spyVisitor = visitor;
@Mock private MineScriptParser.AssignContext mockAssignContext;
@Mock private MineScriptParser.ExpressionContext mockExpressionContext;
@Mock private MineScriptParser.ExpressionContext mockExpressionContext1;
@Mock private MineScriptParser.ExpressionContext mockExpressionContext2;
@Mock private MineScriptParser.BoolContext mockBoolContext;
@Mock private MineScriptParser.AbsDirContext mockAbsDirContext;
@Mock private MineScriptParser.RelDirContext mockRelDirContext;
@Mock private MineScriptParser.NumberContext mockNumberContext;
@Mock private MineScriptParser.IdContext mockIdContext;
@Mock private MineScriptParser.NegContext mockNegContext;
@Mock private MineScriptParser.NotExprContext mockNotExprContext;
@Mock private MineScriptParser.AddSubContext mockAddSubContext;



@ParameterizedTest
@ValueSource(ints = {-1000, -10, 0, 10, 1000})
void visitAssignStoresCorrectNumber(int value) {
// Mock functions ID(), expression(), and visit()
Mockito.when(mockAssignContext.ID()).thenReturn(new MockTerminalNode("varName"));
Mockito.when(mockAssignContext.expression()).thenReturn(mockExpressionContext);
Mockito.when(spyVisitor.visit(mockExpressionContext)).thenReturn(new MSNumber(value));
Mockito.when(mockAssignContext.expression()).thenReturn(mockExpressionContext1);
Mockito.when(spyVisitor.visit(mockExpressionContext1)).thenReturn(new MSNumber(value));

// Call the visitAssign method on the spy
MSType result = spyVisitor.visitAssign(mockAssignContext);
Expand All @@ -57,8 +66,8 @@ void visitAssignStoresCorrectNumber(int value) {
void visitAssignStoresCorrectBoolean(boolean value) {
// Mock functions ID(), expression(), and visit()
Mockito.when(mockAssignContext.ID()).thenReturn(new MockTerminalNode("varName"));
Mockito.when(mockAssignContext.expression()).thenReturn(mockExpressionContext);
Mockito.when(spyVisitor.visit(mockExpressionContext)).thenReturn(new MSBool(value));
Mockito.when(mockAssignContext.expression()).thenReturn(mockExpressionContext1);
Mockito.when(spyVisitor.visit(mockExpressionContext1)).thenReturn(new MSBool(value));

// Call the visitAssign method on the spy
MSType result = spyVisitor.visitAssign(mockAssignContext);
Expand All @@ -77,8 +86,8 @@ void visitAssignStoresCorrectBoolean(boolean value) {
void visitAssignStoresCorrectRelDir(MSRelDir.Direction value) {
// Mock functions ID(), expression(), and visit()
Mockito.when(mockAssignContext.ID()).thenReturn(new MockTerminalNode("varName"));
Mockito.when(mockAssignContext.expression()).thenReturn(mockExpressionContext);
Mockito.when(spyVisitor.visit(mockExpressionContext)).thenReturn(new MSRelDir(value.toString().toLowerCase()));
Mockito.when(mockAssignContext.expression()).thenReturn(mockExpressionContext1);
Mockito.when(spyVisitor.visit(mockExpressionContext1)).thenReturn(new MSRelDir(value.toString().toLowerCase()));

// Call the visitAssign method on the spy
MSType result = spyVisitor.visitAssign(mockAssignContext);
Expand All @@ -97,8 +106,8 @@ void visitAssignStoresCorrectRelDir(MSRelDir.Direction value) {
void visitAssignStoresCorrectAbsDir(MSAbsDir.Direction value) {
// Mock functions ID(), expression(), and visit()
Mockito.when(mockAssignContext.ID()).thenReturn(new MockTerminalNode("varName"));
Mockito.when(mockAssignContext.expression()).thenReturn(mockExpressionContext);
Mockito.when(spyVisitor.visit(mockExpressionContext)).thenReturn(new MSAbsDir(value.toString().toLowerCase()));
Mockito.when(mockAssignContext.expression()).thenReturn(mockExpressionContext1);
Mockito.when(spyVisitor.visit(mockExpressionContext1)).thenReturn(new MSAbsDir(value.toString().toLowerCase()));

// Call the visitAssign method on the spy
MSType result = spyVisitor.visitAssign(mockAssignContext);
Expand All @@ -114,17 +123,17 @@ void visitAssignStoresCorrectAbsDir(MSAbsDir.Direction value) {

@Test
void visitNotExprValidBoolReturnsNegatedBool() {
Mockito.when(mockNotExprContext.expression()).thenReturn(mockExpressionContext);
Mockito.when(spyVisitor.visit(mockExpressionContext)).thenReturn(new MSBool(false));
Mockito.when(mockNotExprContext.expression()).thenReturn(mockExpressionContext1);
Mockito.when(spyVisitor.visit(mockExpressionContext1)).thenReturn(new MSBool(false));

MSType result = spyVisitor.visitNotExpr(mockNotExprContext);
Assertions.assertTrue(((MSBool) result).getValue());
}

@Test
void visitNotExprPassZeroReturnsTrue() {
Mockito.when(mockNotExprContext.expression()).thenReturn(mockExpressionContext);
Mockito.when(spyVisitor.visit(mockExpressionContext)).thenReturn(new MSNumber(0));
Mockito.when(mockNotExprContext.expression()).thenReturn(mockExpressionContext1);
Mockito.when(spyVisitor.visit(mockExpressionContext1)).thenReturn(new MSNumber(0));

MSType result = spyVisitor.visitNotExpr(mockNotExprContext);
Assertions.assertTrue(((MSBool) result).getValue());
Expand All @@ -133,35 +142,35 @@ void visitNotExprPassZeroReturnsTrue() {
@ParameterizedTest
@ValueSource(ints = {-1000, -100, 100, 1000})
void visitNotExprPassNonZeroNumberReturnsFalse(int value) {
Mockito.when(mockNotExprContext.expression()).thenReturn(mockExpressionContext);
Mockito.when(spyVisitor.visit(mockExpressionContext)).thenReturn(new MSNumber(value));
Mockito.when(mockNotExprContext.expression()).thenReturn(mockExpressionContext1);
Mockito.when(spyVisitor.visit(mockExpressionContext1)).thenReturn(new MSNumber(value));

MSType result = spyVisitor.visitNotExpr(mockNotExprContext);
Assertions.assertFalse(((MSBool) result).getValue());
}

@Test
void visitNotExprInvalidTypeThrowsRuntimeException() {
Mockito.when(mockNotExprContext.expression()).thenReturn(mockExpressionContext);
Mockito.when(spyVisitor.visit(mockExpressionContext)).thenReturn(new MSRelDir("right"));
Mockito.when(mockNotExprContext.expression()).thenReturn(mockExpressionContext1);
Mockito.when(spyVisitor.visit(mockExpressionContext1)).thenReturn(new MSRelDir("right"));

Assertions.assertThrows(RuntimeException.class, () -> spyVisitor.visitNotExpr(mockNotExprContext));
}

@ParameterizedTest
@ValueSource(ints = {-1000, -10, 0, 10, 1000})
void visitNegNegatesNumber(int value) {
Mockito.when(mockNegContext.expression()).thenReturn(mockExpressionContext);
Mockito.when(spyVisitor.visit(mockExpressionContext)).thenReturn(new MSNumber(value));
Mockito.when(mockNegContext.expression()).thenReturn(mockExpressionContext1);
Mockito.when(spyVisitor.visit(mockExpressionContext1)).thenReturn(new MSNumber(value));

MSType result = spyVisitor.visitNeg(mockNegContext);
Assertions.assertEquals(-value, ((MSNumber) result).getValue());
}

@Test
void visitNegInvalidTypeThrowsRuntimeException() {
Mockito.when(mockNegContext.expression()).thenReturn(mockExpressionContext);
Mockito.when(spyVisitor.visit(mockExpressionContext)).thenReturn(new MSBool(false));
Mockito.when(mockNegContext.expression()).thenReturn(mockExpressionContext1);
Mockito.when(spyVisitor.visit(mockExpressionContext1)).thenReturn(new MSBool(false));

Assertions.assertThrows(RuntimeException.class, () -> spyVisitor.visitNeg(mockNegContext));
}
Expand Down Expand Up @@ -250,4 +259,22 @@ void visitNumberInvalidInputThrowsRuntimeException(){
Mockito.when(mockNumberContext.NUMBER()).thenReturn(new MockTerminalNode("abc"));
Assertions.assertThrows(RuntimeException.class, () -> spyVisitor.visitNumber(mockNumberContext));
}

@ParameterizedTest
@CsvSource ({"1, 2, +", "2, 1, -", "0, 0, +", "-1, -2, +", "-2, -1, -"})
void visitAddSubValidInputReturnsNumber(int value1, int value2, String operator){
mockAddSubContext.op = new MockToken(operator);
Mockito.when(mockAddSubContext.expression(0)).thenReturn(mockExpressionContext1);
Mockito.when(mockAddSubContext.expression(1)).thenReturn(mockExpressionContext2);
Mockito.when(spyVisitor.visit(mockExpressionContext1)).thenReturn(new MSNumber(value1));
Mockito.when(spyVisitor.visit(mockExpressionContext2)).thenReturn(new MSNumber(value2));

MSType result = spyVisitor.visitAddSub(mockAddSubContext);
if (operator.equals("+")){
Assertions.assertEquals(value1 + value2, ((MSNumber) result).getValue());
} else if (operator.equals("-")){
Assertions.assertEquals(value1 - value2, ((MSNumber) result).getValue());
}
}

}
58 changes: 58 additions & 0 deletions src/test/interpreter/utils/MockToken.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package interpreter.utils;

import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenSource;

public record MockToken(String token) implements Token {

@Override
public String getText() {
return token;
}

@Override
public int getType() {
return 0;
}

@Override
public int getLine() {
return 0;
}

@Override
public int getCharPositionInLine() {
return 0;
}

@Override
public int getChannel() {
return 0;
}

@Override
public int getTokenIndex() {
return 0;
}

@Override
public int getStartIndex() {
return 0;
}

@Override
public int getStopIndex() {
return 0;
}

@Override
public TokenSource getTokenSource() {
return null;
}

@Override
public CharStream getInputStream() {
return null;
}
}