diff --git a/tested/dodona.py b/tested/dodona.py index 90e5f7683..b2cb127b0 100644 --- a/tested/dodona.py +++ b/tested/dodona.py @@ -17,15 +17,7 @@ from attrs import define from cattrs.preconf.json import make_converter - -@unique -class Permission(StrEnum): - """To which level of user this message is visible.""" - - STAFF = auto() - STUDENT = auto() - ZEUS = auto() - +from testsuite import Permission @define class ExtendedMessage: diff --git a/tested/dsl/schema-strict.json b/tested/dsl/schema-strict.json index d9e3f4074..37f0d1225 100644 --- a/tested/dsl/schema-strict.json +++ b/tested/dsl/schema-strict.json @@ -105,7 +105,10 @@ }, "hidden" : { "type" : "boolean", - "description" : "Defines if the unit/tab is hidden for the student or not" + "description" : "Tab is only shown if it has tests that failed" + }, + "permission": { + "$ref" : "#/definitions/permission" }, "tab" : { "type" : "string", @@ -142,6 +145,14 @@ } ] }, + "permission": { + "type" : "string", + "description" : "One of the permission levels supported by Dodona", + "enum" : [ + "student", + "staff" + ] + }, "unit" : { "type" : "object", "description" : "A unit in the test suite.", diff --git a/tested/dsl/schema.json b/tested/dsl/schema.json index f8d066bca..e148e2abb 100644 --- a/tested/dsl/schema.json +++ b/tested/dsl/schema.json @@ -105,7 +105,10 @@ }, "hidden" : { "type" : "boolean", - "description" : "Defines if the unit/tab is hidden for the student or not" + "description" : "Tab is only shown if it has tests that failed" + }, + "permission": { + "$ref" : "#/definitions/permission" }, "tab" : { "type" : "string", @@ -142,6 +145,14 @@ } ] }, + "permission": { + "type" : "string", + "description" : "One of the permission levels supported by Dodona", + "enum" : [ + "student", + "staff" + ] + }, "unit" : { "type" : "object", "description" : "A unit in the test suite.", diff --git a/tested/judge/core.py b/tested/judge/core.py index 24bdd3b31..e14de9e34 100644 --- a/tested/judge/core.py +++ b/tested/judge/core.py @@ -324,7 +324,7 @@ def _process_results( collector.add(CloseTab(), currently_open_tab) currently_open_tab = currently_open_tab + 1 tab = bundle.suite.tabs[currently_open_tab] - collector.add(StartTab(title=tab.name, hidden=tab.hidden)) + collector.add(StartTab(title=tab.name, hidden=tab.hidden, permission=tab.permission)) # Handle the contexts. collector.add(StartContext(description=planned.context.description)) diff --git a/tested/judge/evaluation.py b/tested/judge/evaluation.py index 44b2571ab..e478366f8 100644 --- a/tested/judge/evaluation.py +++ b/tested/judge/evaluation.py @@ -487,7 +487,7 @@ def complete_evaluation(bundle: Bundle, collector: OutputManager): for tab in bundle.suite.tabs[tab_start:]: if context_start == 0 and testcase_start == 0: - collector.add(StartTab(title=tab.name, hidden=tab.hidden)) + collector.add(StartTab(title=tab.name, hidden=tab.hidden, permission=tab.permission)) assert tab.contexts for context in tab.contexts[context_start:]: updates: list[Update] = [ diff --git a/tested/testsuite.py b/tested/testsuite.py index 4ef5f0aac..c93a23522 100644 --- a/tested/testsuite.py +++ b/tested/testsuite.py @@ -683,6 +683,13 @@ def _runs_to_tab_converter(runs: list | None): contexts.append(context) return contexts +@unique +class Permission(StrEnum): + """To which level of user this message is visible.""" + + STAFF = auto() + STUDENT = auto() + ZEUS = auto() @custom_fallback_field(get_converter(), {"runs": ("contexts", _runs_to_tab_converter)}) @define @@ -692,6 +699,7 @@ class Tab(WithFeatures, WithFunctions): name: str contexts: list[Context] = field() hidden: bool | None = None + permission: Permission | None = None def get_used_features(self) -> FeatureSet: assert self.contexts is not None diff --git a/tests/test_dsl_yaml.py b/tests/test_dsl_yaml.py index aecf78846..e6090bc47 100644 --- a/tests/test_dsl_yaml.py +++ b/tests/test_dsl_yaml.py @@ -37,6 +37,7 @@ GenericValueOracle, LanguageLiterals, LanguageSpecificOracle, + Permission, SupportedLanguage, TextOutputChannel, ValueOutputChannel, @@ -1326,6 +1327,26 @@ def test_programming_language_can_be_globally_configured(): assert testcase.input.type == "expression" assert testcase.input.literals.keys() == {"java"} +def test_tabs_can_be_given_permission(): + yaml_str = """ +namespace: "solution" +tabs: +- tab: "Ctx" + permission: "staff" + testcases: + - arguments: [ "--arg", "argument" ] + stdin: "Input string" + stdout: "Output string" + stderr: "Error string" + exit_code: 1 + """ + json_str = translate_to_test_suite(yaml_str) + suite = parse_test_suite(json_str) + assert len(suite.tabs) == 1 + tab = suite.tabs[0] + assert tab.permission == Permission.STAFF + assert isinstance(testcase.input, LanguageLiterals) + assert testcase.input.type == "expression" def test_strict_json_schema_is_valid(): path_to_schema = Path(__file__).parent / "tested-draft7.json"