Skip to content

Commit faf52a3

Browse files
committed
Add tests for cubelist combine functions (and fix).
1 parent 3851b0f commit faf52a3

File tree

2 files changed

+52
-17
lines changed

2 files changed

+52
-17
lines changed

lib/iris/cube.py

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -640,27 +640,13 @@ def combine(self, options: str | dict | None = None, **kwargs) -> CubeList:
640640
return combine_cubes(self, options, **kwargs)
641641

642642
def combine_cube(self, options: str | dict | None = None, **kwargs) -> CubeList:
643-
result = self.combine()
643+
result = self.combine(options, **kwargs)
644644
n_cubes = len(result)
645645
if n_cubes != 1:
646-
from iris.util import _combine_options_asdict
647-
648-
opts_dict = _combine_options_asdict(options)
649-
merge_concat_sequence = opts_dict.get("merge_concat_sequence")
650-
is_merge = (
651-
not isinstance(merge_concat_sequence, str)
652-
or len(merge_concat_sequence) < 0
653-
or not merge_concat_sequence.endswith("m")
654-
)
655-
err_type = (
656-
iris.exceptions.MergeError
657-
if is_merge
658-
else iris.exceptions.ConcatenateError
659-
)
660646
msg = f"'combine' operation yielded {n_cubes} cubes, expected exactly 1."
661-
raise err_type(msg)
647+
raise ValueError(msg)
662648

663-
return result
649+
return result[0]
664650

665651
def realise_data(self):
666652
"""Fetch 'real' data for all cubes, in a shared calculation.

lib/iris/tests/unit/cube/test_CubeList.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -719,3 +719,52 @@ def test__repr_html_(mocker):
719719
# "CubeListRepresentation(cubelist).repr_html()" was called exactly once, with no args
720720
mock.call()
721721
]
722+
723+
724+
class Test_combine__apis:
725+
"""Confirm that CubeList.combine/combine_cube just call combine_cubes."""
726+
727+
def mock_combine_cubes(self):
728+
def mock_call(cubes, options=None, **kwargs):
729+
self.call_params = [cubes, options, kwargs]
730+
return cubes # used to test effect of different cases
731+
732+
return mock_call
733+
734+
def test_combine(self):
735+
cubelist = CubeList([])
736+
arg = mock.sentinel.options_arg
737+
kwargs = dict(
738+
key_test_1=1,
739+
key_test_2=2,
740+
)
741+
with mock.patch("iris.util.combine_cubes", self.mock_combine_cubes()):
742+
result = cubelist.combine(arg, **kwargs)
743+
assert self.call_params == [cubelist, arg, kwargs]
744+
assert result == cubelist
745+
746+
@pytest.mark.parametrize("ncubes", [0, 1, 2], ids=["nocubes", "onecube", "ncubes"])
747+
def test_combine_cube(self, ncubes):
748+
"""In this case, also check behaviour for result of <1 =1 >1 cubes."""
749+
cubelist = CubeList(
750+
[Cube([0], long_name=f"cube_{i_cube})") for i_cube in range(ncubes)]
751+
)
752+
arg = mock.sentinel.options_arg
753+
kwargs = dict(
754+
key_test_1=1,
755+
key_test_2=2,
756+
)
757+
if ncubes == 1:
758+
with mock.patch("iris.util.combine_cubes", self.mock_combine_cubes()):
759+
result = cubelist.combine_cube(arg, **kwargs)
760+
assert self.call_params == [cubelist, arg, kwargs]
761+
assert result == cubelist[0]
762+
else:
763+
if ncubes == 0:
764+
msg = "'combine' operation yielded 0 cubes, expected exactly 1"
765+
else:
766+
msg = f"'combine' operation yielded {ncubes} cubes, expected exactly 1"
767+
768+
with mock.patch("iris.util.combine_cubes", self.mock_combine_cubes()):
769+
with pytest.raises(ValueError, match=msg):
770+
result = cubelist.combine_cube(arg, **kwargs)

0 commit comments

Comments
 (0)