Exemple #1
0
class ComponentRegistryCase(
    unittest.TestCase, common.MetaCase("DummyCase", (object,), {})
):
    """This test case can be used as a base for writings tests on components

    This test case is meant to test components in a special component registry,
    where you want to have maximum control on which components are loaded
    or not, or when you want to create additional components in your tests.

    If you only want to *use* the components of the tested addon in your tests,
    then consider using one of:

    * :class:`TransactionComponentCase`
    * :class:`SavepointComponentCase`

    This test case creates a special
    :class:`odoo.addons.component.core.ComponentRegistry` for the purpose of
    the tests. By default, it loads all the components of the dependencies, but
    not the components of the current addon (which you have to handle
    manually). In your tests, you can add more components in 2 manners.

    All the components of an Odoo module::

        self._load_module_components('connector')

    Only specific components::

        self._build_components(MyComponent1, MyComponent2)

    Note: for the lookups of the components, the default component
    registry is a global registry for the database. Here, you will
    need to explicitly pass ``self.comp_registry`` in the
    :class:`~odoo.addons.component.core.WorkContext`::

        work = WorkContext(model_name='res.users',
                           collection='my.collection',
                           components_registry=self.comp_registry)

    Or::

        collection_record = self.env['my.collection'].browse(1)
        with collection_record.work_on(
                'res.partner',
                components_registry=self.comp_registry) as work:

    """

    if sys.version_info < (3, 8):
        # Copy/paste from
        # https://github.com/odoo/odoo/blob/0218d870d319af4f263d5e9aa324990f7cc90139/
        # odoo/tests/common.py#L248-L268
        # Partial backport of bpo-24412, merged in CPython 3.8
        _class_cleanups = []

        @classmethod
        def addClassCleanup(cls, function, *args, **kwargs):
            """Same as addCleanup, except the cleanup items are called even if
            setUpClass fails (unlike tearDownClass). Backport of bpo-24412."""
            cls._class_cleanups.append((function, args, kwargs))

        @classmethod
        def doClassCleanups(cls):
            """Execute all class cleanup functions.
            Normally called for you after tearDownClass.
            Backport of bpo-24412."""
            cls.tearDown_exceptions = []
            while cls._class_cleanups:
                function, args, kwargs = cls._class_cleanups.pop()
                try:
                    function(*args, **kwargs)
                except Exception:
                    cls.tearDown_exceptions.append(sys.exc_info())

    @staticmethod
    def _setup_registry(class_or_instance):
        # keep the original classes registered by the metaclass
        # so we'll restore them at the end of the tests, it avoid
        # to pollute it with Stub / Test components
        class_or_instance._original_components = copy.deepcopy(
            MetaComponent._modules_components
        )

        # it will be our temporary component registry for our test session
        class_or_instance.comp_registry = ComponentRegistry()

        # it builds the 'final component' for every component of the
        # 'component' addon and push them in the component registry
        class_or_instance.comp_registry.load_components("component")
        # build the components of every installed addons already installed
        # but the current addon (when running with pytest/nosetest, we
        # simulate the --test-enable behavior by excluding the current addon
        # which is in 'to install' / 'to upgrade' with --test-enable).
        current_addon = _get_addon_name(class_or_instance.__module__)
        with new_rollbacked_env() as env:
            env["component.builder"].build_registry(
                class_or_instance.comp_registry,
                states=("installed",),
                exclude_addons=[current_addon],
            )

        # Fake that we are ready to work with the registry
        # normally, it is set to True and the end of the build
        # of the components. Here, we'll add components later in
        # the components registry, but we don't mind for the tests.
        class_or_instance.comp_registry.ready = True
        if hasattr(class_or_instance, "env"):
            # let it propagate via ctx
            class_or_instance.env.context = dict(
                class_or_instance.env.context,
                components_registry=class_or_instance.comp_registry,
            )

    @staticmethod
    def _teardown_registry(class_or_instance):
        # restore the original metaclass' classes
        MetaComponent._modules_components = class_or_instance._original_components

    def _load_module_components(self, module):
        self.comp_registry.load_components(module)

    def _build_components(self, *classes):
        for cls in classes:
            cls._build_component(self.comp_registry)
Exemple #2
0
class DatamodelRegistryCase(unittest.TestCase,
                            common.MetaCase("DummyCase", (object, ), {})):
    """ This test case can be used as a base for writings tests on datamodels

    This test case is meant to test datamodels in a special datamodel registry,
    where you want to have maximum control on which datamodels are loaded
    or not, or when you want to create additional datamodels in your tests.

    If you only want to *use* the datamodels of the tested addon in your tests,
    then consider using one of:

    * :class:`TransactionDatamodelCase`
    * :class:`SavepointDatamodelCase`

    This test case creates a special
    :class:`odoo.addons.datamodel.core.DatamodelRegistry` for the purpose of
    the tests. By default, it loads all the datamodels of the dependencies, but
    not the datamodels of the current addon (which you have to handle
    manually). In your tests, you can add more datamodels in 2 manners.

    All the datamodels of an Odoo module::

        self._load_module_datamodels('connector')

    Only specific datamodels::

        self._build_datamodels(MyDatamodel1, MyDatamodel2)

    Note: for the lookups of the datamodels, the default datamodel
    registry is a global registry for the database. Here, you will
    need to explicitly pass ``self.datamodel_registry`` in the
    """
    def setUp(self):
        super(DatamodelRegistryCase, self).setUp()

        # keep the original classes registered by the metaclass
        # so we'll restore them at the end of the tests, it avoid
        # to pollute it with Stub / Test datamodels
        self._original_datamodels = copy.deepcopy(
            MetaDatamodel._modules_datamodels)

        # it will be our temporary datamodel registry for our test session
        self.datamodel_registry = DatamodelRegistry()

        # it builds the 'final datamodel' for every datamodel of the
        # 'datamodel' addon and push them in the datamodel registry
        self.datamodel_registry.load_datamodels("datamodel")
        # build the datamodels of every installed addons already installed
        # but the current addon (when running with pytest/nosetest, we
        # simulate the --test-enable behavior by excluding the current addon
        # which is in 'to install' / 'to upgrade' with --test-enable).
        current_addon = _get_addon_name(self.__module__)

        registry = odoo.registry(common.get_db_name())
        uid = odoo.SUPERUSER_ID
        cr = registry.cursor()
        env = api.Environment(cr, uid, {})
        env["datamodel.builder"].build_registry(
            self.datamodel_registry,
            states=("installed", ),
            exclude_addons=[current_addon],
        )
        self.env = env
        _datamodel_databases[self.env.cr.dbname] = self.datamodel_registry

        @self.addCleanup
        def _close_and_roolback():
            cr.rollback()  # we shouldn't have to commit anything
            cr.close()

        # Fake that we are ready to work with the registry
        # normally, it is set to True and the end of the build
        # of the datamodels. Here, we'll add datamodels later in
        # the datamodels registry, but we don't mind for the tests.
        self.datamodel_registry.ready = True

    def tearDown(self):
        super(DatamodelRegistryCase, self).tearDown()
        # restore the original metaclass' classes
        MetaDatamodel._modules_datamodels = self._original_datamodels

    def _load_module_datamodels(self, module):
        self.datamodel_registry.load_datamodels(module)

    def _build_datamodels(self, *classes):
        for cls in classes:
            cls._build_datamodel(self.datamodel_registry)
Exemple #3
0
class ComponentRegistryCase(unittest.TestCase,
                            common.MetaCase('DummyCase', (object, ), {})):
    """ This test case can be used as a base for writings tests on components

    This test case is meant to test components in a special component registry,
    where you want to have maximum control on which components are loaded
    or not, or when you want to create additional components in your tests.

    If you only want to *use* the components of the tested addon in your tests,
    then consider using one of:

    * :class:`TransactionComponentCase`
    * :class:`SavepointComponentCase`

    This test case creates a special
    :class:`odoo.addons.component.core.ComponentRegistry` for the purpose of
    the tests. By default, it loads all the components of the dependencies, but
    not the components of the current addon (which you have to handle
    manually). In your tests, you can add more components in 2 manners.

    All the components of an Odoo module::

        self._load_module_components('connector')

    Only specific components::

        self._build_components(MyComponent1, MyComponent2)

    Note: for the lookups of the components, the default component
    registry is a global registry for the database. Here, you will
    need to explicitly pass ``self.comp_registry`` in the
    :class:`~odoo.addons.component.core.WorkContext`::

        work = WorkContext(model_name='res.users',
                           collection='my.collection',
                           components_registry=self.comp_registry)

    Or::

        collection_record = self.env['my.collection'].browse(1)
        with collection_record.work_on(
                'res.partner',
                components_registry=self.comp_registry) as work:

    """
    def setUp(self):
        super(ComponentRegistryCase, self).setUp()

        # keep the original classes registered by the metaclass
        # so we'll restore them at the end of the tests, it avoid
        # to pollute it with Stub / Test components
        self._original_components = copy.deepcopy(
            MetaComponent._modules_components)

        # it will be our temporary component registry for our test session
        self.comp_registry = ComponentRegistry()

        # it builds the 'final component' for every component of the
        # 'component' addon and push them in the component registry
        self.comp_registry.load_components('component')
        # build the components of every installed addons already installed
        # but the current addon (when running with pytest/nosetest, we
        # simulate the --test-enable behavior by excluding the current addon
        # which is in 'to install' / 'to upgrade' with --test-enable).
        current_addon = _get_addon_name(self.__module__)
        with new_rollbacked_env() as env:
            env['component.builder'].build_registry(
                self.comp_registry,
                states=('installed', ),
                exclude_addons=[current_addon],
            )

        # Fake that we are ready to work with the registry
        # normally, it is set to True and the end of the build
        # of the components. Here, we'll add components later in
        # the components registry, but we don't mind for the tests.
        self.comp_registry.ready = True

    def tearDown(self):
        super(ComponentRegistryCase, self).tearDown()
        # restore the original metaclass' classes
        MetaComponent._modules_components = self._original_components

    def _load_module_components(self, module):
        self.comp_registry.load_components(module)

    def _build_components(self, *classes):
        for cls in classes:
            cls._build_component(self.comp_registry)