Coverage for tests/test_generation/test_validation.py: 100%
82 statements
« prev ^ index » next coverage.py v7.2.7, created at 2024-08-27 18:25 +0000
« prev ^ index » next coverage.py v7.2.7, created at 2024-08-27 18:25 +0000
1import re
2import subprocess
4import pytest
6from prisma.utils import temp_env_update
8from ..utils import Testdir
11def _remove_known_warnings(output: str) -> str:
12 # as we run generation under coverage we need to remove any warnings
13 # for example, coverage.py will warn that the tests module was not imported
14 output = re.sub(r'.*prisma:GeneratorProcess .* CoverageWarning:.*', '', output)
15 output = re.sub(r'.*prisma:GeneratorProcess .* was never imported.*', '', output)
17 # unknown why this is logged but it doesn't seem to effect anything
18 output = re.sub(
19 r'.*prisma:GeneratorProcess child exited with code null.*',
20 '',
21 output,
22 )
24 return output
27def assert_no_generator_output(output: str) -> None:
28 assert 'prisma:GeneratorProcess' not in _remove_known_warnings(output)
31def test_model_name_python_keyword(testdir: Testdir) -> None:
32 """Model name shadowing a python keyword is not allowed"""
33 schema = (
34 testdir.SCHEMA_HEADER
35 + """
36 model from {{
37 id String @id
38 name String
39 }}
40 """
41 )
42 with pytest.raises(subprocess.CalledProcessError) as exc:
43 testdir.generate(schema=schema)
45 assert 'Model name "from" shadows a Python keyword; use a different model name with \'@@map("from")\'' in str(
46 exc.value.output, 'utf-8'
47 )
50def test_model_name_lowercase_python_keyword(testdir: Testdir) -> None:
51 """Model name that when transformed to lowercase a python keyword is not allowed"""
52 schema = (
53 testdir.SCHEMA_HEADER
54 + """
55 model Class {{
56 id String @id
57 name String
58 }}
59 """
60 )
61 with pytest.raises(subprocess.CalledProcessError) as exc:
62 testdir.generate(schema=schema)
64 assert (
65 'Model name "Class" results in a client property that shadows a Python keyword; use a different model name with \'@@map("Class")\''
66 in str(exc.value.output, 'utf-8')
67 )
70def test_field_name_basemodel_attribute(testdir: Testdir) -> None:
71 """Field name shadowing a basemodel attribute is not allowed"""
72 schema = (
73 testdir.SCHEMA_HEADER
74 + """
75 model User {{
76 id String @id
77 json String
78 }}
79 """
80 )
81 with pytest.raises(subprocess.CalledProcessError) as exc:
82 testdir.generate(schema=schema)
84 assert (
85 'Field name "json" shadows a BaseModel attribute; '
86 'use a different field name with \'@map("json")\'' in str(exc.value.output, 'utf-8')
87 )
90def test_field_name_python_keyword(testdir: Testdir) -> None:
91 """Field name shadowing a python keyword is not allowed"""
92 schema = (
93 testdir.SCHEMA_HEADER
94 + """
95 model User {{
96 id String @id
97 from String
98 }}
99 """
100 )
101 with pytest.raises(subprocess.CalledProcessError) as exc:
102 testdir.generate(schema=schema)
104 assert 'Field name "from" shadows a Python keyword; use a different field name with \'@map("from")\'' in str(
105 exc.value.output, 'utf-8'
106 )
109def test_field_name_prisma_not_allowed(testdir: Testdir) -> None:
110 """Field name "prisma" is not allowed as it overrides our own method"""
111 schema = (
112 testdir.SCHEMA_HEADER
113 + """
114 model User {{
115 id String @id
116 prisma String
117 }}
118 """
119 )
120 with pytest.raises(subprocess.CalledProcessError) as exc:
121 testdir.generate(schema=schema)
123 assert (
124 'Field name "prisma" shadows a Prisma Client Python method; '
125 'use a different field name with \'@map("prisma")\''
126 ) in str(exc.value.output, 'utf-8')
129def test_field_name_matching_query_builder_alias_not_allowed(
130 testdir: Testdir,
131) -> None:
132 """A field name that is the same as an alias used by our internal query builder
133 is not allowed as it will lead to confusing error messages
135 https://github.com/RobertCraigie/prisma-client-py/issues/124
136 """
137 schema = (
138 testdir.SCHEMA_HEADER
139 + """
140 model User {{
141 id String @id
142 order_by String
143 }}
144 """
145 )
146 with pytest.raises(subprocess.CalledProcessError) as exc:
147 testdir.generate(schema=schema)
149 assert (
150 'Field name "order_by" shadows an internal keyword; ' 'use a different field name with \'@map("order_by")\''
151 ) in str(exc.value.output, 'utf-8')
154def test_custom_model_instance_name_not_valid_identifier(
155 testdir: Testdir,
156) -> None:
157 schema = (
158 testdir.SCHEMA_HEADER
159 + """
160 /// @Python(instance_name: "1")
161 model User {{
162 id String @id
163 }}
164 """
165 )
166 with pytest.raises(subprocess.CalledProcessError) as exc:
167 testdir.generate(schema=schema)
169 assert 'Custom Model instance_name "1" is not a valid Python identifier' in str(exc.value.output, 'utf-8')
172def test_native_binary_target_no_warning(testdir: Testdir) -> None:
173 """binaryTargets only being native does not raise warning"""
174 with temp_env_update({'PRISMA_PY_DEBUG': '0'}):
175 result = testdir.generate(options='binaryTargets = ["native"]')
177 stdout = _remove_known_warnings(result.stdout.decode('utf-8'))
178 assert 'Warning' not in stdout
179 assert 'binaryTargets option' not in stdout
180 assert_no_generator_output(stdout)
183def test_binary_targets_warning(testdir: Testdir) -> None:
184 """Binary targets option being present raises a warning"""
185 with temp_env_update({'PRISMA_PY_DEBUG': '0'}):
186 result = testdir.generate(options='binaryTargets = ["native", "rhel-openssl-1.1.x"]')
188 stdout = result.stdout.decode('utf-8')
189 assert_no_generator_output(stdout)
190 assert 'Warning: The binaryTargets option ' 'is not officially supported by Prisma Client Python' in stdout
193@pytest.mark.parametrize(
194 'http,new',
195 [
196 ('aiohttp', 'asyncio'),
197 ('requests', 'sync'),
198 ],
199)
200def test_old_http_option(testdir: Testdir, http: str, new: str) -> None:
201 """A helpful error is raised if the old http config option is used"""
202 with pytest.raises(subprocess.CalledProcessError) as exc:
203 testdir.generate(options=f'http = "{http}"')
205 stdout = exc.value.stdout.decode('utf-8')
206 assert 'The http option has been removed ' 'in favour of the interface option.' in stdout
207 assert 'Please remove the http option from ' 'your Prisma schema and replace it with:' in stdout
208 assert f'interface = "{new}"' in stdout
211def test_decimal_type_experimental(testdir: Testdir) -> None:
212 """The Decimal type requires a config flag to be set"""
213 schema = (
214 testdir.SCHEMA_HEADER
215 + """
216 model User {{
217 id String @id @default(cuid())
218 points Decimal
219 }}
220 """
221 )
222 with pytest.raises(subprocess.CalledProcessError) as exc:
223 testdir.generate(schema=schema)
225 output = str(exc.value.output, 'utf-8')
226 assert 'Support for the Decimal type is experimental' in output
227 assert 'set the `enable_experimental_decimal` config flag to true' in output
230def test_composite_type_not_supported(testdir: Testdir) -> None:
231 """Composite types are not supported yet"""
232 schema = (
233 testdir.default_generator
234 + """
235 datasource db {{
236 provider = "mongodb"
237 url = env("foo")
238 }}
240 model User {{
241 id String @id @map("_id")
242 // settings UserSettings
243 }}
245 type UserSettings {{
246 points Decimal
247 }}
248 """
249 )
250 with pytest.raises(subprocess.CalledProcessError) as exc:
251 testdir.generate(schema=schema)
253 output = str(exc.value.output, 'utf-8')
254 assert 'Composite types are not supported yet.' in output
255 assert 'https://github.com/RobertCraigie/prisma-client-py/issues/314' in output