Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support DSL values in oracles #439

Merged
merged 8 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions tested/internationalization/nl.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ nl:
Contacteer de lesgever.
unsupported: "Evaluation in %{lang} wordt niet ondersteund."
unknown:
compilation: "Ongekende compilatie fout"
compilation: "Ongekende compilatiefout"
produced:
stderr: "De evaluatiecode produceerde volgende uitvoer op stderr:"
stdout: "De evaluatiecode produceerde volgende uitvoer op stdout:"
Expand All @@ -86,7 +86,7 @@ nl:
languages:
config:
unknown:
compilation: "Ongekende compilatie fout"
compilation: "Ongekende compilatiefout"
generator:
missing:
input: "Geen invoer gevonden."
Expand Down
12 changes: 6 additions & 6 deletions tested/judge/programmed.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
generate_custom_evaluator,
generate_statement,
)
from tested.serialisation import BooleanEvalResult, EvalResult, Value
from tested.oracles.common import BooleanEvalResult
from tested.serialisation import Value
from tested.testsuite import CustomCheckOracle
from tested.utils import get_identifier

Expand All @@ -34,7 +35,7 @@
evaluator: CustomCheckOracle,
expected: Value,
actual: Value,
) -> BaseExecutionResult | EvalResult:
) -> BaseExecutionResult | BooleanEvalResult:
"""
Run the custom evaluation. Concerning structure and execution, the custom
oracle is very similar to the execution of the whole evaluation. It a
Expand Down Expand Up @@ -181,7 +182,7 @@
oracle: CustomCheckOracle,
expected: Value,
actual: Value,
) -> EvalResult:
) -> BooleanEvalResult:
"""
Run an evaluation in Python. While the templates are still used to generate
code, they are not executed in a separate process, but inside python itself.
Expand Down Expand Up @@ -267,13 +268,12 @@
permission=Permission.STAFF,
)
)
return EvalResult(
return BooleanEvalResult(

Check warning on line 271 in tested/judge/programmed.py

View check run for this annotation

Codecov / codecov/patch

tested/judge/programmed.py#L271

Added line #L271 was not covered by tests
result=Status.INTERNAL_ERROR,
readable_expected=None,
readable_actual=None,
messages=messages,
)

assert isinstance(result_, BooleanEvalResult)
result_.messages.extend(messages)
return result_.as_eval_result()
return result_
2 changes: 1 addition & 1 deletion tested/languages/bash/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ def convert_encoder(values: list[Value]) -> str:
}}

function send_value {{
echo "{{\\"type\\": \\"text\\", \\"data\\": $(json_escape "$1")}}"
echo "{{\\"type\\": \\"text\\", \\"data\\": $(json_escape "$1")}}"
}}
"""
for value in values:
Expand Down
2 changes: 1 addition & 1 deletion tested/languages/c/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,6 @@ def convert_encoder(values: list[Value]) -> str:
"""
for value in values:
result += " " * 4 + f"write_value(stdout, {convert_value(value)});\n"
result += " " * 4 + 'printf("\\n");\n'
result += " " * 4 + 'printf("");\n'
result += "}\n"
return result
2 changes: 2 additions & 0 deletions tested/languages/c/templates/evaluation_result.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ typedef struct EvaluationResult {
char* readableActual;
size_t nrOfMessages;
Message** messages;
char* dslExpected;
char* dslActual;
} EvaluationResult;


Expand Down
2 changes: 1 addition & 1 deletion tested/languages/csharp/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ def convert_encoder(values: list[Value]) -> str:

for value in values:
result += " " * 6 + f"Values.WriteValue(stdout, {convert_value(value)});"
result += " " * 6 + 'stdout.Write("\\n");\n'
result += " " * 6 + 'stdout.Write("");\n'

result += "}\n}\n}\n"
return result
2 changes: 1 addition & 1 deletion tested/languages/csharp/templates/EvaluationResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace Tested {
public record Message(string Description, string Format = "text", string? Permission = null);
public record EvaluationResult(bool Result, string? ReadableExpected = null, string? ReadableActual = null, List<Message>? Messages = null)
public record EvaluationResult(bool Result, string? ReadableExpected = null, string? ReadableActual = null, List<Message>? Messages = null, string? DslExpected = null, string? DslActual = null)
{
public List<Message> Messages { get; init; } = Messages ?? new List<Message>();
}
Expand Down
2 changes: 1 addition & 1 deletion tested/languages/haskell/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -350,5 +350,5 @@ def convert_encoder(values: list[Value]) -> str:

for value in values:
result += indent + f"sendValueH stdout ({convert_value(value)})\n"
result += indent + 'putStr "\\n"\n'
result += indent + 'putStr ""\n'
return result
6 changes: 5 additions & 1 deletion tested/languages/haskell/templates/EvaluationUtils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ data EvaluationResult = EvaluationResult {
result :: Bool,
readableExpected :: Maybe (String),
readableActual :: Maybe (String),
messages :: [Message]
messages :: [Message],
dslExpected :: Maybe (String),
dslActual :: Maybe (String)
} deriving Show

message description = Message {
Expand All @@ -24,5 +26,7 @@ evaluationResult = EvaluationResult {
result = False,
readableExpected = Nothing,
readableActual = Nothing,
dslExpected = Nothing,
dslActual = Nothing,
messages = []
}
2 changes: 1 addition & 1 deletion tested/languages/java/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ def convert_encoder(values: list[Value]) -> str:

for value in values:
result += " " * 8 + f"Values.send(writer, {convert_value(value)});\n"
result += " " * 8 + 'writer.write("\\n");\n'
result += " " * 8 + 'writer.write("");\n'

result += " " * 8 + "writer.close();\n"
result += " " * 4 + "}\n"
Expand Down
20 changes: 18 additions & 2 deletions tested/languages/java/templates/EvaluationResult.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ public class EvaluationResult {
public final boolean result;
public final String readableExpected;
public final String readableActual;
public final String dslExpected;
public final String dslActual;
public final List<Message> messages;

private EvaluationResult(boolean result, String readableExpected, String readableActual, List<Message> messages) {
private EvaluationResult(boolean result, String readableExpected, String readableActual, String dslExpected, String dslActual, List<Message> messages) {
this.result = result;
this.readableExpected = readableExpected;
this.readableActual = readableActual;
this.dslExpected = dslExpected;
this.dslActual = dslActual;
this.messages = messages;
}

Expand Down Expand Up @@ -44,6 +48,8 @@ public static class Builder {
private final boolean result;
private String readableExpected = null;
private String readableActual = null;
private String dslExpected = null;
private String dslActual = null;
private final List<Message> messages = new ArrayList<>();

private Builder(boolean result) {
Expand All @@ -59,6 +65,16 @@ public Builder withReadableActual(String readableActual) {
this.readableActual = readableActual;
return this;
}

public Builder withDslExpected(String dslExpected) {
this.dslExpected = dslExpected;
return this;
}

public Builder withDslActual(String dslActual) {
this.dslActual = dslActual;
return this;
}

public Builder withMessages(List<Message> messages) {
this.messages.addAll(messages);
Expand All @@ -71,7 +87,7 @@ public Builder withMessage(Message message) {
}

public EvaluationResult build() {
return new EvaluationResult(result, readableExpected, readableActual, messages);
return new EvaluationResult(result, readableExpected, readableActual, dslExpected, dslActual, messages);
}
}
}
78 changes: 51 additions & 27 deletions tested/languages/java/templates/Values.java
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,13 @@ private static List<String> internalEncode(Object value) {

private static String encode(Object value) {
var typeAndData = internalEncode(value);
return "{ \"data\": " + typeAndData.get(1) + "," +
" \"type\": \"" + typeAndData.get(0) + "\", " +
" \"diagnostic\": " + typeAndData.get(2) + "}";
return """
{
"data": %s,
"type": "%s",
"diagnostic": %s
}
""".formatted(typeAndData.get(1), typeAndData.get(0), typeAndData.get(2));
}

public static void send(PrintWriter writer, Object value) {
Expand All @@ -145,37 +149,57 @@ public static void sendException(PrintWriter writer, Throwable exception) {
exception.printStackTrace(new PrintWriter(sw));
var trace = sw.toString();
var msg = exception.getMessage();
var result = "{ \"message\": \"" + escape(msg == null ? "" : msg) +
"\", \"stacktrace\": \"" + escape(trace) +
"\", \"type\": \"" + exception.getClass().getSimpleName() + "\"}";
String result = """
{
"message": %s,
"stacktrace": %s,
"type": "%s"
}
""".formatted(asJson(msg), asJson(trace), exception.getClass().getSimpleName());
writer.write(result);
}

private static String convertMessage(EvaluationResult.Message message) {
String result = "{" +
"\"description\": \"" + message.description + "\"," +
"\"format\": \"" + message.format + "\"";
if (message.permission instanceof String) {
result += ", \"permission\": \"" + message.permission + "\"";
}
return result + "}";
var description = asJson(message.description);
var format = asJson(message.format);
var permission = asJson(message.permission);

return """
{
"description": %s,
"format": %s,
"permission": %s
}
""".formatted(description, format, permission);
}

public static void evaluated(PrintWriter writer,
boolean result, String expected, String actual, Collection<EvaluationResult.Message> messages) {
List<String> converted = messages.stream().map(Values::convertMessage).collect(Collectors.toList());
String builder = "{" +
"\"result\": " +
result +
", \"readable_expected\": \"" + expected + "\"" +
", \"readable_actual\": \"" + actual + "\"" +
", \"messages\": [" +
String.join(", ", converted) +
"]}";
writer.print(builder);

private static String asJson(String value) {
if (value == null) {
return "null";
} else {
return "\"%s\"".formatted(escape(value));
}
}

public static void sendEvaluated(PrintWriter writer, EvaluationResult r) {
evaluated(writer, r.result, r.readableExpected, r.readableActual, r.messages);
List<String> converted = r.messages.stream().map(Values::convertMessage).collect(Collectors.toList());
var readableExpected = asJson(r.readableExpected);
var readableActual = asJson(r.readableActual);
var dslExpected = asJson(r.dslExpected);
var dslActual = asJson(r.dslActual);
var messages = String.join(", ", converted);

String result = """
{
"result": %b,
"readable_expected": %s,
"readable_actual": %s,
"dsl_expected": %s,
"dsl_actual": %s,
"messages": [%s]
}
""".formatted(r.result, readableExpected, readableActual, dslExpected, dslActual, messages);

writer.print(result);
}
}
2 changes: 1 addition & 1 deletion tested/languages/javascript/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,6 @@ def convert_encoder(values: list[Value]) -> str:

for value in values:
result += f"values.sendValue(process.stdout.fd, {convert_value(value)});\n"
result += 'fs.writeSync(process.stdout.fd, "\\n");\n'
result += 'fs.writeSync(process.stdout.fd, "");\n'

return result
2 changes: 1 addition & 1 deletion tested/languages/kotlin/generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ def convert_encoder(values: list[Value]) -> str:

for value in values:
result += " " * 4 + f"valuesSend(writer, {convert_value(value)})\n"
result += " " * 4 + 'writer.write("\\n")\n'
result += " " * 4 + 'writer.write("")\n'

result += " " * 4 + "writer.close()\n"
result += "}\n"
Expand Down
18 changes: 16 additions & 2 deletions tested/languages/kotlin/templates/EvaluationResult.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ class EvaluationResult private constructor(
val result: Boolean,
val readableExpected: String?,
val readableActual: String?,
val dslExpected: String?,
val dslActual: String?,
val messages: List<Message>
) {
class Message(val description: String,
Expand All @@ -11,7 +13,9 @@ class EvaluationResult private constructor(
class Builder(
private val result: Boolean,
private var readableActual: String? = null,
private var readableExpected: String? = null
private var readableExpected: String? = null,
private var dslActual: String? = null,
private var dslExpected: String? = null
) {
private val messages: MutableList<Message> = ArrayList()

Expand All @@ -25,6 +29,16 @@ class EvaluationResult private constructor(
return this
}

fun withDslActual(dslActual: String?): Builder {
this.dslActual = dslActual
return this
}

fun withDslExpected(dslExpected: String?): Builder {
this.dslExpected = dslExpected
return this
}

fun withMessages(messages: List<Message>): Builder {
this.messages += messages
return this
Expand All @@ -37,7 +51,7 @@ class EvaluationResult private constructor(

fun build(): EvaluationResult {
return EvaluationResult(result, readableExpected,
readableActual, messages)
readableActual, dslExpected, dslActual, messages)
}
}
}
Loading
Loading