mirror of
https://github.com/wassname/sloth.git
synced 2026-09-09 11:35:32 +08:00
- seperate items and inserters
- use dicts for ITEMS and INSERTERS
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
class Factory:
|
||||
"""
|
||||
A generic factory for both items and inserters.
|
||||
"""
|
||||
|
||||
def __init__(self, items=None):
|
||||
"""
|
||||
Constructor.
|
||||
|
||||
Parameters
|
||||
==========
|
||||
items: dict
|
||||
Mapping from type to python callable. If not None, all mappings
|
||||
will be registered with the factory.
|
||||
"""
|
||||
self.items_ = {}
|
||||
|
||||
if items is not None:
|
||||
for _type, item in items.iteritems():
|
||||
self.register(_type, item, replace=True)
|
||||
|
||||
def register(self, _type, item, replace=False):
|
||||
"""
|
||||
Register a new type-item mapping.
|
||||
|
||||
Parameters
|
||||
==========
|
||||
|
||||
|
||||
"""
|
||||
_type = _type.lower()
|
||||
|
||||
if _type in self.items_ and not replace:
|
||||
raise Exception("Type %s already has an item: %s" % \
|
||||
(_type, str(self.items_[_type])))
|
||||
else:
|
||||
self.items_[_type] = item
|
||||
|
||||
def clear(self, _type=None):
|
||||
"""
|
||||
Remove a type-item mapping.
|
||||
|
||||
Parameters
|
||||
==========
|
||||
_type: str
|
||||
Type for which the mapping should be removed. If None, all
|
||||
mappings will be removed.
|
||||
"""
|
||||
if _type is None:
|
||||
self.items_ = {}
|
||||
else:
|
||||
_type = _type.lower()
|
||||
if _type in self.items_:
|
||||
del self.items_[_type]
|
||||
|
||||
def create(self, _type, *args, **kwargs):
|
||||
"""
|
||||
Create a new objectt.
|
||||
|
||||
Parameters
|
||||
==========
|
||||
_type: str
|
||||
Type for which a new object should be created.
|
||||
|
||||
All further arguments will be passed to the constructor/creating function
|
||||
of the mapping.
|
||||
|
||||
Returns
|
||||
=======
|
||||
Newly created object. If for the given type no mapping exists, this
|
||||
function returns ``None``.
|
||||
"""
|
||||
_type = _type.lower()
|
||||
|
||||
if _type not in self.items_:
|
||||
return None
|
||||
item = self.items_[_type]
|
||||
if item is None:
|
||||
return None
|
||||
return item(*args, **kwargs)
|
||||
|
||||
### testing
|
||||
import pytest
|
||||
class MockupRectItem: pass
|
||||
class MockupPointItem: pass
|
||||
class MockupPolygonItem: pass
|
||||
|
||||
def _create_factory():
|
||||
itemfactory = Factory({'point': MockupPointItem,
|
||||
'polygon': MockupPolygonItem})
|
||||
itemfactory.register('rect', MockupRectItem)
|
||||
|
||||
return itemfactory
|
||||
|
||||
def test_register():
|
||||
itemfactory = _create_factory()
|
||||
|
||||
item = itemfactory.create('rect')
|
||||
assert isinstance(item, MockupRectItem)
|
||||
item = itemfactory.create('point')
|
||||
assert isinstance(item, MockupPointItem)
|
||||
item = itemfactory.create('polygon')
|
||||
assert isinstance(item, MockupPolygonItem)
|
||||
item = itemfactory.create('polygon2')
|
||||
assert item is None
|
||||
|
||||
def test_register_fail():
|
||||
itemfactory = _create_factory()
|
||||
with pytest.raises(Exception):
|
||||
itemfactory.register('rect', MockupRectItem)
|
||||
|
||||
def test_register_replace():
|
||||
itemfactory = _create_factory()
|
||||
|
||||
itemfactory.register('rect', MockupPolygonItem, replace=True)
|
||||
item = itemfactory.create('rect')
|
||||
assert isinstance(item, MockupPolygonItem)
|
||||
|
||||
def test_clear():
|
||||
itemfactory = _create_factory()
|
||||
|
||||
item = itemfactory.create('rect')
|
||||
assert isinstance(item, MockupRectItem)
|
||||
itemfactory.clear('rect')
|
||||
item = itemfactory.create('rect')
|
||||
assert item is None
|
||||
|
||||
item = itemfactory.create('point')
|
||||
assert isinstance(item, MockupPointItem)
|
||||
item = itemfactory.create('polygon')
|
||||
assert isinstance(item, MockupPolygonItem)
|
||||
itemfactory.clear()
|
||||
assert itemfactory.create('point') is None
|
||||
assert itemfactory.create('polygon') is None
|
||||
|
||||
Reference in New Issue
Block a user