<commit_before>require 'fileutils'
require 'erb'

require 'vcr/cassette/http_interaction_list'
require 'vcr/cassette/reader'
require 'vcr/cassette/serializers'

module VCR
  # The media VCR uses to store HTTP interactions for later re-use.
  class Cassette

    # The supported record modes.
    #
    #   * :all -- Record every HTTP interactions; do not play any back.
    #   * :none -- Do not record any HTTP interactions; play them back.
    #   * :new_episodes -- Playback previously recorded HTTP interactions and record new ones.
    #   * :once -- Record the HTTP interactions if the cassette has not already been recorded;
    #              otherwise, playback the HTTP interactions.
    VALID_RECORD_MODES = [:all, :none, :new_episodes, :once]

    # @return [#to_s] The name of the cassette. Used to determine the cassette's file name.
    # @see #file
    attr_reader :name

    # @return [Symbol] The record mode. Determines whether the cassette records HTTP interactions,
    #  plays them back, or does both.
    attr_reader :record_mode

    # @return [Array<Symbol, #call>] List of request matchers. Used to find a response from an
    #  existing HTTP interaction to play back.
    attr_reader :match_requests_on

    # @return [Boolean, Hash] The cassette's ERB option. The file will be treated as an
    #  ERB template if this has a truthy value. A hash, if provided, will be used as local
    #  variables for the ERB template.
    attr_reader :erb

    # @return [Integer, nil] How frequently (in seconds) the cassette should be re-recorded.
    attr_reader :re_record_interval

    # @return [Array<Symbol>] If set, {VCR::Configuration#before_record} and
    #  {VCR::Configuration#before_playback} hooks with a corresponding tag will apply.
    attr_reader :tags

    # @param (see VCR#insert_cassette)
    # @see VCR#insert_cassette
    def initialize(name, options = {})
      options = VCR.configuration.default_cassette_options.merge(options)
      invalid_options = options.keys - [
        :record, :erb, :match_requests_on, :re_record_interval, :tag, :tags,
        :update_content_length_header, :allow_playback_repeats, :exclusive,
        :serialize_with
      ]

      if invalid_options.size > 0
        raise ArgumentError.new("You passed the following invalid options to VCR::Cassette.new: #{invalid_options.inspect}.")
      end

      @name                         = name
      @record_mode                  = options[:record]
      @erb                          = options[:erb]
      @match_requests_on            = options[:match_requests_on]
      @re_record_interval           = options[:re_record_interval]
      @tags                         = Array(options.fetch(:tags) { options[:tag] })
      @tags                         << :update_content_length_header if options[:update_content_length_header]
      @allow_playback_repeats       = options[:allow_playback_repeats]
      @exclusive                    = options[:exclusive]
      @serializer                   = VCR.cassette_serializers[options[:serialize_with]]
      @record_mode                  = :all if should_re_record?
      @parent_list                  = @exclusive ? HTTPInteractionList::NullList : VCR.http_interactions

      raise_error_unless_valid_record_mode
    end

    # Ejects the current cassette. The cassette will no longer be used.
    # In addition, any newly recorded HTTP interactions will be written to
    # disk.
    def eject
      write_recorded_interactions_to_disk
    end

    # @private
    def http_interactions
      @http_interactions ||= HTTPInteractionList.new \
        should_stub_requests? ? previously_recorded_interactions : [],
        match_requests_on,
        @allow_playback_repeats,
        @parent_list
    end

    # @private
    def record_http_interaction(interaction)
      new_recorded_interactions << interaction
    end

    # @private
    def new_recorded_interactions
      @new_recorded_interactions ||= []
    end

    # @return [String] The file for this cassette.
    # @note VCR will take care of sanitizing the cassette name to make it valid file name.
    def file
      return nil unless VCR.configuration.cassette_library_dir
      File.join(VCR.configuration.cassette_library_dir, "#{sanitized_name}.#{@serializer.file_extension}")
    end

    # @return [Boolean] Whether or not the cassette is recording.
    def recording?
      case record_mode
        when :none; false
        when :once; file.nil? || !File.size?(file)
        else true
      end
    end

    # @return [Hash] The hash that will be serialized when the cassette is written to disk.
    def serializable_hash
      {
        "http_interactions" => interactions_to_record.map(&:to_hash),
        "recorded_with"     => "VCR #{VCR.version}"
      }
    end

  private

    def previously_recorded_interactions
      @previously_recorded_interactions ||= if file && File.size?(file)
        deserialized_hash['http_interactions'].map { |h| HTTPInteraction.from_hash(h) }.tap do |interactions|
          invoke_hook(:before_playback, interactions)
<commit_msg>Fix typo.<commit_after>require 'fileutils'
require 'erb'

require 'vcr/cassette/http_interaction_list'
require 'vcr/cassette/reader'
require 'vcr/cassette/serializers'

module VCR
  # The media VCR uses to store HTTP interactions for later re-use.
  class Cassette

    # The supported record modes.
    #
    #   * :all -- Record every HTTP interactions; do not play any back.
    #   * :none -- Do not record any HTTP interactions; play them back.
    #   * :new_episodes -- Playback previously recorded HTTP interactions and record new ones.
    #   * :once -- Record the HTTP interactions if the cassette has not already been recorded;
    #              otherwise, playback the HTTP interactions.
    VALID_RECORD_MODES = [:all, :none, :new_episodes, :once]

    # @return [#to_s] The name of the cassette. Used to determine the cassette's file name.
    # @see #file
    attr_reader :name

    # @return [Symbol] The record mode. Determines whether the cassette records HTTP interactions,
    #  plays them back, or does both.
    attr_reader :record_mode

    # @return [Array<Symbol, #call>] List of request matchers. Used to find a response from an
    #  existing HTTP interaction to play back.
    attr_reader :match_requests_on

    # @return [Boolean, Hash] The cassette's ERB option. The file will be treated as an
    #  ERB template if this has a truthy value. A hash, if provided, will be used as local
    #  variables for the ERB template.
    attr_reader :erb

    # @return [Integer, nil] How frequently (in seconds) the cassette should be re-recorded.
    attr_reader :re_record_interval

    # @return [Array<Symbol>] If set, {VCR::Configuration#before_record} and
    #  {VCR::Configuration#before_playback} hooks with a corresponding tag will apply.
    attr_reader :tags

    # @param (see VCR#insert_cassette)
    # @see VCR#insert_cassette
    def initialize(name, options = {})
      options = VCR.configuration.default_cassette_options.merge(options)
      invalid_options = options.keys - [
        :record, :erb, :match_requests_on, :re_record_interval, :tag, :tags,
        :update_content_length_header, :allow_playback_repeats, :exclusive,
        :serialize_with
      ]

      if invalid_options.size > 0
        raise ArgumentError.new("You passed the following invalid options to VCR::Cassette.new: #{invalid_options.inspect}.")
      end

      @name                         = name
      @record_mode                  = options[:record]
      @erb                          = options[:erb]
      @match_requests_on            = options[:match_requests_on]
      @re_record_interval           = options[:re_record_interval]
      @tags                         = Array(options.fetch(:tags) { options[:tag] })
      @tags                         << :update_content_length_header if options[:update_content_length_header]
      @allow_playback_repeats       = options[:allow_playback_repeats]
      @exclusive                    = options[:exclusive]
      @serializer                   = VCR.cassette_serializers[options[:serialize_with]]
      @record_mode                  = :all if should_re_record?
      @parent_list                  = @exclusive ? HTTPInteractionList::NullList : VCR.http_interactions

      raise_error_unless_valid_record_mode
    end

    # Ejects the current cassette. The cassette will no longer be used.
    # In addition, any newly recorded HTTP interactions will be written to
    # disk.
    def eject
      write_recorded_interactions_to_disk
    end

    # @private
    def http_interactions
      @http_interactions ||= HTTPInteractionList.new \
        should_stub_requests? ? previously_recorded_interactions : [],
        match_requests_on,
        @allow_playback_repeats,
        @parent_list
    end

    # @private
    def record_http_interaction(interaction)
      new_recorded_interactions << interaction
    end

    # @private
    def new_recorded_interactions
      @new_recorded_interactions ||= []
    end

    # @return [String] The file for this cassette.
    # @note VCR will take care of sanitizing the cassette name to make it a valid file name.
    def file
      return nil unless VCR.configuration.cassette_library_dir
      File.join(VCR.configuration.cassette_library_dir, "#{sanitized_name}.#{@serializer.file_extension}")
    end

    # @return [Boolean] Whether or not the cassette is recording.
    def recording?
      case record_mode
        when :none; false
        when :once; file.nil? || !File.size?(file)
        else true
      end
    end

    # @return [Hash] The hash that will be serialized when the cassette is written to disk.
    def serializable_hash
      {
        "http_interactions" => interactions_to_record.map(&:to_hash),
        "recorded_with"     => "VCR #{VCR.version}"
      }
    end

  private

    def previously_recorded_interactions
      @previously_recorded_interactions ||= if file && File.size?(file)
        deserialized_hash['http_interactions'].map { |h| HTTPInteraction.from_hash(h) }.tap do |interactions|
          invoke_hook(:before_playback, interactions)

{'fraction_non_alphanumeric': 0.08140673981191222, 'fraction_numerical': 0.00019592476489028212, 'mean_word_length': 2.7505510653930934, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2928355', 'n_tokens_mistral': 3014, 'n_tokens_neox': 2877, 'n_words': 846}