<commit_before>require 'rspec/core'
require 'ostruct'

module RSpec::Plugins
  module Core

    class Plugin
      attr_accessor :example_group, :plugin_module

      def initialize(example_group, plugin_module)
        @example_group    = example_group
        @plugin_module    = plugin_module
      end
    end

    # This module holds the class methods for the plugin module.
    def self.included(plugin_module)
      plugin_module.extend(ClassMethods)

      plugin_module.define_singleton_method :included do |example_group|

        plugin_class = plugin_module.const_defined?(:Plugin) ? plugin_module::Plugin : Plugin
        plugin = plugin_class.new(example_group, plugin_module)

        example_group.metadata[:plugins] ||= {}
        example_group.metadata[:plugins][plugin_module] = plugin

        settings = plugin_module.settings

        # -- define helper methods
        settings.helpers.values.each do |helper|
          example_group.define_singleton_method helper.signal do |*args|
            helper.block.call(plugin, self, *args)
          end
        end

        # -- define listener for formatter events --
        settings.listeners.values.each do |listener|
          plugin.define_singleton_method(listener.signal) do |*args|
            listener.block.call(plugin, *args)
          end
        end

        # -- define rspec hooks --
        # formatters must be registered and de-registered to let them run per spec
        # register formatter listeners before all other hooks
        if ! settings.listeners.empty?
          example_group.send :before, :all do
            RSpec.configure do |config|
              config.reporter.register_listener plugin, *settings.listeners.keys
            end
          end
        end
        # -- register additional hooks
        settings.hooks.each do |hook|
          example_group.send hook.position, hook.target do |*args|
            hook.block.call(plugin, *args)
          end
        end
        # remove formatters after all other hooks
        if ! settings.listeners.empty?
          example_group.send :after, :all do
            RSpec.configure do |config|
              settings.listeners.keys.each do |signal|
                config.reporter.registered_listeners(signal).delete(plugin)
              end
            end
          end
        end
      end
    end

    def method_missing(symbol, *args, &block)
      listener = respond_to_missing?(symbol, false)
      if listener
        return listener.block.call(self, *args)
      else
        raise NoMethodError, "non existing method called: #{symbol}"
      end
    end

    def respond_to_missing?(symbol, include_private)
      methods.index(:plugin_module) && plugin_module.settings.listeners[symbol]
    end

    class Hook
      attr_accessor :position, :target, :block
      def initialize(method, target, &block)
        @position = method
        @target = target
        @block = block
      end
    end

    class Listener
      attr_accessor :signal, :block
      def initialize(signal, &block)
        @signal = signal
        @block = block
      end
    end

    module ClassMethods
      def settings
        id = self.to_s.to_sym
        Thread.current[id] ||= OpenStruct.new(
            {:listeners    => {},
             :helpers      => {},
             :hooks        => [],
             :id          => id
            })
      end

      def hook(position, target, &block)
        settings.hooks << Hook.new(position, target, &block)
      end

      # Register a notification callback.
      # {RSpec Reporter Notifications}[rdoc-href:RSpec::Core::Reporter::NOTIFICATIONS]
      # for a list of available notifications. The :close notification is reserved for
      # the plugin cleanup hook.
      def on(signal, &block)
        settings.listeners[signal] = Listener.new(signal, &block)
      end

      # Register a helper method for the example group an example group helper method.
      # Call #helpers to get the list of defined helper methods.
      def helper(method_name, &block)<commit_msg>Added option to change the plugin class.<commit_after>require 'rspec/core'
require 'ostruct'

module RSpec::Plugins
  module Core

    class Plugin
      attr_accessor :example_group, :plugin_module
      def initialize(example_group, plugin_module)
        @example_group    = example_group
        @plugin_module    = plugin_module
      end
    end

    # This module holds the class methods for the plugin module.
    def self.included(plugin_module)
      plugin_module.extend(ClassMethods)
      plugin_module.define_singleton_method :included do |example_group|

        settings = plugin_module.settings
        plugin = settings.plugin_class.new
        example_group.metadata[:plugins] ||= {}
        example_group.metadata[:plugins][plugin_module] = plugin

        # -- define helper methods
        settings.helpers.values.each do |helper|
          example_group.define_singleton_method helper.signal do |*args|
            helper.block.call(plugin, self, *args)
          end
        end

        # -- define listener for formatter events --
        settings.listeners.values.each do |listener|
          plugin.define_singleton_method(listener.signal) do |*args|
            listener.block.call(plugin, *args)
          end
        end

        # -- define rspec hooks --
        # formatters must be registered and de-registered to let them run per spec
        # register formatter listeners before all other hooks
        if ! settings.listeners.empty?
          example_group.send :before, :all do
            RSpec.configure do |config|
              config.reporter.register_listener plugin, *settings.listeners.keys
            end
          end
        end
        # -- register additional hooks
        settings.hooks.each do |hook|
          example_group.send hook.position, hook.target do |*args|
            hook.block.call(plugin, *args)
          end
        end
        # remove formatters after all other hooks
        if ! settings.listeners.empty?
          example_group.send :after, :all do
            RSpec.configure do |config|
              settings.listeners.keys.each do |signal|
                config.reporter.registered_listeners(signal).delete(plugin)
              end
            end
          end
        end
      end
    end

    def method_missing(symbol, *args, &block)
      super
      listener = respond_to_missing?(symbol, false)
      if listener
        return listener.block.call(self, *args)
      end
    end

    def respond_to_missing?(symbol, include_private)
      methods.index(:plugin_module) && plugin_module.settings.listeners[symbol]
    end

    class Hook
      attr_accessor :position, :target, :block
      def initialize(method, target, &block)
        @position = method
        @target = target
        @block = block
      end
    end

    class Listener
      attr_accessor :signal, :block
      def initialize(signal, &block)
        @signal = signal
        @block = block
      end
    end

    module ClassMethods
      def settings
        id = self.to_s.to_sym
        Thread.current[id] ||= OpenStruct.new(
            {:listeners    => {},
             :helpers      => {},
             :hooks        => [],
             :id          => id,
             :plugin_class => Plugin
            })
      end

      def hook(position, target, &block)
        settings.hooks << Hook.new(position, target, &block)
      end

      # Register a notification callback.
      # {RSpec Reporter Notifications}[rdoc-href:RSpec::Core::Reporter::NOTIFICATIONS]
      # for a list of available notifications. The :close notification is reserved for
      # the plugin cleanup hook.
      def on(signal, &block)
        settings.listeners[signal] = Listener.new(signal, &block)
      end

      # Register a helper method for the example group an example group helper method.
      # Call #helpers to get the list of defined helper methods.
      def helper(method_name, &block)
{'fraction_non_alphanumeric': 0.08127648965345301, 'fraction_numerical': 0.0, 'mean_word_length': 2.0988798764001544, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 12, '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': '1429258', 'n_tokens_mistral': 2134, 'n_tokens_neox': 2098, 'n_words': 589}