Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(react-query): improve cli utils #1383

Merged
merged 12 commits into from
Dec 7, 2024
5 changes: 5 additions & 0 deletions .changeset/calm-masks-fry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@suspensive/react-query": patch
---

refactor(react-query): improve cli utils
4 changes: 2 additions & 2 deletions packages/react-query/src/bin/cli.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { execFileSync } from 'child_process'
import path from 'path'
import { execFileSync } from 'node:child_process'
import path from 'node:path'
import packageJson from '../../package.json'
import { getTanStackReactQueryPackageJson } from './utils/package'
import { getStatusTable } from './utils/table'
Expand Down
103 changes: 47 additions & 56 deletions packages/react-query/src/bin/utils/commands.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import fs from 'fs'
import type { Mock, MockInstance } from 'vitest'
import fs from 'node:fs'
import packageJson from '../../../package.json'
import { fixAction, statusAction, switchAction } from './commands'
import {
Expand All @@ -14,65 +13,48 @@ import {
import { switchVersion } from './switchVersion'
import { getStatusTable } from './table'

vi.mock('fs')
vi.mock('path')
vi.mock('node:fs')
vi.mock('node:path')
vi.mock('./package')
vi.mock('./switchVersion')

describe('commands', () => {
let consoleLogSpy: MockInstance
let consoleWarnSpy: MockInstance

beforeEach(() => {
consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {})
consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})

const getPackageJsonMock = getPackageJson as Mock
getPackageJsonMock.mockReturnValue(packageJson)
const getIndexFileContentMock = getIndexFileContent as Mock
getIndexFileContentMock.mockReturnValue('export * from "@suspensive/react-query-4"')
const getTanStackReactQueryPackageJsonMock = getTanStackReactQueryPackageJson as Mock
getTanStackReactQueryPackageJsonMock.mockReturnValue({ version: '5.0.0' })
const getSuspensiveReactQueryPackageJsonMock = getSuspensiveReactQueryPackageJson as Mock
getSuspensiveReactQueryPackageJsonMock.mockReturnValue({ version: packageJson.version })
const getTargetSuspensiveReactQueryVersionMock = getTargetSuspensiveReactQueryVersion as Mock
getTargetSuspensiveReactQueryVersionMock.mockReturnValue('5')
const getTargetSuspensiveReactQueryAPIsMock = getTargetSuspensiveReactQueryAPIs as Mock
getTargetSuspensiveReactQueryAPIsMock.mockReturnValue([])
const getTanStackReactQueryAPIsMock = getTanStackReactQueryAPIs as Mock
getTanStackReactQueryAPIsMock.mockReturnValue([])

vi.mocked(switchVersion).mockImplementation(() => {})
const consoleLogSpy = vi.spyOn(console, 'log').mockClear()
const consoleWarnSpy = vi.spyOn(console, 'warn').mockClear()

const mockGetPackageJson = vi.mocked(getPackageJson)
mockGetPackageJson.mockReturnValue(packageJson)
const mockGetIndexFileContent = vi.mocked(getIndexFileContent)
mockGetIndexFileContent.mockReturnValue('export * from "@suspensive/react-query-4"')
const mockGetTanStackReactQueryPackageJson = vi.mocked(getTanStackReactQueryPackageJson)
mockGetTanStackReactQueryPackageJson.mockReturnValue({
name: 'tanstack-query',
description: '',
version: '5.0.0',
})

afterEach(() => {
vi.clearAllMocks()
const mockGetSuspensiveReactQueryPackageJson = vi.mocked(getSuspensiveReactQueryPackageJson)
mockGetSuspensiveReactQueryPackageJson.mockReturnValue({
name: 'tanstack-query',
description: '',
version: packageJson.version,
})
const mockGetTargetSuspensiveReactQueryAPIsMock = vi.mocked(getTargetSuspensiveReactQueryAPIs)
mockGetTargetSuspensiveReactQueryAPIsMock.mockReturnValue([])
const mockGetTanStackReactQueryAPIsMock = vi.mocked(getTanStackReactQueryAPIs)
mockGetTanStackReactQueryAPIsMock.mockReturnValue([])

describe('getSuspensiveReactQueryVersion', () => {
it('should return the correct version', () => {
const getTargetSuspensiveReactQueryVersionMock = getTargetSuspensiveReactQueryVersion as Mock
getTargetSuspensiveReactQueryVersionMock.mockReturnValue('4')

const result = getTargetSuspensiveReactQueryVersion()

expect(result).toBe('4')
})

it('should return "not found" when version is not present', () => {
const getTargetSuspensiveReactQueryVersionMock = getTargetSuspensiveReactQueryVersion as Mock
getTargetSuspensiveReactQueryVersionMock.mockReturnValue('not found')

const result = getTargetSuspensiveReactQueryVersion()
beforeEach(() => {
const mockGetTargetSuspensiveReactQueryVersion = vi.mocked(getTargetSuspensiveReactQueryVersion)
mockGetTargetSuspensiveReactQueryVersion.mockReturnValue('5')

expect(result).toBe('not found')
})
vi.resetModules()
vi.clearAllMocks()
})

describe('statusAction', () => {
it('should display the status correctly when versions are compatible (version 4)', () => {
const getTargetSuspensiveReactQueryVersionMock = getTargetSuspensiveReactQueryVersion as Mock
getTargetSuspensiveReactQueryVersionMock.mockReturnValue('4')
const mockGetTargetSuspensiveReactQueryVersion = vi.mocked(getTargetSuspensiveReactQueryVersion)
mockGetTargetSuspensiveReactQueryVersion.mockReturnValue('4')

statusAction()

Expand All @@ -92,13 +74,22 @@ describe('commands', () => {
})

it('should display incompatible versions message (suspensive 4, tanstack 5)', () => {
const getTargetSuspensiveReactQueryVersionMock = getTargetSuspensiveReactQueryVersion as Mock
getTargetSuspensiveReactQueryVersionMock.mockReturnValue('4')
const mockGetTargetSuspensiveReactQueryVersion = vi.mocked(getTargetSuspensiveReactQueryVersion)
mockGetTargetSuspensiveReactQueryVersion.mockReturnValue('4')

statusAction()

expect(consoleLogSpy).toHaveBeenCalledWith(getStatusTable('4'))
})

it('should handle undefined versions', () => {
const mockGetTargetSuspensiveReactQueryVersion = vi.mocked(getTargetSuspensiveReactQueryVersion)
mockGetTargetSuspensiveReactQueryVersion.mockReturnValue(undefined)

statusAction()

expect(consoleWarnSpy).toHaveBeenCalledWith('[@suspensive/react-query]', 'The version is not found.')
})
})

describe('switchAction', () => {
Expand All @@ -117,26 +108,26 @@ describe('commands', () => {
it('should warn about not supported version', () => {
switchAction('1')

expect(consoleWarnSpy).toHaveBeenCalledWith('[@suspensive/react-query]', `version v1 is not supported.`)
expect(consoleWarnSpy).toHaveBeenCalledWith('[@suspensive/react-query]', 'version v1 is not supported.')
})
})

describe('fixAction', () => {
it('should not switch when versions are compatible', () => {
fixAction()

expect(consoleLogSpy).toHaveBeenCalledWith('[@suspensive/react-query]', `The versions are compatible.`)
expect(consoleLogSpy).toHaveBeenCalledWith('[@suspensive/react-query]', 'The versions are compatible.')
expect(switchVersion).not.toHaveBeenCalled()
})

it('should switch to version 5 when tanstack is 5', () => {
vi.mocked(fs.readFileSync).mockReturnValue(`export * from '@suspensive/react-query-4'`)
const getTargetSuspensiveReactQueryVersionMock = getTargetSuspensiveReactQueryVersion as Mock
getTargetSuspensiveReactQueryVersionMock.mockReturnValue('4')
const mockGetTargetSuspensiveReactQueryVersion = vi.mocked(getTargetSuspensiveReactQueryVersion)
mockGetTargetSuspensiveReactQueryVersion.mockReturnValue('4')

fixAction()

expect(consoleLogSpy).toHaveBeenCalledWith('[@suspensive/react-query]', `Switching to the compatible version...`)
expect(consoleLogSpy).toHaveBeenCalledWith('[@suspensive/react-query]', 'Switching to the compatible version...')
expect(switchVersion).toHaveBeenCalledWith(5)
})
})
Expand Down
14 changes: 9 additions & 5 deletions packages/react-query/src/bin/utils/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@ import { getTanStackReactQueryPackageJson, getTargetSuspensiveReactQueryVersion
import { switchVersion } from './switchVersion'
import { getStatusTable } from './table'

export const statusAction = () => {
export function statusAction() {
const targetSuspensiveReactQueryVersion = getTargetSuspensiveReactQueryVersion()

if (!targetSuspensiveReactQueryVersion) {
return console.warn('[@suspensive/react-query]', 'The version is not found.')
}

console.log(getStatusTable(targetSuspensiveReactQueryVersion))
}

export const switchAction = (version: string) => {
export function switchAction(version: string) {
if (version === '4') {
switchVersion(4)
} else if (version === '5') {
Expand All @@ -18,15 +22,15 @@ export const switchAction = (version: string) => {
}
}

export const fixAction = () => {
export function fixAction() {
const tanStackReactQueryPackageJson = getTanStackReactQueryPackageJson()
const suspensiveReactQueryVersion = getTargetSuspensiveReactQueryVersion()

const tanStackReactQueryMajorVersion = tanStackReactQueryPackageJson.version.split('.')[0]
if (suspensiveReactQueryVersion === tanStackReactQueryMajorVersion) {
console.log('[@suspensive/react-query]', `The versions are compatible.`)
console.log('[@suspensive/react-query]', 'The versions are compatible.')
} else {
console.log('[@suspensive/react-query]', `Switching to the compatible version...`)
console.log('[@suspensive/react-query]', 'Switching to the compatible version...')
switchVersion(Number(tanStackReactQueryMajorVersion))
}
}
6 changes: 3 additions & 3 deletions packages/react-query/src/bin/utils/copy.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import fs from 'fs'
import fs from 'node:fs'
import { copy } from './copy'

describe('copy', () => {
Expand All @@ -18,8 +18,8 @@ describe('copy', () => {

it('should copy and replace files with the specified version', () => {
vi.spyOn(fs, 'readdirSync').mockReturnValue(['v5', 'other'] as unknown as fs.Dirent[])
vi.spyOn(fs, 'unlinkSync').mockImplementation(() => {})
vi.spyOn(fs, 'writeFileSync').mockImplementation(() => {})
vi.spyOn(fs, 'unlinkSync').mockReturnValue()
vi.spyOn(fs, 'writeFileSync').mockReturnValue()

expect(copy(5)).toBe(true)
expect(fs.readdirSync).toHaveBeenCalledTimes(1)
Expand Down
8 changes: 4 additions & 4 deletions packages/react-query/src/bin/utils/copy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import fs from 'fs'
import { join, resolve } from 'path'
import fs from 'node:fs'
import { join, resolve } from 'node:path'

const dir = resolve(__dirname, '..')

Expand All @@ -10,7 +10,7 @@ export function copy(version: number) {
return false
}

files.forEach((file) => {
for (const file of files) {
if (file.includes(`v${version}`)) {
Copy link
Collaborator Author

@gwansikk gwansikk Dec 3, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may not have a significant impact on our project, but I agree with the intent and would like to follow it.

ref: https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/docs/rules/no-array-for-each.md

const src = join(dir, file)
const dest = join(dir, file.replace(`v${version}`, 'index'))
Expand All @@ -23,7 +23,7 @@ export function copy(version: number) {
}
fs.writeFileSync(dest, content, 'utf-8')
}
})
}

return true
}
Loading
Loading