File: rack.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 (79 lines) | stat: -rw-r--r-- 2,386 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
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
module VCR
  module Middleware
    # Object yielded by VCR's {Rack} middleware that allows you to configure
    # the cassette dynamically based on the rack env.
    class CassetteArguments
      # @private
      def initialize
        @name    = nil
        @options = {}
      end

      # Sets (and gets) the cassette name.
      #
      # @param [#to_s] name the cassette name
      # @return [#to_s] the cassette name
      def name(name = nil)
        @name = name if name
        @name
      end

      # Sets (and gets) the cassette options.
      #
      # @param [Hash] options the cassette options
      # @return [Hash] the cassette options
      def options(options = {})
        @options.merge!(options)
      end
    end

    # Rack middleware that uses a VCR cassette for each incoming HTTP request.
    #
    # @example
    #   app = Rack::Builder.new do
    #     use VCR::Middleware::Rack do |cassette, env|
    #       cassette.name "rack/#{env['SERVER_NAME']}"
    #       cassette.options :record => :new_episodes
    #     end
    #
    #     run MyRackApp
    #   end
    #
    # @note This will record/replay _outbound_ HTTP requests made by your rack app.
    class Rack
      include VCR::VariableArgsBlockCaller

      # Constructs a new instance of VCR's rack middleware.
      #
      # @param [#call] app the rack app
      # @yield the cassette configuration block
      # @yieldparam [CassetteArguments] cassette the cassette configuration object
      # @yieldparam [(optional) Hash] env the rack env hash
      # @raise [ArgumentError] if no configuration block is provided
      def initialize(app, &block)
        raise ArgumentError.new("You must provide a block to set the cassette options") unless block
        @app, @cassette_arguments_block, @mutex = app, block, Mutex.new
      end

      # Implements the rack middleware interface.
      #
      # @param [Hash] env the rack env hash
      # @return [Array(Integer, Hash, #each)] the rack response
      def call(env)
        @mutex.synchronize do
          VCR.use_cassette(*cassette_arguments(env)) do
            @app.call(env)
          end
        end
      end

    private

      def cassette_arguments(env)
        arguments = CassetteArguments.new
        call_block(@cassette_arguments_block, arguments, env)
        [arguments.name, arguments.options]
      end
    end
  end
end