blob: 5580a5eefce7c4aef44aae4f822d0601f9a2b24c [file] [log] [blame]
George Keishinge7e91712021-09-03 11:28:44 -05001#!/usr/bin/env python3
Michael Walsh18176322016-11-15 15:11:21 -06002
3r"""
Michael Walsh410b1782019-10-22 15:56:18 -05004This module provides validation functions like valid_value(), valid_integer(), etc. for robot programs.
Michael Walsh18176322016-11-15 15:11:21 -06005"""
6
Michael Walsh84230c22019-08-01 12:23:07 -05007import re
Michael Walshc108e422019-03-28 12:27:18 -05008import gen_print as gp
Michael Walsh18176322016-11-15 15:11:21 -06009import gen_valid as gv
Michael Walsh84230c22019-08-01 12:23:07 -050010import func_args as fa
Michael Walsh18176322016-11-15 15:11:21 -060011
12from robot.libraries.BuiltIn import BuiltIn
Michael Walsh18176322016-11-15 15:11:21 -060013
14
Michael Walsh84230c22019-08-01 12:23:07 -050015def valid_var_name(var_name):
Michael Walsh18176322016-11-15 15:11:21 -060016 r"""
Michael Walsh84230c22019-08-01 12:23:07 -050017 Validate the robot variable name and return its value.
Michael Walsh3e26e102017-01-10 11:29:28 -060018
Michael Walsh410b1782019-10-22 15:56:18 -050019 If the variable is undefined, this function will print an error message and call BuiltIn().fail().
Michael Walsh18176322016-11-15 15:11:21 -060020
Michael Walsh84230c22019-08-01 12:23:07 -050021 Description of arguments():
Michael Walsh410b1782019-10-22 15:56:18 -050022 var_name The name of the robot variable (e.g. "var1"). Do not include "${}" (e.g.
23 "${var1}". Just provide the simple name of the variable.
Michael Walsh18176322016-11-15 15:11:21 -060024 """
25
26 # Note: get_variable_value() seems to have no trouble with local variables.
27 var_value = BuiltIn().get_variable_value("${" + var_name + "}")
Michael Walsh18176322016-11-15 15:11:21 -060028 if var_value is None:
Michael Walsh84230c22019-08-01 12:23:07 -050029 var_value = "<undefined>"
30 error_message = gv.valid_value(var_value, invalid_values=[var_value],
31 var_name=var_name)
Michael Walsh18176322016-11-15 15:11:21 -060032 BuiltIn().fail(error_message)
33
Michael Walsh84230c22019-08-01 12:23:07 -050034 return var_value
Michael Walsh18176322016-11-15 15:11:21 -060035
Michael Walsh84230c22019-08-01 12:23:07 -050036
37def valid_init(var_name, *args, **kwargs):
Michael Walsh18176322016-11-15 15:11:21 -060038 r"""
Michael Walsh410b1782019-10-22 15:56:18 -050039 Do initialization for variable validation and return var_name, args and kwargs.
Michael Walsh3e26e102017-01-10 11:29:28 -060040
Michael Walsh410b1782019-10-22 15:56:18 -050041 This function is to be called by all of the various validation functions in this module.
Michael Walsh18176322016-11-15 15:11:21 -060042
Michael Walsh84230c22019-08-01 12:23:07 -050043 This function is designed solely for use by other functions in this file.
Michael Walsh18176322016-11-15 15:11:21 -060044
Michael Walsh84230c22019-08-01 12:23:07 -050045 Description of argument(s):
46 var_name The name of the variable to be validated.
Michael Walsh410b1782019-10-22 15:56:18 -050047 args The positional arguments to be passed to a validation function.
48 kwargs The keyword arguments to be passed to a validation function.
Michael Walsh18176322016-11-15 15:11:21 -060049 """
50
Michael Walsh84230c22019-08-01 12:23:07 -050051 var_value = valid_var_name(var_name)
Michael Walsh410b1782019-10-22 15:56:18 -050052 # Convert python string object definitions to objects (useful for robot callers).
Michael Walsh84230c22019-08-01 12:23:07 -050053 args = fa.args_to_objects(args)
54 kwargs = fa.args_to_objects(kwargs)
55 return var_value, args, kwargs
Michael Walsh2c687e92018-05-09 11:47:56 -050056
57
Michael Walsh84230c22019-08-01 12:23:07 -050058def process_error_message(error_message):
Michael Walsh2c687e92018-05-09 11:47:56 -050059 r"""
Michael Walsh84230c22019-08-01 12:23:07 -050060 Process an error message.
Michael Walsh2c687e92018-05-09 11:47:56 -050061
Michael Walsh84230c22019-08-01 12:23:07 -050062 If error_message is non-blank, fail. Otherwise, do nothing.
Michael Walsh2c687e92018-05-09 11:47:56 -050063
Michael Walsh84230c22019-08-01 12:23:07 -050064 This function is designed solely for use by other functions in this file.
Michael Walsh2c687e92018-05-09 11:47:56 -050065
Michael Walsh84230c22019-08-01 12:23:07 -050066 Description of argument(s):
67 error_message The error message to be processed.
Michael Walsh2c687e92018-05-09 11:47:56 -050068 """
69
Michael Walsh84230c22019-08-01 12:23:07 -050070 if error_message:
Michael Walshc108e422019-03-28 12:27:18 -050071 error_message = gp.sprint_error_report(error_message)
Michael Walsh2c687e92018-05-09 11:47:56 -050072 BuiltIn().fail(error_message)
Michael Walsh84230c22019-08-01 12:23:07 -050073
74
Michael Walsh410b1782019-10-22 15:56:18 -050075# The docstring header will be pre-pended to each validation function's existing docstring.
Michael Walsh84230c22019-08-01 12:23:07 -050076docstring_header = \
77 r"""
78 Fail if the variable named by var_name is invalid.
79 """
80
81
82def customize_doc_string(doc_string):
83 r"""
84 Customize a gen_valid function docstring and return the result.
85
86 This function is designed solely for use by other functions in this file.
87
Michael Walsh410b1782019-10-22 15:56:18 -050088 The caller should pass a docstring from a gen_valid.py validation function. This docstring will be
89 changed to make a suitable docstring for this module's corresponding validation function.
Michael Walsh84230c22019-08-01 12:23:07 -050090
91 For example:
92
Michael Walsh410b1782019-10-22 15:56:18 -050093 Let's suppose that gen_valid.py has a function called "valid_value()". This module could make the
94 following call to essentially copy gen_valid's "valid_value()" function, modify it and then assign it to
95 the local version of the valid_value() function.
Michael Walsh84230c22019-08-01 12:23:07 -050096
97 valid.__doc__ = customize_doc_string(gv.valid.__doc__)
98
99 Description of argument(s):
100 doc_string The docstring to be customized.
101 """
102
103 doc_string = docstring_header + doc_string
104 doc_string = doc_string.split("\n")
105
106 start_ix = 0
107 # Find the "var_value" line.
108 start_ix = next((index for index, value in
109 enumerate(doc_string[start_ix:], start_ix)
110 if re.match("[ ]+var_value ", value)), None)
111 # Replace the "var_value" line with our "var_name" line.
112 doc_string[start_ix] = " var_name " \
113 + "The name of the variable to be validated."
114
115 return "\n".join(doc_string)
116
117
Michael Walsh410b1782019-10-22 15:56:18 -0500118# All of the following functions are robot wrappers for the equivalent functions defined in gen_valid.py.
119# Note that the only difference between any two of these locally defined functions is the function name and
120# the gv.<function name> which they call. Also, note that the docstring for each is created by modifying the
121# docstring from the supporting gen_valid.py function.
Michael Walsh84230c22019-08-01 12:23:07 -0500122
123def valid_type(var_name, *args, **kwargs):
124
125 var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
126 error_message = \
127 gv.valid_type(var_value, *args, var_name=var_name, **kwargs)
128 process_error_message(error_message)
129
130
131def valid_value(var_name, *args, **kwargs):
132
133 var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
134 error_message = \
135 gv.valid_value(var_value, *args, var_name=var_name, **kwargs)
136 process_error_message(error_message)
137
138
139def valid_range(var_name, *args, **kwargs):
140
141 var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
142 error_message = \
143 gv.valid_range(var_value, *args, var_name=var_name, **kwargs)
144 process_error_message(error_message)
145
146
147def valid_integer(var_name, *args, **kwargs):
148
149 var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
150 error_message = \
151 gv.valid_integer(var_value, *args, var_name=var_name, **kwargs)
152 process_error_message(error_message)
153
154
Michael Walsh8333a182019-10-22 16:19:00 -0500155def valid_float(var_name, *args, **kwargs):
156
157 var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
158 error_message = \
159 gv.valid_float(var_value, *args, var_name=var_name, **kwargs)
160 process_error_message(error_message)
161
162
163def valid_date_time(var_name, *args, **kwargs):
164
165 var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
166 error_message = \
167 gv.valid_date_time(var_value, *args, var_name=var_name, **kwargs)
168 process_error_message(error_message)
169
170
Michael Walsh84230c22019-08-01 12:23:07 -0500171def valid_dir_path(var_name, *args, **kwargs):
172
173 var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
174 error_message = \
175 gv.valid_dir_path(var_value, *args, var_name=var_name, **kwargs)
176 process_error_message(error_message)
177
178
179def valid_file_path(var_name, *args, **kwargs):
180
181 var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
182 error_message = \
183 gv.valid_file_path(var_value, *args, var_name=var_name, **kwargs)
184 process_error_message(error_message)
185
186
187def valid_path(var_name, *args, **kwargs):
188
189 var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
190 error_message = \
191 gv.valid_path(var_value, *args, var_name=var_name, **kwargs)
192 process_error_message(error_message)
193
194
195def valid_list(var_name, *args, **kwargs):
196
197 var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
198 error_message = \
199 gv.valid_list(var_value, *args, var_name=var_name, **kwargs)
200 process_error_message(error_message)
201
202
203def valid_dict(var_name, *args, **kwargs):
204
205 var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
206 error_message = \
207 gv.valid_dict(var_value, *args, var_name=var_name, **kwargs)
208 process_error_message(error_message)
209
210
Michael Walshbe3a8152019-08-20 16:38:19 -0500211def valid_program(var_name, *args, **kwargs):
212
213 var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
214 error_message = \
215 gv.valid_program(var_value, *args, var_name=var_name, **kwargs)
216 process_error_message(error_message)
217
218
Michael Walshb9d8dfd2019-09-11 11:11:12 -0500219def valid_length(var_name, *args, **kwargs):
220
221 var_value, args, kwargs = valid_init(var_name, *args, **kwargs)
222 error_message = \
223 gv.valid_length(var_value, *args, var_name=var_name, **kwargs)
224 process_error_message(error_message)
225
226
Michael Walsh410b1782019-10-22 15:56:18 -0500227# Modify the validation function docstrings by calling customize_doc_string for each function in the
228# func_names list.
Michael Walsh84230c22019-08-01 12:23:07 -0500229func_names = [
230 "valid_type", "valid_value", "valid_range", "valid_integer",
231 "valid_dir_path", "valid_file_path", "valid_path", "valid_list",
Michael Walsh8333a182019-10-22 16:19:00 -0500232 "valid_dict", "valid_program", "valid_length", "valid_float",
233 "valid_date_time"
Michael Walsh84230c22019-08-01 12:23:07 -0500234]
235
236for func_name in func_names:
237 cmd_buf = func_name \
238 + ".__doc__ = customize_doc_string(gv.raw_doc_strings['" \
239 + func_name + "'])"
240 exec(cmd_buf)