diff --git a/src/openjd/model/_step_param_space_iter.py b/src/openjd/model/_step_param_space_iter.py index 88a1024..cf4e840 100644 --- a/src/openjd/model/_step_param_space_iter.py +++ b/src/openjd/model/_step_param_space_iter.py @@ -65,20 +65,26 @@ class StepParameterSpaceIterator(Iterable[TaskParameterSet], Sized): """ _parameters: dict[str, TaskParameter] - _expr_tree: Node + _expr_tree: Union[Node, list] _parsedtree: CombinationExpressionNode - def __init__(self, *, space: StepParameterSpace): - if space.combination is None: - # space.taskParameterDefinitions is a dict[str,TaskParameter] - combination = "*".join(name for name in space.taskParameterDefinitions) + def __init__(self, *, space: Optional[StepParameterSpace]): + # Special case the zero-dimensional space with one element + if space is None: + self._parameters = {} + self._parsetree = None + self._expr_tree = [{}] else: - combination = space.combination - self._parameters = dict(space.taskParameterDefinitions) + if space.combination is None: + # space.taskParameterDefinitions is a dict[str,TaskParameter] + combination = "*".join(name for name in space.taskParameterDefinitions) + else: + combination = space.combination + self._parameters = dict(space.taskParameterDefinitions) - # Raises: TokenError, ExpressionError - self._parsetree = CombinationExpressionParser().parse(combination) - self._expr_tree = self._create_expr_tree(self._parsetree) + # Raises: TokenError, ExpressionError + self._parsetree = CombinationExpressionParser().parse(combination) + self._expr_tree = self._create_expr_tree(self._parsetree) @property def names(self) -> AbstractSet[str]: @@ -107,7 +113,10 @@ def __next__(self) -> TaskParameterSet: self._root.next(result) return result - return Iter(self._expr_tree) + if isinstance(self._expr_tree, Node): + return Iter(self._expr_tree) + else: + return iter(self._expr_tree) def __len__(self) -> int: """The number of task parameter sets that are defined by this parameter space""" diff --git a/test/openjd/model/test_step_param_space_iter.py b/test/openjd/model/test_step_param_space_iter.py index 1be56e5..b3b4be1 100644 --- a/test/openjd/model/test_step_param_space_iter.py +++ b/test/openjd/model/test_step_param_space_iter.py @@ -8,7 +8,11 @@ ParameterValue, ParameterValueType, StepParameterSpaceIterator, + create_job, + parse_model, ) + +from openjd.model.v2023_09 import JobTemplate as JobTemplate_2023_09 from openjd.model.v2023_09 import ( RangeExpressionTaskParameterDefinition as RangeExpressionTaskParameterDefinition_2023_09, ) @@ -51,6 +55,52 @@ def test_names(self, range_int_param): # THEN assert result.names == set(("Param1", "Param2")) + def test_no_param_iteration(self): + # GIVEN + expected = [{}] + # The parameter space is None in the mdoel when there are no parameters + template_data = { + "specificationVersion": "jobtemplate-2023-09", + "name": "Job", + "steps": [{"name": "step", "script": {"actions": {"onRun": {"command": "do thing"}}}}], + } + job_template = parse_model(model=JobTemplate_2023_09, obj=template_data) + job = create_job(job_template=job_template, job_parameter_values=dict()) + + space = job.steps[0].parameterSpace + iterator = StepParameterSpaceIterator(space=space) + + # WHEN + result = list(iterator) + + # THEN + assert result == expected + + def test_no_param_getelem(self): + # GIVEN + # The parameter space in a job with no task parameters + template_data = { + "specificationVersion": "jobtemplate-2023-09", + "name": "Job", + "steps": [{"name": "step", "script": {"actions": {"onRun": {"command": "do thing"}}}}], + } + job_template = parse_model(model=JobTemplate_2023_09, obj=template_data) + job = create_job(job_template=job_template, job_parameter_values=dict()) + + space = job.steps[0].parameterSpace + + # WHEN + result = StepParameterSpaceIterator(space=space) + + # THEN + with pytest.raises(IndexError): + result[1] + with pytest.raises(IndexError): + result[-2] + expected = {} + assert result[0] == expected + assert result[-1] == expected + @pytest.mark.parametrize( "range_int_param", [