laneya

multiplayer roguelike game
git clone https://git.ce9e.org/laneya.git

commit
8309a9de6ebbbeb9d1a4be8862d6e9bc4ae74346
parent
91eb438565b36d7049fa195cea606868cc2c82b3
Author
Tobias Bengfort <tobias.bengfort@gmx.net>
Date
2014-10-04 08:23
Merge branch 'feature-tests'

Diffstat

M .gitignore 1 +
M README.rst 20 ++++++++++++++++++++
M laneya/deferred.py 56 ++++++--------------------------------------------------
M setup.cfg 12 ++++++++++++
A tests/__init__.py 0
A tests/shared.py 29 +++++++++++++++++++++++++++++
A tests/test_deferred.py 209 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A tox.ini 23 +++++++++++++++++++++++

8 files changed, 300 insertions, 50 deletions


diff --git a/.gitignore b/.gitignore

@@ -4,6 +4,7 @@
    4     4 *.pyc
    5     5 .env
    6     6 .tox
   -1     7 .cover
    7     8 *.egg-info
    8     9 *-orig
    9    10 docs/build

diff --git a/README.rst b/README.rst

@@ -22,6 +22,7 @@ calling::
   22    22 laneya consists of two programs: A server called ``laneyad`` and a client
   23    23 called ``laneya``.
   24    24 
   -1    25 
   25    26 Build Documentation
   26    27 -------------------
   27    28 
@@ -37,4 +38,23 @@ To add a new module to the documentation, create a corresponding file in
   37    38 ``docs/source/index.rst``.
   38    39 
   39    40 
   -1    41 Run Tests
   -1    42 ---------
   -1    43 
   -1    44 You can automatically run all tests via tox::
   -1    45 
   -1    46   pip install tox
   -1    47   tox
   -1    48 
   -1    49 This will setup virtual environments for multiple versions of python and run
   -1    50 all tests with each of these versions.
   -1    51 
   -1    52 Alternatively you can run the tests manually::
   -1    53 
   -1    54   pip install flake8 nose coverage
   -1    55   flake8
   -1    56   nosetests
   -1    57   xdg-open .cover/index.html
   -1    58 
   -1    59 
   40    60 .. _sphinx: http://sphinx-doc.org

diff --git a/laneya/deferred.py b/laneya/deferred.py

@@ -48,7 +48,7 @@ class Deferred(object):
   48    48             for d, callback, errback in self.promise._children:
   49    49                 if status == RESOLVED:
   50    50                     callback(value).then(d.resolve, d.reject)
   51    -1                 elif status == REJECTED:
   -1    51                 else:  # rejected
   52    52                     errback(value).then(d.resolve, d.reject)
   53    53         else:
   54    54             raise AlreadyDoneError
@@ -93,6 +93,10 @@ class Promise(object):
   93    93             self._children.append((d, _callback, _errback))
   94    94             return d.promise
   95    95 
   -1    96     def _raise(self):
   -1    97         if self._status == REJECTED and isinstance(self._value, Exception):
   -1    98             raise self._value
   -1    99 
   96   100 
   97   101 def when(value=None):
   98   102     """Wrap value in a promise if it is not already one."""
@@ -140,58 +144,10 @@ def all(*promises):
  140   144             data['count'] -= 1
  141   145 
  142   146             if data['count'] == 0:
  143    -1                 try:
  144    -1                     d.resolve(data['results'])
  145    -1                 except AlreadyDoneError:
  146    -1                     pass
   -1   147                 d.resolve(data['results'])
  147   148         return success
  148   149 
  149   150     for i, promise in enumerate(promises):
  150   151         promise.then(success_factory(i), d.reject)
  151   152 
  152   153     return d.promise
  153    -1 
  154    -1 
  155    -1 if __name__ == '__main__':
  156    -1     def expect_factory(expected):
  157    -1         def expect(actual):
  158    -1             if actual == expected:
  159    -1                 print(actual)
  160    -1             else:
  161    -1                 print("%s != %s" % (actual, expected))
  162    -1         return expect
  163    -1 
  164    -1     def fail(error):
  165    -1         raise Exception('fail')
  166    -1 
  167    -1     d = Deferred()
  168    -1     d.resolve('huhu1')
  169    -1     d.promise.then(expect_factory('huhu1'), fail)
  170    -1 
  171    -1     d = Deferred()
  172    -1     d.promise.then(expect_factory('huhu2'), fail)
  173    -1     d.resolve('huhu2')
  174    -1 
  175    -1     d = Deferred()
  176    -1     d.reject('huhu3')
  177    -1     d.promise.then(fail, expect_factory('huhu3'))
  178    -1 
  179    -1     d = Deferred()
  180    -1     d.promise.then(fail, expect_factory('huhu4'))
  181    -1     d.reject('huhu4')
  182    -1 
  183    -1     d = Deferred()
  184    -1     d.reject('huhu5')
  185    -1     d.promise.then(fail).then(fail, expect_factory('huhu5'))
  186    -1 
  187    -1     d = Deferred()
  188    -1     d.reject('huhu6')
  189    -1     d.promise.then(fail, when).then(expect_factory('huhu6'), fail)
  190    -1 
  191    -1     when('huhu7').then(expect_factory('huhu7'), fail)
  192    -1 
  193    -1     when(when('huhu8')).then(expect_factory('huhu8'), fail)
  194    -1 
  195    -1     reject('huhu9').then(fail, expect_factory('huhu9'))
  196    -1 
  197    -1     when(reject('huhu10')).then(fail, expect_factory('huhu10'))

diff --git a/setup.cfg b/setup.cfg

@@ -1,3 +1,15 @@
   -1     1 [nosetests]
   -1     2 with-coverage=1
   -1     3 cover-package=laneya
   -1     4 cover-inclusive=1
   -1     5 cover-erase=1
   -1     6 cover-branches=1
   -1     7 cover-html=1
   -1     8 cover-html-dir=.cover
   -1     9 
   -1    10 [flake8]
   -1    11 exclude=.env,.tox,.git,build,dist,docs
   -1    12 
    1    13 [build_sphinx]
    2    14 source-dir = docs/source
    3    15 build-dir  = docs/build

diff --git a/tests/__init__.py b/tests/__init__.py

diff --git a/tests/shared.py b/tests/shared.py

@@ -0,0 +1,29 @@
   -1     1 try:
   -1     2     import unittest2 as unittest  # flake8: noqa
   -1     3 except ImportError:
   -1     4     import unittest  # flake8: noqa
   -1     5 
   -1     6 
   -1     7 class SpyMixin:
   -1     8     def __init__(self):
   -1     9         self._spy_calls = {}
   -1    10         self._key = 0
   -1    11 
   -1    12     def create_spy(self):
   -1    13         key = self._key
   -1    14         self._key += 1
   -1    15 
   -1    16         def spy(*args, **kwargs):
   -1    17             if not key in self._spy_calls:
   -1    18                 self._spy_calls[key] = []
   -1    19             self._spy_calls[key].append((args, kwargs))
   -1    20 
   -1    21         spy.key = key
   -1    22         return spy
   -1    23 
   -1    24     def assertCalled(self, spy):
   -1    25         self.assertIn(spy.key, self._spy_calls)
   -1    26 
   -1    27     def assertCalledWith(self, spy, *args, **kwargs):
   -1    28         self.assertCalled(spy)
   -1    29         self.assertIn((args, kwargs), self._spy_calls[spy.key])

diff --git a/tests/test_deferred.py b/tests/test_deferred.py

@@ -0,0 +1,209 @@
   -1     1 import shared
   -1     2 from shared import unittest
   -1     3 
   -1     4 from laneya import deferred as q
   -1     5 
   -1     6 
   -1     7 class TestDeferred(unittest.TestCase, shared.SpyMixin):
   -1     8     def __init__(self, *args, **kwargs):
   -1     9         unittest.TestCase.__init__(self, *args, **kwargs)
   -1    10         shared.SpyMixin.__init__(self)
   -1    11 
   -1    12     def assertNeverCalled(self, *args, **kwargs):
   -1    13         assert False
   -1    14 
   -1    15     def test_deferred_resolve(self):
   -1    16         spy = self.create_spy()
   -1    17 
   -1    18         d = q.Deferred()
   -1    19         d.resolve('foo')
   -1    20         d.promise.then(spy, self.assertNeverCalled)._raise()
   -1    21 
   -1    22         self.assertCalledWith(spy, 'foo')
   -1    23 
   -1    24     def test_deferred_resolve_inverted(self):
   -1    25         spy = self.create_spy()
   -1    26 
   -1    27         d = q.Deferred()
   -1    28         d.promise.then(spy, self.assertNeverCalled)._raise()
   -1    29         d.resolve('foo')
   -1    30 
   -1    31         self.assertCalledWith(spy, 'foo')
   -1    32 
   -1    33     def test_deferred_resolve_done(self):
   -1    34         spy = self.create_spy()
   -1    35 
   -1    36         d = q.Deferred()
   -1    37         d.promise.then(spy, self.assertNeverCalled)._raise()
   -1    38         d.resolve('foo')
   -1    39 
   -1    40         with self.assertRaises(q.AlreadyDoneError):
   -1    41             d.resolve('bar')
   -1    42 
   -1    43         with self.assertRaises(q.AlreadyDoneError):
   -1    44             d.reject('bar')
   -1    45 
   -1    46         self.assertCalledWith(spy, 'foo')
   -1    47 
   -1    48     def test_deferred_reject(self):
   -1    49         spy = self.create_spy()
   -1    50 
   -1    51         d = q.Deferred()
   -1    52         d.reject('foo')
   -1    53         d.promise.then(self.assertNeverCalled, spy)._raise()
   -1    54 
   -1    55         self.assertCalledWith(spy, 'foo')
   -1    56 
   -1    57     def test_deferred_reject_inverted(self):
   -1    58         spy = self.create_spy()
   -1    59 
   -1    60         d = q.Deferred()
   -1    61         d.promise.then(self.assertNeverCalled, spy)._raise()
   -1    62         d.reject('foo')
   -1    63 
   -1    64         self.assertCalledWith(spy, 'foo')
   -1    65 
   -1    66     def test_deferred_reject_done(self):
   -1    67         spy = self.create_spy()
   -1    68 
   -1    69         d = q.Deferred()
   -1    70         d.promise.then(self.assertNeverCalled, spy)._raise()
   -1    71         d.reject('foo')
   -1    72 
   -1    73         with self.assertRaises(q.AlreadyDoneError):
   -1    74             d.resolve('bar')
   -1    75 
   -1    76         with self.assertRaises(q.AlreadyDoneError):
   -1    77             d.reject('bar')
   -1    78 
   -1    79         self.assertCalledWith(spy, 'foo')
   -1    80 
   -1    81     def test_success_propagation(self):
   -1    82         spy = self.create_spy()
   -1    83 
   -1    84         d = q.Deferred()
   -1    85         d.resolve('foo')
   -1    86         d.promise\
   -1    87             .then(None, self.assertNeverCalled)\
   -1    88             .then(spy, self.assertNeverCalled)\
   -1    89             ._raise()
   -1    90 
   -1    91         self.assertCalledWith(spy, 'foo')
   -1    92 
   -1    93     def test_error_propagation(self):
   -1    94         spy = self.create_spy()
   -1    95 
   -1    96         d = q.Deferred()
   -1    97         d.reject('foo')
   -1    98         d.promise\
   -1    99             .then(self.assertNeverCalled)\
   -1   100             .then(self.assertNeverCalled, spy)\
   -1   101             ._raise()
   -1   102 
   -1   103         self.assertCalledWith(spy, 'foo')
   -1   104 
   -1   105     def test_success_chaining(self):
   -1   106         spy = self.create_spy()
   -1   107         fn = lambda x: x + 'bar'
   -1   108 
   -1   109         d = q.Deferred()
   -1   110         d.resolve('foo')
   -1   111         d.promise\
   -1   112             .then(fn, self.assertNeverCalled)\
   -1   113             .then(spy, self.assertNeverCalled)\
   -1   114             ._raise()
   -1   115 
   -1   116         self.assertCalledWith(spy, 'foobar')
   -1   117 
   -1   118     def test_error_chaining(self):
   -1   119         spy = self.create_spy()
   -1   120         fn = lambda x: x + 'bar'
   -1   121 
   -1   122         d = q.Deferred()
   -1   123         d.reject('foo')
   -1   124         d.promise\
   -1   125             .then(self.assertNeverCalled, fn)\
   -1   126             .then(spy, self.assertNeverCalled)\
   -1   127             ._raise()
   -1   128 
   -1   129         self.assertCalledWith(spy, 'foobar')
   -1   130 
   -1   131     def test_when_with_value(self):
   -1   132         spy = self.create_spy()
   -1   133 
   -1   134         p = q.when('foo')
   -1   135         p.then(spy, self.assertNeverCalled)._raise()
   -1   136 
   -1   137         self.assertCalledWith(spy, 'foo')
   -1   138 
   -1   139     def test_when_with_promise(self):
   -1   140         p1 = q.Promise()
   -1   141         p2 = q.when(p1)
   -1   142 
   -1   143         self.assertEqual(p1, p2)
   -1   144 
   -1   145     def test_reject(self):
   -1   146         spy = self.create_spy()
   -1   147 
   -1   148         p = q.reject('foo')
   -1   149         p.then(self.assertNeverCalled, spy)._raise()
   -1   150 
   -1   151         self.assertCalledWith(spy, 'foo')
   -1   152 
   -1   153     def test_wrap_return(self):
   -1   154         spy = self.create_spy()
   -1   155         fn = lambda x: 'foo'
   -1   156 
   -1   157         p = q.wrap(fn)('bar')
   -1   158         p.then(spy, self.assertNeverCalled)._raise()
   -1   159 
   -1   160         self.assertCalledWith(spy, 'foo')
   -1   161 
   -1   162     def test_wrap_raise(self):
   -1   163         spy = self.create_spy()
   -1   164         err = Exception('foo')
   -1   165 
   -1   166         def fn(x):
   -1   167             raise err
   -1   168 
   -1   169         p = q.wrap(fn)('bar')
   -1   170         p.then(self.assertNeverCalled, spy)._raise()
   -1   171 
   -1   172         self.assertCalledWith(spy, err)
   -1   173 
   -1   174     def test_raise(self):
   -1   175         with self.assertRaises(AssertionError):
   -1   176             q.when('foo').then(self.assertNeverCalled)._raise()
   -1   177 
   -1   178     def test_all_success(self):
   -1   179         spy = self.create_spy()
   -1   180 
   -1   181         d1 = q.Deferred()
   -1   182         d2 = q.Deferred()
   -1   183         d3 = q.Deferred()
   -1   184 
   -1   185         d1.resolve('foo')
   -1   186         d3.resolve('baz')
   -1   187         d2.resolve('bar')
   -1   188 
   -1   189         q.all(d1.promise, d2.promise, d3.promise)\
   -1   190             .then(spy, self.assertNeverCalled)\
   -1   191             ._raise()
   -1   192 
   -1   193         self.assertCalledWith(spy, ['foo', 'bar', 'baz'])
   -1   194 
   -1   195     def test_all_error(self):
   -1   196         spy = self.create_spy()
   -1   197 
   -1   198         d1 = q.Deferred()
   -1   199         d2 = q.Deferred()
   -1   200         d3 = q.Deferred()
   -1   201 
   -1   202         d2.resolve('bar')
   -1   203         d3.reject('baz')
   -1   204 
   -1   205         q.all(d1.promise, d2.promise, d3.promise)\
   -1   206             .then(self.assertNeverCalled, spy)\
   -1   207             ._raise()
   -1   208 
   -1   209         self.assertCalledWith(spy, 'baz')

diff --git a/tox.ini b/tox.ini

@@ -0,0 +1,23 @@
   -1     1 # Tox (http://tox.testrun.org/) is a tool for running tests
   -1     2 # in multiple virtualenvs. This configuration file will run the
   -1     3 # test suite on all supported python versions. To use it, "pip install tox"
   -1     4 # and then run "tox" from this directory.
   -1     5 
   -1     6 [tox]
   -1     7 envlist = py26, py27
   -1     8 
   -1     9 [testenv]
   -1    10 commands =
   -1    11     flake8
   -1    12     nosetests laneya
   -1    13 deps =
   -1    14     flake8
   -1    15     nose
   -1    16     coverage
   -1    17 
   -1    18 [testenv:py26]
   -1    19 deps =
   -1    20     flake8
   -1    21     nose
   -1    22     coverage
   -1    23     unittest2