<commit_before>"""
Tests for string matchers.
"""
from taipan.testing import skipIf, skipUnless

from callee._compat import IS_PY3
import callee.strings as __unit__
from tests import MatcherTestCase


# String type matchers

class String(MatcherTestCase):
    test_none = lambda self: self.assert_no_match(None)
    test_empty_string = lambda self: self.assert_match('')
    test_some_string = lambda self: self.assert_match("Alice has a cat")

    @skipIf(IS_PY3, "requires Python 2.x")
    def test_some_bytes__py2(self):
        self.assert_match(bytes("Alice has a cat"))

    @skipUnless(IS_PY3, "requires Python 3.x")
    def test_some_bytes__py3(self):
        self.assert_no_match(bytes("Alice has a cat", 'ascii'))

    test_some_object = lambda self: self.assert_no_match(object())
    test_some_number = lambda self: self.assert_no_match(42)

    def assert_match(self, value):
        return super(String, self).assert_match(__unit__.String(), value)

    def assert_no_match(self, value):
        return super(String, self).assert_no_match(__unit__.String(), value)


class Unicode(MatcherTestCase):
    test_none = lambda self: self.assert_no_match(None)
    test_empty_unicode = lambda self: self.assert_match(u'')
    test_some_unicode = lambda self: self.assert_match(u"Alice has a cat")

    @skipIf(IS_PY3, "requires Python 2.x")
    def test_some_string__py2(self):
        self.assert_no_match("Alice has a cat")

    @skipUnless(IS_PY3, "requires Python 3.x")
    def test_some_string__py3(self):
        self.assert_match("Alice has a cat")

    test_some_object = lambda self: self.assert_no_match(object())
    test_some_number = lambda self: self.assert_no_match(42)

    def assert_match(self, value):
        return super(Unicode, self).assert_match(__unit__.Unicode(), value)

    def assert_no_match(self, value):
        return super(Unicode, self).assert_no_match(__unit__.Unicode(), value)


class Bytes(MatcherTestCase):
    test_none = lambda self: self.assert_no_match(None)
    test_empty_unicode = lambda self: self.assert_no_match(u'')
    test_some_unicode = lambda self: self.assert_no_match(u"Alice has a cat")

    @skipIf(IS_PY3, "requires Python 2.x")
    def test_some_string__py2(self):
        self.assert_match("Alice has a cat")

    @skipUnless(IS_PY3, "requires Python 3.x")
    def test_some_string__py3(self):
        self.assert_no_match("Alice has a cat")

    test_some_object = lambda self: self.assert_no_match(object())
    test_some_number = lambda self: self.assert_no_match(42)

    def assert_match(self, value):
        return super(Bytes, self).assert_match(__unit__.Bytes(), value)

    def assert_no_match(self, value):
        return super(Bytes, self).assert_no_match(__unit__.Bytes(), value)


# Infix matchers

class StartsWith(MatcherTestCase):

    # Assertion functions

    def assert_match(self, value, prefix):
        return super(StartsWith, self) \
            .assert_match(__unit__.StartsWith(prefix), value)

    def assert_no_match(self, value, prefix):
        return super(StartsWith, self) \
            .assert_no_match(__unit__.StartsWith(prefix), value)


class EndsWith(MatcherTestCase):

    # Assertion functions

    def assert_match(self, value, prefix):
        return super(EndsWith, self) \
            .assert_match(__unit__.EndsWith(prefix), value)

    def assert_no_match(self, value, prefix):
        return super(EndsWith, self) \
            .assert_no_match(__unit__.EndsWith(prefix), value)


# Pattern matchers

class Glob(MatcherTestCase):

    # Assertion functions

    def assert_match(self, value, pattern):
        return super(Glob, self).assert_match(__unit__.Glob(pattern), value)

    def assert_no_match(self, value, pattern):
        return super(Glob, self) \
            .assert_no_match(__unit__.Glob(pattern), value)


class Regex(MatcherTestCase):

    # Assertion functions

    def assert_match(self, value, pattern):
        return super(Regex, self).assert_match(__unit__.Regex(pattern), value)

    def assert_no_match(self, value, pattern):
        return super(Regex, self) \
            .assert_no_match(__unit__.Regex(pattern), value)<commit_msg>Tests for Glob and Pattern<commit_after>"""
Tests for string matchers.
"""
from itertools import combinations
import re

from taipan.testing import skipIf, skipUnless

from callee._compat import IS_PY3
import callee.strings as __unit__
from tests import MatcherTestCase


# String type matchers

class String(MatcherTestCase):
    test_none = lambda self: self.assert_no_match(None)
    test_empty_string = lambda self: self.assert_match('')
    test_some_string = lambda self: self.assert_match("Alice has a cat")

    @skipIf(IS_PY3, "requires Python 2.x")
    def test_some_bytes__py2(self):
        self.assert_match(bytes("Alice has a cat"))

    @skipUnless(IS_PY3, "requires Python 3.x")
    def test_some_bytes__py3(self):
        self.assert_no_match(bytes("Alice has a cat", 'ascii'))

    test_some_object = lambda self: self.assert_no_match(object())
    test_some_number = lambda self: self.assert_no_match(42)

    def assert_match(self, value):
        return super(String, self).assert_match(__unit__.String(), value)

    def assert_no_match(self, value):
        return super(String, self).assert_no_match(__unit__.String(), value)


class Unicode(MatcherTestCase):
    test_none = lambda self: self.assert_no_match(None)
    test_empty_unicode = lambda self: self.assert_match(u'')
    test_some_unicode = lambda self: self.assert_match(u"Alice has a cat")

    @skipIf(IS_PY3, "requires Python 2.x")
    def test_some_string__py2(self):
        self.assert_no_match("Alice has a cat")

    @skipUnless(IS_PY3, "requires Python 3.x")
    def test_some_string__py3(self):
        self.assert_match("Alice has a cat")

    test_some_object = lambda self: self.assert_no_match(object())
    test_some_number = lambda self: self.assert_no_match(42)

    def assert_match(self, value):
        return super(Unicode, self).assert_match(__unit__.Unicode(), value)

    def assert_no_match(self, value):
        return super(Unicode, self).assert_no_match(__unit__.Unicode(), value)


class Bytes(MatcherTestCase):
    test_none = lambda self: self.assert_no_match(None)
    test_empty_unicode = lambda self: self.assert_no_match(u'')
    test_some_unicode = lambda self: self.assert_no_match(u"Alice has a cat")

    @skipIf(IS_PY3, "requires Python 2.x")
    def test_some_string__py2(self):
        self.assert_match("Alice has a cat")

    @skipUnless(IS_PY3, "requires Python 3.x")
    def test_some_string__py3(self):
        self.assert_no_match("Alice has a cat")

    test_some_object = lambda self: self.assert_no_match(object())
    test_some_number = lambda self: self.assert_no_match(42)

    def assert_match(self, value):
        return super(Bytes, self).assert_match(__unit__.Bytes(), value)

    def assert_no_match(self, value):
        return super(Bytes, self).assert_no_match(__unit__.Bytes(), value)


# Infix matchers

class StartsWith(MatcherTestCase):

    # TODO(xion): write those tests

    # Assertion functions

    def assert_match(self, value, prefix):
        return super(StartsWith, self) \
            .assert_match(__unit__.StartsWith(prefix), value)

    def assert_no_match(self, value, prefix):
        return super(StartsWith, self) \
            .assert_no_match(__unit__.StartsWith(prefix), value)


class EndsWith(MatcherTestCase):

    # TODO(xion): write those tests

    # Assertion functions

    def assert_match(self, value, prefix):
        return super(EndsWith, self) \
            .assert_match(__unit__.EndsWith(prefix), value)

    def assert_no_match(self, value, prefix):
        return super(EndsWith, self) \
            .assert_no_match(__unit__.EndsWith(prefix), value)


# Pattern matchers

class PatternTestCase(MatcherTestCase):
    ALPHABET = 'abcdefghijklmnopqrstvuwxyz'

    # Some tests is O(2^N) wrt to size of this set, so keep it short.
    LETTERS = 'abcdef'

    def suffixes(self):
        for l in range(len(self.LETTERS)):
            for suffix in combinations(self.LETTERS, l):
                return ''.join(suffix)


class Glob(PatternTestCase):

    def test_exact(self):
        self.assert_match('', '')
        self.assert_match(' ', ' ')
        self.assert_match('foo', 'foo')
        self.assert_match('foo!', 'foo!')  # ! is not special outside of []

    def test_escaping(self):
        self.assert_match('foo?', 'foo[?]')
        self.assert_match('foo*', 'foo[*]')

    def test_question_mark(self):
        text = 'foo'
        for char in self.ALPHABET:
            self.assert_match(text + char, text + '?')

    def test_asterisk(self):
        text = 'foo'
        for suffix in self.suffixes():
            self.assert_match(text + suffix, text + '*')

    def test_square_brackets(self):
        text = 'foo'
        for suffix in self.suffixes():
            square_pattern = ''.join('[%s]' % char for char in suffix)
            self.assert_match(text + suffix, text + square_pattern)

    # Assertion functions

    def assert_match(self, value, pattern):
        return super(Glob, self).assert_match(__unit__.Glob(pattern), value)

    def assert_no_match(self, value, pattern):
        return super(Glob, self) \
            .assert_no_match(__unit__.Glob(pattern), value)


class Regex(PatternTestCase):

    def test_exact(self):
        self.assert_match('', '')
        self.assert_match(' ', ' ')
        self.assert_match('foo', 'foo')
        self.assert_match('foo^', 'foo')  # ^ is not special outside of []

    def test_escaping(self):
        self.assert_match('foo(', r'foo\(')
        self.assert_match('foo.', r'foo\.')

    def test_dot(self):
        text = 'foo'
        for char in self.ALPHABET:
            self.assert_match(text + char, re.escape(text) + '.')

    def test_dots(self):
        text = 'foo'
        for suffix in self.suffixes():
            self.assert_match(text + suffix, re.escape(text) + '.*')

    def test_square_brackets(self):
        text = 'foo'
        for suffix in self.suffixes():
            square_pattern = ''.join('[%s]' % char for char in suffix)
            self.assert_match(text + suffix, re.escape(text) + square_pattern)

    # Assertion functions

    def assert_match(self, value, pattern):
        return super(Regex, self).assert_match(__unit__.Regex(pattern), value)

    def assert_no_match(self, value, pattern):
        return super(Regex, self) \
            .assert_no_match(__unit__.Regex(pattern), value)
{'fraction_non_alphanumeric': 0.11315938740782756, 'fraction_numerical': 0.004821327283040272, 'mean_word_length': 3.5036185610898256, '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': '5248416', 'n_tokens_mistral': 3425, 'n_tokens_neox': 3298, 'n_words': 756}