File: hooks.rb

package info (click to toggle)
ruby-vcr 6.0.0%2Breally5.0.0-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,320 kB
  • sloc: ruby: 8,456; sh: 177; makefile: 7
file content (62 lines) | stat: -rw-r--r-- 1,466 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
require 'vcr/util/variable_args_block_caller'

module VCR
  # @private
  module Hooks
    include VariableArgsBlockCaller

    # @private
    FilteredHook = Struct.new(:hook, :filters) do
      include VariableArgsBlockCaller

      def conditionally_invoke(*args)
        filters = Array(self.filters)
        return if filters.any? { |f| !call_block(f.to_proc, *args) }
        call_block(hook, *args)
      end
    end

    def self.included(klass)
      klass.class_eval do
        extend ClassMethods
        hooks_module = Module.new
        const_set("DefinedHooks", hooks_module)
        include hooks_module
      end
    end

    def invoke_hook(hook_type, *args)
      hooks[hook_type].map do |hook|
        hook.conditionally_invoke(*args)
      end
    end

    def clear_hooks
      hooks.clear
    end

    def hooks
      @hooks ||= Hash.new do |hash, hook_type|
        hash[hook_type] = []
      end
    end

    def has_hooks_for?(hook_type)
      hooks[hook_type].any?
    end

    # @private
    module ClassMethods
      def define_hook(hook_type, prepend = false)
        placement_method = prepend ? :unshift : :<<

        # Put the hook methods in a module so we can override and super to these methods.
        self::DefinedHooks.module_eval do
          define_method hook_type do |*filters, &hook|
            hooks[hook_type].send(placement_method, FilteredHook.new(hook, filters))
          end
        end
      end
    end
  end
end