Skip to content
This repository was archived by the owner on Mar 16, 2026. It is now read-only.

Commit 2355811

Browse files
1 parent 9ff1b4a commit 2355811

File tree

1 file changed

+83
-47
lines changed

1 file changed

+83
-47
lines changed

tests/unit/test__types.py

Lines changed: 83 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from sqlalchemy_bigquery._types import _get_transitive_schema_fields, STRUCT_FIELD_TYPES
55

6+
67
def create_fut(name, field_type, mode="NULLABLE", sub_fields=None):
78
"""
89
Helper function to create a SchemaField object for testing.
@@ -21,77 +22,115 @@ def create_fut(name, field_type, mode="NULLABLE", sub_fields=None):
2122
(
2223
"STRUCT field, not REPEATED, with sub-fields, should recurse",
2324
[
24-
create_fut("s1", "STRUCT", "NULLABLE", sub_fields=[
25-
create_fut("child1", "STRING", "NULLABLE")
26-
])
25+
create_fut(
26+
"s1",
27+
"STRUCT",
28+
"NULLABLE",
29+
sub_fields=[create_fut("child1", "STRING", "NULLABLE")],
30+
)
2731
],
2832
["s1", "s1.child1"],
2933
),
3034
(
3135
"RECORD field (alias for STRUCT), not REPEATED, with sub-fields, should recurse",
3236
[
33-
create_fut("r1", "RECORD", "NULLABLE", sub_fields=[
34-
create_fut("child_r1", "INTEGER", "NULLABLE")
35-
])
37+
create_fut(
38+
"r1",
39+
"RECORD",
40+
"NULLABLE",
41+
sub_fields=[create_fut("child_r1", "INTEGER", "NULLABLE")],
42+
)
3643
],
3744
["r1", "r1.child_r1"],
3845
),
3946
(
4047
"STRUCT field, REPEATED, with sub-fields, should NOT recurse",
4148
[
42-
create_fut("s2", "STRUCT", "REPEATED", sub_fields=[
43-
create_fut("child2", "STRING", "NULLABLE")
44-
])
49+
create_fut(
50+
"s2",
51+
"STRUCT",
52+
"REPEATED",
53+
sub_fields=[create_fut("child2", "STRING", "NULLABLE")],
54+
)
4555
],
4656
["s2"],
4757
),
4858
(
4959
"Non-STRUCT field (STRING), not REPEATED, should NOT recurse",
50-
[
51-
create_fut("f1", "STRING", "NULLABLE")
52-
],
60+
[create_fut("f1", "STRING", "NULLABLE")],
5361
["f1"],
5462
),
5563
(
5664
"Non-STRUCT field (INTEGER), REPEATED, should NOT recurse",
57-
[
58-
create_fut("f2", "INTEGER", "REPEATED")
59-
],
65+
[create_fut("f2", "INTEGER", "REPEATED")],
6066
["f2"],
6167
),
6268
(
6369
"Deeply nested STRUCT, not REPEATED, should recurse fully",
6470
[
65-
create_fut("s_outer", "STRUCT", "NULLABLE", sub_fields=[
66-
create_fut("s_inner1", "STRUCT", "NULLABLE", sub_fields=[
67-
create_fut("s_leaf1", "STRING", "NULLABLE")
68-
]),
69-
create_fut("s_sibling", "INTEGER", "NULLABLE"),
70-
create_fut("s_inner2_repeated_struct", "STRUCT", "REPEATED", sub_fields=[
71-
create_fut("s_leaf2_ignored", "BOOLEAN", "NULLABLE") # This sub-field should be ignored
72-
]),
73-
])
71+
create_fut(
72+
"s_outer",
73+
"STRUCT",
74+
"NULLABLE",
75+
sub_fields=[
76+
create_fut(
77+
"s_inner1",
78+
"STRUCT",
79+
"NULLABLE",
80+
sub_fields=[create_fut("s_leaf1", "STRING", "NULLABLE")],
81+
),
82+
create_fut("s_sibling", "INTEGER", "NULLABLE"),
83+
create_fut(
84+
"s_inner2_repeated_struct",
85+
"STRUCT",
86+
"REPEATED",
87+
sub_fields=[
88+
create_fut(
89+
"s_leaf2_ignored", "BOOLEAN", "NULLABLE"
90+
) # This sub-field should be ignored
91+
],
92+
),
93+
],
94+
)
95+
],
96+
[
97+
"s_outer",
98+
"s_outer.s_inner1",
99+
"s_outer.s_inner1.s_leaf1",
100+
"s_outer.s_sibling",
101+
"s_outer.s_inner2_repeated_struct",
74102
],
75-
["s_outer", "s_outer.s_inner1", "s_outer.s_inner1.s_leaf1", "s_outer.s_sibling", "s_outer.s_inner2_repeated_struct"],
76103
),
77104
(
78105
"STRUCT field, not REPEATED, but no sub-fields, should not error and not recurse further",
79-
[
80-
create_fut("s3", "STRUCT", "NULLABLE", sub_fields=[])
81-
],
106+
[create_fut("s3", "STRUCT", "NULLABLE", sub_fields=[])],
82107
["s3"],
83108
),
84109
(
85110
"Multiple top-level fields with mixed conditions",
86111
[
87112
create_fut("id", "INTEGER", "REQUIRED"),
88-
create_fut("user_profile", "STRUCT", "NULLABLE", sub_fields=[
89-
create_fut("name", "STRING", "NULLABLE"),
90-
create_fut("addresses", "RECORD", "REPEATED", sub_fields=[ # addresses is REPEATED STRUCT
91-
create_fut("street", "STRING", "NULLABLE"), # This sub-field should be ignored
92-
create_fut("city", "STRING", "NULLABLE") # This sub-field should be ignored
93-
])
94-
]),
113+
create_fut(
114+
"user_profile",
115+
"STRUCT",
116+
"NULLABLE",
117+
sub_fields=[
118+
create_fut("name", "STRING", "NULLABLE"),
119+
create_fut(
120+
"addresses",
121+
"RECORD",
122+
"REPEATED",
123+
sub_fields=[ # addresses is REPEATED STRUCT
124+
create_fut(
125+
"street", "STRING", "NULLABLE"
126+
), # This sub-field should be ignored
127+
create_fut(
128+
"city", "STRING", "NULLABLE"
129+
), # This sub-field should be ignored
130+
],
131+
),
132+
],
133+
),
95134
create_fut("tags", "STRING", "REPEATED"),
96135
],
97136
["id", "user_profile", "user_profile.name", "user_profile.addresses", "tags"],
@@ -103,26 +142,23 @@ def create_fut(name, field_type, mode="NULLABLE", sub_fields=None):
103142
),
104143
(
105144
"Field type not in STRUCT_FIELD_TYPES and mode is REPEATED",
106-
[
107-
create_fut("f_arr", "FLOAT", "REPEATED")
108-
],
109-
["f_arr"]
145+
[create_fut("f_arr", "FLOAT", "REPEATED")],
146+
["f_arr"],
110147
),
111148
(
112149
"Field type not in STRUCT_FIELD_TYPES and mode is not REPEATED",
113-
[
114-
create_fut("f_single", "DATE", "NULLABLE")
115-
],
116-
["f_single"]
117-
)
150+
[create_fut("f_single", "DATE", "NULLABLE")],
151+
["f_single"],
152+
),
118153
]
119154

120155

121156
@pytest.mark.parametrize(
122-
"description, input_fields_list, expected_field_names",
123-
test_cases
157+
"description, input_fields_list, expected_field_names", test_cases
124158
)
125-
def test_get_transitive_schema_fields_conditions(description, input_fields_list, expected_field_names):
159+
def test_get_transitive_schema_fields_conditions(
160+
description, input_fields_list, expected_field_names
161+
):
126162
"""
127163
Tests the _get_transitive_schema_fields function, focusing on the conditional logic
128164
`if field.field_type in STRUCT_FIELD_TYPES and field.mode != "REPEATED":`.

0 commit comments

Comments
 (0)