python-2.5.2/win32/Lib/test/test_mhlib.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     1 """
       
     2    Tests for the mhlib module
       
     3    Nick Mathewson
       
     4 """
       
     5 
       
     6 ### BUG: This suite doesn't currently test the mime functionality of
       
     7 ###      mhlib.  It should.
       
     8 
       
     9 import unittest
       
    10 from test.test_support import run_unittest, TESTFN, TestSkipped
       
    11 import os, StringIO
       
    12 import sys
       
    13 import mhlib
       
    14 
       
    15 if (sys.platform.startswith("win") or sys.platform=="riscos" or
       
    16       sys.platform.startswith("atheos")):
       
    17     # mhlib.updateline() renames a file to the name of a file that already
       
    18     # exists.  That causes a reasonable OS <wink> to complain in test_sequence
       
    19     # here, like the "OSError: [Errno 17] File exists" raised on Windows.
       
    20     # mhlib's listsubfolders() and listallfolders() do something with
       
    21     # link counts, and that causes test_listfolders() here to get back
       
    22     # an empty list from its call of listallfolders().
       
    23     # The other tests here pass on Windows.
       
    24     raise TestSkipped("skipped on %s -- " % sys.platform +
       
    25                       "too many Unix assumptions")
       
    26 
       
    27 _mhroot = TESTFN+"_MH"
       
    28 _mhpath = os.path.join(_mhroot, "MH")
       
    29 _mhprofile = os.path.join(_mhroot, ".mh_profile")
       
    30 
       
    31 def normF(f):
       
    32     return os.path.join(*f.split('/'))
       
    33 
       
    34 def writeFile(fname, contents):
       
    35     dir = os.path.split(fname)[0]
       
    36     if dir and not os.path.exists(dir):
       
    37         mkdirs(dir)
       
    38     f = open(fname, 'w')
       
    39     f.write(contents)
       
    40     f.close()
       
    41 
       
    42 def readFile(fname):
       
    43     f = open(fname)
       
    44     r = f.read()
       
    45     f.close()
       
    46     return r
       
    47 
       
    48 def writeProfile(dict):
       
    49     contents = [ "%s: %s\n" % (k, v) for k, v in dict.iteritems() ]
       
    50     writeFile(_mhprofile, "".join(contents))
       
    51 
       
    52 def writeContext(folder):
       
    53     folder = normF(folder)
       
    54     writeFile(os.path.join(_mhpath, "context"),
       
    55               "Current-Folder: %s\n" % folder)
       
    56 
       
    57 def writeCurMessage(folder, cur):
       
    58     folder = normF(folder)
       
    59     writeFile(os.path.join(_mhpath, folder, ".mh_sequences"),
       
    60               "cur: %s\n"%cur)
       
    61 
       
    62 def writeMessage(folder, n, headers, body):
       
    63     folder = normF(folder)
       
    64     headers = "".join([ "%s: %s\n" % (k, v) for k, v in headers.iteritems() ])
       
    65     contents = "%s\n%s\n" % (headers,body)
       
    66     mkdirs(os.path.join(_mhpath, folder))
       
    67     writeFile(os.path.join(_mhpath, folder, str(n)), contents)
       
    68 
       
    69 def getMH():
       
    70     return mhlib.MH(os.path.abspath(_mhpath), _mhprofile)
       
    71 
       
    72 def sortLines(s):
       
    73     lines = s.split("\n")
       
    74     lines = [ line.strip() for line in lines if len(line) >= 2 ]
       
    75     lines.sort()
       
    76     return lines
       
    77 
       
    78 # These next 2 functions are copied from test_glob.py.
       
    79 def mkdirs(fname):
       
    80     if os.path.exists(fname) or fname == '':
       
    81         return
       
    82     base, file = os.path.split(fname)
       
    83     mkdirs(base)
       
    84     os.mkdir(fname)
       
    85 
       
    86 def deltree(fname):
       
    87     if not os.path.exists(fname):
       
    88         return
       
    89     for f in os.listdir(fname):
       
    90         fullname = os.path.join(fname, f)
       
    91         if os.path.isdir(fullname):
       
    92             deltree(fullname)
       
    93         else:
       
    94             try:
       
    95                 os.unlink(fullname)
       
    96             except:
       
    97                 pass
       
    98     try:
       
    99         os.rmdir(fname)
       
   100     except:
       
   101         pass
       
   102 
       
   103 class MhlibTests(unittest.TestCase):
       
   104     def setUp(self):
       
   105         deltree(_mhroot)
       
   106         mkdirs(_mhpath)
       
   107         writeProfile({'Path' : os.path.abspath(_mhpath),
       
   108                       'Editor': 'emacs',
       
   109                       'ignored-attribute': 'camping holiday'})
       
   110         # Note: These headers aren't really conformant to RFC822, but
       
   111         #  mhlib shouldn't care about that.
       
   112 
       
   113         # An inbox with a couple of messages.
       
   114         writeMessage('inbox', 1,
       
   115                      {'From': 'Mrs. Premise',
       
   116                       'To': 'Mrs. Conclusion',
       
   117                       'Date': '18 July 2001'}, "Hullo, Mrs. Conclusion!\n")
       
   118         writeMessage('inbox', 2,
       
   119                      {'From': 'Mrs. Conclusion',
       
   120                       'To': 'Mrs. Premise',
       
   121                       'Date': '29 July 2001'}, "Hullo, Mrs. Premise!\n")
       
   122 
       
   123         # A folder with many messages
       
   124         for i in range(5, 101)+range(101, 201, 2):
       
   125             writeMessage('wide', i,
       
   126                          {'From': 'nowhere', 'Subject': 'message #%s' % i},
       
   127                          "This is message number %s\n" % i)
       
   128 
       
   129         # A deeply nested folder
       
   130         def deep(folder, n):
       
   131             writeMessage(folder, n,
       
   132                          {'Subject': 'Message %s/%s' % (folder, n) },
       
   133                          "This is message number %s in %s\n" % (n, folder) )
       
   134         deep('deep/f1', 1)
       
   135         deep('deep/f1', 2)
       
   136         deep('deep/f1', 3)
       
   137         deep('deep/f2', 4)
       
   138         deep('deep/f2', 6)
       
   139         deep('deep', 3)
       
   140         deep('deep/f2/f3', 1)
       
   141         deep('deep/f2/f3', 2)
       
   142 
       
   143     def tearDown(self):
       
   144         deltree(_mhroot)
       
   145 
       
   146     def test_basic(self):
       
   147         writeContext('inbox')
       
   148         writeCurMessage('inbox', 2)
       
   149         mh = getMH()
       
   150 
       
   151         eq = self.assertEquals
       
   152         eq(mh.getprofile('Editor'), 'emacs')
       
   153         eq(mh.getprofile('not-set'), None)
       
   154         eq(mh.getpath(), os.path.abspath(_mhpath))
       
   155         eq(mh.getcontext(), 'inbox')
       
   156 
       
   157         mh.setcontext('wide')
       
   158         eq(mh.getcontext(), 'wide')
       
   159         eq(readFile(os.path.join(_mhpath, 'context')),
       
   160            "Current-Folder: wide\n")
       
   161 
       
   162         mh.setcontext('inbox')
       
   163 
       
   164         inbox = mh.openfolder('inbox')
       
   165         eq(inbox.getfullname(),
       
   166            os.path.join(os.path.abspath(_mhpath), 'inbox'))
       
   167         eq(inbox.getsequencesfilename(),
       
   168            os.path.join(os.path.abspath(_mhpath), 'inbox', '.mh_sequences'))
       
   169         eq(inbox.getmessagefilename(1),
       
   170            os.path.join(os.path.abspath(_mhpath), 'inbox', '1'))
       
   171 
       
   172     def test_listfolders(self):
       
   173         mh = getMH()
       
   174         eq = self.assertEquals
       
   175 
       
   176         folders = mh.listfolders()
       
   177         folders.sort()
       
   178         eq(folders, ['deep', 'inbox', 'wide'])
       
   179 
       
   180         folders = mh.listallfolders()
       
   181         folders.sort()
       
   182         tfolders = map(normF, ['deep', 'deep/f1', 'deep/f2', 'deep/f2/f3',
       
   183                                 'inbox', 'wide'])
       
   184         tfolders.sort()
       
   185         eq(folders, tfolders)
       
   186 
       
   187         folders = mh.listsubfolders('deep')
       
   188         folders.sort()
       
   189         eq(folders, map(normF, ['deep/f1', 'deep/f2']))
       
   190 
       
   191         folders = mh.listallsubfolders('deep')
       
   192         folders.sort()
       
   193         eq(folders, map(normF, ['deep/f1', 'deep/f2', 'deep/f2/f3']))
       
   194         eq(mh.listsubfolders(normF('deep/f2')), [normF('deep/f2/f3')])
       
   195 
       
   196         eq(mh.listsubfolders('inbox'), [])
       
   197         eq(mh.listallsubfolders('inbox'), [])
       
   198 
       
   199     def test_sequence(self):
       
   200         mh = getMH()
       
   201         eq = self.assertEquals
       
   202         writeCurMessage('wide', 55)
       
   203 
       
   204         f = mh.openfolder('wide')
       
   205         all = f.listmessages()
       
   206         eq(all, range(5, 101)+range(101, 201, 2))
       
   207         eq(f.getcurrent(), 55)
       
   208         f.setcurrent(99)
       
   209         eq(readFile(os.path.join(_mhpath, 'wide', '.mh_sequences')),
       
   210            'cur: 99\n')
       
   211 
       
   212         def seqeq(seq, val):
       
   213             eq(f.parsesequence(seq), val)
       
   214 
       
   215         seqeq('5-55', range(5, 56))
       
   216         seqeq('90-108', range(90, 101)+range(101, 109, 2))
       
   217         seqeq('90-108', range(90, 101)+range(101, 109, 2))
       
   218 
       
   219         seqeq('10:10', range(10, 20))
       
   220         seqeq('10:+10', range(10, 20))
       
   221         seqeq('101:10', range(101, 121, 2))
       
   222 
       
   223         seqeq('cur', [99])
       
   224         seqeq('.', [99])
       
   225         seqeq('prev', [98])
       
   226         seqeq('next', [100])
       
   227         seqeq('cur:-3', [97, 98, 99])
       
   228         seqeq('first-cur', range(5, 100))
       
   229         seqeq('150-last', range(151, 201, 2))
       
   230         seqeq('prev-next', [98, 99, 100])
       
   231 
       
   232         lowprimes = [5, 7, 11, 13, 17, 19, 23, 29]
       
   233         lowcompos = [x for x in range(5, 31) if not x in lowprimes ]
       
   234         f.putsequences({'cur': [5],
       
   235                         'lowprime': lowprimes,
       
   236                         'lowcompos': lowcompos})
       
   237         seqs = readFile(os.path.join(_mhpath, 'wide', '.mh_sequences'))
       
   238         seqs = sortLines(seqs)
       
   239         eq(seqs, ["cur: 5",
       
   240                   "lowcompos: 6 8-10 12 14-16 18 20-22 24-28 30",
       
   241                   "lowprime: 5 7 11 13 17 19 23 29"])
       
   242 
       
   243         seqeq('lowprime', lowprimes)
       
   244         seqeq('lowprime:1', [5])
       
   245         seqeq('lowprime:2', [5, 7])
       
   246         seqeq('lowprime:-2', [23, 29])
       
   247 
       
   248         ## Not supported
       
   249         #seqeq('lowprime:first', [5])
       
   250         #seqeq('lowprime:last', [29])
       
   251         #seqeq('lowprime:prev', [29])
       
   252         #seqeq('lowprime:next', [29])
       
   253 
       
   254     def test_modify(self):
       
   255         mh = getMH()
       
   256         eq = self.assertEquals
       
   257 
       
   258         mh.makefolder("dummy1")
       
   259         self.assert_("dummy1" in mh.listfolders())
       
   260         path = os.path.join(_mhpath, "dummy1")
       
   261         self.assert_(os.path.exists(path))
       
   262 
       
   263         f = mh.openfolder('dummy1')
       
   264         def create(n):
       
   265             msg = "From: foo\nSubject: %s\n\nDummy Message %s\n" % (n,n)
       
   266             f.createmessage(n, StringIO.StringIO(msg))
       
   267 
       
   268         create(7)
       
   269         create(8)
       
   270         create(9)
       
   271 
       
   272         eq(readFile(f.getmessagefilename(9)),
       
   273            "From: foo\nSubject: 9\n\nDummy Message 9\n")
       
   274 
       
   275         eq(f.listmessages(), [7, 8, 9])
       
   276         files = os.listdir(path)
       
   277         files.sort()
       
   278         eq(files, ['7', '8', '9'])
       
   279 
       
   280         f.removemessages(['7', '8'])
       
   281         files = os.listdir(path)
       
   282         files.sort()
       
   283         eq(files, [',7', ',8', '9'])
       
   284         eq(f.listmessages(), [9])
       
   285         create(10)
       
   286         create(11)
       
   287         create(12)
       
   288 
       
   289         mh.makefolder("dummy2")
       
   290         f2 = mh.openfolder("dummy2")
       
   291         eq(f2.listmessages(), [])
       
   292         f.movemessage(10, f2, 3)
       
   293         f.movemessage(11, f2, 5)
       
   294         eq(f.listmessages(), [9, 12])
       
   295         eq(f2.listmessages(), [3, 5])
       
   296         eq(readFile(f2.getmessagefilename(3)),
       
   297            "From: foo\nSubject: 10\n\nDummy Message 10\n")
       
   298 
       
   299         f.copymessage(9, f2, 4)
       
   300         eq(f.listmessages(), [9, 12])
       
   301         eq(readFile(f2.getmessagefilename(4)),
       
   302            "From: foo\nSubject: 9\n\nDummy Message 9\n")
       
   303 
       
   304         f.refilemessages([9, 12], f2)
       
   305         eq(f.listmessages(), [])
       
   306         eq(f2.listmessages(), [3, 4, 5, 6, 7])
       
   307         eq(readFile(f2.getmessagefilename(7)),
       
   308            "From: foo\nSubject: 12\n\nDummy Message 12\n")
       
   309         # XXX This should check that _copysequences does the right thing.
       
   310 
       
   311         mh.deletefolder('dummy1')
       
   312         mh.deletefolder('dummy2')
       
   313         self.assert_('dummy1' not in mh.listfolders())
       
   314         self.assert_(not os.path.exists(path))
       
   315 
       
   316     def test_read(self):
       
   317         mh = getMH()
       
   318         eq = self.assertEquals
       
   319 
       
   320         f = mh.openfolder('inbox')
       
   321         msg = f.openmessage(1)
       
   322         # Check some basic stuff from rfc822
       
   323         eq(msg.getheader('From'), "Mrs. Premise")
       
   324         eq(msg.getheader('To'), "Mrs. Conclusion")
       
   325 
       
   326         # Okay, we have the right message.  Let's check the stuff from
       
   327         # mhlib.
       
   328         lines = sortLines(msg.getheadertext())
       
   329         eq(lines, ["Date: 18 July 2001",
       
   330                    "From: Mrs. Premise",
       
   331                    "To: Mrs. Conclusion"])
       
   332         lines = sortLines(msg.getheadertext(lambda h: len(h)==4))
       
   333         eq(lines, ["Date: 18 July 2001",
       
   334                    "From: Mrs. Premise"])
       
   335         eq(msg.getbodytext(), "Hullo, Mrs. Conclusion!\n\n")
       
   336         eq(msg.getbodytext(0), "Hullo, Mrs. Conclusion!\n\n")
       
   337 
       
   338         # XXXX there should be a better way to reclaim the file handle
       
   339         msg.fp.close()
       
   340         del msg
       
   341 
       
   342 
       
   343 def test_main():
       
   344     run_unittest(MhlibTests)
       
   345 
       
   346 
       
   347 if __name__ == "__main__":
       
   348     test_main()