<commit_before>import * as FSE from 'fs-extra'
import * as Path from 'path'
import { GitProcess } from 'dugite'
import { expect } from 'chai'

import { setupEmptyRepository } from '../../helpers/repositories'
import { getStatusOrThrow } from '../../helpers/status'
import { saveGitIgnore, readGitIgnoreAtRoot } from '../../../src/lib/git'

describe('gitignore', () => {
  describe('saveGitIgnore', () => {
    it(`creates gitignore file when it doesn't exist`, async () => {
      const repo = await setupEmptyRepository()

      await saveGitIgnore(repo, 'node_modules\n')

      const exists = await FSE.pathExists(`${repo.path}/.gitignore`)

      expect(exists).is.true
    })

    it('deletes gitignore file when no entries provided', async () => {
      const repo = await setupEmptyRepository()
      const path = repo.path

      const ignoreFile = `${path}/.gitignore`
      await FSE.writeFile(ignoreFile, 'node_modules\n')

      // update gitignore file to be empty
      await saveGitIgnore(repo, '')

      const exists = await FSE.pathExists(ignoreFile)
      expect(exists).is.false
    })

    it('applies rule correctly to repository', async () => {
      const repo = await setupEmptyRepository()

      const path = repo.path

      await saveGitIgnore(repo, '*.txt\n')
      await GitProcess.exec(['add', '.gitignore'], path)
      await GitProcess.exec(['commit', '-m', 'create the ignore file'], path)

      // Create a txt file
      const file = Path.join(repo.path, 'a.txt')

      await FSE.writeFile(file, 'thrvbnmerkl;,iuw')

      // Check status of repo
      const status = await getStatusOrThrow(repo)
      const files = status.workingDirectory.files

      expect(files.length).to.equal(0)
    })

    describe('autocrlf and safecrlf are true', () => {
      it('appends CRLF to file', async () => {
        const repo = await setupEmptyRepository()

        await GitProcess.exec(
          ['config', '--local', 'core.autocrlf', 'true'],
          repo.path
        )
        await GitProcess.exec(
          ['config', '--local', 'core.safecrlf', 'true'],
          repo.path
        )

        const path = repo.path

        await saveGitIgnore(repo, 'node_modules')
        await GitProcess.exec(['add', '.gitignore'], path)

        const commit = await GitProcess.exec(
          ['commit', '-m', 'create the ignore file'],
          path
        )
        expect(commit.exitCode).to.equal(0)

        const contents = await readGitIgnoreAtRoot(repo)
        expect(contents!.endsWith('\r\n'))
      })
    })

    describe('autocrlf and safecrlf are unset', () => {
      it('appends LF to file', async () => {
        const repo = await setupEmptyRepository()

        // ensure this repository only ever sticks to LF
        await GitProcess.exec(
          ['config', '--local', 'core.eol', 'lf'],
          repo.path
        )

        // do not do any conversion of line endings when committing
        await GitProcess.exec(
          ['config', '--local', 'core.autocrlf', 'input'],
          repo.path
        )

        const path = repo.path

        await saveGitIgnore(repo, 'node_modules')
        await GitProcess.exec(['add', '.gitignore'], path)

        const commit = await GitProcess.exec(
          ['commit', '-m', 'create the ignore file'],
          path
        )
        expect(commit.exitCode).to.equal(0)

        const contents = await readGitIgnoreAtRoot(repo)
        expect(contents!.endsWith('\n'))
      })
    })
  })
})<commit_msg>add a bunch more tests<commit_after>import * as FSE from 'fs-extra'
import * as Path from 'path'
import { GitProcess } from 'dugite'
import { expect } from 'chai'

import { setupEmptyRepository } from '../../helpers/repositories'
import { getStatusOrThrow } from '../../helpers/status'
import {
  saveGitIgnore,
  readGitIgnoreAtRoot,
  appendIgnoreRule,
} from '../../../src/lib/git'

describe('gitignore', () => {
  describe('readGitIgnoreAtRoot', () => {
    it('returns null when .gitignore does not exist on disk', async () => {
      const repo = await setupEmptyRepository()

      const gitignore = await readGitIgnoreAtRoot(repo)

      expect(gitignore).is.null
    })

    it('reads contents from disk', async () => {
      const repo = await setupEmptyRepository()
      const path = repo.path

      const expected = 'node_modules\nyarn-error.log\n'

      const ignoreFile = `${path}/.gitignore`
      await FSE.writeFile(ignoreFile, expected)

      const gitignore = await readGitIgnoreAtRoot(repo)

      expect(gitignore).equals(expected)
    })

    it('when autocrlf=true and safecrlf=true, appends CRLF to file', async () => {
      const repo = await setupEmptyRepository()

      await GitProcess.exec(
        ['config', '--local', 'core.autocrlf', 'true'],
        repo.path
      )
      await GitProcess.exec(
        ['config', '--local', 'core.safecrlf', 'true'],
        repo.path
      )

      const path = repo.path

      await saveGitIgnore(repo, 'node_modules')
      await GitProcess.exec(['add', '.gitignore'], path)

      const commit = await GitProcess.exec(
        ['commit', '-m', 'create the ignore file'],
        path
      )
      expect(commit.exitCode).to.equal(0)

      const contents = await readGitIgnoreAtRoot(repo)
      expect(contents!.endsWith('\r\n'))
    })

    it('when autocrlf=input, appends LF to file', async () => {
      const repo = await setupEmptyRepository()

      // ensure this repository only ever sticks to LF
      await GitProcess.exec(['config', '--local', 'core.eol', 'lf'], repo.path)

      // do not do any conversion of line endings when committing
      await GitProcess.exec(
        ['config', '--local', 'core.autocrlf', 'input'],
        repo.path
      )

      const path = repo.path

      await saveGitIgnore(repo, 'node_modules')
      await GitProcess.exec(['add', '.gitignore'], path)

      const commit = await GitProcess.exec(
        ['commit', '-m', 'create the ignore file'],
        path
      )
      expect(commit.exitCode).to.equal(0)

      const contents = await readGitIgnoreAtRoot(repo)
      expect(contents!.endsWith('\n'))
    })
  })

  describe('saveGitIgnore', () => {
    it(`creates gitignore file when it doesn't exist`, async () => {
      const repo = await setupEmptyRepository()

      await saveGitIgnore(repo, 'node_modules\n')

      const exists = await FSE.pathExists(`${repo.path}/.gitignore`)

      expect(exists).is.true
    })

    it('deletes gitignore file when no entries provided', async () => {
      const repo = await setupEmptyRepository()
      const path = repo.path

      const ignoreFile = `${path}/.gitignore`
      await FSE.writeFile(ignoreFile, 'node_modules\n')

      // update gitignore file to be empty
      await saveGitIgnore(repo, '')

      const exists = await FSE.pathExists(ignoreFile)
      expect(exists).is.false
    })

    it('applies rule correctly to repository', async () => {
      const repo = await setupEmptyRepository()

      const path = repo.path

      await saveGitIgnore(repo, '*.txt\n')
      await GitProcess.exec(['add', '.gitignore'], path)
      await GitProcess.exec(['commit', '-m', 'create the ignore file'], path)

      // Create a txt file
      const file = Path.join(repo.path, 'a.txt')

      await FSE.writeFile(file, 'thrvbnmerkl;,iuw')

      // Check status of repo
      const status = await getStatusOrThrow(repo)
      const files = status.workingDirectory.files

      expect(files.length).to.equal(0)
    })
  })

  describe('appendIgnoreRule', () => {
    it('appends one rule', async () => {
      const repo = await setupEmptyRepository()
      const path = repo.path

      const ignoreFile = `${path}/.gitignore`
      await FSE.writeFile(ignoreFile, 'node_modules\n')

      await appendIgnoreRule(repo, ['yarn-error.log'])

      const gitignore = await FSE.readFile(ignoreFile)

      const expected = 'node_modules\nyarn-error.log\n'
      expect(gitignore.toString('utf8')).equals(expected)
    })

    it('appends multiple rules', async () => {
      const repo = await setupEmptyRepository()
      const path = repo.path

      const ignoreFile = `${path}/.gitignore`
      await FSE.writeFile(ignoreFile, 'node_modules\n')

      await appendIgnoreRule(repo, ['yarn-error.log', '.eslintcache', 'dist/'])

      const gitignore = await FSE.readFile(ignoreFile)

      const expected = 'node_modules\nyarn-error.log\n.eslintcache\ndist/\n'
      expect(gitignore.toString('utf8')).equals(expected)
    })
  })
})
{'fraction_non_alphanumeric': 0.1395784543325527, 'fraction_numerical': 0.000936768149882904, 'mean_word_length': 2.631377551020408, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 25, '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': '109812', 'n_tokens_mistral': 2561, 'n_tokens_neox': 2480, 'n_words': 637}