<commit_before>"""Test shortcodes."""

import pytest

from nikola import shortcodes

from .base import FakeSite


def noargs(site, data='', lang=''):
    return "noargs {0} success!".format(data)


def arg(*args, **kwargs):
    # don’t clutter the kwargs dict
    kwargs.pop('site')
    data = kwargs.pop('data')
    kwargs.pop('lang')
    return "arg {0}/{1}/{2}".format(args, sorted(kwargs.items()), data)


@pytest.fixture(scope="module")
def site():
    s = FakeSite()
    s.register_shortcode('noargs', noargs)
    s.register_shortcode('arg', arg)
    return s


def test_noargs(site):
    assert shortcodes.apply_shortcodes(
        'test({{% noargs %}})', site.shortcode_registry)[0] == 'test(noargs  success!)'
    assert shortcodes.apply_shortcodes(
        'test({{% noargs %}}\\hello world/{{% /noargs %}})', site.
        shortcode_registry)[0] == 'test(noargs \\hello world/ success!)'


def test_arg_pos(site):
    assert shortcodes.apply_shortcodes(
        'test({{% arg 1 %}})', site.shortcode_registry)[0] == "test(arg ('1',)/[]/)"
    assert shortcodes.apply_shortcodes(
        'test({{% arg 1 2aa %}})', site.shortcode_registry)[0] == "test(arg ('1', '2aa')/[]/)"
    assert shortcodes.apply_shortcodes(
        'test({{% arg "hello world" %}})', site.shortcode_registry)[0] == "test(arg ('hello world',)/[]/)"
    assert shortcodes.apply_shortcodes(
        'test({{% arg back\\ slash arg2 %}})', site.shortcode_registry)[0] == "test(arg ('back slash', 'arg2')/[]/)"
    assert shortcodes.apply_shortcodes(
        'test({{% arg "%}}" %}})', site.shortcode_registry)[0] == "test(arg ('%}}',)/[]/)"


def test_arg_keyword(site):
    assert shortcodes.apply_shortcodes(
        'test({{% arg 1a=2b %}})', site.shortcode_registry)[0] == "test(arg ()/[('1a', '2b')]/)"
    assert shortcodes.apply_shortcodes(
        'test({{% arg 1a="2b 3c" 4d=5f %}})', site.shortcode_registry)[0] == "test(arg ()/[('1a', '2b 3c'), ('4d', '5f')]/)"
    assert shortcodes.apply_shortcodes('test({{% arg 1a="2b 3c" 4d=5f back=slash\\ slash %}})',
                                       site.shortcode_registry)[0] == "test(arg ()/[('1a', '2b 3c'), ('4d', '5f'), ('back', 'slash slash')]/)"


def test_data(site):
    assert shortcodes.apply_shortcodes(
        'test({{% arg 123 %}}Hello!{{% /arg %}})', site.shortcode_registry)[0] == "test(arg ('123',)/[]/Hello!)"
    assert shortcodes.apply_shortcodes('test({{% arg 123 456 foo=bar %}}Hello world!{{% /arg %}})',
                                       site.shortcode_registry)[0] == "test(arg ('123', '456')/[('foo', 'bar')]/Hello world!)"
    assert shortcodes.apply_shortcodes('test({{% arg 123 456 foo=bar baz="quotes rock." %}}Hello test suite!{{% /arg %}})',
                                       site.shortcode_registry)[0] == "test(arg ('123', '456')/[('baz', 'quotes rock.'), ('foo', 'bar')]/Hello test suite!)"
    assert shortcodes.apply_shortcodes('test({{% arg "123 foo" foobar foo=bar baz="quotes rock." %}}Hello test suite!!{{% /arg %}})',
                                       site.shortcode_registry)[0] == "test(arg ('123 foo', 'foobar')/[('baz', 'quotes rock.'), ('foo', 'bar')]/Hello test suite!!)"


def test_errors(site):
    with pytest.raises(shortcodes.ParsingError, match="^Shortcode 'start' starting at .* is not terminated correctly with '%}}'!"):
        shortcodes.apply_shortcodes('{{% start', site.shortcode_registry, raise_exceptions=True)

    with pytest.raises(shortcodes.ParsingError, match="^Syntax error in shortcode 'wrong' at .*: expecting whitespace!"):
        shortcodes.apply_shortcodes('{{% wrong ending %%}', site.shortcode_registry, raise_exceptions=True)

    with pytest.raises(shortcodes.ParsingError, match="^Found shortcode ending '{{% /end %}}' which isn't closing a started shortcode"):
        shortcodes.apply_shortcodes('{{% start %}} {{% /end %}}', site.shortcode_registry, raise_exceptions=True)

    with pytest.raises(shortcodes.ParsingError, match="^Unexpected end of unquoted string"):
        shortcodes.apply_shortcodes('{{% start "asdf %}}', site.shortcode_registry, raise_exceptions=True)

    with pytest.raises(shortcodes.ParsingError, match="^String starting at .* must be non-empty!"):
        shortcodes.apply_shortcodes('{{% start =b %}}', site.shortcode_registry, raise_exceptions=True)

    with pytest.raises(shortcodes.ParsingError, match="^Unexpected end of data while escaping"):
        shortcodes.apply_shortcodes('{{% start "a\\', site.shortcode_registry, raise_exceptions=True)

    with pytest.raises(shortcodes.ParsingError, match="^Unexpected end of data while escaping"):
        shortcodes.apply_shortcodes('{{% start a\\', site.shortcode_registry, raise_exceptions=True)

    with pytest.raises(shortcodes.ParsingError, match="^Unexpected quotation mark in unquoted string"):
        shortcodes.apply_shortcodes('{{% start a"b" %}}', site.shortcode_registry, raise_exceptions=True)

    with pytest.raises(shortcodes.ParsingError, match="^Syntax error in shortcode 'start' at .*: expecting whitespace!"):
        shortcodes.apply_shortcodes('{{% start "a"b %}}', site.shortcode_registry, raise_exceptions=True)

    with pytest.raises(shortcodes.ParsingError, match="^Syntax error: '{{%' must be followed by shortcode name"):
        shortcodes.apply_shortcodes('{{% %}}', site.shortcode_registry, raise_exceptions=True)

    with pytest.raises(shortcodes.ParsingError, match="^Syntax error: '{{%' must be followed by shortcode name"):
        shortcodes.apply_shortcodes('{{%', site.shortcode_registry, raise_exceptions=True)

    with pytest.raises(shortcodes.ParsingError, match="^Syntax error: '{{%' must be followed by shortcode name"):
        shortcodes.apply_shortcodes('{{% ', site.shortcode_registry, raise_exceptions=True)

    with pytest.raises(shortcodes.ParsingError, match="^Found shortcode ending '{{% / %}}' which isn't closing a started shortcode"):
        shortcodes.apply_shortcodes('{{% / %}}', site.shortcode_registry, raise_exceptions=True)

    with pytest.raises(shortcodes.ParsingError, match="^Syntax error: '{{% /' must be followed by ' %}}'"):
        shortcodes.apply_shortcodes('{{% / a %}}', site.shortcode_registry, raise_exceptions=True)

    with pytest.raises(shortcodes.ParsingError, match="^Shortcode '<==' starting at .* is not terminated correctly with '%}}'!"):
        shortcodes.apply_shortcodes('==> {{% <==', site.shortcode_registry, raise_exceptions=True)


@pytest.mark.parametrize(
    "input, expected",
    [('{{% foo %}}', (u'SC1', {u'SC1': u'{{% foo %}}'})),
     ('{{% foo %}} bar {{% /foo %}}',
      (u'SC1', {u'SC1': u'{{% foo %}} bar {{% /foo %}}'})),
     ('AAA{{% foo %}} bar {{% /foo %}}BBB',
      (u'AAASC1BBB', {u'SC1': u'{{% foo %}} bar {{% /foo %}}'})),<commit_msg>Make it possible to detect single defects easier.<commit_after>"""Test shortcodes."""

import pytest

from nikola import shortcodes

from .base import FakeSite


def noargs(site, data='', lang=''):
    return "noargs {0} success!".format(data)


def arg(*args, **kwargs):
    # don’t clutter the kwargs dict
    kwargs.pop('site')
    data = kwargs.pop('data')
    kwargs.pop('lang')
    return "arg {0}/{1}/{2}".format(args, sorted(kwargs.items()), data)


@pytest.fixture(scope="module")
def site():
    s = FakeSite()
    s.register_shortcode('noargs', noargs)
    s.register_shortcode('arg', arg)
    return s


@pytest.mark.parametrize("template, expected_result", [
  ('test({{% noargs %}})', 'test(noargs  success!)'),
  ('test({{% noargs %}}\\hello world/{{% /noargs %}})',
   'test(noargs \\hello world/ success!)'),
])
def test_noargs(site, template, expected_result):
    assert shortcodes.apply_shortcodes(template, site.shortcode_registry)[0] == expected_result


@pytest.mark.parametrize("template, expected_result", [
    ('test({{% arg 1 %}})', "test(arg ('1',)/[]/)"),
    ('test({{% arg 1 2aa %}})', "test(arg ('1', '2aa')/[]/)"),
    ('test({{% arg "hello world" %}})', "test(arg ('hello world',)/[]/)"),
    ('test({{% arg back\\ slash arg2 %}})',
     "test(arg ('back slash', 'arg2')/[]/)"),
    ('test({{% arg "%}}" %}})', "test(arg ('%}}',)/[]/)"),
])
def test_positional_arguments(site, template, expected_result):
    assert shortcodes.apply_shortcodes(template, site.shortcode_registry)[0] == expected_result


@pytest.mark.parametrize("template, expected_result", [
    ('test({{% arg 1a=2b %}})', "test(arg ()/[('1a', '2b')]/)"),
    ('test({{% arg 1a="2b 3c" 4d=5f %}})',
     "test(arg ()/[('1a', '2b 3c'), ('4d', '5f')]/)"),
    ('test({{% arg 1a="2b 3c" 4d=5f back=slash\\ slash %}})',
     "test(arg ()/[('1a', '2b 3c'), ('4d', '5f'), ('back', 'slash slash')]/)"),
])
def test_arg_keyword(site, template, expected_result):
    assert shortcodes.apply_shortcodes(template, site.shortcode_registry)[0] == expected_result


@pytest.mark.parametrize("template, expected_result", [
    ('test({{% arg 123 %}}Hello!{{% /arg %}})', "test(arg ('123',)/[]/Hello!)"),
    ('test({{% arg 123 456 foo=bar %}}Hello world!{{% /arg %}})',
     "test(arg ('123', '456')/[('foo', 'bar')]/Hello world!)"),
    ('test({{% arg 123 456 foo=bar baz="quotes rock." %}}Hello test suite!{{% /arg %}})',
     "test(arg ('123', '456')/[('baz', 'quotes rock.'), ('foo', 'bar')]/Hello test suite!)"),
    ('test({{% arg "123 foo" foobar foo=bar baz="quotes rock." %}}Hello test suite!!{{% /arg %}})',
     "test(arg ('123 foo', 'foobar')/[('baz', 'quotes rock.'), ('foo', 'bar')]/Hello test suite!!)"),
])
def test_data(site, template, expected_result):
    assert shortcodes.apply_shortcodes(template, site.shortcode_registry)[0] == expected_result


@pytest.mark.parametrize("template, expected_error_pattern", [
    ('{{% start',
     "^Shortcode 'start' starting at .* is not terminated correctly with '%}}'!"),
    ('{{% wrong ending %%}',
     "^Syntax error in shortcode 'wrong' at .*: expecting whitespace!"),
    ('{{% start %}} {{% /end %}}',
     "^Found shortcode ending '{{% /end %}}' which isn't closing a started shortcode"),
    ('{{% start "asdf %}}', "^Unexpected end of unquoted string"),
    ('{{% start =b %}}', "^String starting at .* must be non-empty!"),
    ('{{% start "a\\', "^Unexpected end of data while escaping"),
    ('{{% start a\\', "^Unexpected end of data while escaping"),
    ('{{% start a"b" %}}', "^Unexpected quotation mark in unquoted string"),
    ('{{% start "a"b %}}',
     "^Syntax error in shortcode 'start' at .*: expecting whitespace!"),
    ('{{% %}}', "^Syntax error: '{{%' must be followed by shortcode name"),
    ('{{%', "^Syntax error: '{{%' must be followed by shortcode name"),
    ('{{% ', "^Syntax error: '{{%' must be followed by shortcode name"),
    ('{{% / %}}',
     "^Found shortcode ending '{{% / %}}' which isn't closing a started shortcode"),
    ('{{% / a %}}', "^Syntax error: '{{% /' must be followed by ' %}}'"),
    ('==> {{% <==',
     "^Shortcode '<==' starting at .* is not terminated correctly with '%}}'!"),
])
def test_errors(site, template, expected_error_pattern):
    with pytest.raises(shortcodes.ParsingError, match=expected_error_pattern):
        shortcodes.apply_shortcodes(template,
                                    site.shortcode_registry,
                                    raise_exceptions=True)


@pytest.mark.parametrize(
    "input, expected",
    [('{{% foo %}}', (u'SC1', {u'SC1': u'{{% foo %}}'})),
     ('{{% foo %}} bar {{% /foo %}}',
      (u'SC1', {u'SC1': u'{{% foo %}} bar {{% /foo %}}'})),
     ('AAA{{% foo %}} bar {{% /foo %}}BBB',
      (u'AAASC1BBB', {u'SC1': u'{{% foo %}} bar {{% /foo %}}'})),
{'fraction_non_alphanumeric': 0.21865562171024247, 'fraction_numerical': 0.015014237639140565, 'mean_word_length': 4.098988121425429, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6241186', 'n_tokens_mistral': 4065, 'n_tokens_neox': 3929, 'n_words': 871}