Skip to content

Commit 66dc94d

Browse files
suffix reserved words in custom operation method names (#416)
1 parent 4e70511 commit 66dc94d

File tree

2 files changed

+161
-2
lines changed

2 files changed

+161
-2
lines changed

ariadne_codegen/client_generators/custom_operation.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
generate_return,
2424
)
2525
from ..plugins.manager import PluginManager
26-
from ..utils import str_to_snake_case
26+
from ..utils import process_name
2727
from .arguments import ArgumentsGenerator
2828
from .constants import (
2929
ANY,
@@ -156,7 +156,11 @@ def _generate_method(
156156
)
157157

158158
return generate_method_definition(
159-
name=str_to_snake_case(operation_name),
159+
name=process_name(
160+
operation_name,
161+
convert_to_snake_case=self.convert_to_snake_case,
162+
plugin_manager=self.plugin_manager,
163+
),
160164
arguments=method_arguments,
161165
return_type=generate_name(return_type_name),
162166
description=description,
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
import ast
2+
3+
from graphql import build_schema
4+
5+
from ariadne_codegen.client_generators.arguments import ArgumentsGenerator
6+
from ariadne_codegen.client_generators.custom_operation import CustomOperationGenerator
7+
8+
from ..utils import get_class_def
9+
10+
11+
def _get_method_names(class_def: ast.ClassDef) -> list[str]:
12+
"""Return names of methods (FunctionDef) in the class body."""
13+
return [node.name for node in class_def.body if isinstance(node, ast.FunctionDef)]
14+
15+
16+
def test_reserved_word_as_operation_name_generates_suffixed_method():
17+
schema_str = """
18+
schema { query: Query }
19+
type Query {
20+
return(id: ID!): ReturnType
21+
}
22+
type ReturnType {
23+
id: ID!
24+
value: String
25+
}
26+
"""
27+
schema = build_schema(schema_str)
28+
arguments_generator = ArgumentsGenerator(
29+
schema=schema,
30+
convert_to_snake_case=True,
31+
custom_scalars={},
32+
plugin_manager=None,
33+
)
34+
generator = CustomOperationGenerator(
35+
graphql_fields=schema.query_type.fields,
36+
name="Query",
37+
base_name="GraphQLOperation",
38+
enums_module_name="enums",
39+
convert_to_snake_case=True,
40+
custom_scalars={},
41+
plugin_manager=None,
42+
arguments_generator=arguments_generator,
43+
)
44+
module = generator.generate()
45+
query_class = get_class_def(module, name_filter="Query")
46+
assert query_class is not None
47+
method_names = _get_method_names(query_class)
48+
assert "return_" in method_names
49+
assert "return" not in method_names
50+
51+
52+
def test_builtin_name_as_operation_name_generates_suffixed_method():
53+
schema_str = """
54+
schema { query: Query }
55+
type Query {
56+
str(id: ID!): StrType
57+
}
58+
type StrType {
59+
id: ID!
60+
}
61+
"""
62+
schema = build_schema(schema_str)
63+
arguments_generator = ArgumentsGenerator(
64+
schema=schema,
65+
convert_to_snake_case=True,
66+
custom_scalars={},
67+
plugin_manager=None,
68+
)
69+
generator = CustomOperationGenerator(
70+
graphql_fields=schema.query_type.fields,
71+
name="Query",
72+
base_name="GraphQLOperation",
73+
enums_module_name="enums",
74+
convert_to_snake_case=True,
75+
custom_scalars={},
76+
plugin_manager=None,
77+
arguments_generator=arguments_generator,
78+
)
79+
module = generator.generate()
80+
query_class = get_class_def(module, name_filter="Query")
81+
assert query_class is not None
82+
method_names = _get_method_names(query_class)
83+
assert "str_" in method_names
84+
assert "str" not in method_names
85+
86+
87+
def test_normal_operation_name_unchanged():
88+
schema_str = """
89+
schema { query: Query }
90+
type Query {
91+
getUser(id: ID!): User
92+
}
93+
type User {
94+
id: ID!
95+
name: String
96+
}
97+
"""
98+
schema = build_schema(schema_str)
99+
arguments_generator = ArgumentsGenerator(
100+
schema=schema,
101+
convert_to_snake_case=True,
102+
custom_scalars={},
103+
plugin_manager=None,
104+
)
105+
generator = CustomOperationGenerator(
106+
graphql_fields=schema.query_type.fields,
107+
name="Query",
108+
base_name="GraphQLOperation",
109+
enums_module_name="enums",
110+
convert_to_snake_case=True,
111+
custom_scalars={},
112+
plugin_manager=None,
113+
arguments_generator=arguments_generator,
114+
)
115+
module = generator.generate()
116+
query_class = get_class_def(module, name_filter="Query")
117+
assert query_class is not None
118+
method_names = _get_method_names(query_class)
119+
assert "get_user" in method_names
120+
121+
122+
def test_generated_module_formats_with_black():
123+
from ariadne_codegen.utils import ast_to_str
124+
125+
schema_str = """
126+
schema { query: Query }
127+
type Query {
128+
return(id: ID!): ReturnType
129+
}
130+
type ReturnType {
131+
id: ID!
132+
}
133+
"""
134+
schema = build_schema(schema_str)
135+
arguments_generator = ArgumentsGenerator(
136+
schema=schema,
137+
convert_to_snake_case=True,
138+
custom_scalars={},
139+
plugin_manager=None,
140+
)
141+
generator = CustomOperationGenerator(
142+
graphql_fields=schema.query_type.fields,
143+
name="Query",
144+
base_name="GraphQLOperation",
145+
enums_module_name="enums",
146+
convert_to_snake_case=True,
147+
custom_scalars={},
148+
plugin_manager=None,
149+
arguments_generator=arguments_generator,
150+
)
151+
module = generator.generate()
152+
# Should not raise (e.g. Black InvalidInput for "def return(...)")
153+
code = ast_to_str(module)
154+
assert "def return_" in code
155+
assert "def return(" not in code

0 commit comments

Comments
 (0)