view MoinMoin/ @ 2252:ecd43cdbb9b6

breadcrubms now show up titles properly.
author Ashutosh Singla <>
date Tue, 27 Aug 2013 19:11:15 +0530
parents 9cf6a6b474c5
children ee404f81afe9
line wrap: on
line source
# Copyright: 2005 MoinMoin:NirSoffer
# Copyright: 2007 MoinMoin:AlexanderSchremmer
# Copyright: 2008,2011 MoinMoin:ThomasWaldmann
# License: GNU GPL v2 (or any later version), see LICENSE.txt for details.

MoinMoin Testing Framework

All test modules must be named test_modulename to be included in the
test suite. If you are testing a package, name the test module

Tests that require a certain configuration, like section_numbers = 1, must
use a Config class to define the required configuration within the test class.

from __future__ import absolute_import, division

# exclude some directories from py.test test discovery, pathes relative to this file
collect_ignore = [
    'static',  # same
    '../wiki',  # no tests there
    '../instance',  # tw likes to use this for wiki data (non-revisioned)
import atexit
import os
import sys
import inspect

import pytest
import py
import MoinMoin.log

# Logging for tests to avoid useless output like timing information on stderr on test failures
Moindir = py.path.local(__file__).dirname
config_file = Moindir + '/_tests/test_logging.conf'

from import create_app_ext, destroy_app, before_wiki, teardown_wiki
from MoinMoin._tests import wikiconfig
from import create_simple_mapping

def init_test_app(given_config):
    namespace_mapping, backend_mapping, acl_mapping = \
        create_simple_mapping("stores:memory:", given_config.default_acl)
    more_config = dict(
        create_storage=True,  # create a fresh storage at each app start
        destroy_storage=True,  # kill all storage contents at app shutdown
        create_index=True,  # create a fresh index at each app start
        destroy_index=True,  # kill index contents at app shutdown
    app = create_app_ext(flask_config_dict=dict(SECRET_KEY='foobarfoobar'),
    ctx = app.test_request_context('/', base_url="http://localhost:8080/")
    return app, ctx

def deinit_test_app(app, ctx):

# we keep state in these globals:
prev_app = None
prev_ctx = None
prev_cfg = None

class MoinTestFunction(pytest.collect.Function):
    def setup(self):
        global prev_app, prev_ctx, prev_cfg

        if inspect.isclass(self.parent.obj.__class__):
            cls = self.parent.obj.__class__
            cfg = getattr(cls, 'Config', wikiconfig.Config)
            reinit = getattr(cls, 'reinit_storage', False)
            if (prev_cfg is not cfg or reinit) and prev_app is not None:
                # other config, previous app exists, so deinit it:
                deinit_test_app(prev_app, prev_ctx)
            if prev_cfg is not cfg or reinit or prev_app is None:
                # other config or no app yet, init app:
      , self.ctx = init_test_app(cfg)
                # otherwise continue using the app/ctx we have:
       = prev_app
                self.ctx = prev_ctx
            # remember what we have, for next setup()
            prev_app, prev_ctx, prev_cfg =, self.ctx, cfg
            prev_app, prev_ctx, prev_cfg = None, None, None

        super(MoinTestFunction, self).setup()
        #XXX: hack till we get better funcarg tools
        if hasattr(self._obj, 'im_self'):

    def teardown(self):
        super(MoinTestFunction, self).teardown()

def pytest_pycollect_makemodule(path, parent):
    return Module(path, parent=parent)

def pytest_pycollect_makeitem(__multicall__, collector, name, obj):
    if collector.funcnamefilter(name) and inspect.isfunction(obj):
        return MoinTestFunction(name, parent=collector)

def pytest_pyfunc_call(pyfuncitem):
    """hook to intercept generators and run them as a single test items"""
    if inspect.isgeneratorfunction(pyfuncitem.obj):
        for item in pyfuncitem.obj():
            kwarg = item[1:]

def pytest_report_header(config):
    return "The tests here are implemented only for pytest-2"

class Module(pytest.collect.Module):
    def run(self, *args, **kwargs):
        if coverage is not None:
            coverage_modules.update(getattr(self.obj, 'coverage_modules', []))
        return super(Module, self).run(*args, **kwargs)