<commit_before>"""Endless template tags tests."""

import string

from django.template import (
    Context,
    Template,
    TemplateSyntaxError,
)
from django.test import TestCase
from django.test.client import RequestFactory

from endless_pagination.settings import (
    PAGE_LABEL,
    PER_PAGE,
)


class TemplateTagsTestMixin(object):
    """Base test mixin for template tags."""

    def setUp(self):
        self.factory = RequestFactory()

    def render(self, request, contents, **kwargs):
        """Render *contents* using given *request*.

        The context data is represented by keyword arguments.
        Is no keyword arguments are provided, a default context will be used.

        Return the generated HTML and the modified context.
        """
        template = Template('{% load endless %}' + contents)
        context_data = kwargs.copy() if kwargs else {'objects': range(47)}
        context_data['request'] = request
        context = Context(context_data)
        html = template.render(context)
        return html.strip(), context

    def request(self, url='/', page=None, **kwargs):
        """Return a Django request for the given *page*."""
        querydict = kwargs.copy()
        if page is not None:
            querydict[PAGE_LABEL] = page
        return self.factory.get(url, querydict)


class PaginateTestMixin(TemplateTagsTestMixin):
    """Test mixin for *paginate* and *lazy_paginate* tags.

    Subclasses must define *tagname*.
    """

    def render(self, request, contents, **kwargs):
        text = string.Template(contents).substitute(tagname=self.tagname)
        return super(PaginateTestMixin, self).render(request, text, **kwargs)

    def test_object_list(self):
        # Ensure the queryset is correctly updated.
        template = '{% $tagname objects %}'
        html, context = self.render(self.request(), template)
        self.assertSequenceEqual(range(PER_PAGE), context['objects'])
        self.assertEqual('', html)

    def test_per_page_argument(self):
        # Ensure the queryset reflects the given ``per_page`` argument.
        template = '{% $tagname 20 objects %}'
        _, context = self.render(self.request(), template)
        self.assertSequenceEqual(range(20), context['objects'])

    def test_per_page_argument_as_variable(self):
        # Ensure the queryset reflects the given ``per_page`` argument.
        # In this case, the argument is provided as context variable.
        template = '{% $tagname per_page entries %}'
        _, context = self.render(
            self.request(), template, entries=range(47), per_page=5)
        self.assertSequenceEqual(range(5), context['entries'])

    def test_first_page_argument(self):
        # Ensure the queryset reflects the given ``first_page`` argument.
        template = '{% $tagname 10,20 objects %}'
        _, context = self.render(self.request(), template)
        self.assertSequenceEqual(range(10), context['objects'])
        # Check the second page.
        _, context = self.render(self.request(page=2), template)
        self.assertSequenceEqual(range(10, 30), context['objects'])

    def test_first_page_argument_as_variable(self):
        # Ensure the queryset reflects the given ``first_page`` argument.
        # In this case, the argument is provided as context variable.
        template = '{% $tagname first_page,subsequent_pages entries %}'
        context_data = {
            'entries': range(47),
            'first_page': 1,
            'subsequent_pages': 40,
        }
        _, context = self.render(self.request(), template, **context_data)
        self.assertSequenceEqual([0], context['entries'])
        # Check the second page.
        _, context = self.render(
            self.request(page=2), template, **context_data)
        self.assertSequenceEqual(range(1, 41), context['entries'])

    def test_starting_from_page_argument(self):
        # Ensure the queryset reflects the given ``starting_from_page`` arg.
        template = '{% $tagname 10 objects starting from page 3 %}'
        _, context = self.render(self.request(), template)
        self.assertSequenceEqual(range(20, 30), context['objects'])

    def test_starting_from_page_argument_as_variable(self):
        # Ensure the queryset reflects the given ``starting_from_page`` arg.
        # In this case, the argument is provided as context variable.
        template = '{% $tagname 10 entries starting from page mypage %}'
        _, context = self.render(
            self.request(), template, entries=range(47), mypage=2)
        self.assertSequenceEqual(range(10, 20), context['entries'])

    def test_using_argument(self):
        # Ensure the template tag uses the given querystring key.
        template = '{% $tagname 20 objects using "mypage" %}'
        _, context = self.render(
            self.request(mypage=2), template)
        self.assertSequenceEqual(range(20, 40), context['objects'])

    def test_using_argument_as_variable(self):
        # Ensure the template tag uses the given querystring key.
        # In this case, the argument is provided as context variable.
        template = '{% $tagname 20 entries using qskey %}'
        _, context = self.render(
            self.request(p=3), template, entries=range(47), qskey='p')
        self.assertSequenceEqual(range(40, 47), context['entries'])

    def test_with_argument(self):
        # Ensure the context contains the correct override path.
        template = '{% $tagname 10 objects with "/mypath/" %}'
        _, context = self.render(self.request(), template)
        self.assertEqual('/mypath/', context['endless_override_path'])

    def test_with_argument_as_variable(self):
        # Ensure the context contains the correct override path.
        # In this case, the argument is provided as context variable.
        path = '/my/path/'
        template = '{% $tagname 10 entries with path %}'
        _, context = self.render(
            self.request(), template, entries=range(47), path=path)
        self.assertEqual(path, context['endless_override_path'])

    def test_as_argument(self):
        # Ensure it is possible to change the resulting context variable.
        template = '{% $tagname 20 objects as object_list %}'
        _, context = self.render(self.request(), template)
        self.assertSequenceEqual(range(20), context['object_list'])
        # The input queryset has not been changed.
        self.assertSequenceEqual(range(47), context['objects'])

    def test_complete_argument_list(self):
        # Ensure the tag works providing all the arguments.
        template = (
            '{% $tagname 5,10 objects '
            'starting from page 2 '
            'using mypage '
            'with path '
            'as paginated %}'
        )
        _, context = self.render(
            self.request(), template, objects=range(47), mypage='page-number',
            path='mypath')
        self.assertSequenceEqual(range(5, 15), context['paginated'])
        self.assertEqual('mypath', context['endless_override_path'])

    def test_invalid_arguments(self):
        # An error is raised if invalid arguments are provided.
        templates = (
            '{% $tagname %}',
            '{% $tagname foo bar spam eggs %}',
            '{% $tagname 20 objects as object_list using "mykey" %}',
        )
        request = self.request()
        for template in templates:
            with self.assertRaises(TemplateSyntaxError):
                self.render(request, template)

    def test_nested_context_variable(self):
        # Ensure nested context variables are correctly handled.
        manager = {'all': range(47)}
        template = '{% $tagname 5 manager.all as objects %}'
        _, context = self.render(self.request(), template, manager=manager)
        self.assertSequenceEqual(range(5), context['objects'])

    def test_failing_nested_context_variable(self):
        # An error is raised if a nested context variable is used but no
        # alias is provided.
        manager = {'all': range(47)}
        template = '{% $tagname 5 manager.all %}'
        with self.assertRaises(TemplateSyntaxError) as cm:
            self.render(self.request(), template, manager=manager)
        self.assertIn('manager.all', str(cm.exception))


class PaginateTest(PaginateTestMixin, TestCase):

    tagname = 'paginate'


class LazyPaginateTest(PaginateTestMixin, TestCase):

    tagname = 'lazy_paginate'


class ShowMoreTest(TestCase):

    pass


class GetPagesTest(TestCase):

    pass


class ShowPagesTest(TestCase):

    pass


class ShowCurrentNumberTest(TestCase):

    pass<commit_msg>Added test for multiple pagination.<commit_after>"""Endless template tags tests."""

import string

from django.template import (
    Context,
    Template,
    TemplateSyntaxError,
)
from django.test import TestCase
from django.test.client import RequestFactory

from endless_pagination.settings import (
    PAGE_LABEL,
    PER_PAGE,
)


class TemplateTagsTestMixin(object):
    """Base test mixin for template tags."""

    def setUp(self):
        self.factory = RequestFactory()

    def render(self, request, contents, **kwargs):
        """Render *contents* using given *request*.

        The context data is represented by keyword arguments.
        Is no keyword arguments are provided, a default context will be used.

        Return the generated HTML and the modified context.
        """
        template = Template('{% load endless %}' + contents)
        context_data = kwargs.copy() if kwargs else {'objects': range(47)}
        context_data['request'] = request
        context = Context(context_data)
        html = template.render(context)
        return html.strip(), context

    def request(self, url='/', page=None, **kwargs):
        """Return a Django request for the given *page*."""
        querydict = kwargs.copy()
        if page is not None:
            querydict[PAGE_LABEL] = page
        return self.factory.get(url, querydict)


class PaginateTestMixin(TemplateTagsTestMixin):
    """Test mixin for *paginate* and *lazy_paginate* tags.

    Subclasses must define *tagname*.
    """

    def render(self, request, contents, **kwargs):
        text = string.Template(contents).substitute(tagname=self.tagname)
        return super(PaginateTestMixin, self).render(request, text, **kwargs)

    def test_object_list(self):
        # Ensure the queryset is correctly updated.
        template = '{% $tagname objects %}'
        html, context = self.render(self.request(), template)
        self.assertSequenceEqual(range(PER_PAGE), context['objects'])
        self.assertEqual('', html)

    def test_per_page_argument(self):
        # Ensure the queryset reflects the given ``per_page`` argument.
        template = '{% $tagname 20 objects %}'
        _, context = self.render(self.request(), template)
        self.assertSequenceEqual(range(20), context['objects'])

    def test_per_page_argument_as_variable(self):
        # Ensure the queryset reflects the given ``per_page`` argument.
        # In this case, the argument is provided as context variable.
        template = '{% $tagname per_page entries %}'
        _, context = self.render(
            self.request(), template, entries=range(47), per_page=5)
        self.assertSequenceEqual(range(5), context['entries'])

    def test_first_page_argument(self):
        # Ensure the queryset reflects the given ``first_page`` argument.
        template = '{% $tagname 10,20 objects %}'
        _, context = self.render(self.request(), template)
        self.assertSequenceEqual(range(10), context['objects'])
        # Check the second page.
        _, context = self.render(self.request(page=2), template)
        self.assertSequenceEqual(range(10, 30), context['objects'])

    def test_first_page_argument_as_variable(self):
        # Ensure the queryset reflects the given ``first_page`` argument.
        # In this case, the argument is provided as context variable.
        template = '{% $tagname first_page,subsequent_pages entries %}'
        context_data = {
            'entries': range(47),
            'first_page': 1,
            'subsequent_pages': 40,
        }
        _, context = self.render(self.request(), template, **context_data)
        self.assertSequenceEqual([0], context['entries'])
        # Check the second page.
        _, context = self.render(
            self.request(page=2), template, **context_data)
        self.assertSequenceEqual(range(1, 41), context['entries'])

    def test_starting_from_page_argument(self):
        # Ensure the queryset reflects the given ``starting_from_page`` arg.
        template = '{% $tagname 10 objects starting from page 3 %}'
        _, context = self.render(self.request(), template)
        self.assertSequenceEqual(range(20, 30), context['objects'])

    def test_starting_from_page_argument_as_variable(self):
        # Ensure the queryset reflects the given ``starting_from_page`` arg.
        # In this case, the argument is provided as context variable.
        template = '{% $tagname 10 entries starting from page mypage %}'
        _, context = self.render(
            self.request(), template, entries=range(47), mypage=2)
        self.assertSequenceEqual(range(10, 20), context['entries'])

    def test_using_argument(self):
        # Ensure the template tag uses the given querystring key.
        template = '{% $tagname 20 objects using "mypage" %}'
        _, context = self.render(
            self.request(mypage=2), template)
        self.assertSequenceEqual(range(20, 40), context['objects'])

    def test_using_argument_as_variable(self):
        # Ensure the template tag uses the given querystring key.
        # In this case, the argument is provided as context variable.
        template = '{% $tagname 20 entries using qskey %}'
        _, context = self.render(
            self.request(p=3), template, entries=range(47), qskey='p')
        self.assertSequenceEqual(range(40, 47), context['entries'])

    def test_with_argument(self):
        # Ensure the context contains the correct override path.
        template = '{% $tagname 10 objects with "/mypath/" %}'
        _, context = self.render(self.request(), template)
        self.assertEqual('/mypath/', context['endless_override_path'])

    def test_with_argument_as_variable(self):
        # Ensure the context contains the correct override path.
        # In this case, the argument is provided as context variable.
        path = '/my/path/'
        template = '{% $tagname 10 entries with path %}'
        _, context = self.render(
            self.request(), template, entries=range(47), path=path)
        self.assertEqual(path, context['endless_override_path'])

    def test_as_argument(self):
        # Ensure it is possible to change the resulting context variable.
        template = '{% $tagname 20 objects as object_list %}'
        _, context = self.render(self.request(), template)
        self.assertSequenceEqual(range(20), context['object_list'])
        # The input queryset has not been changed.
        self.assertSequenceEqual(range(47), context['objects'])

    def test_complete_argument_list(self):
        # Ensure the tag works providing all the arguments.
        template = (
            '{% $tagname 5,10 objects '
            'starting from page 2 '
            'using mypage '
            'with path '
            'as paginated %}'
        )
        _, context = self.render(
            self.request(), template, objects=range(47), mypage='page-number',
            path='mypath')
        self.assertSequenceEqual(range(5, 15), context['paginated'])
        self.assertEqual('mypath', context['endless_override_path'])

    def test_invalid_arguments(self):
        # An error is raised if invalid arguments are provided.
        templates = (
            '{% $tagname %}',
            '{% $tagname foo bar spam eggs %}',
            '{% $tagname 20 objects as object_list using "mykey" %}',
        )
        request = self.request()
        for template in templates:
            with self.assertRaises(TemplateSyntaxError):
                self.render(request, template)

    def test_nested_context_variable(self):
        # Ensure nested context variables are correctly handled.
        manager = {'all': range(47)}
        template = '{% $tagname 5 manager.all as objects %}'
        _, context = self.render(self.request(), template, manager=manager)
        self.assertSequenceEqual(range(5), context['objects'])

    def test_failing_nested_context_variable(self):
        # An error is raised if a nested context variable is used but no
        # alias is provided.
        manager = {'all': range(47)}
        template = '{% $tagname 5 manager.all %}'
        with self.assertRaises(TemplateSyntaxError) as cm:
            self.render(self.request(), template, manager=manager)
        self.assertIn('manager.all', str(cm.exception))

    def test_multiple_pagination(self):
        # Ensure multiple pagination works correctly.
        template = (
            '{% $tagname 10,20 objects %}'
            '{% $tagname 1 items using items_page %}'
            '{% $tagname 5 entries.all using "entries" as myentries %}'
        )
        _, context = self.render(
            self.request(page=2, entries=3), template,
            objects=range(47), entries={'all': string.letters},
            items=['foo', 'bar'], items_page='p')
        self.assertSequenceEqual(range(10, 30), context['objects'])
        self.assertSequenceEqual(['foo'], context['items'])
        self.assertSequenceEqual(string.letters[10:15], context['myentries'])
        self.assertSequenceEqual(string.letters, context['entries']['all'])


class PaginateTest(PaginateTestMixin, TestCase):

    tagname = 'paginate'


class LazyPaginateTest(PaginateTestMixin, TestCase):

    tagname = 'lazy_paginate'


class ShowMoreTest(TemplateTagsTestMixin, TestCase):

    pass


class GetPagesTest(TemplateTagsTestMixin, TestCase):

    pass


class ShowPagesTest(TemplateTagsTestMixin, TestCase):

    pass


class ShowCurrentNumberTest(TemplateTagsTestMixin, TestCase):

    pass
{'fraction_non_alphanumeric': 0.11286421110500275, 'fraction_numerical': 0.011214953271028037, 'mean_word_length': 2.8994640943194, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3430434', 'n_tokens_mistral': 5031, 'n_tokens_neox': 4872, 'n_words': 1360}