# -*- coding: utf-8 -*-

#
# Unit tests for string functions from tdda.referencetest.checkfiles
#

from __future__ import absolute_import
from __future__ import unicode_literals
from __future__ import division

import unittest

from tdda.referencetest.checkfiles import FilesComparison


class TestInternals(unittest.TestCase):
    def test_diff_marker(self):
        compare = FilesComparison()
        self.assertEqual(compare.diff_marker('ABC', 'XYZ'), '(ABC|XYZ)')
        self.assertEqual(compare.diff_marker('ABC:', 'ABC: yes'), 'ABC:(| yes)')
        self.assertEqual(compare.diff_marker('', 'AAA'), '(|AAA)')
        self.assertEqual(compare.diff_marker('AAA', ''), '(AAA|)')
        self.assertEqual(compare.diff_marker('ABC', 'AXC'), 'A(B|X)C')

    def test_single_pattern(self):
        compare = FilesComparison()
        cpatterns = compare.compile_patterns(['gr.*t'])
        self.assertTrue(compare.check_patterns(cpatterns,
                                               'great', 'grapefruit'))

    def test_unanchored_patterns(self):
        compare = FilesComparison()
        cpatterns = compare.compile_patterns(['A\d{2}B', 'X[a-z]+Y'])
        for actual, expected in [('A22BC', 'A99BC'),
                                 ('XappleY', 'XtrafficY'),
                                 ('A22BXappleY', 'A99BXtrafficY'),
                                 ('froggyA22BXappleY', 'froggyA99BXtrafficY'),
                                 ('frA22BXappleYoggy', 'frA99BXtrafficYoggy'),
                                 ('A22BA99B', 'A99BA22B')]:
            self.assertTrue(compare.check_patterns(cpatterns,
                                                   actual, expected),
                            '%s <--> %s' % (actual, expected))
        for actual, expected in [('A222BC', 'A99BC'),
                                 ('222BC', 'A99BC'),
                                 ('XappleYXappleY', 'XappleY')]:
            self.assertFalse(compare.check_patterns(cpatterns,
                                                    actual, expected),
                             '%s <--> %s' % (actual, expected))

    def test_anchored_patterns(self):
        compare = FilesComparison()
        cpatterns = compare.compile_patterns([r'^\d+$'])
        for actual, expected in [('2', '222222222222'),
                                 ('2', '2'),
                                 ('02', '2'),
                                 ('2', '23'),
                                 ('123', '564')]:
            self.assertTrue(compare.check_patterns(cpatterns,
                                                   actual, expected),
                            '%s <--> %s' % (actual, expected))
        for actual, expected in [('2', '222222222222a22'),
                                 ('', '23'),
                                 ('123', '')]:
            self.assertFalse(compare.check_patterns(cpatterns,
                                                    actual, expected),
                             '%s <--> %s' % (actual, expected))

    def test_grouped_pattern(self):
        compare = FilesComparison()
        cpatterns = compare.compile_patterns(['(a|an) (grapefruit|apple)'])
        self.assertTrue(compare.check_patterns(cpatterns,
                                               'a grapefruit', 'an apple'))
        self.assertTrue(compare.check_patterns(cpatterns,
                                               'I have a grapefruit', 'I have an apple'))
        self.assertTrue(compare.check_patterns(cpatterns,
                                               'I have a grapefruit and an apple',
                                               'I have an apple and a grapefruit'))
        self.assertFalse(compare.check_patterns(cpatterns,
                                               'I have a grapefruit and a banana',
                                               'I have an apple and a grapefruit'))


class TestStrings(unittest.TestCase):
    def test_strings_ok(self):
        compare = FilesComparison()
        self.assertEqual(compare.check_strings([], []), (0, []))
        self.assertEqual(compare.check_strings(['abc'], ['abc']), (0, []))
        self.assertEqual(compare.check_strings(['ab', 'c'], ['ab', 'c']),
                         (0, []))

    def test_strings_fail(self):
        compare = FilesComparison()
        self.assertEqual(compare.check_strings([], ['x'], create_temporaries=False),
                         (1, ['Strings have different numbers of lines, '
                              'differences start at end of actual string',
                              'No files available for comparison']))
        self.assertEqual(compare.check_strings(['y'], ['x'], create_temporaries=False),
                         (1, ['1 line is different, starting at line 1',
                              'No files available for comparison']))

    def test_print(self):
        msgs = []
        compare = FilesComparison(print_fn=lambda x: msgs.append(x))
        compare.check_strings(['a'], ['b'], create_temporaries=False)
        self.assertEqual(msgs, ['1 line is different, starting at line 1',
                                'No files available for comparison'])

    def test_strip(self):
        compare = FilesComparison()
        self.assertEqual(compare.check_strings(['   abc'], ['abc'],
                                               create_temporaries=False),
                         (1, ['1 line is different, starting at line 1',
                              'No files available for comparison']))
        self.assertEqual(compare.check_strings(['   abc'], ['abc'],
                                               lstrip=True), (0, []))
        self.assertEqual(compare.check_strings(['abc   '], ['abc'],