Skip to content

Instantly share code, notes, and snippets.

@gfargo
Last active September 6, 2022 17:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gfargo/adfdaab954dc8d256c24924dc7c18c82 to your computer and use it in GitHub Desktop.
Save gfargo/adfdaab954dc8d256c24924dc7c18c82 to your computer and use it in GitHub Desktop.
Github Co-Pilot wrote all the tests...

Using Github Co-Pilot to write my Tests 🧪

Premise 🦾🤖

Can I speed up the process of writing tests for helper methods that I've just extracted from a Hook or Component 🤔🤨

Process ⚙️

I started by extracting the helper methods I had previously written inside the React Hook or Component into a seperate file adding exports & passing additional required variables.

Once I had functioning extracted functions I created a test file with the desired imports and a series of comments e.g.

import {
  extractFieldIds,
  getStep,
  getStepId,
  getStepIndex,
  getStepType,
} from "../../utils/helpers"

// Write tests for `getStep` method.
...

I then clicked through each comment ♻️🤖 refreshing completions

Results 🎉

The attached code is the final "fully-passing" versions of both the utility methods & tests, although it's worth mentioning the only modifications I've made to the tests generated by Co-Pilot were minor modifications e.g. switching a toBe to toBeStrictEqual etc.

It took me 2 revisions which involved;

  1. making minor code modifications
  2. re-run jest
  3. observe.

✅🎉✅🎉✅

After the third run I had green on all tests and 💯% code coverage

✅🎉✅🎉✅

import {
extractFieldIds,
getStep,
getStepId,
getStepIndex,
getStepType,
} from "../../utils/helpers"
// Write tests for `getStep` method.
describe(`getStep`, () => {
it(`returns the step at the given index`, () => {
const stepIndex = 0
const config = {
steps: [
{
stepId: `step-id`,
stepType: `form`,
content: {
fields: [],
},
},
],
}
const step = getStep(stepIndex, config)
expect(step).toStrictEqual({
stepId: `step-id`,
stepType: `form`,
content: {
fields: [],
},
})
})
it(`returns undefined if the step index is out of bounds`, () => {
const stepIndex = 1
const config = {
steps: [
{
stepId: `step-id`,
stepType: `form`,
content: {
fields: [],
},
},
],
}
const step = getStep(stepIndex, config)
expect(step).toBeUndefined()
})
it(`returns undefined if the config is undefined`, () => {
const stepIndex = 0
const config = undefined
const step = getStep(stepIndex, config)
expect(step).toBeUndefined()
})
it(`returns undefined if the config is null`, () => {
const stepIndex = 0
const config = null
const step = getStep(stepIndex, config)
expect(step).toBeUndefined()
})
it(`returns undefined if the config has no steps`, () => {
const stepIndex = 0
const config = {
steps: [],
}
const step = getStep(stepIndex, config)
expect(step).toBeUndefined()
})
it(`returns undefined if the config has no steps at the given index`, () => {
const stepIndex = 1
const config = {
steps: [
{
stepId: `step-id`,
stepType: `form`,
content: {
fields: [],
},
},
],
}
const step = getStep(stepIndex, config)
expect(step).toBeUndefined()
})
})
// write tests for `extractFieldIds` method.
describe(`extractFieldIds`, () => {
it(`returns an array of field ids`, () => {
const step = {
stepId: `step-id`,
stepType: `form`,
content: {
fields: [
{
fieldId: `field-id`,
},
],
},
}
const fieldIds = extractFieldIds(step)
expect(fieldIds).toStrictEqual([`field-id`])
})
it(`returns an empty array if the step is not a form`, () => {
const step = {
stepId: `step-id`,
stepType: `not-a-form`,
content: {
fields: [],
},
}
const fieldIds = extractFieldIds(step)
expect(fieldIds).toStrictEqual([])
})
it(`returns an empty array if the step has no content`, () => {
const step = {
stepId: `step-id`,
stepType: `form`,
content: {},
}
const fieldIds = extractFieldIds(step)
expect(fieldIds).toStrictEqual([])
})
it(`returns an empty array if the step has no fields`, () => {
const step = {
stepId: `step-id`,
stepType: `form`,
content: {
fields: [],
},
}
const fieldIds = extractFieldIds(step)
expect(fieldIds).toStrictEqual([])
})
})
// write tests for `getStepType` method.
describe(`getStepType`, () => {
it(`returns the step type`, () => {
const stepIndex = 0
const config = {
steps: [
{
stepId: `step-id`,
stepType: `form`,
content: {
fields: [],
},
},
],
}
const stepType = getStepType(stepIndex, config)
expect(stepType).toBe(`form`)
})
it(`returns undefined if the step index is out of bounds`, () => {
const stepIndex = 1
const config = {
steps: [
{
stepId: `step-id`,
stepType: `form`,
content: {
fields: [],
},
},
],
}
const stepType = getStepType(stepIndex, config)
expect(stepType).toBeUndefined()
})
it(`returns undefined if the config is undefined`, () => {
const stepIndex = 0
const config = undefined
const stepType = getStepType(stepIndex, config)
expect(stepType).toBeUndefined()
})
it(`returns undefined if the config is null`, () => {
const stepIndex = 0
const config = null
const stepType = getStepType(stepIndex, config)
expect(stepType).toBeUndefined()
})
it(`returns undefined if the config has no steps`, () => {
const stepIndex = 0
const config = {
steps: [],
}
const stepType = getStepType(stepIndex, config)
expect(stepType).toBeUndefined()
})
it(`returns undefined if the config has no steps at the given index`, () => {
const stepIndex = 1
const config = {
steps: [
{
stepId: `step-id`,
stepType: `form`,
content: {
fields: [],
},
},
],
}
const stepType = getStepType(stepIndex, config)
expect(stepType).toBeUndefined()
})
})
// write tests for `getStepId` method
describe(`getStepId`, () => {
it(`returns the step id`, () => {
const stepIndex = 0
const config = {
steps: [
{
stepId: `step-id`,
stepType: `form`,
content: {
fields: [],
},
},
],
}
const stepId = getStepId(stepIndex, config)
expect(stepId).toBe(`step-id`)
})
it(`returns undefined if the step index is out of bounds`, () => {
const stepIndex = 1
const config = {
steps: [
{
stepId: `step-id`,
stepType: `form`,
content: {
fields: [],
},
},
],
}
const stepId = getStepId(stepIndex, config)
expect(stepId).toBeUndefined()
})
it(`returns undefined if the config is undefined`, () => {
const stepIndex = 0
const config = undefined
const stepId = getStepId(stepIndex, config)
expect(stepId).toBeUndefined()
})
it(`returns undefined if the config is null`, () => {
const stepIndex = 0
const config = null
const stepId = getStepId(stepIndex, config)
expect(stepId).toBeUndefined()
})
it(`returns undefined if the config has no steps`, () => {
const stepIndex = 0
const config = {
steps: [],
}
const stepId = getStepId(stepIndex, config)
expect(stepId).toBeUndefined()
})
it(`returns undefined if the config has no steps at the given index`, () => {
const stepIndex = 1
const config = {
steps: [
{
stepId: `step-id`,
stepType: `form`,
content: {
fields: [],
},
},
],
}
const stepId = getStepId(stepIndex, config)
expect(stepId).toBeUndefined()
})
})
// write tests for `getStepIndex` method
describe(`getStepIndex`, () => {
it(`returns the step index`, () => {
const stepId = `step-id`
const config = {
steps: [
{
stepId: `step-id`,
stepType: `form`,
content: {
fields: [],
},
},
],
}
const stepIndex = getStepIndex(stepId, config)
expect(stepIndex).toBe(0)
})
it(`returns undefined if the step id is not found`, () => {
const stepId = `not-a-step-id`
const config = {
steps: [
{
stepId: `step-id`,
stepType: `form`,
content: {
fields: [],
},
},
],
}
const stepIndex = getStepIndex(stepId, config)
expect(stepIndex).toBeUndefined()
})
it(`returns undefined if the config is undefined`, () => {
const stepId = `step-id`
const config = undefined
const stepIndex = getStepIndex(stepId, config)
expect(stepIndex).toBeUndefined()
})
it(`returns undefined if the config is null`, () => {
const stepId = `step-id`
const config = null
const stepIndex = getStepIndex(stepId, config)
expect(stepIndex).toBeUndefined()
})
it(`returns undefined if the config has no steps`, () => {
const stepId = `step-id`
const config = {
steps: [],
}
const stepIndex = getStepIndex(stepId, config)
expect(stepIndex).toBeUndefined()
})
it(`returns undefined if the config has no steps with the given id`, () => {
const stepId = `not-a-step-id`
const config = {
steps: [
{
stepId: `step-id`,
stepType: `form`,
content: {
fields: [],
},
},
],
}
const stepIndex = getStepIndex(stepId, config)
expect(stepIndex).toBeUndefined()
})
})
import { OkaydFormConfig, OkaydFormStep } from "../types"
// TODO: Write tests for this. - @gfargo
export const getStep = (
stepIndex: number,
config: OkaydFormConfig,
): OkaydFormStep => config?.steps[stepIndex]
export const getStepId = (stepIndex: number, config: OkaydFormConfig): string =>
getStep(stepIndex, config)?.stepId || undefined
export const getStepIndex = (
stepId: string,
config: OkaydFormConfig,
): number => {
const stepIndex = config?.steps?.findIndex(step => step.stepId === stepId)
return stepIndex >= 0 ? stepIndex : undefined
}
export const getStepType = (
stepIndex: number,
config: OkaydFormConfig,
): string => getStep(stepIndex, config)?.stepType || undefined
export const extractFieldIds = (step: OkaydFormStep): string[] =>
(step.stepType === `form` &&
step?.content?.fields?.map(field => field.fieldId)) ||
[]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment