tests/test-ctxmanager.py
author Durham Goode <durham@fb.com>
Mon, 12 Sep 2016 10:55:43 -0700
changeset 29926 be16091ac14d
parent 28801 441491aba8c3
child 32279 68c43a416585
permissions -rw-r--r--
manifest: change manifestctx to not inherit from manifestdict If manifestctx inherits from manifestdict, it requires some weird logic to lazily load the dict if a piece of information is asked for. This ended up being complicated and unintuitive to use. Let's move the dict creation to .read(). This will make even more sense once we start adding readdelta() and other similar methods to manifestctx.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
27703
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     1
from __future__ import absolute_import
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     2
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     3
import silenttestrunner
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     4
import unittest
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     5
28801
441491aba8c3 test-ctxmanager: stop direct symbol import of mercurial.util
Yuya Nishihara <yuya@tcha.org>
parents: 27786
diff changeset
     6
from mercurial import util
27703
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     7
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     8
class contextmanager(object):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
     9
    def __init__(self, name, trace):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    10
        self.name = name
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    11
        self.entered = False
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    12
        self.exited = False
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    13
        self.trace = trace
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    14
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    15
    def __enter__(self):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    16
        self.entered = True
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    17
        self.trace(('enter', self.name))
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    18
        return self
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    19
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    20
    def __exit__(self, exc_type, exc_val, exc_tb):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    21
        self.exited = exc_type, exc_val, exc_tb
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    22
        self.trace(('exit', self.name))
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    23
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    24
    def __repr__(self):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    25
        return '<ctx %r>' % self.name
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    26
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    27
class ctxerror(Exception):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    28
    pass
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    29
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    30
class raise_on_enter(contextmanager):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    31
    def __enter__(self):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    32
        self.trace(('raise', self.name))
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    33
        raise ctxerror(self.name)
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    34
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    35
class raise_on_exit(contextmanager):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    36
    def __exit__(self, exc_type, exc_val, exc_tb):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    37
        self.trace(('raise', self.name))
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    38
        raise ctxerror(self.name)
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    39
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    40
def ctxmgr(name, trace):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    41
    return lambda: contextmanager(name, trace)
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    42
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    43
class test_ctxmanager(unittest.TestCase):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    44
    def test_basics(self):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    45
        trace = []
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    46
        addtrace = trace.append
28801
441491aba8c3 test-ctxmanager: stop direct symbol import of mercurial.util
Yuya Nishihara <yuya@tcha.org>
parents: 27786
diff changeset
    47
        with util.ctxmanager(ctxmgr('a', addtrace), ctxmgr('b', addtrace)) as c:
27785
ba427b51f1d8 util: rename ctxmanager's __call__ method to enter
Bryan O'Sullivan <bryano@fb.com>
parents: 27703
diff changeset
    48
            a, b = c.enter()
27703
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    49
            c.atexit(addtrace, ('atexit', 'x'))
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    50
            c.atexit(addtrace, ('atexit', 'y'))
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    51
        self.assertEqual(trace, [('enter', 'a'), ('enter', 'b'),
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    52
                                 ('atexit', 'y'), ('atexit', 'x'),
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    53
                                 ('exit', 'b'), ('exit', 'a')])
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    54
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    55
    def test_raise_on_enter(self):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    56
        trace = []
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    57
        addtrace = trace.append
27786
4a7dc29bfad8 test-ctxmanager: fix Python 2.6 compatibility problem
Bryan O'Sullivan <bryano@fb.com>
parents: 27785
diff changeset
    58
        def go():
28801
441491aba8c3 test-ctxmanager: stop direct symbol import of mercurial.util
Yuya Nishihara <yuya@tcha.org>
parents: 27786
diff changeset
    59
            with util.ctxmanager(ctxmgr('a', addtrace),
441491aba8c3 test-ctxmanager: stop direct symbol import of mercurial.util
Yuya Nishihara <yuya@tcha.org>
parents: 27786
diff changeset
    60
                                 lambda: raise_on_enter('b', addtrace)) as c:
27785
ba427b51f1d8 util: rename ctxmanager's __call__ method to enter
Bryan O'Sullivan <bryano@fb.com>
parents: 27703
diff changeset
    61
                c.enter()
27703
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    62
                addtrace('unreachable')
27786
4a7dc29bfad8 test-ctxmanager: fix Python 2.6 compatibility problem
Bryan O'Sullivan <bryano@fb.com>
parents: 27785
diff changeset
    63
        self.assertRaises(ctxerror, go)
27703
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    64
        self.assertEqual(trace, [('enter', 'a'), ('raise', 'b'), ('exit', 'a')])
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    65
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    66
    def test_raise_on_exit(self):
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    67
        trace = []
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    68
        addtrace = trace.append
27786
4a7dc29bfad8 test-ctxmanager: fix Python 2.6 compatibility problem
Bryan O'Sullivan <bryano@fb.com>
parents: 27785
diff changeset
    69
        def go():
28801
441491aba8c3 test-ctxmanager: stop direct symbol import of mercurial.util
Yuya Nishihara <yuya@tcha.org>
parents: 27786
diff changeset
    70
            with util.ctxmanager(ctxmgr('a', addtrace),
441491aba8c3 test-ctxmanager: stop direct symbol import of mercurial.util
Yuya Nishihara <yuya@tcha.org>
parents: 27786
diff changeset
    71
                                 lambda: raise_on_exit('b', addtrace)) as c:
27785
ba427b51f1d8 util: rename ctxmanager's __call__ method to enter
Bryan O'Sullivan <bryano@fb.com>
parents: 27703
diff changeset
    72
                c.enter()
27703
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    73
                addtrace('running')
27786
4a7dc29bfad8 test-ctxmanager: fix Python 2.6 compatibility problem
Bryan O'Sullivan <bryano@fb.com>
parents: 27785
diff changeset
    74
        self.assertRaises(ctxerror, go)
27703
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    75
        self.assertEqual(trace, [('enter', 'a'), ('enter', 'b'), 'running',
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    76
                                 ('raise', 'b'), ('exit', 'a')])
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    77
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    78
if __name__ == '__main__':
4e27c0a70574 util: introduce ctxmanager, to avoid nested try/finally blocks
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
    79
    silenttestrunner.main(__name__)