text: 'use strict'
  
  const fs = require('fs')
  const path = require('path')
  const mkdirp = require('mkdirp')
  const rimraf = require('rimraf')
  const tempy = require('tempy')
  const installFrom = require('../src/install')
  const uninstallFrom = require('../src/uninstall')
  const findDepDir = require('../src/utils/find-dep-dir')
  
  function install(rootDir, dir) {
    const depDir = findDepDir(path.join(rootDir, dir))
    installFrom(depDir)
  }
  
  function uninstall(rootDir, dir) {
    const depDir = findDepDir(path.join(rootDir, dir))
    uninstallFrom(depDir)
  }
  
  function mkdir(rootDir, dir) {
    mkdirp.sync(path.join(rootDir, dir))
  }
  
  function writeFile(dir, filePath, data) {
    fs.writeFileSync(path.join(dir, filePath), data)
  }
  
  function readFile(dir, filePath) {
    return fs.readFileSync(path.join(dir, filePath), 'utf-8')
  }
  
  function exists(dir, filePath) {
    return fs.existsSync(path.join(dir, filePath))
  }
  
  describe('yorkie-pnpm', () => {
    let dir
    beforeEach(() => (dir = tempy.directory()))
    afterEach(() => rimraf.sync(dir))
  
    it('should support basic layout', () => {
      mkdir(dir, '.git/hooks')
      mkdir(dir, 'node_modules/yorkie-pnpm')
      writeFile(dir, 'package.json', '{}')
  
      install(dir, '/node_modules/yorkie-pnpm')
      const hook = readFile(dir, '.git/hooks/pre-commit')
  
      expect(hook).toMatch('#yorkie-pnpm')
      expect(hook).toMatch('cd "."')
      expect(hook).toMatch(`node "./node_modules/yorkie-pnpm/src/runner.js" pre-commit`)
      expect(hook).toMatch('--no-verify')
  
      const prepareCommitMsg = readFile(dir, '.git/hooks/prepare-commit-msg')
      expect(prepareCommitMsg).toMatch('cannot be bypassed')
  
      uninstall(dir, 'node_modules/yorkie-pnpm')
      expect(exists(dir, '.git/hooks/pre-push')).toBeFalsy()
    })
  
    it('should not install git hooks when installed in sub directory', () => {
      mkdir(dir, '.git/hooks')
      mkdir(dir, 'A/B/node_modules/yorkie-pnpm')
      writeFile(dir, 'A/B/package.json', '{}')
  
      install(dir, 'A/B/node_modules/yorkie-pnpm')
      expect(exists(dir, '.git/hooks/pre-commit')).toBeFalsy()
    })
  
    it('should support git submodule', () => {
      mkdir(dir, '.git/modules/A/B')
      mkdir(dir, 'A/B/node_modules/yorkie-pnpm')
      writeFile(dir, 'package.json', '{}')
      writeFile(dir, 'A/B/package.json', '{}')
      writeFile(dir, 'A/B/.git', 'git: ../../.git/modules/A/B')
  
      install(dir, 'A/B/node_modules/yorkie-pnpm')
      const hook = readFile(dir, '.git/modules/A/B/hooks/pre-commit')
  
      expect(hook).toMatch('cd "."')
  
      uninstall(dir, 'A/B/node_modules/yorkie-pnpm')
      expect(exists(dir, '.git/hooks/pre-push')).toBeFalsy()
    })
  
    it('should not install git hooks in submodule sub directory', () => {
      mkdir(dir, '.git/modules/A/B')
      mkdir(dir, 'A/B/C/node_modules/yorkie-pnpm')
      writeFile(dir, 'package.json', '{}')
      writeFile(dir, 'A/B/C/package.json', '{}')
      writeFile(dir, 'A/B/.git', 'git: ../../.git/modules/A/B')
  
      install(dir, 'A/B/C/node_modules/yorkie-pnpm')
      expect(exists(dir, '.git/modules/A/B/hooks/pre-commit')).toBeFalsy()
    })
  
    it('should support git worktrees', () => {
      mkdir(dir, '.git/worktrees/B')
      mkdir(dir, 'A/B/node_modules/yorkie-pnpm')
      writeFile(dir, 'package.json', '{}')
      writeFile(dir, 'A/B/package.json', '{}')
  
      // Git path for worktrees is absolute
      const absolutePath = path.join(dir, '.git/worktrees/B')
      writeFile(dir, 'A/B/.git', `git: ${absolutePath}`)
  
      install(dir, 'A/B/node_modules/yorkie-pnpm')
      const hook = readFile(dir, '.git/worktrees/B/hooks/pre-commit')
  
      expect(hook).toMatch('cd "."')
  
      uninstall(dir, 'A/B/node_modules/yorkie-pnpm')
      expect(exists(dir, '.git/hooks/pre-commit')).toBeFalsy()
    })
  
    it('should not modify user hooks', () => {
      mkdir(dir, '.git/hooks')
      mkdir(dir, 'node_modules/yorkie-pnpm')
      writeFile(dir, '.git/hooks/pre-push', 'foo')
  
      // Verify that it's not overwritten
      install(dir, 'node_modules/yorkie-pnpm')
      const hook = readFile(dir, '.git/hooks/pre-push')
      expect(hook).toBe('foo')
  
      uninstall(dir, 'node_modules/yorkie-pnpm')
      expect(exists(dir, '.git/hooks/pre-push')).toBeTruthy()
    })
  
    it('should not install from /node_modules/A/node_modules', () => {
      mkdir(dir, '.git/hooks')
      mkdir(dir, 'node_modules/A/node_modules/yorkie-pnpm')
  
      install(dir, 'node_modules/A/node_modules/yorkie-pnpm')
      expect(exists(dir, '.git/hooks/pre-push')).toBeFalsy()
    })
  
    it("should not crash if there's no .git directory", () => {
      mkdir(dir, 'node_modules/yorkie-pnpm')
  
      expect(() => install(dir, 'node_modules/yorkie-pnpm')).not.toThrow()
      expect(() => uninstall(dir, 'node_modules/yorkie-pnpm')).not.toThrow()
    })
  
    it('should migrate existing scripts (ghooks)', () => {
      mkdir(dir, '.git/hooks')
      writeFile(dir, 'package.json', '{}')
      mkdir(dir, '/node_modules/yorkie-pnpm')
      writeFile(
        dir,
        '.git/hooks/pre-commit',
        '// Generated by ghooks. Do not edit this file.'
      )
  
      install(dir, 'node_modules/yorkie-pnpm')
      const hook = readFile(dir, '.git/hooks/pre-commit')
      expect(hook).toMatch('yorkie-pnpm')
      expect(hook).not.toMatch('ghooks')
    })
  
    it('should migrate existing scripts (pre-commit)', () => {
      mkdir(dir, '.git/hooks')
      writeFile(dir, 'package.json', '{}')
      mkdir(dir, '/node_modules/yorkie-pnpm')
      writeFile(dir, '.git/hooks/pre-commit', './node_modules/pre-commit/hook')
  
      install(dir, 'node_modules/yorkie-pnpm')
      const hook = readFile(dir, '.git/hooks/pre-commit')
      expect(hook).toMatch('yorkie-pnpm')
      expect(hook).not.toMatch('./node_modules/pre-commit/hook')
    })
  
    it('should support installing from pnpm', () => {
      mkdir(dir, '.git/hooks')
      mkdir(dir, 'node_modules/.pnpm/registry.npmmirror.com+yorkie-pnpm@2.0.0/node_modules/yorkie-pnpm')
      writeFile(dir, 'package.json', '{}')
  
      install(dir, 'node_modules/.pnpm/registry.npmmirror.com+yorkie-pnpm@2.0.0/node_modules/yorkie-pnpm')
      const hook = readFile(dir, '.git/hooks/pre-commit')
  
      expect(hook).toMatch('#yorkie-pnpm')
      expect(hook).toMatch('cd "."')
      expect(hook).toMatch('--no-verify')
  
      const prepareCommitMsg = readFile(dir, '.git/hooks/prepare-commit-msg')
      expect(prepareCommitMsg).toMatch('cannot be bypassed')
  
      uninstall(dir, 'node_modules/.pnpm/registry.npmmirror.com+yorkie-pnpm@2.0.0/node_modules/yorkie-pnpm')
      expect(exists(dir, '.git/hooks/pre-push')).toBeFalsy()
    })
  })
  