def test_after(self): m = Mock() class Type(): pass def make_t(): return Type() @requires(first(Type)) def f_t(t): m.f_t() @requires(Type) def n_t(t): m.n_t() @requires(last(Type)) def l_t_1(t): m.l_t_1() @requires(after(Type)) def after_t1(): m.after_t1() @requires(last(Type)) def l_t_2(t): m.l_t_2() Runner(make_t, l_t_1, after_t1, l_t_2, n_t, f_t)() compare([ call.f_t(), call.n_t(), call.l_t_1(), call.after_t1(), call.l_t_2(), ], m.mock_calls)
def test_ordering_runners(self): m = Mock() class Type(): pass @requires(first()) def f_none(): m.f_none() def n_none(): m.n_none() def l_none(): m.l_none() def make_t(): return Type() @requires(first(Type)) def f_t(t): m.f_t() @requires(Type) def n_t(t): m.n_t() @requires(last(Type)) def l_t(t): m.l_t() runner = Runner() runner.add(l_none, last()) runner.add(f_t) Runner(Runner(l_t, n_t), runner, Runner(f_none, n_none), Runner(make_t))() compare([ call.f_none(), call.n_none(), call.l_none(), call.f_t(), call.n_t(), call.l_t(), ], m.mock_calls)
def test_ordering(self): m = Mock() class Type(): pass @requires(first()) def f_none(): m.f_none() def n_none(): m.n_none() @requires(last()) def l_none(): m.l_none() def make_t(): return Type() @requires(first(Type)) def f_t(t): m.f_t() @requires(Type) def n_t(t): m.n_t() @requires(last(Type)) def l_t(t): m.l_t() Runner(l_t, n_t, l_none, f_t, f_none, n_none, make_t)() compare([ call.f_none(), call.n_none(), call.l_none(), call.f_t(), call.n_t(), call.l_t(), ], m.mock_calls)
def test_clone(self): m = Mock() class T1(object): pass class T2(object): pass def f1(): m.f1() def n1(): m.n1() return T1(), T2() def l1(): m.l1() def t1(obj): m.t1() def t2(obj): m.t2() # original runner1 = Runner() runner1.add(f1, first()) runner1.add(n1) runner1.add(l1, last()) runner1.add(t1, T1) runner1.add(t2, T2) # now clone and add bits def f2(): m.f2() def n2(): m.n2() def l2(): m.l2() def tn(obj): m.tn() runner2 = runner1.clone() runner2.add(f2, first()) runner2.add(n2) runner2.add(l2, last()) # make sure types stay in order runner2.add(tn, T2) # now run both, and make sure we only get what we should runner1() compare([ call.f1(), call.n1(), call.l1(), call.t1(), call.t2(), ], m.mock_calls) m.reset_mock() runner2() compare([ call.f1(), call.f2(), call.n1(), call.n2(), call.l1(), call.l2(), call.t1(), call.t2(), call.tn() ], m.mock_calls)
def make_runner(do): runner = Runner(ArgumentParser) runner.add(options, ArgumentParser) runner.add(parse_args, last(ArgumentParser)) runner.add(parse_config, first(Namespace)) runner.add(setup_logging, log_path = item(first(Config), 'log'), quiet = attr(first(Namespace), 'quiet'), verbose = attr(first(Namespace), 'verbose')) runner.add(DatabaseHandler, item(Config, 'db')) runner.add(do, attr(DatabaseHandler, 'conn'), attr(Namespace, 'path')) return runner
def test_complex_(self): # parser -> args -> dbs (later) -> job (earlier) m = Mock() class T1(object): pass class T2(object): pass class T3(object): pass def parser(): m.parser() return T1() @requires(T1) def args(obj): m.args(type(obj)) @requires(T2) def dbs(obj): m.dbs(type(obj)) return T3() @requires(last(T1)) def parse(obj): m.parse(type(obj)) return T2() runner = Runner(parser, args, dbs, parse) @requires(T1) def more_args(obj): m.more_args(type(obj)) @requires(T2, T3) def job(o1, o2): m.job(type(o1), type(o2)) runner.add(more_args) runner.add(job) runner() compare([ call.parser(), call.args(T1), call.more_args(T1), call.parse(T1), call.dbs(T2), call.job(T2, T3), ], m.mock_calls)
def test_simple_chain(self): m = Mock() class T1(object): pass class T2(object): pass t1 = T1() t2 = T2() def parser(): m.parser() return t1 @requires(T1) def base_args(obj): m.base_args(obj) @requires(last(T1)) def parse(obj): m.parse(obj) return t2 runner = Runner(parser, base_args, parse) @requires(T1) def my_args(obj): m.my_args(obj) runner.add(my_args) @requires(T2) def job(obj): m.job(obj) runner.add(job) runner() compare([ call.parser(), call.base_args(t1), call.my_args(t1), call.parse(t1), call.job(t2), ], m.mock_calls)
def test_how_when(self): m = Mock() class T(dict): foo = 'bar' @requires(item(first(T), 'baz')) def f_t(o): m.f_t(o) @requires(T) def n_t(o): m.n_t(o.__class__) @requires(attr(last(T), 'foo')) def l_t(o): m.l_t(o) def make_t(): t = T() t['baz'] = 'bob' return t Runner(l_t, n_t, f_t, make_t)() compare([ call.f_t('bob'), call.n_t(T), call.l_t('bar'), ], m.mock_calls)
def test_last(self): l = last(Type1) compare(repr(l), 'last(Type1)') compare(l.type, Type1) self.assertTrue(isinstance(l, when))
from argparse import ArgumentParser, Namespace from .configparser import RawConfigParser from mush import Runner, requires, first, last, attr, item import logging, os, sqlite3, sys log = logging.getLogger() @requires(ArgumentParser) def base_options(parser): parser.add_argument('config', help='Path to .ini file') parser.add_argument('--quiet', action='store_true', help='Log less to the console') parser.add_argument('--verbose', action='store_true', help='Log more to the console') @requires(last(ArgumentParser)) def parse_args(parser): return parser.parse_args() class Config(dict): pass @requires(first(Namespace)) def parse_config(args): config = RawConfigParser(dict_type=Config) config.read(args.config) return Config(config.items('main')) def setup_logging(log_path, quiet=False, verbose=False): handler = logging.FileHandler(log_path) handler.setLevel(logging.DEBUG) log.addHandler(handler)