-
Notifications
You must be signed in to change notification settings - Fork 431
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactored optimizer tests to use a contextmanager
- Loading branch information
Showing
1 changed file
with
57 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,6 +2,7 @@ | |
# Gramps - a GTK+/GNOME based genealogy program | ||
# | ||
# Copyright (C) 2016 Tom Samstag | ||
# Copyright (C) 2025 Doug Blank <[email protected]> | ||
# | ||
# This program is free software; you can redistribute it and/or modify | ||
# it under the terms of the GNU General Public License as published by | ||
|
@@ -22,10 +23,10 @@ | |
Unittest that tests person-specific filter rules | ||
""" | ||
import unittest | ||
from unittest.mock import patch | ||
import os | ||
from time import perf_counter | ||
import inspect | ||
from contextlib import contextmanager | ||
|
||
from ....filters import reload_custom_filters | ||
|
||
|
@@ -103,6 +104,37 @@ | |
EXAMPLE = os.path.join(TEST_DIR, "example.gramps") | ||
|
||
|
||
@contextmanager | ||
def count_method_calls(cls, method_name): | ||
""" | ||
Context manager to monkey-patch a method and count its calls. | ||
Args: | ||
cls: The class containing the method. | ||
method_name: The name of the method to patch. | ||
Yields: | ||
A callable that returns the call count. | ||
""" | ||
original_method = getattr(cls, method_name) | ||
call_count = 0 | ||
|
||
def patched_method(self, *args, **kwargs): | ||
nonlocal call_count | ||
call_count += 1 | ||
return original_method(self, *args, **kwargs) | ||
|
||
setattr(cls, method_name, patched_method) | ||
|
||
def get_call_count(): | ||
return call_count | ||
|
||
try: | ||
yield get_call_count | ||
finally: | ||
setattr(cls, method_name, original_method) | ||
|
||
|
||
class BaseTest(unittest.TestCase): | ||
""" | ||
Person rule tests. | ||
|
@@ -1090,36 +1122,33 @@ def test_isdefaultperson(self): | |
), | ||
) | ||
|
||
@patch("gramps.gen.filters.rules.person.IsDefaultPerson.apply_to_one") | ||
def test_isdefaultperson_optimized(self, mock): | ||
def test_isdefaultperson_optimized(self): | ||
""" | ||
Test IsDefaultPerson rule. | ||
""" | ||
mock.return_value = True | ||
rule = IsDefaultPerson([]) | ||
self.assertEqual( | ||
self.filter_with_rule(rule), | ||
set( | ||
[ | ||
"GNUJQCL9MD64AM56OH", | ||
] | ||
), | ||
) | ||
# This used the optimizer, so it didn't loop through DB | ||
self.assertEqual(mock.call_count, 1) | ||
|
||
@patch("gramps.gen.filters.rules.person.IsFemale.apply_to_one") | ||
def test_isfemale_not_optimized(self, mock): | ||
""" | ||
Test IsFemale rule. | ||
""" | ||
# Make everyone a female for this test: | ||
mock.return_value = True | ||
rule = IsFemale([]) | ||
# too many to list out to test explicitly | ||
self.assertEqual(len(self.filter_with_rule(rule)), 2128) | ||
# This did not use the optimizer, so it did loop through DB | ||
self.assertEqual(mock.call_count, 2128) | ||
with count_method_calls(IsDefaultPerson, "apply_to_one") as get_call_count: | ||
rule = IsDefaultPerson([]) | ||
self.assertEqual( | ||
self.filter_with_rule(rule), | ||
set( | ||
[ | ||
"GNUJQCL9MD64AM56OH", | ||
] | ||
), | ||
) | ||
# This used the optimizer, so it didn't loop through DB | ||
self.assertEqual(get_call_count(), 1) | ||
|
||
def test_isfemale_not_optimized(self): | ||
""" | ||
Test IsFemale rule. Same as below, but tests optimizer. | ||
""" | ||
with count_method_calls(IsFemale, "apply_to_one") as get_call_count: | ||
rule = IsFemale([]) | ||
# too many to list out to test explicitly | ||
self.assertEqual(len(self.filter_with_rule(rule)), 940) | ||
# This did not use the optimizer, so it did loop through DB | ||
self.assertEqual(get_call_count(), self.db.get_number_of_people()) | ||
|
||
def test_isfemale(self): | ||
""" | ||
|