django_coverage_plugin icon indicating copy to clipboard operation
django_coverage_plugin copied to clipboard

Widget templates not covered (when they are clearly used).

Open PetrDlouhy opened this issue 1 year ago • 2 comments
trafficstars

I have Widget such as:

class PlanChoiceWidget(RadioSelect):
    option_template_name = "plans/plan_choice_widget.html"

and tests such as:

class PlanChoiceWidgetTests1(TestCase):

    def setUp(self):
        self.factory = RequestFactory()
        self.plan_pricing = baker.make(
            "PlanPricing", plan__name="Foo", price=Decimal("10.00"),
            has_automatic_renewal=True
        )
        self.request = self.factory.get("")
        self.request.user = baker.make("accounts.UserProfile")

    def render_widget(self, plan):
        widget = PlanChoiceWidget()
        choice_data = {
            "name": "plan_choice",
            "value": plan.pk,
            "attrs": {"id": "id_plan_choice"},
        }
        widget.choices = [(plan.pk, plan)]
        widget.request = self.request
        return widget.render(**choice_data)

    def test_plan_choice_widget_render(self):
        rendered_html = self.render_widget(self.plan_pricing)

        self.assertInHTML(
            '<div class="pricing-plans-price__price jsPricingPlansCardPriceWhole">10</div>',
            rendered_html,
        )
        self.assertIn('data-amount="10.00"', rendered_html)
        self.assertIn('data-renewal="True"', rendered_html)

    def test_non_recurring_plan(self):
        self.plan_pricing.has_automatic_renewal = False
        self.plan_pricing.save()

        rendered_html = self.render_widget(self.plan_pricing)

        self.assertIn('<input type="radio" name="plan_choice"', rendered_html)

When I look at the coverage it shows 0% for this template although lines from plans/plan_choice_widget.html template are matched by the tests.

My .coveragerc:

[run]
omit =
   */virtualenvs/*
   */migrations/*
   */site-packages/*
   *.txt
   */settings/dev.py
plugins =
    django_coverage_plugin
branch = True
source = blenderhub
relative_files = True

I am using django-coverage-plugin version 3.1.0, coverage version 7.4.1.

More widget templates from my project are not matched. Is this a known problem or should I gather more information?

PetrDlouhy avatar Apr 29 '24 15:04 PetrDlouhy

I believe this is because the function that sniffs the frame for the filename fails to work on a template render - it seems that the self object in the relevant context only contains a NodeList, which does not have an origin.

schinckel avatar May 24 '24 00:05 schinckel

I'll create a PR shortly, but my patch seems to work (waiting on a CI run to check).

@@ -104,5 +104,15 @@
 def filename_for_frame(frame):
     try:
-        return frame.f_locals["self"].origin.name
-    except (KeyError, AttributeError):
+        self = frame.f_locals["self"]
+    except KeyError:
         return None
+
+    try:
+        return self.origin.name
+    except AttributeError:
+        pass
+
+    try:
+        return self[0].origin.name
+    except (IndexError, AttributeError):
+        pass

schinckel avatar May 24 '24 01:05 schinckel