Changeset - 1927a1812033
[Not reviewed]
0 3 1
Brett Smith - 7 years ago 2017-05-12 11:40:27
brettcsmith@brettcsmith.org
loaders: Add LoaderChain.
4 files changed with 115 insertions and 5 deletions:
0 comments (0 inline, 0 general)
oxrlib/loaders.py
Show inline comments
 
import cgi
 
import functools
 
import io
 
import urllib.request
 
import urllib.parse
...
 
@@ -19,6 +20,10 @@ class LoaderSourceError(LoaderError):
 
    pass
 

	
 

	
 
class NoLoadersError(Exception):
 
    pass
 

	
 

	
 
class FileCache:
 
    def __init__(self, dir_path, filename_pattern):
 
        self.dir_path = dir_path
...
 
@@ -75,3 +80,32 @@ class OXRAPIRequest:
 
            'historical/{}.json'.format(date.isoformat()),
 
            {'app_id': self.app_id, 'base': base},
 
        )
 

	
 

	
 
class LoaderChain:
 
    def __init__(self):
 
        self.loaders = []
 

	
 
    def add_loader(self, loader):
 
        self.loaders.append(loader)
 

	
 
    def _wrap_load_method(orig_func):
 
        @functools.wraps(orig_func)
 
        def load_wrapper(self, *args, **kwargs):
 
            self.used_loader = None
 
            error = None
 
            for loader in self.loaders:
 
                try:
 
                    response = getattr(loader, orig_func.__name__)(*args, **kwargs)
 
                except LoaderError as this_error:
 
                    error = this_error
 
                else:
 
                    self.used_loader = loader
 
                    return response
 
            else:
 
                raise NoLoadersError() if error is None else error
 
        return load_wrapper
 

	
 
    @_wrap_load_method
 
    def historical(self, date, base):
 
        pass
tests/__init__.py
Show inline comments
 
import datetime
 
import pathlib
 
import random
 

	
 
import pytest
 

	
 
TEST_DIR = pathlib.Path(__file__).parent
 

	
 
def relpath(*parts):
 
    return TEST_DIR / pathlib.Path(*parts)
 

	
 
@pytest.fixture
 
def any_date():
 
    return datetime.date.today() - datetime.timedelta(days=730 - random.randint(0, 365))
tests/test_LoaderChain.py
Show inline comments
 
new file 100644
 
import io
 

	
 
import pytest
 

	
 
import oxrlib.loaders
 

	
 
from . import any_date
 

	
 
SUCCESS_S = '"success"\n'
 
ERROR = oxrlib.loaders.LoaderNoDataError("test")
 

	
 
class FakeLoader:
 
    def __init__(self, result):
 
        self.result = result
 

	
 
    def _respond(self, *args, **kwargs):
 
        return io.StringIO(self.result)
 

	
 
    def __getattr__(self, name):
 
        return self._respond
 

	
 

	
 
class FakeErrorLoader(FakeLoader):
 
    def __init__(self, error):
 
        self.error = error
 

	
 
    def _respond(self, *args, **kwargs):
 
        raise self.error
 

	
 

	
 
@pytest.fixture
 
def lchain():
 
    return oxrlib.loaders.LoaderChain()
 

	
 
@pytest.fixture
 
def good_loader():
 
    return FakeLoader(SUCCESS_S)
 

	
 
@pytest.fixture
 
def error_loader():
 
    return FakeErrorLoader(ERROR)
 

	
 
def test_no_loaders(lchain, any_date):
 
    try:
 
        lchain.historical(any_date, 'USD')
 
    except oxrlib.loaders.NoLoadersError:
 
        pass
 
    else:
 
        assert False, "expected NoLoadersError not raised"
 

	
 
def test_one_with_success(lchain, any_date, good_loader):
 
    lchain.add_loader(good_loader)
 
    response = lchain.historical(any_date, 'USD')
 
    assert response.read(32) == SUCCESS_S
 

	
 
def test_two_with_success(lchain, any_date, good_loader, error_loader):
 
    lchain.add_loader(error_loader)
 
    lchain.add_loader(good_loader)
 
    response = lchain.historical(any_date, 'USD')
 
    assert response.read(32) == SUCCESS_S
 

	
 
@pytest.mark.parametrize('count', [1, 2])
 
def test_no_success(lchain, any_date, error_loader, count):
 
    for _ in range(count):
 
        lchain.add_loader(error_loader)
 
    try:
 
        lchain.historical(any_date, 'USD')
 
    except type(ERROR) as error:
 
        assert error is ERROR
 
    else:
 
        assert False, "{} not raised".format(type(ERROR).__name__)
tests/test_OXRAPIRequest.py
Show inline comments
 
import datetime
 
import http.client
 
import io
 
import json
...
 
@@ -10,6 +9,8 @@ import urllib.parse
 
import pytest
 
import oxrlib.loaders
 

	
 
from . import any_date
 

	
 
APPID_CHARS = string.ascii_letters + string.digits
 
RANDOM_APPID = ''.join(random.choice(APPID_CHARS) for _ in range(32))
 
API_ROOT = 'http://[100::]/oxrlibtest/'
...
 
@@ -67,10 +68,6 @@ class FakeOpener:
 
def api_client():
 
    return oxrlib.loaders.OXRAPIRequest(RANDOM_APPID, API_ROOT)
 

	
 
@pytest.fixture
 
def any_date():
 
    return datetime.date.today() - datetime.timedelta(days=730 - random.randint(0, 365))
 

	
 
@pytest.mark.parametrize('base', ['USD', 'JPY'])
 
def test_success(api_client, any_date, base):
 
    body = "Good Test"
0 comments (0 inline, 0 general)