File: test_toml_spec_tests.py

package info (click to toggle)
python-tomlkit 0.13.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,096 kB
  • sloc: python: 5,985; makefile: 20; sh: 5
file content (111 lines) | stat: -rw-r--r-- 3,457 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
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())