-
Notifications
You must be signed in to change notification settings - Fork 7
add file content #577
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
base: master
Are you sure you want to change the base?
add file content #577
Conversation
…make stdin more consistent
Documentation for usage of filesThis documentation will discuss all the changes made regarding FilesFiles are used to describe files that can be added as input for a test and will provide the student with this file in Dodona. This is done in the following way: files:
- name: "animal.txt"
url: "media/workdir/animal.txt"
file:
content: "animal.txt" # is the content that the file should have
location: "media/workdir/animal.txt" # is the location of the file
oracle: ... There are several issues with this:
The name input_files:
- name: "animal.txt"
path: "media/workdir/animal.txt"
- name: "human.txt"
path: "media/workdir/human.txt"
output_files:
data:
- content: "lion"
path: "media/workdir/animal.txt"
- content: "tim"
path: "media/workdir/human.txt"
oracle: ....
output_files:
- content: "animal"
path: "media/workdir/animal.txt"
- content: "humant"
path: "media/workdir/human.txt" You can still only specify paths in the output_files:
data:
- content: !path "animal.txt"
path: "media/workdir/animal.txt"
- content: "Humans can make music and a warm meal"
path: "media/workdir/human.txt"
oracle: .... So For the feedback, it's all still a bit fuzzy because right now all the content is dumped after eachother. Potential solution:
Most of that will probably need to happen on Dodona itself. Stdin, Stdout and StderrHow things currently work, you have to specify the full contents of the stdin, stdout and stderr channels. This can get ugly, when that's a lot of text. This is why the usage of files is also very benificial here. Example for Stdin: stdin: !path "media/workdir/animal.txt" The usage of Under the hood, Stderr and Stdout are both just textual output channels. So they both have the exact same functionality. Examples for Stdout: stdout: !path "media/workdir/animal.txt"
stdout:
content: !path "media/workdir/animal.txt"
config: ...
oracle: ... |
Thanks for all the detailed examples. I'll try to follow the same structure in my feedback. Input filesI would remove the parameter First exampleThis example makes no sense. All benefits of being able to specify content inline are lost if you also specify a First example feedbackI would expect the Second exampleWhy are we providing urls to the random internet here? This again makes no sense. You're exercise will be using a local copy of that file in the git repo. But students would be linked to a random website, which content might change, breaking the exercise. These should not be a use-case we want to support. some more feedbackIf Another option would be to be more consistent with Output filesI am not sure I am the biggest fan of the fact that First exampleI assume Returning the content inline in all cases is fine for now. We can resolve exceptionally large files in a future iteration. (But Dodona isn't very suited to compare long files anyway) StdinI like that stdin matches input files. So, feedback applied there should also be usefull here first exampleok second exampleI don't see much need for this usecase (as it is supported by first example) I do not understand why the output would be any different from the output of the first example? Third exampleThe usecase here seems, very long stdin, better specified in a file. If we didn't require a name, we could simply specify If we insist on naming the file we can do
I am confused by your example, as Fourth exampleSee input files, having both Fifth exampleno comment sixth exampleno comment Seventh exampleHow is the description adjusted to contain the link? A simple text replace? Stdout & StderrFirst exampleok Second exampleAgain no need, but no harm done Third exampleI would prefer simply The example feedback is really confusing. Fourth exampleI don't get at all how arguments should have any impact on how we represent stdout? Fifth exampleHaving everything specified at once is very confusing. What will TESTed use? |
Thanks for your feedback. Input filesFirst exampleIt is a valid point to scrap Second exampleI just read this part of the existing documentation again. I'm not against the removal of Output filesI really wouldn't change anything here. StdinThird exampleThis was a mistake. I edited the docs. Seventh exampleThis is done using a regex and text replacement. Stdout & StderrThird exampleThey just aren't used in this case. Fourth exampleI'm simply following the way it's done with Fifth exampleI don't understand what you mean? This is just a simple example where output-redirection for |
Then why is there
Okay I missed that it was an output pipe and not an input pipe. For stdin, an argument for hiding large inputs can be made. But for stdout we'll always want to visualize the comparison of expected and generated. And I don't see the need to ever show this as a file to the user.
You have specified:
So we have now three ways to specify the expected content of This creates some complexity that is not needed nor desired |
This was an extra request from @pdawyndt. Since input redirection can already be present in the
This is just the exact same as |
Documentation for new extensions (updated version from feedback)This documentation will discuss all the changes made regarding the IO of a test. Input filesInput files (currently First exampletabs:
- tab: counting
contexts:
- testcases:
- expression: count_words('fish.txt', 'sharks')
return: 1
input_files:
- path: "fish.txt"
content: "There are sharks in the water!"
- path: "mammal.txt"
content: "There are tigers in the water!" A The presence of the The feedback for this example is the following: First example feedback{"command": "start-judgement"}
{"title": "counting", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "count_words('<a class=\"file-link\" target=\"_blank\">fish.txt</a>', 'sharks')", "format": "html"}, "command": "start-testcase"}
{"expected": "1", "channel": "return", "command": "start-test"}
{"generated": "1", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"message": {"description": "<div class='contains-file''><p>File: <a class=\"file-link\" target=\"_blank\"><span class=\"code\">mammal.txt</span></a></p></div>", "format": "html"}, "command": "append-message"}
{"data": {"statements": "count_words('fish.txt', 'sharks')", "input_files": [{"path": "fish.txt", "content": "There are sharks in the water!"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} The seen input files are provided in the data and the start of the html to make a hyperlink is provided in the Second exampletabs:
- tab: counting
contexts:
- testcases:
- expression: count_words('fish.txt', 'sharks')
return: 1
input_files:
- path: "fish.txt"
url: "media/workdir/fish.txt" In this case, the file is expected to already be present in the working directory. The feedback would be the following: Second example feedback{"command": "start-judgement"}
{"title": "counting", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "count_words('<a class=\"file-link\" target=\"_blank\">fish.txt</a>', 'sharks')", "format": "html"}, "command": "start-testcase"}
{"expected": "1", "channel": "return", "command": "start-test"}
{"generated": "1", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {"statements": "count_words('fish.txt', 'sharks')", "input_files": [{"path": "fish.txt", "url": "media/workdir/fish.txt"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} The main difference is that the Output filesIn TESTed, you were only able to provide a single output file using
First exampletabs:
- tab: output_file
contexts:
- testcases:
- expression: genereer('origineel_tekst.txt', 'text', 3)
return: true
output_files:
- content: !path "files_tests/tekst1.txt"
path: "text1.txt"
- content: !path "files_tests/tekst2.txt"
path: "text2.txt"
- content: "Created using write mode.\n3\n"
path: "text3.txt"
input_files:
- path: "origineel_tekst.txt"
url: "media/workdir/origineel_tekst.txt" The feedback provided for this test would look something like the following: {"command": "start-judgement"}
{"title": "output_file", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "genereer('<a class=\"file-link\" target=\"_blank\">origineel_tekst.txt</a>', 'text', 3)", "format": "html"}, "command": "start-testcase"}
{"expected": "Created using write mode.\n1\n", "channel": "File: text1.txt", "command": "start-test"}
{"generated": "Created using write mode.\n1\n", "status": {"enum": "correct"}, "command": "close-test"}
{"expected": "Created using write mode.\n2\n", "channel": "File: text2.txt", "command": "start-test"}
{"generated": "Created using write mode.\n2\n", "status": {"enum": "correct"}, "command": "close-test"}
{"expected": "Created using write mode.\n3\n", "channel": "File: text3.txt", "command": "start-test"}
{"generated": "Created using write mode.\n3\n", "status": {"enum": "correct"}, "command": "close-test"}
{"expected": "True", "channel": "return", "command": "start-test"}
{"generated": "True", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {"statements": "genereer('origineel_tekst.txt', 'text', 3)", "input_files": [{"path": "origineel_tekst.txt", "url": "media/workdir/origineel_tekst.txt"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} For each output file, the feedback includes a pair showing both the expected and the generated content. The StdinIn TESTed, First exampletabs:
- tab: stdin
contexts:
- testcases:
- stdin: "hello"
stdout: "hello world!\n" In this setup, Second exampletabs:
- tab: stdin
contexts:
- testcases:
- stdin:
content: "hello"
stdout: "hello world!\n" This one is equivalent with the first example. The feedback for those would look something like this: {"command": "start-judgement"}
{"title": "stdin", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "hello\n", "format": "console"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} This is the exact same as it is now, but stdin is no longer present in data. This is because we didn't see any more use for it. Third exampletabs:
- tab: stdin
contexts:
- testcases:
- stdin:
path: "hello.txt"
url: "media/workdir/hello.txt"
stdout: "hello world!\n" In this case, the content must be read from a file. The output looks like this: Third example feedback{"command": "start-judgement"}
{"title": "stdin", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "$ submission < <a class=\"file-link\" target=\"_blank\">hello.txt</a>", "format": "html"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {"input_files": [{"path": "hello.txt", "url": "media/workdir/hello.txt"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} The provided data file is also given in Fourth exampletabs:
- tab: stdin
contexts:
- testcases:
- stdin:
path: "hello.txt"
content: "hello"
stdout: "hello world!\n" In this case, the file doesn't need to physically exist in the working directory. The feedback will be the following: Fourth example feedback{"command": "start-judgement"}
{"title": "stdin", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "$ submission < <a class=\"file-link\" target=\"_blank\">hello.txt</a>", "format": "html"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {"input_files": [{"path": "hello.txt", "content": "hello\n"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} Now the content will be provided in data instead of a Fifth exampletabs:
- tab: stdin
contexts:
- testcases:
- stdin:
path: "hello.txt"
content: "hello"
arguments: ["world"]
stdout: "hello world!\n" Because an argument was provided, the Fifth example feedback{"command": "start-judgement"}
{"title": "stdin", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "$ submission world < <a class=\"file-link\" target=\"_blank\">hello.txt</a>", "format": "html"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {"input_files": [{"path": "hello.txt", "content": "hello\n"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} Sixth exampletabs:
- tab: stdin
contexts:
- testcases:
- stdin:
content: "hello"
arguments: ["world"]
stdout: "hello world!\n" Sixth example feedback{"command": "start-judgement"}
{"title": "stdin", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "$ submission world <<< hello", "format": "console"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} TESTed uses here-files in this case, but for single-line content, you can use a special shorthand syntax, as shown in the Seventh exampletabs:
- tab: stdin
contexts:
- testcases:
- stdin:
path: "hello.txt"
content: "hello"
arguments: ["world"]
description: "stdin_test world < hello.txt"
stdout: "hello world!\n" Here the Seventh example feedback:{"command": "start-judgement"}
{"title": "stdin", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "stdin_test world < <a class=\"file-link\" target=\"_blank\">hello.txt</a>", "format": "html"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {"input_files": [{"path": "hello.txt", "content": "hello\n"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} Stdout & StderrIn TESTed, First exampletabs:
- tab: stdout
contexts:
- testcases:
- stdin: "hello"
stdout: "hello world!\n" This was already possible in TESTed. Second example- tab: stdout
contexts:
- testcases:
- stdin: "hello"
stdout:
content: "hello world!\n" In TESTed, the key First and second example feedback{"command": "start-judgement"}
{"title": "stdout", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "hello\n", "format": "console"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} This is still the same as it is in TESTed. Third exampletabs:
- tab: stdout
contexts:
- testcases:
- stdin: "hello"
stdout:
path: "files_tests/hello_out.txt"
url: "media/hello_out.txt" Just like Third example feedback{"command": "start-judgement"}
{"title": "stdout", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "$ submission <<< hello > <a class=\"file-link\" target=\"_blank\">files_tests/hello_out.txt</a>", "format": "html"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {"input_files": [{"path": "files_tests/hello_out.txt", "url": "media/hello_out.txt"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"}
In the Fourth exampletabs:
- tab: stdout
contexts:
- testcases:
- stdin: "hello"
arguments: ["world"]
stdout:
path: "files_tests/hello_out.txt"
url: "media/hello_out.txt" In the example above arguments are added. This provide the following feedback: Fourth example feedback{"command": "start-judgement"}
{"title": "stdout", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "$ submission world <<< hello > <a class=\"file-link\" target=\"_blank\">files_tests/hello_out.txt</a>", "format": "html"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {"input_files": [{"path": "files_tests/hello_out.txt", "url": "media/hello_out.txt"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} The output is almost the exact same. The only difference is the extra argument in The same thing can also be done for Fifth exampletabs:
- tab: stdout
contexts:
- testcases:
- stdin:
path: "hello.txt"
url: "media/workdir/hello.txt"
arguments: ["world"]
stdout:
path: "files_tests/hello_out.txt"
content: "hello world!\n"
stderr:
path: "files_tests/hello_err.txt"
data: "ERROR\n" # Deprecated The Fourth example feedback{"command": "start-judgement"}
{"title": "stdout", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "$ submission world < <a class=\"file-link\" target=\"_blank\">hello.txt</a> > <a class=\"file-link\" target=\"_blank\">files_tests/hello_out.txt</a> 2> <a class=\"file-link\" target=\"_blank\">files_tests/hello_err.txt</a>", "format": "html"}, "command": "start-testcase"}
{"expected": "ERROR\n", "channel": "stderr", "command": "start-test"}
{"generated": "", "status": {"enum": "wrong"}, "command": "close-test"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {"input_files": [{"path": "files_tests/hello_out.txt", "content": "hello world!\n"}, {"path": "files_tests/hello_err.txt", "content": "ERROR\n"}, {"path": "hello.txt", "url": "media/workdir/hello.txt"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} Now the |
Documentation for new extensions (updated version)This documentation will discuss all the changes made regarding the IO of a test. Input filesInput files (currently First exampletabs:
- tab: counting
contexts:
- testcases:
- expression: count_words('fish.txt', 'sharks')
return: 1
input_files:
- path: "fish.txt"
content: "There are sharks in the water!"
- path: "mammal.txt"
content: "There are tigers in the water!" A The presence of the The feedback for this example is the following: First example feedback{"command": "start-judgement"}
{"title": "counting", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "count_words('<a class=\"file-link\" target=\"_blank\">fish.txt</a>', 'sharks')", "format": "html"}, "command": "start-testcase"}
{"expected": "1", "channel": "return", "command": "start-test"}
{"generated": "1", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"message": {"description": "<div class='contains-file''><p>File: <a class=\"file-link\" target=\"_blank\"><span class=\"code\">mammal.txt</span></a></p></div>", "format": "html"}, "command": "append-message"}
{"data": {"statements": "count_words('fish.txt', 'sharks')", "files": [{"path": "fish.txt", "content": "There are sharks in the water!"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} The seen input files are provided in the data and the start of the html to get make a hyperlink is provided in the Second exampletabs:
- tab: counting
contexts:
- testcases:
- expression: count_words('fish.txt', 'sharks')
return: 1
input_files:
- path: "fish.txt" In this case, the file is expected to already be present in the working directory. Dodona will make the hyperlink in the Second example feedback{"command": "start-judgement"}
{"title": "counting", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "count_words('<a class=\"file-link\" target=\"_blank\">fish.txt</a>', 'sharks')", "format": "html"}, "command": "start-testcase"}
{"expected": "1", "channel": "return", "command": "start-test"}
{"generated": "1", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {"statements": "count_words('fish.txt', 'sharks')", "files": [{"path": "fish.txt"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} The main difference is that only Output filesIn TESTed, you were only able to provide a single output file using
First exampletabs:
- tab: output_file
contexts:
- testcases:
- expression: genereer('origineel_tekst.txt', 'text', 3)
return: true
output_files:
- content: !path "files_tests/tekst1.txt"
path: "text1.txt"
- content: !path "files_tests/tekst2.txt"
path: "text2.txt"
- content: "Created using write mode.\n3\n"
path: "text3.txt"
input_files:
- path: "origineel_tekst.txt"
content: "Created using write mode.\n" The feedback provided for this test would look something like the following: {"command": "start-judgement"}
{"title": "output_file", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "genereer('<a class=\"file-link\" target=\"_blank\">origineel_tekst.txt</a>', 'text', 3)", "format": "html"}, "command": "start-testcase"}
{"expected": "Created using write mode.\n1\n", "channel": "file: text1.txt", "command": "start-test"}
{"generated": "Created using write mode.\n1\n", "status": {"enum": "correct"}, "command": "close-test"}
{"expected": "Created using write mode.\n2\n", "channel": "file: text2.txt", "command": "start-test"}
{"generated": "Created using write mode.\n2\n", "status": {"enum": "correct"}, "command": "close-test"}
{"expected": "Created using write mode.\n3\n", "channel": "file: text3.txt", "command": "start-test"}
{"generated": "Created using write mode.\n3\n", "status": {"enum": "correct"}, "command": "close-test"}
{"expected": "True", "channel": "return", "command": "start-test"}
{"generated": "True", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {"statements": "genereer('origineel_tekst.txt', 'text', 3)", "files": [{"path": "origineel_tekst.txt", "content": "Created using write mode.\n"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} For each output file, the feedback includes a pair showing both the expected and the generated content. The StdinIn TESTed, First exampletabs:
- tab: stdin
contexts:
- testcases:
- stdin: "hello"
stdout: "hello world!\n" In this setup, Second exampletabs:
- tab: stdin
contexts:
- testcases:
- stdin:
content: "hello"
stdout: "hello world!\n" This one is equivalent with the first example. The feedback for those would look something like this: {"command": "start-judgement"}
{"title": "stdin", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "hello\n", "format": "console"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} This is the exact same as it is now, but stdin is no longer present in data. This is because we didn't see any more use for it. Third exampletabs:
- tab: stdin
contexts:
- testcases:
- stdin:
path: "hello.txt"
stdout: "hello world!\n" In this case, the content must be read from a file. The output looks like this: Third example feedback{"command": "start-judgement"}
{"title": "stdin", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "$ submission < <a class=\"file-link\" target=\"_blank\">hello.txt</a>", "format": "html"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {"files": [{"path": "hello.txt"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} The provided information about the file is also given in Fourth exampletabs:
- tab: stdin
contexts:
- testcases:
- stdin:
path: "hello.txt"
content: "hello"
stdout: "hello world!\n" In this case, the file doesn't need to physically exist in the working directory. The feedback will be the following: Fourth example feedback{"command": "start-judgement"}
{"title": "stdin", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "$ submission < <a class=\"file-link\" target=\"_blank\">hello.txt</a>", "format": "html"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {"files": [{"path": "hello.txt", "content": "hello\n"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} Now the content will be provided in data. Fifth exampletabs:
- tab: stdin
contexts:
- testcases:
- stdin:
path: "hello.txt"
content: "hello"
arguments: ["world"]
stdout: "hello world!\n" Because an argument was provided, the Fifth example feedback{"command": "start-judgement"}
{"title": "stdin", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "$ submission world < <a class=\"file-link\" target=\"_blank\">hello.txt</a>", "format": "html"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {"files": [{"path": "hello.txt", "content": "hello\n"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} Sixth exampletabs:
- tab: stdin
contexts:
- testcases:
- stdin:
content: "hello"
arguments: ["world"]
stdout: "hello world!\n" Sixth example feedback{"command": "start-judgement"}
{"title": "stdin", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "$ submission world <<< hello", "format": "console"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} TESTed uses here-files in this case, but for single-line content, you can use a special shorthand syntax, as shown in the Seventh exampletabs:
- tab: stdin
contexts:
- testcases:
- stdin:
path: "hello.txt"
content: "hello"
arguments: ["world"]
description: "stdin_test world < hello.txt"
stdout: "hello world!\n" Here the Seventh example feedback:{"command": "start-judgement"}
{"title": "stdin", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "stdin_test world < <a class=\"file-link\" target=\"_blank\">hello.txt</a>", "format": "html"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {"files": [{"path": "hello.txt", "content": "hello\n"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} Stdout & StderrIn TESTed, First exampletabs:
- tab: stdout
contexts:
- testcases:
- stdin: "hello"
stdout: "hello world!\n" This was already possible in TESTed. Second example- tab: stdout
contexts:
- testcases:
- stdin: "hello"
stdout:
content: "hello world!\n" In TESTed, the key First and second example feedback{"command": "start-judgement"}
{"title": "stdout", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "hello\n", "format": "console"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} This is still the same as it is in TESTed. Third exampletabs:
- tab: stdout
contexts:
- testcases:
- stdin: "hello"
stdout:
path: "files_tests/hello_out.txt" Just like Third example feedback{"command": "start-judgement"}
{"title": "stdout", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "hello\n", "format": "console"}, "command": "start-testcase"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} Currently the feedback will still be the same. In a later stage the new DSL could be used by Dodona to provide the feedback by file instead of just a string. Fifth exampletabs:
- tab: stdout
contexts:
- testcases:
- stdin:
path: "hello.txt"
url: "media/workdir/hello.txt"
arguments: ["world"]
stdout:
path: "files_tests/hello_out.txt"
content: "hello world!\n"
stderr:
path: "files_tests/hello_err.txt"
data: "ERROR\n" # Deprecated The Fourth example feedback{"command": "start-judgement"}
{"title": "stdout", "command": "start-tab"}
{"command": "start-context"}
{"description": {"description": "$ submission world < <a class=\"file-link\" target=\"_blank\">hello.txt</a>", "format": "html"}, "command": "start-testcase"}
{"expected": "ERROR\n", "channel": "stderr", "command": "start-test"}
{"generated": "ERROR\n", "status": {"enum": "correct"}, "command": "close-test"}
{"expected": "hello world!\n", "channel": "stdout", "command": "start-test"}
{"generated": "hello world!\n", "status": {"enum": "correct"}, "command": "close-test"}
{"command": "close-testcase"}
{"data": {"files": [{"path": "hello.txt"}]}, "command": "close-context"}
{"command": "close-tab"}
{"command": "close-judgement"} |
This version of the described features looks fine to me. Is the code also ready for review? |
Yes, the code is ready too. |
Just realised that the way deprecated messages are done still need to change, but other than that it should be fine. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't review all json schema's, But I assume the feedback I have given on the strict schema is applicable to all
type: TextChannelType = TextChannelType.TEXT | ||
|
||
def get_data_as_string(self, working_directory: Path) -> str: | ||
"""Get the data as a string, reading the file if necessary.""" | ||
if self.type == TextChannelType.TEXT: | ||
if self.data is not None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't keep support for all deprecated usages (eg. with data and type TextChannelType.FILE
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is used for stdin
, stdout
and stderr
.
For stdin
you could only provide a string. So, in this case nothing would change since data
is the provided string and type is TextChannelType.TEXT
.
For stdout
and stderr
, you could also only provide a string. So in this case there are no problems either.
Why would you still need to read the file if data
is already provided?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this was the old code:
if self.type == TextChannelType.TEXT:
return self.data
elif self.type == TextChannelType.FILE:
file_path = _resolve_path(working_directory, self.data)
with open(file_path, "r") as file:
return file.read()
So in the old case it was possible to have data
and type TextChannelType.FILE
.
Now as far as I understood data
is deprecated and replaced by content
and path
This check if self.data is not None:
will return true if we are evaluating an old exercise making use of the deprecated data
keyword.
Looking at the old code, this could mean we have to handle either TEXT
or a FILE
.
Your code acts as if the FILE
case never existed.
So a couple of things could be happening here:
- I completely misunderstood the code, the variable names here have a different meaning as those in the DSL for example...
- In the old code
elif self.type == TextChannelType.FILE
was impossible to reach and never used, so we can remove it without issues - You need to add a check on
self.type
in the caseself.data is not None
Could you tell me which of these three cases it is?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable data
and the keys data
and content
in the DSL are the same thing here. This new check makes life easier because now you can provide content
and path
. In this case, there would be no need to read it from the file.
So I think you misunderstood the code.
However, I don't think there was any usecase for the type FILE
before I made any changes.
@@ -148,6 +168,7 @@ def _parse_yaml(yaml_stream: str) -> YamlObject: | |||
yaml.add_constructor("!" + actual_type, _custom_type_constructors, loader) | |||
yaml.add_constructor("!expression", _expression_string, loader) | |||
yaml.add_constructor("!oracle", _return_oracle, loader) | |||
yaml.add_constructor("!path", _path_string, loader) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
has this ever been discussed during one of your thesis meetings?
It has. This is used in the |
No description provided.