Changeset 111:a8df0817a791
- 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:
-
Legend:
- Unmodified
- Added
- Removed
-
|
r109
|
r111
|
|
| 33 | 33 | |
| 34 | 34 | def parse_fetch_response(text): |
| | 35 | #XXX doc |
| 35 | 36 | response = iter(parse_response(text)) |
| 36 | 37 | |
| 37 | 38 | def expect(expected_value): |
| 38 | | next_value = response.next() |
| | 39 | next_value = response.next().upper() |
| 39 | 40 | if next_value != expected_value: |
| 40 | 41 | raise ParseError('expected %r, got %r' % (expected_value, next_value)) |
| 41 | 42 | |
| 42 | | msg_data = {} |
| | 43 | parsed_response = {} |
| 43 | 44 | while True: |
| 44 | 45 | try: |
| … |
… |
|
| 46 | 47 | except StopIteration: |
| 47 | 48 | break |
| 48 | | msgid = int(response.next()) |
| | 49 | |
| | 50 | msg_id = _int_or_error(response.next(), 'invalid message ID') |
| 49 | 51 | 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 | |
| | 75 | def _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 | |
| 52 | 81 | |
| 53 | 82 | |
| … |
… |
|
| 57 | 86 | |
| 58 | 87 | CTRL_CHARS = ''.join([chr(ch) for ch in range(32)]) |
| 59 | | ATOM_SPECIALS = r'()%*\"]' + CTRL_CHARS |
| | 88 | ATOM_SPECIALS = r'()%*"]' + CTRL_CHARS |
| 60 | 89 | ALL_CHARS = [chr(ch) for ch in range(256)] |
| 61 | 90 | ATOM_NON_SPECIALS = [ch for ch in ALL_CHARS if ch not in ATOM_SPECIALS] |
-
|
r110
|
r111
|
|
| 26 | 26 | def run_suite(): |
| 27 | 27 | suite = load_suite() |
| 28 | | runner = unittest.TextTestRunner(verbosity=2) |
| | 28 | runner = unittest.TextTestRunner(verbosity=1) |
| 29 | 29 | runner.run(suite) |
| 30 | 30 | |
-
|
r109
|
r111
|
|
| 38 | 38 | self._test('FOO', 'FOO') |
| 39 | 39 | self._test('F.O:-O_0;', 'F.O:-O_0;') |
| | 40 | self._test(r'\Seen', r'\Seen') |
| 40 | 41 | |
| 41 | 42 | def test_string(self): |
| … |
… |
|
| 129 | 130 | return dt.astimezone(system_offset).replace(tzinfo=None) |
| 130 | 131 | |
| | 132 | |
| 131 | 133 | class TestParseFetchResponse(unittest.TestCase): |
| 132 | 134 | |
| 133 | 135 | def test_basic(self): |
| 134 | 136 | 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: {}}) |
| 141 | 138 | |
| 142 | 139 | |
| … |
… |
|
| 149 | 146 | |
| 150 | 147 | |
| | 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 | |
| 151 | 163 | def test_UID(self): |
| 152 | 164 | 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 | |
| 155 | 173 | |
| 156 | 174 | 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): |
| 157 | 180 | self.fail() |
| | 181 | |
| 158 | 182 | |
| 159 | 183 | def test_INTERNALDATE(self): |
| … |
… |
|
| 181 | 205 | # dt = check(' 9-Dec-2007 17:08:08 +0000', |
| 182 | 206 | # 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): |
| 211 | 207 | |
| 212 | 208 | |