Skip to content

Commit

Permalink
feat(create-gatsby): TypeScript option (#34611)
Browse files Browse the repository at this point in the history
Co-authored-by: Lennart <lekoarts@gmail.com>
Co-authored-by: Jude Agboola <marvinjudehk@gmail.com>
  • Loading branch information
3 people committed Feb 8, 2022
1 parent 01adaff commit a78ef94
Show file tree
Hide file tree
Showing 11 changed files with 709 additions and 101 deletions.
14 changes: 13 additions & 1 deletion docs/docs/quick-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ This quick start is intended for intermediate to advanced developers. For a gent
npm init gatsby
```

It'll ask for a site title and the name of the project's directory. Continue following the prompts to choose your preferred CMS, styling tools and additional features.
It'll ask for a site title and the name of the project's directory. Continue following the prompts to choose your preferred language (JavaScript or TypeScript), CMS, styling tools and additional features.

2. Once everything is downloaded you will see a message with instructions for navigating to your site and running it locally.

Expand All @@ -38,6 +38,18 @@ Try editing the home page in `src/pages/index.js`. Saved changes will live reloa

## What's next?

### Use flags

The CLI also supports two flags:

- `-y` skips the questionnaire
- `-ts` initializes your project with the [minimal TypeScript starter](https://github.com/gatsbyjs/gatsby-starter-minimal-ts) instead of the [minimal JavaScript starter](https://github.com/gatsbyjs/gatsby-starter-minimal)

Flags are not positional, so these commands are equivalent:

- `npm init gatsby -y -ts my-site-name`
- `npm init gatsby my-site-name -y -ts`

### Add more features

[Follow our guides](/docs/how-to/) to add more functionality to your site or browse [our plugins](/plugins/) to quickly install additional features.
Expand Down
255 changes: 255 additions & 0 deletions packages/create-gatsby/src/__tests__/run.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
import { reporter } from "../utils/reporter"
import { initStarter } from "../init-starter"
import { trackCli } from "../tracking"
import { run, DEFAULT_STARTERS } from "../index"

jest.mock(`../utils/parse-args`)
jest.mock(`enquirer`, () => {
const OriginalEnquirer = jest.requireActual(`enquirer`)

class MockedEnquirer extends OriginalEnquirer {
constructor() {
super()
// Turns waiting for user input off and autofills with answers
this.options = { show: false, autofill: true }

// Mock answers
this.answers = {
// First prompt answer
name: `hello-world`,

// Main question set answers
project: `hello-world`,
language: `js`,
cms: `none`,
styling: `none`,
features: [],

// Confirmation prompt answer
confirm: true,
}
}
}
return MockedEnquirer
})
jest.mock(`../utils/reporter`)
jest.mock(`../tracking`, () => {
return {
trackCli: jest.fn(),
}
})
jest.mock(`../init-starter`, () => {
return {
initStarter: jest.fn(),
getPackageManager: jest.fn(),
gitSetup: jest.fn(),
}
})
jest.mock(`../install-plugins`, () => {
return {
installPlugins: jest.fn(),
}
})
jest.mock(`../utils/site-metadata`, () => {
return {
setSiteMetadata: jest.fn(),
}
})
jest.mock(`../utils/hash`, () => {
return {
sha256: jest.fn(args => args),
md5: jest.fn(args => args),
}
})
jest.mock(`../utils/question-helpers`, () => {
const originalQuestionHelpers = jest.requireActual(
`../utils/question-helpers`
)
return {
...originalQuestionHelpers,
validateProjectName: jest.fn(() => true),
}
})
jest.mock(`../components/utils`, () => {
return {
center: jest.fn(args => args),
wrap: jest.fn(args => args),
}
})

const dirName = `hello-world`
let parseArgsMock

describe(`run`, () => {
beforeEach(() => {
jest.clearAllMocks()
parseArgsMock = require(`../utils/parse-args`).parseArgs
})

describe(`no skip flag`, () => {
beforeEach(() => {
parseArgsMock.mockReturnValueOnce({
flags: { yes: false },
dirName,
})
})

it(`should welcome the user`, async () => {
await run()
expect(reporter.info).toHaveBeenCalledWith(
expect.stringContaining(`Welcome to Gatsby!`)
)
})
it(`should communicate setup questions will be asked`, async () => {
await run()
expect(reporter.info).toHaveBeenCalledWith(
expect.stringContaining(
`This command will generate a new Gatsby site for you`
)
)
})
it(`should confirm actions`, async () => {
await run()
expect(reporter.info).toHaveBeenCalledWith(
expect.stringContaining(`Thanks! Here's what we'll now do`)
)
})
it(`should notify of successful site creation`, async () => {
await run()
expect(reporter.success).toHaveBeenCalledWith(
expect.stringContaining(`Created site`)
)
})
})

describe(`skip flag`, () => {
beforeEach(() => {
parseArgsMock.mockReturnValueOnce({
flags: { yes: true },
dirName,
})
})

it(`should welcome the user`, async () => {
await run()
expect(reporter.info).toHaveBeenCalledWith(
expect.stringContaining(`Welcome to Gatsby!`)
)
})
it(`should not communicate setup questions`, async () => {
await run()
expect(reporter.info).not.toHaveBeenCalledWith(
expect.stringContaining(
`This command will generate a new Gatsby site for you`
)
)
})
it(`should not confirm actions`, async () => {
await run()
expect(reporter.info).not.toHaveBeenCalledWith(
expect.stringContaining(`Thanks! Here's what we'll now do`)
)
})
it(`should notify of successful site creation`, async () => {
await run()
expect(reporter.success).toHaveBeenCalledWith(
expect.stringContaining(`Created site`)
)
})
it(`should use the JS starter by default`, async () => {
await run()
expect(initStarter).toHaveBeenCalledWith(
DEFAULT_STARTERS.js,
dirName,
[],
dirName
)
})
it(`should track JS was selected as language`, async () => {
await run()
expect(trackCli).toHaveBeenCalledWith(`CREATE_GATSBY_SELECT_OPTION`, {
name: `LANGUAGE`,
valueString: `js`,
})
})
})

describe(`no ts flag`, () => {
beforeEach(() => {
parseArgsMock.mockReturnValueOnce({
flags: { ts: false },
dirName,
})
})

it(`should use the JS starter`, async () => {
await run()
expect(initStarter).toHaveBeenCalledWith(
DEFAULT_STARTERS.js,
dirName,
[],
dirName
)
})
it(`should track JS was selected as language`, async () => {
await run()
expect(trackCli).toHaveBeenCalledWith(`CREATE_GATSBY_SELECT_OPTION`, {
name: `LANGUAGE`,
valueString: `js`,
})
})
})

describe(`ts flag`, () => {
beforeEach(() => {
parseArgsMock.mockReturnValueOnce({
flags: { ts: true },
dirName,
})
})

it(`should use the TS starter`, async () => {
await run()
expect(initStarter).toHaveBeenCalledWith(
DEFAULT_STARTERS.ts,
dirName,
[],
dirName
)
})

it(`should track TS was selected as language`, async () => {
await run()
expect(trackCli).toHaveBeenCalledWith(`CREATE_GATSBY_SELECT_OPTION`, {
name: `LANGUAGE`,
valueString: `ts`,
})
})
})
})

describe(`skip and ts flag`, () => {
beforeEach(() => {
parseArgsMock.mockReturnValueOnce({
flags: { yes: true, ts: true },
dirName,
})
})

it(`should use the TS starter`, async () => {
await run()
expect(initStarter).toHaveBeenCalledWith(
DEFAULT_STARTERS.ts,
dirName,
[],
dirName
)
})
it(`should track TS was selected as language`, async () => {
await run()
expect(trackCli).toHaveBeenCalledWith(`CREATE_GATSBY_SELECT_OPTION`, {
name: `LANGUAGE`,
valueString: `ts`,
})
})
})
52 changes: 52 additions & 0 deletions packages/create-gatsby/src/__tests__/utils/parse-args.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { parseArgs } from "../../utils/parse-args"
import { reporter } from "../../utils/reporter"

const dirNameArg = `hello-world`

jest.mock(`../../utils/reporter`)

describe(`parseArgs`, () => {
it(`should parse without flags and dir name`, () => {
const { flags, dirName } = parseArgs([])
expect(flags.yes).toBeFalsy()
expect(flags.ts).toBeFalsy()
expect(dirName).toEqual(``)
})
it(`should parse with dir name without flags`, () => {
const { flags, dirName } = parseArgs([dirNameArg])
expect(flags.yes).toBeFalsy()
expect(flags.ts).toBeFalsy()
expect(dirName).toEqual(dirNameArg)
})
it(`should parse with flags before dir name`, () => {
const { flags, dirName } = parseArgs([`-y`, `-ts`, dirNameArg])
expect(flags.yes).toBeTruthy()
expect(flags.ts).toBeTruthy()
expect(dirName).toEqual(dirNameArg)
})
it(`should parse with flags after dir name`, () => {
const { flags, dirName } = parseArgs([dirNameArg, `-y`, `-ts`])
expect(flags.yes).toBeTruthy()
expect(flags.ts).toBeTruthy()
expect(dirName).toEqual(dirNameArg)
})
it(`should parse with flags before and after dir name`, () => {
const { flags, dirName } = parseArgs([`-y`, dirNameArg, `-ts`])
expect(flags.yes).toBeTruthy()
expect(flags.ts).toBeTruthy()
expect(dirName).toEqual(dirNameArg)
})
it(`should warn if unknown flags are used`, () => {
const unknownFlag = `-unknown`
const { flags, dirName } = parseArgs([dirNameArg, unknownFlag])
expect(reporter.warn).toBeCalledTimes(1)
expect(reporter.warn).toBeCalledWith(
expect.stringContaining(
`Found unknown argument "${unknownFlag}", ignoring. Known arguments are: -y, -ts`
)
)
expect(flags.yes).toBeFalsy()
expect(flags.ts).toBeFalsy()
expect(dirName).toEqual(dirNameArg)
})
})

0 comments on commit a78ef94

Please sign in to comment.