Source

dutest-trac / trac-dev / testing / tracdutest / gviz.py

Full commit
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# Copyright 2009-2018 Olemis Lang <olemis at gmail.com>
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

r"""Classes used to test Trac data sources compatible with Google Charts API

Notice: Most of the classes offered in this module have been imported from
        TracGViz plugin; created in 2009

Copyright 2009-2018 Olemis Lang <olemis at gmail.com>
Licensed under the Apache License
"""
__author__ = 'Olemis Lang'

__metaclass__ = type

from trac.core import ComponentMeta
from trac.db.api import _parse_db_str, DatabaseManager
from trac.test import EnvironmentStub

import os.path
import sys
import tempfile

from dutest import DocTestLoader, DocTestSuiteFixture
from os.path import dirname
from types import MethodType

from tracdutest import DocTestTracLoader
from tracdutest.rpc import DocTestRpcLoader
from tracdutest.util.web import dummy_request

# Hide this module from tracebacks written into test results.
__unittest = True

#------------------------------------------------------
#    Test artifacts used to test GViz providers
#------------------------------------------------------

class DocTestGVizLoader(DocTestRpcLoader):
    r"""Load doctests used to test Trac GViz providers.
    """
    if not __name__.startswith('tracgviz.'):
        # Load trac built-in components and standard RPC handlers 
        # and GViz core system if used outside TracGViz package ;o).
        default_packages = ['trac', 'tracrpc', 'tracgviz']

    class doctestSuiteClass(DocTestTracLoader.doctestSuiteClass):
        r"""Include the appropriate RPC handler in global namespace 
        before running all test cases in the suite.
        """
        def setUp(self):
            r"""Include the appropriate RPC handler and GViz provider in 
            global namespace before running all test cases in the suite. 
            In this case four objects are added to the global namespace :

              - `rpcobj`          an instance of the RPC handler used to 
                                  perform anonymous requests.
              - `auth_rpcobj`     an instance of the RPC handler used to 
                                  perform authenticated requests. The user 
                                  name is determined by `username` 
                                  attribute and defaults to `murphy`.
              - `gvizobj`         an instance of the GViz provider used to 
                                  retrieve data just like if `anonymous` 
                                  user was accessing the site.
              - `auth_gvizobj`    an instance of the GViz provider used to 
                                  retrieve data just like if an 
                                  authenticated user was accessing the site.
                                  The user name is determined by `username` 
                                  attribute and defaults to `murphy`.
            """
            # Fail here if either XmlRpcPlugin or TracGViz are not 
            # available. Thus this fact will be reported as a failure and 
            # subsequent test cases will be run anyway.
            from tracrpc.api import XMLRPCSystem
            self.rpcsys = XMLRPCSystem(self.env)
            from tracgviz.api import TracGVizSystem
            self.gvizsys = TracGVizSystem(self.env)

            # Add request objects
            DocTestTracLoader.doctestSuiteClass.setUp(self)

            gvizns = self.ns_from_name()
            if rpcns is None :
                # TODO: If doctests belong to a GViz provider class then 
                #       instantiate it. In the mean time ...
                self.partial_setup()
            else :
                try :
                    rpcns = self.setup_gviz(gvizns)
                except RuntimeError :
                    self.partial_setup()
                else :
                    try :
                      self.setup_rpc(rpcns)
                    except RuntimeError :
                        DocTestRpcLoader.doctestSuiteClass.partial_setup(self)

        def setup_gviz(self, gvizns):
            r"""(Insert | update) the correct GViz provider in the global 
            namespace.

            @param gvizns               the namespace used to load the 
                                        GViz provider.
            @throws RuntimeError        if the provider bound to the 
                                        requested namespace cannot be found.
            """
            globs = self.globalns
            for p in self.gvizsys.providers :
              if p.gviz_namespace() == gvizns :
                globs['gvizobj'] = GVizDirectProxy(rpch, globs['req'])
                globs['auth_gvizobj'] = GVizDirectProxy(rpch, globs['auth_req'])
                break
            else :
              raise RuntimeError('Cannot load GViz provider for %s' % gvizns)

        def partial_setup(self):
            r"""Perform partial setup due to some minor failure (e.g. 
            namespace missing in test name).
            """
            globs = self.globalns
            globs.update([nm, None] for nm in ['rpcobj', 'auth_rpcobj', \
                                                'gvizobj', 'auth_gvizobj'])

class GVizDirectProxy:
    r"""A proxy used in tests to encapsulate the interaction with GViz 
    providers. In this case the provider's methods are invoked directly.

    It also asserts that the permissions necessary to execute a given 
    method are satisfied by the corresponding request object.
    """
    # TODO: Implement