#!/usr/bin/env python
# coding=UTF-8

import sys
import unittest
sys.path.insert(0, "..")

import redbot.message.headers as headers
from redbot.message import http_syntax as syntax
import redbot.speak as rs
from redbot.message import DummyMsg

class GeneralHeaderTesters(unittest.TestCase):
    def setUp(self):
        self.red = DummyMsg()
    
    def test_unquote_string(self):
        i = 0
        for (instr, expected_str, expected_notes) in [
            ('foo', 'foo', []),
            ('"foo"', 'foo', []),
            (r'"fo\"o"', 'fo"o', []),
            (r'"f\"o\"o"', 'f"o"o', []),
            (r'"fo\\o"', r'fo\o', []),
            (r'"f\\o\\o"', r'f\o\o', []),
            (r'"fo\o"', 'foo', []),
        ]:
            self.red.__init__()
            out_str = headers.unquote_string(unicode(instr))
            diff = set(
                [n.__name__ for n in expected_notes]).symmetric_difference(
                set(self.red.note_classes)
            )
            self.assertEqual(len(diff), 0, 
                "[%s] Mismatched notes: %s" % (i, diff)
            )
            self.assertEqual(expected_str, out_str, 
                "[%s] %s != %s" % (i, str(expected_str), str(out_str)))
            i += 1
    
    def test_split_string(self):
        i = 0
        for (instr, expected_outlist, item, split) in [
            ('"abc", "def"', 
             ['"abc"', '"def"'], 
             syntax.QUOTED_STRING, 
             r"\s*,\s*"
            ),
            (r'"\"ab", "c\d"', 
             [r'"\"ab"', r'"c\d"'], 
             syntax.QUOTED_STRING, 
             r"\s*,\s*"
            )
        ]:
            self.red.__init__()
            outlist = headers.split_string(unicode(instr), item, split)
            self.assertEqual(expected_outlist, outlist, 
                "[%s] %s != %s" % (i, str(expected_outlist), str(outlist)))
            i += 1
    
    def test_parse_params(self):
        i = 0
        for (instr, expected_pd, expected_notes, delim) in [
            ('foo=bar', {'foo': 'bar'}, [], ';'),
            ('foo="bar"', {'foo': 'bar'}, [], ';'),
            ('foo="bar"; baz=bat', {'foo': 'bar', 'baz': 'bat'}, [], ';'),
            ('foo="bar"; baz="b=t"; bam="boom"',
             {'foo': 'bar', 'baz': 'b=t', 'bam': 'boom'}, [], ';'
            ),
            (r'foo="b\"ar"', {'foo': 'b"ar'}, [], ';'),
            (r'foo=bar; foo=baz', 
             {'foo': 'baz'}, 
             [rs.PARAM_REPEATS], 
             ';'
            ),
            ('foo=bar; baz="b;at"', 
             {'foo': 'bar', 'baz': "b;at"}, 
             [],
             ';'
            ),
            ('foo=bar, baz="bat"', 
             {'foo': 'bar', 'baz': "bat"}, 
             [],
             ','
            ),
            ('foo=bar, baz="b,at"', 
             {'foo': 'bar', 'baz': "b,at"}, 
             [],
             ','
            ),
            ("foo=bar; baz='bat'", 
             {'foo': 'bar', 'baz': "'bat'"}, 
             [rs.PARAM_SINGLE_QUOTED], 
             ';'
            ),
            ("foo*=\"UTF-8''a%cc%88.txt\"", 
             {'foo*': u'a\u0308.txt'},
             [rs.PARAM_STAR_QUOTED], 
             ';'
            ),
            ("foo*=''a%cc%88.txt", 
             {},
             [rs.PARAM_STAR_NOCHARSET], 
             ';'
            ),
            ("foo*=utf-16''a%cc%88.txt", 
             {},
             [rs.PARAM_STAR_CHARSET], 
             ';'
            ),
            ("nostar*=utf-8''a%cc%88.txt",
             {},
             [rs.PARAM_STAR_BAD], 
             ';'
            ),
            ("NOstar*=utf-8''a%cc%88.txt",
             {},
             [rs.PARAM_STAR_BAD], 
             ';'
            )
        ]:
            self.red.__init__()
            param_dict = headers.parse_params(
              self.red, 'test', instr, ['nostar'], delim
            )
            diff = set(
                [n.__name__ for n in expected_notes]).symmetric_difference(
                set(self.red.note_classes)
            )
            self.assertEqual(len(diff), 0, 
                "[%s] Mismatched notes: %s" % (i, diff)
            )
            self.assertEqual(expected_pd, param_dict, 
                "[%s] %s != %s" % (i, str(expected_pd), str(param_dict)))
            i += 1
                
if __name__ == "__main__":
    # requires Python 2.7
    import sys
    loader = unittest.TestLoader()
    if len(sys.argv) == 2:
        auto_suite = loader.discover("../redbot/message/headers", 
                                    "%s.py" % sys.argv[1],  
                                    "../redbot"
        )
        all_tests = unittest.TestSuite([auto_suite])
    else:
        auto_suite = loader.discover(
            "../redbot", "*.py", '../redbot'
        )
        local_suite = loader.loadTestsFromTestCase(GeneralHeaderTesters)
        all_tests = unittest.TestSuite([local_suite, auto_suite])
    result = unittest.TextTestRunner().run(all_tests)
    if result.errors or result.failures:
        sys.exit(1)

@@ -84,16 +84,47 @@
  %22..%22)%0A%0A
+from functools import partial%0A%0A
 import r
@@ -172,70 +172,29 @@
 bot.
-message import http_syntax as syntax%0Aimport redbot.speak as rs
+syntax import rfc7230
 %0Afro
@@ -711,40 +711,8 @@
  %5D:%0A
-            self.red.__init__()%0A
     
@@ -772,279 +772,8 @@
 r))%0A
-            diff = set(%0A                %5Bn.__name__ for n in expected_notes%5D).symmetric_difference(%0A                set(self.red.note_classes)%0A            )%0A            self.assertEqual(len(diff), 0, %0A                %22%5B%25s%5D Mismatched notes: %25s%22 %25 (i, diff)%0A            )%0A
     
@@ -1097,36 +1097,37 @@
         
-syntax.QUOTED_STRING
+rfc7230.quoted_string
 , %0A     
@@ -1246,28 +1246,29 @@
     
-syntax.QUOTED_STRING
+rfc7230.quoted_string
 , %0A 
@@ -2118,32 +2118,37 @@
  %0A             %5B
+heade
 rs.PARAM_REPEATS
@@ -2662,32 +2662,37 @@
  %0A             %5B
+heade
 rs.PARAM_SINGLE_
@@ -2823,32 +2823,37 @@
 ,%0A             %5B
+heade
 rs.PARAM_STAR_QU
@@ -2951,32 +2951,37 @@
 ,%0A             %5B
+heade
 rs.PARAM_STAR_NO
@@ -3088,32 +3088,37 @@
 ,%0A             %5B
+heade
 rs.PARAM_STAR_CH
@@ -3224,32 +3224,37 @@
 ,%0A             %5B
+heade
 rs.PARAM_STAR_BA
@@ -3364,16 +3364,21 @@
        %5B
+heade
 rs.PARAM
@@ -3529,31 +3529,49 @@
     
-self.red, 'test', instr
+instr, partial(self.red.add_note, %22test%22)
 , %5B'

update test