diff --git a/force_bdss/api.py b/force_bdss/api.py index 577adb698147a5a3f9f791393af5b6071b5e4ab6..cb5c0467b0c082e2a5bc0e7dfb27175d8bb15d98 100644 --- a/force_bdss/api.py +++ b/force_bdss/api.py @@ -1,15 +1,21 @@ from .base_extension_plugin import BaseExtensionPlugin # noqa -from .ids import bundle_id -from .data_sources.i_data_source_bundle import IDataSourceBundle # noqa -from .mco.i_multi_criteria_optimizer_bundle import IMultiCriteriaOptimizerBundle # noqa -from .kpi.i_kpi_calculator_bundle import IKPICalculatorBundle # noqa +from .ids import bundle_id # noqa + from .data_sources.base_data_source_model import BaseDataSourceModel # noqa from .data_sources.data_source_result import DataSourceResult # noqa from .data_sources.data_source_parameters import DataSourceParameters # noqa from .data_sources.base_data_source import BaseDataSource # noqa +from .data_sources.base_data_source_bundle import BaseDataSourceBundle # noqa +from .data_sources.i_data_source_bundle import IDataSourceBundle # noqa + from .kpi.base_kpi_calculator import BaseKPICalculator # noqa from .kpi.kpi_calculator_result import KPICalculatorResult # noqa from .kpi.base_kpi_calculator_model import BaseKPICalculatorModel # noqa +from .kpi.base_kpi_calculator_bundle import BaseKPICalculatorBundle # noqa +from .kpi.i_kpi_calculator_bundle import IKPICalculatorBundle # noqa + from .mco.base_mco_model import BaseMCOModel # noqa from .mco.base_mco_communicator import BaseMCOCommunicator # noqa from .mco.base_multi_criteria_optimizer import BaseMultiCriteriaOptimizer # noqa +from .mco.base_multi_criteria_optimizer_bundle import BaseMultiCriteriaOptimizerBundle # noqa +from .mco.i_multi_criteria_optimizer_bundle import IMultiCriteriaOptimizerBundle # noqa diff --git a/force_bdss/core_plugins/csv_extractor/csv_extractor/csv_extractor_bundle.py b/force_bdss/core_plugins/csv_extractor/csv_extractor/csv_extractor_bundle.py index 19b499f989ae4a38537948dc60a8bdeb608a9287..55f998c49c4bfef7dfb37f93f61f3c435f00f518 100644 --- a/force_bdss/core_plugins/csv_extractor/csv_extractor/csv_extractor_bundle.py +++ b/force_bdss/core_plugins/csv_extractor/csv_extractor/csv_extractor_bundle.py @@ -1,15 +1,16 @@ -from traits.api import provides, HasStrictTraits, String +from traits.api import String -from force_bdss.api import IDataSourceBundle, bundle_id +from force_bdss.api import bundle_id, BaseDataSourceBundle from .csv_extractor_model import CSVExtractorModel from .csv_extractor_data_source import CSVExtractorDataSource -@provides(IDataSourceBundle) -class CSVExtractorBundle(HasStrictTraits): +class CSVExtractorBundle(BaseDataSourceBundle): id = String(bundle_id("enthought", "csv_extractor")) + name = String("CSV Extractor") + def create_model(self, model_data=None): if model_data is None: model_data = {} diff --git a/force_bdss/core_plugins/dummy_kpi/kpi_adder/kpi_adder_bundle.py b/force_bdss/core_plugins/dummy_kpi/kpi_adder/kpi_adder_bundle.py index a16fc046f6fc5c7393f9a489b9a3b6368c047888..ab40c710bbbff3bbdd5c5a39d62b95414198fbc4 100644 --- a/force_bdss/core_plugins/dummy_kpi/kpi_adder/kpi_adder_bundle.py +++ b/force_bdss/core_plugins/dummy_kpi/kpi_adder/kpi_adder_bundle.py @@ -1,15 +1,16 @@ -from traits.api import provides, HasStrictTraits, String +from traits.api import String -from force_bdss.api import IKPICalculatorBundle, bundle_id +from force_bdss.api import bundle_id, BaseKPICalculatorBundle from .kpi_adder_model import KPIAdderModel from .kpi_adder_calculator import KPIAdderCalculator -@provides(IKPICalculatorBundle) -class KPIAdderBundle(HasStrictTraits): +class KPIAdderBundle(BaseKPICalculatorBundle): id = String(bundle_id("enthought", "kpi_adder")) + name = String("KPI Adder") + def create_model(self, model_data=None): if model_data is None: model_data = {} diff --git a/force_bdss/core_plugins/dummy_mco/dakota/dakota_bundle.py b/force_bdss/core_plugins/dummy_mco/dakota/dakota_bundle.py index 329dd58dd8dd7b2cc6131be3c30e57f5a357446d..e4d9f441bf4dbcce63ac1de06a53a56dc35d693b 100644 --- a/force_bdss/core_plugins/dummy_mco/dakota/dakota_bundle.py +++ b/force_bdss/core_plugins/dummy_mco/dakota/dakota_bundle.py @@ -1,15 +1,16 @@ -from traits.api import HasStrictTraits, provides, String -from force_bdss.api import IMultiCriteriaOptimizerBundle, bundle_id +from traits.api import String +from force_bdss.api import bundle_id, BaseMultiCriteriaOptimizerBundle from .dakota_communicator import DakotaCommunicator from .dakota_model import DakotaModel from .dakota_optimizer import DakotaOptimizer -@provides(IMultiCriteriaOptimizerBundle) -class DakotaBundle(HasStrictTraits): +class DakotaBundle(BaseMultiCriteriaOptimizerBundle): id = String(bundle_id("enthought", "dakota")) + name = "Dakota" + def create_model(self, model_data=None): if model_data is None: model_data = {} diff --git a/force_bdss/data_sources/base_data_source.py b/force_bdss/data_sources/base_data_source.py index c700ea861daeaeb670451137b70f09ad8c065966..07a5ee9467db3488bf84f16770c756060f806771 100644 --- a/force_bdss/data_sources/base_data_source.py +++ b/force_bdss/data_sources/base_data_source.py @@ -1,24 +1,37 @@ +from traits.api import ABCHasStrictTraits, Instance import abc -import six +from .base_data_source_model import BaseDataSourceModel +from ..bdss_application import BDSSApplication +from ..data_sources.i_data_source_bundle import IDataSourceBundle -class BaseDataSource(six.with_metaclass(abc.ABCMeta)): + +class BaseDataSource(ABCHasStrictTraits): """Base class for the DataSource, any computational engine/retriever for data. Inherit from this class for your specific DataSource. """ - def __init__(self, bundle, application, model): + #: A reference to the bundle + bundle = Instance(IDataSourceBundle) + #: A reference to the application + application = Instance(BDSSApplication) + #: A reference to the model class + model = Instance(BaseDataSourceModel) + + def __init__(self, bundle, application, model, *args, **kwargs): self.bundle = bundle self.application = application self.model = model + super(BaseDataSource, self).__init__(*args, **kwargs) @property def name(self): + """Utility property to retrieve the bundle name from the data source + object.""" return self.bundle.name @abc.abstractmethod def run(self, parameters): """Executes the data source evaluation/fetching and returns the list of results as a DataSourceResult instance.""" - pass diff --git a/force_bdss/data_sources/base_data_source_bundle.py b/force_bdss/data_sources/base_data_source_bundle.py new file mode 100644 index 0000000000000000000000000000000000000000..ab53763fd294b025edfefd25b90e8ff200227641 --- /dev/null +++ b/force_bdss/data_sources/base_data_source_bundle.py @@ -0,0 +1,56 @@ +import abc +from traits.api import ABCHasStrictTraits, provides, String + +from .i_data_source_bundle import IDataSourceBundle + + +@provides(IDataSourceBundle) +class BaseDataSourceBundle(ABCHasStrictTraits): + """Base class for DataSource bundles. Reimplement this class to + create your own DataSource. + """ + # NOTE: changes to this class must be ported also to the IDataSourceBundle + + #: Unique identifier that identifies the bundle uniquely in the + #: universe of bundles. Create one with the function bundle_id() + id = String() + + #: A human readable name of the bundle. Spaces allowed + name = String() + + @abc.abstractmethod + def create_data_source(self, application, model): + """Factory method. + Must return the bundle-specific BaseDataSource instance. + + Parameters + ---------- + application: Application + The envisage application. + model: BaseDataSourceModel + The model of the data source, instantiated with create_model() + + Returns + ------- + BaseDataSource + The specific instance of the generated DataSource + """ + + @abc.abstractmethod + def create_model(self, model_data=None): + """Factory method. + Creates the model object (or network of model objects) of the KPI + calculator. The model can provide a traits UI View according to + traitsui specifications, so that a UI can be provided automatically. + + Parameters + ---------- + model_data: dict or None + A dictionary containing the information to recreate the model. + If None, an empty (with defaults) model will be returned. + + Returns + ------- + BaseDataSourceModel + The model + """ diff --git a/force_bdss/data_sources/i_data_source_bundle.py b/force_bdss/data_sources/i_data_source_bundle.py index 5270245c23d05b36fda603bd723d843a6777ecd7..8ed2556078382854920a999ce5c1bf1a8d6ed19f 100644 --- a/force_bdss/data_sources/i_data_source_bundle.py +++ b/force_bdss/data_sources/i_data_source_bundle.py @@ -13,7 +13,6 @@ class IDataSourceBundle(Interface): """Factory method. Must return the bundle-specific BaseDataSource instance. """ - pass def create_model(self, model_data=None): """Factory method. diff --git a/force_bdss/data_sources/tests/__init__.py b/force_bdss/data_sources/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/force_bdss/data_sources/tests/test_base_data_source.py b/force_bdss/data_sources/tests/test_base_data_source.py new file mode 100644 index 0000000000000000000000000000000000000000..e4784fb31f4fd47184eb021e758443d959e03292 --- /dev/null +++ b/force_bdss/data_sources/tests/test_base_data_source.py @@ -0,0 +1,29 @@ +import unittest + +from force_bdss.data_sources.base_data_source import BaseDataSource +from force_bdss.data_sources.base_data_source_model import BaseDataSourceModel +from force_bdss.data_sources.i_data_source_bundle import IDataSourceBundle + +try: + import mock +except ImportError: + from unittest import mock + +from force_bdss.bdss_application import BDSSApplication + + +class DummyDataSource(BaseDataSource): + def run(self, *args, **kwargs): + pass + + +class TestBaseDataSource(unittest.TestCase): + def test_initialization(self): + bundle = mock.Mock(spec=IDataSourceBundle) + application = mock.Mock(spec=BDSSApplication) + model = mock.Mock(spec=BaseDataSourceModel) + ds = DummyDataSource(bundle, application, model) + + self.assertEqual(ds.bundle, bundle) + self.assertEqual(ds.application, application) + self.assertEqual(ds.model, model) diff --git a/force_bdss/data_sources/tests/test_base_data_source_bundle.py b/force_bdss/data_sources/tests/test_base_data_source_bundle.py new file mode 100644 index 0000000000000000000000000000000000000000..3564a7eb423a4ea3e265b4996be184744c8b1d6f --- /dev/null +++ b/force_bdss/data_sources/tests/test_base_data_source_bundle.py @@ -0,0 +1,23 @@ +import unittest + +from force_bdss.data_sources.base_data_source_bundle import \ + BaseDataSourceBundle + + +class DummyDataSourceBundle(BaseDataSourceBundle): + id = "foo" + + name = "bar" + + def create_data_source(self, application, model): + pass + + def create_model(self, model_data=None): + pass + + +class TestBaseDataSourceBundle(unittest.TestCase): + def test_initialization(self): + bundle = DummyDataSourceBundle() + self.assertEqual(bundle.id, 'foo') + self.assertEqual(bundle.name, 'bar') diff --git a/force_bdss/kpi/base_kpi_calculator.py b/force_bdss/kpi/base_kpi_calculator.py index 5e67d149216292b3a516e4488b4ae85e28e753da..0a9a2e0cd3e83ac8b4a074c551f7aed75867246b 100644 --- a/force_bdss/kpi/base_kpi_calculator.py +++ b/force_bdss/kpi/base_kpi_calculator.py @@ -1,18 +1,44 @@ import abc -import six +from traits.api import ABCHasStrictTraits, Instance -class BaseKPICalculator(six.with_metaclass(abc.ABCMeta)): - def __init__(self, bundle, application, model): +from ..bdss_application import BDSSApplication +from .base_kpi_calculator_model import BaseKPICalculatorModel +from .i_kpi_calculator_bundle import IKPICalculatorBundle + + +class BaseKPICalculator(ABCHasStrictTraits): + """Base class for the KPICalculators. + + Inherit this class for your KPI calculator. + """ + #: A reference to the bundle + bundle = Instance(IKPICalculatorBundle) + #: A reference to the application + application = Instance(BDSSApplication) + #: A reference to the model class + model = Instance(BaseKPICalculatorModel) + + def __init__(self, bundle, application, model, *args, **kwargs): self.bundle = bundle self.application = application self.model = model + super(BaseKPICalculator, self).__init__(*args, **kwargs) @property def name(self): + """Convenience property. Returns the name of the originating bundle.""" return self.bundle.name @abc.abstractmethod def run(self, data_source_results): - """Executes the KPI evaluation and returns the list of results.""" - pass + """ + Executes the KPI evaluation and returns the list of results. + Reimplement this method in your specific KPI calculator. + + Parameters + ---------- + data_source_results: + a list of DataSourceResult instances containing the results of the + evaluation. + """ diff --git a/force_bdss/kpi/base_kpi_calculator_bundle.py b/force_bdss/kpi/base_kpi_calculator_bundle.py new file mode 100644 index 0000000000000000000000000000000000000000..5ae40637ebae8a75b0fed7089cfa6a629383e11c --- /dev/null +++ b/force_bdss/kpi/base_kpi_calculator_bundle.py @@ -0,0 +1,58 @@ +import abc +from traits.api import ABCHasStrictTraits, provides, String + +from .i_kpi_calculator_bundle import IKPICalculatorBundle + + +@provides(IKPICalculatorBundle) +class BaseKPICalculatorBundle(ABCHasStrictTraits): + """Base class for the Key Performance Indicator calculator bundles. + Inherit from this class to create a bundle, and reimplement the abstract + methods. + """ + # NOTE: any changes in this interface must be ported to + # IKPICalculatorBundle + + #: A unique ID generated with bundle_id() routine + id = String() + + #: A UI friendly name for the bundle. Can contain spaces. + name = String() + + @abc.abstractmethod + def create_kpi_calculator(self, application, model): + """Factory method. + Creates and returns an instance of a KPI Calculator, associated + to the given application and model. + + Parameters + ---------- + application: Application + The envisage application. + model: BaseKPICalculatorModel + The model of the calculator, instantiated with create_model() + + Returns + ------- + BaseKPICalculator + The specific instance of the generated KPICalculator + """ + + @abc.abstractmethod + def create_model(self, model_data=None): + """Factory method. + Creates the model object (or network of model objects) of the KPI + calculator. The model can provide a traits UI View according to + traitsui specifications, so that a UI can be provided automatically. + + Parameters + ---------- + model_data: dict or None + A dictionary containing the information to recreate the model. + If None, an empty (with defaults) model will be returned. + + Returns + ------- + BaseKPICalculatorModel + The model + """ diff --git a/force_bdss/kpi/i_kpi_calculator_bundle.py b/force_bdss/kpi/i_kpi_calculator_bundle.py index d4e8992ba059883f1b8824eb74966f3cdb0222e3..938e7de719990cf5e672c1c350adbf36bfca2a31 100644 --- a/force_bdss/kpi/i_kpi_calculator_bundle.py +++ b/force_bdss/kpi/i_kpi_calculator_bundle.py @@ -2,8 +2,12 @@ from traits.api import Interface, String class IKPICalculatorBundle(Interface): + """Envisage required interface for the BaseKPICalculatorBundle. + You should not need to use this directly.""" id = String() + name = String() + def create_kpi_calculator(self, application, model): pass diff --git a/force_bdss/kpi/tests/__init__.py b/force_bdss/kpi/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/force_bdss/kpi/tests/test_base_kpi_calculator.py b/force_bdss/kpi/tests/test_base_kpi_calculator.py new file mode 100644 index 0000000000000000000000000000000000000000..512f51fdfe685aaf58296213548ec1a0b12c48cc --- /dev/null +++ b/force_bdss/kpi/tests/test_base_kpi_calculator.py @@ -0,0 +1,27 @@ +import unittest +try: + import mock +except ImportError: + from unittest import mock + +from force_bdss.bdss_application import BDSSApplication +from force_bdss.kpi.base_kpi_calculator_model import BaseKPICalculatorModel +from force_bdss.kpi.base_kpi_calculator import BaseKPICalculator +from force_bdss.kpi.i_kpi_calculator_bundle import IKPICalculatorBundle + + +class DummyKPICalculator(BaseKPICalculator): + def run(self, *args, **kwargs): + pass + + +class TestBaseKPICalculator(unittest.TestCase): + def test_initialization(self): + bundle = mock.Mock(spec=IKPICalculatorBundle) + application = mock.Mock(spec=BDSSApplication) + model = mock.Mock(spec=BaseKPICalculatorModel) + kpic = DummyKPICalculator(bundle, application, model) + + self.assertEqual(kpic.bundle, bundle) + self.assertEqual(kpic.application, application) + self.assertEqual(kpic.model, model) diff --git a/force_bdss/kpi/tests/test_base_kpi_calculator_bundle.py b/force_bdss/kpi/tests/test_base_kpi_calculator_bundle.py new file mode 100644 index 0000000000000000000000000000000000000000..30dc60e7f8a5d4e6ebbc7598b14a03f247b61f3c --- /dev/null +++ b/force_bdss/kpi/tests/test_base_kpi_calculator_bundle.py @@ -0,0 +1,23 @@ +import unittest + +from force_bdss.kpi.base_kpi_calculator_bundle import \ + BaseKPICalculatorBundle + + +class DummyKPICalculatorBundle(BaseKPICalculatorBundle): + id = "foo" + + name = "bar" + + def create_kpi_calculator(self, application, model): + pass + + def create_model(self, model_data=None): + pass + + +class TestBaseKPICalculatorBundle(unittest.TestCase): + def test_initialization(self): + bundle = DummyKPICalculatorBundle() + self.assertEqual(bundle.id, 'foo') + self.assertEqual(bundle.name, 'bar') diff --git a/force_bdss/mco/base_multi_criteria_optimizer.py b/force_bdss/mco/base_multi_criteria_optimizer.py index 5930c5ca5ecc0528e6e8effdf262d45f213f117f..6dd3462260517368527aa9a53582169792033deb 100644 --- a/force_bdss/mco/base_multi_criteria_optimizer.py +++ b/force_bdss/mco/base_multi_criteria_optimizer.py @@ -1,17 +1,37 @@ import abc -import six +from traits.api import ABCHasStrictTraits, Instance -class BaseMultiCriteriaOptimizer(six.with_metaclass(abc.ABCMeta)): - def __init__(self, bundle, application, model): +from ..bdss_application import BDSSApplication +from .base_mco_model import BaseMCOModel +from .i_multi_criteria_optimizer_bundle import IMultiCriteriaOptimizerBundle + + +class BaseMultiCriteriaOptimizer(ABCHasStrictTraits): + """Base class for the Multi Criteria Optimizer. + + Inherit this class for your MCO implementation + """ + #: A reference to the bundle + bundle = Instance(IMultiCriteriaOptimizerBundle) + #: A reference to the application + application = Instance(BDSSApplication) + #: A reference to the model class + model = Instance(BaseMCOModel) + + def __init__(self, bundle, application, model, *args, **kwargs): self.bundle = bundle self.application = application self.model = model + super(BaseMultiCriteriaOptimizer, self).__init__(*args, **kwargs) @property def name(self): + """Convenience property to return the name of the bundle from the + MCO itself""" return self.bundle.name @abc.abstractmethod def run(self): + """Reimplement this method to perform the MCO operations.""" pass diff --git a/force_bdss/mco/base_multi_criteria_optimizer_bundle.py b/force_bdss/mco/base_multi_criteria_optimizer_bundle.py new file mode 100644 index 0000000000000000000000000000000000000000..228ec4c9c3546b6428a1226028af3acabb11c3c8 --- /dev/null +++ b/force_bdss/mco/base_multi_criteria_optimizer_bundle.py @@ -0,0 +1,76 @@ +import abc + +from traits.api import ABCHasStrictTraits, String +from traits.has_traits import provides + +from force_bdss.mco.i_multi_criteria_optimizer_bundle import ( + IMultiCriteriaOptimizerBundle +) + + +@provides(IMultiCriteriaOptimizerBundle) +class BaseMultiCriteriaOptimizerBundle(ABCHasStrictTraits): + """Base class for the MultiCriteria Optimizer bundle. + """ + # NOTE: any changes to the interface of this class must be replicated + # in the IMultiCriteriaOptimizerBundle interface class. + + #: A unique ID produced with the bundle_id() routine. + id = String() + + #: A user friendly name of the bundle. Spaces allowed. + name = String() + + @abc.abstractmethod + def create_optimizer(self, application, model): + """Factory method. + Creates the optimizer with the given application + and model and returns it to the caller. + + Parameters + ---------- + application: Application + The envisage application instance + model: BaseMCOModel + The model to associate to the optimizer, instantiated through + create_model() + + Returns + ------- + BaseMCOOptimizer + The optimizer + """ + + @abc.abstractmethod + def create_model(self, model_data=None): + """Factory method. + Creates the model object (or network of model objects) of the MCO. + The model can provide a traits UI View according to traitsui + specifications, so that a UI can be provided automatically. + + Parameters + ---------- + model_data: dict or None + A dictionary of data that can be interpreted appropriately to + recreate the model. If None, an empty (with defaults) model will + be created and returned. + + Returns + ------- + BaseMCOModel + The MCOModel + """ + + @abc.abstractmethod + def create_communicator(self, application, model): + """Factory method. Returns the communicator class that allows + exchange between the MCO and the evaluator code. + + Parameters + ---------- + application: Application + The envisage application instance + model: BaseMCOModel + The model to associate to the optimizer, instantiated through + create_model() + """ diff --git a/force_bdss/mco/i_multi_criteria_optimizer_bundle.py b/force_bdss/mco/i_multi_criteria_optimizer_bundle.py index cb4222992cf0d7349a798e9747511c7c7e73b4d6..82a857ae03fc9976247770f8aa095ac9528381a6 100644 --- a/force_bdss/mco/i_multi_criteria_optimizer_bundle.py +++ b/force_bdss/mco/i_multi_criteria_optimizer_bundle.py @@ -2,13 +2,18 @@ from traits.api import Interface, String class IMultiCriteriaOptimizerBundle(Interface): + """Interface for the MultiCriteria Optimizer bundle. + You should not need it, as its main use is for envisage support. + """ id = String() + name = String() + def create_optimizer(self, application, model): pass def create_model(self, model_data=None): pass - def create_communicator(self, model_data): + def create_communicator(self, application, model): pass diff --git a/force_bdss/mco/tests/__init__.py b/force_bdss/mco/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/force_bdss/mco/tests/test_base_multi_criteria_optimizer.py b/force_bdss/mco/tests/test_base_multi_criteria_optimizer.py new file mode 100644 index 0000000000000000000000000000000000000000..cab26edf81e35a21d5f0fd73d0669f2dea69a0d9 --- /dev/null +++ b/force_bdss/mco/tests/test_base_multi_criteria_optimizer.py @@ -0,0 +1,31 @@ +import unittest + +from force_bdss.mco.base_mco_model import BaseMCOModel +from force_bdss.mco.base_multi_criteria_optimizer import \ + BaseMultiCriteriaOptimizer +from force_bdss.mco.i_multi_criteria_optimizer_bundle import \ + IMultiCriteriaOptimizerBundle + +try: + import mock +except ImportError: + from unittest import mock + +from force_bdss.bdss_application import BDSSApplication + + +class DummyMCO(BaseMultiCriteriaOptimizer): + def run(self, *args, **kwargs): + pass + + +class TestBaseKPICalculator(unittest.TestCase): + def test_initialization(self): + bundle = mock.Mock(spec=IMultiCriteriaOptimizerBundle) + application = mock.Mock(spec=BDSSApplication) + model = mock.Mock(spec=BaseMCOModel) + mco = DummyMCO(bundle, application, model) + + self.assertEqual(mco.bundle, bundle) + self.assertEqual(mco.application, application) + self.assertEqual(mco.model, model) diff --git a/force_bdss/mco/tests/test_base_multi_criteria_optimizer_bundle.py b/force_bdss/mco/tests/test_base_multi_criteria_optimizer_bundle.py new file mode 100644 index 0000000000000000000000000000000000000000..de89488eb3ae413fb83236c2582618e43535a40f --- /dev/null +++ b/force_bdss/mco/tests/test_base_multi_criteria_optimizer_bundle.py @@ -0,0 +1,27 @@ +import unittest + +from force_bdss.mco.base_multi_criteria_optimizer_bundle import ( + BaseMultiCriteriaOptimizerBundle +) + + +class DummyMCOBundle(BaseMultiCriteriaOptimizerBundle): + id = "foo" + + name = "bar" + + def create_optimizer(self, application, model): + pass + + def create_model(self, model_data=None): + pass + + def create_communicator(self, model_data): + pass + + +class TestBaseDataSourceBundle(unittest.TestCase): + def test_initialization(self): + bundle = DummyMCOBundle() + self.assertEqual(bundle.id, 'foo') + self.assertEqual(bundle.name, 'bar')