Skip to content

Commit

Permalink
Merge pull request #14 from nemuvski/testing
Browse files Browse the repository at this point in the history
各コマンドの実行フローのテストコード
  • Loading branch information
nemuvski authored Aug 7, 2023
2 parents 5c3ea24 + 85bccc3 commit a37702b
Show file tree
Hide file tree
Showing 14 changed files with 397 additions and 25 deletions.
12 changes: 12 additions & 0 deletions test/__constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* 一時的にファイルを格納しておくディレクトリ名
*/
const TMP_FILE_DIRNAME = '__testing-tmp__'

const PACKAGEJSON_FILENAME = 'package.json'

const GITHUB_HOST = 'https://github.com'

const MOCK_RESPONSE_HEADERS = { 'Content-Type': 'application/zip' }

export { TMP_FILE_DIRNAME, PACKAGEJSON_FILENAME, GITHUB_HOST, MOCK_RESPONSE_HEADERS }
3 changes: 3 additions & 0 deletions test/__stubs__/boilerplate/gatsbyjs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "stub-gatsbyjs"
}
56 changes: 56 additions & 0 deletions test/__stubs__/boilerplate/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import AdmZip from 'adm-zip'
import * as path from 'node:path'

const basePath = path.resolve(__dirname)

/**
* @param zipFolderNameInArchive zipファイル内のフォルダ名
* @see {import('../../../src/generator/base').TemplateGenerator.getUnzippedDirectoryPath()} フォルダ名を揃えること
*/
function reactjsZip(zipFolderNameInArchive: string = 'reactjs-boilerplate-main') {
const zip = new AdmZip()
zip.addLocalFolder(path.join(basePath, 'reactjs'), zipFolderNameInArchive)
return zip
}

/**
* @param zipFolderNameInArchive zipファイル内のフォルダ名
* @see {import('../../../src/generator/base').TemplateGenerator.getUnzippedDirectoryPath()} フォルダ名を揃えること
*/
function nextjsZip(zipFolderNameInArchive: string = 'nextjs-boilerplate-main') {
const zip = new AdmZip()
zip.addLocalFolder(path.join(basePath, 'nextjs'), zipFolderNameInArchive)
return zip
}

/**
* @param zipFolderNameInArchive zipファイル内のフォルダ名
* @see {import('../../../src/generator/base').TemplateGenerator.getUnzippedDirectoryPath()} フォルダ名を揃えること
*/
function remixjsZip(zipFolderNameInArchive: string = 'remixjs-boilerplate-main') {
const zip = new AdmZip()
zip.addLocalFolder(path.join(basePath, 'remixjs'), zipFolderNameInArchive)
return zip
}

/**
* @param zipFolderNameInArchive zipファイル内のフォルダ名
* @see {import('../../../src/generator/base').TemplateGenerator.getUnzippedDirectoryPath()} フォルダ名を揃えること
*/
function gatsbyjsZip(zipFolderNameInArchive: string = 'gatsbyjs-boilerplate-main') {
const zip = new AdmZip()
zip.addLocalFolder(path.join(basePath, 'gatsbyjs'), zipFolderNameInArchive)
return zip
}

/**
* @param zipFolderNameInArchive zipファイル内のフォルダ名
* @see {import('../../../src/generator/base').TemplateGenerator.getUnzippedDirectoryPath()} フォルダ名を揃えること
*/
function sveltejsZip(zipFolderNameInArchive: string = 'sveltejs-boilerplate-main') {
const zip = new AdmZip()
zip.addLocalFolder(path.join(basePath, 'sveltejs'), zipFolderNameInArchive)
return zip
}

export { reactjsZip, nextjsZip, remixjsZip, gatsbyjsZip, sveltejsZip }
3 changes: 3 additions & 0 deletions test/__stubs__/boilerplate/nextjs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "stub-nextjs"
}
3 changes: 3 additions & 0 deletions test/__stubs__/boilerplate/reactjs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "stub-reactjs"
}
3 changes: 3 additions & 0 deletions test/__stubs__/boilerplate/remixjs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "stub-remixjs"
}
3 changes: 3 additions & 0 deletions test/__stubs__/boilerplate/sveltejs/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "stub-sveltejs"
}
18 changes: 18 additions & 0 deletions test/__stubs__/tmp-promise/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { DirectoryResult } from 'tmp-promise'

function stubTmpdir(tmpPath: string) {
return () => tmpPath
}

function stubDir(tmpPath: string) {
return async () => {
return {
path: tmpPath,
cleanup: async () => {
return
},
} as DirectoryResult
}
}

export { stubTmpdir, stubDir }
1 change: 1 addition & 0 deletions test/__testing-tmp__/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
テスト時に利用する一時ファイルの保存先です。
64 changes: 59 additions & 5 deletions test/commands/gatsby.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,65 @@
import { expect, test } from '@oclif/test'
import { RequiredArgsError } from '@oclif/core/lib/parser/errors'
import path from 'node:path'
import { GITHUB_HOST, MOCK_RESPONSE_HEADERS, PACKAGEJSON_FILENAME, TMP_FILE_DIRNAME } from '../__constants'
import * as fs from '../../src/utils/fs'
import tmpPromise from 'tmp-promise'
import { stubDir, stubTmpdir } from '../__stubs__/tmp-promise'
import { gatsbyjsZip } from '../__stubs__/boilerplate'
import { jsonParse } from '../../src/utils/json'

describe('[CMD] gatsby', () => {
test
.command(['gatsby'])
.catch((error) => {
expect(error instanceof RequiredArgsError).to.true
describe('Missing project name', () => {
test
.command(['gatsby'])
.catch((error) => {
expect(error instanceof RequiredArgsError).to.true
})
.it('project nameが未入力')
})

describe('Checking flow', () => {
const fakeName = '__testing__gatsbyjs__'

const generatedDirPath = path.resolve(process.cwd(), fakeName)
const tmpPath = path.resolve(__dirname, '..', TMP_FILE_DIRNAME, fakeName)

beforeEach(async () => {
if (fs.existsSync(tmpPath)) {
await fs.rm(tmpPath, { recursive: true, force: true })
await fs.mkdir(tmpPath, { recursive: true })
} else {
await fs.mkdir(tmpPath, { recursive: true })
}
})
.it('project nameが未入力')

afterEach(async () => {
if (fs.existsSync(tmpPath)) {
await fs.rm(tmpPath, { recursive: true, force: true })
}
// 生成されたディレクトリを削除
if (fs.existsSync(generatedDirPath)) {
await fs.rm(generatedDirPath, { recursive: true, force: true })
}
})

test
.stdout()
.stderr()
.stub(tmpPromise, 'tmpdir', stubTmpdir(tmpPath))
.stub(tmpPromise, 'dir', stubDir(tmpPath))
.nock(GITHUB_HOST, (api) => {
api
.get('/nemuvski/gatsbyjs-boilerplate/archive/main.zip')
.reply(200, gatsbyjsZip().toBuffer(), MOCK_RESPONSE_HEADERS)
})
.command(['gatsby', fakeName])
.it('プロジェクトのディレクトリを作成し、package.jsonの情報が書き換わる', async () => {
const packageJsonPath = path.join(generatedDirPath, PACKAGEJSON_FILENAME)
expect(fs.existsSync(packageJsonPath)).to.true
const rawData = await fs.readFile(packageJsonPath, { encoding: 'utf-8' })
const jsonData = jsonParse<{ name: string }>(rawData)
expect(jsonData.name).to.equal(fakeName)
})
})
})
64 changes: 59 additions & 5 deletions test/commands/next.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,65 @@
import { expect, test } from '@oclif/test'
import { RequiredArgsError } from '@oclif/core/lib/parser/errors'
import path from 'node:path'
import { PACKAGEJSON_FILENAME, TMP_FILE_DIRNAME, GITHUB_HOST, MOCK_RESPONSE_HEADERS } from '../__constants'
import * as fs from '../../src/utils/fs'
import tmpPromise from 'tmp-promise'
import { stubDir, stubTmpdir } from '../__stubs__/tmp-promise'
import { nextjsZip } from '../__stubs__/boilerplate'
import { jsonParse } from '../../src/utils/json'

describe('[CMD] next', () => {
test
.command(['next'])
.catch((error) => {
expect(error instanceof RequiredArgsError).to.true
describe('Missing project name', () => {
test
.command(['next'])
.catch((error) => {
expect(error instanceof RequiredArgsError).to.true
})
.it('project nameが未入力')
})

describe('Checking flow', () => {
const fakeName = '__testing__nextjs__'

const generatedDirPath = path.resolve(process.cwd(), fakeName)
const tmpPath = path.resolve(__dirname, '..', TMP_FILE_DIRNAME, fakeName)

beforeEach(async () => {
if (fs.existsSync(tmpPath)) {
await fs.rm(tmpPath, { recursive: true, force: true })
await fs.mkdir(tmpPath, { recursive: true })
} else {
await fs.mkdir(tmpPath, { recursive: true })
}
})
.it('project nameが未入力')

afterEach(async () => {
if (fs.existsSync(tmpPath)) {
await fs.rm(tmpPath, { recursive: true, force: true })
}
// 生成されたディレクトリを削除
if (fs.existsSync(generatedDirPath)) {
await fs.rm(generatedDirPath, { recursive: true, force: true })
}
})

test
.stdout()
.stderr()
.stub(tmpPromise, 'tmpdir', stubTmpdir(tmpPath))
.stub(tmpPromise, 'dir', stubDir(tmpPath))
.nock(GITHUB_HOST, (api) => {
api
.get('/nemuvski/nextjs-boilerplate/archive/main.zip')
.reply(200, nextjsZip().toBuffer(), MOCK_RESPONSE_HEADERS)
})
.command(['next', fakeName])
.it('プロジェクトのディレクトリを作成し、package.jsonの情報が書き換わる', async () => {
const packageJsonPath = path.join(generatedDirPath, PACKAGEJSON_FILENAME)
expect(fs.existsSync(packageJsonPath)).to.true
const rawData = await fs.readFile(packageJsonPath, { encoding: 'utf-8' })
const jsonData = jsonParse<{ name: string }>(rawData)
expect(jsonData.name).to.equal(fakeName)
})
})
})
64 changes: 59 additions & 5 deletions test/commands/react.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,65 @@
import { expect, test } from '@oclif/test'
import { RequiredArgsError } from '@oclif/core/lib/parser/errors'
import tmpPromise from 'tmp-promise'
import * as path from 'node:path'
import * as fs from '../../src/utils/fs'
import { jsonParse } from '../../src/utils/json'
import { stubDir, stubTmpdir } from '../__stubs__/tmp-promise'
import { PACKAGEJSON_FILENAME, TMP_FILE_DIRNAME, GITHUB_HOST, MOCK_RESPONSE_HEADERS } from '../__constants'
import { reactjsZip } from '../__stubs__/boilerplate'

describe('[CMD] react', () => {
test
.command(['react'])
.catch((error) => {
expect(error instanceof RequiredArgsError).to.true
describe('Missing project name', () => {
test
.command(['react'])
.catch((error) => {
expect(error instanceof RequiredArgsError).to.true
})
.it('project nameが未入力')
})

describe('Checking flow', () => {
const fakeName = '__testing__reactjs__'

const generatedDirPath = path.resolve(process.cwd(), fakeName)
const tmpPath = path.resolve(__dirname, '..', TMP_FILE_DIRNAME, fakeName)

beforeEach(async () => {
if (fs.existsSync(tmpPath)) {
await fs.rm(tmpPath, { recursive: true, force: true })
await fs.mkdir(tmpPath, { recursive: true })
} else {
await fs.mkdir(tmpPath, { recursive: true })
}
})
.it('project nameが未入力')

afterEach(async () => {
if (fs.existsSync(tmpPath)) {
await fs.rm(tmpPath, { recursive: true, force: true })
}
// 生成されたディレクトリを削除
if (fs.existsSync(generatedDirPath)) {
await fs.rm(generatedDirPath, { recursive: true, force: true })
}
})

test
.stdout()
.stderr()
.stub(tmpPromise, 'tmpdir', stubTmpdir(tmpPath))
.stub(tmpPromise, 'dir', stubDir(tmpPath))
.nock(GITHUB_HOST, (api) => {
api
.get('/nemuvski/reactjs-boilerplate/archive/main.zip')
.reply(200, reactjsZip().toBuffer(), MOCK_RESPONSE_HEADERS)
})
.command(['react', fakeName])
.it('プロジェクトのディレクトリを作成し、package.jsonの情報が書き換わる', async () => {
const packageJsonPath = path.join(generatedDirPath, PACKAGEJSON_FILENAME)
expect(fs.existsSync(packageJsonPath)).to.true
const rawData = await fs.readFile(packageJsonPath, { encoding: 'utf-8' })
const jsonData = jsonParse<{ name: string }>(rawData)
expect(jsonData.name).to.equal(fakeName)
})
})
})
64 changes: 59 additions & 5 deletions test/commands/remix.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,65 @@
import { expect, test } from '@oclif/test'
import { RequiredArgsError } from '@oclif/core/lib/parser/errors'
import path from 'node:path'
import { GITHUB_HOST, MOCK_RESPONSE_HEADERS, PACKAGEJSON_FILENAME, TMP_FILE_DIRNAME } from '../__constants'
import * as fs from '../../src/utils/fs'
import tmpPromise from 'tmp-promise'
import { stubDir, stubTmpdir } from '../__stubs__/tmp-promise'
import { remixjsZip } from '../__stubs__/boilerplate'
import { jsonParse } from '../../src/utils/json'

describe('[CMD] remix', () => {
test
.command(['remix'])
.catch((error) => {
expect(error instanceof RequiredArgsError).to.true
describe('Missing project name', () => {
test
.command(['remix'])
.catch((error) => {
expect(error instanceof RequiredArgsError).to.true
})
.it('project nameが未入力')
})

describe('Checking flow', () => {
const fakeName = '__testing__remixjs__'

const generatedDirPath = path.resolve(process.cwd(), fakeName)
const tmpPath = path.resolve(__dirname, '..', TMP_FILE_DIRNAME, fakeName)

beforeEach(async () => {
if (fs.existsSync(tmpPath)) {
await fs.rm(tmpPath, { recursive: true, force: true })
await fs.mkdir(tmpPath, { recursive: true })
} else {
await fs.mkdir(tmpPath, { recursive: true })
}
})
.it('project nameが未入力')

afterEach(async () => {
if (fs.existsSync(tmpPath)) {
await fs.rm(tmpPath, { recursive: true, force: true })
}
// 生成されたディレクトリを削除
if (fs.existsSync(generatedDirPath)) {
await fs.rm(generatedDirPath, { recursive: true, force: true })
}
})

test
.stdout()
.stderr()
.stub(tmpPromise, 'tmpdir', stubTmpdir(tmpPath))
.stub(tmpPromise, 'dir', stubDir(tmpPath))
.nock(GITHUB_HOST, (api) => {
api
.get('/nemuvski/remixjs-boilerplate/archive/main.zip')
.reply(200, remixjsZip().toBuffer(), MOCK_RESPONSE_HEADERS)
})
.command(['remix', fakeName])
.it('プロジェクトのディレクトリを作成し、package.jsonの情報が書き換わる', async () => {
const packageJsonPath = path.join(generatedDirPath, PACKAGEJSON_FILENAME)
expect(fs.existsSync(packageJsonPath)).to.true
const rawData = await fs.readFile(packageJsonPath, { encoding: 'utf-8' })
const jsonData = jsonParse<{ name: string }>(rawData)
expect(jsonData.name).to.equal(fakeName)
})
})
})
Loading

0 comments on commit a37702b

Please sign in to comment.