Skip to content

Commit

Permalink
Refactored optimizer tests to use a contextmanager
Browse files Browse the repository at this point in the history
  • Loading branch information
dsblank committed Feb 1, 2025
1 parent d88b14d commit fe7902b
Showing 1 changed file with 57 additions and 28 deletions.
85 changes: 57 additions & 28 deletions gramps/gen/filters/rules/test/person_rules_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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):
"""
Expand Down

0 comments on commit fe7902b

Please sign in to comment.