forked from abravalheri/validate-pyproject
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_api.py
143 lines (112 loc) · 4.9 KB
/
test_api.py
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
from collections.abc import Mapping
from functools import partial, wraps
import fastjsonschema as FJS
import pytest
from validate_pyproject import _tomllib as tomllib
from validate_pyproject import api, errors, plugins, types
PYPA_SPECS = "https://packaging.python.org/en/latest/specifications"
def test_load():
spec = api.load("pyproject_toml")
assert isinstance(spec, Mapping)
assert spec["$id"] == f"{PYPA_SPECS}/declaring-build-dependencies/"
spec = api.load("project_metadata")
assert spec["$id"] == f"{PYPA_SPECS}/declaring-project-metadata/"
def test_load_plugin():
spec = api.load_builtin_plugin("distutils")
assert spec["$id"].startswith("https://setuptools.pypa.io")
assert "deprecated/distutils" in spec["$id"]
spec = api.load_builtin_plugin("setuptools")
assert spec["$id"].startswith("https://setuptools.pypa.io")
assert "pyproject" in spec["$id"]
class TestRegistry:
def test_with_plugins(self):
plg = plugins.list_plugins_from_entry_points()
registry = api.SchemaRegistry(plg)
main_schema = registry[registry.main]
project = main_schema["properties"]["project"]
assert project["$ref"] == f"{PYPA_SPECS}/declaring-project-metadata/"
tool = main_schema["properties"]["tool"]
assert "setuptools" in tool["properties"]
assert "$ref" in tool["properties"]["setuptools"]
def fake_plugin(self, name, schema_version=7, end="#"):
schema = {
"$id": f"https://example.com/{name}.schema.json",
"$schema": f"http://json-schema.org/draft-{schema_version:02d}/schema{end}",
"type": "object",
}
return types.Schema(schema)
@pytest.mark.parametrize("end", ["", "#"], ids=["no#", "with#"])
def test_schema_ending(self, end):
fn = wraps(self.fake_plugin)(partial(self.fake_plugin, end=end))
plg = plugins.PluginWrapper("plugin", fn)
registry = api.SchemaRegistry([plg])
main_schema = registry[registry.main]
assert main_schema["$schema"] == "http://json-schema.org/draft-07/schema#"
def test_incompatible_versions(self):
fn = wraps(self.fake_plugin)(partial(self.fake_plugin, schema_version=8))
plg = plugins.PluginWrapper("plugin", fn)
with pytest.raises(errors.InvalidSchemaVersion):
api.SchemaRegistry([plg])
def test_duplicated_id(self):
plg = [plugins.PluginWrapper("plg", self.fake_plugin) for _ in range(2)]
with pytest.raises(errors.SchemaWithDuplicatedId):
api.SchemaRegistry(plg)
def test_missing_id(self):
def _fake_plugin(name):
plg = dict(self.fake_plugin(name))
del plg["$id"]
return types.Schema(plg)
plg = plugins.PluginWrapper("plugin", _fake_plugin)
with pytest.raises(errors.SchemaMissingId):
api.SchemaRegistry([plg])
class TestValidator:
example_toml = """\
[project]
name = "myproj"
version = "0"
[tool.setuptools]
zip-safe = false
packages = {find = {}}
"""
@property
def valid_example(self):
return tomllib.loads(self.example_toml)
@property
def invalid_example(self):
example = self.valid_example
example["tool"]["setuptools"]["zip-safe"] = {"hello": "world"}
return example
def test_valid(self):
validator = api.Validator()
assert validator(self.valid_example) is not None
def test_invalid(self):
validator = api.Validator()
with pytest.raises(FJS.JsonSchemaValueException):
validator(self.invalid_example)
# ---
def plugin(self, tool):
plg = plugins.list_plugins_from_entry_points(filtering=lambda e: e.name == tool)
return plg[0]
TOOLS = ("distutils", "setuptools")
@pytest.mark.parametrize("tool, other_tool", zip(TOOLS, reversed(TOOLS)))
def test_plugin_not_enabled(self, tool, other_tool):
plg = self.plugin(tool)
validator = api.Validator([plg])
registry = validator.registry
main_schema = registry[registry.main]
assert tool in main_schema["properties"]["tool"]["properties"]
assert other_tool not in main_schema["properties"]["tool"]["properties"]
tool_properties = main_schema["properties"]["tool"]["properties"]
assert tool_properties[tool]["$ref"] == plg.schema["$id"]
def test_invalid_but_plugin_not_enabled(self):
# When the plugin is not enabled, the validator should ignore the tool
validator = api.Validator([self.plugin("distutils")])
try:
assert validator(self.invalid_example) is not None
except Exception:
registry = validator.registry
main_schema = registry[registry.main]
assert "setuptools" not in main_schema["properties"]["tool"]["properties"]
import json
assert "setuptools" not in json.dumps(main_schema)
raise