<commit_before>require 'spec_helper'
require 'overcommit/hook_context/pre_commit'

describe Overcommit::HookContext::PreCommit do
  let(:config) { double('config') }
  let(:args) { [] }
  let(:context) { described_class.new(config, args) }

  describe '#setup_environment' do
    subject { context.setup_environment }

    context 'when there are no staged changes' do
      around do |example|
        repo do
          `echo "Hello World" > tracked-file`
          `git add tracked-file`
          `git commit -m "Add tracked-file"`
          `echo "Hello Again" > untracked-file`
          example.run
        end
      end

      it 'keeps already-committed files' do
        subject
        File.open('tracked-file', 'r').read == 'Hello World'
      end

      it 'keeps untracked files' do
        subject
        File.open('untracked-file', 'r').read == 'Hello Again'
      end

      it 'keeps modification times the same' do
        expect { subject }.
          to_not change { [File.mtime('tracked-file'), File.mtime('untracked-file')] }
      end
    end

    context 'when there are staged changes' do
      around do |example|
        repo do
          `echo "Hello World" > tracked-file`
          `git add tracked-file`
          `git commit -m "Add tracked-file"`
          `echo "Hello Again" > untracked-file`
          `echo "Some more text" >> tracked-file`
          `git add tracked-file`
          `echo "Yet some more text" >> tracked-file`
          example.run
        end
      end

      it 'keeps staged changes' do
        subject
        File.open('tracked-file', 'r').read == 'Hello WorldSome more text'
      end

      it 'keeps untracked files' do
        subject
        File.open('untracked-file', 'r').read == 'Hello Again'
      end

      it 'keeps modification times the same' do
        expect { subject }.
          to_not change { [File.mtime('tracked-file'), File.mtime('untracked-file')] }
      end
    end

    context 'when a broken symlink is staged' do
      around do |example|
        repo do
          `ln -s non-existent-file symlink`
          `git add symlink`
          example.run
        end
      end

      it 'does not attempt to update/restore the modification time of the file' do
        File.should_not_receive(:mtime)
        File.should_not_receive(:utime)
        subject
      end
    end
  end

  describe '#cleanup_environment' do
    subject { context.cleanup_environment }

    before do
      context.setup_environment
    end

    context 'when there were no staged changes' do
      around do |example|
        repo do
          `echo "Hello World" > tracked-file`
          `git add tracked-file`
          `git commit -m "Add tracked-file"`
          `echo "Hello Again" > untracked-file`
          example.run
        end
      end

      it 'keeps already-committed files' do
        subject
        File.open('tracked-file', 'r').read.should == "Hello World\n"
      end

      it 'keeps untracked files' do
        subject
        File.open('untracked-file', 'r').read.should == "Hello Again\n"
      end

      it 'keeps modification times the same' do
        expect { subject }.
          to_not change { [File.mtime('tracked-file'), File.mtime('untracked-file')] }
      end
    end

    context 'when there were staged changes' do
      around do |example|
        repo do
          `echo "Hello World" > tracked-file`
          `git add tracked-file`
          `git commit -m "Add tracked-file"`
          `echo "Hello Again" > untracked-file`
          `echo "Some more text" >> tracked-file`
          `git add tracked-file`
          `echo "Yet some more text" >> tracked-file`
          example.run
        end
      end

      it 'restores the unstaged changes' do
        subject
        File.open('tracked-file', 'r').read.
          should == "Hello World\nSome more text\nYet some more text\n"
      end

      it 'keeps untracked files' do
        subject
        File.open('untracked-file', 'r').read.should == "Hello Again\n"
      end

      it 'keeps modification times the same' do
        expect { subject }.
          to_not change { [File.mtime('tracked-file'), File.mtime('untracked-file')] }
      end
    end

    context 'when there were deleted files' do
      around do |example|
        repo do
          `echo "Hello World" > tracked-file`
          `git add tracked-file`
          `git commit -m "Add tracked-file"`
          `git rm tracked-file`
          example.run
        end
      end

      it 'deletes the file' do
        subject
        File.exist?('tracked-file').should == false
      end
    end
  end

  describe '#modified_files' do
    subject { context.modified_files }

    it 'does not include submodules' do
      submodule = repo do
        `touch foo`
        `git add foo`
        `git commit -m "Initial commit"`
      end

      repo do
        `git submodule add #{submodule} test-sub &> /dev/null`
        expect(subject).to_not include File.expand_path('test-sub')
      end
    end

    context 'when no files were staged' do
      around do |example|
        repo do
          example.run
        end
      end

      it { should be_empty }
    end

    context 'when files were added' do
      around do |example|
        repo do<commit_msg>Quiet additional clone output in tests<commit_after>require 'spec_helper'
require 'overcommit/hook_context/pre_commit'

describe Overcommit::HookContext::PreCommit do
  let(:config) { double('config') }
  let(:args) { [] }
  let(:context) { described_class.new(config, args) }

  describe '#setup_environment' do
    subject { context.setup_environment }

    context 'when there are no staged changes' do
      around do |example|
        repo do
          `echo "Hello World" > tracked-file`
          `git add tracked-file`
          `git commit -m "Add tracked-file"`
          `echo "Hello Again" > untracked-file`
          example.run
        end
      end

      it 'keeps already-committed files' do
        subject
        File.open('tracked-file', 'r').read == 'Hello World'
      end

      it 'keeps untracked files' do
        subject
        File.open('untracked-file', 'r').read == 'Hello Again'
      end

      it 'keeps modification times the same' do
        expect { subject }.
          to_not change { [File.mtime('tracked-file'), File.mtime('untracked-file')] }
      end
    end

    context 'when there are staged changes' do
      around do |example|
        repo do
          `echo "Hello World" > tracked-file`
          `git add tracked-file`
          `git commit -m "Add tracked-file"`
          `echo "Hello Again" > untracked-file`
          `echo "Some more text" >> tracked-file`
          `git add tracked-file`
          `echo "Yet some more text" >> tracked-file`
          example.run
        end
      end

      it 'keeps staged changes' do
        subject
        File.open('tracked-file', 'r').read == 'Hello WorldSome more text'
      end

      it 'keeps untracked files' do
        subject
        File.open('untracked-file', 'r').read == 'Hello Again'
      end

      it 'keeps modification times the same' do
        expect { subject }.
          to_not change { [File.mtime('tracked-file'), File.mtime('untracked-file')] }
      end
    end

    context 'when a broken symlink is staged' do
      around do |example|
        repo do
          `ln -s non-existent-file symlink`
          `git add symlink`
          example.run
        end
      end

      it 'does not attempt to update/restore the modification time of the file' do
        File.should_not_receive(:mtime)
        File.should_not_receive(:utime)
        subject
      end
    end
  end

  describe '#cleanup_environment' do
    subject { context.cleanup_environment }

    before do
      context.setup_environment
    end

    context 'when there were no staged changes' do
      around do |example|
        repo do
          `echo "Hello World" > tracked-file`
          `git add tracked-file`
          `git commit -m "Add tracked-file"`
          `echo "Hello Again" > untracked-file`
          example.run
        end
      end

      it 'keeps already-committed files' do
        subject
        File.open('tracked-file', 'r').read.should == "Hello World\n"
      end

      it 'keeps untracked files' do
        subject
        File.open('untracked-file', 'r').read.should == "Hello Again\n"
      end

      it 'keeps modification times the same' do
        expect { subject }.
          to_not change { [File.mtime('tracked-file'), File.mtime('untracked-file')] }
      end
    end

    context 'when there were staged changes' do
      around do |example|
        repo do
          `echo "Hello World" > tracked-file`
          `git add tracked-file`
          `git commit -m "Add tracked-file"`
          `echo "Hello Again" > untracked-file`
          `echo "Some more text" >> tracked-file`
          `git add tracked-file`
          `echo "Yet some more text" >> tracked-file`
          example.run
        end
      end

      it 'restores the unstaged changes' do
        subject
        File.open('tracked-file', 'r').read.
          should == "Hello World\nSome more text\nYet some more text\n"
      end

      it 'keeps untracked files' do
        subject
        File.open('untracked-file', 'r').read.should == "Hello Again\n"
      end

      it 'keeps modification times the same' do
        expect { subject }.
          to_not change { [File.mtime('tracked-file'), File.mtime('untracked-file')] }
      end
    end

    context 'when there were deleted files' do
      around do |example|
        repo do
          `echo "Hello World" > tracked-file`
          `git add tracked-file`
          `git commit -m "Add tracked-file"`
          `git rm tracked-file`
          example.run
        end
      end

      it 'deletes the file' do
        subject
        File.exist?('tracked-file').should == false
      end
    end
  end

  describe '#modified_files' do
    subject { context.modified_files }

    it 'does not include submodules' do
      submodule = repo do
        `touch foo`
        `git add foo`
        `git commit -m "Initial commit"`
      end

      repo do
        `git submodule add #{submodule} test-sub 2>&1 > /dev/null`
        expect(subject).to_not include File.expand_path('test-sub')
      end
    end

    context 'when no files were staged' do
      around do |example|
        repo do
          example.run
        end
      end

      it { should be_empty }
    end

    context 'when files were added' do
      around do |example|
        repo do
{'fraction_non_alphanumeric': 0.09865259587298596, 'fraction_numerical': 0.00018844812965231321, 'mean_word_length': 1.866324601674318, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 40, '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': '6073506', 'n_tokens_mistral': 3172, 'n_tokens_neox': 3046, 'n_words': 983}