import unittest

from mygrations.core.parse.rule_delimited import rule_delimited
class test_parse_delimited(unittest.TestCase):
    def get_rule(self, name, separator, quote, literal):

        return rule_delimited(
            False, {
                'name': name,
                'separator': separator,
                'quote': quote
            }, {
                'type': 'literal',
                'value': literal
            }
        )

    def test_name_required(self):

        with self.assertRaises(ValueError):

            self.get_rule('', ',', '`', 'asdf')

    def test_separator_required(self):

        with self.assertRaises(ValueError):

            self.get_rule('bob', '', '', 'asdf')

    def test_no_multi_character_separator(self):

        with self.assertRaises(ValueError):

            self.get_rule('bob', 'as', '', 'asdf')

    def test_no_multi_character_quote(self):

        with self.assertRaises(ValueError):

            self.get_rule('bob', ',', 'as', 'asdf')

    def test_literal_required(self):

        with self.assertRaises(ValueError):

            rule_delimited(False, {'name': 'bob', 'separator': ',', 'quote': '`'}, {})

    def test_can_init_with_name_and_separator(self):

        rule = self.get_rule('bob', ',', '', 'asdf')
        self.assertEquals(rule.name, 'bob')
        self.assertEquals(rule.separator, ',')

    def test_parse_without_quote(self):

        rule = self.get_rule('bob', ',', '', ')')
        self.assertTrue(rule.parse('1,2,3,4)'))
        self.assertEquals(['1', '2', '3', '4'], rule.result)
        self.assertEquals(')', rule.leftovers)

    def test_parse_optional_quotes(self):

        rule = self.get_rule('bob', ',', '`', ')')
        self.assertTrue(rule.parse('asdf,`bob`,huh,`okay`) sup'))
        self.assertEquals(['asdf', 'bob', 'huh', 'okay'], rule.result)
        self.assertEquals(') sup', rule.leftovers)

    def test_syntax_error_missing_quote(self):

        with self.assertRaises(SyntaxError):

            rule = self.get_rule('bob', ',', '`', ')')
            rule.parse('asdf,`bob)')

    def test_separator_in_quotes(self):

        rule = self.get_rule('bob', ',', '`', ')')
        self.assertTrue(rule.parse('asdf,`bob,`,huh,`okay`) sup'))
        self.assertEquals(['asdf', 'bob,', 'huh', 'okay'], rule.result)
        self.assertEquals(') sup', rule.leftovers)

    def test_alternate_characters(self):

        rule = self.get_rule('bob', 'X', '<', 'asdf')

        self.assertTrue(rule.parse('<hey<X<sup<asdf'))
        self.assertEquals(['hey', 'sup'], rule.result)
        self.assertEquals('asdf', rule.leftovers)
