mirror of
https://github.com/aNNiMON/Own-Programming-Language-Tutorial.git
synced 2024-09-20 00:34:20 +03:00
Refactor ounit functions
This commit is contained in:
parent
03d890df7c
commit
31945471dd
@ -5,7 +5,6 @@ import com.annimon.ownlang.lib.*;
|
||||
import com.annimon.ownlang.modules.Module;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -22,72 +21,54 @@ public final class ounit implements Module {
|
||||
|
||||
@Override
|
||||
public Map<String, Function> functions() {
|
||||
final var result = new LinkedHashMap<String, Function>(16);
|
||||
result.put("assertEquals", new assertEquals());
|
||||
result.put("assertNotEquals", new assertNotEquals());
|
||||
result.put("assertSameType", new assertSameType());
|
||||
result.put("assertTrue", new assertTrue());
|
||||
result.put("assertFalse", new assertFalse());
|
||||
result.put("runTests", new runTests());
|
||||
return result;
|
||||
return Map.of(
|
||||
"assertEquals", this::assertEquals,
|
||||
"assertNotEquals", this::assertNotEquals,
|
||||
"assertSameType", this::assertSameType,
|
||||
"assertTrue", this::assertTrue,
|
||||
"assertFalse", this::assertFalse,
|
||||
"runTests", this::runTests
|
||||
);
|
||||
}
|
||||
|
||||
private static String microsToSeconds(long micros) {
|
||||
return new DecimalFormat("#0.0000").format(micros / 1000d / 1000d) + " sec";
|
||||
}
|
||||
|
||||
private static class assertEquals implements Function {
|
||||
@Override
|
||||
public Value execute(Value[] args) {
|
||||
private Value assertEquals(Value[] args) {
|
||||
Arguments.check(2, args.length);
|
||||
if (args[0].equals(args[1])) return NumberValue.ONE;
|
||||
throw new OUnitAssertionException("Values are not equal: "
|
||||
+ "1: " + args[0] + ", 2: " + args[1]);
|
||||
}
|
||||
}
|
||||
|
||||
private static class assertNotEquals implements Function {
|
||||
@Override
|
||||
public Value execute(Value[] args) {
|
||||
private Value assertNotEquals(Value[] args) {
|
||||
Arguments.check(2, args.length);
|
||||
if (!args[0].equals(args[1])) return NumberValue.ONE;
|
||||
throw new OUnitAssertionException("Values are equal: " + args[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private static class assertSameType implements Function {
|
||||
@Override
|
||||
public Value execute(Value[] args) {
|
||||
private Value assertSameType(Value[] args) {
|
||||
Arguments.check(2, args.length);
|
||||
if (args[0].type() == args[1].type()) return NumberValue.ONE;
|
||||
throw new OUnitAssertionException("Types mismatch. "
|
||||
+ "1: " + Types.typeToString(args[0].type())
|
||||
+ ", 2: " + Types.typeToString(args[1].type()));
|
||||
}
|
||||
}
|
||||
|
||||
private static class assertTrue implements Function {
|
||||
@Override
|
||||
public Value execute(Value[] args) {
|
||||
private Value assertTrue(Value[] args) {
|
||||
Arguments.check(1, args.length);
|
||||
if (args[0].asInt() != 0) return NumberValue.ONE;
|
||||
throw new OUnitAssertionException("Expected true, but found false.");
|
||||
}
|
||||
}
|
||||
|
||||
private static class assertFalse implements Function {
|
||||
@Override
|
||||
public Value execute(Value[] args) {
|
||||
private Value assertFalse(Value[] args) {
|
||||
Arguments.check(1, args.length);
|
||||
if (args[0].asInt() == 0) return NumberValue.ONE;
|
||||
throw new OUnitAssertionException("Expected false, but found true.");
|
||||
}
|
||||
}
|
||||
|
||||
private static class runTests implements Function {
|
||||
|
||||
@Override
|
||||
public Value execute(Value[] args) {
|
||||
private Value runTests(Value[] args) {
|
||||
final var testFunctions = ScopeHandler.functions().entrySet().stream()
|
||||
.filter(e -> e.getKey().toLowerCase().startsWith("test"))
|
||||
.toList();
|
||||
@ -126,7 +107,6 @@ public final class ounit implements Module {
|
||||
final long elapsedTime = System.nanoTime() - startTime;
|
||||
return new TestInfo(name, isSuccessfull, failureDescription, elapsedTime / 1000);
|
||||
}
|
||||
}
|
||||
|
||||
private static class OUnitAssertionException extends RuntimeException {
|
||||
|
||||
@ -142,7 +122,7 @@ public final class ounit implements Module {
|
||||
long elapsedTimeInMicros
|
||||
) {
|
||||
public String info() {
|
||||
return String.format("%s [%s]\n%sElapsed: %s\n",
|
||||
return "%s [%s]\n%sElapsed: %s\n".formatted(
|
||||
name,
|
||||
isPassed ? "passed" : "FAILED",
|
||||
isPassed ? "" : (failureDescription + "\n"),
|
||||
|
@ -0,0 +1,52 @@
|
||||
package com.annimon.ownlang.parser;
|
||||
|
||||
import com.annimon.ownlang.lib.FunctionValue;
|
||||
import com.annimon.ownlang.lib.NumberValue;
|
||||
import com.annimon.ownlang.lib.ScopeHandler;
|
||||
import com.annimon.ownlang.parser.ast.Node;
|
||||
import com.annimon.ownlang.stages.Stage;
|
||||
import com.annimon.ownlang.stages.StagesData;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
|
||||
public class MockOUnitStage implements Stage<Node, Node> {
|
||||
|
||||
@Override
|
||||
public Node perform(StagesData stagesData, Node input) {
|
||||
ScopeHandler.resetScope();
|
||||
ScopeHandler.setFunction("assertEquals", (args) -> {
|
||||
assertEquals(args[0], args[1]);
|
||||
return NumberValue.ONE;
|
||||
});
|
||||
ScopeHandler.setFunction("assertNotEquals", (args) -> {
|
||||
assertNotEquals(args[0], args[1]);
|
||||
return NumberValue.ONE;
|
||||
});
|
||||
ScopeHandler.setFunction("assertSameType", (args) -> {
|
||||
assertEquals(args[0].type(), args[1].type());
|
||||
return NumberValue.ONE;
|
||||
});
|
||||
ScopeHandler.setFunction("assertTrue", (args) -> {
|
||||
assertTrue(args[0].asInt() != 0);
|
||||
return NumberValue.ONE;
|
||||
});
|
||||
ScopeHandler.setFunction("assertFalse", (args) -> {
|
||||
assertFalse(args[0].asInt() != 0);
|
||||
return NumberValue.ONE;
|
||||
});
|
||||
ScopeHandler.setFunction("assertFail", (args) -> {
|
||||
assertThrows(Throwable.class,
|
||||
() -> ((FunctionValue) args[0]).getValue().execute());
|
||||
return NumberValue.ONE;
|
||||
});
|
||||
ScopeHandler.setFunction("fail", (args) -> {
|
||||
if (args.length > 0) {
|
||||
fail(args[0].asString());
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
return NumberValue.ONE;
|
||||
});
|
||||
return input;
|
||||
}
|
||||
}
|
@ -2,8 +2,6 @@ package com.annimon.ownlang.parser;
|
||||
|
||||
import com.annimon.ownlang.Console;
|
||||
import com.annimon.ownlang.exceptions.OwnLangParserException;
|
||||
import com.annimon.ownlang.lib.FunctionValue;
|
||||
import com.annimon.ownlang.lib.NumberValue;
|
||||
import com.annimon.ownlang.lib.ScopeHandler;
|
||||
import com.annimon.ownlang.parser.ast.ClassDeclarationStatement;
|
||||
import com.annimon.ownlang.parser.ast.FunctionDefineStatement;
|
||||
@ -42,7 +40,7 @@ public class ProgramsTest {
|
||||
.then(new ParserStage())
|
||||
.then(new LinterStage(LinterStage.Mode.SEMANTIC))
|
||||
.thenConditional(true, new OptimizationStage(9))
|
||||
.then(ProgramsTest::mockOUnit)
|
||||
.then(new MockOUnitStage())
|
||||
.then(new ExecutionStage())
|
||||
.then((stagesData, input) -> {
|
||||
input.accept(testFunctionsExecutor);
|
||||
@ -50,45 +48,6 @@ public class ProgramsTest {
|
||||
});
|
||||
}
|
||||
|
||||
private static Node mockOUnit(StagesData stagesData, Node input) {
|
||||
ScopeHandler.resetScope();
|
||||
// Let's mock junit methods as ounit functions
|
||||
ScopeHandler.setFunction("assertEquals", (args) -> {
|
||||
assertEquals(args[0], args[1]);
|
||||
return NumberValue.ONE;
|
||||
});
|
||||
ScopeHandler.setFunction("assertNotEquals", (args) -> {
|
||||
assertNotEquals(args[0], args[1]);
|
||||
return NumberValue.ONE;
|
||||
});
|
||||
ScopeHandler.setFunction("assertSameType", (args) -> {
|
||||
assertEquals(args[0].type(), args[1].type());
|
||||
return NumberValue.ONE;
|
||||
});
|
||||
ScopeHandler.setFunction("assertTrue", (args) -> {
|
||||
assertTrue(args[0].asInt() != 0);
|
||||
return NumberValue.ONE;
|
||||
});
|
||||
ScopeHandler.setFunction("assertFalse", (args) -> {
|
||||
assertFalse(args[0].asInt() != 0);
|
||||
return NumberValue.ONE;
|
||||
});
|
||||
ScopeHandler.setFunction("assertFail", (args) -> {
|
||||
assertThrows(Throwable.class,
|
||||
() -> ((FunctionValue) args[0]).getValue().execute());
|
||||
return NumberValue.ONE;
|
||||
});
|
||||
ScopeHandler.setFunction("fail", (args) -> {
|
||||
if (args.length > 0) {
|
||||
fail(args[0].asString());
|
||||
} else {
|
||||
fail();
|
||||
}
|
||||
return NumberValue.ONE;
|
||||
});
|
||||
return input;
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void testProgram(InputSource inputSource) {
|
||||
@ -119,7 +78,7 @@ public class ProgramsTest {
|
||||
|
||||
@Override
|
||||
public void visit(ClassDeclarationStatement s) {
|
||||
|
||||
// skip for tests
|
||||
}
|
||||
};
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user