Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,46 @@ def validation_base_name(function_name: str):
return function_name.replace('<>', '')


@typechecked
def validate_fixed_default_size(
param_name: str,
defined_type: str,
default_value: Any,
validations_dict: dict,
):
capacity = fixed_type_size(defined_type)
if capacity is None or default_value is None:
return
if array_type(defined_type) and not isinstance(default_value, list):
return
if not array_type(defined_type) and not isinstance(default_value, str):
return

default_size = len(default_value)
if default_size > capacity:
raise compile_error(
'Parameter {} has a default value of size {}, which exceeds '
"the capacity of type '{}' ({}).".format(
param_name, default_size, defined_type, capacity
)
)

for function_name, arguments in validations_dict.items():
if validation_base_name(function_name) != 'fixed_size':
continue

expected_size = arguments
if isinstance(arguments, list) and len(arguments) == 1:
expected_size = arguments[0]
if isinstance(expected_size, int) and default_size != expected_size:
raise compile_error(
'Parameter {} has a default value of size {}, but its '
"'fixed_size' validation requires {}.".format(
param_name, default_size, expected_size
)
)


@typechecked
def validate_validator_combinations(param_name: str, validations_dict: dict):
validation_names = {validation_base_name(name) for name in validations_dict}
Expand Down Expand Up @@ -776,6 +816,10 @@ def preprocess_inputs(language, name, value, nested_name_list):

# optional attributes
default_value = value.get('default_value', None)
validations_dict = value.get('validation', {})
validate_fixed_default_size(
param_name, defined_type, default_value, validations_dict
)
if not is_fixed_type(defined_type):
code_gen_variable = CodeGenVariable(
language, name, param_name, defined_type, default_value
Expand All @@ -789,7 +833,6 @@ def preprocess_inputs(language, name, value, nested_name_list):
read_only = bool(value.get('read_only', False))
validations = []
additional_constraints = value.get('additional_constraints', '')
validations_dict = value.get('validation', {})
if is_fixed_type(defined_type):
validations_dict['size_lt<>'] = fixed_type_size(defined_type) + 1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@
from generate_parameter_library_py.generate_cpp_header import run as run_cpp
from generate_parameter_library_py.generate_python_module import run as run_python
from generate_parameter_library_py.generate_markdown import run as run_md
from generate_parameter_library_py.parse_yaml import YAMLSyntaxError
from generate_parameter_library_py.parse_yaml import (
YAMLSyntaxError,
preprocess_inputs,
)
from generate_parameter_library_py.generate_cpp_header import parse_args


Expand Down Expand Up @@ -100,3 +103,46 @@ def test_parse_valid_parameter_files(yaml_test_file):
set_up(yaml_test_file)
except Exception as e:
assert False, f'failed to parse valid file, reason:{e}'


@pytest.mark.parametrize(
'defined_type,default_value',
[
('int_array_fixed_03', [101, 102, 103, 104]),
('double_array_fixed_03', [1.0, 2.0, 3.0, 4.0]),
('string_array_fixed_03', ['a', 'b', 'c', 'd']),
('string_fixed_03', 'abcd'),
],
)
def test_fixed_default_cannot_exceed_capacity(defined_type, default_value):
with pytest.raises(YAMLSyntaxError, match='exceeds the capacity'):
preprocess_inputs(
'cpp',
'test_param',
{'type': defined_type, 'default_value': default_value},
['test_namespace'],
)


def test_fixed_default_must_satisfy_fixed_size_validator():
with pytest.raises(YAMLSyntaxError, match="'fixed_size' validation requires 3"):
preprocess_inputs(
'cpp',
'test_param',
{
'type': 'int_array_fixed_03',
'default_value': [101, 102],
'validation': {'fixed_size<>': 3},
},
['test_namespace'],
)


@pytest.mark.parametrize('default_value', [[101, 102], [101, 102, 103]])
def test_fixed_default_at_or_below_capacity_is_valid(default_value):
preprocess_inputs(
'cpp',
'test_param',
{'type': 'int_array_fixed_03', 'default_value': default_value},
['test_namespace'],
)