Skip to content
Snippets Groups Projects
Commit 2da2ae15 authored by martinRenou's avatar martinRenou
Browse files

Merge branch 'master' into update_documentation

parents 28082057 39350bc1
No related branches found
No related tags found
1 merge request!91Update the documentation
Showing
with 299 additions and 48 deletions
......@@ -28,4 +28,8 @@ from .notification_listeners.base_notification_listener import BaseNotificationL
from .notification_listeners.base_notification_listener_factory import BaseNotificationListenerFactory # noqa
from .notification_listeners.base_notification_listener_model import BaseNotificationListenerModel # noqa
from .local_traits import (ZMQSocketURL, Identifier) # noqa
from .ui_hooks.i_ui_hooks_factory import IUIHooksFactory # noqa
from .ui_hooks.base_ui_hooks_factory import BaseUIHooksFactory # noqa
from .ui_hooks.base_ui_hooks_manager import BaseUIHooksManager # noqa
from .local_traits import Identifier # noqa
......@@ -7,6 +7,7 @@ from .ids import ExtensionPointID
from .data_sources.i_data_source_factory import IDataSourceFactory
from .kpi.i_kpi_calculator_factory import IKPICalculatorFactory
from .mco.i_mco_factory import IMCOFactory
from .ui_hooks.i_ui_hooks_factory import IUIHooksFactory
class BaseExtensionPlugin(Plugin):
......@@ -46,3 +47,8 @@ class BaseExtensionPlugin(Plugin):
INotificationListenerFactory,
contributes_to=ExtensionPointID.NOTIFICATION_LISTENER_FACTORIES
)
ui_hooks_factories = List(
IUIHooksFactory,
contributes_to=ExtensionPointID.UI_HOOKS_FACTORIES
)
......@@ -3,6 +3,7 @@ from .dummy_notification_listener.dummy_notification_listener_factory import (
DummyNotificationListenerFactory
)
from .csv_extractor.csv_extractor_factory import CSVExtractorFactory
from .power_evaluator.power_evaluator_factory import PowerEvaluatorFactory
from .kpi_adder.kpi_adder_factory import KPIAdderFactory
from .dummy_dakota.dakota_factory import DummyDakotaFactory
from .dummy_data_source.dummy_data_source_factory import DummyDataSourceFactory
......@@ -16,7 +17,8 @@ class DummyPlugin(BaseExtensionPlugin):
def _data_source_factories_default(self):
return [DummyDataSourceFactory(self),
CSVExtractorFactory(self)]
CSVExtractorFactory(self),
PowerEvaluatorFactory(self)]
def _mco_factories_default(self):
return [DummyDakotaFactory(self)]
......
import math
from force_bdss.api import BaseDataSource, DataValue
from force_bdss.core.slot import Slot
class PowerEvaluatorDataSource(BaseDataSource):
def run(self, model, parameters):
x = parameters[0].value
return [
DataValue(
type=model.cuba_type_out,
value=math.pow(x, model.power)
)]
def slots(self, model):
return (
(
Slot(type=model.cuba_type_in),
),
(
Slot(type=model.cuba_type_out),
)
)
from traits.api import String
from force_bdss.api import factory_id, BaseDataSourceFactory
from .power_evaluator_model import PowerEvaluatorModel
from .power_evaluator_data_source import PowerEvaluatorDataSource
class PowerEvaluatorFactory(BaseDataSourceFactory):
id = String(factory_id("enthought", "power_evaluator"))
name = String("Power Evaluator")
def create_model(self, model_data=None):
if model_data is None:
model_data = {}
return PowerEvaluatorModel(self, **model_data)
def create_data_source(self):
return PowerEvaluatorDataSource(self)
from traits.api import Float, String, on_trait_change
from force_bdss.api import BaseDataSourceModel
class PowerEvaluatorModel(BaseDataSourceModel):
power = Float(1.0)
cuba_type_in = String()
cuba_type_out = String()
@on_trait_change("cuba_type_in,cuba_type_out")
def _notify_changes_slots(self):
self.changes_slots = True
import unittest
from force_bdss.core.data_value import DataValue
from force_bdss.core.slot import Slot
from force_bdss.core_plugins.dummy.power_evaluator.power_evaluator_data_source import PowerEvaluatorDataSource # noqa
from force_bdss.core_plugins.dummy.power_evaluator.power_evaluator_model import PowerEvaluatorModel # noqa
from force_bdss.data_sources.base_data_source_factory import \
BaseDataSourceFactory
try:
import mock
except ImportError:
from unittest import mock
class TestPowerEvaluatorDataSource(unittest.TestCase):
def setUp(self):
self.factory = mock.Mock(spec=BaseDataSourceFactory)
def test_initialization(self):
ds = PowerEvaluatorDataSource(self.factory)
self.assertEqual(ds.factory, self.factory)
def test_run(self):
ds = PowerEvaluatorDataSource(self.factory)
model = PowerEvaluatorModel(self.factory)
model.power = 2
mock_params = [DataValue(value=5, type="METER")]
result = ds.run(model, mock_params)
self.assertIsInstance(result, list)
self.assertEqual(len(result), 1)
self.assertIsInstance(result[0], DataValue)
self.assertEqual(result[0].value, 25)
def test_run_with_exception(self):
ds = PowerEvaluatorDataSource(self.factory)
model = PowerEvaluatorModel(self.factory)
mock_params = []
model.power = 3
with self.assertRaises(IndexError):
ds.run(model, mock_params)
def test_slots(self):
ds = PowerEvaluatorDataSource(self.factory)
model = PowerEvaluatorModel(self.factory)
slots = ds.slots(model)
self.assertEqual(len(slots), 2)
self.assertEqual(len(slots[0]), 1)
self.assertEqual(len(slots[1]), 1)
self.assertIsInstance(slots[0][0], Slot)
self.assertIsInstance(slots[1][0], Slot)
model.cuba_type_in = 'METER'
model.cuba_type_out = 'METER'
slots = ds.slots(model)
self.assertEqual(slots[0][0].type, 'METER')
self.assertEqual(slots[1][0].type, 'METER')
import unittest
from force_bdss.core_plugins.dummy.tests.data_source_factory_test_mixin \
import DataSourceFactoryTestMixin
from force_bdss.core_plugins.dummy.power_evaluator.power_evaluator_factory import PowerEvaluatorFactory # noqa
from force_bdss.core_plugins.dummy.power_evaluator.power_evaluator_data_source import PowerEvaluatorDataSource # noqa
from force_bdss.core_plugins.dummy.power_evaluator.power_evaluator_model import PowerEvaluatorModel # noqa
class TestPowerEvaluatorFactory(DataSourceFactoryTestMixin,
unittest.TestCase):
@property
def factory_class(self):
return PowerEvaluatorFactory
@property
def model_class(self):
return PowerEvaluatorModel
@property
def data_source_class(self):
return PowerEvaluatorDataSource
......@@ -9,6 +9,7 @@ from .data_sources.i_data_source_factory import (
IDataSourceFactory)
from .kpi.i_kpi_calculator_factory import IKPICalculatorFactory
from .mco.i_mco_factory import IMCOFactory
from .ui_hooks.i_ui_hooks_factory import IUIHooksFactory
FACTORY_REGISTRY_PLUGIN_ID = "force.bdss.plugins.factory_registry"
......@@ -50,6 +51,14 @@ class FactoryRegistryPlugin(Plugin):
id=ExtensionPointID.NOTIFICATION_LISTENER_FACTORIES
)
#: UI Hooks are pluggable entities holding methods that are called
#: at specific moments in the UI application lifetime. They can be used
#: to inject special behaviors at those moments.
ui_hooks_factories = ExtensionPoint(
List(IUIHooksFactory),
id=ExtensionPointID.UI_HOOKS_FACTORIES
)
def data_source_factory_by_id(self, id):
"""Finds a given data source factory by means of its id.
The ID is as obtained by the function factory_id() in the
......@@ -140,13 +149,13 @@ class FactoryRegistryPlugin(Plugin):
def notification_listener_factory_by_id(self, id):
"""Finds a given notification listener by means of its id.
The ID is as obtained by the function bundle_id() in the
The ID is as obtained by the function factory_id() in the
plugin api.
Parameters
----------
id: str
The identifier returned by the bundle_id() function.
The identifier returned by the factory_id() function.
Raises
------
......
......@@ -14,6 +14,7 @@ class ExtensionPointID:
KPI_CALCULATOR_FACTORIES = 'force.bdss.kpi_calculator.factories'
NOTIFICATION_LISTENER_FACTORIES = \
'force.bdss.notification_listener.factories'
UI_HOOKS_FACTORIES = 'force.bdss.ui_hooks.factories'
def factory_id(producer, identifier):
......
import re
from traits.api import Regex, BaseStr, String
from traits.api import Regex, String
#: Used for variable names, but allow also empty string as it's the default
#: case and it will be present if the workflow is saved before actually
#: specifying the value.
Identifier = Regex(regex="(^[^\d\W]\w*\Z|^\Z)")
class ZMQSocketURL(BaseStr):
def validate(self, object, name, value):
super(ZMQSocketURL, self).validate(object, name, value)
m = re.match(
"tcp://(\\d{1,3})\.(\\d{1,3})\.(\\d{1,3})\.(\\d{1,3}):(\\d+)",
value)
if m is None:
self.error(object, name, value)
a, b, c, d, port = m.groups()
if not all(map(lambda x: 0 <= int(x) <= 255, (a, b, c, d))):
self.error(object, name, value)
if not (1 <= int(port) <= 65535):
self.error(object, name, value)
return value
#: Identifies a CUBA type with its key. At the moment a String with
#: no validation, but will come later.
CUBAType = String()
import unittest
from traits.api import HasStrictTraits, TraitError
from force_bdss.local_traits import Identifier, CUBAType, ZMQSocketURL
from force_bdss.local_traits import Identifier, CUBAType
class Traited(HasStrictTraits):
val = Identifier()
cuba = CUBAType()
socket_url = ZMQSocketURL()
class TestLocalTraits(unittest.TestCase):
......@@ -26,22 +25,3 @@ class TestLocalTraits(unittest.TestCase):
c = Traited()
c.cuba = "PRESSURE"
self.assertEqual(c.cuba, "PRESSURE")
def test_zmq_socket_url(self):
c = Traited()
for working in ["tcp://127.0.0.1:12345",
"tcp://255.255.255.255:65535",
"tcp://1.1.1.1:65535"]:
c.socket_url = working
self.assertEqual(c.socket_url, working)
for broken in ["tcp://270.0.0.1:12345",
"tcp://0.270.0.1:12345",
"tcp://0.0.270.1:12345",
"tcp://0.0.0.270:12345",
"url://255.255.255.255:65535",
"whatever",
"tcp://1.1.1.1:100000"]:
with self.assertRaises(TraitError):
c.socket_url = broken
import abc
from traits.api import ABCHasStrictTraits, Instance, String, provides
from envisage.plugin import Plugin
from .i_ui_hooks_factory import IUIHooksFactory
@provides(IUIHooksFactory)
class BaseUIHooksFactory(ABCHasStrictTraits):
"""Base class for UIHooksFactory.
UI Hooks are extensions that perform actions associated to specific
moments of the UI lifetime.
"""
#: identifier of the factory
id = String()
#: Name of the factory. User friendly for UI
name = String()
#: A reference to the containing plugin
plugin = Instance(Plugin)
def __init__(self, plugin, *args, **kwargs):
"""Initializes the instance.
Parameters
----------
plugin: Plugin
The plugin that holds this factory.
"""
self.plugin = plugin
super(BaseUIHooksFactory, self).__init__(*args, **kwargs)
@abc.abstractmethod
def create_ui_hooks_manager(self):
"""Creates an instance of the hook manager.
The hooks manager contains a set of methods that are applicable in
various moments of the UI application lifetime.
Returns
-------
BaseUIHooksManager
"""
from traits.api import HasStrictTraits, Instance
from .i_ui_hooks_factory import IUIHooksFactory
class BaseUIHooksManager(HasStrictTraits):
#: A reference to the factory
factory = Instance(IUIHooksFactory)
def __init__(self, factory, *args, **kwargs):
"""Initializes the UI Hooks manager.
Parameters
----------
factory: BaseUIHooksFactory
The factory this UI Hooks manager belongs to
"""
self.factory = factory
super(BaseUIHooksManager, self).__init__(*args, **kwargs)
def before_execution(self, task):
"""Hook that is called before execution of a given evaluation.
Gives a chance to perform operations before the temporary file is
created with its contents and the calculation invoked.
Parameters
----------
task:
The pyface envisage task.
"""
def after_execution(self, task):
"""Hook that is called after execution of a given evaluation.
Gives a chance to perform operations after the calculation finished.
Parameters
----------
task:
The pyface envisage task.
"""
def before_save(self, task):
"""Hook that is called just before saving a given model to disk
in response to a user action. This does not apply to saving of
temporary files before execution.
Parameters
----------
task:
The pyface envisage task
"""
from traits.api import Interface, String, Instance
from envisage.plugin import Plugin
class IUIHooksFactory(Interface):
"""Envisage required interface for the BaseUIHooksFactory.
You should not need to use this directly.
Refer to the BaseUIHooksFactory for documentation.
"""
id = String()
name = String()
plugin = Instance(Plugin)
def create_hook_manager(self):
""""""
import unittest
try:
import mock
except ImportError:
from unittest import mock
from envisage.api import Plugin
from ..base_ui_hooks_factory import BaseUIHooksFactory
class NullUIHooksFactory(BaseUIHooksFactory):
def create_ui_hooks_manager(self):
return None
class TestBaseUIHooksFactory(unittest.TestCase):
def test_initialize(self):
mock_plugin = mock.Mock(spec=Plugin)
factory = NullUIHooksFactory(plugin=mock_plugin)
self.assertEqual(factory.plugin, mock_plugin)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment