Skip to content

Commit caac86c

Browse files
committed
test: add tests re: date-time marshalling/unmarshalling
Fixes arf/planning-sdk-squad#2313 This commit adds new tests for the datetime_to_string and string_to_datetime functions to ensure that each of the required date-time formats are supported. These new tests are aligned with similar tests in the Java and Go cores.
1 parent 819e6dd commit caac86c

File tree

3 files changed

+126
-35
lines changed

3 files changed

+126
-35
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ coverage.xml
4848
.vscode
4949

5050
# virtual env
51-
venv/
51+
venv*/
5252
# python 3 virtual env
5353
python3/
5454

ibm_cloud_sdk_core/utils.py

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import dateutil.parser as date_parser
2424

25+
2526
def has_bad_first_or_last_char(val: str) -> bool:
2627
"""Returns true if a string starts with any of: {," ; or ends with any of: },".
2728
@@ -31,7 +32,9 @@ def has_bad_first_or_last_char(val: str) -> bool:
3132
Returns:
3233
Whether or not the string starts or ends with bad characters.
3334
"""
34-
return val is not None and (val.startswith('{') or val.startswith('"') or val.endswith('}') or val.endswith('"'))
35+
return val is not None and (val.startswith('{') or val.startswith('"')
36+
or val.endswith('}') or val.endswith('"'))
37+
3538

3639
def remove_null_values(dictionary: dict) -> dict:
3740
"""Create a new dictionary without keys mapped to null values.
@@ -46,6 +49,7 @@ def remove_null_values(dictionary: dict) -> dict:
4649
return {k: v for (k, v) in dictionary.items() if v is not None}
4750
return dictionary
4851

52+
4953
def cleanup_values(dictionary: dict) -> dict:
5054
"""Create a new dictionary with boolean values converted to strings.
5155
@@ -62,18 +66,21 @@ def cleanup_values(dictionary: dict) -> dict:
6266
return {k: cleanup_value(v) for (k, v) in dictionary.items()}
6367
return dictionary
6468

69+
6570
def cleanup_value(value: any) -> any:
6671
"""Convert a boolean value to string."""
6772
if isinstance(value, bool):
6873
return 'true' if value else 'false'
6974
return value
7075

76+
7177
def strip_extra_slashes(value: str) -> str:
7278
"""Combine multiple trailing slashes to a single slash"""
7379
if value.endswith('//'):
7480
return value.rstrip('/') + '/'
7581
return value
7682

83+
7784
def datetime_to_string(val: datetime.datetime) -> str:
7885
"""Convert a datetime object to string.
7986
@@ -93,6 +100,7 @@ def datetime_to_string(val: datetime.datetime) -> str:
93100
return val.isoformat().replace('+00:00', 'Z')
94101
return val
95102

103+
96104
def string_to_datetime(string: str) -> datetime.datetime:
97105
"""De-serializes string to datetime.
98106
@@ -107,6 +115,7 @@ def string_to_datetime(string: str) -> datetime.datetime:
107115
return val
108116
return val.replace(tzinfo=datetime.timezone.utc)
109117

118+
110119
def date_to_string(val: datetime.date) -> str:
111120
"""Convert a date object to string.
112121
@@ -120,6 +129,7 @@ def date_to_string(val: datetime.date) -> str:
120129
return str(val)
121130
return val
122131

132+
123133
def string_to_date(string: str) -> datetime.date:
124134
"""De-serializes string to date.
125135
@@ -131,6 +141,7 @@ def string_to_date(string: str) -> datetime.date:
131141
"""
132142
return date_parser.parse(string).date()
133143

144+
134145
def convert_model(val: any) -> dict:
135146
"""Convert a model object into an equivalent dict.
136147
@@ -147,6 +158,7 @@ def convert_model(val: any) -> dict:
147158
# Consider raising a ValueError here in the next major release
148159
return val
149160

161+
150162
def convert_list(val: Union[str, List[str]]) -> str:
151163
"""Convert a list of strings into comma-separated string.
152164
@@ -163,6 +175,7 @@ def convert_list(val: Union[str, List[str]]) -> str:
163175
# Consider raising a ValueError here in the next major release
164176
return val
165177

178+
166179
def read_external_sources(service_name: str) -> dict:
167180
"""Look for external configuration of a service.
168181
@@ -189,6 +202,7 @@ def read_external_sources(service_name: str) -> dict:
189202

190203
return config
191204

205+
192206
def __read_from_env_variables(service_name: str) -> dict:
193207
"""Return a config object based on environment variables for a service.
194208
@@ -203,7 +217,10 @@ def __read_from_env_variables(service_name: str) -> dict:
203217
_parse_key_and_update_config(config, service_name, key, value)
204218
return config
205219

206-
def __read_from_credential_file(service_name: str, *, separator: str = '=') -> dict:
220+
221+
def __read_from_credential_file(service_name: str,
222+
*,
223+
separator: str = '=') -> dict:
207224
"""Return a config object based on credentials file for a service.
208225
209226
Args:
@@ -222,8 +239,7 @@ def __read_from_credential_file(service_name: str, *, separator: str = '=') -> d
222239

223240
# Current working directory
224241
if credential_file_path is None:
225-
file_path = join(
226-
getcwd(), default_credentials_file_name)
242+
file_path = join(getcwd(), default_credentials_file_name)
227243
if isfile(file_path):
228244
credential_file_path = file_path
229245

@@ -241,14 +257,18 @@ def __read_from_credential_file(service_name: str, *, separator: str = '=') -> d
241257
if len(key_val) == 2:
242258
key = key_val[0]
243259
value = key_val[1]
244-
_parse_key_and_update_config(config, service_name, key, value)
260+
_parse_key_and_update_config(config, service_name, key,
261+
value)
245262
return config
246263

247-
def _parse_key_and_update_config(config: dict, service_name: str, key: str, value: str) -> None:
264+
265+
def _parse_key_and_update_config(config: dict, service_name: str, key: str,
266+
value: str) -> None:
248267
service_name = service_name.replace(' ', '_').replace('-', '_').upper()
249268
if key.startswith(service_name):
250269
config[key[len(service_name) + 1:]] = value
251270

271+
252272
def __read_from_vcap_services(service_name: str) -> dict:
253273
"""Return a config object based on the vcap services environment variable.
254274
@@ -264,29 +284,39 @@ def __read_from_vcap_services(service_name: str) -> dict:
264284
services = json_import.loads(vcap_services)
265285
for key in services.keys():
266286
for i in range(len(services[key])):
267-
if vcap_service_credentials and isinstance(vcap_service_credentials, dict):
287+
if vcap_service_credentials and isinstance(
288+
vcap_service_credentials, dict):
268289
break
269290
if services[key][i].get('name') == service_name:
270-
vcap_service_credentials = services[key][i].get('credentials', {})
291+
vcap_service_credentials = services[key][i].get(
292+
'credentials', {})
271293
if not vcap_service_credentials:
272294
if service_name in services.keys():
273295
service = services.get(service_name)
274296
if service:
275-
vcap_service_credentials = service[0].get('credentials', {})
297+
vcap_service_credentials = service[0].get(
298+
'credentials', {})
276299

277-
if vcap_service_credentials and isinstance(vcap_service_credentials, dict):
300+
if vcap_service_credentials and isinstance(vcap_service_credentials,
301+
dict):
278302
new_vcap_creds = {}
279-
if vcap_service_credentials.get('username') and vcap_service_credentials.get('password'): # cf
303+
# cf
304+
if vcap_service_credentials.get(
305+
'username') and vcap_service_credentials.get('password'):
280306
new_vcap_creds['AUTH_TYPE'] = 'basic'
281-
new_vcap_creds['USERNAME'] = vcap_service_credentials.get('username')
282-
new_vcap_creds['PASSWORD'] = vcap_service_credentials.get('password')
307+
new_vcap_creds['USERNAME'] = vcap_service_credentials.get(
308+
'username')
309+
new_vcap_creds['PASSWORD'] = vcap_service_credentials.get(
310+
'password')
283311
vcap_service_credentials = new_vcap_creds
284312
elif vcap_service_credentials.get('iam_apikey'):
285313
new_vcap_creds['AUTH_TYPE'] = 'iam'
286-
new_vcap_creds['APIKEY'] = vcap_service_credentials.get('iam_apikey')
314+
new_vcap_creds['APIKEY'] = vcap_service_credentials.get(
315+
'iam_apikey')
287316
vcap_service_credentials = new_vcap_creds
288317
elif vcap_service_credentials.get('apikey'):
289318
new_vcap_creds['AUTH_TYPE'] = 'iam'
290-
new_vcap_creds['APIKEY'] = vcap_service_credentials.get('apikey')
319+
new_vcap_creds['APIKEY'] = vcap_service_credentials.get(
320+
'apikey')
291321
vcap_service_credentials = new_vcap_creds
292322
return vcap_service_credentials

0 commit comments

Comments
 (0)