10263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum"""
20263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum   Tests for the mhlib module
30263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum   Nick Mathewson
40263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum"""
50263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
60263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum### BUG: This suite doesn't currently test the mime functionality of
70263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum###      mhlib.  It should.
80263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
90263c80b90e9abb312601bc176b8176665953dc7Guido van Rossumimport unittest
10bec087f29d7dca0aaf8f51be7d7c135e9b84e7f1Benjamin Petersonfrom test.test_support import run_unittest, TESTFN, import_module
110263c80b90e9abb312601bc176b8176665953dc7Guido van Rossumimport os, StringIO
12c7ca3ffba3d41f24f6f66d40391a044f199785acTim Petersimport sys
132a869138645a38bea2517d00133158567a39caafBrett Cannonmhlib = import_module('mhlib', deprecated=True)
140263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
1532ef169339e131e83289dd8b39f7b89e76db2850Tim Petersif (sys.platform.startswith("win") or sys.platform=="riscos" or
16283ead8bf238c0cd592da1b943185edf212422b9Tim Peters      sys.platform.startswith("atheos")):
1732ef169339e131e83289dd8b39f7b89e76db2850Tim Peters    # mhlib.updateline() renames a file to the name of a file that already
1832ef169339e131e83289dd8b39f7b89e76db2850Tim Peters    # exists.  That causes a reasonable OS <wink> to complain in test_sequence
1932ef169339e131e83289dd8b39f7b89e76db2850Tim Peters    # here, like the "OSError: [Errno 17] File exists" raised on Windows.
2032ef169339e131e83289dd8b39f7b89e76db2850Tim Peters    # mhlib's listsubfolders() and listallfolders() do something with
2132ef169339e131e83289dd8b39f7b89e76db2850Tim Peters    # link counts, and that causes test_listfolders() here to get back
2232ef169339e131e83289dd8b39f7b89e76db2850Tim Peters    # an empty list from its call of listallfolders().
2332ef169339e131e83289dd8b39f7b89e76db2850Tim Peters    # The other tests here pass on Windows.
24bec087f29d7dca0aaf8f51be7d7c135e9b84e7f1Benjamin Peterson    raise unittest.SkipTest("skipped on %s -- " % sys.platform +
25bec087f29d7dca0aaf8f51be7d7c135e9b84e7f1Benjamin Peterson                            "too many Unix assumptions")
26c7ca3ffba3d41f24f6f66d40391a044f199785acTim Peters
270263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum_mhroot = TESTFN+"_MH"
280263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum_mhpath = os.path.join(_mhroot, "MH")
290263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum_mhprofile = os.path.join(_mhroot, ".mh_profile")
300263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
310263c80b90e9abb312601bc176b8176665953dc7Guido van Rossumdef normF(f):
320263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    return os.path.join(*f.split('/'))
330263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
340263c80b90e9abb312601bc176b8176665953dc7Guido van Rossumdef writeFile(fname, contents):
350263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    dir = os.path.split(fname)[0]
360263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    if dir and not os.path.exists(dir):
370263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        mkdirs(dir)
380263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    f = open(fname, 'w')
390263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    f.write(contents)
400263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    f.close()
410263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
420263c80b90e9abb312601bc176b8176665953dc7Guido van Rossumdef readFile(fname):
430263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    f = open(fname)
440263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    r = f.read()
450263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    f.close()
460263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    return r
470263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
480263c80b90e9abb312601bc176b8176665953dc7Guido van Rossumdef writeProfile(dict):
490263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    contents = [ "%s: %s\n" % (k, v) for k, v in dict.iteritems() ]
500263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    writeFile(_mhprofile, "".join(contents))
510263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
520263c80b90e9abb312601bc176b8176665953dc7Guido van Rossumdef writeContext(folder):
530263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    folder = normF(folder)
54ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters    writeFile(os.path.join(_mhpath, "context"),
550263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum              "Current-Folder: %s\n" % folder)
560263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
570263c80b90e9abb312601bc176b8176665953dc7Guido van Rossumdef writeCurMessage(folder, cur):
580263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    folder = normF(folder)
590263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    writeFile(os.path.join(_mhpath, folder, ".mh_sequences"),
600263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum              "cur: %s\n"%cur)
610263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
620263c80b90e9abb312601bc176b8176665953dc7Guido van Rossumdef writeMessage(folder, n, headers, body):
630263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    folder = normF(folder)
640263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    headers = "".join([ "%s: %s\n" % (k, v) for k, v in headers.iteritems() ])
650263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    contents = "%s\n%s\n" % (headers,body)
660263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    mkdirs(os.path.join(_mhpath, folder))
670263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    writeFile(os.path.join(_mhpath, folder, str(n)), contents)
680263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
690263c80b90e9abb312601bc176b8176665953dc7Guido van Rossumdef getMH():
700263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    return mhlib.MH(os.path.abspath(_mhpath), _mhprofile)
710263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
720263c80b90e9abb312601bc176b8176665953dc7Guido van Rossumdef sortLines(s):
730263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    lines = s.split("\n")
740263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    lines = [ line.strip() for line in lines if len(line) >= 2 ]
750263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    lines.sort()
760263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    return lines
770263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
780263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum# These next 2 functions are copied from test_glob.py.
790263c80b90e9abb312601bc176b8176665953dc7Guido van Rossumdef mkdirs(fname):
800263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    if os.path.exists(fname) or fname == '':
810263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        return
820263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    base, file = os.path.split(fname)
830263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    mkdirs(base)
840263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    os.mkdir(fname)
850263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
860263c80b90e9abb312601bc176b8176665953dc7Guido van Rossumdef deltree(fname):
870263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    if not os.path.exists(fname):
880263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        return
890263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    for f in os.listdir(fname):
900263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        fullname = os.path.join(fname, f)
910263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        if os.path.isdir(fullname):
920263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum            deltree(fullname)
930263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        else:
940263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum            try:
950263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                os.unlink(fullname)
960263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum            except:
970263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                pass
980263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    try:
990263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        os.rmdir(fname)
1000263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    except:
1010263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        pass
1020263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
1030263c80b90e9abb312601bc176b8176665953dc7Guido van Rossumclass MhlibTests(unittest.TestCase):
1040263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    def setUp(self):
1050263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        deltree(_mhroot)
1060263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        mkdirs(_mhpath)
107ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters        writeProfile({'Path' : os.path.abspath(_mhpath),
1080263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                      'Editor': 'emacs',
1090263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                      'ignored-attribute': 'camping holiday'})
1100263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        # Note: These headers aren't really conformant to RFC822, but
1110263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        #  mhlib shouldn't care about that.
1120263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
1130263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        # An inbox with a couple of messages.
114ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters        writeMessage('inbox', 1,
1150263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                     {'From': 'Mrs. Premise',
1160263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                      'To': 'Mrs. Conclusion',
1170263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                      'Date': '18 July 2001'}, "Hullo, Mrs. Conclusion!\n")
118ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters        writeMessage('inbox', 2,
1190263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                     {'From': 'Mrs. Conclusion',
1200263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                      'To': 'Mrs. Premise',
1210263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                      'Date': '29 July 2001'}, "Hullo, Mrs. Premise!\n")
122ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
1230263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        # A folder with many messages
1240263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        for i in range(5, 101)+range(101, 201, 2):
125ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters            writeMessage('wide', i,
1260263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                         {'From': 'nowhere', 'Subject': 'message #%s' % i},
1270263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                         "This is message number %s\n" % i)
128ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
1290263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        # A deeply nested folder
1300263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        def deep(folder, n):
131ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters            writeMessage(folder, n,
1320263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                         {'Subject': 'Message %s/%s' % (folder, n) },
1330263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                         "This is message number %s in %s\n" % (n, folder) )
1340263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        deep('deep/f1', 1)
1350263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        deep('deep/f1', 2)
1360263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        deep('deep/f1', 3)
1370263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        deep('deep/f2', 4)
1380263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        deep('deep/f2', 6)
1390263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        deep('deep', 3)
1400263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        deep('deep/f2/f3', 1)
1410263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        deep('deep/f2/f3', 2)
142ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
1430263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    def tearDown(self):
1440263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        deltree(_mhroot)
145ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
1460263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    def test_basic(self):
1470263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        writeContext('inbox')
1480263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        writeCurMessage('inbox', 2)
1490263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        mh = getMH()
1500263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
1512623a37852153363335956afab010cb0beb7e74eEzio Melotti        eq = self.assertEqual
1520263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(mh.getprofile('Editor'), 'emacs')
1530263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(mh.getprofile('not-set'), None)
1540263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(mh.getpath(), os.path.abspath(_mhpath))
1550263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(mh.getcontext(), 'inbox')
1560263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
1570263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        mh.setcontext('wide')
1580263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(mh.getcontext(), 'wide')
1590263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(readFile(os.path.join(_mhpath, 'context')),
1600263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum           "Current-Folder: wide\n")
1610263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
1620263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        mh.setcontext('inbox')
1630263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
1640263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        inbox = mh.openfolder('inbox')
165ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters        eq(inbox.getfullname(),
1660263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum           os.path.join(os.path.abspath(_mhpath), 'inbox'))
167ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters        eq(inbox.getsequencesfilename(),
1680263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum           os.path.join(os.path.abspath(_mhpath), 'inbox', '.mh_sequences'))
169ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters        eq(inbox.getmessagefilename(1),
1700263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum           os.path.join(os.path.abspath(_mhpath), 'inbox', '1'))
171ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
1720263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    def test_listfolders(self):
1730263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        mh = getMH()
1742623a37852153363335956afab010cb0beb7e74eEzio Melotti        eq = self.assertEqual
1750263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
1760263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        folders = mh.listfolders()
1770263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        folders.sort()
1780263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(folders, ['deep', 'inbox', 'wide'])
179ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
1800263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        folders = mh.listallfolders()
1810263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        folders.sort()
182dbc363ce353ebd59f04778b045b89442bd59912aJack Jansen        tfolders = map(normF, ['deep', 'deep/f1', 'deep/f2', 'deep/f2/f3',
183dbc363ce353ebd59f04778b045b89442bd59912aJack Jansen                                'inbox', 'wide'])
184dbc363ce353ebd59f04778b045b89442bd59912aJack Jansen        tfolders.sort()
185dbc363ce353ebd59f04778b045b89442bd59912aJack Jansen        eq(folders, tfolders)
1860263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
1870263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        folders = mh.listsubfolders('deep')
1880263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        folders.sort()
1890263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(folders, map(normF, ['deep/f1', 'deep/f2']))
190ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
1910263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        folders = mh.listallsubfolders('deep')
1920263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        folders.sort()
1930263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(folders, map(normF, ['deep/f1', 'deep/f2', 'deep/f2/f3']))
1940263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(mh.listsubfolders(normF('deep/f2')), [normF('deep/f2/f3')])
1950263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
1960263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(mh.listsubfolders('inbox'), [])
1970263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(mh.listallsubfolders('inbox'), [])
1980263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
1990263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    def test_sequence(self):
2000263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        mh = getMH()
2012623a37852153363335956afab010cb0beb7e74eEzio Melotti        eq = self.assertEqual
2020263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        writeCurMessage('wide', 55)
203ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
2040263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        f = mh.openfolder('wide')
2050263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        all = f.listmessages()
2060263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(all, range(5, 101)+range(101, 201, 2))
2070263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(f.getcurrent(), 55)
2080263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        f.setcurrent(99)
209ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters        eq(readFile(os.path.join(_mhpath, 'wide', '.mh_sequences')),
2100263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum           'cur: 99\n')
2110263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
2120263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        def seqeq(seq, val):
2130263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum            eq(f.parsesequence(seq), val)
214ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
2150263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('5-55', range(5, 56))
2160263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('90-108', range(90, 101)+range(101, 109, 2))
2170263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('90-108', range(90, 101)+range(101, 109, 2))
218ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
2190263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('10:10', range(10, 20))
2200263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('10:+10', range(10, 20))
2210263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('101:10', range(101, 121, 2))
2220263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
2230263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('cur', [99])
2240263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('.', [99])
2250263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('prev', [98])
2260263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('next', [100])
2270263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('cur:-3', [97, 98, 99])
2280263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('first-cur', range(5, 100))
2290263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('150-last', range(151, 201, 2))
2300263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('prev-next', [98, 99, 100])
2310263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
2320263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        lowprimes = [5, 7, 11, 13, 17, 19, 23, 29]
2330263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        lowcompos = [x for x in range(5, 31) if not x in lowprimes ]
2340263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        f.putsequences({'cur': [5],
2350263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                        'lowprime': lowprimes,
2360263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                        'lowcompos': lowcompos})
2370263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqs = readFile(os.path.join(_mhpath, 'wide', '.mh_sequences'))
2380263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqs = sortLines(seqs)
2390263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(seqs, ["cur: 5",
2400263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                  "lowcompos: 6 8-10 12 14-16 18 20-22 24-28 30",
2410263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                  "lowprime: 5 7 11 13 17 19 23 29"])
2420263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
2430263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('lowprime', lowprimes)
2440263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('lowprime:1', [5])
2450263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('lowprime:2', [5, 7])
2460263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        seqeq('lowprime:-2', [23, 29])
2470263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
2480263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        ## Not supported
2490263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        #seqeq('lowprime:first', [5])
2500263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        #seqeq('lowprime:last', [29])
2510263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        #seqeq('lowprime:prev', [29])
2520263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        #seqeq('lowprime:next', [29])
2530263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
2540263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    def test_modify(self):
2550263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        mh = getMH()
2562623a37852153363335956afab010cb0beb7e74eEzio Melotti        eq = self.assertEqual
2570263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
2580263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        mh.makefolder("dummy1")
259aa98058cc44ba20f35c106d20918c6196b737561Ezio Melotti        self.assertIn("dummy1", mh.listfolders())
2600263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        path = os.path.join(_mhpath, "dummy1")
2615c8da86f3a515ce1a6d5f27fd15e3c5f4d8e931eBenjamin Peterson        self.assertTrue(os.path.exists(path))
262ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
2630263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        f = mh.openfolder('dummy1')
2640263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        def create(n):
2650263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum            msg = "From: foo\nSubject: %s\n\nDummy Message %s\n" % (n,n)
2660263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum            f.createmessage(n, StringIO.StringIO(msg))
2670263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
2680263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        create(7)
2690263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        create(8)
2700263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        create(9)
271ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
2720263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(readFile(f.getmessagefilename(9)),
2730263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum           "From: foo\nSubject: 9\n\nDummy Message 9\n")
2740263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
2750263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(f.listmessages(), [7, 8, 9])
2760263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        files = os.listdir(path)
2770263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        files.sort()
278ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters        eq(files, ['7', '8', '9'])
2790263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
2800263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        f.removemessages(['7', '8'])
2810263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        files = os.listdir(path)
2820263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        files.sort()
2830263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(files, [',7', ',8', '9'])
2840263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(f.listmessages(), [9])
2850263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        create(10)
2860263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        create(11)
2870263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        create(12)
288ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
2890263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        mh.makefolder("dummy2")
2900263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        f2 = mh.openfolder("dummy2")
2910263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(f2.listmessages(), [])
2920263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        f.movemessage(10, f2, 3)
2930263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        f.movemessage(11, f2, 5)
2940263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(f.listmessages(), [9, 12])
2950263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(f2.listmessages(), [3, 5])
2960263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(readFile(f2.getmessagefilename(3)),
2970263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum           "From: foo\nSubject: 10\n\nDummy Message 10\n")
298ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
2990263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        f.copymessage(9, f2, 4)
3000263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(f.listmessages(), [9, 12])
3010263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(readFile(f2.getmessagefilename(4)),
3020263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum           "From: foo\nSubject: 9\n\nDummy Message 9\n")
303ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
3040263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        f.refilemessages([9, 12], f2)
3050263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(f.listmessages(), [])
3060263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(f2.listmessages(), [3, 4, 5, 6, 7])
3070263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(readFile(f2.getmessagefilename(7)),
3080263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum           "From: foo\nSubject: 12\n\nDummy Message 12\n")
3090263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        # XXX This should check that _copysequences does the right thing.
3100263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
3110263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        mh.deletefolder('dummy1')
3120263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        mh.deletefolder('dummy2')
313aa98058cc44ba20f35c106d20918c6196b737561Ezio Melotti        self.assertNotIn('dummy1', mh.listfolders())
3145c8da86f3a515ce1a6d5f27fd15e3c5f4d8e931eBenjamin Peterson        self.assertTrue(not os.path.exists(path))
3150263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
3160263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum    def test_read(self):
3170263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        mh = getMH()
3182623a37852153363335956afab010cb0beb7e74eEzio Melotti        eq = self.assertEqual
319ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
3200263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        f = mh.openfolder('inbox')
3210263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        msg = f.openmessage(1)
3220263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        # Check some basic stuff from rfc822
3230263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(msg.getheader('From'), "Mrs. Premise")
3240263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(msg.getheader('To'), "Mrs. Conclusion")
3250263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
3260263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        # Okay, we have the right message.  Let's check the stuff from
3270263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        # mhlib.
3280263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        lines = sortLines(msg.getheadertext())
329ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters        eq(lines, ["Date: 18 July 2001",
3300263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                   "From: Mrs. Premise",
3310263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                   "To: Mrs. Conclusion"])
3320263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        lines = sortLines(msg.getheadertext(lambda h: len(h)==4))
333ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters        eq(lines, ["Date: 18 July 2001",
3340263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum                   "From: Mrs. Premise"])
3350263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(msg.getbodytext(), "Hullo, Mrs. Conclusion!\n\n")
3360263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        eq(msg.getbodytext(0), "Hullo, Mrs. Conclusion!\n\n")
337ab9ba27dc066adc6423ea137b9481cf524d10ffdTim Peters
3380263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        # XXXX there should be a better way to reclaim the file handle
3390263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        msg.fp.close()
3400263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum        del msg
3410263c80b90e9abb312601bc176b8176665953dc7Guido van Rossum
3422e2be3760ccdfd4bdde4afdd66f4078022ba3b61Fred Drake
3432e2be3760ccdfd4bdde4afdd66f4078022ba3b61Fred Drakedef test_main():
3442e2be3760ccdfd4bdde4afdd66f4078022ba3b61Fred Drake    run_unittest(MhlibTests)
3452e2be3760ccdfd4bdde4afdd66f4078022ba3b61Fred Drake
3462e2be3760ccdfd4bdde4afdd66f4078022ba3b61Fred Drake
3472e2be3760ccdfd4bdde4afdd66f4078022ba3b61Fred Drakeif __name__ == "__main__":
3482e2be3760ccdfd4bdde4afdd66f4078022ba3b61Fred Drake    test_main()
349