diff --git a/patterns/structural/flyweight_with_metaclass.py b/patterns/structural/flyweight_with_metaclass.py index ced8d915..79844234 100644 --- a/patterns/structural/flyweight_with_metaclass.py +++ b/patterns/structural/flyweight_with_metaclass.py @@ -19,12 +19,11 @@ def __new__(mcs, name, parents, dct): def _serialize_params(cls, *args, **kwargs): """ Serialize input parameters to a key. - Simple implementation is just to serialize it as a string + Simple implementation is just to serialize it as a string. ``repr`` keeps + ``("1", "0")``, ``("10",)`` and ``(1,)`` apart, and sorting the keyword + arguments makes the key independent of their order. """ - args_list = list(map(str, args)) - args_list.extend([str(kwargs), cls.__name__]) - key = "".join(args_list) - return key + return repr((cls.__name__, args, sorted(kwargs.items()))) def __call__(cls, *args, **kwargs): key = FlyweightMeta._serialize_params(cls, *args, **kwargs) diff --git a/tests/structural/test_flyweight_with_metaclass.py b/tests/structural/test_flyweight_with_metaclass.py new file mode 100644 index 00000000..5a342182 --- /dev/null +++ b/tests/structural/test_flyweight_with_metaclass.py @@ -0,0 +1,26 @@ +from patterns.structural.flyweight_with_metaclass import Card2 + + +def test_same_arguments_share_an_instance(): + Card2.pool.clear() + assert Card2("10", "h", a=1) is Card2("10", "h", a=1) + + +def test_different_arguments_do_not_share_an_instance(): + Card2.pool.clear() + assert Card2("10", "h", a=1) is not Card2("10", "h", a=2) + + +def test_argument_boundaries_are_part_of_the_key(): + Card2.pool.clear() + assert Card2("1", "0") is not Card2("10") + + +def test_argument_types_are_part_of_the_key(): + Card2.pool.clear() + assert Card2(1) is not Card2("1") + + +def test_keyword_argument_order_does_not_matter(): + Card2.pool.clear() + assert Card2(a=1, b=2) is Card2(b=2, a=1)