<commit_before># coding: utf-8

class TranspecTest
  include FileUtils # This is Rake's one.

  attr_reader :url, :ref, :bundler_args

  def self.base_dir
    @base_dir ||= begin
      base_dir = File.join('tmp', 'projects')

      unless Dir.exist?(base_dir)
        require 'fileutils'
        FileUtils.mkdir_p(base_dir)
      end

      base_dir
    end
  end

  def initialize(url, ref = nil, bundler_args = [])
    @url = url
    @ref = ref
    @bundler_args = bundler_args
  end

  def name
    @name ||= File.basename(url, '.git')
  end

  def project_dir
    @project_dir ||= File.join(self.class.base_dir, name)
  end

  def run
    require 'transpec'

    puts " Testing on #{name} Project ".center(80, '=')

    prepare_project

    in_project_dir do
      with_clean_bundler_env do
        sh 'bundle', 'install', *bundler_args
        sh File.join(Transpec.root, 'bin', 'transpec'), '--force'
        sh 'bundle exec rspec'
      end
    end
  end

  private

  def prepare_project
    if url.start_with?('/')
      prepare_with_local_dir
    else
      prepare_with_git_repo
    end
  end

  def prepare_with_local_dir
    if Dir.exist?(project_dir)
      require 'fileutils'
      FileUtils.rm_rf(project_dir)
    end

    Dir.mkdir(project_dir)

    Dir.chdir(url) do
      Dir.new('.').each do |entry|
        next if ['.', '..', '.git', 'tmp'].include?(entry)
        FileUtils.cp_r(entry, project_dir)
      end
    end
  end

  def prepare_with_git_repo
    if Dir.exist?(project_dir)
      if current_ref == ref
        git_reset_hard
      else
        require 'fileutils'
        FileUtils.rm_rf(project_dir)
        git_clone
      end
    else
      git_clone
    end
  end

  def in_project_dir(&block)
    Dir.chdir(project_dir, &block)
  end

  def current_ref
    in_project_dir do
      `git describe --all`.chomp.sub(/\Aheads\//, '')
    end
  end

  def git_reset_hard
    in_project_dir do
      sh 'git reset --hard'
    end
  end

  def git_clone
    Dir.chdir(self.class.base_dir) do
      # Disabling checkout here to suppress "detached HEAD" warning.
      sh "git clone --no-checkout --depth 1 --branch #{ref} #{url}"
    end

    in_project_dir do
      sh "git checkout --quiet #{ref}"
    end
  end

  def with_clean_bundler_env
    if defined?(Bundler)
      Bundler.with_clean_env do
        # Bundler.with_clean_env cleans environment variables
        # which are set after bundler is loaded.
        prepare_env
        yield
      end
    else
      prepare_env
      yield
    end
  end

  def prepare_env
    # Disable Coveralls.
    ENV['CI'] = ENV['JENKINS_URL'] = ENV['COVERALLS_RUN_LOCALLY'] = nil
  end
end

namespace :test do
  # On Travis CI, reuse system gems to speed up build.
  bundler_args = if ENV['TRAVIS']
                   []
                 else
                   %w(--path vendor/bundle)
                 end

  # rubocop:disable LineLength
  tests = [
    TranspecTest.new(File.expand_path('.'), nil, []),
    TranspecTest.new('https://github.com/sferik/twitter.git', 'v4.1.0', bundler_args),
    TranspecTest.new('https://github.com/yujinakayama/guard.git', 'transpec', bundler_args + %w(--without development)),
    TranspecTest.new('https://github.com/yujinakayama/mail.git', 'transpec', bundler_args)
  ]
  # rubocop:enable LineLength

  desc 'Test Transpec on all projects'
  task all: tests.map(&:name)

  tests.each do |test|<commit_msg>Test --no-parentheses-matcher-arg option in test tasks<commit_after># coding: utf-8

class TranspecTest
  include FileUtils # This is Rake's one.

  attr_reader :url, :ref, :bundler_args

  def self.base_dir
    @base_dir ||= begin
      base_dir = File.join('tmp', 'projects')

      unless Dir.exist?(base_dir)
        require 'fileutils'
        FileUtils.mkdir_p(base_dir)
      end

      base_dir
    end
  end

  def initialize(url, ref = nil, bundler_args = [])
    @url = url
    @ref = ref
    @bundler_args = bundler_args
  end

  def name
    @name ||= File.basename(url, '.git')
  end

  def project_dir
    @project_dir ||= File.join(self.class.base_dir, name)
  end

  def run
    require 'transpec'

    puts " Testing on #{name} Project ".center(80, '=')

    [%w(--force), %w(--force --no-parentheses-matcher-arg)].each do |args|
      prepare_project
      run_test(args)
    end
  end

  private

  def prepare_project
    if url.start_with?('/')
      prepare_with_local_dir
    else
      prepare_with_git_repo
    end
  end

  def prepare_with_local_dir
    if Dir.exist?(project_dir)
      require 'fileutils'
      FileUtils.rm_rf(project_dir)
    end

    Dir.mkdir(project_dir)

    Dir.chdir(url) do
      Dir.new('.').each do |entry|
        next if ['.', '..', '.git', 'tmp'].include?(entry)
        FileUtils.cp_r(entry, project_dir)
      end
    end

    bundle_install
  end

  def prepare_with_git_repo
    if Dir.exist?(project_dir)
      if current_ref == ref
        git_reset_hard
        return
      else
        require 'fileutils'
        FileUtils.rm_rf(project_dir)
      end
    end

    git_clone
    bundle_install
  end

  def run_test(transpec_args = [])
    in_project_dir do
      with_clean_bundler_env do
        sh File.join(Transpec.root, 'bin', 'transpec'), *transpec_args
        sh 'bundle exec rspec'
      end
    end
  end

  def in_project_dir(&block)
    Dir.chdir(project_dir, &block)
  end

  def current_ref
    in_project_dir do
      `git describe --all`.chomp.sub(/\Aheads\//, '')
    end
  end

  def git_reset_hard
    in_project_dir do
      sh 'git reset --hard'
    end
  end

  def git_clone
    Dir.chdir(self.class.base_dir) do
      # Disabling checkout here to suppress "detached HEAD" warning.
      sh "git clone --no-checkout --depth 1 --branch #{ref} #{url}"
    end

    in_project_dir do
      sh "git checkout --quiet #{ref}"
    end
  end

  def bundle_install
    in_project_dir do
      with_clean_bundler_env do
        sh 'bundle', 'install', *bundler_args
      end
    end
  end

  def with_clean_bundler_env
    if defined?(Bundler)
      Bundler.with_clean_env do
        # Bundler.with_clean_env cleans environment variables
        # which are set after bundler is loaded.
        prepare_env
        yield
      end
    else
      prepare_env
      yield
    end
  end

  def prepare_env
    # Disable Coveralls.
    ENV['CI'] = ENV['JENKINS_URL'] = ENV['COVERALLS_RUN_LOCALLY'] = nil
  end
end

namespace :test do
  # On Travis CI, reuse system gems to speed up build.
  bundler_args = if ENV['TRAVIS']
                   []
                 else
                   %w(--path vendor/bundle)
                 end

  # rubocop:disable LineLength
  tests = [
    TranspecTest.new(File.expand_path('.'), nil, ['--quiet']),
    TranspecTest.new('https://github.com/sferik/twitter.git', 'v4.1.0', bundler_args),
    TranspecTest.new('https://github.com/yujinakayama/guard.git', 'transpec', bundler_args + %w(--without development)),
    TranspecTest.new('https://github.com/yujinakayama/mail.git', 'transpec', bundler_args)
  ]
  # rubocop:enable LineLength

  desc 'Test Transpec on all projects'
  task all: tests.map(&:name)

  tests.each do |test|
{'fraction_non_alphanumeric': 0.10751186819324211, 'fraction_numerical': 0.001954761239877129, 'mean_word_length': 2.3566073102155576, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1252439', 'n_tokens_mistral': 2519, 'n_tokens_neox': 2432, 'n_words': 579}