html-pipeline 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +5 -0
- data/README.md +24 -20
- data/lib/html/pipeline.rb +42 -14
- data/lib/html/pipeline/version.rb +1 -1
- data/test/helpers/mocked_instrumentation_service.rb +3 -1
- data/test/html/pipeline_test.rb +29 -7
- metadata +2 -2
    
        data/CHANGELOG.md
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -2,7 +2,8 @@ | |
| 2 2 |  | 
| 3 3 | 
             
            GitHub HTML processing filters and utilities. This module includes a small
         | 
| 4 4 | 
             
            framework for defining DOM based content filters and applying them to user
         | 
| 5 | 
            -
            provided content.
         | 
| 5 | 
            +
            provided content. Read an introduction about this project in
         | 
| 6 | 
            +
            [this blog post](https://github.com/blog/1311-html-pipeline-chainable-content-filters).
         | 
| 6 7 |  | 
| 7 8 | 
             
            ## Installation
         | 
| 8 9 |  | 
| @@ -197,9 +198,10 @@ Pipeline.new [ RootRelativeFilter ], { :base_url => 'http://somehost.com' } | |
| 197 198 |  | 
| 198 199 | 
             
            ## Instrumenting
         | 
| 199 200 |  | 
| 200 | 
            -
             | 
| 201 | 
            -
            [ActiveSupport::Notifications] | 
| 202 | 
            -
             | 
| 201 | 
            +
            Filters and Pipelines can be set up to be instrumented when called. The pipeline
         | 
| 202 | 
            +
            must be setup with an [ActiveSupport::Notifications]
         | 
| 203 | 
            +
            (http://api.rubyonrails.org/classes/ActiveSupport/Notifications.html)
         | 
| 204 | 
            +
            compatible service object and a name. New pipeline objects will default to the
         | 
| 203 205 | 
             
            `HTML::Pipeline.default_instrumentation_service` object.
         | 
| 204 206 |  | 
| 205 207 | 
             
            ``` ruby
         | 
| @@ -208,10 +210,12 @@ service = ActiveSupport::Notifications | |
| 208 210 |  | 
| 209 211 | 
             
            # instrument a specific pipeline
         | 
| 210 212 | 
             
            pipeline = HTML::Pipeline.new [MarkdownFilter], context
         | 
| 211 | 
            -
            pipeline. | 
| 213 | 
            +
            pipeline.setup_instrumentation "MarkdownPipeline", service
         | 
| 212 214 |  | 
| 213 | 
            -
            # or  | 
| 215 | 
            +
            # or set default instrumentation service for all new pipelines
         | 
| 214 216 | 
             
            HTML::Pipeline.default_instrumentation_service = service
         | 
| 217 | 
            +
            pipeline = HTML::Pipeline.new [MarkdownFilter], context
         | 
| 218 | 
            +
            pipeline.setup_instrumentation "MarkdownPipeline"
         | 
| 215 219 | 
             
            ```
         | 
| 216 220 |  | 
| 217 221 | 
             
            Filters are instrumented when they are run through the pipeline. A
         | 
| @@ -221,7 +225,11 @@ instrumentation call. | |
| 221 225 |  | 
| 222 226 | 
             
            ``` ruby
         | 
| 223 227 | 
             
            service.subscribe "call_filter.html_pipeline" do |event, start, ending, transaction_id, payload|
         | 
| 228 | 
            +
              payload[:pipeline] #=> "MarkdownPipeline", set with `setup_instrumentation`
         | 
| 224 229 | 
             
              payload[:filter] #=> "MarkdownFilter"
         | 
| 230 | 
            +
              payload[:context] #=> context Hash
         | 
| 231 | 
            +
              payload[:result] #=> instance of result class
         | 
| 232 | 
            +
              payload[:result][:output] #=> output HTML String or Nokogiri::DocumentFragment
         | 
| 225 233 | 
             
            end
         | 
| 226 234 | 
             
            ```
         | 
| 227 235 |  | 
| @@ -229,10 +237,19 @@ The full pipeline is also instrumented: | |
| 229 237 |  | 
| 230 238 | 
             
            ``` ruby
         | 
| 231 239 | 
             
            service.subscribe "call_pipeline.html_pipeline" do |event, start, ending, transaction_id, payload|
         | 
| 240 | 
            +
              payload[:pipeline] #=> "MarkdownPipeline", set with `setup_instrumentation`
         | 
| 232 241 | 
             
              payload[:filters] #=> ["MarkdownFilter"]
         | 
| 242 | 
            +
              payload[:doc] #=> HTML String or Nokogiri::DocumentFragment
         | 
| 243 | 
            +
              payload[:context] #=> context Hash
         | 
| 244 | 
            +
              payload[:result] #=> instance of result class
         | 
| 245 | 
            +
              payload[:result][:output] #=> output HTML String or Nokogiri::DocumentFragment
         | 
| 233 246 | 
             
            end
         | 
| 234 247 | 
             
            ```
         | 
| 235 248 |  | 
| 249 | 
            +
            ## Documentation
         | 
| 250 | 
            +
             | 
| 251 | 
            +
            Full reference documentation can be [found here](http://rubydoc.info/gems/html-pipeline/frames).
         | 
| 252 | 
            +
             | 
| 236 253 | 
             
            ## Development
         | 
| 237 254 |  | 
| 238 255 | 
             
            To see what has changed in recent versions, see the [CHANGELOG](https://github.com/jch/html-pipeline/blob/master/CHANGELOG.md).
         | 
| @@ -250,21 +267,8 @@ rake test | |
| 250 267 | 
             
            4. Push to the branch (`git push origin my-new-feature`)
         | 
| 251 268 | 
             
            5. Create new [Pull Request](https://help.github.com/articles/using-pull-requests)
         | 
| 252 269 |  | 
| 253 | 
            -
             | 
| 254 | 
            -
            ## TODO
         | 
| 255 | 
            -
             | 
| 256 | 
            -
            * test whether emoji filter works on heroku
         | 
| 257 | 
            -
            * test whether nokogiri monkey patch is still necessary
         | 
| 258 | 
            -
             | 
| 259 270 | 
             
            ## Contributors
         | 
| 260 271 |  | 
| 261 | 
            -
             | 
| 262 | 
            -
            * [Jake Boxer](mailto:jake@github.com)
         | 
| 263 | 
            -
            * [Joshua Peek](mailto:josh@joshpeek.com)
         | 
| 264 | 
            -
            * [Kyle Neath](mailto:kneath@gmail.com)
         | 
| 265 | 
            -
            * [Rob Sanheim](mailto:rsanheim@gmail.com)
         | 
| 266 | 
            -
            * [Simon Rozet](mailto:simon@rozet.name)
         | 
| 267 | 
            -
            * [Vicent Martí](mailto:tanoku@gmail.com)
         | 
| 268 | 
            -
            * [Risk :danger: Olson](mailto:technoweenie@gmail.com)
         | 
| 272 | 
            +
            Thanks to all of [these contributors](https://github.com/jch/html-pipeline/graphs/contributors).
         | 
| 269 273 |  | 
| 270 274 | 
             
            Project is a member of the [OSS Manifesto](http://ossmanifesto.org/).
         | 
    
        data/lib/html/pipeline.rb
    CHANGED
    
    | @@ -25,7 +25,6 @@ module HTML | |
| 25 25 | 
             
              #                   some semblance of type safety.
         | 
| 26 26 | 
             
              class Pipeline
         | 
| 27 27 | 
             
                autoload :VERSION,               'html/pipeline/version'
         | 
| 28 | 
            -
                autoload :Pipeline,              'html/pipeline/pipeline'
         | 
| 29 28 | 
             
                autoload :Filter,                'html/pipeline/filter'
         | 
| 30 29 | 
             
                autoload :AbsoluteSourceFilter,  'html/pipeline/absolute_source_filter'
         | 
| 31 30 | 
             
                autoload :BodyContent,           'html/pipeline/body_content'
         | 
| @@ -65,6 +64,12 @@ module HTML | |
| 65 64 | 
             
                # Set an ActiveSupport::Notifications compatible object to enable.
         | 
| 66 65 | 
             
                attr_accessor :instrumentation_service
         | 
| 67 66 |  | 
| 67 | 
            +
                # Public: String name for this Pipeline. Defaults to Class name.
         | 
| 68 | 
            +
                attr_writer :instrumentation_name
         | 
| 69 | 
            +
                def instrumentation_name
         | 
| 70 | 
            +
                  @instrumentation_name || self.class.name
         | 
| 71 | 
            +
                end
         | 
| 72 | 
            +
             | 
| 68 73 | 
             
                class << self
         | 
| 69 74 | 
             
                  # Public: Default instrumentation service for new pipeline objects.
         | 
| 70 75 | 
             
                  attr_accessor :default_instrumentation_service
         | 
| @@ -94,7 +99,9 @@ module HTML | |
| 94 99 | 
             
                  context = @default_context.merge(context)
         | 
| 95 100 | 
             
                  context = context.freeze
         | 
| 96 101 | 
             
                  result ||= @result_class.new
         | 
| 97 | 
            -
                   | 
| 102 | 
            +
                  payload = default_payload :filters => @filters.map(&:name),
         | 
| 103 | 
            +
                    :context => context, :result => result
         | 
| 104 | 
            +
                  instrument "call_pipeline.html_pipeline", payload do
         | 
| 98 105 | 
             
                    result[:output] =
         | 
| 99 106 | 
             
                      @filters.inject(html) do |doc, filter|
         | 
| 100 107 | 
             
                        perform_filter(filter, doc, context, result)
         | 
| @@ -109,22 +116,13 @@ module HTML | |
| 109 116 | 
             
                #
         | 
| 110 117 | 
             
                # Returns the result of the filter.
         | 
| 111 118 | 
             
                def perform_filter(filter, doc, context, result)
         | 
| 112 | 
            -
                   | 
| 119 | 
            +
                  payload = default_payload :filter => filter.name,
         | 
| 120 | 
            +
                    :context => context, :result => result
         | 
| 121 | 
            +
                  instrument "call_filter.html_pipeline", payload do
         | 
| 113 122 | 
             
                    filter.call(doc, context, result)
         | 
| 114 123 | 
             
                  end
         | 
| 115 124 | 
             
                end
         | 
| 116 125 |  | 
| 117 | 
            -
                # Internal: if the `instrumentation_service` object is set, instruments the
         | 
| 118 | 
            -
                # block, otherwise the block is ran without instrumentation.
         | 
| 119 | 
            -
                #
         | 
| 120 | 
            -
                # Returns the result of the provided block.
         | 
| 121 | 
            -
                def instrument(event, payload = nil)
         | 
| 122 | 
            -
                  return yield unless instrumentation_service
         | 
| 123 | 
            -
                  instrumentation_service.instrument event, payload do
         | 
| 124 | 
            -
                    yield
         | 
| 125 | 
            -
                  end
         | 
| 126 | 
            -
                end
         | 
| 127 | 
            -
             | 
| 128 126 | 
             
                # Like call but guarantee the value returned is a DocumentFragment.
         | 
| 129 127 | 
             
                # Pipelines may return a DocumentFragment or a String. Callers that need a
         | 
| 130 128 | 
             
                # DocumentFragment should use this method.
         | 
| @@ -143,6 +141,36 @@ module HTML | |
| 143 141 | 
             
                    output.to_s
         | 
| 144 142 | 
             
                  end
         | 
| 145 143 | 
             
                end
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                # Public: setup instrumentation for this pipeline.
         | 
| 146 | 
            +
                #
         | 
| 147 | 
            +
                # Returns nothing.
         | 
| 148 | 
            +
                def setup_instrumentation(name = nil, service = nil)
         | 
| 149 | 
            +
                  self.instrumentation_name = name
         | 
| 150 | 
            +
                  self.instrumentation_service =
         | 
| 151 | 
            +
                    service || self.class.default_instrumentation_service
         | 
| 152 | 
            +
                end
         | 
| 153 | 
            +
             | 
| 154 | 
            +
                # Internal: if the `instrumentation_service` object is set, instruments the
         | 
| 155 | 
            +
                # block, otherwise the block is ran without instrumentation.
         | 
| 156 | 
            +
                #
         | 
| 157 | 
            +
                # Returns the result of the provided block.
         | 
| 158 | 
            +
                def instrument(event, payload = nil)
         | 
| 159 | 
            +
                  payload ||= default_payload
         | 
| 160 | 
            +
                  return yield(payload) unless instrumentation_service
         | 
| 161 | 
            +
                  instrumentation_service.instrument event, payload do |payload|
         | 
| 162 | 
            +
                    yield payload
         | 
| 163 | 
            +
                  end
         | 
| 164 | 
            +
                end
         | 
| 165 | 
            +
             | 
| 166 | 
            +
                # Internal: Default payload for instrumentation.
         | 
| 167 | 
            +
                #
         | 
| 168 | 
            +
                # Accepts a Hash of additional payload data to be merged.
         | 
| 169 | 
            +
                #
         | 
| 170 | 
            +
                # Returns a Hash.
         | 
| 171 | 
            +
                def default_payload(payload = {})
         | 
| 172 | 
            +
                  {:pipeline => instrumentation_name}.merge(payload)
         | 
| 173 | 
            +
                end
         | 
| 146 174 | 
             
              end
         | 
| 147 175 | 
             
            end
         | 
| 148 176 |  | 
| @@ -5,11 +5,13 @@ class MockedInstrumentationService | |
| 5 5 | 
             
                subscribe event
         | 
| 6 6 | 
             
              end
         | 
| 7 7 | 
             
              def instrument(event, payload = nil)
         | 
| 8 | 
            -
                 | 
| 8 | 
            +
                payload ||= {}
         | 
| 9 | 
            +
                res = yield payload
         | 
| 9 10 | 
             
                events << [event, payload, res] if @subscribe == event
         | 
| 10 11 | 
             
                res
         | 
| 11 12 | 
             
              end
         | 
| 12 13 | 
             
              def subscribe(event)
         | 
| 13 14 | 
             
                @subscribe = event
         | 
| 15 | 
            +
                @events
         | 
| 14 16 | 
             
              end
         | 
| 15 17 | 
             
            end
         | 
    
        data/test/html/pipeline_test.rb
    CHANGED
    
    | @@ -5,7 +5,7 @@ class HTML::PipelineTest < Test::Unit::TestCase | |
| 5 5 | 
             
              Pipeline = HTML::Pipeline
         | 
| 6 6 | 
             
              class TestFilter
         | 
| 7 7 | 
             
                def self.call(input, context, result)
         | 
| 8 | 
            -
                  input
         | 
| 8 | 
            +
                  input.reverse
         | 
| 9 9 | 
             
                end
         | 
| 10 10 | 
             
              end
         | 
| 11 11 |  | 
| @@ -17,24 +17,28 @@ class HTML::PipelineTest < Test::Unit::TestCase | |
| 17 17 |  | 
| 18 18 | 
             
              def test_filter_instrumentation
         | 
| 19 19 | 
             
                service = MockedInstrumentationService.new
         | 
| 20 | 
            -
                service.subscribe "call_filter.html_pipeline"
         | 
| 20 | 
            +
                events = service.subscribe "call_filter.html_pipeline"
         | 
| 21 21 | 
             
                @pipeline.instrumentation_service = service
         | 
| 22 | 
            -
                filter("hello")
         | 
| 23 | 
            -
                event, payload, res =  | 
| 22 | 
            +
                filter(body = "hello")
         | 
| 23 | 
            +
                event, payload, res = events.pop
         | 
| 24 24 | 
             
                assert event, "event expected"
         | 
| 25 25 | 
             
                assert_equal "call_filter.html_pipeline", event
         | 
| 26 26 | 
             
                assert_equal TestFilter.name, payload[:filter]
         | 
| 27 | 
            +
                assert_equal @pipeline.class.name, payload[:pipeline]
         | 
| 28 | 
            +
                assert_equal body.reverse, payload[:result][:output]
         | 
| 27 29 | 
             
              end
         | 
| 28 30 |  | 
| 29 31 | 
             
              def test_pipeline_instrumentation
         | 
| 30 32 | 
             
                service = MockedInstrumentationService.new
         | 
| 31 | 
            -
                service.subscribe "call_pipeline.html_pipeline"
         | 
| 33 | 
            +
                events = service.subscribe "call_pipeline.html_pipeline"
         | 
| 32 34 | 
             
                @pipeline.instrumentation_service = service
         | 
| 33 | 
            -
                filter("hello")
         | 
| 34 | 
            -
                event, payload, res =  | 
| 35 | 
            +
                filter(body = "hello")
         | 
| 36 | 
            +
                event, payload, res = events.pop
         | 
| 35 37 | 
             
                assert event, "event expected"
         | 
| 36 38 | 
             
                assert_equal "call_pipeline.html_pipeline", event
         | 
| 37 39 | 
             
                assert_equal @pipeline.filters.map(&:name), payload[:filters]
         | 
| 40 | 
            +
                assert_equal @pipeline.class.name, payload[:pipeline]
         | 
| 41 | 
            +
                assert_equal body.reverse, payload[:result][:output]
         | 
| 38 42 | 
             
              end
         | 
| 39 43 |  | 
| 40 44 | 
             
              def test_default_instrumentation_service
         | 
| @@ -46,6 +50,24 @@ class HTML::PipelineTest < Test::Unit::TestCase | |
| 46 50 | 
             
                Pipeline.default_instrumentation_service = nil
         | 
| 47 51 | 
             
              end
         | 
| 48 52 |  | 
| 53 | 
            +
              def test_setup_instrumentation
         | 
| 54 | 
            +
                assert_nil @pipeline.instrumentation_service
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                service = MockedInstrumentationService.new
         | 
| 57 | 
            +
                events = service.subscribe "call_pipeline.html_pipeline"
         | 
| 58 | 
            +
                @pipeline.setup_instrumentation name = 'foo', service
         | 
| 59 | 
            +
             | 
| 60 | 
            +
                assert_equal service, @pipeline.instrumentation_service
         | 
| 61 | 
            +
                assert_equal name, @pipeline.instrumentation_name
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                filter(body = 'foo')
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                event, payload, res = events.pop
         | 
| 66 | 
            +
                assert event, "expected event"
         | 
| 67 | 
            +
                assert_equal name, payload[:pipeline]
         | 
| 68 | 
            +
                assert_equal body.reverse, payload[:result][:output]
         | 
| 69 | 
            +
              end
         | 
| 70 | 
            +
             | 
| 49 71 | 
             
              def filter(input)
         | 
| 50 72 | 
             
                @pipeline.call(input)
         | 
| 51 73 | 
             
              end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: html-pipeline
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0. | 
| 4 | 
            +
              version: 0.0.12
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -10,7 +10,7 @@ authors: | |
| 10 10 | 
             
            autorequire: 
         | 
| 11 11 | 
             
            bindir: bin
         | 
| 12 12 | 
             
            cert_chain: []
         | 
| 13 | 
            -
            date: 2013- | 
| 13 | 
            +
            date: 2013-04-01 00:00:00.000000000 Z
         | 
| 14 14 | 
             
            dependencies:
         | 
| 15 15 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 16 16 | 
             
              name: gemoji
         |