blob: fdfb735bc61264e440f0ce586c0160f2a8b6bc96 [file] [log] [blame]
import json
import os
import re
import pytest
import yaml
from tomlkit import parse
from tomlkit._compat import decode
from tomlkit._utils import parse_rfc3339
from tomlkit.exceptions import TOMLKitError
IGNORED_TESTS = []
# The following tests trigger a RecursionError
IGNORED_TESTS += ["qa-array-inline-nested-1000", "qa-table-inline-nested-1000"]
# The following tests don't work due to time microseconds precision of the tests
IGNORED_TESTS += ["spec-date-time-6", "spec-date-time-local-2", "spec-time-2"]
# The following tests don't work due to nan always comparing to False
IGNORED_TESTS += ["spec-float-13", "spec-float-14", "spec-float-15"]
# The following tests don't work due to issues with th epyyaml library
IGNORED_TESTS += ["spec-key-value-pair-9"]
SPEC_TEST_DIR = os.path.join(os.path.dirname(__file__), "toml-spec-tests")
VALID_TESTS = sorted(
os.path.basename(f).rsplit(".", 1)[0]
for f in os.listdir(os.path.join(SPEC_TEST_DIR, "values"))
if os.path.basename(f).rsplit(".", 1)[0] not in IGNORED_TESTS
)
ERROR_TESTS = sorted(
os.path.basename(f).rsplit(".", 1)[0]
for f in os.listdir(os.path.join(SPEC_TEST_DIR, "errors"))
if os.path.basename(f).rsplit(".", 1)[0] not in IGNORED_TESTS
)
def to_bool(s):
assert s in ["true", "false"]
return s == "true"
stypes = {
"string": str,
"bool": to_bool,
"integer": int,
"float": float,
"datetime": parse_rfc3339,
"datetime-local": parse_rfc3339,
"date": parse_rfc3339,
"time": parse_rfc3339,
}
loader = yaml.SafeLoader
loader.add_implicit_resolver(
"tag:yaml.org,2002:float",
re.compile(
"""^(?:
[-+]?(?:[0-9][0-9_]*)\\.[0-9_]*(?:[eE][-+]?[0-9]+)?
|[-+]?(?:[0-9][0-9_]*)(?:[eE][-+]?[0-9]+)
|\\.[0-9_]+(?:[eE][-+][0-9]+)?
|[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*
|[-+]?\\.(?:inf|Inf|INF)
|\\.(?:nan|NaN|NAN))$""",
re.X,
),
list("-+0123456789."),
)
def untag(value):
if isinstance(value, list):
return [untag(i) for i in value]
elif "type" in value and "value" in value and len(value) == 2:
if value["type"] in stypes:
val = decode(value["value"])
return stypes[value["type"]](val)
elif value["type"] == "array":
return [untag(i) for i in value["value"]]
else:
raise Exception(f'Unsupported type {value["type"]}')
else:
return {k: untag(v) for k, v in value.items()}
@pytest.mark.parametrize("test", VALID_TESTS)
def test_valid_decode(test):
toml_file = os.path.join(SPEC_TEST_DIR, "values", test + ".toml")
yaml_file = os.path.join(SPEC_TEST_DIR, "values", test + ".yaml")
with open(toml_file, encoding="utf-8") as f:
toml_content = f.read()
toml_val = parse(toml_content)
if os.path.exists(yaml_file):
with open(yaml_file, encoding="utf-8") as f:
yaml_val = yaml.load(f.read(), Loader=loader)
else:
with open(
os.path.join(SPEC_TEST_DIR, "values", test + ".json"), encoding="utf-8"
) as f:
yaml_val = untag(json.loads(f.read()))
assert toml_val == yaml_val
assert toml_val.as_string() == toml_content
@pytest.mark.parametrize("test", ERROR_TESTS)
def test_invalid_decode(test):
toml_file = os.path.join(SPEC_TEST_DIR, "errors", test + ".toml")
with pytest.raises(TOMLKitError), open(toml_file, encoding="utf-8") as f:
parse(f.read())