PageRenderTime 52ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/lib-python/2.7/test/test_mailbox.py

https://bitbucket.org/varialus/jyjy
Python | 1970 lines | 1818 code | 82 blank | 70 comment | 59 complexity | f829fe05f175779145a7a8f1da2d7241 MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. import os
  2. import sys
  3. import time
  4. import stat
  5. import socket
  6. import email
  7. import email.message
  8. import re
  9. import StringIO
  10. from test import test_support
  11. import unittest
  12. import mailbox
  13. import glob
  14. try:
  15. import fcntl
  16. except ImportError:
  17. pass
  18. # Silence Py3k warning
  19. rfc822 = test_support.import_module('rfc822', deprecated=True)
  20. class TestBase(unittest.TestCase):
  21. def _check_sample(self, msg):
  22. # Inspect a mailbox.Message representation of the sample message
  23. self.assertIsInstance(msg, email.message.Message)
  24. self.assertIsInstance(msg, mailbox.Message)
  25. for key, value in _sample_headers.iteritems():
  26. self.assertIn(value, msg.get_all(key))
  27. self.assertTrue(msg.is_multipart())
  28. self.assertEqual(len(msg.get_payload()), len(_sample_payloads))
  29. for i, payload in enumerate(_sample_payloads):
  30. part = msg.get_payload(i)
  31. self.assertIsInstance(part, email.message.Message)
  32. self.assertNotIsInstance(part, mailbox.Message)
  33. self.assertEqual(part.get_payload(), payload)
  34. def _delete_recursively(self, target):
  35. # Delete a file or delete a directory recursively
  36. if os.path.isdir(target):
  37. for path, dirs, files in os.walk(target, topdown=False):
  38. for name in files:
  39. os.remove(os.path.join(path, name))
  40. for name in dirs:
  41. os.rmdir(os.path.join(path, name))
  42. os.rmdir(target)
  43. elif os.path.exists(target):
  44. os.remove(target)
  45. class TestMailbox(TestBase):
  46. _factory = None # Overridden by subclasses to reuse tests
  47. _template = 'From: foo\n\n%s'
  48. def setUp(self):
  49. self._path = test_support.TESTFN
  50. self._delete_recursively(self._path)
  51. self._box = self._factory(self._path)
  52. def tearDown(self):
  53. self._box.close()
  54. self._delete_recursively(self._path)
  55. def test_add(self):
  56. # Add copies of a sample message
  57. keys = []
  58. keys.append(self._box.add(self._template % 0))
  59. self.assertEqual(len(self._box), 1)
  60. keys.append(self._box.add(mailbox.Message(_sample_message)))
  61. self.assertEqual(len(self._box), 2)
  62. keys.append(self._box.add(email.message_from_string(_sample_message)))
  63. self.assertEqual(len(self._box), 3)
  64. keys.append(self._box.add(StringIO.StringIO(_sample_message)))
  65. self.assertEqual(len(self._box), 4)
  66. keys.append(self._box.add(_sample_message))
  67. self.assertEqual(len(self._box), 5)
  68. self.assertEqual(self._box.get_string(keys[0]), self._template % 0)
  69. for i in (1, 2, 3, 4):
  70. self._check_sample(self._box[keys[i]])
  71. def test_remove(self):
  72. # Remove messages using remove()
  73. self._test_remove_or_delitem(self._box.remove)
  74. def test_delitem(self):
  75. # Remove messages using __delitem__()
  76. self._test_remove_or_delitem(self._box.__delitem__)
  77. def _test_remove_or_delitem(self, method):
  78. # (Used by test_remove() and test_delitem().)
  79. key0 = self._box.add(self._template % 0)
  80. key1 = self._box.add(self._template % 1)
  81. self.assertEqual(len(self._box), 2)
  82. method(key0)
  83. l = len(self._box)
  84. self.assertEqual(l, 1)
  85. self.assertRaises(KeyError, lambda: self._box[key0])
  86. self.assertRaises(KeyError, lambda: method(key0))
  87. self.assertEqual(self._box.get_string(key1), self._template % 1)
  88. key2 = self._box.add(self._template % 2)
  89. self.assertEqual(len(self._box), 2)
  90. method(key2)
  91. l = len(self._box)
  92. self.assertEqual(l, 1)
  93. self.assertRaises(KeyError, lambda: self._box[key2])
  94. self.assertRaises(KeyError, lambda: method(key2))
  95. self.assertEqual(self._box.get_string(key1), self._template % 1)
  96. method(key1)
  97. self.assertEqual(len(self._box), 0)
  98. self.assertRaises(KeyError, lambda: self._box[key1])
  99. self.assertRaises(KeyError, lambda: method(key1))
  100. def test_discard(self, repetitions=10):
  101. # Discard messages
  102. key0 = self._box.add(self._template % 0)
  103. key1 = self._box.add(self._template % 1)
  104. self.assertEqual(len(self._box), 2)
  105. self._box.discard(key0)
  106. self.assertEqual(len(self._box), 1)
  107. self.assertRaises(KeyError, lambda: self._box[key0])
  108. self._box.discard(key0)
  109. self.assertEqual(len(self._box), 1)
  110. self.assertRaises(KeyError, lambda: self._box[key0])
  111. def test_get(self):
  112. # Retrieve messages using get()
  113. key0 = self._box.add(self._template % 0)
  114. msg = self._box.get(key0)
  115. self.assertEqual(msg['from'], 'foo')
  116. self.assertEqual(msg.get_payload(), '0')
  117. self.assertIs(self._box.get('foo'), None)
  118. self.assertFalse(self._box.get('foo', False))
  119. self._box.close()
  120. self._box = self._factory(self._path, factory=rfc822.Message)
  121. key1 = self._box.add(self._template % 1)
  122. msg = self._box.get(key1)
  123. self.assertEqual(msg['from'], 'foo')
  124. self.assertEqual(msg.fp.read(), '1')
  125. def test_getitem(self):
  126. # Retrieve message using __getitem__()
  127. key0 = self._box.add(self._template % 0)
  128. msg = self._box[key0]
  129. self.assertEqual(msg['from'], 'foo')
  130. self.assertEqual(msg.get_payload(), '0')
  131. self.assertRaises(KeyError, lambda: self._box['foo'])
  132. self._box.discard(key0)
  133. self.assertRaises(KeyError, lambda: self._box[key0])
  134. def test_get_message(self):
  135. # Get Message representations of messages
  136. key0 = self._box.add(self._template % 0)
  137. key1 = self._box.add(_sample_message)
  138. msg0 = self._box.get_message(key0)
  139. self.assertIsInstance(msg0, mailbox.Message)
  140. self.assertEqual(msg0['from'], 'foo')
  141. self.assertEqual(msg0.get_payload(), '0')
  142. self._check_sample(self._box.get_message(key1))
  143. def test_get_string(self):
  144. # Get string representations of messages
  145. key0 = self._box.add(self._template % 0)
  146. key1 = self._box.add(_sample_message)
  147. self.assertEqual(self._box.get_string(key0), self._template % 0)
  148. self.assertEqual(self._box.get_string(key1), _sample_message)
  149. def test_get_file(self):
  150. # Get file representations of messages
  151. key0 = self._box.add(self._template % 0)
  152. key1 = self._box.add(_sample_message)
  153. self.assertEqual(self._box.get_file(key0).read().replace(os.linesep, '\n'),
  154. self._template % 0)
  155. self.assertEqual(self._box.get_file(key1).read().replace(os.linesep, '\n'),
  156. _sample_message)
  157. def test_iterkeys(self):
  158. # Get keys using iterkeys()
  159. self._check_iteration(self._box.iterkeys, do_keys=True, do_values=False)
  160. def test_keys(self):
  161. # Get keys using keys()
  162. self._check_iteration(self._box.keys, do_keys=True, do_values=False)
  163. def test_itervalues(self):
  164. # Get values using itervalues()
  165. self._check_iteration(self._box.itervalues, do_keys=False,
  166. do_values=True)
  167. def test_iter(self):
  168. # Get values using __iter__()
  169. self._check_iteration(self._box.__iter__, do_keys=False,
  170. do_values=True)
  171. def test_values(self):
  172. # Get values using values()
  173. self._check_iteration(self._box.values, do_keys=False, do_values=True)
  174. def test_iteritems(self):
  175. # Get keys and values using iteritems()
  176. self._check_iteration(self._box.iteritems, do_keys=True,
  177. do_values=True)
  178. def test_items(self):
  179. # Get keys and values using items()
  180. self._check_iteration(self._box.items, do_keys=True, do_values=True)
  181. def _check_iteration(self, method, do_keys, do_values, repetitions=10):
  182. for value in method():
  183. self.fail("Not empty")
  184. keys, values = [], []
  185. for i in xrange(repetitions):
  186. keys.append(self._box.add(self._template % i))
  187. values.append(self._template % i)
  188. if do_keys and not do_values:
  189. returned_keys = list(method())
  190. elif do_values and not do_keys:
  191. returned_values = list(method())
  192. else:
  193. returned_keys, returned_values = [], []
  194. for key, value in method():
  195. returned_keys.append(key)
  196. returned_values.append(value)
  197. if do_keys:
  198. self.assertEqual(len(keys), len(returned_keys))
  199. self.assertEqual(set(keys), set(returned_keys))
  200. if do_values:
  201. count = 0
  202. for value in returned_values:
  203. self.assertEqual(value['from'], 'foo')
  204. self.assertTrue(int(value.get_payload()) < repetitions,
  205. (value.get_payload(), repetitions))
  206. count += 1
  207. self.assertEqual(len(values), count)
  208. def test_has_key(self):
  209. # Check existence of keys using has_key()
  210. self._test_has_key_or_contains(self._box.has_key)
  211. def test_contains(self):
  212. # Check existence of keys using __contains__()
  213. self._test_has_key_or_contains(self._box.__contains__)
  214. def _test_has_key_or_contains(self, method):
  215. # (Used by test_has_key() and test_contains().)
  216. self.assertFalse(method('foo'))
  217. key0 = self._box.add(self._template % 0)
  218. self.assertTrue(method(key0))
  219. self.assertFalse(method('foo'))
  220. key1 = self._box.add(self._template % 1)
  221. self.assertTrue(method(key1))
  222. self.assertTrue(method(key0))
  223. self.assertFalse(method('foo'))
  224. self._box.remove(key0)
  225. self.assertFalse(method(key0))
  226. self.assertTrue(method(key1))
  227. self.assertFalse(method('foo'))
  228. self._box.remove(key1)
  229. self.assertFalse(method(key1))
  230. self.assertFalse(method(key0))
  231. self.assertFalse(method('foo'))
  232. def test_len(self, repetitions=10):
  233. # Get message count
  234. keys = []
  235. for i in xrange(repetitions):
  236. self.assertEqual(len(self._box), i)
  237. keys.append(self._box.add(self._template % i))
  238. self.assertEqual(len(self._box), i + 1)
  239. for i in xrange(repetitions):
  240. self.assertEqual(len(self._box), repetitions - i)
  241. self._box.remove(keys[i])
  242. self.assertEqual(len(self._box), repetitions - i - 1)
  243. def test_set_item(self):
  244. # Modify messages using __setitem__()
  245. key0 = self._box.add(self._template % 'original 0')
  246. self.assertEqual(self._box.get_string(key0),
  247. self._template % 'original 0')
  248. key1 = self._box.add(self._template % 'original 1')
  249. self.assertEqual(self._box.get_string(key1),
  250. self._template % 'original 1')
  251. self._box[key0] = self._template % 'changed 0'
  252. self.assertEqual(self._box.get_string(key0),
  253. self._template % 'changed 0')
  254. self._box[key1] = self._template % 'changed 1'
  255. self.assertEqual(self._box.get_string(key1),
  256. self._template % 'changed 1')
  257. self._box[key0] = _sample_message
  258. self._check_sample(self._box[key0])
  259. self._box[key1] = self._box[key0]
  260. self._check_sample(self._box[key1])
  261. self._box[key0] = self._template % 'original 0'
  262. self.assertEqual(self._box.get_string(key0),
  263. self._template % 'original 0')
  264. self._check_sample(self._box[key1])
  265. self.assertRaises(KeyError,
  266. lambda: self._box.__setitem__('foo', 'bar'))
  267. self.assertRaises(KeyError, lambda: self._box['foo'])
  268. self.assertEqual(len(self._box), 2)
  269. def test_clear(self, iterations=10):
  270. # Remove all messages using clear()
  271. keys = []
  272. for i in xrange(iterations):
  273. self._box.add(self._template % i)
  274. for i, key in enumerate(keys):
  275. self.assertEqual(self._box.get_string(key), self._template % i)
  276. self._box.clear()
  277. self.assertEqual(len(self._box), 0)
  278. for i, key in enumerate(keys):
  279. self.assertRaises(KeyError, lambda: self._box.get_string(key))
  280. def test_pop(self):
  281. # Get and remove a message using pop()
  282. key0 = self._box.add(self._template % 0)
  283. self.assertIn(key0, self._box)
  284. key1 = self._box.add(self._template % 1)
  285. self.assertIn(key1, self._box)
  286. self.assertEqual(self._box.pop(key0).get_payload(), '0')
  287. self.assertNotIn(key0, self._box)
  288. self.assertIn(key1, self._box)
  289. key2 = self._box.add(self._template % 2)
  290. self.assertIn(key2, self._box)
  291. self.assertEqual(self._box.pop(key2).get_payload(), '2')
  292. self.assertNotIn(key2, self._box)
  293. self.assertIn(key1, self._box)
  294. self.assertEqual(self._box.pop(key1).get_payload(), '1')
  295. self.assertNotIn(key1, self._box)
  296. self.assertEqual(len(self._box), 0)
  297. def test_popitem(self, iterations=10):
  298. # Get and remove an arbitrary (key, message) using popitem()
  299. keys = []
  300. for i in xrange(10):
  301. keys.append(self._box.add(self._template % i))
  302. seen = []
  303. for i in xrange(10):
  304. key, msg = self._box.popitem()
  305. self.assertIn(key, keys)
  306. self.assertNotIn(key, seen)
  307. seen.append(key)
  308. self.assertEqual(int(msg.get_payload()), keys.index(key))
  309. self.assertEqual(len(self._box), 0)
  310. for key in keys:
  311. self.assertRaises(KeyError, lambda: self._box[key])
  312. def test_update(self):
  313. # Modify multiple messages using update()
  314. key0 = self._box.add(self._template % 'original 0')
  315. key1 = self._box.add(self._template % 'original 1')
  316. key2 = self._box.add(self._template % 'original 2')
  317. self._box.update({key0: self._template % 'changed 0',
  318. key2: _sample_message})
  319. self.assertEqual(len(self._box), 3)
  320. self.assertEqual(self._box.get_string(key0),
  321. self._template % 'changed 0')
  322. self.assertEqual(self._box.get_string(key1),
  323. self._template % 'original 1')
  324. self._check_sample(self._box[key2])
  325. self._box.update([(key2, self._template % 'changed 2'),
  326. (key1, self._template % 'changed 1'),
  327. (key0, self._template % 'original 0')])
  328. self.assertEqual(len(self._box), 3)
  329. self.assertEqual(self._box.get_string(key0),
  330. self._template % 'original 0')
  331. self.assertEqual(self._box.get_string(key1),
  332. self._template % 'changed 1')
  333. self.assertEqual(self._box.get_string(key2),
  334. self._template % 'changed 2')
  335. self.assertRaises(KeyError,
  336. lambda: self._box.update({'foo': 'bar',
  337. key0: self._template % "changed 0"}))
  338. self.assertEqual(len(self._box), 3)
  339. self.assertEqual(self._box.get_string(key0),
  340. self._template % "changed 0")
  341. self.assertEqual(self._box.get_string(key1),
  342. self._template % "changed 1")
  343. self.assertEqual(self._box.get_string(key2),
  344. self._template % "changed 2")
  345. def test_flush(self):
  346. # Write changes to disk
  347. self._test_flush_or_close(self._box.flush, True)
  348. def test_lock_unlock(self):
  349. # Lock and unlock the mailbox
  350. self.assertFalse(os.path.exists(self._get_lock_path()))
  351. self._box.lock()
  352. self.assertTrue(os.path.exists(self._get_lock_path()))
  353. self._box.unlock()
  354. self.assertFalse(os.path.exists(self._get_lock_path()))
  355. def test_close(self):
  356. # Close mailbox and flush changes to disk
  357. self._test_flush_or_close(self._box.close, False)
  358. def _test_flush_or_close(self, method, should_call_close):
  359. contents = [self._template % i for i in xrange(3)]
  360. self._box.add(contents[0])
  361. self._box.add(contents[1])
  362. self._box.add(contents[2])
  363. method()
  364. if should_call_close:
  365. self._box.close()
  366. self._box = self._factory(self._path)
  367. keys = self._box.keys()
  368. self.assertEqual(len(keys), 3)
  369. for key in keys:
  370. self.assertIn(self._box.get_string(key), contents)
  371. def test_dump_message(self):
  372. # Write message representations to disk
  373. for input in (email.message_from_string(_sample_message),
  374. _sample_message, StringIO.StringIO(_sample_message)):
  375. output = StringIO.StringIO()
  376. self._box._dump_message(input, output)
  377. self.assertEqual(output.getvalue(),
  378. _sample_message.replace('\n', os.linesep))
  379. output = StringIO.StringIO()
  380. self.assertRaises(TypeError,
  381. lambda: self._box._dump_message(None, output))
  382. def _get_lock_path(self):
  383. # Return the path of the dot lock file. May be overridden.
  384. return self._path + '.lock'
  385. class TestMailboxSuperclass(TestBase):
  386. def test_notimplemented(self):
  387. # Test that all Mailbox methods raise NotImplementedException.
  388. box = mailbox.Mailbox('path')
  389. self.assertRaises(NotImplementedError, lambda: box.add(''))
  390. self.assertRaises(NotImplementedError, lambda: box.remove(''))
  391. self.assertRaises(NotImplementedError, lambda: box.__delitem__(''))
  392. self.assertRaises(NotImplementedError, lambda: box.discard(''))
  393. self.assertRaises(NotImplementedError, lambda: box.__setitem__('', ''))
  394. self.assertRaises(NotImplementedError, lambda: box.iterkeys())
  395. self.assertRaises(NotImplementedError, lambda: box.keys())
  396. self.assertRaises(NotImplementedError, lambda: box.itervalues().next())
  397. self.assertRaises(NotImplementedError, lambda: box.__iter__().next())
  398. self.assertRaises(NotImplementedError, lambda: box.values())
  399. self.assertRaises(NotImplementedError, lambda: box.iteritems().next())
  400. self.assertRaises(NotImplementedError, lambda: box.items())
  401. self.assertRaises(NotImplementedError, lambda: box.get(''))
  402. self.assertRaises(NotImplementedError, lambda: box.__getitem__(''))
  403. self.assertRaises(NotImplementedError, lambda: box.get_message(''))
  404. self.assertRaises(NotImplementedError, lambda: box.get_string(''))
  405. self.assertRaises(NotImplementedError, lambda: box.get_file(''))
  406. self.assertRaises(NotImplementedError, lambda: box.has_key(''))
  407. self.assertRaises(NotImplementedError, lambda: box.__contains__(''))
  408. self.assertRaises(NotImplementedError, lambda: box.__len__())
  409. self.assertRaises(NotImplementedError, lambda: box.clear())
  410. self.assertRaises(NotImplementedError, lambda: box.pop(''))
  411. self.assertRaises(NotImplementedError, lambda: box.popitem())
  412. self.assertRaises(NotImplementedError, lambda: box.update((('', ''),)))
  413. self.assertRaises(NotImplementedError, lambda: box.flush())
  414. self.assertRaises(NotImplementedError, lambda: box.lock())
  415. self.assertRaises(NotImplementedError, lambda: box.unlock())
  416. self.assertRaises(NotImplementedError, lambda: box.close())
  417. class TestMaildir(TestMailbox):
  418. _factory = lambda self, path, factory=None: mailbox.Maildir(path, factory)
  419. def setUp(self):
  420. TestMailbox.setUp(self)
  421. if os.name in ('nt', 'os2') or sys.platform == 'cygwin':
  422. self._box.colon = '!'
  423. def test_add_MM(self):
  424. # Add a MaildirMessage instance
  425. msg = mailbox.MaildirMessage(self._template % 0)
  426. msg.set_subdir('cur')
  427. msg.set_info('foo')
  428. key = self._box.add(msg)
  429. self.assertTrue(os.path.exists(os.path.join(self._path, 'cur', '%s%sfoo' %
  430. (key, self._box.colon))))
  431. def test_get_MM(self):
  432. # Get a MaildirMessage instance
  433. msg = mailbox.MaildirMessage(self._template % 0)
  434. msg.set_subdir('cur')
  435. msg.set_flags('RF')
  436. key = self._box.add(msg)
  437. msg_returned = self._box.get_message(key)
  438. self.assertIsInstance(msg_returned, mailbox.MaildirMessage)
  439. self.assertEqual(msg_returned.get_subdir(), 'cur')
  440. self.assertEqual(msg_returned.get_flags(), 'FR')
  441. def test_set_MM(self):
  442. # Set with a MaildirMessage instance
  443. msg0 = mailbox.MaildirMessage(self._template % 0)
  444. msg0.set_flags('TP')
  445. key = self._box.add(msg0)
  446. msg_returned = self._box.get_message(key)
  447. self.assertEqual(msg_returned.get_subdir(), 'new')
  448. self.assertEqual(msg_returned.get_flags(), 'PT')
  449. msg1 = mailbox.MaildirMessage(self._template % 1)
  450. self._box[key] = msg1
  451. msg_returned = self._box.get_message(key)
  452. self.assertEqual(msg_returned.get_subdir(), 'new')
  453. self.assertEqual(msg_returned.get_flags(), '')
  454. self.assertEqual(msg_returned.get_payload(), '1')
  455. msg2 = mailbox.MaildirMessage(self._template % 2)
  456. msg2.set_info('2,S')
  457. self._box[key] = msg2
  458. self._box[key] = self._template % 3
  459. msg_returned = self._box.get_message(key)
  460. self.assertEqual(msg_returned.get_subdir(), 'new')
  461. self.assertEqual(msg_returned.get_flags(), 'S')
  462. self.assertEqual(msg_returned.get_payload(), '3')
  463. def test_consistent_factory(self):
  464. # Add a message.
  465. msg = mailbox.MaildirMessage(self._template % 0)
  466. msg.set_subdir('cur')
  467. msg.set_flags('RF')
  468. key = self._box.add(msg)
  469. # Create new mailbox with
  470. class FakeMessage(mailbox.MaildirMessage):
  471. pass
  472. box = mailbox.Maildir(self._path, factory=FakeMessage)
  473. box.colon = self._box.colon
  474. msg2 = box.get_message(key)
  475. self.assertIsInstance(msg2, FakeMessage)
  476. def test_initialize_new(self):
  477. # Initialize a non-existent mailbox
  478. self.tearDown()
  479. self._box = mailbox.Maildir(self._path)
  480. self._check_basics(factory=rfc822.Message)
  481. self._delete_recursively(self._path)
  482. self._box = self._factory(self._path, factory=None)
  483. self._check_basics()
  484. def test_initialize_existing(self):
  485. # Initialize an existing mailbox
  486. self.tearDown()
  487. for subdir in '', 'tmp', 'new', 'cur':
  488. os.mkdir(os.path.normpath(os.path.join(self._path, subdir)))
  489. self._box = mailbox.Maildir(self._path)
  490. self._check_basics(factory=rfc822.Message)
  491. self._box = mailbox.Maildir(self._path, factory=None)
  492. self._check_basics()
  493. def _check_basics(self, factory=None):
  494. # (Used by test_open_new() and test_open_existing().)
  495. self.assertEqual(self._box._path, os.path.abspath(self._path))
  496. self.assertEqual(self._box._factory, factory)
  497. for subdir in '', 'tmp', 'new', 'cur':
  498. path = os.path.join(self._path, subdir)
  499. mode = os.stat(path)[stat.ST_MODE]
  500. self.assertTrue(stat.S_ISDIR(mode), "Not a directory: '%s'" % path)
  501. def test_list_folders(self):
  502. # List folders
  503. self._box.add_folder('one')
  504. self._box.add_folder('two')
  505. self._box.add_folder('three')
  506. self.assertEqual(len(self._box.list_folders()), 3)
  507. self.assertEqual(set(self._box.list_folders()),
  508. set(('one', 'two', 'three')))
  509. def test_get_folder(self):
  510. # Open folders
  511. self._box.add_folder('foo.bar')
  512. folder0 = self._box.get_folder('foo.bar')
  513. folder0.add(self._template % 'bar')
  514. self.assertTrue(os.path.isdir(os.path.join(self._path, '.foo.bar')))
  515. folder1 = self._box.get_folder('foo.bar')
  516. self.assertEqual(folder1.get_string(folder1.keys()[0]),
  517. self._template % 'bar')
  518. def test_add_and_remove_folders(self):
  519. # Delete folders
  520. self._box.add_folder('one')
  521. self._box.add_folder('two')
  522. self.assertEqual(len(self._box.list_folders()), 2)
  523. self.assertEqual(set(self._box.list_folders()), set(('one', 'two')))
  524. self._box.remove_folder('one')
  525. self.assertEqual(len(self._box.list_folders()), 1)
  526. self.assertEqual(set(self._box.list_folders()), set(('two',)))
  527. self._box.add_folder('three')
  528. self.assertEqual(len(self._box.list_folders()), 2)
  529. self.assertEqual(set(self._box.list_folders()), set(('two', 'three')))
  530. self._box.remove_folder('three')
  531. self.assertEqual(len(self._box.list_folders()), 1)
  532. self.assertEqual(set(self._box.list_folders()), set(('two',)))
  533. self._box.remove_folder('two')
  534. self.assertEqual(len(self._box.list_folders()), 0)
  535. self.assertEqual(self._box.list_folders(), [])
  536. def test_clean(self):
  537. # Remove old files from 'tmp'
  538. foo_path = os.path.join(self._path, 'tmp', 'foo')
  539. bar_path = os.path.join(self._path, 'tmp', 'bar')
  540. with open(foo_path, 'w') as f:
  541. f.write("@")
  542. with open(bar_path, 'w') as f:
  543. f.write("@")
  544. self._box.clean()
  545. self.assertTrue(os.path.exists(foo_path))
  546. self.assertTrue(os.path.exists(bar_path))
  547. foo_stat = os.stat(foo_path)
  548. os.utime(foo_path, (time.time() - 129600 - 2,
  549. foo_stat.st_mtime))
  550. self._box.clean()
  551. self.assertFalse(os.path.exists(foo_path))
  552. self.assertTrue(os.path.exists(bar_path))
  553. def test_create_tmp(self, repetitions=10):
  554. # Create files in tmp directory
  555. hostname = socket.gethostname()
  556. if '/' in hostname:
  557. hostname = hostname.replace('/', r'\057')
  558. if ':' in hostname:
  559. hostname = hostname.replace(':', r'\072')
  560. pid = os.getpid()
  561. pattern = re.compile(r"(?P<time>\d+)\.M(?P<M>\d{1,6})P(?P<P>\d+)"
  562. r"Q(?P<Q>\d+)\.(?P<host>[^:/]+)")
  563. previous_groups = None
  564. for x in xrange(repetitions):
  565. tmp_file = self._box._create_tmp()
  566. head, tail = os.path.split(tmp_file.name)
  567. self.assertEqual(head, os.path.abspath(os.path.join(self._path,
  568. "tmp")),
  569. "File in wrong location: '%s'" % head)
  570. match = pattern.match(tail)
  571. self.assertTrue(match is not None, "Invalid file name: '%s'" % tail)
  572. groups = match.groups()
  573. if previous_groups is not None:
  574. self.assertTrue(int(groups[0] >= previous_groups[0]),
  575. "Non-monotonic seconds: '%s' before '%s'" %
  576. (previous_groups[0], groups[0]))
  577. self.assertTrue(int(groups[1] >= previous_groups[1]) or
  578. groups[0] != groups[1],
  579. "Non-monotonic milliseconds: '%s' before '%s'" %
  580. (previous_groups[1], groups[1]))
  581. self.assertTrue(int(groups[2]) == pid,
  582. "Process ID mismatch: '%s' should be '%s'" %
  583. (groups[2], pid))
  584. self.assertTrue(int(groups[3]) == int(previous_groups[3]) + 1,
  585. "Non-sequential counter: '%s' before '%s'" %
  586. (previous_groups[3], groups[3]))
  587. self.assertTrue(groups[4] == hostname,
  588. "Host name mismatch: '%s' should be '%s'" %
  589. (groups[4], hostname))
  590. previous_groups = groups
  591. tmp_file.write(_sample_message)
  592. tmp_file.seek(0)
  593. self.assertTrue(tmp_file.read() == _sample_message)
  594. tmp_file.close()
  595. file_count = len(os.listdir(os.path.join(self._path, "tmp")))
  596. self.assertTrue(file_count == repetitions,
  597. "Wrong file count: '%s' should be '%s'" %
  598. (file_count, repetitions))
  599. def test_refresh(self):
  600. # Update the table of contents
  601. self.assertEqual(self._box._toc, {})
  602. key0 = self._box.add(self._template % 0)
  603. key1 = self._box.add(self._template % 1)
  604. self.assertEqual(self._box._toc, {})
  605. self._box._refresh()
  606. self.assertEqual(self._box._toc, {key0: os.path.join('new', key0),
  607. key1: os.path.join('new', key1)})
  608. key2 = self._box.add(self._template % 2)
  609. self.assertEqual(self._box._toc, {key0: os.path.join('new', key0),
  610. key1: os.path.join('new', key1)})
  611. self._box._refresh()
  612. self.assertEqual(self._box._toc, {key0: os.path.join('new', key0),
  613. key1: os.path.join('new', key1),
  614. key2: os.path.join('new', key2)})
  615. def test_lookup(self):
  616. # Look up message subpaths in the TOC
  617. self.assertRaises(KeyError, lambda: self._box._lookup('foo'))
  618. key0 = self._box.add(self._template % 0)
  619. self.assertEqual(self._box._lookup(key0), os.path.join('new', key0))
  620. os.remove(os.path.join(self._path, 'new', key0))
  621. self.assertEqual(self._box._toc, {key0: os.path.join('new', key0)})
  622. # Be sure that the TOC is read back from disk (see issue #6896
  623. # about bad mtime behaviour on some systems).
  624. self._box.flush()
  625. self.assertRaises(KeyError, lambda: self._box._lookup(key0))
  626. self.assertEqual(self._box._toc, {})
  627. def test_lock_unlock(self):
  628. # Lock and unlock the mailbox. For Maildir, this does nothing.
  629. self._box.lock()
  630. self._box.unlock()
  631. def test_folder (self):
  632. # Test for bug #1569790: verify that folders returned by .get_folder()
  633. # use the same factory function.
  634. def dummy_factory (s):
  635. return None
  636. box = self._factory(self._path, factory=dummy_factory)
  637. folder = box.add_folder('folder1')
  638. self.assertIs(folder._factory, dummy_factory)
  639. folder1_alias = box.get_folder('folder1')
  640. self.assertIs(folder1_alias._factory, dummy_factory)
  641. def test_directory_in_folder (self):
  642. # Test that mailboxes still work if there's a stray extra directory
  643. # in a folder.
  644. for i in range(10):
  645. self._box.add(mailbox.Message(_sample_message))
  646. # Create a stray directory
  647. os.mkdir(os.path.join(self._path, 'cur', 'stray-dir'))
  648. # Check that looping still works with the directory present.
  649. for msg in self._box:
  650. pass
  651. def test_file_permissions(self):
  652. # Verify that message files are created without execute permissions
  653. if not hasattr(os, "stat") or not hasattr(os, "umask"):
  654. return
  655. msg = mailbox.MaildirMessage(self._template % 0)
  656. orig_umask = os.umask(0)
  657. try:
  658. key = self._box.add(msg)
  659. finally:
  660. os.umask(orig_umask)
  661. path = os.path.join(self._path, self._box._lookup(key))
  662. mode = os.stat(path).st_mode
  663. self.assertEqual(mode & 0111, 0)
  664. def test_folder_file_perms(self):
  665. # From bug #3228, we want to verify that the file created inside a Maildir
  666. # subfolder isn't marked as executable.
  667. if not hasattr(os, "stat") or not hasattr(os, "umask"):
  668. return
  669. orig_umask = os.umask(0)
  670. try:
  671. subfolder = self._box.add_folder('subfolder')
  672. finally:
  673. os.umask(orig_umask)
  674. path = os.path.join(subfolder._path, 'maildirfolder')
  675. st = os.stat(path)
  676. perms = st.st_mode
  677. self.assertFalse((perms & 0111)) # Execute bits should all be off.
  678. def test_reread(self):
  679. # Put the last modified times more than two seconds into the past
  680. # (because mtime may have only a two second granularity).
  681. for subdir in ('cur', 'new'):
  682. os.utime(os.path.join(self._box._path, subdir),
  683. (time.time()-5,)*2)
  684. # Because mtime has a two second granularity in worst case (FAT), a
  685. # refresh is done unconditionally if called for within
  686. # two-second-plus-a-bit of the last one, just in case the mbox has
  687. # changed; so now we have to wait for that interval to expire.
  688. time.sleep(2.01 + self._box._skewfactor)
  689. # Re-reading causes the ._toc attribute to be assigned a new dictionary
  690. # object, so we'll check that the ._toc attribute isn't a different
  691. # object.
  692. orig_toc = self._box._toc
  693. def refreshed():
  694. return self._box._toc is not orig_toc
  695. self._box._refresh()
  696. self.assertFalse(refreshed())
  697. # Now, write something into cur and remove it. This changes
  698. # the mtime and should cause a re-read.
  699. filename = os.path.join(self._path, 'cur', 'stray-file')
  700. f = open(filename, 'w')
  701. f.close()
  702. os.unlink(filename)
  703. self._box._refresh()
  704. self.assertTrue(refreshed())
  705. class _TestMboxMMDF(TestMailbox):
  706. def tearDown(self):
  707. self._box.close()
  708. self._delete_recursively(self._path)
  709. for lock_remnant in glob.glob(self._path + '.*'):
  710. test_support.unlink(lock_remnant)
  711. def test_add_from_string(self):
  712. # Add a string starting with 'From ' to the mailbox
  713. key = self._box.add('From foo@bar blah\nFrom: foo\n\n0')
  714. self.assertEqual(self._box[key].get_from(), 'foo@bar blah')
  715. self.assertEqual(self._box[key].get_payload(), '0')
  716. def test_add_mbox_or_mmdf_message(self):
  717. # Add an mboxMessage or MMDFMessage
  718. for class_ in (mailbox.mboxMessage, mailbox.MMDFMessage):
  719. msg = class_('From foo@bar blah\nFrom: foo\n\n0')
  720. key = self._box.add(msg)
  721. def test_open_close_open(self):
  722. # Open and inspect previously-created mailbox
  723. values = [self._template % i for i in xrange(3)]
  724. for value in values:
  725. self._box.add(value)
  726. self._box.close()
  727. mtime = os.path.getmtime(self._path)
  728. self._box = self._factory(self._path)
  729. self.assertEqual(len(self._box), 3)
  730. for key in self._box.iterkeys():
  731. self.assertIn(self._box.get_string(key), values)
  732. self._box.close()
  733. self.assertEqual(mtime, os.path.getmtime(self._path))
  734. def test_add_and_close(self):
  735. # Verifying that closing a mailbox doesn't change added items
  736. self._box.add(_sample_message)
  737. for i in xrange(3):
  738. self._box.add(self._template % i)
  739. self._box.add(_sample_message)
  740. self._box._file.flush()
  741. self._box._file.seek(0)
  742. contents = self._box._file.read()
  743. self._box.close()
  744. with open(self._path, 'rb') as f:
  745. self.assertEqual(contents, f.read())
  746. self._box = self._factory(self._path)
  747. def test_lock_conflict(self):
  748. # Fork off a subprocess that will lock the file for 2 seconds,
  749. # unlock it, and then exit.
  750. if not hasattr(os, 'fork'):
  751. return
  752. pid = os.fork()
  753. if pid == 0:
  754. # In the child, lock the mailbox.
  755. self._box.lock()
  756. time.sleep(2)
  757. self._box.unlock()
  758. os._exit(0)
  759. # In the parent, sleep a bit to give the child time to acquire
  760. # the lock.
  761. time.sleep(0.5)
  762. try:
  763. self.assertRaises(mailbox.ExternalClashError,
  764. self._box.lock)
  765. finally:
  766. # Wait for child to exit. Locking should now succeed.
  767. exited_pid, status = os.waitpid(pid, 0)
  768. self._box.lock()
  769. self._box.unlock()
  770. def test_relock(self):
  771. # Test case for bug #1575506: the mailbox class was locking the
  772. # wrong file object in its flush() method.
  773. msg = "Subject: sub\n\nbody\n"
  774. key1 = self._box.add(msg)
  775. self._box.flush()
  776. self._box.close()
  777. self._box = self._factory(self._path)
  778. self._box.lock()
  779. key2 = self._box.add(msg)
  780. self._box.flush()
  781. self.assertTrue(self._box._locked)
  782. self._box.close()
  783. class TestMbox(_TestMboxMMDF):
  784. _factory = lambda self, path, factory=None: mailbox.mbox(path, factory)
  785. def test_file_perms(self):
  786. # From bug #3228, we want to verify that the mailbox file isn't executable,
  787. # even if the umask is set to something that would leave executable bits set.
  788. # We only run this test on platforms that support umask.
  789. if hasattr(os, 'umask') and hasattr(os, 'stat'):
  790. try:
  791. old_umask = os.umask(0077)
  792. self._box.close()
  793. os.unlink(self._path)
  794. self._box = mailbox.mbox(self._path, create=True)
  795. self._box.add('')
  796. self._box.close()
  797. finally:
  798. os.umask(old_umask)
  799. st = os.stat(self._path)
  800. perms = st.st_mode
  801. self.assertFalse((perms & 0111)) # Execute bits should all be off.
  802. class TestMMDF(_TestMboxMMDF):
  803. _factory = lambda self, path, factory=None: mailbox.MMDF(path, factory)
  804. class TestMH(TestMailbox):
  805. _factory = lambda self, path, factory=None: mailbox.MH(path, factory)
  806. def test_list_folders(self):
  807. # List folders
  808. self._box.add_folder('one')
  809. self._box.add_folder('two')
  810. self._box.add_folder('three')
  811. self.assertEqual(len(self._box.list_folders()), 3)
  812. self.assertEqual(set(self._box.list_folders()),
  813. set(('one', 'two', 'three')))
  814. def test_get_folder(self):
  815. # Open folders
  816. def dummy_factory (s):
  817. return None
  818. self._box = self._factory(self._path, dummy_factory)
  819. new_folder = self._box.add_folder('foo.bar')
  820. folder0 = self._box.get_folder('foo.bar')
  821. folder0.add(self._template % 'bar')
  822. self.assertTrue(os.path.isdir(os.path.join(self._path, 'foo.bar')))
  823. folder1 = self._box.get_folder('foo.bar')
  824. self.assertEqual(folder1.get_string(folder1.keys()[0]),
  825. self._template % 'bar')
  826. # Test for bug #1569790: verify that folders returned by .get_folder()
  827. # use the same factory function.
  828. self.assertIs(new_folder._factory, self._box._factory)
  829. self.assertIs(folder0._factory, self._box._factory)
  830. def test_add_and_remove_folders(self):
  831. # Delete folders
  832. self._box.add_folder('one')
  833. self._box.add_folder('two')
  834. self.assertEqual(len(self._box.list_folders()), 2)
  835. self.assertEqual(set(self._box.list_folders()), set(('one', 'two')))
  836. self._box.remove_folder('one')
  837. self.assertEqual(len(self._box.list_folders()), 1)
  838. self.assertEqual(set(self._box.list_folders()), set(('two', )))
  839. self._box.add_folder('three')
  840. self.assertEqual(len(self._box.list_folders()), 2)
  841. self.assertEqual(set(self._box.list_folders()), set(('two', 'three')))
  842. self._box.remove_folder('three')
  843. self.assertEqual(len(self._box.list_folders()), 1)
  844. self.assertEqual(set(self._box.list_folders()), set(('two', )))
  845. self._box.remove_folder('two')
  846. self.assertEqual(len(self._box.list_folders()), 0)
  847. self.assertEqual(self._box.list_folders(), [])
  848. def test_sequences(self):
  849. # Get and set sequences
  850. self.assertEqual(self._box.get_sequences(), {})
  851. msg0 = mailbox.MHMessage(self._template % 0)
  852. msg0.add_sequence('foo')
  853. key0 = self._box.add(msg0)
  854. self.assertEqual(self._box.get_sequences(), {'foo':[key0]})
  855. msg1 = mailbox.MHMessage(self._template % 1)
  856. msg1.set_sequences(['bar', 'replied', 'foo'])
  857. key1 = self._box.add(msg1)
  858. self.assertEqual(self._box.get_sequences(),
  859. {'foo':[key0, key1], 'bar':[key1], 'replied':[key1]})
  860. msg0.set_sequences(['flagged'])
  861. self._box[key0] = msg0
  862. self.assertEqual(self._box.get_sequences(),
  863. {'foo':[key1], 'bar':[key1], 'replied':[key1],
  864. 'flagged':[key0]})
  865. self._box.remove(key1)
  866. self.assertEqual(self._box.get_sequences(), {'flagged':[key0]})
  867. def test_issue2625(self):
  868. msg0 = mailbox.MHMessage(self._template % 0)
  869. msg0.add_sequence('foo')
  870. key0 = self._box.add(msg0)
  871. refmsg0 = self._box.get_message(key0)
  872. def test_issue7627(self):
  873. msg0 = mailbox.MHMessage(self._template % 0)
  874. key0 = self._box.add(msg0)
  875. self._box.lock()
  876. self._box.remove(key0)
  877. self._box.unlock()
  878. def test_pack(self):
  879. # Pack the contents of the mailbox
  880. msg0 = mailbox.MHMessage(self._template % 0)
  881. msg1 = mailbox.MHMessage(self._template % 1)
  882. msg2 = mailbox.MHMessage(self._template % 2)
  883. msg3 = mailbox.MHMessage(self._template % 3)
  884. msg0.set_sequences(['foo', 'unseen'])
  885. msg1.set_sequences(['foo'])
  886. msg2.set_sequences(['foo', 'flagged'])
  887. msg3.set_sequences(['foo', 'bar', 'replied'])
  888. key0 = self._box.add(msg0)
  889. key1 = self._box.add(msg1)
  890. key2 = self._box.add(msg2)
  891. key3 = self._box.add(msg3)
  892. self.assertEqual(self._box.get_sequences(),
  893. {'foo':[key0,key1,key2,key3], 'unseen':[key0],
  894. 'flagged':[key2], 'bar':[key3], 'replied':[key3]})
  895. self._box.remove(key2)
  896. self.assertEqual(self._box.get_sequences(),
  897. {'foo':[key0,key1,key3], 'unseen':[key0], 'bar':[key3],
  898. 'replied':[key3]})
  899. self._box.pack()
  900. self.assertEqual(self._box.keys(), [1, 2, 3])
  901. key0 = key0
  902. key1 = key0 + 1
  903. key2 = key1 + 1
  904. self.assertEqual(self._box.get_sequences(),
  905. {'foo':[1, 2, 3], 'unseen':[1], 'bar':[3], 'replied':[3]})
  906. # Test case for packing while holding the mailbox locked.
  907. key0 = self._box.add(msg1)
  908. key1 = self._box.add(msg1)
  909. key2 = self._box.add(msg1)
  910. key3 = self._box.add(msg1)
  911. self._box.remove(key0)
  912. self._box.remove(key2)
  913. self._box.lock()
  914. self._box.pack()
  915. self._box.unlock()
  916. self.assertEqual(self._box.get_sequences(),
  917. {'foo':[1, 2, 3, 4, 5],
  918. 'unseen':[1], 'bar':[3], 'replied':[3]})
  919. def _get_lock_path(self):
  920. return os.path.join(self._path, '.mh_sequences.lock')
  921. class TestBabyl(TestMailbox):
  922. _factory = lambda self, path, factory=None: mailbox.Babyl(path, factory)
  923. def tearDown(self):
  924. self._box.close()
  925. self._delete_recursively(self._path)
  926. for lock_remnant in glob.glob(self._path + '.*'):
  927. test_support.unlink(lock_remnant)
  928. def test_labels(self):
  929. # Get labels from the mailbox
  930. self.assertEqual(self._box.get_labels(), [])
  931. msg0 = mailbox.BabylMessage(self._template % 0)
  932. msg0.add_label('foo')
  933. key0 = self._box.add(msg0)
  934. self.assertEqual(self._box.get_labels(), ['foo'])
  935. msg1 = mailbox.BabylMessage(self._template % 1)
  936. msg1.set_labels(['bar', 'answered', 'foo'])
  937. key1 = self._box.add(msg1)
  938. self.assertEqual(set(self._box.get_labels()), set(['foo', 'bar']))
  939. msg0.set_labels(['blah', 'filed'])
  940. self._box[key0] = msg0
  941. self.assertEqual(set(self._box.get_labels()),
  942. set(['foo', 'bar', 'blah']))
  943. self._box.remove(key1)
  944. self.assertEqual(set(self._box.get_labels()), set(['blah']))
  945. class TestMessage(TestBase):
  946. _factory = mailbox.Message # Overridden by subclasses to reuse tests
  947. def setUp(self):
  948. self._path = test_support.TESTFN
  949. def tearDown(self):
  950. self._delete_recursively(self._path)
  951. def test_initialize_with_eMM(self):
  952. # Initialize based on email.message.Message instance
  953. eMM = email.message_from_string(_sample_message)
  954. msg = self._factory(eMM)
  955. self._post_initialize_hook(msg)
  956. self._check_sample(msg)
  957. def test_initialize_with_string(self):
  958. # Initialize based on string
  959. msg = self._factory(_sample_message)
  960. self._post_initialize_hook(msg)
  961. self._check_sample(msg)
  962. def test_initialize_with_file(self):
  963. # Initialize based on contents of file
  964. with open(self._path, 'w+') as f:
  965. f.write(_sample_message)
  966. f.seek(0)
  967. msg = self._factory(f)
  968. self._post_initialize_hook(msg)
  969. self._check_sample(msg)
  970. def test_initialize_with_nothing(self):
  971. # Initialize without arguments
  972. msg = self._factory()
  973. self._post_initialize_hook(msg)
  974. self.assertIsInstance(msg, email.message.Message)
  975. self.assertIsInstance(msg, mailbox.Message)
  976. self.assertIsInstance(msg, self._factory)
  977. self.assertEqual(msg.keys(), [])
  978. self.assertFalse(msg.is_multipart())
  979. self.assertEqual(msg.get_payload(), None)
  980. def test_initialize_incorrectly(self):
  981. # Initialize with invalid argument
  982. self.assertRaises(TypeError, lambda: self._factory(object()))
  983. def test_become_message(self):
  984. # Take on the state of another message
  985. eMM = email.message_from_string(_sample_message)
  986. msg = self._factory()
  987. msg._become_message(eMM)
  988. self._check_sample(msg)
  989. def test_explain_to(self):
  990. # Copy self's format-specific data to other message formats.
  991. # This test is superficial; better ones are in TestMessageConversion.
  992. msg = self._factory()
  993. for class_ in (mailbox.Message, mailbox.MaildirMessage,
  994. mailbox.mboxMessage, mailbox.MHMessage,
  995. mailbox.BabylMessage, mailbox.MMDFMessage):
  996. other_msg = class_()
  997. msg._explain_to(other_msg)
  998. other_msg = email.message.Message()
  999. self.assertRaises(TypeError, lambda: msg._explain_to(other_msg))
  1000. def _post_initialize_hook(self, msg):
  1001. # Overridden by subclasses to check extra things after initialization
  1002. pass
  1003. class TestMaildirMessage(TestMessage):
  1004. _factory = mailbox.MaildirMessage
  1005. def _post_initialize_hook(self, msg):
  1006. self.assertEqual(msg._subdir, 'new')
  1007. self.assertEqual(msg._info,'')
  1008. def test_subdir(self):
  1009. # Use get_subdir() and set_subdir()
  1010. msg = mailbox.MaildirMessage(_sample_message)
  1011. self.assertEqual(msg.get_subdir(), 'new')
  1012. msg.set_subdir('cur')
  1013. self.assertEqual(msg.get_subdir(), 'cur')
  1014. msg.set_subdir('new')
  1015. self.assertEqual(msg.get_subdir(), 'new')
  1016. self.assertRaises(ValueError, lambda: msg.set_subdir('tmp'))
  1017. self.assertEqual(msg.get_subdir(), 'new')
  1018. msg.set_subdir('new')
  1019. self.assertEqual(msg.get_subdir(), 'new')
  1020. self._check_sample(msg)
  1021. def test_flags(self):
  1022. # Use get_flags(), set_flags(), add_flag(), remove_flag()
  1023. msg = mailbox.MaildirMessage(_sample_message)
  1024. self.assertEqual(msg.get_flags(), '')
  1025. self.assertEqual(msg.get_subdir(), 'new')
  1026. msg.set_flags('F')
  1027. self.assertEqual(msg.get_subdir(), 'new')
  1028. self.assertEqual(msg.get_flags(), 'F')
  1029. msg.set_flags('SDTP')
  1030. self.assertEqual(msg.get_flags(), 'DPST')
  1031. msg.add_flag('FT')
  1032. self.assertEqual(msg.get_flags(), 'DFPST')
  1033. msg.remove_flag('TDRP')
  1034. self.assertEqual(msg.get_flags(), 'FS')
  1035. self.assertEqual(msg.get_subdir(), 'new')
  1036. self._check_sample(msg)
  1037. def test_date(self):
  1038. # Use get_date() and set_date()
  1039. msg = mailbox.MaildirMessage(_sample_message)
  1040. diff = msg.get_date() - time.time()
  1041. self.assertTrue(abs(diff) < 60, diff)
  1042. msg.set_date(0.0)
  1043. self.assertEqual(msg.get_date(), 0.0)
  1044. def test_info(self):
  1045. # Use get_info() and set_info()
  1046. msg = mailbox.MaildirMessage(_sample_message)
  1047. self.assertEqual(msg.get_info(), '')
  1048. msg.set_info('1,foo=bar')
  1049. self.assertEqual(msg.get_info(), '1,foo=bar')
  1050. self.assertRaises(TypeError, lambda: msg.set_info(None))
  1051. self._check_sample(msg)
  1052. def test_info_and_flags(self):
  1053. # Test interaction of info and flag methods
  1054. msg = mailbox.MaildirMessage(_sample_message)
  1055. self.assertEqual(msg.get_info(), '')
  1056. msg.set_flags('SF')
  1057. self.assertEqual(msg.get_flags(), 'FS')
  1058. self.assertEqual(msg.get_info(), '2,FS')
  1059. msg.set_info('1,')
  1060. self.assertEqual(msg.get_flags(), '')
  1061. self.assertEqual(msg.get_info(), '1,')
  1062. msg.remove_flag('RPT')
  1063. self.assertEqual(msg.get_flags(), '')
  1064. self.assertEqual(msg.get_info(), '1,')
  1065. msg.add_flag('D')
  1066. self.assertEqual(msg.get_flags(), 'D')
  1067. self.assertEqual(msg.get_info(), '2,D')
  1068. self._check_sample(msg)
  1069. class _TestMboxMMDFMessage(TestMessage):
  1070. _factory = mailbox._mboxMMDFMessage
  1071. def _post_initialize_hook(self, msg):
  1072. self._check_from(msg)
  1073. def test_initialize_with_unixfrom(self):
  1074. # Initialize with a message that already has a _unixfrom attribute
  1075. msg = mailbox.Message(_sample_message)
  1076. msg.set_unixfrom('From foo@bar blah')
  1077. msg = mailbox.mboxMessage(msg)
  1078. self.assertEqual(msg.get_from(), 'foo@bar blah')
  1079. def test_from(self):
  1080. # Get and s

Large files files are truncated, but you can click here to view the full file