Skip to content

Commit c58ceb7

Browse files
committed
Convert Test_difference to pytest.
1 parent e0e669c commit c58ceb7

File tree

1 file changed

+119
-175
lines changed

1 file changed

+119
-175
lines changed

lib/iris/tests/unit/common/metadata/test_CubeMetadata.py

Lines changed: 119 additions & 175 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ def test_op_different__attribute_value(self, op_leniency):
444444
lmetadata = self.cls(**self.lvalues)
445445
rmetadata = self.cls(**self.rvalues)
446446

447-
# Result contains entirely EMPTY attributes (either strict or lenient).
447+
# Result has entirely EMPTY attributes (whether strict or lenient).
448448
# TODO: is this maybe a mistake of the existing implementation ?
449449
expected = self.lvalues.copy()
450450
expected["attributes"] = None
@@ -457,30 +457,31 @@ def test_op_different__attribute_value(self, op_leniency):
457457
assert rmetadata.combine(lmetadata)._asdict() == expected
458458

459459

460-
class Test_difference(tests.IrisTest):
461-
def setUp(self):
462-
self.values = dict(
460+
class Test_difference:
461+
@pytest.fixture(autouse=True)
462+
def setup(self):
463+
self.lvalues = dict(
463464
standard_name=sentinel.standard_name,
464465
long_name=sentinel.long_name,
465466
var_name=sentinel.var_name,
466467
units=sentinel.units,
467-
attributes=sentinel.attributes,
468+
attributes=dict(), # MUST be a dict
468469
cell_methods=sentinel.cell_methods,
469470
)
471+
# Make a copy with all-different objects in it.
472+
self.rvalues = deepcopy(self.lvalues)
470473
self.dummy = sentinel.dummy
471474
self.cls = CubeMetadata
472475
self.none = self.cls(*(None,) * len(self.cls._fields))
473476

474477
def test_wraps_docstring(self):
475-
self.assertEqual(
476-
BaseMetadata.difference.__doc__, self.cls.difference.__doc__
477-
)
478+
assert self.cls.difference.__doc__ == BaseMetadata.difference.__doc__
478479

479480
def test_lenient_service(self):
480481
qualname_difference = _qualname(self.cls.difference)
481-
self.assertIn(qualname_difference, _LENIENT)
482-
self.assertTrue(_LENIENT[qualname_difference])
483-
self.assertTrue(_LENIENT[self.cls.difference])
482+
assert qualname_difference in _LENIENT
483+
assert _LENIENT[qualname_difference]
484+
assert _LENIENT[self.cls.difference]
484485

485486
def test_lenient_default(self):
486487
other = sentinel.other
@@ -490,11 +491,8 @@ def test_lenient_default(self):
490491
) as mocker:
491492
result = self.none.difference(other)
492493

493-
self.assertEqual(return_value, result)
494-
self.assertEqual(1, mocker.call_count)
495-
(arg,), kwargs = mocker.call_args
496-
self.assertEqual(other, arg)
497-
self.assertEqual(dict(lenient=None), kwargs)
494+
assert return_value == result
495+
assert mocker.call_args_list == [mock.call(other, lenient=None)]
498496

499497
def test_lenient(self):
500498
other = sentinel.other
@@ -505,178 +503,124 @@ def test_lenient(self):
505503
) as mocker:
506504
result = self.none.difference(other, lenient=lenient)
507505

508-
self.assertEqual(return_value, result)
509-
self.assertEqual(1, mocker.call_count)
510-
(arg,), kwargs = mocker.call_args
511-
self.assertEqual(other, arg)
512-
self.assertEqual(dict(lenient=lenient), kwargs)
506+
assert return_value == result
507+
assert mocker.call_args_list == [mock.call(other, lenient=lenient)]
513508

514-
def test_op_lenient_same(self):
515-
lmetadata = self.cls(**self.values)
516-
rmetadata = self.cls(**self.values)
517-
518-
with mock.patch("iris.common.metadata._LENIENT", return_value=True):
519-
self.assertIsNone(lmetadata.difference(rmetadata))
520-
self.assertIsNone(rmetadata.difference(lmetadata))
521-
522-
def test_op_lenient_same_none(self):
523-
lmetadata = self.cls(**self.values)
524-
right = self.values.copy()
525-
right["var_name"] = None
526-
rmetadata = self.cls(**right)
527-
528-
with mock.patch("iris.common.metadata._LENIENT", return_value=True):
529-
self.assertIsNone(lmetadata.difference(rmetadata))
530-
self.assertIsNone(rmetadata.difference(lmetadata))
531-
532-
def test_op_lenient_same_cell_methods_none(self):
533-
lmetadata = self.cls(**self.values)
534-
right = self.values.copy()
535-
right["cell_methods"] = None
536-
rmetadata = self.cls(**right)
537-
lexpected = deepcopy(self.none)._asdict()
538-
lexpected["cell_methods"] = (sentinel.cell_methods, None)
539-
rexpected = deepcopy(self.none)._asdict()
540-
rexpected["cell_methods"] = (None, sentinel.cell_methods)
541-
542-
with mock.patch("iris.common.metadata._LENIENT", return_value=True):
543-
self.assertEqual(
544-
lexpected, lmetadata.difference(rmetadata)._asdict()
545-
)
546-
self.assertEqual(
547-
rexpected, rmetadata.difference(lmetadata)._asdict()
548-
)
509+
def test_op_same(self, op_leniency):
510+
is_lenient = op_leniency == "lenient"
511+
lmetadata = self.cls(**self.lvalues)
512+
rmetadata = self.cls(**self.rvalues)
549513

550-
def test_op_lenient_different(self):
551-
left = self.values.copy()
552-
lmetadata = self.cls(**left)
553-
right = self.values.copy()
554-
right["units"] = self.dummy
555-
rmetadata = self.cls(**right)
556-
lexpected = deepcopy(self.none)._asdict()
557-
lexpected["units"] = (left["units"], right["units"])
558-
rexpected = deepcopy(self.none)._asdict()
559-
rexpected["units"] = lexpected["units"][::-1]
560-
561-
with mock.patch("iris.common.metadata._LENIENT", return_value=True):
562-
self.assertEqual(
563-
lexpected, lmetadata.difference(rmetadata)._asdict()
564-
)
565-
self.assertEqual(
566-
rexpected, rmetadata.difference(lmetadata)._asdict()
567-
)
514+
with mock.patch(
515+
"iris.common.metadata._LENIENT", return_value=is_lenient
516+
):
517+
assert lmetadata.difference(rmetadata) is None
518+
assert rmetadata.difference(lmetadata) is None
568519

569-
def test_op_lenient_different_cell_methods(self):
570-
left = self.values.copy()
571-
lmetadata = self.cls(**left)
572-
right = self.values.copy()
573-
right["cell_methods"] = self.dummy
574-
rmetadata = self.cls(**right)
575-
lexpected = deepcopy(self.none)._asdict()
576-
lexpected["cell_methods"] = (
577-
left["cell_methods"],
578-
right["cell_methods"],
579-
)
580-
rexpected = deepcopy(self.none)._asdict()
581-
rexpected["cell_methods"] = lexpected["cell_methods"][::-1]
520+
def test_op_different__none(self, fieldname, op_leniency):
521+
if fieldname in ("attributes",): # 'units'):
522+
# These cannot properly be set to 'None'. Tested elsewhere.
523+
pytest.skip()
582524

583-
with mock.patch("iris.common.metadata._LENIENT", return_value=True):
584-
self.assertEqual(
585-
lexpected, lmetadata.difference(rmetadata)._asdict()
586-
)
587-
self.assertEqual(
588-
rexpected, rmetadata.difference(lmetadata)._asdict()
589-
)
525+
is_lenient = op_leniency == "lenient"
526+
527+
lmetadata = self.cls(**self.lvalues)
528+
self.rvalues[fieldname] = None
529+
rmetadata = self.cls(**self.rvalues)
590530

591-
def test_op_strict_same(self):
592-
lmetadata = self.cls(**self.values)
593-
rmetadata = self.cls(**self.values)
594-
595-
with mock.patch("iris.common.metadata._LENIENT", return_value=False):
596-
self.assertIsNone(lmetadata.difference(rmetadata))
597-
self.assertIsNone(rmetadata.difference(lmetadata))
598-
599-
def test_op_strict_different(self):
600-
left = self.values.copy()
601-
lmetadata = self.cls(**left)
602-
right = self.values.copy()
603-
right["long_name"] = self.dummy
604-
rmetadata = self.cls(**right)
605-
lexpected = deepcopy(self.none)._asdict()
606-
lexpected["long_name"] = (left["long_name"], right["long_name"])
607-
rexpected = deepcopy(self.none)._asdict()
608-
rexpected["long_name"] = lexpected["long_name"][::-1]
609-
610-
with mock.patch("iris.common.metadata._LENIENT", return_value=False):
611-
self.assertEqual(
612-
lexpected, lmetadata.difference(rmetadata)._asdict()
531+
if fieldname in ("units", "cell_methods"):
532+
# These ones are always "strict"
533+
strict_result = True
534+
elif fieldname in ("standard_name", "long_name", "var_name"):
535+
strict_result = not is_lenient
536+
else:
537+
# Ensure we are handling all the different field cases
538+
raise ValueError(
539+
f"{self.__name__} unhandled fieldname : {fieldname}"
613540
)
614-
self.assertEqual(
615-
rexpected, rmetadata.difference(lmetadata)._asdict()
541+
542+
if strict_result:
543+
diffentry = tuple(
544+
[getattr(mm, fieldname) for mm in (lmetadata, rmetadata)]
616545
)
546+
lexpected = self.none._asdict()
547+
lexpected[fieldname] = diffentry
548+
rexpected = lexpected.copy()
549+
rexpected[fieldname] = diffentry[::-1]
550+
# NOTE: in these cases, the difference metadata will fail an == operation,
551+
# because of the 'None' entries.
552+
# But we can use metadata._asdict() and test that.
617553

618-
def test_op_strict_different_cell_methods(self):
619-
left = self.values.copy()
620-
lmetadata = self.cls(**left)
621-
right = self.values.copy()
622-
right["cell_methods"] = self.dummy
623-
rmetadata = self.cls(**right)
624-
lexpected = deepcopy(self.none)._asdict()
625-
lexpected["cell_methods"] = (
626-
left["cell_methods"],
627-
right["cell_methods"],
628-
)
629-
rexpected = deepcopy(self.none)._asdict()
630-
rexpected["cell_methods"] = lexpected["cell_methods"][::-1]
554+
with mock.patch(
555+
"iris.common.metadata._LENIENT", return_value=is_lenient
556+
):
557+
if strict_result:
558+
assert lmetadata.difference(rmetadata)._asdict() == lexpected
559+
assert rmetadata.difference(lmetadata)._asdict() == rexpected
560+
else:
561+
# Expect NO differences
562+
assert lmetadata.difference(rmetadata) is None
563+
assert rmetadata.difference(lmetadata) is None
631564

632-
with mock.patch("iris.common.metadata._LENIENT", return_value=False):
633-
self.assertEqual(
634-
lexpected, lmetadata.difference(rmetadata)._asdict()
635-
)
636-
self.assertEqual(
637-
rexpected, rmetadata.difference(lmetadata)._asdict()
638-
)
565+
def test_op_different__attribute_extra(self, op_leniency):
566+
is_lenient = op_leniency == "lenient"
567+
self.lvalues["attributes"] = {"_a_common_": self.dummy}
568+
lmetadata = self.cls(**self.lvalues)
569+
rvalues = deepcopy(self.lvalues)
570+
rvalues["attributes"]["_b_extra_"] = mock.sentinel.extra
571+
rmetadata = self.cls(**rvalues)
572+
573+
if not is_lenient:
574+
# In this case, attributes returns a "difference dictionary"
575+
diffentry = tuple([{}, {"_b_extra_": mock.sentinel.extra}])
576+
lexpected = self.none._asdict()
577+
lexpected["attributes"] = diffentry
578+
rexpected = lexpected.copy()
579+
rexpected["attributes"] = diffentry[::-1]
639580

640-
def test_op_strict_different_none(self):
641-
left = self.values.copy()
642-
lmetadata = self.cls(**left)
643-
right = self.values.copy()
644-
right["long_name"] = None
645-
rmetadata = self.cls(**right)
646-
lexpected = deepcopy(self.none)._asdict()
647-
lexpected["long_name"] = (left["long_name"], right["long_name"])
648-
rexpected = deepcopy(self.none)._asdict()
649-
rexpected["long_name"] = lexpected["long_name"][::-1]
650-
651-
with mock.patch("iris.common.metadata._LENIENT", return_value=False):
652-
self.assertEqual(
653-
lexpected, lmetadata.difference(rmetadata)._asdict()
654-
)
655-
self.assertEqual(
656-
rexpected, rmetadata.difference(lmetadata)._asdict()
657-
)
581+
with mock.patch(
582+
"iris.common.metadata._LENIENT", return_value=is_lenient
583+
):
584+
if is_lenient:
585+
# It recognises no difference
586+
assert lmetadata.difference(rmetadata) is None
587+
assert rmetadata.difference(lmetadata) is None
588+
else:
589+
# As calculated above
590+
assert lmetadata.difference(rmetadata)._asdict() == lexpected
591+
assert rmetadata.difference(lmetadata)._asdict() == rexpected
592+
593+
def test_op_different__attribute_value(self, op_leniency):
594+
is_lenient = op_leniency == "lenient"
595+
self.lvalues["attributes"] = {
596+
"_a_common_": self.dummy,
597+
"_b_extra_": mock.sentinel.value1,
598+
}
599+
lmetadata = self.cls(**self.lvalues)
600+
self.rvalues["attributes"] = {
601+
"_a_common_": self.dummy,
602+
"_b_extra_": mock.sentinel.value2,
603+
}
604+
rmetadata = self.cls(**self.rvalues)
658605

659-
def test_op_strict_different_measure_none(self):
660-
left = self.values.copy()
661-
lmetadata = self.cls(**left)
662-
right = self.values.copy()
663-
right["cell_methods"] = None
664-
rmetadata = self.cls(**right)
665-
lexpected = deepcopy(self.none)._asdict()
666-
lexpected["cell_methods"] = (
667-
left["cell_methods"],
668-
right["cell_methods"],
606+
# In this case, attributes returns a "difference dictionary"
607+
diffentry = tuple(
608+
[
609+
{"_b_extra_": mock.sentinel.value1},
610+
{"_b_extra_": mock.sentinel.value2},
611+
]
669612
)
670-
rexpected = deepcopy(self.none)._asdict()
671-
rexpected["cell_methods"] = lexpected["cell_methods"][::-1]
613+
lexpected = self.none._asdict()
614+
lexpected["attributes"] = diffentry
615+
rexpected = lexpected.copy()
616+
rexpected["attributes"] = diffentry[::-1]
672617

673-
with mock.patch("iris.common.metadata._LENIENT", return_value=False):
674-
self.assertEqual(
675-
lexpected, lmetadata.difference(rmetadata)._asdict()
676-
)
677-
self.assertEqual(
678-
rexpected, rmetadata.difference(lmetadata)._asdict()
679-
)
618+
with mock.patch(
619+
"iris.common.metadata._LENIENT", return_value=is_lenient
620+
):
621+
# As calculated above -- same for both strict + lenient
622+
assert lmetadata.difference(rmetadata)._asdict() == lexpected
623+
assert rmetadata.difference(lmetadata)._asdict() == rexpected
680624

681625

682626
class Test_equal(tests.IrisTest):

0 commit comments

Comments
 (0)