Skip to content

Commit

Permalink
Allow YAML anchors and merge keys
Browse files Browse the repository at this point in the history
  • Loading branch information
niknetniko committed Sep 21, 2023
1 parent 24d4786 commit f079198
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 111 deletions.
38 changes: 8 additions & 30 deletions tested/dsl/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@
"type" : "object",
"unevaluatedProperties" : false,
"properties" : {
"config" : {
"$ref" : "#/$defs/globalConfig",
"description" : "Configuration applicable to the whole test suite."
},
"files" : {
"type" : "array",
"items" : {
Expand Down Expand Up @@ -71,6 +67,10 @@
}
],
"default" : "tested"
},
"definitions": {
"description": "Define hashes to use elsewhere.",
"type": "object"
}
},
"oneOf" : [
Expand All @@ -90,10 +90,6 @@
"type" : "object",
"unevaluatedProperties" : false,
"properties" : {
"config" : {
"$ref" : "#/$defs/globalConfig",
"description" : "Configuration applicable to this unit/tab"
},
"files" : {
"type" : "array",
"items" : {
Expand Down Expand Up @@ -123,6 +119,10 @@
},
"testcases" : {
"$ref" : "#/$defs/_scriptList"
},
"definitions": {
"description": "Define hashes to use elsewhere.",
"type": "object"
}
},
"oneOf" : [
Expand Down Expand Up @@ -166,10 +166,6 @@
"type" : "object",
"unevaluatedProperties" : false,
"properties" : {
"config" : {
"$ref" : "#/$defs/globalConfig",
"description" : "Configuration settings at context level"
},
"files" : {
"type" : "array",
"items" : {
Expand Down Expand Up @@ -280,10 +276,6 @@
"description" : "Expected output at stdout",
"$ref" : "#/$defs/textOutputChannel"
},
"config" : {
"$ref" : "#/$defs/globalConfig",
"description" : "Configuration settings at testcase level"
},
"exit_code" : {
"type" : "integer",
"description" : "Expected exit code for the run"
Expand Down Expand Up @@ -494,20 +486,6 @@
}
}
},
"globalConfig" : {
"type" : "object",
"description" : "Global configuration properties",
"minProperties" : 1,
"unevaluatedProperties" : false,
"properties" : {
"stdout" : {
"$ref" : "#/$defs/textConfigurationOptions"
},
"stderr" : {
"$ref" : "#/$defs/textConfigurationOptions"
}
}
},
"file" : {
"type" : "object",
"description" : "Path to a file for input.",
Expand Down
37 changes: 8 additions & 29 deletions tested/dsl/schema_draft7.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@
"_rootObject" : {
"type" : "object",
"properties" : {
"config" : {
"$ref" : "#/definitions/globalConfig",
"description" : "Configuration applicable to the whole test suite."
},
"files" : {
"type" : "array",
"items" : {
Expand Down Expand Up @@ -70,6 +66,10 @@
}
],
"default" : "tested"
},
"definitions": {
"description": "Define hashes to use elsewhere.",
"type": "object"
}
},
"oneOf" : [
Expand All @@ -88,10 +88,6 @@
"unit" : {
"type" : "object",
"properties" : {
"config" : {
"$ref" : "#/definitions/globalConfig",
"description" : "Configuration applicable to this unit/tab"
},
"files" : {
"type" : "array",
"items" : {
Expand Down Expand Up @@ -121,6 +117,10 @@
},
"testcases" : {
"$ref" : "#/definitions/_scriptList"
},
"definitions": {
"description": "Define hashes to use elsewhere.",
"type": "object"
}
},
"oneOf" : [
Expand Down Expand Up @@ -163,10 +163,6 @@
"testcase" : {
"type" : "object",
"properties" : {
"config" : {
"$ref" : "#/definitions/globalConfig",
"description" : "Configuration settings at context level"
},
"files" : {
"type" : "array",
"items" : {
Expand Down Expand Up @@ -276,10 +272,6 @@
"description" : "Expected output at stdout",
"$ref" : "#/definitions/textOutputChannel"
},
"config" : {
"$ref" : "#/definitions/globalConfig",
"description" : "Configuration settings at testcase level"
},
"exitCode" : {
"type" : "integer",
"description" : "Expected exit code for the run"
Expand Down Expand Up @@ -487,19 +479,6 @@
}
}
},
"globalConfig" : {
"type" : "object",
"description" : "Global configuration properties",
"minProperties" : 1,
"properties" : {
"stdout" : {
"$ref" : "#/definitions/textConfigurationOptions"
},
"stderr" : {
"$ref" : "#/definitions/textConfigurationOptions"
}
}
},
"file" : {
"type" : "object",
"description" : "Path to a file for input.",
Expand Down
45 changes: 10 additions & 35 deletions tested/dsl/translate_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
TextOutputChannel,
ValueOutputChannel,
)
from tested.utils import get_args, recursive_dict_merge
from tested.utils import get_args

OptionDict = dict[str, int | bool]
YamlDict = dict[str, "YamlObject"]
Expand Down Expand Up @@ -136,48 +136,28 @@ class DslContext:
Carries context in each level.
"""

config: dict
files: list[FileUrl]
language: SupportedLanguage | Literal["tested"] = "tested"

def deepen_context(
self,
new_level: YamlDict | None,
include_config=True,
include_files=True,
merge_with: str | None = None,
) -> "DslContext":
def deepen_context(self, new_level: YamlDict | None) -> "DslContext":
"""
Merge certain fields of the new object with the current context, resulting
in a new context for the new level.
:param new_level: The new object from the DSL to get information from.
:param include_config: If config should be considered.
:param include_files: If files should be considered.
:param merge_with: If merging configs, the key of the subsection to update.
:return: A new context.
"""
if new_level is None:
return self

new_config = self.config
if include_config and "config" in new_level:
assert isinstance(new_level["config"], dict)
if merge_with:
original_config = self.config.get(merge_with, {})
else:
original_config = self.config

new_config = recursive_dict_merge(original_config, new_level["config"])

new_files = self.files
if include_files and "files" in new_level:
if "files" in new_level:
assert isinstance(new_level["files"], list)
additional_files = {_convert_file(f) for f in new_level["files"]}
new_files = list(set(self.files) | additional_files)

return evolve(self, config=new_config, files=new_files)
return evolve(self, files=new_files)


def convert_validation_error_to_group(
Expand Down Expand Up @@ -317,20 +297,15 @@ def _convert_custom_check_oracle(stream: dict) -> CustomCheckOracle:
)


def _convert_text_output_channel(
stream: YamlObject, context: DslContext, config_name: str
) -> TextOutputChannel:
def _convert_text_output_channel(stream: YamlObject) -> TextOutputChannel:
if isinstance(stream, str):
data = stream
config = context.config.get(config_name, {})
return TextOutputChannel(data=data, oracle=GenericTextOracle(options=config))
return TextOutputChannel(data=data, oracle=GenericTextOracle())
else:
assert isinstance(stream, dict)
data = str(stream["data"])
if "oracle" not in stream or stream["oracle"] == "builtin":
config = context.deepen_context(
stream, include_files=False, merge_with=config_name
).config
config = cast(dict, stream.get("config", {}))
return TextOutputChannel(
data=data, oracle=GenericTextOracle(options=config)
)
Expand Down Expand Up @@ -430,9 +405,9 @@ def _convert_testcase(testcase: YamlDict, context: DslContext) -> Testcase:
output.result = return_channel

if (stdout := testcase.get("stdout")) is not None:
output.stdout = _convert_text_output_channel(stdout, context, "stdout")
output.stdout = _convert_text_output_channel(stdout)
if (stderr := testcase.get("stderr")) is not None:
output.stderr = _convert_text_output_channel(stderr, context, "stderr")
output.stderr = _convert_text_output_channel(stderr)
if (exception := testcase.get("exception")) is not None:
if isinstance(exception, str):
message = exception
Expand Down Expand Up @@ -525,7 +500,7 @@ def _convert_dsl(dsl_object: YamlObject) -> Suite:
:param dsl_object: A validated DSL test suite object.
:return: A full test suite.
"""
context = DslContext(config={}, files=[])
context = DslContext(files=[])
if isinstance(dsl_object, list):
namespace = None
tab_list = dsl_object
Expand Down
43 changes: 26 additions & 17 deletions tests/test_dsl_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,29 +170,33 @@ def test_parse_ctx_exception_types():
def test_parse_ctx_with_config():
yaml_str = """
- tab: "Config ctx"
config:
stdout:
definitions:
stdout: &stdout
tryFloatingPoint: true
applyRounding: true
roundTo: 2
stderr:
stderr: &stderr
ignoreWhitespace: true
caseInsensitive: false
testcases:
- arguments: [ '-a', '2.125', '1.212' ]
stdout: "3.34"
stdout:
data: "3.34"
config: *stdout
- arguments: [ '-a', '2.125', '1.212' ]
stdout:
data: "3.337"
config:
<<: *stdout
roundTo: 3
- config:
stdout:
roundTo: 1
arguments: [ '-a', '2.125', '1.212' ]
stdout: "3.3"
- arguments: [ '-a', '2.125', '1.212' ]
stdout:
config: *stdout
data: "3.3"
- arguments: [ '-e' ]
stderr: " Fail "
stderr:
config: *stderr
data: " Fail "
"""
args = ["-a", "2.125", "1.212"]
json_str = translate_to_test_suite(yaml_str)
Expand Down Expand Up @@ -234,7 +238,7 @@ def test_parse_ctx_with_config():
assert len(options) == 3
assert options["tryFloatingPoint"]
assert options["applyRounding"]
assert options["roundTo"] == 1
assert options["roundTo"] == 2

stderr = tc3.output.stderr
assert stderr.data == " Fail "
Expand All @@ -247,20 +251,23 @@ def test_parse_ctx_with_config():
def test_statements():
yaml_str = """
- tab: "Statements"
config:
stdout:
definitions:
stdout: &stdout
ignoreWhitespace: true
contexts:
- testcases:
- statement: 'safe: Safe = Safe("Ignore whitespace")'
stdout: "New safe"
stdout:
data: "New safe"
config: *stdout
- expression: 'safe.content()'
return: !v "Ignore whitespace"
- testcases:
- statement: 'safe: Safe = Safe(uint8(5))'
stdout:
data: "New safe"
config:
<<: *stdout
ignoreWhitespace: false
- expression: 'safe.content()'
return: 'uint8(5)'
Expand Down Expand Up @@ -419,8 +426,8 @@ def test_statement_with_yaml_dict():

def test_global_config_trickles_down():
yaml_str = """
config:
stdout:
definitions:
config: &stdout
applyRounding: true
roundTo: 63
tryFloatingPoint: true
Expand All @@ -432,7 +439,9 @@ def test_global_config_trickles_down():
testcases:
- arguments: [ "--arg", "argument" ]
stdin: "Input string"
stdout: "Output string"
stdout:
data: "Output string"
config: *stdout
stderr: "Error string"
exit_code: 1
"""
Expand Down

0 comments on commit f079198

Please sign in to comment.