Changeset 111:a8df0817a791

Show
Ignore:
Timestamp:
17/12/09 14:02:26 (2 years ago)
Author:
Menno Smits <menno@…>
Branch:
default
Message:

core parts of fetch parsing done, lots more tests parsing

Location:
imapclient
Files:
3 modified

Legend:

Unmodified
Added
Removed
  • imapclient/response_parser.py

    r109 r111  
    3333 
    3434def parse_fetch_response(text): 
     35    #XXX doc 
    3536    response = iter(parse_response(text)) 
    3637 
    3738    def expect(expected_value): 
    38         next_value = response.next() 
     39        next_value = response.next().upper() 
    3940        if next_value != expected_value: 
    4041            raise ParseError('expected %r, got %r' % (expected_value, next_value)) 
    4142 
    42     msg_data = {} 
     43    parsed_response = {} 
    4344    while True: 
    4445        try: 
     
    4647        except StopIteration: 
    4748            break 
    48         msgid = int(response.next()) 
     49 
     50        msg_id = _int_or_error(response.next(), 'invalid message ID') 
    4951        expect('FETCH') 
    50         msg_data[msgid] = response.next() 
    51     return msg_data 
     52 
     53        msg_response = response.next() 
     54        if not isinstance(msg_response, tuple): 
     55            raise ParseError('bad response type: %s' % repr(msg_response)) 
     56        if len(msg_response) % 2: 
     57            raise ParseError('uneven number of response items: %s' % repr(msg_response)) 
     58 
     59        #XXX extract this 
     60        msg_data = {} 
     61        for i in xrange(0, len(msg_response), 2): 
     62            word = msg_response[i].upper() 
     63            value = msg_response[i+1] 
     64 
     65            if word == 'UID': 
     66                msg_id = _int_or_error(value, 'invalid UID') 
     67            else: 
     68                msg_data[word] = value 
     69 
     70        parsed_response[msg_id] = msg_data 
     71 
     72    return parsed_response 
     73 
     74 
     75def _int_or_error(value, error_text): 
     76    try: 
     77        return int(value) 
     78    except (TypeError, ValueError): 
     79        raise ParseError('%s: %s' % (error_text, repr(value))) 
     80 
    5281 
    5382 
     
    5786 
    5887    CTRL_CHARS = ''.join([chr(ch) for ch in range(32)]) 
    59     ATOM_SPECIALS = r'()%*\"]' + CTRL_CHARS 
     88    ATOM_SPECIALS = r'()%*"]' + CTRL_CHARS 
    6089    ALL_CHARS = [chr(ch) for ch in range(256)] 
    6190    ATOM_NON_SPECIALS = [ch for ch in ALL_CHARS if ch not in ATOM_SPECIALS] 
  • imapclient/test/__init__.py

    r110 r111  
    2626def run_suite(): 
    2727    suite = load_suite() 
    28     runner = unittest.TextTestRunner(verbosity=2) 
     28    runner = unittest.TextTestRunner(verbosity=1) 
    2929    runner.run(suite) 
    3030 
  • imapclient/test/test_response_parser.py

    r109 r111  
    3838        self._test('FOO', 'FOO') 
    3939        self._test('F.O:-O_0;', 'F.O:-O_0;') 
     40        self._test(r'\Seen', r'\Seen') 
    4041 
    4142    def test_string(self): 
     
    129130    return dt.astimezone(system_offset).replace(tzinfo=None) 
    130131 
     132 
    131133class TestParseFetchResponse(unittest.TestCase): 
    132134 
    133135    def test_basic(self): 
    134136        self.assertEquals(parse_fetch_response('* 4 FETCH ()'), {4: {}}) 
    135  
    136  
    137     def test_simple_pair(self): 
    138         self.assertEquals(parse_fetch_response('* 23 FETCH (ABC 123 STUFF "hello")'), 
    139                           {'23': {'ABC': 123, 
    140                                   'STUFF': 'hello'}}) 
     137        self.assertEquals(parse_fetch_response('* 4 fEtCh ()'), {4: {}}) 
    141138 
    142139 
     
    149146 
    150147 
     148    def test_bad_data(self): 
     149        self.assertRaises(ParseError, parse_fetch_response, '* 2 FETCH WHAT') 
     150 
     151 
     152    def test_simple_pairs(self): 
     153        self.assertEquals(parse_fetch_response('* 23 FETCH (ABC 123 StUfF "hello")'), 
     154                          {23: {'ABC': 123, 
     155                                'STUFF': 'hello'}}) 
     156 
     157 
     158    def test_odd_pairs(self): 
     159        self.assertRaises(ParseError, parse_fetch_response, '* 2 FETCH (ONE)') 
     160        self.assertRaises(ParseError, parse_fetch_response, '* 2 FETCH (ONE TWO THREE)') 
     161 
     162 
    151163    def test_UID(self): 
    152164        self.assertEquals(parse_fetch_response('* 23 FETCH (UID 76)'), 
    153                           {'76': {}}) 
    154  
     165                          {76: {}}) 
     166        self.assertEquals(parse_fetch_response('* 23 FETCH (uiD 76)'), 
     167                          {76: {}}) 
     168 
     169 
     170    def test_bad_UID(self): 
     171        self.assertRaises(ParseError, parse_fetch_response, '* 2 FETCH (UID X)') 
     172         
    155173 
    156174    def test_FLAGS(self): 
     175        self.assertEquals(parse_fetch_response('* 23 FETCH (FLAGS (\Seen Stuff))'), 
     176                          {23: {'FLAGS': (r'\Seen', 'Stuff')}}) 
     177 
     178 
     179    def test_multiple_messages(self): 
    157180        self.fail() 
     181 
    158182 
    159183    def test_INTERNALDATE(self): 
     
    181205#         dt = check(' 9-Dec-2007 17:08:08 +0000', 
    182206#                    datetime.datetime(2007, 12, 9, 17, 8, 8, 0, FixedOffset(0))) 
    183  
    184     def test_multiple_fields(self): 
    185         self.fail() 
    186  
    187     def test_multiple_messages(self): 
    188         self.fail() 
    189  
    190     def test_case_handling(self): 
    191         self.fail() 
    192 #         self._parse_test( 
    193 #             [r'2 (flaGS (\Deleted Foo \Seen))'], 
    194 #             {2: {'FLAGS': [r'\Deleted', 'Foo', r'\Seen']}} 
    195 #             ) 
    196  
    197  
    198     def test_invalid(self): 
    199         self.fail() 
    200 #         self.assertRaises(ValueError, self.p, [r'2 (FLAGS (\Deleted) MORE)']) 
    201 #         self.assertRaises(ValueError, 
    202 #                 self.t.process_pairs, 'FOO 123 BAH "abc" WHAT?') 
    203 #         self.assertRaises(ValueError, 
    204 #                 self.t.process_pairs, 'HMMM FOO 123 BAH "abc"') 
    205 #         self.assertRaises(ValueError, 
    206 #                 self.t.process_pairs, 'FOO 123 BAD BAH "abc"') 
    207  
    208 #TODO convert the following are mainly FETCH specific tests 
    209  
    210 #     def test_INTERNALDATE(self): 
    211207 
    212208