Skip to content

Commit

Permalink
🧪 test(none): improve @roots/bud-react coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
kellymears committed Jun 27, 2024
1 parent e528871 commit 599273b
Show file tree
Hide file tree
Showing 13 changed files with 417 additions and 71 deletions.
3 changes: 2 additions & 1 deletion sources/@roots/bud-react/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@
"@types/babel__core": "7.20.5",
"@types/node": "20.12.8",
"@types/react": "18.3.1",
"@types/react-dom": "18.3.0"
"@types/react-dom": "18.3.0",
"vitest": "1.6.0"
},
"dependencies": {
"@babel/preset-react": "7.24.1",
Expand Down
2 changes: 1 addition & 1 deletion sources/@roots/bud-react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ declare module '@roots/bud-framework' {
}
}

export default BudReact
export {default} from '@roots/bud-react/extension'
46 changes: 16 additions & 30 deletions sources/@roots/bud-react/src/react-refresh/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,16 +84,15 @@ export default class BudReactRefresh extends Extension<
*/
@bind
public override async configAfter(bud: Bud) {
if (!this.isEnabled()) return
if (bud.context.mode !== `development`) return
if (bud.context.hot === false) return
if (!bud.isDevelopment) return
if (!(`hot` in bud.server.enabledMiddleware)) return

if (!this.compilerExtension) {
const signifier = bud.swc
const signifier = bud.swc?.enabled
? `@roots/bud-react/swc-refresh`
: bud.typescript && bud.typescript.babel === false
: bud.typescript?.enabled && bud.typescript.babel === false
? `@roots/bud-react/typescript-refresh`
: bud.babel || bud.typescript?.babel === true
: bud.babel?.enabled || bud.typescript?.babel === true
? `@roots/bud-react/babel-refresh`
: false

Expand All @@ -117,10 +116,10 @@ export default class BudReactRefresh extends Extension<
*/
@bind
public override async make(
bud: Bud,
_bud: Bud,
options: Options,
): Promise<RefreshPlugin> {
return new RefreshPlugin(omit(this.options, [`compilerExtension`]))
return new RefreshPlugin(omit(options, [`compilerExtension`]))
}

/**
Expand Down Expand Up @@ -154,30 +153,17 @@ export default class BudReactRefresh extends Extension<
*/
@bind
public configure(userOptions?: false | Options): this {
this.app.hooks.action(
`config.after`,
this.makeReactRefreshCallback(userOptions),
)

return this
}

/**
* Callback handling {@link RefreshPlugin} configuration
*/
@bind
protected makeReactRefreshCallback(
userOptions?: false | Options,
): (bud: Bud) => Promise<unknown> {
return async () => {
if (!this.app.isDevelopment) return this
if (userOptions === false || !this.app.isDevelopment) {
this.enable(false)
return
}

if (!isUndefined(userOptions) && !isBoolean(userOptions))
this.setOptions(userOptions)
this.enable(true)

userOptions === false ? this.enable(false) : this.enable()
this.app.hooks.action(`config.after`, async () => {
this.setOptions(userOptions)
})

return this
}
return this
}
}
10 changes: 2 additions & 8 deletions sources/@roots/bud-react/src/swc-refresh/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import {
@development
export default class BudSWCRefresh extends Extension {
/**
* {@link Extension.buildBefore}
* {@link Extension.register}
*/
@bind
public override async buildBefore(bud: Bud) {
public override async register(bud: Bud) {
await this.registerTransform(bud)
}

Expand All @@ -26,12 +26,6 @@ export default class BudSWCRefresh extends Extension {
*/
public async registerTransform({isDevelopment, swc}: Bud) {
this.logger.log(`Registering swc react-refresh transformer`)
if (!swc) {
this.logger.warn(
`SWC not found. Skipping registration of ${this.constructor.name}.`,
)
return this
}

swc.setTransform((transform = {}) => ({
...(transform ?? {}),
Expand Down
10 changes: 2 additions & 8 deletions sources/@roots/bud-react/src/typescript-refresh/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import {
@development
export default class BudTypeScriptRefresh extends Extension {
/**
* {@link Extension.buildBefore}
* {@link Extension.register}
*/
@bind
public override async buildBefore(bud: Bud) {
public override async register(bud: Bud) {
this.registerTransform(bud)
}

Expand All @@ -27,12 +27,6 @@ export default class BudTypeScriptRefresh extends Extension {
@bind
public async registerTransform(bud: Bud) {
this.logger.log(`Registering react-refresh-typescript transformer`)
if (!bud.typescript) {
this.logger.warn(
`Typescript not found. Skipping registration of ${this.constructor.name}.`,
)
return this
}

const transform = await this.import(
`react-refresh-typescript`,
Expand Down
43 changes: 39 additions & 4 deletions sources/@roots/bud-react/test/babel-refresh/extension.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,43 @@
import Extension from '@roots/bud-react/babel-refresh'
import {describe, expect, it} from 'vitest'
import {beforeEach, describe, expect, it, vi} from 'vitest'

import Extension from '../../src/babel-refresh'

describe(`@roots/bud-react/babel-refresh`, () => {
it(`should be constructable`, () => {
expect(Extension).toBeInstanceOf(Function)
let bud: any
let extension: Extension
beforeEach(async () => {
bud = {
babel: {
setPlugin: vi.fn(),
},
module: {
resolve: vi.fn(async (...args) => `/test/path/`),
},
}
extension = new Extension(bud)
})
describe(`register()`, async () => {
it(`should call logger.log`, async () => {
const spy = vi.spyOn(extension.logger, `log`)
await extension.register(bud)

expect(spy).toHaveBeenCalledWith(
`Registering react-refresh-babel transformer`,
)
})

it(`should interface with bud.babel`, async () => {
await extension.register(bud)

expect(bud.babel.setPlugin).toHaveBeenCalledWith(
`react-refresh/babel`,
expect.arrayContaining([
`/test/path/`,
{
skipEnvCheck: true,
},
]),
)
})
})
})
104 changes: 99 additions & 5 deletions sources/@roots/bud-react/test/extension.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,102 @@
import Extension from '@roots/bud-react/extension'
import {describe, expect, it} from 'vitest'
import type {Bud} from '@roots/bud-framework'

describe(`@roots/bud-react`, () => {
it(`should be constructable`, () => {
expect(Extension).toBeInstanceOf(Function)
import {beforeEach, describe, expect, it, vi} from 'vitest'

import DefaultExport from '../src'
import Extension from '../src/extension'

describe(`@roots/bud-react`, async () => {
let bud: any
let extension: Extension

beforeEach(async () => {
bud = {
extensions: {
add: vi.fn(),
get: vi.fn(),
},
module: {
resolve: vi.fn(async (...args) => `/test/path/`),
},
provide: vi.fn(),
} as unknown as Bud

extension = new Extension(bud)
})

it(`should re-export @roots/bud-react/extension`, async () => {
const module = await import(`../src`)
expect(module.default).toBe(DefaultExport)
})

describe(`boot()`, async () => {
it(`should be a function`, () => {
expect(extension.boot).toBeInstanceOf(Function)
})

it(`should resolve react`, async () => {
const spy = vi.spyOn(extension, `resolve`)
await extension.boot(bud)

expect(spy).toHaveBeenCalledWith(
`react`,
expect.stringMatching(/@roots\/bud-react\/src\/extension\/index/),
)
})

it(`should call bud.provide`, async () => {
await extension.boot(bud)
expect(bud.provide).toHaveBeenCalledWith(
`/test/path/`,
expect.arrayContaining([`React`]),
)
})

it(`should interface with swc if available`, async () => {
bud.swc = {
jsc: {},
setJsc: vi.fn(),
setTransform: vi.fn(),
}

await extension.boot(bud)

expect(bud.swc.setJsc).toHaveBeenCalledWith(
expect.objectContaining({
transform: {
react: {
runtime: `automatic`,
},
},
}),
)

expect(bud.swc.setTransform).toHaveBeenCalledWith(
expect.any(Function),
)
})

it(`should interface with babel if available`, async () => {
bud.babel = {
setPreset: vi.fn(),
}

await extension.boot(bud)

expect(bud.babel.setPreset).toHaveBeenCalledWith(
`@babel/preset-react`,
`/test/path/`,
)
})
})

describe(`get refresh()`, async () => {
it(`should call bud.extensions.get when referenced`, () => {
extension.refresh

expect(bud.extensions.get).toHaveBeenCalledWith(
`@roots/bud-react/react-refresh`,
)
})
})
})
4 changes: 2 additions & 2 deletions sources/@roots/bud-react/test/extension/extension.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import '@roots/bud-react'
import Extension from '@roots/bud-react/extension'
import {describe, expect, it} from 'vitest'

import Extension from '../../src/extension'

describe(`@roots/bud-react`, () => {
it(`should be constructable`, () => {
expect(Extension).toBeInstanceOf(Function)
Expand Down
Loading

0 comments on commit 599273b

Please sign in to comment.