Skip to content

Commit

Permalink
Test Processor invokes request, operation plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
numberoverzero committed Apr 7, 2015
1 parent 987f0a4 commit 3ef8a2c
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 13 deletions.
29 changes: 18 additions & 11 deletions pyservice/processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def __init__(self, obj, operation):
def __call__(self):
""" Entry point for external callers to begin processing """
if self.scope is None:
raise ValueError("Already processed request")
raise RuntimeError("Already processed request")
self.process_request()
return self.result

Expand Down Expand Up @@ -90,18 +90,9 @@ def _continue(self):
n = len(plugins)
self.index += 1

# We're still working through the plugins for this scope
if self.index < n:
if self.scope == "request":
plugins[self.index]()
elif self.scope == "operation":
plugins[self.index](self.request, self.response, self.context)
else:
raise ValueError("Unexpected scope '{}'".format(self.scope))

# We just processed the last plugin for this scope, either roll over
# to the next scope or invoke the function underneath it all
elif self.index == n:
if self.index == n:

# Determine the next scope and continue execution
next_scope = self.transitions.get(self.scope, missing)
Expand All @@ -114,6 +105,22 @@ def _continue(self):
else:
self._execute()

# We're still working through the plugins for this scope
else: # self.index < n
# This is an assert instead of an exception because there's no
# single best way to recover from walking off the end of the
# available plugins - return, increment scope, raise?
assert self.index < n, "index exceeded length of plugins"

if self.scope == "request":
plugins[self.index](self.context)
elif self.scope == "operation":
plugins[self.index](self.request, self.response, self.context)
# Don't know how to handle plugins of other types, this is likely
# a bug. Raise an error immediately instead of silently hanging
else: # pragma: no cover
raise ValueError("Unexpected scope '{}'".format(self.scope))

def _execute(self): # pragma: no cover
raise NotImplementedError("Subclasses must implement _execute.")

Expand Down
31 changes: 29 additions & 2 deletions tests/test_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
class PluginObj:
''' Mock client/service with plugins '''
def __init__(self):
self.plugins = {}
self.plugins = {
"request": [],
"operation": []
}


class TestProcessor(processors.Processor):
Expand All @@ -15,6 +18,7 @@ def __init__(self, operation, result):
obj = PluginObj()
super().__init__(obj, operation)
self.calls = collections.defaultdict(int)
self._plugin_obj = obj
self._result = result

def _execute(self):
Expand Down Expand Up @@ -53,5 +57,28 @@ def test_processor_multiple_calls():
process = TestProcessor("not used", "also not used")
process()

with pytest.raises(ValueError):
with pytest.raises(RuntimeError):
process()


def test_processor_plugin_scopes():
''' Ensure plugins in request and operation scopes are invoked '''
operation = "my_operation"
process = TestProcessor(operation, "not used")

called = []

def request_plugin(context):
called.append("request")
assert context.operation == operation
context.process_request()
process._plugin_obj.plugins["request"].append(request_plugin)

def operation_plugin(request, response, context):
called.append("operation")
assert context.operation == operation
context.process_request()
process._plugin_obj.plugins["operation"].append(operation_plugin)

process()
assert called == ["request", "operation"]

0 comments on commit 3ef8a2c

Please sign in to comment.