From fdc195465b1c44c8638b7b7aa3f0c48c5e9647aa Mon Sep 17 00:00:00 2001 From: Sebastian Rittau Date: Tue, 12 Dec 2023 16:41:18 +0100 Subject: [PATCH] Add tests for TestCase.assertDictEqual() (#11154) --- stdlib/unittest/case.pyi | 2 ++ test_cases/stdlib/check_unittest.py | 51 ++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/stdlib/unittest/case.pyi b/stdlib/unittest/case.pyi index cc5d683e2..7efe6cdc9 100644 --- a/stdlib/unittest/case.pyi +++ b/stdlib/unittest/case.pyi @@ -249,6 +249,8 @@ class TestCase: def assertListEqual(self, list1: list[Any], list2: list[Any], msg: Any = None) -> None: ... def assertTupleEqual(self, tuple1: tuple[Any, ...], tuple2: tuple[Any, ...], msg: Any = None) -> None: ... def assertSetEqual(self, set1: AbstractSet[object], set2: AbstractSet[object], msg: Any = None) -> None: ... + # assertDictEqual accepts only true dict instances. We can't use that here, since that would make + # assertDictEqual incompatible with TypedDict. def assertDictEqual(self, d1: Mapping[Any, object], d2: Mapping[Any, object], msg: Any = None) -> None: ... def fail(self, msg: Any = None) -> NoReturn: ... def countTestCases(self) -> int: ... diff --git a/test_cases/stdlib/check_unittest.py b/test_cases/stdlib/check_unittest.py index 3a9edafef..140dcb368 100644 --- a/test_cases/stdlib/check_unittest.py +++ b/test_cases/stdlib/check_unittest.py @@ -1,10 +1,11 @@ from __future__ import annotations import unittest +from collections.abc import Iterator, Mapping from datetime import datetime, timedelta from decimal import Decimal from fractions import Fraction -from typing_extensions import assert_type +from typing_extensions import TypedDict, assert_type from unittest.mock import MagicMock, Mock, patch case = unittest.TestCase() @@ -89,6 +90,54 @@ case.assertGreater(Spam(), Eggs()) # type: ignore case.assertGreater(Ham(), Bacon()) # type: ignore case.assertGreater(Bacon(), Ham()) # type: ignore + +### +# Tests for assertDictEqual +### + + +class TD1(TypedDict): + x: int + y: str + + +class TD2(TypedDict): + a: bool + b: bool + + +class MyMapping(Mapping[str, int]): + def __getitem__(self, __key: str) -> int: + return 42 + + def __iter__(self) -> Iterator[str]: + return iter([]) + + def __len__(self) -> int: + return 0 + + +td1: TD1 = {"x": 1, "y": "foo"} +td2: TD2 = {"a": True, "b": False} +m = MyMapping() + +case.assertDictEqual({}, {}) +case.assertDictEqual({"x": 1, "y": 2}, {"x": 1, "y": 2}) +case.assertDictEqual({"x": 1, "y": "foo"}, {"y": "foo", "x": 1}) +case.assertDictEqual({"x": 1}, {}) +case.assertDictEqual({}, {"x": 1}) +case.assertDictEqual({1: "x"}, {"y": 222}) +case.assertDictEqual({1: "x"}, td1) +case.assertDictEqual(td1, {1: "x"}) +case.assertDictEqual(td1, td2) + +case.assertDictEqual(1, {}) # type: ignore +case.assertDictEqual({}, 1) # type: ignore + +# These should fail, but don't due to TypedDict limitations: +# case.assertDictEqual(m, {"": 0}) # xtype: ignore +# case.assertDictEqual({"": 0}, m) # xtype: ignore + ### # Tests for mock.patch ###