2
2
3
3
import pytest
4
4
5
- from wtforms .validators import regexp
5
+ from wtforms .validators import regexp , ValidatorSetupError
6
6
from wtforms .validators import ValidationError
7
7
8
8
@@ -14,43 +14,187 @@ def grab_error_message(callable, form, field):
14
14
15
15
16
16
@pytest .mark .parametrize (
17
- "re_pattern, re_flags, test_v, expected_v" ,
17
+ "re_pattern, re_flags, re_mode, test_v, expected_v" ,
18
18
[
19
- ("^a" , None , "abcd" , "a" ),
20
- ("^a" , re .I , "ABcd" , "A" ),
21
- (re .compile ("^a" ), None , "abcd" , "a" ),
22
- (re .compile ("^a" , re .I ), None , "ABcd" , "A" ),
19
+ # match mode
20
+ ("^a" , None , "match" , "abcd" , "a" ),
21
+ ("^a" , re .I , "match" , "ABcd" , "A" ),
22
+ ("^ab" , None , "match" , "abcd" , "ab" ),
23
+ ("^ab" , re .I , "match" , "ABcd" , "AB" ),
24
+ ("^abcd" , None , "match" , "abcd" , "abcd" ),
25
+ ("^abcd" , re .I , "match" , "ABcd" , "ABcd" ),
26
+ (r"^\w+" , None , "match" , "abcd" , "abcd" ),
27
+ (r"^\w+" , re .I , "match" , "ABcd" , "ABcd" ),
28
+ (re .compile ("^a" ), None , "match" , "abcd" , "a" ),
29
+ (re .compile ("^a" , re .I ), None , "match" , "ABcd" , "A" ),
30
+ (re .compile ("^ab" ), None , "match" , "abcd" , "ab" ),
31
+ (re .compile ("^ab" , re .I ), None , "match" , "ABcd" , "AB" ),
32
+ (re .compile ("^abcd" ), None , "match" , "abcd" , "abcd" ),
33
+ (re .compile ("^abcd" , re .I ), None , "match" , "ABcd" , "ABcd" ),
34
+ (re .compile (r"^\w+" ), None , "match" , "abcd" , "abcd" ),
35
+ (re .compile (r"^\w+" , re .I ), None , "match" , "ABcd" , "ABcd" ),
36
+ # fullmatch mode
37
+ ("^abcd" , None , "fullmatch" , "abcd" , "abcd" ),
38
+ ("^abcd" , re .I , "fullmatch" , "ABcd" , "ABcd" ),
39
+ ("^abcd$" , None , "fullmatch" , "abcd" , "abcd" ),
40
+ ("^abcd$" , re .I , "fullmatch" , "ABcd" , "ABcd" ),
41
+ (r"^\w+" , None , "fullmatch" , "abcd" , "abcd" ),
42
+ (r"^\w+" , re .I , "fullmatch" , "ABcd" , "ABcd" ),
43
+ (r"^\w+$" , None , "fullmatch" , "abcd" , "abcd" ),
44
+ (r"^\w+$" , re .I , "fullmatch" , "ABcd" , "ABcd" ),
45
+ (re .compile ("^abcd" ), None , "fullmatch" , "abcd" , "abcd" ),
46
+ (re .compile ("^abcd" , re .I ), None , "fullmatch" , "ABcd" , "ABcd" ),
47
+ (re .compile ("^abcd$" ), None , "fullmatch" , "abcd" , "abcd" ),
48
+ (re .compile ("^abcd$" , re .I ), None , "fullmatch" , "ABcd" , "ABcd" ),
49
+ (re .compile (r"^\w+" ), None , "fullmatch" , "abcd" , "abcd" ),
50
+ (re .compile (r"^\w+" , re .I ), None , "fullmatch" , "ABcd" , "ABcd" ),
51
+ (re .compile (r"^\w+$" ), None , "fullmatch" , "abcd" , "abcd" ),
52
+ (re .compile (r"^\w+$" , re .I ), None , "fullmatch" , "ABcd" , "ABcd" ),
53
+ # search mode
54
+ ("^a" , None , "search" , "abcd" , "a" ),
55
+ ("^a" , re .I , "search" , "ABcd" , "A" ),
56
+ ("bc" , None , "search" , "abcd" , "bc" ),
57
+ ("bc" , re .I , "search" , "ABcd" , "Bc" ),
58
+ ("cd$" , None , "search" , "abcd" , "cd" ),
59
+ ("cd$" , re .I , "search" , "ABcd" , "cd" ),
60
+ (r"\w" , None , "search" , "abcd" , "a" ),
61
+ (r"\w" , re .I , "search" , "ABcd" , "A" ),
62
+ (r"\w$" , None , "search" , "abcd" , "d" ),
63
+ (r"\w$" , re .I , "search" , "ABcd" , "d" ),
64
+ (r"\w+" , None , "search" , "abcd" , "abcd" ),
65
+ (r"\w+" , re .I , "search" , "ABcd" , "ABcd" ),
66
+ (r"\w+$" , None , "search" , "abcd" , "abcd" ),
67
+ (r"\w+$" , re .I , "search" , "ABcd" , "ABcd" ),
68
+ (re .compile ("^a" ), None , "search" , "abcd" , "a" ),
69
+ (re .compile ("^a" , re .I ), None , "search" , "ABcd" , "A" ),
70
+ (re .compile (r"d$" ), None , "search" , "abcd" , "d" ),
71
+ (re .compile (r"d$" , re .I ), None , "search" , "ABcd" , "d" ),
72
+ (re .compile ("bc" ), None , "search" , "abcd" , "bc" ),
73
+ (re .compile ("bc" , re .I ), None , "search" , "ABcd" , "Bc" ),
74
+ (re .compile (r"\w" ), None , "search" , "abcd" , "a" ),
75
+ (re .compile (r"\w" , re .I ), None , "search" , "ABcd" , "A" ),
76
+ (re .compile (r"\w+" ), None , "search" , "abcd" , "abcd" ),
77
+ (re .compile (r"\w+" , re .I ), None , "search" , "ABcd" , "ABcd" ),
23
78
],
24
79
)
25
80
def test_regex_passes (
26
- re_pattern , re_flags , test_v , expected_v , dummy_form , dummy_field
81
+ re_pattern , re_flags , re_mode , test_v , expected_v , dummy_form , dummy_field
27
82
):
28
83
"""
29
84
Regex should pass if there is a match.
30
- Should work for complie regex too
85
+ Should work for compile regex too
31
86
"""
32
- validator = regexp (re_pattern , re_flags ) if re_flags else regexp (re_pattern )
87
+ kwargs = {
88
+ "regex" : re_pattern ,
89
+ "flags" : re_flags if re_flags else 0 ,
90
+ "message" : None ,
91
+ "mode" : re_mode ,
92
+ }
93
+ validator = regexp (** kwargs )
33
94
dummy_field .data = test_v
34
95
assert validator (dummy_form , dummy_field ).group (0 ) == expected_v
35
96
36
97
37
98
@pytest .mark .parametrize (
38
- "re_pattern, re_flags, test_v" ,
99
+ "re_pattern, re_flags, re_mode, test_v" ,
39
100
[
40
- ("^a" , None , "ABC" ),
41
- ("^a" , re .I , "foo" ),
42
- ("^a" , None , None ),
43
- (re .compile ("^a" ), None , "foo" ),
44
- (re .compile ("^a" , re .I ), None , None ),
101
+ # math mode
102
+ ("^a" , None , "match" , "ABC" ),
103
+ ("^a" , re .I , "match" , "foo" ),
104
+ ("^a" , None , "match" , None ),
105
+ ("^ab" , None , "match" , "ABC" ),
106
+ ("^ab" , re .I , "match" , "foo" ),
107
+ ("^ab" , None , "match" , None ),
108
+ ("^ab$" , None , "match" , "ABC" ),
109
+ ("^ab$" , re .I , "match" , "foo" ),
110
+ ("^ab$" , None , "match" , None ),
111
+ (re .compile ("^a" ), None , "match" , "ABC" ),
112
+ (re .compile ("^a" , re .I ), None , "match" , "foo" ),
113
+ (re .compile ("^a" ), None , "match" , None ),
114
+ (re .compile ("^ab" ), None , "match" , "ABC" ),
115
+ (re .compile ("^ab" , re .I ), None , "match" , "foo" ),
116
+ (re .compile ("^ab" ), None , "match" , None ),
117
+ (re .compile ("^ab$" ), None , "match" , "ABC" ),
118
+ (re .compile ("^ab$" , re .I ), None , "match" , "foo" ),
119
+ (re .compile ("^ab$" ), None , "match" , None ),
120
+ # fullmatch mode
121
+ ("^abcd" , None , "fullmatch" , "abc" ),
122
+ ("^abcd" , re .I , "fullmatch" , "abc" ),
123
+ ("^abcd" , None , "fullmatch" , "foo" ),
124
+ ("^abcd" , re .I , "fullmatch" , "foo" ),
125
+ ("^abcd" , None , "fullmatch" , None ),
126
+ ("^abcd" , re .I , "fullmatch" , None ),
127
+ ("abcd$" , None , "fullmatch" , "abc" ),
128
+ ("abcd$" , re .I , "fullmatch" , "abc" ),
129
+ ("abcd$" , None , "fullmatch" , "foo" ),
130
+ ("abcd$" , re .I , "fullmatch" , "foo" ),
131
+ ("abcd$" , None , "fullmatch" , None ),
132
+ ("abcd$" , re .I , "fullmatch" , None ),
133
+ ("^abcd$" , None , "fullmatch" , "abc" ),
134
+ ("^abcd$" , re .I , "fullmatch" , "abc" ),
135
+ ("^abcd$" , None , "fullmatch" , "foo" ),
136
+ ("^abcd$" , re .I , "fullmatch" , "foo" ),
137
+ ("^abcd$" , None , "fullmatch" , None ),
138
+ ("^abcd$" , re .I , "fullmatch" , None ),
139
+ (re .compile ("^abcd" ), None , "fullmatch" , "abc" ),
140
+ (re .compile ("^abcd" , re .I ), None , "fullmatch" , "abc" ),
141
+ (re .compile ("^abcd" ), None , "fullmatch" , "foo" ),
142
+ (re .compile ("^abcd" , re .I ), None , "fullmatch" , "foo" ),
143
+ (re .compile ("^abcd" ), None , "fullmatch" , None ),
144
+ (re .compile ("^abcd" , re .I ), None , "fullmatch" , None ),
145
+ (re .compile ("abcd$" ), None , "fullmatch" , "abc" ),
146
+ (re .compile ("abcd$" , re .I ), None , "fullmatch" , "abc" ),
147
+ (re .compile ("abcd$" ), None , "fullmatch" , "foo" ),
148
+ (re .compile ("abcd$" , re .I ), None , "fullmatch" , "foo" ),
149
+ (re .compile ("abcd$" ), None , "fullmatch" , None ),
150
+ (re .compile ("abcd$" , re .I ), None , "fullmatch" , None ),
151
+ (re .compile ("^abcd$" ), None , "fullmatch" , "abc" ),
152
+ (re .compile ("^abcd$" , re .I ), None , "fullmatch" , "abc" ),
153
+ (re .compile ("^abcd$" ), None , "fullmatch" , "foo" ),
154
+ (re .compile ("^abcd$" , re .I ), None , "fullmatch" , "foo" ),
155
+ (re .compile ("^abcd$" ), None , "fullmatch" , None ),
156
+ (re .compile ("^abcd$" , re .I ), None , "fullmatch" , None ),
157
+ # search mode
158
+ ("^a" , None , "search" , "foo" ),
159
+ ("^a" , re .I , "search" , "foo" ),
160
+ ("^a" , None , "search" , None ),
161
+ ("^a" , re .I , "search" , None ),
162
+ ("bc" , None , "search" , "foo" ),
163
+ ("bc" , re .I , "search" , "foo" ),
164
+ ("bc" , None , "search" , None ),
165
+ ("bc" , re .I , "search" , None ),
166
+ ("cd$" , None , "search" , "foo" ),
167
+ ("cd$" , re .I , "search" , "foo" ),
168
+ ("cd$" , None , "search" , None ),
169
+ ("cd$" , re .I , "search" , None ),
170
+ (re .compile ("^a" ), None , "search" , "foo" ),
171
+ (re .compile ("^a" , re .I ), None , "search" , "foo" ),
172
+ (re .compile ("^a" ), None , "search" , None ),
173
+ (re .compile ("^a" , re .I ), None , "search" , None ),
174
+ (re .compile ("bc" ), None , "search" , "foo" ),
175
+ (re .compile ("bc" , re .I ), None , "search" , "foo" ),
176
+ (re .compile ("bc" ), None , "search" , None ),
177
+ (re .compile ("bc" , re .I ), None , "search" , None ),
178
+ (re .compile (r"cd$" ), None , "search" , "foo" ),
179
+ (re .compile (r"cd$" , re .I ), None , "search" , "foo" ),
180
+ (re .compile (r"cd$" ), None , "search" , None ),
181
+ (re .compile (r"cd$" , re .I ), None , "search" , None ),
45
182
],
46
183
)
47
- def test_regex_raises (re_pattern , re_flags , test_v , dummy_form , dummy_field ):
184
+ def test_regex_raises (re_pattern , re_flags , re_mode , test_v , dummy_form , dummy_field ):
48
185
"""
49
186
Regex should raise ValidationError if there is no match
50
- Should work for complie regex too
187
+ Should work for compile regex too
51
188
"""
52
- validator = regexp (re_pattern , re_flags ) if re_flags else regexp (re_pattern )
189
+ kwargs = {
190
+ "regex" : re_pattern ,
191
+ "flags" : re_flags if re_flags else 0 ,
192
+ "message" : None ,
193
+ "mode" : re_mode ,
194
+ }
195
+ validator = regexp (** kwargs )
53
196
dummy_field .data = test_v
197
+
54
198
with pytest .raises (ValidationError ):
55
199
validator (dummy_form , dummy_field )
56
200
@@ -62,3 +206,38 @@ def test_regexp_message(dummy_form, dummy_field):
62
206
validator = regexp ("^a" , message = "foo" )
63
207
dummy_field .data = "f"
64
208
assert grab_error_message (validator , dummy_form , dummy_field ) == "foo"
209
+
210
+
211
+ @pytest .mark .parametrize (
212
+ "re_mode" ,
213
+ [
214
+ "MATCH" ,
215
+ "SEARCH" ,
216
+ "FULLMATCH" ,
217
+ "Match" ,
218
+ "Search" ,
219
+ "Fullmatch" ,
220
+ "" ,
221
+ "match " ,
222
+ " match" ,
223
+ "search " ,
224
+ " search" ,
225
+ "fullmatch " ,
226
+ " fullmatch" ,
227
+ None ,
228
+ 1 ,
229
+ 1.0 ,
230
+ True ,
231
+ False ,
232
+ [],
233
+ {},
234
+ (),
235
+ ]
236
+ )
237
+ def test_regex_invalid_mode (dummy_form , dummy_field , re_mode ):
238
+ """
239
+ Regexp validator should raise ValidatorSetupError during an object instantiation,
240
+ if mode is invalid (unsupported).
241
+ """
242
+ with pytest .raises (ValidatorSetupError ):
243
+ regexp ("^a" , mode = re_mode )
0 commit comments