From 83730a437c868b06ff0d36fbcf9608ab8adabd43 Mon Sep 17 00:00:00 2001 From: breblanc Date: Tue, 15 Apr 2025 18:13:39 +0200 Subject: [PATCH 01/24] made first version for using templates --- tested/nat_translation.py | 62 ++++++++++++++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/tested/nat_translation.py b/tested/nat_translation.py index 4915def2..091f2772 100644 --- a/tested/nat_translation.py +++ b/tested/nat_translation.py @@ -82,13 +82,20 @@ def construct_custom(loader, tag_suffix, node): def translate_yaml( - data: Any, translations: dict, language: str, env: Environment + data: Any, + translations: dict, + templates: dict, + template_data: dict, + language: str, + env: Environment, ) -> Any: """ This function will translate the multilingual object. :param data: The object to translate. :param translations: The merge of all found translations maps. + :param templates: The merge of all found templates. + :param template_data: The data passed to a template. This will only not be empty when a template is processed. :param language: The language to translate to. :param env: The Jinja-environment to use. :return: The translated object. @@ -97,7 +104,12 @@ def translate_yaml( if "__tag__" in data and data["__tag__"] == "!natural_language": value = data["value"] assert language in value - return translate_yaml(value[language], translations, language, env) + return translate_yaml( + value[language], translations, templates, template_data, language, env + ) + + current_templates = data.pop("templates", {}) + templates = {**templates, **current_templates} current_translations = data.pop("translations", {}) for key, value in current_translations.items(): @@ -105,15 +117,49 @@ def translate_yaml( current_translations[key] = value[language] translations = {**translations, **current_translations} - return { - key: translate_yaml(value, translations, language, env) + template = None + if "placeholder" in data: + placeholder = data.pop("placeholder") + name = placeholder["name"] + new_temp_data = translate_yaml( + placeholder["data"], + translations, + templates, + template_data, + language, + env, + ) + + assert name in templates + template = translate_yaml( + templates[name], translations, templates, new_temp_data, language, env + ) + + if not data: + return template + assert isinstance(template, dict) + + result = { + key: translate_yaml( + value, translations, templates, template_data, language, env + ) for key, value in data.items() } + if template is not None: + result.update(template) + + return result elif isinstance(data, list): - return [translate_yaml(item, translations, language, env) for item in data] + return [ + translate_yaml(item, translations, templates, template_data, language, env) + for item in data + ] elif isinstance(data, str): + print(data) try: - return env.from_string(data).render(translations) + return env.from_string(data).render( + translations=translations, template=template_data + ) except TemplateSyntaxError: return data return data @@ -188,10 +234,10 @@ def run_translation( _, ext = os.path.splitext(path) assert ext.lower() in (".yaml", ".yml"), f"expected a yaml file, got {ext}." parsed_yaml = parse_yaml(yaml_stream) - validate_pre_dsl(parsed_yaml) + #validate_pre_dsl(parsed_yaml) enviroment = create_enviroment() - translated_data = translate_yaml(parsed_yaml, {}, language, enviroment) + translated_data = translate_yaml(parsed_yaml, {}, {}, {}, language, enviroment) missing_keys = TrackingUndefined.missing_keys translated_yaml_string = convert_to_yaml(translated_data) From d5fd52ca05b9d3bd18d45c20db1e6da5d621648f Mon Sep 17 00:00:00 2001 From: breblanc Date: Tue, 15 Apr 2025 19:26:05 +0200 Subject: [PATCH 02/24] Fixed linting and typing errors --- tested/nat_translation.py | 5 ++--- tests/test_preprocess_dsl.py | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tested/nat_translation.py b/tested/nat_translation.py index 091f2772..9377dd85 100644 --- a/tested/nat_translation.py +++ b/tested/nat_translation.py @@ -155,10 +155,9 @@ def translate_yaml( for item in data ] elif isinstance(data, str): - print(data) try: return env.from_string(data).render( - translations=translations, template=template_data + translations=translations, templates=template_data ) except TemplateSyntaxError: return data @@ -234,7 +233,7 @@ def run_translation( _, ext = os.path.splitext(path) assert ext.lower() in (".yaml", ".yml"), f"expected a yaml file, got {ext}." parsed_yaml = parse_yaml(yaml_stream) - #validate_pre_dsl(parsed_yaml) + # validate_pre_dsl(parsed_yaml) enviroment = create_enviroment() translated_data = translate_yaml(parsed_yaml, {}, {}, {}, language, enviroment) diff --git a/tests/test_preprocess_dsl.py b/tests/test_preprocess_dsl.py index bbedfcfa..ea5f37d8 100644 --- a/tests/test_preprocess_dsl.py +++ b/tests/test_preprocess_dsl.py @@ -24,7 +24,7 @@ def validate_natural_translate(yaml_str: str, translated_yaml_str: str): enviroment = create_enviroment() yaml_object = parse_yaml(yaml_str) - translated_dsl = translate_yaml(yaml_object, {}, "en", enviroment) + translated_dsl = translate_yaml(yaml_object, {}, {}, {}, "en", enviroment) translated_yaml = convert_to_yaml(translated_dsl) assert translated_yaml.strip() == translated_yaml_str @@ -393,7 +393,7 @@ def test_validation(): validate_pre_dsl(yaml_object) enviroment = create_enviroment() - translated_data = translate_yaml(yaml_object, {}, "en", enviroment) + translated_data = translate_yaml(yaml_object, {}, {}, {}, "en", enviroment) translated_yaml_string = convert_to_yaml(translated_data) _validate_dsl(_parse_yaml(translated_yaml_string)) @@ -595,7 +595,7 @@ def test_to_yaml_object(): environment = create_enviroment() parsed_yaml = parse_yaml(yaml_str) - translated_dsl = translate_yaml(parsed_yaml, {}, "en", environment) + translated_dsl = translate_yaml(parsed_yaml, {}, {}, {}, "en", environment) translated_yaml_string = convert_to_yaml(translated_dsl) yaml_object = _parse_yaml(translated_yaml_string) assert isinstance(yaml_object, dict) From afa532af551240e221e36fa959e649e42fc61785 Mon Sep 17 00:00:00 2001 From: breblanc Date: Mon, 5 May 2025 21:12:34 +0200 Subject: [PATCH 03/24] updated template preprocessor --- tested/nat_translation.py | 177 ++++++++++++++++++++++++++++++-------- 1 file changed, 143 insertions(+), 34 deletions(-) diff --git a/tested/nat_translation.py b/tested/nat_translation.py index 9377dd85..618dfaa0 100644 --- a/tested/nat_translation.py +++ b/tested/nat_translation.py @@ -4,8 +4,9 @@ from pathlib import Path from typing import Any, Type, cast +import jinja2 import yaml -from jinja2 import Environment, TemplateSyntaxError, Undefined +from jinja2 import Environment, TemplateSyntaxError, Undefined, UndefinedError from jsonschema.protocols import Validator from jsonschema.validators import validator_for from yaml.nodes import MappingNode, ScalarNode, SequenceNode @@ -81,11 +82,47 @@ def construct_custom(loader, tag_suffix, node): return {"__tag__": tag_suffix, "value": data} +def init_template( + template: dict, + translations: dict, + templates: dict, + default_template: dict, + parameters: dict, + language: str, + env: Environment, +) -> dict: + + # translate parameters before inserting them into the template + new_parameters = translate_yaml( + parameters, + translations, + templates, + default_template, + parameters, + language, + env, + ) + + # translate template and insert parameters + template = translate_yaml( + template, + translations, + templates, + default_template, + new_parameters, + language, + env, + ) + assert isinstance(template, dict) + return template + + def translate_yaml( data: Any, translations: dict, templates: dict, - template_data: dict, + default_template: dict, + parameters: dict, language: str, env: Environment, ) -> Any: @@ -95,18 +132,29 @@ def translate_yaml( :param data: The object to translate. :param translations: The merge of all found translations maps. :param templates: The merge of all found templates. - :param template_data: The data passed to a template. This will only not be empty when a template is processed. + :param default_template: The defined default template. + :param parameters: The data passed to a template. This will only not be empty when a template is processed. :param language: The language to translate to. :param env: The Jinja-environment to use. :return: The translated object. """ if isinstance(data, dict): - if "__tag__" in data and data["__tag__"] == "!natural_language": - value = data["value"] - assert language in value - return translate_yaml( - value[language], translations, templates, template_data, language, env - ) + if "__tag__" in data: + if data["__tag__"] == "!natural_language": + value = data["value"] + assert language in value + return translate_yaml( + value[language], + translations, + templates, + default_template, + parameters, + language, + env, + ) + elif data["__tag__"] == "!parameter": + assert data["value"] in parameters + return parameters[data["value"]] current_templates = data.pop("templates", {}) templates = {**templates, **current_templates} @@ -117,50 +165,111 @@ def translate_yaml( current_translations[key] = value[language] translations = {**translations, **current_translations} - template = None - if "placeholder" in data: - placeholder = data.pop("placeholder") - name = placeholder["name"] - new_temp_data = translate_yaml( - placeholder["data"], + if "default_template" in data: + assert ( + not default_template + ), "Only one definition of a default template allowed!" + default_template = data.pop("default_template") + + if "template" in data or "parameters" in data: + if "template" in data: + name = data.pop("template") + assert name in templates + template = templates[name] + else: + assert default_template + template = default_template + template = init_template( + template, translations, templates, - template_data, + default_template, + data.pop("parameters", {}), language, env, ) - assert name in templates - template = translate_yaml( - templates[name], translations, templates, new_temp_data, language, env - ) - - if not data: - return template - assert isinstance(template, dict) + if data: + # Extra specifications in data will overwrite parts of the template. + data = translate_yaml( + data, + translations, + templates, + default_template, + parameters, + language, + env, + ) + for key, value in data.items(): + template[key] = value + return template + + if "repeat" in data: + repeat = data.pop("repeat") + assert "parameters" in repeat + parameters = repeat["parameters"] + assert isinstance(parameters, list) + + template = repeat.pop("case", {}) + if "template" in repeat: + name = repeat.pop("template") + assert name in templates + template = templates[name] + + return [ + init_template( + template, + translations, + templates, + default_template, + param_item, + language, + env, + ) + for param_item in parameters + ] result = { key: translate_yaml( - value, translations, templates, template_data, language, env + value, + translations, + templates, + default_template, + parameters, + language, + env, ) for key, value in data.items() } - if template is not None: - result.update(template) - return result elif isinstance(data, list): - return [ - translate_yaml(item, translations, templates, template_data, language, env) - for item in data - ] + result = [] + for item in data: + has_repeat = isinstance(item, dict) and "repeat" in item + translated = translate_yaml( + item, + translations, + templates, + default_template, + parameters, + language, + env, + ) + if has_repeat and isinstance(translated, list): + result.extend(translated) + else: + result.append(translated) + return result elif isinstance(data, str): try: + return env.from_string(data).render({**translations, **parameters}) + except UndefinedError: return env.from_string(data).render( - translations=translations, templates=template_data + translations=translations, parameters=parameters ) except TemplateSyntaxError: return data + return data @@ -236,7 +345,7 @@ def run_translation( # validate_pre_dsl(parsed_yaml) enviroment = create_enviroment() - translated_data = translate_yaml(parsed_yaml, {}, {}, {}, language, enviroment) + translated_data = translate_yaml(parsed_yaml, {}, {}, {}, {}, language, enviroment) missing_keys = TrackingUndefined.missing_keys translated_yaml_string = convert_to_yaml(translated_data) From e9e70ecfe3537422f0fa0afe3e4a16c300213acc Mon Sep 17 00:00:00 2001 From: breblanc Date: Thu, 15 May 2025 20:31:02 +0200 Subject: [PATCH 04/24] removed default value and throw errors for certain cases --- tested/nat_translation.py | 41 ++++++++++++--------------------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/tested/nat_translation.py b/tested/nat_translation.py index 618dfaa0..0fab4310 100644 --- a/tested/nat_translation.py +++ b/tested/nat_translation.py @@ -86,7 +86,6 @@ def init_template( template: dict, translations: dict, templates: dict, - default_template: dict, parameters: dict, language: str, env: Environment, @@ -97,10 +96,10 @@ def init_template( parameters, translations, templates, - default_template, parameters, language, env, + True ) # translate template and insert parameters @@ -108,10 +107,10 @@ def init_template( template, translations, templates, - default_template, new_parameters, language, env, + True ) assert isinstance(template, dict) return template @@ -121,10 +120,10 @@ def translate_yaml( data: Any, translations: dict, templates: dict, - default_template: dict, parameters: dict, language: str, env: Environment, + inside_templates: bool = False, ) -> Any: """ This function will translate the multilingual object. @@ -132,7 +131,6 @@ def translate_yaml( :param data: The object to translate. :param translations: The merge of all found translations maps. :param templates: The merge of all found templates. - :param default_template: The defined default template. :param parameters: The data passed to a template. This will only not be empty when a template is processed. :param language: The language to translate to. :param env: The Jinja-environment to use. @@ -147,7 +145,6 @@ def translate_yaml( value[language], translations, templates, - default_template, parameters, language, env, @@ -165,25 +162,18 @@ def translate_yaml( current_translations[key] = value[language] translations = {**translations, **current_translations} - if "default_template" in data: - assert ( - not default_template - ), "Only one definition of a default template allowed!" - default_template = data.pop("default_template") - if "template" in data or "parameters" in data: + assert parameters == inside_templates, "A template was defined inside another template. This is not allowed!" if "template" in data: name = data.pop("template") assert name in templates template = templates[name] else: - assert default_template - template = default_template + raise "Found parameter without specifying template!" template = init_template( template, translations, templates, - default_template, data.pop("parameters", {}), language, env, @@ -195,7 +185,6 @@ def translate_yaml( data, translations, templates, - default_template, parameters, language, env, @@ -205,23 +194,22 @@ def translate_yaml( return template if "repeat" in data: + assert parameters == inside_templates, "A repeat was defined inside another template. This is not allowed!" repeat = data.pop("repeat") assert "parameters" in repeat parameters = repeat["parameters"] assert isinstance(parameters, list) - template = repeat.pop("case", {}) - if "template" in repeat: - name = repeat.pop("template") - assert name in templates - template = templates[name] + assert "template" in repeat + name = repeat.pop("template") + assert name in templates + template = templates[name] return [ init_template( template, translations, templates, - default_template, param_item, language, env, @@ -234,7 +222,6 @@ def translate_yaml( value, translations, templates, - default_template, parameters, language, env, @@ -250,7 +237,6 @@ def translate_yaml( item, translations, templates, - default_template, parameters, language, env, @@ -261,12 +247,9 @@ def translate_yaml( result.append(translated) return result elif isinstance(data, str): + assert len(set(translations.keys()).intersection(set(parameters.keys()))) == 0, "Found a key in the translations map that is the same as inside a template. Please try to avoid this!" try: return env.from_string(data).render({**translations, **parameters}) - except UndefinedError: - return env.from_string(data).render( - translations=translations, parameters=parameters - ) except TemplateSyntaxError: return data @@ -345,7 +328,7 @@ def run_translation( # validate_pre_dsl(parsed_yaml) enviroment = create_enviroment() - translated_data = translate_yaml(parsed_yaml, {}, {}, {}, {}, language, enviroment) + translated_data = translate_yaml(parsed_yaml, {}, {}, {}, language, enviroment) missing_keys = TrackingUndefined.missing_keys translated_yaml_string = convert_to_yaml(translated_data) From ea321b2c7ae26907375e38b6b977bfc4a446f8dd Mon Sep 17 00:00:00 2001 From: breblanc Date: Fri, 16 May 2025 11:18:01 +0200 Subject: [PATCH 05/24] fixed tests and linting --- tested/nat_translation.py | 35 +++++++++++++++++------------------ tests/test_preprocess_dsl.py | 2 +- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/tested/nat_translation.py b/tested/nat_translation.py index 4712fb89..40133273 100644 --- a/tested/nat_translation.py +++ b/tested/nat_translation.py @@ -98,24 +98,12 @@ def init_template( # translate parameters before inserting them into the template new_parameters = translate_yaml( - parameters, - translations, - templates, - parameters, - language, - env, - True + parameters, translations, templates, parameters, language, env, True ) # translate template and insert parameters template = translate_yaml( - template, - translations, - templates, - new_parameters, - language, - env, - True + template, translations, templates, new_parameters, language, env, True ) assert isinstance(template, dict) return template @@ -139,6 +127,7 @@ def translate_yaml( :param parameters: The data passed to a template. This will only not be empty when a template is processed. :param language: The language to translate to. :param env: The Jinja-environment to use. + :param inside_templates: Indicator if a template is being processed. :return: The translated object. """ if isinstance(data, dict): @@ -153,6 +142,7 @@ def translate_yaml( parameters, language, env, + inside_templates, ) elif data["__tag__"] == "!parameter": assert data["value"] in parameters @@ -168,13 +158,15 @@ def translate_yaml( translations = {**translations, **current_translations} if "template" in data or "parameters" in data: - assert parameters == inside_templates, "A template was defined inside another template. This is not allowed!" + assert ( + parameters == inside_templates + ), "A template was defined inside another template. This is not allowed!" if "template" in data: name = data.pop("template") assert name in templates template = templates[name] else: - raise "Found parameter without specifying template!" + raise ValueError("Found parameter without specifying template!") template = init_template( template, translations, @@ -193,13 +185,16 @@ def translate_yaml( parameters, language, env, + inside_templates, ) for key, value in data.items(): template[key] = value return template if "repeat" in data: - assert parameters == inside_templates, "A repeat was defined inside another template. This is not allowed!" + assert ( + parameters == inside_templates + ), "A repeat was defined inside another template. This is not allowed!" repeat = data.pop("repeat") assert "parameters" in repeat parameters = repeat["parameters"] @@ -230,6 +225,7 @@ def translate_yaml( parameters, language, env, + inside_templates, ) for key, value in data.items() } @@ -245,6 +241,7 @@ def translate_yaml( parameters, language, env, + inside_templates, ) if has_repeat and isinstance(translated, list): result.extend(translated) @@ -252,7 +249,9 @@ def translate_yaml( result.append(translated) return result elif isinstance(data, str): - assert len(set(translations.keys()).intersection(set(parameters.keys()))) == 0, "Found a key in the translations map that is the same as inside a template. Please try to avoid this!" + assert ( + len(set(translations.keys()).intersection(set(parameters.keys()))) == 0 + ), "Found a key in the translations map that is the same as inside a template. Please try to avoid this!" try: return env.from_string(data).render({**translations, **parameters}) except TemplateSyntaxError: diff --git a/tests/test_preprocess_dsl.py b/tests/test_preprocess_dsl.py index 05a62a80..feb11e28 100644 --- a/tests/test_preprocess_dsl.py +++ b/tests/test_preprocess_dsl.py @@ -25,7 +25,7 @@ def validate_natural_translate(yaml_str: str, translated_yaml_str: str): enviroment = create_enviroment() yaml_object = parse_yaml(yaml_str) validate_pre_dsl(yaml_object) - translated_dsl = translate_yaml(yaml_object, {}, "en", enviroment) + translated_dsl = translate_yaml(yaml_object, {}, {}, {}, "en", enviroment) translated_yaml = convert_to_yaml(translated_dsl) assert translated_yaml.strip() == translated_yaml_str From 36ee5566842894b00d4dcb40b5d6249000060882 Mon Sep 17 00:00:00 2001 From: breblanc Date: Fri, 16 May 2025 12:18:09 +0200 Subject: [PATCH 06/24] made a few more tests --- tested/nat_translation.py | 7 +- tests/test_preprocess_dsl.py | 203 ++++++++++++++++++++++++++++++++++- 2 files changed, 205 insertions(+), 5 deletions(-) diff --git a/tested/nat_translation.py b/tested/nat_translation.py index 40133273..e273fc66 100644 --- a/tested/nat_translation.py +++ b/tested/nat_translation.py @@ -4,9 +4,8 @@ from pathlib import Path from typing import Any, Type, cast -import jinja2 import yaml -from jinja2 import Environment, TemplateSyntaxError, Undefined, UndefinedError +from jinja2 import Environment, TemplateSyntaxError, Undefined from jsonschema.protocols import Validator from jsonschema.validators import validator_for from yaml.nodes import MappingNode, ScalarNode, SequenceNode @@ -159,7 +158,7 @@ def translate_yaml( if "template" in data or "parameters" in data: assert ( - parameters == inside_templates + not parameters and not inside_templates ), "A template was defined inside another template. This is not allowed!" if "template" in data: name = data.pop("template") @@ -193,7 +192,7 @@ def translate_yaml( if "repeat" in data: assert ( - parameters == inside_templates + not parameters and not inside_templates ), "A repeat was defined inside another template. This is not allowed!" repeat = data.pop("repeat") assert "parameters" in repeat diff --git a/tests/test_preprocess_dsl.py b/tests/test_preprocess_dsl.py index feb11e28..b67bc87e 100644 --- a/tests/test_preprocess_dsl.py +++ b/tests/test_preprocess_dsl.py @@ -24,9 +24,10 @@ def validate_natural_translate(yaml_str: str, translated_yaml_str: str): enviroment = create_enviroment() yaml_object = parse_yaml(yaml_str) - validate_pre_dsl(yaml_object) + # validate_pre_dsl(yaml_object) translated_dsl = translate_yaml(yaml_object, {}, {}, {}, "en", enviroment) translated_yaml = convert_to_yaml(translated_dsl) + print(translated_yaml) assert translated_yaml.strip() == translated_yaml_str @@ -353,6 +354,206 @@ def test_natural_translate_io_test(): validate_natural_translate(yaml_str, translated_yaml_str) +def test_normal_template(): + yaml_str = """ +tabs: + - tab: 'animals' + templates: + animal_IO: + expression: + java: "Submission.animals({{ input }})" + python: "animals({{ input }})" + return: "{{ output }}" + testcases: + - template: "animal_IO" + parameters: + input: "Sardines" + output: "fish" + - template: "animal_IO" + parameters: + input: "Whale" + output: "mammal" + return: "mammal (not a fish)" + """.strip() + translated_yaml_str = """ +tabs: +- tab: animals + testcases: + - expression: + java: Submission.animals(Sardines) + python: animals(Sardines) + return: fish + - expression: + java: Submission.animals(Whale) + python: animals(Whale) + return: mammal (not a fish) + """.strip() + validate_natural_translate(yaml_str, translated_yaml_str) + + +def test_normal_repeat(): + yaml_str = """ +templates: + one_name: + stdin: |- + 1 + {{ name }} + stdout: "{{ username }}" +units: +- unit: IO + scripts: + - template: one_name + parameters: + name: Graham Chapman + username: gchap + - repeat: + template: one_name + parameters: + - name: John Cleese + username: jclee + - name: Terry Gilliam + username: tgill + - name: Eric Idle + username: eidle + - name: Terry Jones + username: tjone + - name: Michael Palin + username: mpali + """.strip() + translated_yaml_str = """ +units: +- unit: IO + scripts: + - stdin: '1 + + Graham Chapman' + stdout: gchap + - stdin: '1 + + John Cleese' + stdout: jclee + - stdin: '1 + + Terry Gilliam' + stdout: tgill + - stdin: '1 + + Eric Idle' + stdout: eidle + - stdin: '1 + + Terry Jones' + stdout: tjone + - stdin: '1 + + Michael Palin' + stdout: mpali + """.strip() + validate_natural_translate(yaml_str, translated_yaml_str) + + +def test_templates_with_translations_wrong(): + yaml_str = """ +translations: + animals: + en: "animals" + nl: "dieren" +tabs: + - tab: '{{ animals }}' + templates: + animal_IO: + expression: + java: "Submission.{{ animals }}({{ animals }})" + python: "{{animals}}({{ animals }})" + return: "{{ output }}" + testcases: + - template: "animal_IO" + parameters: + animals: "Sardines" + output: "fish" + """.strip() + try: + validate_natural_translate(yaml_str, "") + except AssertionError as e: + assert ( + repr(e) + == "AssertionError('Found a key in the translations map that is the same as inside a template. Please try to avoid this!')" + ) + else: + assert False + + +def test_templates_with_translations_correct(): + yaml_str = """ +translations: + animals: + en: "animals" + nl: "dieren" +tabs: + - tab: '{{ animals }}' + templates: + animal_IO: + expression: + java: "Submission.{{ animals }}({{ input }})" + python: "{{animals}}({{ input }})" + return: "{{ output }}" + testcases: + - template: "animal_IO" + parameters: + input: "Sardines" + output: "fish" + """.strip() + translated_yaml_str = """ +tabs: +- tab: animals + testcases: + - expression: + java: Submission.animals(Sardines) + python: animals(Sardines) + return: fish + """.strip() + validate_natural_translate(yaml_str, translated_yaml_str) + + +def test_non_string_parameter(): + yaml_str = """ +templates: + calculator_IO: + expression: "calculator('{{ expr }}')" + return: !parameter "result" + calculator_IO_non_int: + expression: "calculator('{{ expr }}', string)" + return: "{{ result }}" +tabs: + - tab: 'calculator' + testcases: + - template: "calculator_IO" + parameters: + expr: "2 + 10" + result: 12 + - template: "calculator_IO" + parameters: + expr: "4 * 13" + result: 52 + - template: "calculator_IO_non_int" + parameters: + expr: "4 * 13" + result: 52 + """.strip() + translated_yaml_str = """ +tabs: +- tab: calculator + testcases: + - expression: calculator('2 + 10') + return: 12 + - expression: calculator('4 * 13') + return: 52 + - expression: calculator('4 * 13', string) + return: '52' + """.strip() + validate_natural_translate(yaml_str, translated_yaml_str) + + def test_validation(): yaml_str = """ translations: From fa2fcb83e322d5e4505fe10c69b7973a1b6a39f2 Mon Sep 17 00:00:00 2001 From: breblanc Date: Fri, 16 May 2025 20:32:05 +0200 Subject: [PATCH 07/24] added templates to json schema for correct validation --- tested/dsl/multilingual-schema.json | 2461 ++++++--- tested/dsl/schema-strict-nat-translation.json | 4911 +++++++++++------ tested/dsl/schema-strict.json | 71 +- tested/transform_json.py | 122 +- tests/test_json_schema_transformer.py | 51 +- tests/test_preprocess_dsl.py | 2 +- 6 files changed, 4959 insertions(+), 2659 deletions(-) diff --git a/tested/dsl/multilingual-schema.json b/tested/dsl/multilingual-schema.json index b32f98d4..88915ead 100644 --- a/tested/dsl/multilingual-schema.json +++ b/tested/dsl/multilingual-schema.json @@ -139,7 +139,14 @@ }, "translations": { "type": "object", - "description": "Define translations in the global scope." + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } } } }, @@ -271,8 +278,46 @@ ] }, "hidden": { - "type": "boolean", - "description": "Defines if the unit/tab is hidden for the student or not" + "anyOf": [ + { + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + { + "type": "boolean", + "description": "Defines if the unit/tab is hidden for the student or not" + } + ] }, "tab": { "oneOf": [ @@ -317,7 +362,14 @@ }, "translations": { "type": "object", - "description": "Define translations in the global scope." + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } } }, "oneOf": [ @@ -391,8 +443,46 @@ ] }, "hidden": { - "type": "boolean", - "description": "Defines if the unit/tab is hidden for the student or not" + "anyOf": [ + { + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + { + "type": "boolean", + "description": "Defines if the unit/tab is hidden for the student or not" + } + ] }, "unit": { "oneOf": [ @@ -437,7 +527,14 @@ }, "translations": { "type": "object", - "description": "Define translations in the global scope." + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } } }, "oneOf": [ @@ -589,7 +686,7 @@ "type": "array", "minItems": 1, "items": { - "$ref": "#/definitions/script" + "$ref": "#/definitions/testcase" } }, { @@ -598,7 +695,7 @@ "type": "array", "minItems": 1, "items": { - "$ref": "#/definitions/script" + "$ref": "#/definitions/testcase" } }, "not": { @@ -709,7 +806,14 @@ }, "translations": { "type": "object", - "description": "Define translations in the global scope." + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } } } }, @@ -799,7 +903,14 @@ }, "translations": { "type": "object", - "description": "Define translations in the global scope." + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } } } }, @@ -812,46 +923,84 @@ "$ref": "#/subDefinitions/message" }, "stdin": { - "oneOf": [ + "anyOf": [ { - "description": "Stdin for this context", - "type": [ - "string", - "number", - "integer", - "boolean" + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } ] }, { - "type": "object", - "additionalProperties": { - "description": "Stdin for this context", - "type": [ - "string", - "number", - "integer", - "boolean" - ] - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" + "oneOf": [ + { + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" + ] + }, + { + "type": "object", + "additionalProperties": { + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" ] }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } + } + ] } ] }, @@ -861,46 +1010,84 @@ "description": "Array of program call arguments", "type": "array", "items": { - "oneOf": [ + "anyOf": [ { - "type": [ - "string", - "number", - "integer", - "boolean" + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } ] }, { - "type": "object", - "additionalProperties": { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" + "oneOf": [ + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + }, + { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "number", + "integer", + "boolean" ] }, - { - "required": [ - "types" - ] - } - ] - } - } - ] + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + } + ] } }, { @@ -909,11 +1096,19 @@ "description": "Array of program call arguments", "type": "array", "items": { - "type": [ - "string", - "number", - "integer", - "boolean" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } ] } }, @@ -1008,175 +1203,58 @@ "$ref": "#/subDefinitions/fileOutputChannel" }, "exit_code": { - "type": "integer", - "description": "Expected exit code for the run" - } - } - }, - "script": { - "type": "object", - "description": "An individual test (script) for a statement or expression", - "properties": { - "description": { - "$ref": "#/subDefinitions/message" - }, - "stdin": { - "oneOf": [ - { - "description": "Stdin for this context", - "type": [ - "string", - "number", - "integer", - "boolean" - ] - }, + "anyOf": [ { - "type": "object", - "additionalProperties": { - "description": "Stdin for this context", - "type": [ - "string", - "number", - "integer", - "boolean" - ] - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" }, - { - "required": [ - "types" - ] - } - ] - } - } - ] - }, - "arguments": { - "oneOf": [ - { - "description": "Array of program call arguments", - "type": "array", - "items": { - "oneOf": [ - { - "type": [ - "string", - "number", - "integer", - "boolean" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] - }, - { - "type": "object", - "additionalProperties": { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } } - ] - } + } + ] }, { - "type": "object", - "additionalProperties": { - "description": "Array of program call arguments", - "type": "array", - "items": { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } + "type": "integer", + "description": "Expected exit code for the run" } ] }, - "statement": { - "description": "The statement to evaluate.", - "$ref": "#/subDefinitions/expressionOrStatement" - }, - "expression": { - "description": "The expression to evaluate.", - "$ref": "#/subDefinitions/expressionOrStatement" - }, - "exception": { - "description": "Expected exception message", - "$ref": "#/subDefinitions/exceptionChannel" - }, - "files": { + "template": { "oneOf": [ { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } + "type": "string", + "description": "Name of the template to insert." }, { "type": "object", "additionalProperties": { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } + "type": "string", + "description": "Name of the template to insert." }, "not": { "anyOf": [ @@ -1200,122 +1278,135 @@ } ] }, - "return": { - "description": "Expected return value", - "$ref": "#/subDefinitions/returnOutputChannel" - }, - "stderr": { - "description": "Expected output at stderr", - "$ref": "#/subDefinitions/textOutputChannel" - }, - "stdout": { - "description": "Expected output at stdout", - "$ref": "#/subDefinitions/textOutputChannel" - }, - "file": { - "description": "Expected files generated by the submission.", - "$ref": "#/subDefinitions/fileOutputChannel" - }, - "exit_code": { - "type": "integer", - "description": "Expected exit code for the run" - } - } - } - }, - "subDefinitions": { - "expressionOrStatement": { - "oneOf": [ - { - "type": "string", - "format": "tested-dsl-expression", - "description": "A statement of expression in Python-like syntax as YAML string." - }, - { + "parameters": { "type": "object", + "description": "The parameters that are to be inserted into the template.", "additionalProperties": { - "type": "string", - "format": "tested-dsl-expression", - "description": "A statement of expression in Python-like syntax as YAML string." - }, - "not": { - "anyOf": [ + "oneOf": [ { - "required": [ - "description" - ] + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" }, { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } } ] } }, - { - "anyOf": [ - { + "repeat": { + "type": "object", + "description": "A certain loop that will generate test cases with the given parameters and template.", + "required": [ + "template", + "parameters" + ], + "properties": { + "template": { "oneOf": [ + { + "type": "string", + "description": "Name of the template to insert." + }, { "type": "object", - "description": "Programming-language-specific statement or expression.", - "minProperties": 1, - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" + "additionalProperties": { + "type": "string", + "description": "Name of the template to insert." }, - "items": { - "oneOf": [ + "not": { + "anyOf": [ { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." + "required": [ + "description" + ] }, { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] } ] } + } + ] + }, + "parameters": { + "oneOf": [ + { + "type": "array", + "items": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + } + } }, { "type": "object", "additionalProperties": { - "type": "object", - "description": "Programming-language-specific statement or expression.", - "minProperties": 1, - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, + "type": "array", "items": { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } } }, "not": { @@ -1340,43 +1431,31 @@ } ] } - ] + } } - ] + } }, - "yamlValueOrPythonExpression": { - "oneOf": [ - { - "$ref": "#/subDefinitions/yamlValue" + "testcase_without_templates": { + "type": "object", + "description": "An individual test for a statement or expression", + "additionalProperties": false, + "properties": { + "description": { + "$ref": "#/subDefinitions/message" }, - { - "type": "string", - "format": "tested-dsl-expression", - "description": "An expression in Python-syntax." - } - ] - }, - "file": { - "oneOf": [ - { - "type": "object", - "description": "A file used in the test suite.", - "required": [ - "name", - "url" - ], - "properties": { - "name": { + "stdin": { + "anyOf": [ + { "oneOf": [ { - "type": "string", - "description": "The filename, including the file extension." + "description": "The key of the parameter.", + "type": "string" }, { "type": "object", "additionalProperties": { - "type": "string", - "description": "The filename, including the file extension." + "description": "The key of the parameter.", + "type": "string" }, "not": { "anyOf": [ @@ -1400,19 +1479,27 @@ } ] }, - "url": { + { "oneOf": [ { - "type": "string", - "format": "uri", - "description": "Relative path to the file in the `description` folder of an exercise." + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" + ] }, { "type": "object", "additionalProperties": { - "type": "string", - "format": "uri", - "description": "Relative path to the file in the `description` folder of an exercise." + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" + ] }, "not": { "anyOf": [ @@ -1436,99 +1523,20 @@ } ] } - } - }, - { - "type": "object", - "additionalProperties": { - "type": "object", - "description": "A file used in the test suite.", - "required": [ - "name", - "url" - ], - "properties": { - "name": { - "type": "string", - "description": "The filename, including the file extension." - }, - "url": { - "type": "string", - "format": "uri", - "description": "Relative path to the file in the `description` folder of an exercise." - } - } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } - } - ] - }, - "exceptionChannel": { - "oneOf": [ - { - "type": "string", - "description": "Message of the expected exception." + ] }, - { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "Message of the expected exception." - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } - }, - { - "type": "object", - "required": [ - "types" - ], - "properties": { - "message": { + "arguments": { + "anyOf": [ + { "oneOf": [ { - "description": "Message of the expected exception.", + "description": "The key of the parameter.", "type": "string" }, { "type": "object", "additionalProperties": { - "description": "Message of the expected exception.", + "description": "The key of the parameter.", "type": "string" }, "not": { @@ -1553,44 +1561,88 @@ } ] }, - "types": { + { "oneOf": [ { - "minProperties": 1, - "description": "Language mapping of expected exception types.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, + "description": "Array of program call arguments", + "type": "array", "items": { - "oneOf": [ + "anyOf": [ { - "type": "string" + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] }, { - "type": "object", - "additionalProperties": { - "type": "string" - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" + "oneOf": [ + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + }, + { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "number", + "integer", + "boolean" ] }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } + } + ] } ] } @@ -1598,14 +1650,23 @@ { "type": "object", "additionalProperties": { - "minProperties": 1, - "description": "Language mapping of expected exception types.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, + "description": "Array of program call arguments", + "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + ] } }, "not": { @@ -1630,98 +1691,36 @@ } ] } - } + ] }, - { - "type": "object", - "additionalProperties": { - "type": "object", - "required": [ - "types" - ], - "properties": { - "message": { - "description": "Message of the expected exception.", - "type": "string" - }, - "types": { - "minProperties": 1, - "description": "Language mapping of expected exception types.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, - "items": { - "type": "string" - } - } - } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } - } - ] - }, - "textOutputChannel": { - "anyOf": [ - { - "$ref": "#/subDefinitions/textualType" + "statement": { + "description": "The statement to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" }, - { + "expression": { + "description": "The expression to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "exception": { + "description": "Expected exception message", + "$ref": "#/subDefinitions/exceptionChannel" + }, + "files": { "oneOf": [ { - "type": "object", - "description": "Built-in oracle for text values.", - "required": [ - "data" - ], - "properties": { - "data": { - "$ref": "#/subDefinitions/textualType" - }, - "oracle": { - "const": "builtin" - }, - "config": { - "$ref": "#/subDefinitions/textConfigurationOptions" - } + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" } }, { "type": "object", "additionalProperties": { - "type": "object", - "description": "Built-in oracle for text values.", - "required": [ - "data" - ], - "properties": { - "data": { - "$ref": "#/subDefinitions/textualType" - }, - "oracle": { - "const": "builtin" - }, - "config": { - "$ref": "#/subDefinitions/textConfigurationOptions" - } + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" } }, "not": { @@ -1746,22 +1745,610 @@ } ] }, - { - "oneOf": [ + "return": { + "description": "Expected return value", + "$ref": "#/subDefinitions/returnOutputChannel" + }, + "stderr": { + "description": "Expected output at stderr", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "stdout": { + "description": "Expected output at stdout", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "file": { + "description": "Expected files generated by the submission.", + "$ref": "#/subDefinitions/fileOutputChannel" + }, + "exit_code": { + "anyOf": [ { - "type": "object", - "description": "Custom oracle for text values.", - "required": [ - "oracle", - "file", - "data" - ], - "properties": { - "data": { - "$ref": "#/subDefinitions/textualType" + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" }, - "oracle": { - "const": "custom_check" + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + { + "type": "integer", + "description": "Expected exit code for the run" + } + ] + } + } + } + }, + "subDefinitions": { + "expressionOrStatement": { + "oneOf": [ + { + "type": "string", + "format": "tested-dsl-expression", + "description": "A statement of expression in Python-like syntax as YAML string." + }, + { + "type": "object", + "additionalProperties": { + "type": "string", + "format": "tested-dsl-expression", + "description": "A statement of expression in Python-like syntax as YAML string." + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + }, + { + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "description": "Programming-language-specific statement or expression.", + "minProperties": 1, + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "oneOf": [ + { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." + }, + { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + } + }, + { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Programming-language-specific statement or expression.", + "minProperties": 1, + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + } + ] + } + ] + }, + "yamlValueOrPythonExpression": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValue" + }, + { + "type": "string", + "description": "The key of the parameter." + }, + { + "type": "string", + "format": "tested-dsl-expression", + "description": "An expression in Python-syntax." + } + ] + }, + "file": { + "oneOf": [ + { + "type": "object", + "description": "A file used in the test suite.", + "required": [ + "name", + "url" + ], + "properties": { + "name": { + "oneOf": [ + { + "type": "string", + "description": "The filename, including the file extension." + }, + { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "The filename, including the file extension." + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "url": { + "oneOf": [ + { + "type": "string", + "format": "uri", + "description": "Relative path to the file in the `description` folder of an exercise." + }, + { + "type": "object", + "additionalProperties": { + "type": "string", + "format": "uri", + "description": "Relative path to the file in the `description` folder of an exercise." + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + } + } + }, + { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "A file used in the test suite.", + "required": [ + "name", + "url" + ], + "properties": { + "name": { + "type": "string", + "description": "The filename, including the file extension." + }, + "url": { + "type": "string", + "format": "uri", + "description": "Relative path to the file in the `description` folder of an exercise." + } + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "exceptionChannel": { + "oneOf": [ + { + "type": "string", + "description": "Message of the expected exception." + }, + { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Message of the expected exception." + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + }, + { + "type": "object", + "required": [ + "types" + ], + "properties": { + "message": { + "oneOf": [ + { + "description": "Message of the expected exception.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "Message of the expected exception.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "types": { + "oneOf": [ + { + "minProperties": 1, + "description": "Language mapping of expected exception types.", + "type": "object", + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + } + }, + { + "type": "object", + "additionalProperties": { + "minProperties": 1, + "description": "Language mapping of expected exception types.", + "type": "object", + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "type": "string" + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + } + } + }, + { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "types" + ], + "properties": { + "message": { + "description": "Message of the expected exception.", + "type": "string" + }, + "types": { + "minProperties": 1, + "description": "Language mapping of expected exception types.", + "type": "object", + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "type": "string" + } + } + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "textOutputChannel": { + "anyOf": [ + { + "$ref": "#/subDefinitions/textualType" + }, + { + "oneOf": [ + { + "type": "object", + "description": "Built-in oracle for text values.", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/subDefinitions/textualType" + }, + "oracle": { + "const": "builtin" + }, + "config": { + "$ref": "#/subDefinitions/textConfigurationOptions" + } + } + }, + { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Built-in oracle for text values.", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/subDefinitions/textualType" + }, + "oracle": { + "const": "builtin" + }, + "config": { + "$ref": "#/subDefinitions/textConfigurationOptions" + } + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + { + "oneOf": [ + { + "type": "object", + "description": "Custom oracle for text values.", + "required": [ + "oracle", + "file", + "data" + ], + "properties": { + "data": { + "$ref": "#/subDefinitions/textualType" + }, + "oracle": { + "const": "custom_check" }, "file": { "oneOf": [ @@ -3399,163 +3986,429 @@ } ] } - }, + }, + { + "type": "object", + "required": [ + "description" + ], + "properties": { + "description": { + "oneOf": [ + { + "description": "The message to display.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The message to display.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "format": { + "oneOf": [ + { + "type": "string", + "default": "text", + "description": "The format of the message, either a programming language, 'text' or 'html'." + }, + { + "type": "object", + "additionalProperties": { + "type": "string", + "default": "text", + "description": "The format of the message, either a programming language, 'text' or 'html'." + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + } + } + }, + { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "description" + ], + "properties": { + "description": { + "description": "The message to display.", + "type": "string" + }, + "format": { + "type": "string", + "default": "text", + "description": "The format of the message, either a programming language, 'text' or 'html'." + } + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "textConfigurationOptions": { + "oneOf": [ { "type": "object", - "required": [ - "description" - ], + "description": "Configuration properties for textual comparison and to configure if the expected value should be hidden or not", + "minProperties": 1, "properties": { - "description": { - "oneOf": [ + "applyRounding": { + "anyOf": [ { - "description": "The message to display.", - "type": "string" + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] }, { - "type": "object", - "additionalProperties": { - "description": "The message to display.", - "type": "string" - }, - "not": { - "anyOf": [ - { - "required": [ - "description" + "description": "Apply rounding when comparing as float", + "type": "boolean" + } + ] + }, + "caseInsensitive": { + "anyOf": [ + { + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] + } + } + ] + }, + { + "description": "Ignore case when comparing strings", + "type": "boolean" + } + ] + }, + "ignoreWhitespace": { + "anyOf": [ + { + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" }, - { - "required": [ - "value" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] + } + } + ] + }, + { + "description": "Ignore trailing whitespace", + "type": "boolean" + } + ] + }, + "normalizeTrailingNewlines": { + "anyOf": [ + { + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } + } + ] + }, + { + "description": "Normalize trailing newlines", + "type": "boolean" } ] }, - "format": { - "oneOf": [ + "roundTo": { + "anyOf": [ { - "type": "string", - "default": "text", - "description": "The format of the message, either a programming language, 'text' or 'html'." + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + { + "description": "The number of decimals to round at, when applying the rounding on floats", + "type": "integer" + } + ] + }, + "tryFloatingPoint": { + "anyOf": [ + { + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] }, { - "type": "object", - "additionalProperties": { - "type": "string", - "default": "text", - "description": "The format of the message, either a programming language, 'text' or 'html'." - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] + "description": "Try comparing text as floating point numbers", + "type": "boolean" + } + ] + }, + "hideExpected": { + "anyOf": [ + { + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } + } + ] + }, + { + "description": "Hide the expected value in feedback (default: false), not recommended to use!", + "type": "boolean" } ] } } }, - { - "type": "object", - "additionalProperties": { - "type": "object", - "required": [ - "description" - ], - "properties": { - "description": { - "description": "The message to display.", - "type": "string" - }, - "format": { - "type": "string", - "default": "text", - "description": "The format of the message, either a programming language, 'text' or 'html'." - } - } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } - } - ] - }, - "textConfigurationOptions": { - "oneOf": [ - { - "type": "object", - "description": "Configuration properties for textual comparison and to configure if the expected value should be hidden or not", - "minProperties": 1, - "properties": { - "applyRounding": { - "description": "Apply rounding when comparing as float", - "type": "boolean" - }, - "caseInsensitive": { - "description": "Ignore case when comparing strings", - "type": "boolean" - }, - "ignoreWhitespace": { - "description": "Ignore trailing whitespace", - "type": "boolean" - }, - "normalizeTrailingNewlines": { - "description": "Normalize trailing newlines", - "type": "boolean" - }, - "roundTo": { - "description": "The number of decimals to round at, when applying the rounding on floats", - "type": "integer" - }, - "tryFloatingPoint": { - "description": "Try comparing text as floating point numbers", - "type": "boolean" - }, - "hideExpected": { - "description": "Hide the expected value in feedback (default: false), not recommended to use!", - "type": "boolean" - } - } - }, { "type": "object", "additionalProperties": { @@ -3564,32 +4417,88 @@ "minProperties": 1, "properties": { "applyRounding": { - "description": "Apply rounding when comparing as float", - "type": "boolean" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "Apply rounding when comparing as float", + "type": "boolean" + } + ] }, "caseInsensitive": { - "description": "Ignore case when comparing strings", - "type": "boolean" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "Ignore case when comparing strings", + "type": "boolean" + } + ] }, "ignoreWhitespace": { - "description": "Ignore trailing whitespace", - "type": "boolean" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "Ignore trailing whitespace", + "type": "boolean" + } + ] }, "normalizeTrailingNewlines": { - "description": "Normalize trailing newlines", - "type": "boolean" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "Normalize trailing newlines", + "type": "boolean" + } + ] }, "roundTo": { - "description": "The number of decimals to round at, when applying the rounding on floats", - "type": "integer" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "The number of decimals to round at, when applying the rounding on floats", + "type": "integer" + } + ] }, "tryFloatingPoint": { - "description": "Try comparing text as floating point numbers", - "type": "boolean" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "Try comparing text as floating point numbers", + "type": "boolean" + } + ] }, "hideExpected": { - "description": "Hide the expected value in feedback (default: false), not recommended to use!", - "type": "boolean" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "Hide the expected value in feedback (default: false), not recommended to use!", + "type": "boolean" + } + ] } } }, @@ -3709,46 +4618,84 @@ ] }, "textualType": { - "oneOf": [ + "anyOf": [ { - "description": "Simple textual value, converted to string.", - "type": [ - "string", - "number", - "integer", - "boolean" + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } ] }, { - "type": "object", - "additionalProperties": { - "description": "Simple textual value, converted to string.", - "type": [ - "string", - "number", - "integer", - "boolean" - ] - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" + "oneOf": [ + { + "description": "Simple textual value, converted to string.", + "type": [ + "string", + "number", + "integer", + "boolean" + ] + }, + { + "type": "object", + "additionalProperties": { + "description": "Simple textual value, converted to string.", + "type": [ + "string", + "number", + "integer", + "boolean" ] }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } + } + ] } ] }, diff --git a/tested/dsl/schema-strict-nat-translation.json b/tested/dsl/schema-strict-nat-translation.json index 65083de8..50943261 100644 --- a/tested/dsl/schema-strict-nat-translation.json +++ b/tested/dsl/schema-strict-nat-translation.json @@ -129,7 +129,14 @@ }, "translations": { "type": "object", - "description": "Define translations in the global scope." + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } } } }, @@ -246,8 +253,69 @@ ] }, "hidden": { - "type": "boolean", - "description": "Defines if the unit/tab is hidden for the student or not" + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } + ] + }, + { + "type": "boolean", + "description": "Defines if the unit/tab is hidden for the student or not" + } + ] }, "tab": { "oneOf": [ @@ -287,7 +355,14 @@ }, "translations": { "type": "object", - "description": "Define translations in the global scope." + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } } }, "oneOf": [ @@ -356,8 +431,69 @@ ] }, "hidden": { - "type": "boolean", - "description": "Defines if the unit/tab is hidden for the student or not" + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } + ] + }, + { + "type": "boolean", + "description": "Defines if the unit/tab is hidden for the student or not" + } + ] }, "unit": { "oneOf": [ @@ -397,7 +533,14 @@ }, "translations": { "type": "object", - "description": "Define translations in the global scope." + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } } }, "oneOf": [ @@ -534,7 +677,7 @@ "type": "array", "minItems": 1, "items": { - "$ref": "#/definitions/script" + "$ref": "#/definitions/testcase" } }, { @@ -555,7 +698,7 @@ "type": "array", "minItems": 1, "items": { - "$ref": "#/definitions/script" + "$ref": "#/definitions/testcase" } } } @@ -639,7 +782,14 @@ }, "translations": { "type": "object", - "description": "Define translations in the global scope." + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } } } }, @@ -719,7 +869,14 @@ }, "translations": { "type": "object", - "description": "Define translations in the global scope." + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } } } }, @@ -732,41 +889,102 @@ "$ref": "#/subDefinitions/message" }, "stdin": { - "oneOf": [ + "anyOf": [ { - "description": "Stdin for this context", - "type": [ - "string", - "number", - "integer", - "boolean" + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } ] }, { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "oneOf": [ + { + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" + ] }, - "value": { + { "type": "object", - "additionalProperties": { - "description": "Stdin for this context", - "type": [ - "string", - "number", - "integer", - "boolean" - ] + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + } } } - } + ] } ] }, @@ -776,40 +994,101 @@ "description": "Array of program call arguments", "type": "array", "items": { - "oneOf": [ - { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - }, + "anyOf": [ { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { + "oneOf": [ + { "type": "object", - "additionalProperties": { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - } - } - } - } + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } + ] + }, + { + "oneOf": [ + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + } + } + } + ] + } ] } }, @@ -831,11 +1110,19 @@ "description": "Array of program call arguments", "type": "array", "items": { - "type": [ - "string", - "number", - "integer", - "boolean" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } ] } } @@ -908,151 +1195,75 @@ "$ref": "#/subDefinitions/fileOutputChannel" }, "exit_code": { - "type": "integer", - "description": "Expected exit code for the run" - } - } - }, - "script": { - "type": "object", - "description": "An individual test (script) for a statement or expression", - "properties": { - "description": { - "$ref": "#/subDefinitions/message" - }, - "stdin": { - "oneOf": [ - { - "description": "Stdin for this context", - "type": [ - "string", - "number", - "integer", - "boolean" - ] - }, + "anyOf": [ { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { + "oneOf": [ + { "type": "object", - "additionalProperties": { - "description": "Stdin for this context", - "type": [ - "string", - "number", - "integer", - "boolean" - ] + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } } - } - } - } - ] - }, - "arguments": { - "oneOf": [ - { - "description": "Array of program call arguments", - "type": "array", - "items": { - "oneOf": [ - { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { "type": "object", - "additionalProperties": { - "type": [ - "string", - "number", - "integer", - "boolean" - ] + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } } } } } - ] - } + } + ] }, { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "description": "Array of program call arguments", - "type": "array", - "items": { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - } - } - } - } + "type": "integer", + "description": "Expected exit code for the run" } ] }, - "statement": { - "description": "The statement to evaluate.", - "$ref": "#/subDefinitions/expressionOrStatement" - }, - "expression": { - "description": "The expression to evaluate.", - "$ref": "#/subDefinitions/expressionOrStatement" - }, - "exception": { - "description": "Expected exception message", - "$ref": "#/subDefinitions/exceptionChannel" - }, - "files": { + "template": { "oneOf": [ { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } + "type": "string", + "description": "Name of the template to insert." }, { "type": "object", @@ -1069,109 +1280,116 @@ "value": { "type": "object", "additionalProperties": { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } + "type": "string", + "description": "Name of the template to insert." } } } } ] }, - "return": { - "description": "Expected return value", - "$ref": "#/subDefinitions/returnOutputChannel" - }, - "stderr": { - "description": "Expected output at stderr", - "$ref": "#/subDefinitions/textOutputChannel" - }, - "stdout": { - "description": "Expected output at stdout", - "$ref": "#/subDefinitions/textOutputChannel" - }, - "file": { - "description": "Expected files generated by the submission.", - "$ref": "#/subDefinitions/fileOutputChannel" - }, - "exit_code": { - "type": "integer", - "description": "Expected exit code for the run" - } - } - } - }, - "subDefinitions": { - "expressionOrStatement": { - "oneOf": [ - { - "type": "string", - "format": "tested-dsl-expression", - "description": "A statement of expression in Python-like syntax as YAML string." + "parameters": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + } + } + ] + } }, - { + "repeat": { "type": "object", + "description": "A certain loop that will generate test cases with the given parameters and template.", "required": [ - "__tag__", - "value" + "template", + "parameters" ], "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "string", - "format": "tested-dsl-expression", - "description": "A statement of expression in Python-like syntax as YAML string." - } - } - } - }, - { - "anyOf": [ - { + "template": { "oneOf": [ + { + "type": "string", + "description": "Name of the template to insert." + }, { "type": "object", - "description": "Programming-language-specific statement or expression.", - "minProperties": 1, - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, - "items": { - "oneOf": [ - { + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { "type": "string", - "description": "A language-specific literal, which will be used verbatim." - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { + "description": "Name of the template to insert." + } + } + } + } + ] + }, + "parameters": { + "oneOf": [ + { + "type": "array", + "items": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { "type": "string", - "description": "A language-specific literal, which will be used verbatim." + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } } } } - } - ] + ] + } } }, { @@ -1189,22 +1407,34 @@ "value": { "type": "object", "additionalProperties": { - "type": "object", - "description": "Programming-language-specific statement or expression.", - "minProperties": 1, - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, + "type": "array", "items": { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } } } } } } ] - }, + } + } + } + } + }, + "testcase_without_templates": { + "type": "object", + "description": "An individual test for a statement or expression", + "additionalProperties": false, + "properties": { + "description": { + "$ref": "#/subDefinitions/message" + }, + "stdin": { + "anyOf": [ { "oneOf": [ { @@ -1217,44 +1447,11 @@ "__tag__": { "type": "string", "description": "The tag used in the yaml", - "const": "!programming_language" + "const": "!parameter" }, "value": { - "description": "Programming-language-specific statement or expression.", - "minProperties": 1, - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, - "items": { - "oneOf": [ - { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." - } - } - } - } - ] - }, - "type": "object" + "description": "The key of the parameter.", + "type": "string" } } }, @@ -1282,19 +1479,11 @@ "__tag__": { "type": "string", "description": "The tag used in the yaml", - "const": "!programming_language" + "const": "!parameter" }, "value": { - "description": "Programming-language-specific statement or expression.", - "minProperties": 1, - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, - "items": { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." - }, - "type": "object" + "description": "The key of the parameter.", + "type": "string" } } } @@ -1302,52 +1491,17 @@ } } ] - } - ] - } - ] - }, - "yamlValueOrPythonExpression": { - "oneOf": [ - { - "$ref": "#/subDefinitions/yamlValue" - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!expression" }, - "value": { - "type": "string", - "format": "tested-dsl-expression", - "description": "An expression in Python-syntax." - } - } - } - ] - }, - "file": { - "oneOf": [ - { - "type": "object", - "description": "A file used in the test suite.", - "required": [ - "name", - "url" - ], - "properties": { - "name": { + { "oneOf": [ { - "type": "string", - "description": "The filename, including the file extension." + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" + ] }, { "type": "object", @@ -1364,21 +1518,25 @@ "value": { "type": "object", "additionalProperties": { - "type": "string", - "description": "The filename, including the file extension." + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" + ] } } } } ] - }, - "url": { - "oneOf": [ - { - "type": "string", - "format": "uri", - "description": "Relative path to the file in the `description` folder of an exercise." - }, + } + ] + }, + "arguments": { + "anyOf": [ + { + "oneOf": [ { "type": "object", "required": [ @@ -1389,98 +1547,13 @@ "__tag__": { "type": "string", "description": "The tag used in the yaml", - "const": "!natural_language" + "const": "!parameter" }, "value": { - "type": "object", - "additionalProperties": { - "type": "string", - "format": "uri", - "description": "Relative path to the file in the `description` folder of an exercise." - } + "description": "The key of the parameter.", + "type": "string" } } - } - ] - } - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "object", - "description": "A file used in the test suite.", - "required": [ - "name", - "url" - ], - "properties": { - "name": { - "type": "string", - "description": "The filename, including the file extension." - }, - "url": { - "type": "string", - "format": "uri", - "description": "Relative path to the file in the `description` folder of an exercise." - } - } - } - } - } - } - ] - }, - "exceptionChannel": { - "oneOf": [ - { - "type": "string", - "description": "Message of the expected exception." - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "Message of the expected exception." - } - } - } - }, - { - "type": "object", - "required": [ - "types" - ], - "properties": { - "message": { - "oneOf": [ - { - "description": "Message of the expected exception.", - "type": "string" }, { "type": "object", @@ -1497,47 +1570,128 @@ "value": { "type": "object", "additionalProperties": { - "description": "Message of the expected exception.", - "type": "string" + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } } } } } ] }, - "types": { + { "oneOf": [ { - "minProperties": 1, - "description": "Language mapping of expected exception types.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, + "description": "Array of program call arguments", + "type": "array", "items": { - "oneOf": [ + "anyOf": [ { - "type": "string" + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } + ] }, { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "oneOf": [ + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] }, - "value": { + { "type": "object", - "additionalProperties": { - "type": "string" + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + } } } - } + ] } ] } @@ -1557,14 +1711,23 @@ "value": { "type": "object", "additionalProperties": { - "minProperties": 1, - "description": "Language mapping of expected exception types.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, + "description": "Array of program call arguments", + "type": "array", "items": { - "type": "string" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + ] } } } @@ -1572,76 +1735,30 @@ } ] } - } + ] }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "statement": { + "description": "The statement to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "expression": { + "description": "The expression to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "exception": { + "description": "Expected exception message", + "$ref": "#/subDefinitions/exceptionChannel" + }, + "files": { + "oneOf": [ + { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } }, - "value": { - "type": "object", - "additionalProperties": { - "type": "object", - "required": [ - "types" - ], - "properties": { - "message": { - "description": "Message of the expected exception.", - "type": "string" - }, - "types": { - "minProperties": 1, - "description": "Language mapping of expected exception types.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, - "items": { - "type": "string" - } - } - } - } - } - } - } - ] - }, - "textOutputChannel": { - "anyOf": [ - { - "$ref": "#/subDefinitions/textualType" - }, - { - "oneOf": [ - { - "type": "object", - "description": "Built-in oracle for text values.", - "required": [ - "data" - ], - "properties": { - "data": { - "$ref": "#/subDefinitions/textualType" - }, - "oracle": { - "const": "builtin" - }, - "config": { - "$ref": "#/subDefinitions/textConfigurationOptions" - } - } - }, - { + { "type": "object", "required": [ "__tag__", @@ -1656,21 +1773,10 @@ "value": { "type": "object", "additionalProperties": { - "type": "object", - "description": "Built-in oracle for text values.", - "required": [ - "data" - ], - "properties": { - "data": { - "$ref": "#/subDefinitions/textualType" - }, - "oracle": { - "const": "builtin" - }, - "config": { - "$ref": "#/subDefinitions/textConfigurationOptions" - } + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" } } } @@ -1678,503 +1784,217 @@ } ] }, - { - "oneOf": [ + "return": { + "description": "Expected return value", + "$ref": "#/subDefinitions/returnOutputChannel" + }, + "stderr": { + "description": "Expected output at stderr", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "stdout": { + "description": "Expected output at stdout", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "file": { + "description": "Expected files generated by the submission.", + "$ref": "#/subDefinitions/fileOutputChannel" + }, + "exit_code": { + "anyOf": [ { - "type": "object", - "description": "Custom oracle for text values.", - "required": [ - "oracle", - "file", - "data" - ], - "properties": { - "data": { - "$ref": "#/subDefinitions/textualType" - }, - "oracle": { - "const": "custom_check" - }, - "file": { - "oneOf": [ - { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { "type": "string", - "description": "The path to the file containing the custom check function." + "description": "The tag used in the yaml", + "const": "!parameter" }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "The path to the file containing the custom check function." - } - } - } + "value": { + "description": "The key of the parameter.", + "type": "string" } - ] + } }, - "name": { - "oneOf": [ - { + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { "type": "string", - "description": "The name of the custom check function.", - "default": "evaluate" + "description": "The tag used in the yaml", + "const": "!natural_language" }, - { + "value": { "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { "type": "string", - "description": "The name of the custom check function.", - "default": "evaluate" - } - } - } - } - ] - }, - "arguments": { - "oneOf": [ - { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "oneOf": [ - { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "description": "The tag used in the yaml", + "const": "!parameter" }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } - } - } - } - ] - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } + "value": { + "description": "The key of the parameter.", + "type": "string" } } } } - ] - }, - "languages": { - "oneOf": [ - { - "type": "array", - "description": "Which programming languages are supported by this oracle.", - "items": { - "$ref": "#/subDefinitions/programmingLanguage" - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "array", - "description": "Which programming languages are supported by this oracle.", - "items": { - "$ref": "#/subDefinitions/programmingLanguage" - } - } - } - } - } - ] + } } - } + ] }, { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "object", - "description": "Custom oracle for text values.", - "required": [ - "oracle", - "file", - "data" - ], - "properties": { - "data": { - "$ref": "#/subDefinitions/textualType" - }, - "oracle": { - "const": "custom_check" - }, - "file": { - "type": "string", - "description": "The path to the file containing the custom check function." - }, - "name": { - "type": "string", - "description": "The name of the custom check function.", - "default": "evaluate" - }, - "arguments": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } - }, - "languages": { - "type": "array", - "description": "Which programming languages are supported by this oracle.", - "items": { - "$ref": "#/subDefinitions/programmingLanguage" - } - } - } - } - } - } + "type": "integer", + "description": "Expected exit code for the run" } ] } - ] - }, - "fileOutputChannel": { - "anyOf": [ + } + } + }, + "subDefinitions": { + "expressionOrStatement": { + "oneOf": [ { - "oneOf": [ - { + "type": "string", + "format": "tested-dsl-expression", + "description": "A statement of expression in Python-like syntax as YAML string." + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { "type": "object", - "description": "Built-in oracle for files.", - "required": [ - "content", - "location" - ], - "properties": { - "content": { - "oneOf": [ - { - "type": "string", - "description": "Path to the file containing the expected contents, relative to the evaluation directory." - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { + "additionalProperties": { + "type": "string", + "format": "tested-dsl-expression", + "description": "A statement of expression in Python-like syntax as YAML string." + } + } + } + }, + { + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "description": "Programming-language-specific statement or expression.", + "minProperties": 1, + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "oneOf": [ + { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { "type": "string", - "description": "Path to the file containing the expected contents, relative to the evaluation directory." + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." + } } } } - } - ] + ] + } }, - "location": { - "oneOf": [ - { + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { "type": "string", - "description": "Path to where the file generated by the submission should go." + "description": "The tag used in the yaml", + "const": "!natural_language" }, - { + "value": { "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "additionalProperties": { + "type": "object", + "description": "Programming-language-specific statement or expression.", + "minProperties": 1, + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" }, - "value": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "Path to where the file generated by the submission should go." - } + "items": { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." } } } - ] - }, - "oracle": { - "const": "builtin" - }, - "config": { - "$ref": "#/subDefinitions/fileConfigurationOptions" + } } - } + ] }, { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { + "oneOf": [ + { "type": "object", - "additionalProperties": { - "type": "object", - "description": "Built-in oracle for files.", - "required": [ - "content", - "location" - ], - "properties": { - "content": { - "type": "string", - "description": "Path to the file containing the expected contents, relative to the evaluation directory." - }, - "location": { - "type": "string", - "description": "Path to where the file generated by the submission should go." - }, - "oracle": { - "const": "builtin" - }, - "config": { - "$ref": "#/subDefinitions/fileConfigurationOptions" - } - } - } - } - } - } - ] - }, - { - "oneOf": [ - { - "type": "object", - "description": "Custom oracle for file values.", - "required": [ - "oracle", - "content", - "location", - "file" - ], - "properties": { - "oracle": { - "const": "custom_check" - }, - "content": { - "oneOf": [ - { - "type": "string", - "description": "Path to the file containing the expected contents, relative to the evaluation directory." - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "Path to the file containing the expected contents, relative to the evaluation directory." - } - } - } - } - ] - }, - "location": { - "oneOf": [ - { - "type": "string", - "description": "Path to where the file generated by the submission should go." - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "Path to where the file generated by the submission should go." - } - } - } - } - ] - }, - "file": { - "oneOf": [ - { - "type": "string", - "description": "The path to the file containing the custom check function." - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "The path to the file containing the custom check function." - } - } - } - } - ] - }, - "name": { - "oneOf": [ - { + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { "type": "string", - "description": "The name of the custom check function.", - "default": "evaluate" + "description": "The tag used in the yaml", + "const": "!programming_language" }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "The name of the custom check function.", - "default": "evaluate" - } - } - } - } - ] - }, - "arguments": { - "oneOf": [ - { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "value": { + "description": "Programming-language-specific statement or expression.", + "minProperties": 1, + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, "items": { "oneOf": [ { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "type": "string", + "description": "A language-specific literal, which will be used verbatim." }, { "type": "object", @@ -2191,148 +2011,71 @@ "value": { "type": "object", "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "type": "string", + "description": "A language-specific literal, which will be used verbatim." } } } } ] - } + }, + "type": "object" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" }, - { + "value": { "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!programming_language" + }, + "value": { + "description": "Programming-language-specific statement or expression.", + "minProperties": 1, + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, "items": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } + "type": "string", + "description": "A language-specific literal, which will be used verbatim." + }, + "type": "object" } } } } - ] - }, - "languages": { - "oneOf": [ - { - "type": "array", - "description": "Which programming languages are supported by this oracle.", - "items": { - "$ref": "#/subDefinitions/programmingLanguage" - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "array", - "description": "Which programming languages are supported by this oracle.", - "items": { - "$ref": "#/subDefinitions/programmingLanguage" - } - } - } - } - } - ] - } - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "object", - "description": "Custom oracle for file values.", - "required": [ - "oracle", - "content", - "location", - "file" - ], - "properties": { - "oracle": { - "const": "custom_check" - }, - "content": { - "type": "string", - "description": "Path to the file containing the expected contents, relative to the evaluation directory." - }, - "location": { - "type": "string", - "description": "Path to where the file generated by the submission should go." - }, - "file": { - "type": "string", - "description": "The path to the file containing the custom check function." - }, - "name": { - "type": "string", - "description": "The name of the custom check function.", - "default": "evaluate" - }, - "arguments": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } - }, - "languages": { - "type": "array", - "description": "Which programming languages are supported by this oracle.", - "items": { - "$ref": "#/subDefinitions/programmingLanguage" - } - } - } } } - } + ] } ] } ] }, - "returnOutputChannel": { + "yamlValueOrPythonExpression": { "oneOf": [ { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "$ref": "#/subDefinitions/yamlValue" }, { "type": "object", @@ -2344,13 +2087,11 @@ "__tag__": { "type": "string", "description": "The tag used in the yaml", - "const": "!natural_language" + "const": "!parameter" }, "value": { - "type": "object", - "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } + "type": "string", + "description": "The key of the parameter." } } }, @@ -2364,46 +2105,86 @@ "__tag__": { "type": "string", "description": "The tag used in the yaml", - "const": "!oracle" + "const": "!expression" }, "value": { - "additionalProperties": false, - "required": [ - "value" - ], - "properties": { - "oracle": { - "const": "builtin" + "type": "string", + "format": "tested-dsl-expression", + "description": "An expression in Python-syntax." + } + } + } + ] + }, + "file": { + "oneOf": [ + { + "type": "object", + "description": "A file used in the test suite.", + "required": [ + "name", + "url" + ], + "properties": { + "name": { + "oneOf": [ + { + "type": "string", + "description": "The filename, including the file extension." }, - "value": { - "oneOf": [ - { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" }, - { + "value": { "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } - } + "additionalProperties": { + "type": "string", + "description": "The filename, including the file extension." } } - ] + } } - }, - "type": "object" + ] + }, + "url": { + "oneOf": [ + { + "type": "string", + "format": "uri", + "description": "Relative path to the file in the `description` folder of an exercise." + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "format": "uri", + "description": "Relative path to the file in the `description` folder of an exercise." + } + } + } + } + ] } } }, @@ -2423,35 +2204,33 @@ "type": "object", "additionalProperties": { "type": "object", + "description": "A file used in the test suite.", "required": [ - "__tag__", - "value" + "name", + "url" ], "properties": { - "__tag__": { + "name": { "type": "string", - "description": "The tag used in the yaml", - "const": "!oracle" + "description": "The filename, including the file extension." }, - "value": { - "additionalProperties": false, - "required": [ - "value" - ], - "properties": { - "oracle": { - "const": "builtin" - }, - "value": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } - }, - "type": "object" + "url": { + "type": "string", + "format": "uri", + "description": "Relative path to the file in the `description` folder of an exercise." } } } } } + } + ] + }, + "exceptionChannel": { + "oneOf": [ + { + "type": "string", + "description": "Message of the expected exception." }, { "type": "object", @@ -2463,45 +2242,241 @@ "__tag__": { "type": "string", "description": "The tag used in the yaml", - "const": "!oracle" + "const": "!natural_language" }, "value": { - "additionalProperties": false, - "required": [ - "value", - "oracle", - "file" - ], - "properties": { - "oracle": { - "const": "custom_check" - }, - "value": { - "oneOf": [ - { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Message of the expected exception." + } + } + } + }, + { + "type": "object", + "required": [ + "types" + ], + "properties": { + "message": { + "oneOf": [ + { + "description": "Message of the expected exception.", + "type": "string" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "description": "Message of the expected exception.", + "type": "string" + } + } + } + } + ] + }, + "types": { + "oneOf": [ + { + "minProperties": 1, + "description": "Language mapping of expected exception types.", + "type": "object", + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string" + } } } } + ] + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "minProperties": 1, + "description": "Language mapping of expected exception types.", + "type": "object", + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "type": "string" + } + } } - ] + } + } + ] + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "types" + ], + "properties": { + "message": { + "description": "Message of the expected exception.", + "type": "string" + }, + "types": { + "minProperties": 1, + "description": "Language mapping of expected exception types.", + "type": "object", + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "type": "string" + } + } + } + } + } + } + } + ] + }, + "textOutputChannel": { + "anyOf": [ + { + "$ref": "#/subDefinitions/textualType" + }, + { + "oneOf": [ + { + "type": "object", + "description": "Built-in oracle for text values.", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/subDefinitions/textualType" + }, + "oracle": { + "const": "builtin" + }, + "config": { + "$ref": "#/subDefinitions/textConfigurationOptions" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Built-in oracle for text values.", + "required": [ + "data" + ], + "properties": { + "data": { + "$ref": "#/subDefinitions/textualType" + }, + "oracle": { + "const": "builtin" + }, + "config": { + "$ref": "#/subDefinitions/textConfigurationOptions" + } + } + } + } + } + } + ] + }, + { + "oneOf": [ + { + "type": "object", + "description": "Custom oracle for text values.", + "required": [ + "oracle", + "file", + "data" + ], + "properties": { + "data": { + "$ref": "#/subDefinitions/textualType" + }, + "oracle": { + "const": "custom_check" }, "file": { "oneOf": [ @@ -2566,8 +2541,8 @@ "arguments": { "oneOf": [ { - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", "items": { "oneOf": [ { @@ -2611,8 +2586,8 @@ "value": { "type": "object", "additionalProperties": { - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", "items": { "$ref": "#/subDefinitions/yamlValueOrPythonExpression" } @@ -2657,51 +2632,37 @@ } ] } - }, - "type": "object" - } - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + } }, - "value": { + { "type": "object", - "additionalProperties": { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!oracle" - }, - "value": { - "additionalProperties": false, + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Custom oracle for text values.", "required": [ - "value", "oracle", - "file" + "file", + "data" ], "properties": { + "data": { + "$ref": "#/subDefinitions/textualType" + }, "oracle": { "const": "custom_check" }, - "value": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - }, "file": { "type": "string", "description": "The path to the file containing the custom check function." @@ -2712,8 +2673,8 @@ "default": "evaluate" }, "arguments": { - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", "items": { "$ref": "#/subDefinitions/yamlValueOrPythonExpression" } @@ -2725,151 +2686,32 @@ "$ref": "#/subDefinitions/programmingLanguage" } } - }, - "type": "object" + } } } } } - } - }, + ] + } + ] + }, + "fileOutputChannel": { + "anyOf": [ { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!oracle" - }, - "value": { - "additionalProperties": false, + "oneOf": [ + { + "type": "object", + "description": "Built-in oracle for files.", "required": [ - "oracle", - "functions" + "content", + "location" ], "properties": { - "oracle": { - "const": "specific_check" - }, - "functions": { + "content": { "oneOf": [ { - "minProperties": 1, - "description": "Language mapping of oracle functions.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, - "items": { - "oneOf": [ - { - "type": "object", - "required": [ - "file" - ], - "properties": { - "file": { - "oneOf": [ - { - "type": "string", - "description": "The path to the file containing the custom check function." - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "The path to the file containing the custom check function." - } - } - } - } - ] - }, - "name": { - "oneOf": [ - { - "type": "string", - "description": "The name of the custom check function.", - "default": "evaluate" - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "The name of the custom check function.", - "default": "evaluate" - } - } - } - } - ] - } - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "object", - "required": [ - "file" - ], - "properties": { - "file": { - "type": "string", - "description": "The path to the file containing the custom check function." - }, - "name": { - "type": "string", - "description": "The name of the custom check function.", - "default": "evaluate" - } - } - } - } - } - } - ] - } + "type": "string", + "description": "Path to the file containing the expected contents, relative to the evaluation directory." }, { "type": "object", @@ -2886,78 +2728,236 @@ "value": { "type": "object", "additionalProperties": { - "minProperties": 1, - "description": "Language mapping of oracle functions.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, - "items": { - "type": "object", - "required": [ - "file" - ], - "properties": { - "file": { - "type": "string", - "description": "The path to the file containing the custom check function." - }, - "name": { - "type": "string", - "description": "The name of the custom check function.", - "default": "evaluate" - } - } - } + "type": "string", + "description": "Path to the file containing the expected contents, relative to the evaluation directory." } } } } ] }, - "arguments": { + "location": { "oneOf": [ { - "minProperties": 1, - "description": "Language mapping of oracle arguments.", + "type": "string", + "description": "Path to where the file generated by the submission should go." + }, + { "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, - "items": { - "oneOf": [ - { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "oneOf": [ - { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." - } - } - } - } - ] - } + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Path to where the file generated by the submission should go." + } + } + } + } + ] + }, + "oracle": { + "const": "builtin" + }, + "config": { + "$ref": "#/subDefinitions/fileConfigurationOptions" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Built-in oracle for files.", + "required": [ + "content", + "location" + ], + "properties": { + "content": { + "type": "string", + "description": "Path to the file containing the expected contents, relative to the evaluation directory." + }, + "location": { + "type": "string", + "description": "Path to where the file generated by the submission should go." + }, + "oracle": { + "const": "builtin" + }, + "config": { + "$ref": "#/subDefinitions/fileConfigurationOptions" + } + } + } + } + } + } + ] + }, + { + "oneOf": [ + { + "type": "object", + "description": "Custom oracle for file values.", + "required": [ + "oracle", + "content", + "location", + "file" + ], + "properties": { + "oracle": { + "const": "custom_check" + }, + "content": { + "oneOf": [ + { + "type": "string", + "description": "Path to the file containing the expected contents, relative to the evaluation directory." + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Path to the file containing the expected contents, relative to the evaluation directory." + } + } + } + } + ] + }, + "location": { + "oneOf": [ + { + "type": "string", + "description": "Path to where the file generated by the submission should go." + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Path to where the file generated by the submission should go." + } + } + } + } + ] + }, + "file": { + "oneOf": [ + { + "type": "string", + "description": "The path to the file containing the custom check function." + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "The path to the file containing the custom check function." + } + } + } + } + ] + }, + "name": { + "oneOf": [ + { + "type": "string", + "description": "The name of the custom check function.", + "default": "evaluate" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "The name of the custom check function.", + "default": "evaluate" + } + } + } + } + ] + }, + "arguments": { + "oneOf": [ + { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" }, { "type": "object", @@ -2974,12 +2974,7 @@ "value": { "type": "object", "additionalProperties": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." - } + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" } } } @@ -3002,19 +2997,10 @@ "value": { "type": "object", "additionalProperties": { - "minProperties": 1, - "description": "Language mapping of oracle arguments.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", "items": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." - } + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" } } } @@ -3022,10 +3008,14 @@ } ] }, - "value": { + "languages": { "oneOf": [ { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "type": "array", + "description": "Which programming languages are supported by this oracle.", + "items": { + "$ref": "#/subDefinitions/programmingLanguage" + } }, { "type": "object", @@ -3042,126 +3032,90 @@ "value": { "type": "object", "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } - } - } - } + "type": "array", + "description": "Which programming languages are supported by this oracle.", + "items": { + "$ref": "#/subDefinitions/programmingLanguage" + } + } + } + } + } ] } - }, - "type": "object" - } - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + } }, - "value": { + { "type": "object", - "additionalProperties": { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!oracle" - }, - "value": { - "additionalProperties": false, + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "Custom oracle for file values.", "required": [ "oracle", - "functions" + "content", + "location", + "file" ], "properties": { "oracle": { - "const": "specific_check" + "const": "custom_check" }, - "functions": { - "minProperties": 1, - "description": "Language mapping of oracle functions.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, - "items": { - "type": "object", - "required": [ - "file" - ], - "properties": { - "file": { - "type": "string", - "description": "The path to the file containing the custom check function." - }, - "name": { - "type": "string", - "description": "The name of the custom check function.", - "default": "evaluate" - } - } - } + "content": { + "type": "string", + "description": "Path to the file containing the expected contents, relative to the evaluation directory." + }, + "location": { + "type": "string", + "description": "Path to where the file generated by the submission should go." + }, + "file": { + "type": "string", + "description": "The path to the file containing the custom check function." + }, + "name": { + "type": "string", + "description": "The name of the custom check function.", + "default": "evaluate" }, "arguments": { - "minProperties": 1, - "description": "Language mapping of oracle arguments.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", "items": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." - } + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" } }, - "value": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "languages": { + "type": "array", + "description": "Which programming languages are supported by this oracle.", + "items": { + "$ref": "#/subDefinitions/programmingLanguage" + } } - }, - "type": "object" + } } } } } - } + ] } ] }, - "programmingLanguage": { + "returnOutputChannel": { "oneOf": [ { - "type": "string", - "description": "One of the programming languages supported by TESTed.", - "enum": [ - "bash", - "c", - "haskell", - "java", - "javascript", - "typescript", - "kotlin", - "python", - "runhaskell", - "csharp", - "cpp" - ] + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" }, { "type": "object", @@ -3178,32 +3132,63 @@ "value": { "type": "object", "additionalProperties": { - "type": "string", - "description": "One of the programming languages supported by TESTed.", - "enum": [ - "bash", - "c", - "haskell", - "java", - "javascript", - "typescript", - "kotlin", - "python", - "runhaskell", - "csharp", - "cpp" - ] + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" } } } - } - ] - }, - "message": { - "oneOf": [ + }, { - "type": "string", - "description": "A simple message to display." + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!oracle" + }, + "value": { + "additionalProperties": false, + "required": [ + "value" + ], + "properties": { + "oracle": { + "const": "builtin" + }, + "value": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + } + } + ] + } + }, + "type": "object" + } + } }, { "type": "object", @@ -3220,8 +3205,33 @@ "value": { "type": "object", "additionalProperties": { - "type": "string", - "description": "A simple message to display." + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!oracle" + }, + "value": { + "additionalProperties": false, + "required": [ + "value" + ], + "properties": { + "oracle": { + "const": "builtin" + }, + "value": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + }, + "type": "object" + } + } } } } @@ -3229,141 +3239,1341 @@ { "type": "object", "required": [ - "description" + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!oracle" + }, + "value": { + "additionalProperties": false, + "required": [ + "value", + "oracle", + "file" + ], + "properties": { + "oracle": { + "const": "custom_check" + }, + "value": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + } + } + ] + }, + "file": { + "oneOf": [ + { + "type": "string", + "description": "The path to the file containing the custom check function." + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "The path to the file containing the custom check function." + } + } + } + } + ] + }, + "name": { + "oneOf": [ + { + "type": "string", + "description": "The name of the custom check function.", + "default": "evaluate" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "The name of the custom check function.", + "default": "evaluate" + } + } + } + } + ] + }, + "arguments": { + "oneOf": [ + { + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + } + } + ] + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + } + } + } + ] + }, + "languages": { + "oneOf": [ + { + "type": "array", + "description": "Which programming languages are supported by this oracle.", + "items": { + "$ref": "#/subDefinitions/programmingLanguage" + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "array", + "description": "Which programming languages are supported by this oracle.", + "items": { + "$ref": "#/subDefinitions/programmingLanguage" + } + } + } + } + } + ] + } + }, + "type": "object" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!oracle" + }, + "value": { + "additionalProperties": false, + "required": [ + "value", + "oracle", + "file" + ], + "properties": { + "oracle": { + "const": "custom_check" + }, + "value": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + "file": { + "type": "string", + "description": "The path to the file containing the custom check function." + }, + "name": { + "type": "string", + "description": "The name of the custom check function.", + "default": "evaluate" + }, + "arguments": { + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + }, + "languages": { + "type": "array", + "description": "Which programming languages are supported by this oracle.", + "items": { + "$ref": "#/subDefinitions/programmingLanguage" + } + } + }, + "type": "object" + } + } + } + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!oracle" + }, + "value": { + "additionalProperties": false, + "required": [ + "oracle", + "functions" + ], + "properties": { + "oracle": { + "const": "specific_check" + }, + "functions": { + "oneOf": [ + { + "minProperties": 1, + "description": "Language mapping of oracle functions.", + "type": "object", + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "oneOf": [ + { + "type": "object", + "required": [ + "file" + ], + "properties": { + "file": { + "oneOf": [ + { + "type": "string", + "description": "The path to the file containing the custom check function." + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "The path to the file containing the custom check function." + } + } + } + } + ] + }, + "name": { + "oneOf": [ + { + "type": "string", + "description": "The name of the custom check function.", + "default": "evaluate" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "The name of the custom check function.", + "default": "evaluate" + } + } + } + } + ] + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "file" + ], + "properties": { + "file": { + "type": "string", + "description": "The path to the file containing the custom check function." + }, + "name": { + "type": "string", + "description": "The name of the custom check function.", + "default": "evaluate" + } + } + } + } + } + } + ] + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "minProperties": 1, + "description": "Language mapping of oracle functions.", + "type": "object", + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "type": "object", + "required": [ + "file" + ], + "properties": { + "file": { + "type": "string", + "description": "The path to the file containing the custom check function." + }, + "name": { + "type": "string", + "description": "The name of the custom check function.", + "default": "evaluate" + } + } + } + } + } + } + } + ] + }, + "arguments": { + "oneOf": [ + { + "minProperties": 1, + "description": "Language mapping of oracle arguments.", + "type": "object", + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "oneOf": [ + { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "oneOf": [ + { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." + } + } + } + } + ] + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." + } + } + } + } + } + ] + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "minProperties": 1, + "description": "Language mapping of oracle arguments.", + "type": "object", + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." + } + } + } + } + } + } + ] + }, + "value": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + } + } + ] + } + }, + "type": "object" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!oracle" + }, + "value": { + "additionalProperties": false, + "required": [ + "oracle", + "functions" + ], + "properties": { + "oracle": { + "const": "specific_check" + }, + "functions": { + "minProperties": 1, + "description": "Language mapping of oracle functions.", + "type": "object", + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "type": "object", + "required": [ + "file" + ], + "properties": { + "file": { + "type": "string", + "description": "The path to the file containing the custom check function." + }, + "name": { + "type": "string", + "description": "The name of the custom check function.", + "default": "evaluate" + } + } + } + }, + "arguments": { + "minProperties": 1, + "description": "Language mapping of oracle arguments.", + "type": "object", + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." + } + } + }, + "value": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + }, + "type": "object" + } + } + } + } + } + } + ] + }, + "programmingLanguage": { + "oneOf": [ + { + "type": "string", + "description": "One of the programming languages supported by TESTed.", + "enum": [ + "bash", + "c", + "haskell", + "java", + "javascript", + "typescript", + "kotlin", + "python", + "runhaskell", + "csharp", + "cpp" + ] + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "One of the programming languages supported by TESTed.", + "enum": [ + "bash", + "c", + "haskell", + "java", + "javascript", + "typescript", + "kotlin", + "python", + "runhaskell", + "csharp", + "cpp" + ] + } + } + } + } + ] + }, + "message": { + "oneOf": [ + { + "type": "string", + "description": "A simple message to display." + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "A simple message to display." + } + } + } + }, + { + "type": "object", + "required": [ + "description" ], "properties": { "description": { "oneOf": [ { - "description": "The message to display.", - "type": "string" + "description": "The message to display.", + "type": "string" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "description": "The message to display.", + "type": "string" + } + } + } + } + ] + }, + "format": { + "oneOf": [ + { + "type": "string", + "default": "text", + "description": "The format of the message, either a programming language, 'text' or 'html'." + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "default": "text", + "description": "The format of the message, either a programming language, 'text' or 'html'." + } + } + } + } + ] + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "description" + ], + "properties": { + "description": { + "description": "The message to display.", + "type": "string" + }, + "format": { + "type": "string", + "default": "text", + "description": "The format of the message, either a programming language, 'text' or 'html'." + } + } + } + } + } + } + ] + }, + "textConfigurationOptions": { + "oneOf": [ + { + "type": "object", + "description": "Configuration properties for textual comparison and to configure if the expected value should be hidden or not", + "minProperties": 1, + "properties": { + "applyRounding": { + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } + ] + }, + { + "description": "Apply rounding when comparing as float", + "type": "boolean" + } + ] + }, + "caseInsensitive": { + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } + ] + }, + { + "description": "Ignore case when comparing strings", + "type": "boolean" + } + ] + }, + "ignoreWhitespace": { + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } + ] }, { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "description": "Ignore trailing whitespace", + "type": "boolean" + } + ] + }, + "normalizeTrailingNewlines": { + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } }, - "value": { + { "type": "object", - "additionalProperties": { - "description": "The message to display.", - "type": "string" + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } } } - } + ] + }, + { + "description": "Normalize trailing newlines", + "type": "boolean" } ] }, - "format": { - "oneOf": [ + "roundTo": { + "anyOf": [ { - "type": "string", - "default": "text", - "description": "The format of the message, either a programming language, 'text' or 'html'." + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } + ] }, { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "description": "The number of decimals to round at, when applying the rounding on floats", + "type": "integer" + } + ] + }, + "tryFloatingPoint": { + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } }, - "value": { + { "type": "object", - "additionalProperties": { - "type": "string", - "default": "text", - "description": "The format of the message, either a programming language, 'text' or 'html'." + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } } } - } + ] + }, + { + "description": "Try comparing text as floating point numbers", + "type": "boolean" } ] - } - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "object", - "required": [ - "description" - ], - "properties": { - "description": { - "description": "The message to display.", - "type": "string" - }, - "format": { - "type": "string", - "default": "text", - "description": "The format of the message, either a programming language, 'text' or 'html'." - } - } - } - } - } - } - ] - }, - "textConfigurationOptions": { - "oneOf": [ - { - "type": "object", - "description": "Configuration properties for textual comparison and to configure if the expected value should be hidden or not", - "minProperties": 1, - "properties": { - "applyRounding": { - "description": "Apply rounding when comparing as float", - "type": "boolean" - }, - "caseInsensitive": { - "description": "Ignore case when comparing strings", - "type": "boolean" - }, - "ignoreWhitespace": { - "description": "Ignore trailing whitespace", - "type": "boolean" - }, - "normalizeTrailingNewlines": { - "description": "Normalize trailing newlines", - "type": "boolean" - }, - "roundTo": { - "description": "The number of decimals to round at, when applying the rounding on floats", - "type": "integer" - }, - "tryFloatingPoint": { - "description": "Try comparing text as floating point numbers", - "type": "boolean" }, "hideExpected": { - "description": "Hide the expected value in feedback (default: false), not recommended to use!", - "type": "boolean" + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } + ] + }, + { + "description": "Hide the expected value in feedback (default: false), not recommended to use!", + "type": "boolean" + } + ] } } }, @@ -3387,32 +4597,88 @@ "minProperties": 1, "properties": { "applyRounding": { - "description": "Apply rounding when comparing as float", - "type": "boolean" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "Apply rounding when comparing as float", + "type": "boolean" + } + ] }, "caseInsensitive": { - "description": "Ignore case when comparing strings", - "type": "boolean" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "Ignore case when comparing strings", + "type": "boolean" + } + ] }, "ignoreWhitespace": { - "description": "Ignore trailing whitespace", - "type": "boolean" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "Ignore trailing whitespace", + "type": "boolean" + } + ] }, "normalizeTrailingNewlines": { - "description": "Normalize trailing newlines", - "type": "boolean" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "Normalize trailing newlines", + "type": "boolean" + } + ] }, "roundTo": { - "description": "The number of decimals to round at, when applying the rounding on floats", - "type": "integer" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "The number of decimals to round at, when applying the rounding on floats", + "type": "integer" + } + ] }, "tryFloatingPoint": { - "description": "Try comparing text as floating point numbers", - "type": "boolean" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "Try comparing text as floating point numbers", + "type": "boolean" + } + ] }, "hideExpected": { - "description": "Hide the expected value in feedback (default: false), not recommended to use!", - "type": "boolean" + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "Hide the expected value in feedback (default: false), not recommended to use!", + "type": "boolean" + } + ] } } } @@ -3505,41 +4771,102 @@ ] }, "textualType": { - "oneOf": [ + "anyOf": [ { - "description": "Simple textual value, converted to string.", - "type": [ - "string", - "number", - "integer", - "boolean" + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } ] }, { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "oneOf": [ + { + "description": "Simple textual value, converted to string.", + "type": [ + "string", + "number", + "integer", + "boolean" + ] }, - "value": { + { "type": "object", - "additionalProperties": { - "description": "Simple textual value, converted to string.", - "type": [ - "string", - "number", - "integer", - "boolean" - ] + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "description": "Simple textual value, converted to string.", + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + } } } - } + ] } ] }, diff --git a/tested/dsl/schema-strict.json b/tested/dsl/schema-strict.json index c486cf5e..7897cbf7 100644 --- a/tested/dsl/schema-strict.json +++ b/tested/dsl/schema-strict.json @@ -221,7 +221,7 @@ "type": "array", "minItems": 1, "items": { - "$ref": "#/definitions/script" + "$ref": "#/definitions/testcase" } }, "context": { @@ -339,75 +339,6 @@ "description": "Expected exit code for the run" } } - }, - "script": { - "type": "object", - "description": "An individual test (script) for a statement or expression", - "properties": { - "description": { - "$ref": "#/subDefinitions/message" - }, - "stdin": { - "description": "Stdin for this context", - "type": [ - "string", - "number", - "integer", - "boolean" - ] - }, - "arguments": { - "description": "Array of program call arguments", - "type": "array", - "items": { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - } - }, - "statement": { - "description": "The statement to evaluate.", - "$ref": "#/subDefinitions/expressionOrStatement" - }, - "expression": { - "description": "The expression to evaluate.", - "$ref": "#/subDefinitions/expressionOrStatement" - }, - "exception": { - "description": "Expected exception message", - "$ref": "#/subDefinitions/exceptionChannel" - }, - "files": { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - }, - "return": { - "description": "Expected return value", - "$ref": "#/subDefinitions/returnOutputChannel" - }, - "stderr": { - "description": "Expected output at stderr", - "$ref": "#/subDefinitions/textOutputChannel" - }, - "stdout": { - "description": "Expected output at stdout", - "$ref": "#/subDefinitions/textOutputChannel" - }, - "file": { - "description": "Expected files generated by the submission.", - "$ref": "#/subDefinitions/fileOutputChannel" - }, - "exit_code": { - "type": "integer", - "description": "Expected exit code for the run" - } - } } }, "subDefinitions" : { diff --git a/tested/transform_json.py b/tested/transform_json.py index ecffea0f..9ecafb0f 100644 --- a/tested/transform_json.py +++ b/tested/transform_json.py @@ -1,10 +1,11 @@ +import copy import json import os import sys from pathlib import Path from typing import Any -SPECIAL_TYPES = ["expression", "programming_language", "oracle"] +SPECIAL_TYPES = ["expression", "programming_language", "oracle", "parameter"] def transform_non_strict(data: Any) -> Any: @@ -97,10 +98,18 @@ def flatten_one_of_stack(data: list) -> list: return new_one_stack +def make_parameter_type_structure(data: dict) -> dict: + return { + "anyOf": [ + {"type": "parameter", "description": "The key of the parameter."}, + data, + ] + } + + def make_tag_structure( - data: Any, data_with_inner_translations: Any = None, tag: str = "!natural_language" + data: dict, data_with_inner_translations: Any = None, tag: str = "!natural_language" ) -> dict: - base = { "type": "object", "required": ["__tag__", "value"], @@ -113,10 +122,10 @@ def make_tag_structure( }, } - if tag in ["!oracle", "!programming_language", "!expression"]: + if tag in ["!oracle", "!programming_language", "!expression", "!parameter"]: base["properties"]["value"] = data base["properties"]["value"]["type"] = "object" - if tag == "!expression": + if tag in ["!expression", "!parameter"]: base["properties"]["value"]["type"] = "string" elif tag == "!natural_language": @@ -131,23 +140,34 @@ def make_tag_structure( def make_translations_map() -> dict: - return {"type": "object", "description": "Define translations in the global scope."} + return {"type": "object", "description": "Define translations."} + + +def make_templates_map() -> dict: + return { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates", + }, + } def transform_json_preprocessor(data: Any, in_sub_def: bool) -> Any: if isinstance(data, dict): - # Standard creation of the special tag structure for translations. new_data = { key: transform_json_preprocessor( value, in_sub_def or key == "subDefinitions" ) for key, value in data.items() } + # Standard creation of the special tag structure for translations and templates. if ( "type" in data and (data["type"] != "object" or in_sub_def) and data["type"] not in ["boolean", "integer"] ): + # Adding support for the other tags. if data["type"] in SPECIAL_TYPES: tag = data.pop("type") new_data.pop("type") @@ -174,6 +194,7 @@ def transform_json_preprocessor(data: Any, in_sub_def: bool) -> Any: for target in targets: if target in data and "properties" in data[target]: data[target]["properties"]["translations"] = make_translations_map() + data[target]["properties"]["templates"] = make_templates_map() # Flatten the oneOf structures if "oneOf" in data: @@ -185,6 +206,21 @@ def transform_json_preprocessor(data: Any, in_sub_def: bool) -> Any: data["yamlValueOrPythonExpression"] = { "oneOf": [ {"$ref": "#/subDefinitions/yamlValue"}, + { + "type": "object", + "required": ["__tag__", "value"], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter", + }, + "value": { + "type": "string", + "description": "The key of the parameter.", + }, + }, + }, { "type": "object", "required": ["__tag__", "value"], @@ -225,6 +261,74 @@ def transform_json_preprocessor(data: Any, in_sub_def: bool) -> Any: return data +def add_templates(data: dict) -> dict: + assert "definitions" in data and isinstance(data["definitions"], dict) + # Addition for adding templates to the json-schema + testcase = data["definitions"].get("testcase", {}) + if testcase: + assert "properties" in testcase + testcase_without_templates = copy.deepcopy(testcase) + testcase_without_templates["properties"]["arguments"] = ( + make_parameter_type_structure( + testcase_without_templates["properties"]["arguments"] + ) + ) + data["definitions"]["testcase_without_templates"] = testcase_without_templates + + testcase["properties"]["template"] = { + "type": "string", + "description": "Name of the template to insert.", + } + testcase["properties"]["parameters"] = { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + } + testcase["properties"]["repeat"] = { + "type": "object", + "description": "A certain loop that will generate test cases with the given parameters and template.", + "required": ["template", "parameters"], + "properties": { + "template": { + "type": "string", + "description": "Name of the template to insert.", + }, + "parameters": { + "type": "array", + "items": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + }, + }, + }, + } + + data["definitions"]["testcase"] = testcase + return data + + +def add_parameter_type(data: Any) -> Any: + if isinstance(data, dict): + if "type" in data: + type_value = data["type"] + if ( + isinstance(type_value, list) + and any(t in ["boolean", "integer"] for t in type_value) + ) or type_value in ["boolean", "integer"]: + # Adding support for "!parameter" tag. + return make_parameter_type_structure(data) + return {k: add_parameter_type(v) for k, v in data.items()} + + if isinstance(data, list): + return [add_parameter_type(value) for value in data] + return data + + def transform_json(json_file: Path, multilingual: bool, ide: bool): """ This function transforms the JSON schema used in the DSL translator into @@ -247,7 +351,9 @@ def transform_json(json_file: Path, multilingual: bool, ide: bool): result = transform_non_strict(json_stream) file_name = "schema.json" else: - result = transform_json_preprocessor(json_stream, False) + stream_with_templates = add_templates(json_stream) + stream_with_templates_and_param = add_parameter_type(stream_with_templates) + result = transform_json_preprocessor(stream_with_templates_and_param, False) if ide: result = transform_ide(result) file_name = "multilingual-schema.json" diff --git a/tests/test_json_schema_transformer.py b/tests/test_json_schema_transformer.py index 4e98740f..3898ac45 100644 --- a/tests/test_json_schema_transformer.py +++ b/tests/test_json_schema_transformer.py @@ -173,42 +173,16 @@ def test_transform_executed_correct(mocker: MockerFixture): mocker.mock_open(read_data=content).return_value for content in [ """ -{ - "files": { - "oneOf": [ - { +{ + "definitions": { + "files": { "description": "A list of files used in the test suite.", "type": "array", "items": { "$ref": "#/subDefinitions/file" } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - } - } - } } - ] - } + } }""" ] ] @@ -220,7 +194,7 @@ def test_transform_executed_correct(mocker: MockerFixture): transform_json(Path("schema.json"), True, False) - assert s.call_count == 25 + assert s.call_count == 7 # Check if the file was opened for writing mock_opener.assert_any_call( @@ -491,6 +465,21 @@ def test_json_schema_expression(): "yamlValueOrPythonExpression": { "oneOf": [ {"$ref": "#/subDefinitions/yamlValue"}, + { + "type": "object", + "required": ["__tag__", "value"], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter", + }, + "value": { + "type": "string", + "description": "The key of the parameter.", + }, + }, + }, { "type": "object", "required": ["__tag__", "value"], diff --git a/tests/test_preprocess_dsl.py b/tests/test_preprocess_dsl.py index b67bc87e..ad3dd72a 100644 --- a/tests/test_preprocess_dsl.py +++ b/tests/test_preprocess_dsl.py @@ -24,7 +24,7 @@ def validate_natural_translate(yaml_str: str, translated_yaml_str: str): enviroment = create_enviroment() yaml_object = parse_yaml(yaml_str) - # validate_pre_dsl(yaml_object) + validate_pre_dsl(yaml_object) translated_dsl = translate_yaml(yaml_object, {}, {}, {}, "en", enviroment) translated_yaml = convert_to_yaml(translated_dsl) print(translated_yaml) From 05e2e7ab77d899e9271ebe11ceb881ded9e405c4 Mon Sep 17 00:00:00 2001 From: breblanc Date: Fri, 16 May 2025 21:03:16 +0200 Subject: [PATCH 08/24] made a few more tests --- tests/test_json_schema_transformer.py | 145 ++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/tests/test_json_schema_transformer.py b/tests/test_json_schema_transformer.py index 3898ac45..7044b80e 100644 --- a/tests/test_json_schema_transformer.py +++ b/tests/test_json_schema_transformer.py @@ -7,6 +7,8 @@ transform_ide, transform_json, transform_json_preprocessor, + add_templates, + add_parameter_type, ) @@ -504,6 +506,149 @@ def test_json_schema_expression(): assert result == json_schema_expected +def test_add_templates(): + json_schema = { + "definitions": { + "testcase": { + "properties": { + "statement": { + "description": "The statement to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement", + }, + "expression": { + "description": "The expression to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement", + }, + "arguments": { + "description": "Array of program call arguments", + "type": "array", + "items": {"type": ["string", "number", "integer", "boolean"]}, + }, + } + } + } + } + + json_schema_expected = { + "definitions": { + "testcase": { + "properties": { + "statement": { + "description": "The statement to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement", + }, + "expression": { + "description": "The expression to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement", + }, + "arguments": { + "description": "Array of program call arguments", + "type": "array", + "items": {"type": ["string", "number", "integer", "boolean"]}, + }, + "template": { + "type": "string", + "description": "Name of the template to insert.", + }, + "parameters": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + }, + "repeat": { + "type": "object", + "description": "A certain loop that will generate test cases with the given parameters and template.", + "required": ["template", "parameters"], + "properties": { + "template": { + "type": "string", + "description": "Name of the template to insert.", + }, + "parameters": { + "type": "array", + "items": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + }, + }, + }, + }, + } + }, + "testcase_without_templates": { + "properties": { + "statement": { + "description": "The statement to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement", + }, + "expression": { + "description": "The expression to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement", + }, + "arguments": { + "anyOf": [ + { + "type": "parameter", + "description": "The key of the parameter.", + }, + { + "description": "Array of program call arguments", + "type": "array", + "items": { + "type": ["string", "number", "integer", "boolean"] + }, + }, + ] + }, + } + }, + } + } + + result = add_templates(json_schema) + assert result == json_schema_expected + + +def test_add_parameters_type(): + json_schema = { + "stdin": { + "description": "Stdin for this context", + "type": ["string", "number", "integer", "boolean"], + }, + "exit_code": { + "type": "integer", + "description": "Expected exit code for the run", + }, + } + + json_schema_expected = { + "stdin": { + "anyOf": [ + {"type": "parameter", "description": "The key of the parameter."}, + { + "description": "Stdin for this context", + "type": ["string", "number", "integer", "boolean"], + }, + ] + }, + "exit_code": { + "anyOf": [ + {"type": "parameter", "description": "The key of the parameter."}, + {"type": "integer", "description": "Expected exit code for the run"}, + ] + }, + } + + result = add_parameter_type(json_schema) + print(result) + assert result == json_schema_expected + + def test_json_schema_yaml_value(): json_schema = { "yamlValue": { From ad440e47c4a9875dc2f86ad751dbbbeb2024f413 Mon Sep 17 00:00:00 2001 From: breblanc Date: Sat, 17 May 2025 12:19:07 +0200 Subject: [PATCH 09/24] added comments --- tested/transform_json.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tested/transform_json.py b/tested/transform_json.py index b0f24c83..2b51bda5 100644 --- a/tested/transform_json.py +++ b/tested/transform_json.py @@ -169,7 +169,8 @@ def make_templates_map() -> dict: def transform_json_for_preprocessor_validation(data: Any, in_sub_def: bool) -> Any: """ - This function is responsible for transforming the JSON-schema such that translations are supported. + This function will start with the result of add_parameter_type. + It is responsible for transforming the JSON-schema such that translations and templates are supported. It also uses a special structure for tags in the YAML that is used in the preprocessing step. :param data: The data to transform. @@ -287,6 +288,13 @@ def transform_json_for_preprocessor_validation(data: Any, in_sub_def: bool) -> A def add_templates(data: dict) -> dict: + """ + This function will start by a new definition for a single testcase and add templates to the existing definition. + The new definition for a testcase will be used to specify a testcase inside a template. + + :param data: The data to transform. + :return: The transformed data. + """ assert "definitions" in data and isinstance(data["definitions"], dict) # Addition for adding templates to the json-schema testcase = data["definitions"].get("testcase", {}) @@ -338,6 +346,13 @@ def add_templates(data: dict) -> dict: def add_parameter_type(data: Any) -> Any: + """ + This function will start with the result of add_templates and add the potential to use the type + parameter in specific places. + + :param data: The data to transform. + :return: The transformed data. + """ if isinstance(data, dict): if "type" in data: type_value = data["type"] From 35df307169e792065f006bc497296e61985a7f2e Mon Sep 17 00:00:00 2001 From: breblanc Date: Tue, 20 May 2025 11:18:36 +0200 Subject: [PATCH 10/24] added an extra assert --- tested/nat_translation.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tested/nat_translation.py b/tested/nat_translation.py index e273fc66..be31dd68 100644 --- a/tested/nat_translation.py +++ b/tested/nat_translation.py @@ -160,6 +160,9 @@ def translate_yaml( assert ( not parameters and not inside_templates ), "A template was defined inside another template. This is not allowed!" + assert ( + "repeat" not in data + ), "A repeat was defined alongside a template. This is not allowed!" if "template" in data: name = data.pop("template") assert name in templates @@ -176,6 +179,7 @@ def translate_yaml( ) if data: + print(data) # Extra specifications in data will overwrite parts of the template. data = translate_yaml( data, From 948e04a04a4099b101b611ddef67a9507d298b8b Mon Sep 17 00:00:00 2001 From: breblanc Date: Tue, 20 May 2025 12:07:13 +0200 Subject: [PATCH 11/24] changed the name of the main function --- tested/nat_translation.py | 20 +++++++++++--------- tests/test_preprocess_dsl.py | 15 ++++++++++----- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/tested/nat_translation.py b/tested/nat_translation.py index be31dd68..35ee378f 100644 --- a/tested/nat_translation.py +++ b/tested/nat_translation.py @@ -96,19 +96,19 @@ def init_template( ) -> dict: # translate parameters before inserting them into the template - new_parameters = translate_yaml( + new_parameters = translate_yaml_and_initialize_templates( parameters, translations, templates, parameters, language, env, True ) # translate template and insert parameters - template = translate_yaml( + template = translate_yaml_and_initialize_templates( template, translations, templates, new_parameters, language, env, True ) assert isinstance(template, dict) return template -def translate_yaml( +def translate_yaml_and_initialize_templates( data: Any, translations: dict, templates: dict, @@ -118,7 +118,7 @@ def translate_yaml( inside_templates: bool = False, ) -> Any: """ - This function will translate the multilingual object. + This function will translate the multilingual object and initialize the templates. :param data: The object to translate. :param translations: The merge of all found translations maps. @@ -134,7 +134,7 @@ def translate_yaml( if data["__tag__"] == "!natural_language": value = data["value"] assert language in value - return translate_yaml( + return translate_yaml_and_initialize_templates( value[language], translations, templates, @@ -181,7 +181,7 @@ def translate_yaml( if data: print(data) # Extra specifications in data will overwrite parts of the template. - data = translate_yaml( + data = translate_yaml_and_initialize_templates( data, translations, templates, @@ -221,7 +221,7 @@ def translate_yaml( ] result = { - key: translate_yaml( + key: translate_yaml_and_initialize_templates( value, translations, templates, @@ -237,7 +237,7 @@ def translate_yaml( result = [] for item in data: has_repeat = isinstance(item, dict) and "repeat" in item - translated = translate_yaml( + translated = translate_yaml_and_initialize_templates( item, translations, templates, @@ -329,7 +329,9 @@ def apply_translations( validate_pre_dsl(parsed_yaml) enviroment = create_enviroment() - translated_data = translate_yaml(parsed_yaml, {}, {}, {}, language, enviroment) + translated_data = translate_yaml_and_initialize_templates( + parsed_yaml, {}, {}, {}, language, enviroment + ) missing_keys = TrackingUndefined.missing_keys messages = build_preprocessor_messages(missing_keys) diff --git a/tests/test_preprocess_dsl.py b/tests/test_preprocess_dsl.py index ad3dd72a..71305c54 100644 --- a/tests/test_preprocess_dsl.py +++ b/tests/test_preprocess_dsl.py @@ -16,7 +16,7 @@ create_enviroment, parse_yaml, translate_file, - translate_yaml, + translate_yaml_and_initialize_templates, validate_pre_dsl, ) @@ -25,9 +25,10 @@ def validate_natural_translate(yaml_str: str, translated_yaml_str: str): enviroment = create_enviroment() yaml_object = parse_yaml(yaml_str) validate_pre_dsl(yaml_object) - translated_dsl = translate_yaml(yaml_object, {}, {}, {}, "en", enviroment) + translated_dsl = translate_yaml_and_initialize_templates( + yaml_object, {}, {}, {}, "en", enviroment + ) translated_yaml = convert_to_yaml(translated_dsl) - print(translated_yaml) assert translated_yaml.strip() == translated_yaml_str @@ -595,7 +596,9 @@ def test_validation(): validate_pre_dsl(yaml_object) enviroment = create_enviroment() - translated_data = translate_yaml(yaml_object, {}, {}, {}, "en", enviroment) + translated_data = translate_yaml_and_initialize_templates( + yaml_object, {}, {}, {}, "en", enviroment + ) translated_yaml_string = convert_to_yaml(translated_data) _validate_dsl(_parse_yaml(translated_yaml_string)) @@ -770,7 +773,9 @@ def test_to_yaml_object(): environment = create_enviroment() parsed_yaml = parse_yaml(yaml_str) - translated_dsl = translate_yaml(parsed_yaml, {}, {}, {}, "en", environment) + translated_dsl = translate_yaml_and_initialize_templates( + parsed_yaml, {}, {}, {}, "en", environment + ) translated_yaml_string = convert_to_yaml(translated_dsl) yaml_object = _parse_yaml(translated_yaml_string) assert isinstance(yaml_object, dict) From d1b905242d1d3b3eb9dcaaaff685ff5e697425a4 Mon Sep 17 00:00:00 2001 From: breblanc Date: Tue, 20 May 2025 18:11:03 +0200 Subject: [PATCH 12/24] added type for parameter tag --- tested/transform_json.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tested/transform_json.py b/tested/transform_json.py index 2b51bda5..6e6153b1 100644 --- a/tested/transform_json.py +++ b/tested/transform_json.py @@ -358,8 +358,8 @@ def add_parameter_type(data: Any) -> Any: type_value = data["type"] if ( isinstance(type_value, list) - and any(t in ["boolean", "integer"] for t in type_value) - ) or type_value in ["boolean", "integer"]: + and any(t in ["boolean", "integer", "number"] for t in type_value) + ) or type_value in ["boolean", "integer", "number"]: # Adding support for "!parameter" tag. return make_parameter_type_structure(data) return {k: add_parameter_type(v) for k, v in data.items()} From af0c8eb819b12966a2c5b0b639c2f4728477033d Mon Sep 17 00:00:00 2001 From: breblanc Date: Tue, 20 May 2025 18:27:47 +0200 Subject: [PATCH 13/24] added an extra message --- tested/nat_translation.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tested/nat_translation.py b/tested/nat_translation.py index 35ee378f..964fa395 100644 --- a/tested/nat_translation.py +++ b/tested/nat_translation.py @@ -144,7 +144,9 @@ def translate_yaml_and_initialize_templates( inside_templates, ) elif data["__tag__"] == "!parameter": - assert data["value"] in parameters + assert ( + data["value"] in parameters + ), "You are using the !parameter tag outside a template or the specified parameter does not exist." return parameters[data["value"]] current_templates = data.pop("templates", {}) From ee77141c58c490f88650da2472ca76a76fa82332 Mon Sep 17 00:00:00 2001 From: breblanc Date: Tue, 20 May 2025 20:07:36 +0200 Subject: [PATCH 14/24] updated the script --- tested/dsl/multilingual-schema.json | 3380 +++++++++++------ tested/dsl/schema-strict-nat-translation.json | 3301 ++++++++++------ tested/transform_json.py | 29 +- 3 files changed, 4227 insertions(+), 2483 deletions(-) diff --git a/tested/dsl/multilingual-schema.json b/tested/dsl/multilingual-schema.json index 88915ead..06080a1c 100644 --- a/tested/dsl/multilingual-schema.json +++ b/tested/dsl/multilingual-schema.json @@ -15,140 +15,269 @@ ], "definitions": { "_rootObject": { - "type": "object", "oneOf": [ { - "required": [ - "tabs" - ], - "not": { - "required": [ - "units" - ] - } - }, - { - "required": [ - "units" - ], - "not": { - "required": [ - "tabs" - ] - } - } - ], - "properties": { - "files": { + "type": "object", "oneOf": [ { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" + "required": [ + "tabs" + ], + "not": { + "required": [ + "units" + ] } }, { - "type": "object", - "additionalProperties": { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - }, + "required": [ + "units" + ], "not": { - "anyOf": [ - { - "required": [ - "description" + "required": [ + "tabs" + ] + } + } + ], + "properties": { + "files": { + "oneOf": [ + { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + { + "type": "object", + "additionalProperties": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] + } + } + ] + }, + "namespace": { + "oneOf": [ + { + "type": "string", + "description": "Namespace of the submitted solution, in `snake_case`" + }, + { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Namespace of the submitted solution, in `snake_case`" }, - { - "required": [ - "value" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] + } + } + ] + }, + "tabs": { + "$ref": "#/definitions/_tabList" + }, + "units": { + "$ref": "#/definitions/_unitList" + }, + "language": { + "description": "Indicate that all code is in a specific language.", + "oneOf": [ + { + "$ref": "#/subDefinitions/programmingLanguage" + }, + { + "const": "tested" + } + ] + }, + "definitions": { + "oneOf": [ + { + "description": "Define hashes to use elsewhere.", + "type": "object" + }, + { + "type": "object", + "additionalProperties": { + "description": "Define hashes to use elsewhere.", + "type": "object" }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } - } - ] - }, - "namespace": { - "oneOf": [ - { - "type": "string", - "description": "Namespace of the submitted solution, in `snake_case`" + } + ] }, - { + "config": { + "$ref": "#/subDefinitions/inheritableConfigObject" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { "type": "object", + "description": "Define templates.", "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } + } + } + }, + { + "type": "object", + "additionalProperties": { + "type": "object", + "oneOf": [ + { + "required": [ + "tabs" + ], + "not": { + "required": [ + "units" + ] + } + }, + { + "required": [ + "units" + ], + "not": { + "required": [ + "tabs" + ] + } + } + ], + "properties": { + "files": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + "namespace": { "type": "string", "description": "Namespace of the submitted solution, in `snake_case`" }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, + "tabs": { + "$ref": "#/definitions/_tabList" + }, + "units": { + "$ref": "#/definitions/_unitList" + }, + "language": { + "description": "Indicate that all code is in a specific language.", + "oneOf": [ { - "required": [ - "value" - ] + "$ref": "#/subDefinitions/programmingLanguage" }, { - "required": [ - "types" - ] + "const": "tested" } ] + }, + "definitions": { + "description": "Define hashes to use elsewhere.", + "type": "object" + }, + "config": { + "$ref": "#/subDefinitions/inheritableConfigObject" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } } } - ] - }, - "tabs": { - "$ref": "#/definitions/_tabList" - }, - "units": { - "$ref": "#/definitions/_unitList" - }, - "language": { - "description": "Indicate that all code is in a specific language.", - "oneOf": [ - { - "$ref": "#/subDefinitions/programmingLanguage" - }, - { - "const": "tested" - } - ] - }, - "definitions": { - "description": "Define hashes to use elsewhere.", - "type": "object" - }, - "config": { - "$ref": "#/subDefinitions/inheritableConfigObject" - }, - "translations": { - "type": "object", - "description": "Define translations." - }, - "templates": { - "type": "object", - "description": "Define templates.", - "additionalProperties": { - "$ref": "#/definitions/testcase_without_templates" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] } } - } + ] }, "_tabList": { "oneOf": [ @@ -231,65 +360,31 @@ ] }, "tab": { - "type": "object", - "description": "A tab in the test suite.", - "required": [ - "tab" - ], - "properties": { - "files": { - "oneOf": [ - { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - }, - { - "type": "object", - "additionalProperties": { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } - } - ] - }, - "hidden": { - "anyOf": [ - { + "oneOf": [ + { + "type": "object", + "description": "A tab in the test suite.", + "required": [ + "tab" + ], + "properties": { + "files": { "oneOf": [ { - "description": "The key of the parameter.", - "type": "string" + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } }, { "type": "object", "additionalProperties": { - "description": "The key of the parameter.", - "type": "string" + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } }, "not": { "anyOf": [ @@ -313,148 +408,93 @@ } ] }, - { - "type": "boolean", - "description": "Defines if the unit/tab is hidden for the student or not" - } - ] - }, - "tab": { - "oneOf": [ - { - "description": "The name of this tab.", - "type": "string" + "hidden": { + "anyOf": [ + { + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + { + "type": "boolean", + "description": "Defines if the unit/tab is hidden for the student or not" + } + ] }, - { - "type": "object", - "additionalProperties": { - "description": "The name of this tab.", - "type": "string" - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] + "tab": { + "oneOf": [ + { + "description": "The name of this tab.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The name of this tab.", + "type": "string" }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } - } - ] - }, - "definitions": { - "description": "Define objects to use elsewhere.", - "type": "object" - }, - "config": { - "$ref": "#/subDefinitions/inheritableConfigObject" - }, - "translations": { - "type": "object", - "description": "Define translations." - }, - "templates": { - "type": "object", - "description": "Define templates.", - "additionalProperties": { - "$ref": "#/definitions/testcase_without_templates" - } - } - }, - "oneOf": [ - { - "required": [ - "contexts" - ], - "properties": { - "contexts": { - "$ref": "#/definitions/_contextList" - } - } - }, - { - "required": [ - "testcases" - ], - "properties": { - "testcases": { - "$ref": "#/definitions/_testcaseList" - } - } - } - ] - }, - "unit": { - "type": "object", - "description": "A unit in the test suite.", - "required": [ - "unit" - ], - "properties": { - "files": { - "oneOf": [ - { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - }, - { - "type": "object", - "additionalProperties": { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } - } - ] - }, - "hidden": { - "anyOf": [ - { + ] + }, + "definitions": { "oneOf": [ { - "description": "The key of the parameter.", - "type": "string" + "description": "Define objects to use elsewhere.", + "type": "object" }, { "type": "object", "additionalProperties": { - "description": "The key of the parameter.", - "type": "string" + "description": "Define objects to use elsewhere.", + "type": "object" }, "not": { "anyOf": [ @@ -478,185 +518,117 @@ } ] }, - { - "type": "boolean", - "description": "Defines if the unit/tab is hidden for the student or not" + "config": { + "$ref": "#/subDefinitions/inheritableConfigObject" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } } - ] - }, - "unit": { + }, "oneOf": [ { - "description": "The name of this tab.", - "type": "string" + "required": [ + "contexts" + ], + "properties": { + "contexts": { + "$ref": "#/definitions/_contextList" + } + } }, { - "type": "object", - "additionalProperties": { - "description": "The name of this tab.", - "type": "string" - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] + "required": [ + "testcases" + ], + "properties": { + "testcases": { + "$ref": "#/definitions/_testcaseList" + } } } ] }, - "definitions": { - "description": "Define objects to use elsewhere.", - "type": "object" - }, - "config": { - "$ref": "#/subDefinitions/inheritableConfigObject" - }, - "translations": { - "type": "object", - "description": "Define translations." - }, - "templates": { - "type": "object", - "description": "Define templates.", - "additionalProperties": { - "$ref": "#/definitions/testcase_without_templates" - } - } - }, - "oneOf": [ - { - "required": [ - "cases" - ], - "properties": { - "cases": { - "$ref": "#/definitions/_caseList" - } - } - }, - { - "required": [ - "scripts" - ], - "properties": { - "scripts": { - "$ref": "#/definitions/_scriptList" - } - } - } - ] - }, - "_contextList": { - "oneOf": [ - { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/definitions/context" - } - }, { "type": "object", "additionalProperties": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/definitions/context" - } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] + "type": "object", + "description": "A tab in the test suite.", + "required": [ + "tab" + ], + "properties": { + "files": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } }, - { - "required": [ - "value" + "hidden": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "boolean", + "description": "Defines if the unit/tab is hidden for the student or not" + } ] }, - { - "required": [ - "types" - ] - } - ] - } - } - ] - }, - "_caseList": { - "oneOf": [ - { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/definitions/case" - } - }, - { - "type": "object", - "additionalProperties": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/definitions/case" - } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] + "tab": { + "description": "The name of this tab.", + "type": "string" + }, + "definitions": { + "description": "Define objects to use elsewhere.", + "type": "object" }, + "config": { + "$ref": "#/subDefinitions/inheritableConfigObject" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } + } + }, + "oneOf": [ { "required": [ - "value" - ] + "contexts" + ], + "properties": { + "contexts": { + "$ref": "#/definitions/_contextList" + } + } }, { "required": [ - "types" - ] + "testcases" + ], + "properties": { + "testcases": { + "$ref": "#/definitions/_testcaseList" + } + } } ] - } - } - ] - }, - "_testcaseList": { - "oneOf": [ - { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/definitions/testcase" - } - }, - { - "type": "object", - "additionalProperties": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/definitions/testcase" - } }, "not": { "anyOf": [ @@ -680,260 +652,107 @@ } ] }, - "_scriptList": { + "unit": { "oneOf": [ - { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/definitions/testcase" - } - }, { "type": "object", - "additionalProperties": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/definitions/testcase" - } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } - } - ] - }, - "context": { - "type": "object", - "description": "A set of testcase in the same context.", - "required": [ - "testcases" - ], - "properties": { - "files": { - "oneOf": [ - { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - }, - { - "type": "object", - "additionalProperties": { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] + "description": "A unit in the test suite.", + "required": [ + "unit" + ], + "properties": { + "files": { + "oneOf": [ + { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + { + "type": "object", + "additionalProperties": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } - } - ] - }, - "context": { - "oneOf": [ - { - "type": "string", - "description": "Description of this context." + } + ] }, - { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "Description of this context." - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } - } - ] - }, - "testcases": { - "$ref": "#/definitions/_testcaseList" - }, - "translations": { - "type": "object", - "description": "Define translations." - }, - "templates": { - "type": "object", - "description": "Define templates.", - "additionalProperties": { - "$ref": "#/definitions/testcase_without_templates" - } - } - } - }, - "case": { - "type": "object", - "description": "A test case.", - "required": [ - "script" - ], - "properties": { - "files": { - "oneOf": [ - { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - }, - { - "type": "object", - "additionalProperties": { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" + "hidden": { + "anyOf": [ + { + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + { + "type": "boolean", + "description": "Defines if the unit/tab is hidden for the student or not" } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } - } - ] - }, - "context": { - "oneOf": [ - { - "type": "string", - "description": "Description of this context." + ] }, - { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "Description of this context." - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } - } - ] - }, - "script": { - "$ref": "#/definitions/_scriptList" - }, - "translations": { - "type": "object", - "description": "Define translations." - }, - "templates": { - "type": "object", - "description": "Define templates.", - "additionalProperties": { - "$ref": "#/definitions/testcase_without_templates" - } - } - } - }, - "testcase": { - "type": "object", - "description": "An individual test for a statement or expression", - "additionalProperties": false, - "properties": { - "description": { - "$ref": "#/subDefinitions/message" - }, - "stdin": { - "anyOf": [ - { + "unit": { "oneOf": [ { - "description": "The key of the parameter.", + "description": "The name of this tab.", "type": "string" }, { "type": "object", "additionalProperties": { - "description": "The key of the parameter.", + "description": "The name of this tab.", "type": "string" }, "not": { @@ -958,27 +777,17 @@ } ] }, - { + "definitions": { "oneOf": [ { - "description": "Stdin for this context", - "type": [ - "string", - "number", - "integer", - "boolean" - ] + "description": "Define objects to use elsewhere.", + "type": "object" }, { "type": "object", "additionalProperties": { - "description": "Stdin for this context", - "type": [ - "string", - "number", - "integer", - "boolean" - ] + "description": "Define objects to use elsewhere.", + "type": "object" }, "not": { "anyOf": [ @@ -1001,220 +810,866 @@ } } ] + }, + "config": { + "$ref": "#/subDefinitions/inheritableConfigObject" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } } - ] - }, - "arguments": { + }, "oneOf": [ { - "description": "Array of program call arguments", - "type": "array", - "items": { + "required": [ + "cases" + ], + "properties": { + "cases": { + "$ref": "#/definitions/_caseList" + } + } + }, + { + "required": [ + "scripts" + ], + "properties": { + "scripts": { + "$ref": "#/definitions/_scriptList" + } + } + } + ] + }, + { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "A unit in the test suite.", + "required": [ + "unit" + ], + "properties": { + "files": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + "hidden": { "anyOf": [ { - "oneOf": [ - { - "description": "The key of the parameter.", - "type": "string" - }, - { - "type": "object", - "additionalProperties": { - "description": "The key of the parameter.", - "type": "string" - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } - } - ] + "description": "The key of the parameter.", + "type": "string" }, { - "oneOf": [ - { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - }, - { - "type": "object", - "additionalProperties": { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } + "type": "boolean", + "description": "Defines if the unit/tab is hidden for the student or not" + } + ] + }, + "unit": { + "description": "The name of this tab.", + "type": "string" + }, + "definitions": { + "description": "Define objects to use elsewhere.", + "type": "object" + }, + "config": { + "$ref": "#/subDefinitions/inheritableConfigObject" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } + } + }, + "oneOf": [ + { + "required": [ + "cases" + ], + "properties": { + "cases": { + "$ref": "#/definitions/_caseList" + } + } + }, + { + "required": [ + "scripts" + ], + "properties": { + "scripts": { + "$ref": "#/definitions/_scriptList" + } + } + } + ] + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "_contextList": { + "oneOf": [ + { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/context" + } + }, + { + "type": "object", + "additionalProperties": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/context" + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "_caseList": { + "oneOf": [ + { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/case" + } + }, + { + "type": "object", + "additionalProperties": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/case" + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "_testcaseList": { + "oneOf": [ + { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/testcase" + } + }, + { + "type": "object", + "additionalProperties": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/testcase" + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "_scriptList": { + "oneOf": [ + { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/testcase" + } + }, + { + "type": "object", + "additionalProperties": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/testcase" + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "context": { + "oneOf": [ + { + "type": "object", + "description": "A set of testcase in the same context.", + "required": [ + "testcases" + ], + "properties": { + "files": { + "oneOf": [ + { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + { + "type": "object", + "additionalProperties": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] } ] } + } + ] + }, + "context": { + "oneOf": [ + { + "type": "string", + "description": "Description of this context." + }, + { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Description of this context." + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "testcases": { + "$ref": "#/definitions/_testcaseList" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } + } + } + }, + { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "A set of testcase in the same context.", + "required": [ + "testcases" + ], + "properties": { + "files": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + "context": { + "type": "string", + "description": "Description of this context." + }, + "testcases": { + "$ref": "#/definitions/_testcaseList" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } + } + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" ] } + ] + } + } + ] + }, + "case": { + "oneOf": [ + { + "type": "object", + "description": "A test case.", + "required": [ + "script" + ], + "properties": { + "files": { + "oneOf": [ + { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + { + "type": "object", + "additionalProperties": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "context": { + "oneOf": [ + { + "type": "string", + "description": "Description of this context." + }, + { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Description of this context." + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "script": { + "$ref": "#/definitions/_scriptList" }, - { + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { "type": "object", + "description": "Define templates.", "additionalProperties": { - "description": "Array of program call arguments", + "$ref": "#/definitions/testcase_without_templates" + } + } + } + }, + { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "A test case.", + "required": [ + "script" + ], + "properties": { + "files": { + "description": "A list of files used in the test suite.", "type": "array", "items": { - "anyOf": [ + "$ref": "#/subDefinitions/file" + } + }, + "context": { + "type": "string", + "description": "Description of this context." + }, + "script": { + "$ref": "#/definitions/_scriptList" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } + } + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "testcase": { + "oneOf": [ + { + "type": "object", + "description": "An individual test for a statement or expression", + "additionalProperties": false, + "properties": { + "description": { + "$ref": "#/subDefinitions/message" + }, + "stdin": { + "anyOf": [ + { + "oneOf": [ { "description": "The key of the parameter.", "type": "string" }, { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + { + "oneOf": [ + { + "description": "Stdin for this context", "type": [ "string", "number", "integer", "boolean" ] + }, + { + "type": "object", + "additionalProperties": { + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" + ] + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } } ] } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } - } - ] - }, - "statement": { - "description": "The statement to evaluate.", - "$ref": "#/subDefinitions/expressionOrStatement" - }, - "expression": { - "description": "The expression to evaluate.", - "$ref": "#/subDefinitions/expressionOrStatement" - }, - "exception": { - "description": "Expected exception message", - "$ref": "#/subDefinitions/exceptionChannel" - }, - "files": { - "oneOf": [ - { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } + ] }, - { - "type": "object", - "additionalProperties": { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" + "arguments": { + "oneOf": [ + { + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ + { + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + { + "oneOf": [ + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + }, + { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + } ] + } + }, + { + "type": "object", + "additionalProperties": { + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + ] + } }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } - } - ] - }, - "return": { - "description": "Expected return value", - "$ref": "#/subDefinitions/returnOutputChannel" - }, - "stderr": { - "description": "Expected output at stderr", - "$ref": "#/subDefinitions/textOutputChannel" - }, - "stdout": { - "description": "Expected output at stdout", - "$ref": "#/subDefinitions/textOutputChannel" - }, - "file": { - "description": "Expected files generated by the submission.", - "$ref": "#/subDefinitions/fileOutputChannel" - }, - "exit_code": { - "anyOf": [ - { + } + ] + }, + "statement": { + "description": "The statement to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "expression": { + "description": "The expression to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "exception": { + "description": "Expected exception message", + "$ref": "#/subDefinitions/exceptionChannel" + }, + "files": { "oneOf": [ { - "description": "The key of the parameter.", - "type": "string" + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } }, { "type": "object", "additionalProperties": { - "description": "The key of the parameter.", - "type": "string" + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } }, "not": { "anyOf": [ @@ -1238,90 +1693,64 @@ } ] }, - { - "type": "integer", - "description": "Expected exit code for the run" - } - ] - }, - "template": { - "oneOf": [ - { - "type": "string", - "description": "Name of the template to insert." + "return": { + "description": "Expected return value", + "$ref": "#/subDefinitions/returnOutputChannel" }, - { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "Name of the template to insert." - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } - } - ] - }, - "parameters": { - "type": "object", - "description": "The parameters that are to be inserted into the template.", - "additionalProperties": { - "oneOf": [ - { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - }, - { - "type": "object", - "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, + "stderr": { + "description": "Expected output at stderr", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "stdout": { + "description": "Expected output at stdout", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "file": { + "description": "Expected files generated by the submission.", + "$ref": "#/subDefinitions/fileOutputChannel" + }, + "exit_code": { + "anyOf": [ + { + "oneOf": [ { - "required": [ - "value" - ] + "description": "The key of the parameter.", + "type": "string" }, { - "required": [ - "types" - ] + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } } ] + }, + { + "type": "integer", + "description": "Expected exit code for the run" } - } - ] - } - }, - "repeat": { - "type": "object", - "description": "A certain loop that will generate test cases with the given parameters and template.", - "required": [ - "template", - "parameters" - ], - "properties": { + ] + }, "template": { "oneOf": [ { @@ -1359,19 +1788,201 @@ "parameters": { "oneOf": [ { - "type": "array", - "items": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + } + }, + { + "type": "object", + "additionalProperties": { "type": "object", "description": "The parameters that are to be inserted into the template.", "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "repeat": { + "oneOf": [ + { + "type": "object", + "description": "A certain loop that will generate test cases with the given parameters and template.", + "required": [ + "template", + "parameters" + ], + "properties": { + "template": { + "oneOf": [ + { + "type": "string", + "description": "Name of the template to insert." + }, + { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Name of the template to insert." + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "parameters": { "oneOf": [ { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "type": "array", + "items": { + "oneOf": [ + { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + } + }, + { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + } }, { "type": "object", "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "type": "array", + "items": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } }, "not": { "anyOf": [ @@ -1400,12 +2011,26 @@ { "type": "object", "additionalProperties": { - "type": "array", - "items": { - "type": "object", - "description": "The parameters that are to be inserted into the template.", - "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "type": "object", + "description": "A certain loop that will generate test cases with the given parameters and template.", + "required": [ + "template", + "parameters" + ], + "properties": { + "template": { + "type": "string", + "description": "Name of the template to insert." + }, + "parameters": { + "type": "array", + "items": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } } } }, @@ -1432,67 +2057,24 @@ ] } } - } - } - }, - "testcase_without_templates": { - "type": "object", - "description": "An individual test for a statement or expression", - "additionalProperties": false, - "properties": { - "description": { - "$ref": "#/subDefinitions/message" }, - "stdin": { - "anyOf": [ - { - "oneOf": [ - { - "description": "The key of the parameter.", - "type": "string" - }, - { - "type": "object", - "additionalProperties": { + { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "An individual test for a statement or expression", + "additionalProperties": false, + "properties": { + "description": { + "$ref": "#/subDefinitions/message" + }, + "stdin": { + "anyOf": [ + { "description": "The key of the parameter.", "type": "string" }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } - } - ] - }, - { - "oneOf": [ - { - "description": "Stdin for this context", - "type": [ - "string", - "number", - "integer", - "boolean" - ] - }, - { - "type": "object", - "additionalProperties": { + { "description": "Stdin for this context", "type": [ "string", @@ -1500,173 +2082,423 @@ "integer", "boolean" ] + } + ] + }, + "arguments": { + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + ] + } + }, + "statement": { + "description": "The statement to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "expression": { + "description": "The expression to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "exception": { + "description": "Expected exception message", + "$ref": "#/subDefinitions/exceptionChannel" + }, + "files": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + "return": { + "description": "Expected return value", + "$ref": "#/subDefinitions/returnOutputChannel" + }, + "stderr": { + "description": "Expected output at stderr", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "stdout": { + "description": "Expected output at stdout", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "file": { + "description": "Expected files generated by the submission.", + "$ref": "#/subDefinitions/fileOutputChannel" + }, + "exit_code": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] + { + "type": "integer", + "description": "Expected exit code for the run" + } + ] + }, + "template": { + "type": "string", + "description": "Name of the template to insert." + }, + "parameters": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + }, + "repeat": { + "type": "object", + "description": "A certain loop that will generate test cases with the given parameters and template.", + "required": [ + "template", + "parameters" + ], + "properties": { + "template": { + "type": "string", + "description": "Name of the template to insert." + }, + "parameters": { + "type": "array", + "items": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + } + } + } + } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + "testcase_without_templates": { + "oneOf": [ + { + "type": "object", + "description": "An individual test for a statement or expression", + "additionalProperties": false, + "properties": { + "description": { + "$ref": "#/subDefinitions/message" + }, + "stdin": { + "anyOf": [ + { + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } - } - ] - } - ] - }, - "arguments": { - "anyOf": [ - { - "oneOf": [ - { - "description": "The key of the parameter.", - "type": "string" + } + ] }, { - "type": "object", - "additionalProperties": { - "description": "The key of the parameter.", - "type": "string" - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" + "oneOf": [ + { + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" + ] + }, + { + "type": "object", + "additionalProperties": { + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" ] }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } + } + ] } ] }, - { - "oneOf": [ + "arguments": { + "anyOf": [ { - "description": "Array of program call arguments", - "type": "array", - "items": { - "anyOf": [ - { - "oneOf": [ + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ { - "description": "The key of the parameter.", - "type": "string" + "required": [ + "description" + ] }, { - "type": "object", - "additionalProperties": { - "description": "The key of the parameter.", - "type": "string" - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + { + "oneOf": [ + { + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ + { + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" }, - { - "required": [ - "value" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + { + "oneOf": [ + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + }, + { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "number", + "integer", + "boolean" ] }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } + } + ] } ] + } + }, + { + "type": "object", + "additionalProperties": { + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + ] + } }, - { - "oneOf": [ + "not": { + "anyOf": [ { - "type": [ - "string", - "number", - "integer", - "boolean" + "required": [ + "description" + ] + }, + { + "required": [ + "value" ] }, { - "type": "object", - "additionalProperties": { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } + "required": [ + "types" + ] } ] } - ] + } + ] + } + ] + }, + "statement": { + "description": "The statement to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "expression": { + "description": "The expression to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "exception": { + "description": "Expected exception message", + "$ref": "#/subDefinitions/exceptionChannel" + }, + "files": { + "oneOf": [ + { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" } }, { "type": "object", "additionalProperties": { - "description": "Array of program call arguments", + "description": "A list of files used in the test suite.", "type": "array", "items": { - "anyOf": [ - { - "description": "The key of the parameter.", - "type": "string" - }, - { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - } - ] + "$ref": "#/subDefinitions/file" } }, "not": { @@ -1690,120 +2522,192 @@ } } ] - } - ] - }, - "statement": { - "description": "The statement to evaluate.", - "$ref": "#/subDefinitions/expressionOrStatement" - }, - "expression": { - "description": "The expression to evaluate.", - "$ref": "#/subDefinitions/expressionOrStatement" - }, - "exception": { - "description": "Expected exception message", - "$ref": "#/subDefinitions/exceptionChannel" - }, - "files": { - "oneOf": [ - { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } }, - { - "type": "object", - "additionalProperties": { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" + "return": { + "description": "Expected return value", + "$ref": "#/subDefinitions/returnOutputChannel" + }, + "stderr": { + "description": "Expected output at stderr", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "stdout": { + "description": "Expected output at stdout", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "file": { + "description": "Expected files generated by the submission.", + "$ref": "#/subDefinitions/fileOutputChannel" + }, + "exit_code": { + "anyOf": [ + { + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + { + "type": "integer", + "description": "Expected exit code for the run" } + ] + } + } + }, + { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "An individual test for a statement or expression", + "additionalProperties": false, + "properties": { + "description": { + "$ref": "#/subDefinitions/message" }, - "not": { + "stdin": { "anyOf": [ { - "required": [ - "description" - ] + "description": "The key of the parameter.", + "type": "string" }, { - "required": [ - "value" + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" ] + } + ] + }, + "arguments": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" }, { - "required": [ - "types" - ] + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + ] + } } ] - } - } - ] - }, - "return": { - "description": "Expected return value", - "$ref": "#/subDefinitions/returnOutputChannel" - }, - "stderr": { - "description": "Expected output at stderr", - "$ref": "#/subDefinitions/textOutputChannel" - }, - "stdout": { - "description": "Expected output at stdout", - "$ref": "#/subDefinitions/textOutputChannel" - }, - "file": { - "description": "Expected files generated by the submission.", - "$ref": "#/subDefinitions/fileOutputChannel" - }, - "exit_code": { - "anyOf": [ - { - "oneOf": [ - { - "description": "The key of the parameter.", - "type": "string" - }, - { - "type": "object", - "additionalProperties": { + }, + "statement": { + "description": "The statement to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "expression": { + "description": "The expression to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "exception": { + "description": "Expected exception message", + "$ref": "#/subDefinitions/exceptionChannel" + }, + "files": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + "return": { + "description": "Expected return value", + "$ref": "#/subDefinitions/returnOutputChannel" + }, + "stderr": { + "description": "Expected output at stderr", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "stdout": { + "description": "Expected output at stdout", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "file": { + "description": "Expected files generated by the submission.", + "$ref": "#/subDefinitions/fileOutputChannel" + }, + "exit_code": { + "anyOf": [ + { "description": "The key of the parameter.", "type": "string" }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] + { + "type": "integer", + "description": "Expected exit code for the run" } - } - ] - }, - { - "type": "integer", - "description": "Expected exit code for the run" + ] + } } - ] + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } } - } + ] } }, "subDefinitions": { diff --git a/tested/dsl/schema-strict-nat-translation.json b/tested/dsl/schema-strict-nat-translation.json index 50943261..a3adef38 100644 --- a/tested/dsl/schema-strict-nat-translation.json +++ b/tested/dsl/schema-strict-nat-translation.json @@ -15,130 +15,249 @@ ], "definitions": { "_rootObject": { - "type": "object", "oneOf": [ { - "required": [ - "tabs" - ], - "not": { - "required": [ - "units" - ] - } - }, - { - "required": [ - "units" - ], - "not": { - "required": [ - "tabs" - ] - } - } - ], - "properties": { - "files": { + "type": "object", "oneOf": [ { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" + "required": [ + "tabs" + ], + "not": { + "required": [ + "units" + ] } }, { - "type": "object", "required": [ - "__tag__", - "value" + "units" ], - "properties": { - "__tag__": { + "not": { + "required": [ + "tabs" + ] + } + } + ], + "properties": { + "files": { + "oneOf": [ + { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + } + } + } + } + ] + }, + "namespace": { + "oneOf": [ + { "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "description": "Namespace of the submitted solution, in `snake_case`" }, - "value": { + { "type": "object", - "additionalProperties": { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Namespace of the submitted solution, in `snake_case`" + } + } + } + } + ] + }, + "tabs": { + "$ref": "#/definitions/_tabList" + }, + "units": { + "$ref": "#/definitions/_unitList" + }, + "language": { + "description": "Indicate that all code is in a specific language.", + "oneOf": [ + { + "$ref": "#/subDefinitions/programmingLanguage" + }, + { + "const": "tested" + } + ] + }, + "definitions": { + "oneOf": [ + { + "description": "Define hashes to use elsewhere.", + "type": "object" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "description": "Define hashes to use elsewhere.", + "type": "object" + } } } } + ] + }, + "config": { + "$ref": "#/subDefinitions/inheritableConfigObject" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" } } - ] + } }, - "namespace": { - "oneOf": [ - { + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { "type": "string", - "description": "Namespace of the submitted solution, in `snake_case`" + "description": "The tag used in the yaml", + "const": "!natural_language" }, - { + "value": { "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { + "additionalProperties": { + "type": "object", + "oneOf": [ + { + "required": [ + "tabs" + ], + "not": { + "required": [ + "units" + ] + } + }, + { + "required": [ + "units" + ], + "not": { + "required": [ + "tabs" + ] + } + } + ], + "properties": { + "files": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + "namespace": { "type": "string", "description": "Namespace of the submitted solution, in `snake_case`" + }, + "tabs": { + "$ref": "#/definitions/_tabList" + }, + "units": { + "$ref": "#/definitions/_unitList" + }, + "language": { + "description": "Indicate that all code is in a specific language.", + "oneOf": [ + { + "$ref": "#/subDefinitions/programmingLanguage" + }, + { + "const": "tested" + } + ] + }, + "definitions": { + "description": "Define hashes to use elsewhere.", + "type": "object" + }, + "config": { + "$ref": "#/subDefinitions/inheritableConfigObject" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } } } } } - ] - }, - "tabs": { - "$ref": "#/definitions/_tabList" - }, - "units": { - "$ref": "#/definitions/_unitList" - }, - "language": { - "description": "Indicate that all code is in a specific language.", - "oneOf": [ - { - "$ref": "#/subDefinitions/programmingLanguage" - }, - { - "const": "tested" - } - ] - }, - "definitions": { - "description": "Define hashes to use elsewhere.", - "type": "object" - }, - "config": { - "$ref": "#/subDefinitions/inheritableConfigObject" - }, - "translations": { - "type": "object", - "description": "Define translations." - }, - "templates": { - "type": "object", - "description": "Define templates.", - "additionalProperties": { - "$ref": "#/definitions/testcase_without_templates" } } - } + ] }, "_tabList": { "oneOf": [ @@ -211,51 +330,23 @@ ] }, "tab": { - "type": "object", - "description": "A tab in the test suite.", - "required": [ - "tab" - ], - "properties": { - "files": { - "oneOf": [ - { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - } - } - } - } - ] - }, - "hidden": { - "anyOf": [ - { + "oneOf": [ + { + "type": "object", + "description": "A tab in the test suite.", + "required": [ + "tab" + ], + "properties": { + "files": { "oneOf": [ + { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, { "type": "object", "required": [ @@ -266,44 +357,15 @@ "__tag__": { "type": "string", "description": "The tag used in the yaml", - "const": "!parameter" - }, - "value": { - "description": "The key of the parameter.", - "type": "string" - } - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "const": "!natural_language" }, "value": { "type": "object", "additionalProperties": { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!parameter" - }, - "value": { - "description": "The key of the parameter.", - "type": "string" - } + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" } } } @@ -311,129 +373,77 @@ } ] }, - { - "type": "boolean", - "description": "Defines if the unit/tab is hidden for the student or not" - } - ] - }, - "tab": { - "oneOf": [ - { - "description": "The name of this tab.", - "type": "string" - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "hidden": { + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } + ] }, - "value": { - "type": "object", - "additionalProperties": { - "description": "The name of this tab.", - "type": "string" - } + { + "type": "boolean", + "description": "Defines if the unit/tab is hidden for the student or not" } - } - } - ] - }, - "definitions": { - "description": "Define objects to use elsewhere.", - "type": "object" - }, - "config": { - "$ref": "#/subDefinitions/inheritableConfigObject" - }, - "translations": { - "type": "object", - "description": "Define translations." - }, - "templates": { - "type": "object", - "description": "Define templates.", - "additionalProperties": { - "$ref": "#/definitions/testcase_without_templates" - } - } - }, - "oneOf": [ - { - "required": [ - "contexts" - ], - "properties": { - "contexts": { - "$ref": "#/definitions/_contextList" - } - } - }, - { - "required": [ - "testcases" - ], - "properties": { - "testcases": { - "$ref": "#/definitions/_testcaseList" - } - } - } - ] - }, - "unit": { - "type": "object", - "description": "A unit in the test suite.", - "required": [ - "unit" - ], - "properties": { - "files": { - "oneOf": [ - { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } + ] }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - } - } - } - } - ] - }, - "hidden": { - "anyOf": [ - { + "tab": { "oneOf": [ + { + "description": "The name of this tab.", + "type": "string" + }, { "type": "object", "required": [ @@ -444,13 +454,24 @@ "__tag__": { "type": "string", "description": "The tag used in the yaml", - "const": "!parameter" + "const": "!natural_language" }, "value": { - "description": "The key of the parameter.", - "type": "string" + "type": "object", + "additionalProperties": { + "description": "The name of this tab.", + "type": "string" + } } } + } + ] + }, + "definitions": { + "oneOf": [ + { + "description": "Define objects to use elsewhere.", + "type": "object" }, { "type": "object", @@ -467,119 +488,57 @@ "value": { "type": "object", "additionalProperties": { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!parameter" - }, - "value": { - "description": "The key of the parameter.", - "type": "string" - } - } + "description": "Define objects to use elsewhere.", + "type": "object" } } } } ] }, - { - "type": "boolean", - "description": "Defines if the unit/tab is hidden for the student or not" + "config": { + "$ref": "#/subDefinitions/inheritableConfigObject" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } } - ] - }, - "unit": { + }, "oneOf": [ { - "description": "The name of this tab.", - "type": "string" + "required": [ + "contexts" + ], + "properties": { + "contexts": { + "$ref": "#/definitions/_contextList" + } + } }, { - "type": "object", "required": [ - "__tag__", - "value" + "testcases" ], "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "description": "The name of this tab.", - "type": "string" - } + "testcases": { + "$ref": "#/definitions/_testcaseList" } } } ] }, - "definitions": { - "description": "Define objects to use elsewhere.", - "type": "object" - }, - "config": { - "$ref": "#/subDefinitions/inheritableConfigObject" - }, - "translations": { - "type": "object", - "description": "Define translations." - }, - "templates": { - "type": "object", - "description": "Define templates.", - "additionalProperties": { - "$ref": "#/definitions/testcase_without_templates" - } - } - }, - "oneOf": [ - { - "required": [ - "cases" - ], - "properties": { - "cases": { - "$ref": "#/definitions/_caseList" - } - } - }, { + "type": "object", "required": [ - "scripts" - ], - "properties": { - "scripts": { - "$ref": "#/definitions/_scriptList" - } - } - } - ] - }, - "_contextList": { - "oneOf": [ - { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/definitions/context" - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" + "__tag__", + "value" ], "properties": { "__tag__": { @@ -590,25 +549,286 @@ "value": { "type": "object", "additionalProperties": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/definitions/context" - } + "type": "object", + "description": "A tab in the test suite.", + "required": [ + "tab" + ], + "properties": { + "files": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + "hidden": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "boolean", + "description": "Defines if the unit/tab is hidden for the student or not" + } + ] + }, + "tab": { + "description": "The name of this tab.", + "type": "string" + }, + "definitions": { + "description": "Define objects to use elsewhere.", + "type": "object" + }, + "config": { + "$ref": "#/subDefinitions/inheritableConfigObject" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } + } + }, + "oneOf": [ + { + "required": [ + "contexts" + ], + "properties": { + "contexts": { + "$ref": "#/definitions/_contextList" + } + } + }, + { + "required": [ + "testcases" + ], + "properties": { + "testcases": { + "$ref": "#/definitions/_testcaseList" + } + } + } + ] } } } } ] }, - "_caseList": { + "unit": { "oneOf": [ { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/definitions/case" - } + "type": "object", + "description": "A unit in the test suite.", + "required": [ + "unit" + ], + "properties": { + "files": { + "oneOf": [ + { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + } + } + } + } + ] + }, + "hidden": { + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } + ] + }, + { + "type": "boolean", + "description": "Defines if the unit/tab is hidden for the student or not" + } + ] + }, + "unit": { + "oneOf": [ + { + "description": "The name of this tab.", + "type": "string" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "description": "The name of this tab.", + "type": "string" + } + } + } + } + ] + }, + "definitions": { + "oneOf": [ + { + "description": "Define objects to use elsewhere.", + "type": "object" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "description": "Define objects to use elsewhere.", + "type": "object" + } + } + } + } + ] + }, + "config": { + "$ref": "#/subDefinitions/inheritableConfigObject" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } + } + }, + "oneOf": [ + { + "required": [ + "cases" + ], + "properties": { + "cases": { + "$ref": "#/definitions/_caseList" + } + } + }, + { + "required": [ + "scripts" + ], + "properties": { + "scripts": { + "$ref": "#/definitions/_scriptList" + } + } + } + ] }, { "type": "object", @@ -625,24 +845,89 @@ "value": { "type": "object", "additionalProperties": { - "type": "array", - "minItems": 1, - "items": { - "$ref": "#/definitions/case" - } - } - } - } - } - ] - }, - "_testcaseList": { - "oneOf": [ + "type": "object", + "description": "A unit in the test suite.", + "required": [ + "unit" + ], + "properties": { + "files": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + "hidden": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "boolean", + "description": "Defines if the unit/tab is hidden for the student or not" + } + ] + }, + "unit": { + "description": "The name of this tab.", + "type": "string" + }, + "definitions": { + "description": "Define objects to use elsewhere.", + "type": "object" + }, + "config": { + "$ref": "#/subDefinitions/inheritableConfigObject" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } + } + }, + "oneOf": [ + { + "required": [ + "cases" + ], + "properties": { + "cases": { + "$ref": "#/definitions/_caseList" + } + } + }, + { + "required": [ + "scripts" + ], + "properties": { + "scripts": { + "$ref": "#/definitions/_scriptList" + } + } + } + ] + } + } + } + } + ] + }, + "_contextList": { + "oneOf": [ { "type": "array", "minItems": 1, "items": { - "$ref": "#/definitions/testcase" + "$ref": "#/definitions/context" } }, { @@ -663,7 +948,7 @@ "type": "array", "minItems": 1, "items": { - "$ref": "#/definitions/testcase" + "$ref": "#/definitions/context" } } } @@ -671,13 +956,13 @@ } ] }, - "_scriptList": { + "_caseList": { "oneOf": [ { "type": "array", "minItems": 1, "items": { - "$ref": "#/definitions/testcase" + "$ref": "#/definitions/case" } }, { @@ -698,7 +983,7 @@ "type": "array", "minItems": 1, "items": { - "$ref": "#/definitions/testcase" + "$ref": "#/definitions/case" } } } @@ -706,208 +991,92 @@ } ] }, - "context": { - "type": "object", - "description": "A set of testcase in the same context.", - "required": [ - "testcases" - ], - "properties": { - "files": { - "oneOf": [ - { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - } - } - } - } - ] + "_testcaseList": { + "oneOf": [ + { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/testcase" + } }, - "context": { - "oneOf": [ - { + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { "type": "string", - "description": "Description of this context." + "description": "The tag used in the yaml", + "const": "!natural_language" }, - { + "value": { "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "Description of this context." - } + "additionalProperties": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/testcase" } } } - ] - }, - "testcases": { - "$ref": "#/definitions/_testcaseList" - }, - "translations": { - "type": "object", - "description": "Define translations." - }, - "templates": { - "type": "object", - "description": "Define templates.", - "additionalProperties": { - "$ref": "#/definitions/testcase_without_templates" } } - } + ] }, - "case": { - "type": "object", - "description": "A test case.", - "required": [ - "script" - ], - "properties": { - "files": { - "oneOf": [ - { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - } - } - } - } - ] + "_scriptList": { + "oneOf": [ + { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/testcase" + } }, - "context": { - "oneOf": [ - { + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { "type": "string", - "description": "Description of this context." + "description": "The tag used in the yaml", + "const": "!natural_language" }, - { + "value": { "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "Description of this context." - } + "additionalProperties": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/definitions/testcase" } } } - ] - }, - "script": { - "$ref": "#/definitions/_scriptList" - }, - "translations": { - "type": "object", - "description": "Define translations." - }, - "templates": { - "type": "object", - "description": "Define templates.", - "additionalProperties": { - "$ref": "#/definitions/testcase_without_templates" } } - } + ] }, - "testcase": { - "type": "object", - "description": "An individual test for a statement or expression", - "additionalProperties": false, - "properties": { - "description": { - "$ref": "#/subDefinitions/message" - }, - "stdin": { - "anyOf": [ - { + "context": { + "oneOf": [ + { + "type": "object", + "description": "A set of testcase in the same context.", + "required": [ + "testcases" + ], + "properties": { + "files": { "oneOf": [ { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!parameter" - }, - "value": { - "description": "The key of the parameter.", - "type": "string" - } + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" } }, { @@ -925,21 +1094,10 @@ "value": { "type": "object", "additionalProperties": { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!parameter" - }, - "value": { - "description": "The key of the parameter.", - "type": "string" - } + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" } } } @@ -947,16 +1105,11 @@ } ] }, - { + "context": { "oneOf": [ { - "description": "Stdin for this context", - "type": [ - "string", - "number", - "integer", - "boolean" - ] + "type": "string", + "description": "Description of this context." }, { "type": "object", @@ -973,231 +1126,101 @@ "value": { "type": "object", "additionalProperties": { - "description": "Stdin for this context", - "type": [ - "string", - "number", - "integer", - "boolean" - ] + "type": "string", + "description": "Description of this context." } } } } ] - } - ] - }, - "arguments": { - "oneOf": [ - { - "description": "Array of program call arguments", - "type": "array", - "items": { - "anyOf": [ - { - "oneOf": [ - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!parameter" - }, - "value": { - "description": "The key of the parameter.", - "type": "string" - } - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!parameter" - }, - "value": { - "description": "The key of the parameter.", - "type": "string" - } - } - } - } - } - } - ] - }, - { - "oneOf": [ - { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - } - } - } - } - ] - } - ] - } }, - { + "testcases": { + "$ref": "#/definitions/_testcaseList" + }, + "translations": { "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "description": "Array of program call arguments", - "type": "array", - "items": { - "anyOf": [ - { - "description": "The key of the parameter.", - "type": "string" - }, - { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - } - ] - } - } - } + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" } } - ] - }, - "statement": { - "description": "The statement to evaluate.", - "$ref": "#/subDefinitions/expressionOrStatement" - }, - "expression": { - "description": "The expression to evaluate.", - "$ref": "#/subDefinitions/expressionOrStatement" - }, - "exception": { - "description": "Expected exception message", - "$ref": "#/subDefinitions/exceptionChannel" + } }, - "files": { - "oneOf": [ - { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" }, - { + "value": { "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { + "additionalProperties": { + "type": "object", + "description": "A set of testcase in the same context.", + "required": [ + "testcases" + ], + "properties": { + "files": { "description": "A list of files used in the test suite.", "type": "array", "items": { "$ref": "#/subDefinitions/file" } + }, + "context": { + "type": "string", + "description": "Description of this context." + }, + "testcases": { + "$ref": "#/definitions/_testcaseList" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } } } } } - ] - }, - "return": { - "description": "Expected return value", - "$ref": "#/subDefinitions/returnOutputChannel" - }, - "stderr": { - "description": "Expected output at stderr", - "$ref": "#/subDefinitions/textOutputChannel" - }, - "stdout": { - "description": "Expected output at stdout", - "$ref": "#/subDefinitions/textOutputChannel" - }, - "file": { - "description": "Expected files generated by the submission.", - "$ref": "#/subDefinitions/fileOutputChannel" - }, - "exit_code": { - "anyOf": [ - { + } + } + ] + }, + "case": { + "oneOf": [ + { + "type": "object", + "description": "A test case.", + "required": [ + "script" + ], + "properties": { + "files": { "oneOf": [ + { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, { "type": "object", "required": [ @@ -1208,12 +1231,332 @@ "__tag__": { "type": "string", "description": "The tag used in the yaml", - "const": "!parameter" + "const": "!natural_language" }, "value": { - "description": "The key of the parameter.", - "type": "string" + "type": "object", + "additionalProperties": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + } + } + } + } + ] + }, + "context": { + "oneOf": [ + { + "type": "string", + "description": "Description of this context." + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Description of this context." + } + } + } + } + ] + }, + "script": { + "$ref": "#/definitions/_scriptList" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "A test case.", + "required": [ + "script" + ], + "properties": { + "files": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" } + }, + "context": { + "type": "string", + "description": "Description of this context." + }, + "script": { + "$ref": "#/definitions/_scriptList" + }, + "translations": { + "type": "object", + "description": "Define translations." + }, + "templates": { + "type": "object", + "description": "Define templates.", + "additionalProperties": { + "$ref": "#/definitions/testcase_without_templates" + } + } + } + } + } + } + } + ] + }, + "testcase": { + "oneOf": [ + { + "type": "object", + "description": "An individual test for a statement or expression", + "additionalProperties": false, + "properties": { + "description": { + "$ref": "#/subDefinitions/message" + }, + "stdin": { + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } + ] + }, + { + "oneOf": [ + { + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" + ] + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + } + } + } + ] + } + ] + }, + "arguments": { + "oneOf": [ + { + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } + ] + }, + { + "oneOf": [ + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + } + } + } + ] + } + ] } }, { @@ -1231,21 +1574,23 @@ "value": { "type": "object", "additionalProperties": { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!parameter" - }, - "value": { - "description": "The key of the parameter.", - "type": "string" - } + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + ] } } } @@ -1253,85 +1598,26 @@ } ] }, - { - "type": "integer", - "description": "Expected exit code for the run" - } - ] - }, - "template": { - "oneOf": [ - { - "type": "string", - "description": "Name of the template to insert." + "statement": { + "description": "The statement to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "Name of the template to insert." - } - } - } - } - ] - }, - "parameters": { - "type": "object", - "description": "The parameters that are to be inserted into the template.", - "additionalProperties": { - "oneOf": [ - { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } - } - } - } - ] - } - }, - "repeat": { - "type": "object", - "description": "A certain loop that will generate test cases with the given parameters and template.", - "required": [ - "template", - "parameters" - ], - "properties": { - "template": { + "expression": { + "description": "The expression to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "exception": { + "description": "Expected exception message", + "$ref": "#/subDefinitions/exceptionChannel" + }, + "files": { "oneOf": [ { - "type": "string", - "description": "Name of the template to insert." + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } }, { "type": "object", @@ -1348,112 +1634,103 @@ "value": { "type": "object", "additionalProperties": { - "type": "string", - "description": "Name of the template to insert." + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } } } } } ] }, - "parameters": { - "oneOf": [ + "return": { + "description": "Expected return value", + "$ref": "#/subDefinitions/returnOutputChannel" + }, + "stderr": { + "description": "Expected output at stderr", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "stdout": { + "description": "Expected output at stdout", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "file": { + "description": "Expected files generated by the submission.", + "$ref": "#/subDefinitions/fileOutputChannel" + }, + "exit_code": { + "anyOf": [ { - "type": "array", - "items": { - "type": "object", - "description": "The parameters that are to be inserted into the template.", - "additionalProperties": { - "oneOf": [ - { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } - } - } + "value": { + "description": "The key of the parameter.", + "type": "string" } - ] - } - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + } }, - "value": { + { "type": "object", - "additionalProperties": { - "type": "array", - "items": { + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { "type": "object", - "description": "The parameters that are to be inserted into the template.", "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } } } } } - } - } - ] - } - } - } - } - }, - "testcase_without_templates": { - "type": "object", - "description": "An individual test for a statement or expression", - "additionalProperties": false, - "properties": { - "description": { - "$ref": "#/subDefinitions/message" - }, - "stdin": { - "anyOf": [ - { + ] + }, + { + "type": "integer", + "description": "Expected exit code for the run" + } + ] + }, + "template": { "oneOf": [ { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!parameter" - }, - "value": { - "description": "The key of the parameter.", - "type": "string" - } - } + "type": "string", + "description": "Name of the template to insert." }, { "type": "object", @@ -1470,6 +1747,25 @@ "value": { "type": "object", "additionalProperties": { + "type": "string", + "description": "Name of the template to insert." + } + } + } + } + ] + }, + "parameters": { + "oneOf": [ + { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { "type": "object", "required": [ "__tag__", @@ -1479,29 +1775,18 @@ "__tag__": { "type": "string", "description": "The tag used in the yaml", - "const": "!parameter" + "const": "!natural_language" }, "value": { - "description": "The key of the parameter.", - "type": "string" + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } } } } - } + ] } - } - ] - }, - { - "oneOf": [ - { - "description": "Stdin for this context", - "type": [ - "string", - "number", - "integer", - "boolean" - ] }, { "type": "object", @@ -1518,40 +1803,148 @@ "value": { "type": "object", "additionalProperties": { - "description": "Stdin for this context", - "type": [ - "string", - "number", - "integer", - "boolean" - ] + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } } } } } ] - } - ] - }, - "arguments": { - "anyOf": [ - { + }, + "repeat": { "oneOf": [ { "type": "object", + "description": "A certain loop that will generate test cases with the given parameters and template.", "required": [ - "__tag__", - "value" + "template", + "parameters" ], "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!parameter" + "template": { + "oneOf": [ + { + "type": "string", + "description": "Name of the template to insert." + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "Name of the template to insert." + } + } + } + } + ] }, - "value": { - "description": "The key of the parameter.", - "type": "string" + "parameters": { + "oneOf": [ + { + "type": "array", + "items": { + "oneOf": [ + { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + } + } + ] + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + } + } + } + ] + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + } + } + } + } + ] } } }, @@ -1571,37 +1964,230 @@ "type": "object", "additionalProperties": { "type": "object", + "description": "A certain loop that will generate test cases with the given parameters and template.", "required": [ - "__tag__", - "value" + "template", + "parameters" ], "properties": { - "__tag__": { + "template": { "type": "string", - "description": "The tag used in the yaml", - "const": "!parameter" + "description": "Name of the template to insert." }, - "value": { - "description": "The key of the parameter.", - "type": "string" + "parameters": { + "type": "array", + "items": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + } + } + } + } + } + } + ] + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "An individual test for a statement or expression", + "additionalProperties": false, + "properties": { + "description": { + "$ref": "#/subDefinitions/message" + }, + "stdin": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + ] + }, + "arguments": { + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + ] + } + }, + "statement": { + "description": "The statement to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "expression": { + "description": "The expression to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "exception": { + "description": "Expected exception message", + "$ref": "#/subDefinitions/exceptionChannel" + }, + "files": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + }, + "return": { + "description": "Expected return value", + "$ref": "#/subDefinitions/returnOutputChannel" + }, + "stderr": { + "description": "Expected output at stderr", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "stdout": { + "description": "Expected output at stdout", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "file": { + "description": "Expected files generated by the submission.", + "$ref": "#/subDefinitions/fileOutputChannel" + }, + "exit_code": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "integer", + "description": "Expected exit code for the run" + } + ] + }, + "template": { + "type": "string", + "description": "Name of the template to insert." + }, + "parameters": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + }, + "repeat": { + "type": "object", + "description": "A certain loop that will generate test cases with the given parameters and template.", + "required": [ + "template", + "parameters" + ], + "properties": { + "template": { + "type": "string", + "description": "Name of the template to insert." + }, + "parameters": { + "type": "array", + "items": { + "type": "object", + "description": "The parameters that are to be inserted into the template.", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" } } } } } } - ] + } + } + } + } + ] + }, + "testcase_without_templates": { + "oneOf": [ + { + "type": "object", + "description": "An individual test for a statement or expression", + "additionalProperties": false, + "properties": { + "description": { + "$ref": "#/subDefinitions/message" }, - { - "oneOf": [ + "stdin": { + "anyOf": [ { - "description": "Array of program call arguments", - "type": "array", - "items": { - "anyOf": [ - { - "oneOf": [ - { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { "type": "object", "required": [ "__tag__", @@ -1618,8 +2204,90 @@ "type": "string" } } - }, - { + } + } + } + } + ] + }, + { + "oneOf": [ + { + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" + ] + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + } + } + } + ] + } + ] + }, + "arguments": { + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { "type": "object", "required": [ "__tag__", @@ -1629,58 +2297,147 @@ "__tag__": { "type": "string", "description": "The tag used in the yaml", - "const": "!natural_language" + "const": "!parameter" }, "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } + ] + }, + { + "oneOf": [ + { + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ + { + "oneOf": [ + { "type": "object", - "additionalProperties": { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!parameter" - }, - "value": { - "description": "The key of the parameter.", - "type": "string" + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } } } } } - } - } - ] - }, - { - "oneOf": [ - { - "type": [ - "string", - "number", - "integer", - "boolean" ] }, { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "oneOf": [ + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] }, - "value": { + { "type": "object", - "additionalProperties": { + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + } + } + } + ] + } + ] + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { "type": [ "string", "number", @@ -1688,12 +2445,35 @@ "boolean" ] } - } + ] } } - ] + } } - ] + } + ] + } + ] + }, + "statement": { + "description": "The statement to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "expression": { + "description": "The expression to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "exception": { + "description": "Expected exception message", + "$ref": "#/subDefinitions/exceptionChannel" + }, + "files": { + "oneOf": [ + { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" } }, { @@ -1711,6 +2491,146 @@ "value": { "type": "object", "additionalProperties": { + "description": "A list of files used in the test suite.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/file" + } + } + } + } + } + ] + }, + "return": { + "description": "Expected return value", + "$ref": "#/subDefinitions/returnOutputChannel" + }, + "stderr": { + "description": "Expected output at stderr", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "stdout": { + "description": "Expected output at stdout", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "file": { + "description": "Expected files generated by the submission.", + "$ref": "#/subDefinitions/fileOutputChannel" + }, + "exit_code": { + "anyOf": [ + { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } + ] + }, + { + "type": "integer", + "description": "Expected exit code for the run" + } + ] + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "description": "An individual test for a statement or expression", + "additionalProperties": false, + "properties": { + "description": { + "$ref": "#/subDefinitions/message" + }, + "stdin": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "Stdin for this context", + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + ] + }, + "arguments": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { "description": "Array of program call arguments", "type": "array", "items": { @@ -1730,142 +2650,61 @@ ] } } - } - } - } - ] - } - ] - }, - "statement": { - "description": "The statement to evaluate.", - "$ref": "#/subDefinitions/expressionOrStatement" - }, - "expression": { - "description": "The expression to evaluate.", - "$ref": "#/subDefinitions/expressionOrStatement" - }, - "exception": { - "description": "Expected exception message", - "$ref": "#/subDefinitions/exceptionChannel" - }, - "files": { - "oneOf": [ - { - "description": "A list of files used in the test suite.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/file" - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { + ] + }, + "statement": { + "description": "The statement to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "expression": { + "description": "The expression to evaluate.", + "$ref": "#/subDefinitions/expressionOrStatement" + }, + "exception": { + "description": "Expected exception message", + "$ref": "#/subDefinitions/exceptionChannel" + }, + "files": { "description": "A list of files used in the test suite.", "type": "array", "items": { "$ref": "#/subDefinitions/file" } - } - } - } - } - ] - }, - "return": { - "description": "Expected return value", - "$ref": "#/subDefinitions/returnOutputChannel" - }, - "stderr": { - "description": "Expected output at stderr", - "$ref": "#/subDefinitions/textOutputChannel" - }, - "stdout": { - "description": "Expected output at stdout", - "$ref": "#/subDefinitions/textOutputChannel" - }, - "file": { - "description": "Expected files generated by the submission.", - "$ref": "#/subDefinitions/fileOutputChannel" - }, - "exit_code": { - "anyOf": [ - { - "oneOf": [ - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!parameter" - }, - "value": { - "description": "The key of the parameter.", - "type": "string" - } - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!parameter" - }, - "value": { - "description": "The key of the parameter.", - "type": "string" - } - } + }, + "return": { + "description": "Expected return value", + "$ref": "#/subDefinitions/returnOutputChannel" + }, + "stderr": { + "description": "Expected output at stderr", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "stdout": { + "description": "Expected output at stdout", + "$ref": "#/subDefinitions/textOutputChannel" + }, + "file": { + "description": "Expected files generated by the submission.", + "$ref": "#/subDefinitions/fileOutputChannel" + }, + "exit_code": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "integer", + "description": "Expected exit code for the run" } - } + ] } } - ] - }, - { - "type": "integer", - "description": "Expected exit code for the run" + } } - ] + } } - } + ] } }, "subDefinitions": { diff --git a/tested/transform_json.py b/tested/transform_json.py index 6e6153b1..e85b7245 100644 --- a/tested/transform_json.py +++ b/tested/transform_json.py @@ -178,18 +178,26 @@ def transform_json_for_preprocessor_validation(data: Any, in_sub_def: bool) -> A :return: The transformed data. """ if isinstance(data, dict): + # Add the translations and templates maps + targets = ["_rootObject", "tab", "unit", "context", "case"] + for target in targets: + if target in data and "properties" in data[target]: + data[target]["properties"]["translations"] = make_translations_map() + data[target]["properties"]["templates"] = make_templates_map() + new_data = { - key: transform_json_for_preprocessor_validation( - value, in_sub_def or key == "subDefinitions" + key: ( + transform_json_for_preprocessor_validation( + value, in_sub_def or key == "subDefinitions" + ) + if key != "translations" and key != "templates" + else value ) for key, value in data.items() } + # Standard creation of the special tag structure for translations and templates. - if ( - "type" in data - and (data["type"] != "object" or in_sub_def) - and data["type"] not in ["boolean", "integer"] - ): + if "type" in data and data["type"] not in ["boolean", "integer"]: # Adding support for the other tags. if data["type"] in SPECIAL_TYPES: tag = data.pop("type") @@ -212,13 +220,6 @@ def transform_json_for_preprocessor_validation(data: Any, in_sub_def: bool) -> A return make_tag_structure(data, new_data) data = new_data - # Add the translations maps - targets = ["_rootObject", "tab", "unit", "context", "case"] - for target in targets: - if target in data and "properties" in data[target]: - data[target]["properties"]["translations"] = make_translations_map() - data[target]["properties"]["templates"] = make_templates_map() - # Flatten the oneOf structures if "oneOf" in data: assert isinstance(data["oneOf"], list) From 4c07d904feb0de3aa2214a1795af3961dfd0e826 Mon Sep 17 00:00:00 2001 From: breblanc Date: Tue, 20 May 2025 20:21:40 +0200 Subject: [PATCH 15/24] removed unused parameter --- tested/transform_json.py | 14 ++++---------- tests/test_json_schema_transformer.py | 10 +++++----- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/tested/transform_json.py b/tested/transform_json.py index e85b7245..9435a319 100644 --- a/tested/transform_json.py +++ b/tested/transform_json.py @@ -167,14 +167,13 @@ def make_templates_map() -> dict: } -def transform_json_for_preprocessor_validation(data: Any, in_sub_def: bool) -> Any: +def transform_json_for_preprocessor_validation(data: Any) -> Any: """ This function will start with the result of add_parameter_type. It is responsible for transforming the JSON-schema such that translations and templates are supported. It also uses a special structure for tags in the YAML that is used in the preprocessing step. :param data: The data to transform. - :param in_sub_def: Indicates if the sub-definition are being processed. :return: The transformed data. """ if isinstance(data, dict): @@ -187,9 +186,7 @@ def transform_json_for_preprocessor_validation(data: Any, in_sub_def: bool) -> A new_data = { key: ( - transform_json_for_preprocessor_validation( - value, in_sub_def or key == "subDefinitions" - ) + transform_json_for_preprocessor_validation(value) if key != "translations" and key != "templates" else value ) @@ -281,10 +278,7 @@ def transform_json_for_preprocessor_validation(data: Any, in_sub_def: bool) -> A return data if isinstance(data, list): - return [ - transform_json_for_preprocessor_validation(value, in_sub_def) - for value in data - ] + return [transform_json_for_preprocessor_validation(value) for value in data] return data @@ -395,7 +389,7 @@ def transform_json(json_file: Path, multilingual: bool, ide: bool): stream_with_templates = add_templates(json_stream) stream_with_templates_and_param = add_parameter_type(stream_with_templates) result = transform_json_for_preprocessor_validation( - stream_with_templates_and_param, False + stream_with_templates_and_param ) if ide: result = transform_ide(result) diff --git a/tests/test_json_schema_transformer.py b/tests/test_json_schema_transformer.py index ac2418a7..8130e5dd 100644 --- a/tests/test_json_schema_transformer.py +++ b/tests/test_json_schema_transformer.py @@ -236,7 +236,7 @@ def test_nat_lang_json_schema_structure(): ] } - result = transform_json_for_preprocessor_validation(json_schema, False) + result = transform_json_for_preprocessor_validation(json_schema) assert result == json_schema_expected @@ -344,7 +344,7 @@ def test_prog_lang_json_schema_structure(): } } - result = transform_json_for_preprocessor_validation(json_schema, True) + result = transform_json_for_preprocessor_validation(json_schema) assert result == json_schema_expected @@ -444,7 +444,7 @@ def test_json_schema_oracle(): ] } - result = transform_json_for_preprocessor_validation(json_schema, True) + result = transform_json_for_preprocessor_validation(json_schema) assert result == json_schema_expected @@ -502,7 +502,7 @@ def test_json_schema_expression(): } } - result = transform_json_for_preprocessor_validation(json_schema, True) + result = transform_json_for_preprocessor_validation(json_schema) assert result == json_schema_expected @@ -663,7 +663,7 @@ def test_json_schema_yaml_value(): }, } - result = transform_json_for_preprocessor_validation(json_schema, False) + result = transform_json_for_preprocessor_validation(json_schema) assert result == json_schema_expected From af08c0cc98c07cccd5958c04e621ffc40dc22f5d Mon Sep 17 00:00:00 2001 From: breblanc Date: Tue, 20 May 2025 20:44:33 +0200 Subject: [PATCH 16/24] added one more case --- tested/transform_json.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tested/transform_json.py b/tested/transform_json.py index 9435a319..adf85bd1 100644 --- a/tested/transform_json.py +++ b/tested/transform_json.py @@ -194,7 +194,7 @@ def transform_json_for_preprocessor_validation(data: Any) -> Any: } # Standard creation of the special tag structure for translations and templates. - if "type" in data and data["type"] not in ["boolean", "integer"]: + if "type" in data and data["type"] not in ["boolean", "integer", "number"]: # Adding support for the other tags. if data["type"] in SPECIAL_TYPES: tag = data.pop("type") From 855aa98401046a13e117a43e5d40d752fd91ec22 Mon Sep 17 00:00:00 2001 From: breblanc Date: Tue, 20 May 2025 21:43:38 +0200 Subject: [PATCH 17/24] simplified the code some more --- tested/transform_json.py | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/tested/transform_json.py b/tested/transform_json.py index adf85bd1..d5138aa9 100644 --- a/tested/transform_json.py +++ b/tested/transform_json.py @@ -121,9 +121,7 @@ def make_parameter_type_structure(data: dict) -> dict: } -def make_tag_structure( - data: dict, data_with_inner_translations: Any = None, tag: str = "!natural_language" -) -> dict: +def make_tag_structure(data: dict, tag: str = "!natural_language") -> dict: base = { "type": "object", "required": ["__tag__", "value"], @@ -147,8 +145,6 @@ def make_tag_structure( "type": "object", "additionalProperties": data, } - if data_with_inner_translations is not None: - return {"oneOf": [data_with_inner_translations, base]} return base @@ -200,21 +196,12 @@ def transform_json_for_preprocessor_validation(data: Any) -> Any: tag = data.pop("type") new_data.pop("type") # translations applied to inner part - tag_data_with_inner_translations = make_tag_structure( - new_data, - tag=f"!{tag}", - ) + new_data = make_tag_structure(new_data, tag=f"!{tag}") # translations not applied to inner part - tag_data = make_tag_structure( - data, - tag=f"!{tag}", - ) - return make_tag_structure( - data=tag_data, - data_with_inner_translations=tag_data_with_inner_translations, - ) - - return make_tag_structure(data, new_data) + data = make_tag_structure(data, tag=f"!{tag}") + + result = make_tag_structure(data) + return {"oneOf": [new_data, result]} data = new_data # Flatten the oneOf structures @@ -274,7 +261,12 @@ def transform_json_for_preprocessor_validation(data: Any) -> Any: "$ref" in data and data["$ref"] == "#/subDefinitions/yamlValueOrPythonExpression" ): - data = make_tag_structure(data, data) + data = { + "oneOf": [ + {"$ref": "#/subDefinitions/yamlValueOrPythonExpression"}, + make_tag_structure(data), + ] + } return data if isinstance(data, list): From 478863f09d326af942a1d230c327cd8ee9903d1b Mon Sep 17 00:00:00 2001 From: breblanc Date: Tue, 20 May 2025 21:48:40 +0200 Subject: [PATCH 18/24] simplified the code some more --- tested/transform_json.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tested/transform_json.py b/tested/transform_json.py index d5138aa9..8a7b4ec1 100644 --- a/tested/transform_json.py +++ b/tested/transform_json.py @@ -134,13 +134,13 @@ def make_tag_structure(data: dict, tag: str = "!natural_language") -> dict: }, } - if tag in ["!oracle", "!programming_language", "!expression", "!parameter"]: + if tag != "!natural_language": base["properties"]["value"] = data base["properties"]["value"]["type"] = "object" if tag in ["!expression", "!parameter"]: base["properties"]["value"]["type"] = "string" - elif tag == "!natural_language": + else: base["properties"]["value"] = { "type": "object", "additionalProperties": data, From cf0bbb4b70f823c0deb069a7a090a39107b616ac Mon Sep 17 00:00:00 2001 From: breblanc Date: Wed, 21 May 2025 14:53:37 +0200 Subject: [PATCH 19/24] remove a print --- tested/nat_translation.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tested/nat_translation.py b/tested/nat_translation.py index 964fa395..f466e9f2 100644 --- a/tested/nat_translation.py +++ b/tested/nat_translation.py @@ -181,7 +181,6 @@ def translate_yaml_and_initialize_templates( ) if data: - print(data) # Extra specifications in data will overwrite parts of the template. data = translate_yaml_and_initialize_templates( data, From 555ae6ed986dacd25d5d77de347720f867aa6170 Mon Sep 17 00:00:00 2001 From: breblanc Date: Wed, 21 May 2025 15:20:36 +0200 Subject: [PATCH 20/24] added another check --- tested/nat_translation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tested/nat_translation.py b/tested/nat_translation.py index f466e9f2..097937cf 100644 --- a/tested/nat_translation.py +++ b/tested/nat_translation.py @@ -145,7 +145,7 @@ def translate_yaml_and_initialize_templates( ) elif data["__tag__"] == "!parameter": assert ( - data["value"] in parameters + data["value"] in parameters and inside_templates ), "You are using the !parameter tag outside a template or the specified parameter does not exist." return parameters[data["value"]] From 837b1e6c5678d155016cee4ca3d94b9cadeb6c28 Mon Sep 17 00:00:00 2001 From: breblanc Date: Thu, 22 May 2025 10:34:58 +0200 Subject: [PATCH 21/24] small change --- tested/nat_translation.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tested/nat_translation.py b/tested/nat_translation.py index 097937cf..3d365014 100644 --- a/tested/nat_translation.py +++ b/tested/nat_translation.py @@ -221,7 +221,7 @@ def translate_yaml_and_initialize_templates( for param_item in parameters ] - result = { + return { key: translate_yaml_and_initialize_templates( value, translations, @@ -233,7 +233,6 @@ def translate_yaml_and_initialize_templates( ) for key, value in data.items() } - return result elif isinstance(data, list): result = [] for item in data: From ff9381db680ac9d5445e3b7b50186b143b0f4064 Mon Sep 17 00:00:00 2001 From: breblanc Date: Thu, 22 May 2025 16:56:43 +0200 Subject: [PATCH 22/24] all arguments can now use !parameter --- tested/dsl/multilingual-schema.json | 1070 ++++++++++------- tested/dsl/schema-strict-nat-translation.json | 1045 ++++++++++------ tested/transform_json.py | 11 +- tests/test_json_schema_transformer.py | 29 +- 4 files changed, 1351 insertions(+), 804 deletions(-) diff --git a/tested/dsl/multilingual-schema.json b/tested/dsl/multilingual-schema.json index 06080a1c..f5dcf721 100644 --- a/tested/dsl/multilingual-schema.json +++ b/tested/dsl/multilingual-schema.json @@ -1512,132 +1512,170 @@ ] }, "arguments": { - "oneOf": [ + "anyOf": [ { - "description": "Array of program call arguments", - "type": "array", - "items": { - "anyOf": [ - { - "oneOf": [ + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ { - "description": "The key of the parameter.", - "type": "string" + "required": [ + "description" + ] }, { - "type": "object", - "additionalProperties": { - "description": "The key of the parameter.", - "type": "string" - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + { + "oneOf": [ + { + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ + { + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" }, - { - "required": [ - "value" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + { + "oneOf": [ + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + }, + { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "number", + "integer", + "boolean" ] }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } + } + ] } ] - }, - { - "oneOf": [ - { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - }, - { - "type": "object", - "additionalProperties": { + } + }, + { + "type": "object", + "additionalProperties": { + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { "type": [ "string", "number", "integer", "boolean" ] - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] } - } - ] - } - ] - } - }, - { - "type": "object", - "additionalProperties": { - "description": "Array of program call arguments", - "type": "array", - "items": { - "anyOf": [ - { - "description": "The key of the parameter.", - "type": "string" - }, - { - "type": [ - "string", - "number", - "integer", - "boolean" ] } - ] - } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } + } + ] } ] }, @@ -2086,25 +2124,33 @@ ] }, "arguments": { - "description": "Array of program call arguments", - "type": "array", - "items": { - "anyOf": [ - { - "description": "The key of the parameter.", - "type": "string" - }, - { - "type": [ - "string", - "number", - "integer", - "boolean" - ] - } - ] - } - }, + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + ] + } + } + ] + }, "statement": { "description": "The statement to evaluate.", "$ref": "#/subDefinitions/expressionOrStatement" @@ -3325,71 +3371,109 @@ ] }, "arguments": { - "oneOf": [ + "anyOf": [ { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "oneOf": [ - { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" }, - { - "type": "object", - "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] } - ] - } + } + ] }, { - "type": "object", - "additionalProperties": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" + "oneOf": [ + { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } ] + } + }, + { + "type": "object", + "additionalProperties": { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } + } + ] } ] }, @@ -3462,11 +3546,19 @@ "default": "evaluate" }, "arguments": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + ] }, "languages": { "type": "array", @@ -3791,71 +3883,109 @@ ] }, "arguments": { - "oneOf": [ + "anyOf": [ { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "oneOf": [ - { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" }, - { - "type": "object", - "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] } - ] - } - }, - { - "type": "object", - "additionalProperties": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" + ] + }, + { + "oneOf": [ + { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } ] + } + }, + { + "type": "object", + "additionalProperties": { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } + } + ] } ] }, @@ -3934,11 +4064,19 @@ "default": "evaluate" }, "arguments": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + ] }, "languages": { "type": "array", @@ -4198,71 +4336,109 @@ ] }, "arguments": { - "oneOf": [ + "anyOf": [ { - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" }, - { - "type": "object", - "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] - } + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] } - ] - } + } + ] }, { - "type": "object", - "additionalProperties": { - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" + "oneOf": [ + { + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } ] + } + }, + { + "type": "object", + "additionalProperties": { + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } + } + ] } ] }, @@ -4335,11 +4511,19 @@ "default": "evaluate" }, "arguments": { - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + ] }, "languages": { "type": "array", @@ -4562,124 +4746,162 @@ ] }, "arguments": { - "oneOf": [ + "anyOf": [ { - "minProperties": 1, - "description": "Language mapping of oracle arguments.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, - "items": { - "oneOf": [ - { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "oneOf": [ - { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." - }, - { - "type": "object", - "additionalProperties": { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] + "oneOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "object", + "additionalProperties": { + "description": "The key of the parameter.", + "type": "string" + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] + } + } + ] + }, + { + "oneOf": [ + { + "minProperties": 1, + "description": "Language mapping of oracle arguments.", + "type": "object", + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "oneOf": [ + { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "oneOf": [ + { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." + }, + { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] + } + ] + } + }, + { + "type": "object", + "additionalProperties": { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." } + }, + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } + ] } - ] - } - }, - { + } + ] + } + }, + { + "type": "object", + "additionalProperties": { + "minProperties": 1, + "description": "Language mapping of oracle arguments.", "type": "object", - "additionalProperties": { + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { "type": "array", "description": "List of YAML (or tagged expression) values to use as arguments to the function.", "items": { "type": "string", "description": "A language-specific literal, which will be used verbatim." } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] - }, - { - "required": [ - "types" - ] - } - ] } - } - ] - } - }, - { - "type": "object", - "additionalProperties": { - "minProperties": 1, - "description": "Language mapping of oracle arguments.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, - "items": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." - } - } - }, - "not": { - "anyOf": [ - { - "required": [ - "description" - ] - }, - { - "required": [ - "value" - ] }, - { - "required": [ - "types" + "not": { + "anyOf": [ + { + "required": [ + "description" + ] + }, + { + "required": [ + "value" + ] + }, + { + "required": [ + "types" + ] + } ] } - ] - } + } + ] } ] }, @@ -4756,20 +4978,28 @@ } }, "arguments": { - "minProperties": 1, - "description": "Language mapping of oracle arguments.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, - "items": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "minProperties": 1, + "description": "Language mapping of oracle arguments.", + "type": "object", + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." + } + } } - } + ] }, "value": { "$ref": "#/subDefinitions/yamlValueOrPythonExpression" diff --git a/tested/dsl/schema-strict-nat-translation.json b/tested/dsl/schema-strict-nat-translation.json index a3adef38..470a7408 100644 --- a/tested/dsl/schema-strict-nat-translation.json +++ b/tested/dsl/schema-strict-nat-translation.json @@ -1456,15 +1456,42 @@ ] }, "arguments": { - "oneOf": [ + "anyOf": [ { - "description": "Array of program call arguments", - "type": "array", - "items": { - "anyOf": [ - { - "oneOf": [ - { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { "type": "object", "required": [ "__tag__", @@ -1481,120 +1508,154 @@ "type": "string" } } - }, + } + } + } + } + ] + }, + { + "oneOf": [ + { + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } }, - "value": { + { "type": "object", - "additionalProperties": { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!parameter" - }, - "value": { - "description": "The key of the parameter.", - "type": "string" + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } } } } } - } - } - ] - }, - { - "oneOf": [ - { - "type": [ - "string", - "number", - "integer", - "boolean" ] }, { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "oneOf": [ + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] }, - "value": { + { "type": "object", - "additionalProperties": { - "type": [ - "string", - "number", - "integer", - "boolean" - ] + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + } } } - } + ] } ] } - ] - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" }, - "value": { + { "type": "object", - "additionalProperties": { - "description": "Array of program call arguments", - "type": "array", - "items": { - "anyOf": [ - { - "description": "The key of the parameter.", - "type": "string" - }, - { - "type": [ - "string", - "number", - "integer", - "boolean" + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } ] } - ] + } } } } - } + ] } ] }, @@ -2033,24 +2094,32 @@ ] }, "arguments": { - "description": "Array of program call arguments", - "type": "array", - "items": { - "anyOf": [ - { - "description": "The key of the parameter.", - "type": "string" - }, - { - "type": [ - "string", - "number", - "integer", - "boolean" - ] + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "Array of program call arguments", + "type": "array", + "items": { + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": [ + "string", + "number", + "integer", + "boolean" + ] + } + ] } - ] - } + } + ] }, "statement": { "description": "The statement to evaluate.", @@ -3378,61 +3447,122 @@ ] }, "arguments": { - "oneOf": [ + "anyOf": [ { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "oneOf": [ - { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { "type": "object", - "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } } } } } - ] - } + } + ] }, { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "oneOf": [ + { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + } + } + ] + } }, - "value": { + { "type": "object", - "additionalProperties": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } } } } - } + ] } ] }, @@ -3512,11 +3642,19 @@ "default": "evaluate" }, "arguments": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + ] }, "languages": { "type": "array", @@ -3789,61 +3927,122 @@ ] }, "arguments": { - "oneOf": [ + "anyOf": [ { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "oneOf": [ - { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { "type": "object", - "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } } } } } - ] - } + } + ] }, { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "oneOf": [ + { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + } + } + ] + } }, - "value": { + { "type": "object", - "additionalProperties": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } } } } - } + ] } ] }, @@ -3929,11 +4128,19 @@ "default": "evaluate" }, "arguments": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + ] }, "languages": { "type": "array", @@ -4186,61 +4393,122 @@ ] }, "arguments": { - "oneOf": [ + "anyOf": [ { - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "type": "array", - "items": { - "oneOf": [ - { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { "type": "object", - "additionalProperties": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } } } } } - ] - } + } + ] }, { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "oneOf": [ + { + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + } + } + ] + } }, - "value": { + { "type": "object", - "additionalProperties": { - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } } } } - } + ] } ] }, @@ -4334,11 +4602,19 @@ "default": "evaluate" }, "arguments": { - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "type": "array", - "items": { - "$ref": "#/subDefinitions/yamlValueOrPythonExpression" - } + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "type": "array", + "items": { + "$ref": "#/subDefinitions/yamlValueOrPythonExpression" + } + } + ] }, "languages": { "type": "array", @@ -4538,64 +4814,158 @@ ] }, "arguments": { - "oneOf": [ + "anyOf": [ { - "minProperties": 1, - "description": "Language mapping of oracle arguments.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, - "items": { - "oneOf": [ - { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "oneOf": [ - { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { + "oneOf": [ + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!parameter" + }, + "value": { + "description": "The key of the parameter.", + "type": "string" + } + } + } + } + } + } + ] + }, + { + "oneOf": [ + { + "minProperties": 1, + "description": "Language mapping of oracle arguments.", + "type": "object", + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "oneOf": [ + { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "oneOf": [ + { "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" + "description": "A language-specific literal, which will be used verbatim." }, - "value": { + { "type": "object", - "additionalProperties": { + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." + } + } + } + } + ] + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { "type": "string", "description": "A language-specific literal, which will be used verbatim." } } } } - ] - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { + } + ] + } + }, + { + "type": "object", + "required": [ + "__tag__", + "value" + ], + "properties": { + "__tag__": { + "type": "string", + "description": "The tag used in the yaml", + "const": "!natural_language" + }, + "value": { + "type": "object", + "additionalProperties": { + "minProperties": 1, + "description": "Language mapping of oracle arguments.", "type": "object", - "additionalProperties": { + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { "type": "array", "description": "List of YAML (or tagged expression) values to use as arguments to the function.", "items": { @@ -4606,41 +4976,8 @@ } } } - ] - } - }, - { - "type": "object", - "required": [ - "__tag__", - "value" - ], - "properties": { - "__tag__": { - "type": "string", - "description": "The tag used in the yaml", - "const": "!natural_language" - }, - "value": { - "type": "object", - "additionalProperties": { - "minProperties": 1, - "description": "Language mapping of oracle arguments.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, - "items": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." - } - } - } } - } + ] } ] }, @@ -4738,20 +5075,28 @@ } }, "arguments": { - "minProperties": 1, - "description": "Language mapping of oracle arguments.", - "type": "object", - "propertyNames": { - "$ref": "#/subDefinitions/programmingLanguage" - }, - "items": { - "type": "array", - "description": "List of YAML (or tagged expression) values to use as arguments to the function.", - "items": { - "type": "string", - "description": "A language-specific literal, which will be used verbatim." + "anyOf": [ + { + "description": "The key of the parameter.", + "type": "string" + }, + { + "minProperties": 1, + "description": "Language mapping of oracle arguments.", + "type": "object", + "propertyNames": { + "$ref": "#/subDefinitions/programmingLanguage" + }, + "items": { + "type": "array", + "description": "List of YAML (or tagged expression) values to use as arguments to the function.", + "items": { + "type": "string", + "description": "A language-specific literal, which will be used verbatim." + } + } } - } + ] }, "value": { "$ref": "#/subDefinitions/yamlValueOrPythonExpression" diff --git a/tested/transform_json.py b/tested/transform_json.py index 8a7b4ec1..064f4e20 100644 --- a/tested/transform_json.py +++ b/tested/transform_json.py @@ -287,13 +287,7 @@ def add_templates(data: dict) -> dict: testcase = data["definitions"].get("testcase", {}) if testcase: assert "properties" in testcase - testcase_without_templates = copy.deepcopy(testcase) - testcase_without_templates["properties"]["arguments"] = ( - make_parameter_type_structure( - testcase_without_templates["properties"]["arguments"] - ) - ) - data["definitions"]["testcase_without_templates"] = testcase_without_templates + data["definitions"]["testcase_without_templates"] = copy.deepcopy(testcase) testcase["properties"]["template"] = { "type": "string", @@ -349,6 +343,9 @@ def add_parameter_type(data: Any) -> Any: ) or type_value in ["boolean", "integer", "number"]: # Adding support for "!parameter" tag. return make_parameter_type_structure(data) + + if "arguments" in data: + data["arguments"] = make_parameter_type_structure(data["arguments"]) return {k: add_parameter_type(v) for k, v in data.items()} if isinstance(data, list): diff --git a/tests/test_json_schema_transformer.py b/tests/test_json_schema_transformer.py index 8130e5dd..82560302 100644 --- a/tests/test_json_schema_transformer.py +++ b/tests/test_json_schema_transformer.py @@ -518,12 +518,7 @@ def test_add_templates(): "expression": { "description": "The expression to evaluate.", "$ref": "#/subDefinitions/expressionOrStatement", - }, - "arguments": { - "description": "Array of program call arguments", - "type": "array", - "items": {"type": ["string", "number", "integer", "boolean"]}, - }, + } } } } @@ -541,11 +536,6 @@ def test_add_templates(): "description": "The expression to evaluate.", "$ref": "#/subDefinitions/expressionOrStatement", }, - "arguments": { - "description": "Array of program call arguments", - "type": "array", - "items": {"type": ["string", "number", "integer", "boolean"]}, - }, "template": { "type": "string", "description": "Name of the template to insert.", @@ -589,22 +579,7 @@ def test_add_templates(): "expression": { "description": "The expression to evaluate.", "$ref": "#/subDefinitions/expressionOrStatement", - }, - "arguments": { - "anyOf": [ - { - "type": "parameter", - "description": "The key of the parameter.", - }, - { - "description": "Array of program call arguments", - "type": "array", - "items": { - "type": ["string", "number", "integer", "boolean"] - }, - }, - ] - }, + } } }, } From 650fe1fd333ff927bd2d86f60ce4c740b777c8ac Mon Sep 17 00:00:00 2001 From: breblanc Date: Thu, 22 May 2025 17:02:24 +0200 Subject: [PATCH 23/24] fixed linting --- tests/test_json_schema_transformer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_json_schema_transformer.py b/tests/test_json_schema_transformer.py index 82560302..244fb014 100644 --- a/tests/test_json_schema_transformer.py +++ b/tests/test_json_schema_transformer.py @@ -518,7 +518,7 @@ def test_add_templates(): "expression": { "description": "The expression to evaluate.", "$ref": "#/subDefinitions/expressionOrStatement", - } + }, } } } @@ -579,7 +579,7 @@ def test_add_templates(): "expression": { "description": "The expression to evaluate.", "$ref": "#/subDefinitions/expressionOrStatement", - } + }, } }, } From 39e808a9ab8275117c11b38cb70cee73797a6e80 Mon Sep 17 00:00:00 2001 From: breblanc Date: Sun, 1 Jun 2025 19:00:23 +0200 Subject: [PATCH 24/24] made small comment change --- tested/transform_json.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tested/transform_json.py b/tested/transform_json.py index 064f4e20..a175e69a 100644 --- a/tested/transform_json.py +++ b/tested/transform_json.py @@ -302,7 +302,7 @@ def add_templates(data: dict) -> dict: } testcase["properties"]["repeat"] = { "type": "object", - "description": "A certain loop that will generate test cases with the given parameters and template.", + "description": "A loop to generate test cases with the given parameters and template.", "required": ["template", "parameters"], "properties": { "template": {