Commit 5c583b62 authored by Matt Todd's avatar Matt Todd

Setup pipeline instrumentation, with name, test

Add an `instrumentation_name` attribute to the Pipeline. Events report
this name for the originating pipeline.

Add `setup_instrumentation` method to the Pipeline. Sets the
instrumentation name and service.
parent 88421ed1
......@@ -64,6 +64,12 @@ module HTML
# Set an ActiveSupport::Notifications compatible object to enable.
attr_accessor :instrumentation_service
# Public: String name for this Pipeline. Defaults to Class name.
attr_writer :instrumentation_name
def instrumentation_name
@instrumentation_name || self.class.name
end
class << self
# Public: Default instrumentation service for new pipeline objects.
attr_accessor :default_instrumentation_service
......@@ -94,7 +100,7 @@ module HTML
context = context.freeze
result ||= @result_class.new
payload = default_payload :filters => @filters.map(&:name),
:doc => html, :context => context, :result => result
:context => context, :result => result
instrument "call_pipeline.html_pipeline", payload do
result[:output] =
@filters.inject(html) do |doc, filter|
......@@ -111,12 +117,40 @@ module HTML
# Returns the result of the filter.
def perform_filter(filter, doc, context, result)
payload = default_payload :filter => filter.name,
:doc => doc, :context => context, :result => result
:context => context, :result => result
instrument "call_filter.html_pipeline", payload do
filter.call(doc, context, result)
end
end
# Like call but guarantee the value returned is a DocumentFragment.
# Pipelines may return a DocumentFragment or a String. Callers that need a
# DocumentFragment should use this method.
def to_document(input, context = {}, result = nil)
result = call(input, context, result)
HTML::Pipeline.parse(result[:output])
end
# Like call but guarantee the value returned is a string of HTML markup.
def to_html(input, context = {}, result = nil)
result = call(input, context, result = nil)
output = result[:output]
if output.respond_to?(:to_html)
output.to_html
else
output.to_s
end
end
# Public: setup instrumentation for this pipeline.
#
# Returns nothing.
def setup_instrumentation(name = nil, service = nil)
self.instrumentation_name = name
self.instrumentation_service =
service || self.class.default_instrumentation_service
end
# Internal: if the `instrumentation_service` object is set, instruments the
# block, otherwise the block is ran without instrumentation.
#
......@@ -135,26 +169,7 @@ module HTML
#
# Returns a Hash.
def default_payload(payload = {})
{:pipeline => self.class.name}.merge(payload)
end
# Like call but guarantee the value returned is a DocumentFragment.
# Pipelines may return a DocumentFragment or a String. Callers that need a
# DocumentFragment should use this method.
def to_document(input, context = {}, result = nil)
result = call(input, context, result)
HTML::Pipeline.parse(result[:output])
end
# Like call but guarantee the value returned is a string of HTML markup.
def to_html(input, context = {}, result = nil)
result = call(input, context, result = nil)
output = result[:output]
if output.respond_to?(:to_html)
output.to_html
else
output.to_s
end
{:pipeline => instrumentation_name}.merge(payload)
end
end
end
......
......@@ -12,5 +12,6 @@ class MockedInstrumentationService
end
def subscribe(event)
@subscribe = event
@events
end
end
......@@ -17,29 +17,27 @@ class HTML::PipelineTest < Test::Unit::TestCase
def test_filter_instrumentation
service = MockedInstrumentationService.new
service.subscribe "call_filter.html_pipeline"
events = service.subscribe "call_filter.html_pipeline"
@pipeline.instrumentation_service = service
filter(body = "hello")
event, payload, res = service.events.pop
event, payload, res = events.pop
assert event, "event expected"
assert_equal "call_filter.html_pipeline", event
assert_equal TestFilter.name, payload[:filter]
assert_equal @pipeline.class.name, payload[:pipeline]
assert_equal body, payload[:doc]
assert_equal body.reverse, payload[:result][:output]
end
def test_pipeline_instrumentation
service = MockedInstrumentationService.new
service.subscribe "call_pipeline.html_pipeline"
events = service.subscribe "call_pipeline.html_pipeline"
@pipeline.instrumentation_service = service
filter(body = "hello")
event, payload, res = service.events.pop
event, payload, res = events.pop
assert event, "event expected"
assert_equal "call_pipeline.html_pipeline", event
assert_equal @pipeline.filters.map(&:name), payload[:filters]
assert_equal @pipeline.class.name, payload[:pipeline]
assert_equal body, payload[:doc]
assert_equal body.reverse, payload[:result][:output]
end
......@@ -52,6 +50,24 @@ class HTML::PipelineTest < Test::Unit::TestCase
Pipeline.default_instrumentation_service = nil
end
def test_setup_instrumentation
assert_nil @pipeline.instrumentation_service
service = MockedInstrumentationService.new
events = service.subscribe "call_pipeline.html_pipeline"
@pipeline.setup_instrumentation name = 'foo', service
assert_equal service, @pipeline.instrumentation_service
assert_equal name, @pipeline.instrumentation_name
filter(body = 'foo')
event, payload, res = events.pop
assert event, "expected event"
assert_equal name, payload[:pipeline]
assert_equal body.reverse, payload[:result][:output]
end
def filter(input)
@pipeline.call(input)
end
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment