upgrade Jest and TypeScript

This commit is contained in:
Pig Fang 2021-06-05 17:10:41 +08:00
parent ed82469f88
commit 7381699690
No known key found for this signature in database
GPG Key ID: A8198F548DADA9E2
57 changed files with 1063 additions and 1127 deletions

View File

@ -23,3 +23,4 @@ rules:
- off
- checksVoidReturn: false
'@typescript-eslint/unbound-method': off
'@typescript-eslint/restrict-template-expressions': off

View File

@ -51,13 +51,13 @@
"xterm-addon-fit": "^0.4.0"
},
"devDependencies": {
"@gplane/tsconfig": "^1.1.0",
"@gplane/tsconfig": "^4.2.0",
"@testing-library/jest-dom": "^5.11.10",
"@testing-library/react": "^11.2.6",
"@types/bootstrap": "^4.3.3",
"@types/css-minimizer-webpack-plugin": "^1.1.0",
"@types/echarts": "^4.6.0",
"@types/jest": "^26.0.20",
"@types/jest": "^26.0.23",
"@types/jquery": "^3.3.38",
"@types/js-yaml": "^3.12.4",
"@types/lodash.debounce": "^4.0.6",
@ -78,7 +78,7 @@
"eslint-formatter-beauty": "^3.0.0",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.3.1",
"jest": "^26.6.3",
"jest": "^27.0.4",
"jest-extended": "^0.11.5",
"jquery": "^3.5.1",
"js-yaml": "^3.13.1",
@ -87,10 +87,10 @@
"postcss-loader": "^5.3.0",
"prettier": "^2.0.5",
"style-loader": "^2.0.0",
"ts-jest": "^26.5.1",
"ts-jest": "^27.0.2",
"ts-loader": "^9.2.2",
"ts-node": "^8.10.2",
"typescript": "^4.1.3",
"ts-node": "^10.0.0",
"typescript": "^4.3.2",
"url-loader": "^4.1.1",
"webpack": "^5.38.1",
"webpack-cli": "^4.7.0",
@ -115,10 +115,7 @@
"jest": {
"preset": "ts-jest",
"resetMocks": true,
"timers": "modern",
"transform": {
".*\\.tsx?$": "ts-jest"
},
"testEnvironment": "jsdom",
"moduleFileExtensions": [
"js",
"ts",

View File

@ -1,7 +1,7 @@
import type { Stdio } from 'blessing-skin-shell'
import cac from 'cac'
import * as fetch from '../net'
import { User, Texture } from '../types'
import type { User, Texture } from '../types'
type Response = fetch.ResponseBody<{ user: User; texture: Texture }>

View File

@ -33,7 +33,7 @@ export default async function rm(stdio: Stdio, args: string[]) {
stdio.println("Try 'rm --help' for more information.")
}
if (opts.force && opts.recursive && path.startsWith('/')) {
if (opts.force && opts.recursive && path?.startsWith('/')) {
await fetch.post('/admin/resource?clear-cache')
}
}

View File

@ -1,4 +1,4 @@
import { Stdio } from 'blessing-skin-shell'
import type { Stdio } from 'blessing-skin-shell'
import * as event from '../event'
/* istanbul ignore next */

View File

@ -10,3 +10,5 @@ if (process.env.NODE_ENV === 'development') {
const base = link?.href ?? blessing.base_url
__webpack_public_path__ = `${base}/app/`
}
export {}

View File

@ -1,9 +1,9 @@
{
const blessingElement = document.querySelector('#blessing-globals')!
// @ts-ignore
window.blessing = JSON.parse(blessingElement.textContent!)
const blessingElement = document.querySelector('#blessing-globals')!
// @ts-ignore
window.blessing = JSON.parse(blessingElement.textContent!)
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js?v6')
})
}
window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js?v6')
})
export {}

View File

@ -58,7 +58,7 @@ export async function walkFetch(request: Request): Promise<any> {
} = body
return {
code: 1,
message: Object.keys(errors).map((field) => errors[field][0])[0],
message: Object.keys(errors).map((field) => errors[field]![0])[0],
}
} else if (response.status === 419) {
return showModal({

View File

@ -1,7 +1,7 @@
import React from 'react'
import { t } from '@/scripts/i18n'
import { showModal } from '@/scripts/notify'
import { Player } from '@/scripts/types'
import type { Player } from '@/scripts/types'
import { Box } from './styles'
interface Props {

View File

@ -1,6 +1,6 @@
import React from 'react'
import { t } from '@/scripts/i18n'
import { Player } from '@/scripts/types'
import type { Player } from '@/scripts/types'
import ButtonEdit from '@/components/ButtonEdit'
interface Props {

View File

@ -4,7 +4,7 @@ import { useImmer } from 'use-immer'
import useIsLargeScreen from '@/scripts/hooks/useIsLargeScreen'
import { t } from '@/scripts/i18n'
import * as fetch from '@/scripts/net'
import { Player, Paginator } from '@/scripts/types'
import type { Player, Paginator } from '@/scripts/types'
import { toast, showModal } from '@/scripts/notify'
import urls from '@/scripts/urls'
import Pagination from '@/components/Pagination'
@ -87,7 +87,7 @@ const PlayersManagement: React.FC = () => {
if (code === 0) {
toast.success(message)
setPlayers((players) => {
players[index].name = name
players[index]!.name = name
})
} else {
toast.error(message)
@ -115,7 +115,7 @@ const PlayersManagement: React.FC = () => {
if (code === 0) {
toast.success(message)
setPlayers((players) => {
players[index].uid = uid
players[index]!.uid = uid
})
} else {
toast.error(message)
@ -126,15 +126,15 @@ const PlayersManagement: React.FC = () => {
const handleUpdateTexture = async (type: 'skin' | 'cape', tid: number) => {
const { code, message } = await fetch.put<fetch.ResponseBody>(
urls.admin.players.texture(players[textureUpdating].pid),
urls.admin.players.texture(players[textureUpdating]!.pid),
{ type, tid },
)
if (code === 0) {
toast.success(message)
setPlayers((players) => {
const field = `tid_${type}` as 'tid_skin' | 'tid_cape'
players[textureUpdating][field] = tid
const field = `tid_${type}` as const
players[textureUpdating]![field] = tid
})
} else {
toast.error(message)

View File

@ -1,7 +1,7 @@
import React from 'react'
import styled from '@emotion/styled'
import { t } from '@/scripts/i18n'
import { Plugin } from './types'
import type { Plugin } from './types'
const Box = styled.div`
cursor: default;

View File

@ -7,7 +7,7 @@ import { toast, showModal } from '@/scripts/notify'
import FileInput from '@/components/FileInput'
import Loading from '@/components/Loading'
import InfoBox from './InfoBox'
import { Plugin } from './types'
import type { Plugin } from './types'
const PluginsManagement: React.FC = () => {
const [isLoading, setIsLoading] = useState(true)
@ -43,7 +43,7 @@ const PluginsManagement: React.FC = () => {
if (code === 0) {
toast.success(message)
setPlugins((plugins) => {
plugins[i].enabled = true
plugins[i]!.enabled = true
})
} else {
showModal({
@ -73,7 +73,7 @@ const PluginsManagement: React.FC = () => {
if (code === 0) {
toast.success(message)
setPlugins((plugins) => {
plugins[i].enabled = false
plugins[i]!.enabled = false
})
} else {
toast.error(message)
@ -108,7 +108,7 @@ const PluginsManagement: React.FC = () => {
}
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setFile(event.target.files![0])
setFile(event.target.files![0]!)
}
const handleUrlChange = (event: React.ChangeEvent<HTMLInputElement>) => {
@ -161,7 +161,7 @@ const PluginsManagement: React.FC = () => {
const chunks = Array(Math.ceil(plugins.length / 2))
.fill(null)
.map((_, i) => plugins.slice(i * 2, (i + 1) * 2))
.map((_, i) => plugins.slice(i * 2, (i + 1) * 2) as [Plugin, Plugin?])
return (
<div className="row">
@ -173,7 +173,7 @@ const PluginsManagement: React.FC = () => {
) : (
chunks.map((chunk, i) => (
<div className="row" key={`${chunk[0].name}&${chunk[1]?.name}`}>
{chunk.map((plugin, j) => (
{(chunk as Plugin[]).map((plugin, j) => (
<div className="col-md-6" key={plugin.name}>
<InfoBox
plugin={plugin}

View File

@ -1,6 +1,6 @@
import React from 'react'
import { t } from '@/scripts/i18n'
import { Plugin } from './types'
import type { Plugin } from './types'
interface Props {
plugin: Plugin

View File

@ -7,7 +7,7 @@ import * as fetch from '@/scripts/net'
import { toast, showModal } from '@/scripts/notify'
import Loading from '@/components/Loading'
import Pagination from '@/components/Pagination'
import { Plugin } from './types'
import type { Plugin } from './types'
import Row from './Row'
enableMapSet()
@ -64,8 +64,8 @@ const PluginsMarket: React.FC = () => {
if (code === 0) {
toast.success(message)
setPlugins((plugins) => {
plugins[index].can_update = false
plugins[index].installed = plugins[index].version
plugins[index]!.can_update = false
plugins[index]!.installed = plugins[index]!.version
})
} else {
showModal({

View File

@ -1,7 +1,7 @@
import React from 'react'
import styled from '@emotion/styled'
import { t } from '@/scripts/i18n'
import { Texture } from '@/scripts/types'
import type { Texture } from '@/scripts/types'
import { Report, Status } from './types'
const Card = styled.div`

View File

@ -8,7 +8,7 @@ import { toast, showModal } from '@/scripts/notify'
import Loading from '@/components/Loading'
import Pagination from '@/components/Pagination'
import ViewerSkeleton from '@/components/ViewerSkeleton'
import { Report, Status } from './types'
import type { Report, Status } from './types'
import ImageBox from './ImageBox'
const Previewer = React.lazy(() => import('@/components/Viewer'))
@ -62,7 +62,7 @@ const ReportsManagement: React.FC = () => {
if (resp.code === 0) {
toast.success(resp.message)
setReports((reports) => {
reports[index].status = resp.data.status
reports[index]!.status = resp.data.status
})
} else {
toast.error(resp.message)

View File

@ -1,4 +1,4 @@
import { Texture, User } from '@/scripts/types'
import type { Texture, User } from '@/scripts/types'
export const enum Status {
Pending = 0,

View File

@ -1,7 +1,7 @@
import styled from '@emotion/styled'
import React from 'react'
import { t } from '@/scripts/i18n'
import { Line } from './types'
import type { Line } from './types'
const Group = styled.td`
width: 15%;

View File

@ -49,7 +49,7 @@ const Translations: React.FC = () => {
if (code === 0) {
toast.success(message)
setLines((lines) => {
lines[index].text[blessing.locale] = text
lines[index]!.text[blessing.locale] = text
})
} else {
toast.error(message)

View File

@ -1,6 +1,6 @@
import React from 'react'
import { t } from '@/scripts/i18n'
import { User } from '@/scripts/types'
import type { User } from '@/scripts/types'
import { Box, Icon, InfoTable } from './styles'
import {
humanizePermission,

View File

@ -1,6 +1,6 @@
import React from 'react'
import { t } from '@/scripts/i18n'
import { User } from '@/scripts/types'
import type { User } from '@/scripts/types'
import ButtonEdit from '@/components/ButtonEdit'
import {
humanizePermission,

View File

@ -92,7 +92,7 @@ const UsersManagement: React.FC = () => {
if (code === 0) {
toast.success(message)
setUsers((users) => {
users[index].email = email
users[index]!.email = email
})
} else {
toast.error(message)
@ -124,7 +124,7 @@ const UsersManagement: React.FC = () => {
if (code === 0) {
toast.success(message)
setUsers((users) => {
users[index].nickname = nickname
users[index]!.nickname = nickname
})
} else {
toast.error(message)
@ -152,7 +152,7 @@ const UsersManagement: React.FC = () => {
if (code === 0) {
toast.success(message)
setUsers((users) => {
users[index].score = score
users[index]!.score = score
})
} else {
toast.error(message)
@ -189,7 +189,7 @@ const UsersManagement: React.FC = () => {
if (code === 0) {
toast.success(message)
setUsers((users) => {
users[index].permission = permission
users[index]!.permission = permission
})
} else {
toast.error(message)
@ -203,7 +203,7 @@ const UsersManagement: React.FC = () => {
if (code === 0) {
toast.success(message)
setUsers((users) => {
users[index].verified = !users[index].verified
users[index]!.verified = !users[index]!.verified
})
} else {
toast.error(message)

View File

@ -1,7 +1,7 @@
import { t } from '@/scripts/i18n'
import * as fetch from '@/scripts/net'
import { showModal, toast } from '@/scripts/notify'
import { Texture } from '@/scripts/types'
import type { Texture } from '@/scripts/types'
import urls from '@/scripts/urls'
export default async function addClosetItem(

View File

@ -2,7 +2,7 @@ import React from 'react'
import { t } from '@/scripts/i18n'
import { TextureType } from '@/scripts/types'
import Button from './Button'
import { Filter } from './types'
import type { Filter } from './types'
import { humanizeType } from './utils'
interface Props {

View File

@ -2,7 +2,7 @@ import React from 'react'
import styled from '@emotion/styled'
import { t } from '@/scripts/i18n'
import * as cssUtils from '@/styles/utils'
import { LibraryItem } from './types'
import type { LibraryItem } from './types'
import { humanizeType } from './utils'
const Card = styled.div`

View File

@ -14,7 +14,7 @@ import removeClosetItem from '@/views/user/Closet/removeClosetItem'
import FilterSelector from './FilterSelector'
import Button from './Button'
import Item from './Item'
import { Filter, LibraryItem } from './types'
import type { Filter, LibraryItem } from './types'
const SkinLibrary: React.FC = () => {
const [isLoading, setIsLoading] = useState(true)

View File

@ -1,4 +1,4 @@
import { TextureType } from '@/scripts/types'
import type { TextureType } from '@/scripts/types'
export type Filter = 'skin' | TextureType

View File

@ -1,6 +1,6 @@
import { t } from '@/scripts/i18n'
import { TextureType } from '@/scripts/types'
import { Filter } from './types'
import type { Filter } from './types'
export function humanizeType(type: Filter): string {
switch (type) {

View File

@ -1,13 +1,13 @@
import React from 'react'
import { t } from '@/scripts/i18n'
import { ClosetItem } from '@/scripts/types'
import type { ClosetItem as ClosetItemType } from '@/scripts/types'
import setAsAvatar from './setAsAvatar'
import { Card, DropdownButton } from './styles'
interface Props {
item: ClosetItem
item: ClosetItemType
selected: boolean
onClick(item: ClosetItem): void
onClick(item: ClosetItemType): void
onRename(): void
onRemove(): void
}

View File

@ -3,7 +3,7 @@ import $ from 'jquery'
import { t } from '@/scripts/i18n'
import * as fetch from '@/scripts/net'
import { toast } from '@/scripts/notify'
import { Player } from '@/scripts/types'
import type { Player } from '@/scripts/types'
import urls from '@/scripts/urls'
import Loading from '@/components/Loading'
import Modal from '@/components/Modal'

View File

@ -1,7 +1,7 @@
import React from 'react'
import { t } from '@/scripts/i18n'
import ButtonEdit from '@/components/ButtonEdit'
import { App } from './types'
import type { App } from './types'
interface Props {
app: App

View File

@ -6,7 +6,7 @@ import { showModal, toast } from '@/scripts/notify'
import Loading from '@/components/Loading'
import Row from './Row'
import ModalCreate from './ModalCreate'
import { App } from './types'
import type { App } from './types'
type Exception = {
message: string

View File

@ -2,7 +2,7 @@ import React, { useState } from 'react'
import { t } from '@/scripts/i18n'
import * as fetch from '@/scripts/net'
import { toast } from '@/scripts/notify'
import { Player } from '@/scripts/types'
import type { Player } from '@/scripts/types'
import urls from '@/scripts/urls'
import Modal from '@/components/Modal'

View File

@ -1,7 +1,7 @@
/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react'
import { t } from '@/scripts/i18n'
import { Player } from '@/scripts/types'
import type { Player } from '@/scripts/types'
import ButtonEdit from '@/components/ButtonEdit'
import * as cssUtils from '@/styles/utils'

View File

@ -39,7 +39,7 @@ const Players: React.FC = () => {
const players = await fetch.get<Player[]>('/user/player/list')
setPlayers(players)
if (players.length === 1) {
selectPlayer(players[0])
selectPlayer(players[0]!)
}
setIsLoading(false)
}

View File

@ -1,6 +1,6 @@
/* eslint-disable max-params */
/* eslint-disable max-classes-per-file */
import { PlayerObject, SkinObject, CapeObject } from 'skinview3d'
import type { PlayerObject, SkinObject, CapeObject } from 'skinview3d'
export class SkinViewer {
disposed: boolean

View File

@ -4,14 +4,28 @@ import { t } from '@/scripts/i18n'
import FileInput from '@/components/FileInput'
test('click to select file', () => {
const { getAllByText } = render(<FileInput file={null} onChange={() => {}} />)
const { getAllByText } = render(
<FileInput
file={null}
onChange={() => {
/* */
}}
/>,
)
fireEvent.click(getAllByText(t('skinlib.upload.select-file'))[1])
fireEvent.click(getAllByText(t('skinlib.upload.select-file'))[1]!)
})
test('display file name', () => {
const file = new File([], 'f.txt')
const { queryByText } = render(<FileInput file={file} onChange={() => {}} />)
const { queryByText } = render(
<FileInput
file={file}
onChange={() => {
/* */
}}
/>,
)
expect(queryByText('f.txt')).toBeInTheDocument()
})

View File

@ -50,7 +50,7 @@ describe('remove plugin', () => {
it('cancelled', async () => {
const stdio = new Stdio()
setImmediate(() => process.stdin.emit('keypress', 'n', 'n'))
setTimeout(() => process.stdin.emit('keypress', 'n', 'n'), 0)
await apt(stdio, ['remove', 'test'])
expect(fetch.post).not.toBeCalled()
})
@ -59,7 +59,7 @@ describe('remove plugin', () => {
fetch.post.mockResolvedValue({ code: 0, message: 'ok' })
const stdio = new Stdio()
setImmediate(() => process.stdin.emit('keypress', 'y', 'y'))
setTimeout(() => process.stdin.emit('keypress', 'y', 'y'), 0)
await apt(stdio, ['remove', 'test'])
expect(fetch.post).toBeCalledWith('/admin/plugins/manage', {
action: 'delete',

View File

@ -50,7 +50,7 @@ describe('remove plugin', () => {
it('cancelled', async () => {
const stdio = new Stdio()
setImmediate(() => process.stdin.emit('keypress', 'n', 'n'))
setTimeout(() => process.stdin.emit('keypress', 'n', 'n'), 0)
await dnf(stdio, ['remove', 'test'])
expect(fetch.post).not.toBeCalled()
})
@ -59,7 +59,7 @@ describe('remove plugin', () => {
fetch.post.mockResolvedValue({ code: 0, message: 'ok' })
const stdio = new Stdio()
setImmediate(() => process.stdin.emit('keypress', 'y', 'y'))
setTimeout(() => process.stdin.emit('keypress', 'y', 'y'), 0)
await dnf(stdio, ['remove', 'test'])
expect(fetch.post).toBeCalledWith('/admin/plugins/manage', {
action: 'delete',

View File

@ -46,7 +46,7 @@ describe('remove plugin', () => {
it('cancelled', async () => {
const stdio = new Stdio()
setImmediate(() => process.stdin.emit('keypress', 'n', 'n'))
setTimeout(() => process.stdin.emit('keypress', 'n', 'n'), 0)
await pacman(stdio, ['-R', 'test'])
expect(fetch.post).not.toBeCalled()
})
@ -55,7 +55,7 @@ describe('remove plugin', () => {
fetch.post.mockResolvedValue({ code: 0, message: 'ok' })
const stdio = new Stdio()
setImmediate(() => process.stdin.emit('keypress', 'y', 'y'))
setTimeout(() => process.stdin.emit('keypress', 'y', 'y'), 0)
await pacman(stdio, ['-R', 'test'])
expect(fetch.post).toBeCalledWith('/admin/plugins/manage', {
action: 'delete',

View File

@ -1,13 +1,15 @@
import { Spinner } from '@/scripts/cli/Spinner'
import { Stdio } from './stdio'
test('run', () => {
test('run', async () => {
jest.useRealTimers()
const stdio = new Stdio()
const spinner = new Spinner(stdio)
spinner.start()
jest.runTimersToTime(500)
await new Promise((resolve) => setTimeout(resolve, 500))
expect(stdio.getStdout().length).toBeGreaterThan(0)
spinner.stop()

View File

@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/indent */
import * as net from '../../src/scripts/net'
import type * as net from '../../src/scripts/net'
export { ResponseBody } from '../../src/scripts/net'
export type { ResponseBody } from '../../src/scripts/net'
export const init = {} as typeof net.init

View File

@ -1,5 +1,5 @@
import { ModalOptions, ModalResult } from '../../src/components/Modal'
import { Toast } from '../../src/scripts/toast'
import type { ModalOptions, ModalResult } from '../../src/components/Modal'
import type { Toast } from '../../src/scripts/toast'
export const showModal = {} as jest.Mock<
Promise<ModalResult>,

View File

@ -1,7 +1,7 @@
import type { Paginator } from '@/scripts/types'
export function flushPromises() {
return new Promise((resolve) => setImmediate(resolve))
return new Promise((resolve) => setTimeout(resolve, 0))
}
export function createPaginator<T>(data: T[], perPage = 6): Paginator<T> {

View File

@ -3,7 +3,7 @@ import { render, waitFor, fireEvent } from '@testing-library/react'
import { createPaginator } from '../../utils'
import { t } from '@/scripts/i18n'
import * as fetch from '@/scripts/net'
import { Player } from '@/scripts/types'
import type { Player } from '@/scripts/types'
import urls from '@/scripts/urls'
import PlayersManagement from '@/views/admin/PlayersManagement'

View File

@ -236,7 +236,7 @@ describe('upload plugin archive', () => {
const { getAllByText } = render(<PluginsManagement />)
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
fireEvent.click(getAllByText(t('general.submit'))[0])
fireEvent.click(getAllByText(t('general.submit'))[0]!)
expect(fetch.post).not.toBeCalled()
})
@ -253,7 +253,7 @@ describe('upload plugin archive', () => {
fireEvent.change(getByTitle(t('skinlib.upload.select-file')), {
target: { files: [file] },
})
fireEvent.click(getAllByText(t('general.submit'))[0])
fireEvent.click(getAllByText(t('general.submit'))[0]!)
await waitFor(() => {
expect(fetch.get).toBeCalledTimes(2)
expect(fetch.post).toBeCalledWith(
@ -261,7 +261,7 @@ describe('upload plugin archive', () => {
expect.any(FormData),
)
})
const formData = fetch.post.mock.calls[0][1] as FormData
const formData = fetch.post.mock.calls[0]![1] as FormData
expect(formData.get('file')).toStrictEqual(file)
expect(queryByText('plugin.zip')).not.toBeInTheDocument()
expect(queryByText('ok')).toBeInTheDocument()
@ -281,7 +281,7 @@ describe('upload plugin archive', () => {
fireEvent.change(getByTitle(t('skinlib.upload.select-file')), {
target: { files: [file] },
})
fireEvent.click(getAllByText(t('general.submit'))[0])
fireEvent.click(getAllByText(t('general.submit'))[0]!)
await waitFor(() => {
expect(fetch.get).toBeCalledTimes(1)
expect(fetch.post).toBeCalledWith(
@ -312,7 +312,7 @@ describe('submit remote URL', () => {
fireEvent.input(getByLabelText('URL'), {
target: { value: 'https://example.com/a.zip' },
})
fireEvent.click(getAllByText(t('general.submit'))[1])
fireEvent.click(getAllByText(t('general.submit'))[1]!)
await waitFor(() => {
expect(fetch.get).toBeCalledTimes(2)
expect(fetch.post).toBeCalledWith('/admin/plugins/wget', {
@ -342,7 +342,7 @@ describe('submit remote URL', () => {
fireEvent.input(getByLabelText('URL'), {
target: { value: 'https://example.com/a.zip' },
})
fireEvent.click(getAllByText(t('general.submit'))[1])
fireEvent.click(getAllByText(t('general.submit'))[1]!)
await waitFor(() => {
expect(fetch.get).toBeCalledTimes(1)
expect(fetch.post).toBeCalledWith('/admin/plugins/wget', {

View File

@ -3,7 +3,7 @@ import { render, waitFor, fireEvent } from '@testing-library/react'
import { t } from '@/scripts/i18n'
import * as fetch from '@/scripts/net'
import PluginsMarket from '@/views/admin/PluginsMarket'
import { Plugin } from '@/views/admin/PluginsMarket/types'
import type { Plugin } from '@/views/admin/PluginsMarket/types'
jest.mock('@/scripts/net')

View File

@ -40,7 +40,7 @@ describe('edit line', () => {
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
fireEvent.click(getByText(t('admin.i18n.modify')))
fireEvent.input(getByDisplayValue(fixtureLine.text.en), {
fireEvent.input(getByDisplayValue(fixtureLine.text.en!), {
target: { value: 'finish' },
})
fireEvent.click(getByText(t('general.confirm')))
@ -63,7 +63,7 @@ describe('edit line', () => {
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
fireEvent.click(getByText(t('admin.i18n.modify')))
fireEvent.input(getByDisplayValue(fixtureLine.text.en), {
fireEvent.input(getByDisplayValue(fixtureLine.text.en!), {
target: { value: 'finish' },
})
fireEvent.click(getByText(t('general.confirm')))
@ -72,7 +72,7 @@ describe('edit line', () => {
text: 'finish',
}),
)
expect(queryByText(fixtureLine.text.en)).toBeInTheDocument()
expect(queryByText(fixtureLine.text.en!)).toBeInTheDocument()
expect(queryByText('failed')).toBeInTheDocument()
expect(getByRole('alert')).toHaveClass('alert-danger')
})
@ -84,12 +84,12 @@ describe('edit line', () => {
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
fireEvent.click(getByText(t('admin.i18n.modify')))
fireEvent.input(getByDisplayValue(fixtureLine.text.en), {
fireEvent.input(getByDisplayValue(fixtureLine.text.en!), {
target: { value: 'finish' },
})
fireEvent.click(getByText(t('general.cancel')))
await waitFor(() => expect(fetch.put).not.toBeCalled())
expect(queryByText(fixtureLine.text.en)).toBeInTheDocument()
expect(queryByText(fixtureLine.text.en!)).toBeInTheDocument()
})
})
@ -109,7 +109,7 @@ describe('delete line', () => {
await waitFor(() =>
expect(fetch.del).toBeCalledWith(`/admin/i18n/${fixtureLine.id}`),
)
expect(queryByText(fixtureLine.text.en)).not.toBeInTheDocument()
expect(queryByText(fixtureLine.text.en!)).not.toBeInTheDocument()
expect(queryByText('ok')).toBeInTheDocument()
expect(getByRole('status')).toHaveClass('alert-success')
})
@ -121,6 +121,6 @@ describe('delete line', () => {
fireEvent.click(getByText(t('admin.i18n.delete')))
fireEvent.click(getByText(t('general.cancel')))
await waitFor(() => expect(fetch.del).not.toBeCalled())
expect(queryByText(fixtureLine.text.en)).toBeInTheDocument()
expect(queryByText(fixtureLine.text.en!)).toBeInTheDocument()
})
})

View File

@ -199,7 +199,7 @@ describe('edit texture name', () => {
)
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
fireEvent.click(getAllByTitle(t('skinlib.show.edit'))[0])
fireEvent.click(getAllByTitle(t('skinlib.show.edit'))[0]!)
fireEvent.input(getByDisplayValue(fixtureSkin.name), {
target: { value: '' },
})
@ -223,7 +223,7 @@ describe('edit texture name', () => {
} = render(<Show />)
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
fireEvent.click(getAllByTitle(t('skinlib.show.edit'))[0])
fireEvent.click(getAllByTitle(t('skinlib.show.edit'))[0]!)
fireEvent.input(getByDisplayValue(fixtureSkin.name), {
target: { value: 't' },
})
@ -250,7 +250,7 @@ describe('edit texture name', () => {
} = render(<Show />)
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
fireEvent.click(getAllByTitle(t('skinlib.show.edit'))[0])
fireEvent.click(getAllByTitle(t('skinlib.show.edit'))[0]!)
fireEvent.input(getByDisplayValue(fixtureSkin.name), {
target: { value: 't' },
})
@ -278,7 +278,7 @@ describe('edit texture type', () => {
)
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
fireEvent.click(getAllByTitle(t('skinlib.show.edit'))[1])
fireEvent.click(getAllByTitle(t('skinlib.show.edit'))[1]!)
fireEvent.click(getByLabelText('Alex'))
fireEvent.click(getByText(t('general.cancel')))
await waitFor(() => expect(fetch.put).not.toBeCalled())
@ -297,7 +297,7 @@ describe('edit texture type', () => {
} = render(<Show />)
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
fireEvent.click(getAllByTitle(t('skinlib.show.edit'))[1])
fireEvent.click(getAllByTitle(t('skinlib.show.edit'))[1]!)
fireEvent.click(getByLabelText('Alex'))
fireEvent.click(getByText(t('general.confirm')))
await waitFor(() =>
@ -322,7 +322,7 @@ describe('edit texture type', () => {
} = render(<Show />)
await waitFor(() => expect(fetch.get).toBeCalledTimes(1))
fireEvent.click(getAllByTitle(t('skinlib.show.edit'))[1])
fireEvent.click(getAllByTitle(t('skinlib.show.edit'))[1]!)
fireEvent.click(getByLabelText('Alex'))
fireEvent.click(getByText(t('general.confirm')))
await waitFor(() =>

View File

@ -6,7 +6,7 @@ import * as fetch from '@/scripts/net'
import { TextureType } from '@/scripts/types'
import urls from '@/scripts/urls'
import SkinLibrary from '@/views/skinlib/SkinLibrary'
import { LibraryItem } from '@/views/skinlib/SkinLibrary/types'
import type { LibraryItem } from '@/views/skinlib/SkinLibrary/types'
jest.mock('@/scripts/net')

View File

@ -221,7 +221,7 @@ describe('upload texture', () => {
expect.any(FormData),
)
const formData = fetch.post.mock.calls[0][1] as FormData
const formData = fetch.post.mock.calls[0]![1] as FormData
expect(formData.get('name')).toBe('t')
expect(formData.get('type')).toBe('steve')
expect(formData.get('file')).toStrictEqual(file)
@ -241,7 +241,7 @@ describe('upload texture', () => {
fireEvent.click(getByText(t('skinlib.upload.button')))
await waitFor(() => expect(fetch.post).toBeCalled())
const formData = fetch.post.mock.calls[0][1] as FormData
const formData = fetch.post.mock.calls[0]![1] as FormData
expect(formData.get('public')).toBe('0')
})

View File

@ -441,7 +441,7 @@ describe('apply textures to player', () => {
expect(await findByText(fixturePlayer.name)).toBeInTheDocument()
fireEvent.input(getAllByPlaceholderText(t('user.typeToSearch'))[1], {
fireEvent.input(getAllByPlaceholderText(t('user.typeToSearch'))[1]!, {
target: { value: 'reina' },
})
expect(queryByText(fixturePlayer.name)).not.toBeInTheDocument()

View File

@ -3,7 +3,7 @@ import { render, fireEvent, waitFor } from '@testing-library/react'
import * as fetch from '@/scripts/net'
import { t } from '@/scripts/i18n'
import OAuth from '@/views/user/OAuth'
import { App } from '@/views/user/OAuth/types'
import type { App } from '@/views/user/OAuth/types'
jest.mock('@/scripts/net')

View File

@ -12,7 +12,7 @@ const tree: TreeObject = {}
function parseURI(uri: string): ts.ArrowFunction {
const matches = /\{([a-z]+)\}/.exec(uri)
if (matches) {
if (matches?.[0] && matches?.[1]) {
const param = matches[1]
const type =
param.endsWith('id') ||

View File

@ -5,6 +5,7 @@
"module": "esnext",
"moduleResolution": "node",
"declaration": false,
"declarationMap": false,
"baseUrl": ".",
"paths": {
"@/*": ["./resources/assets/src/*"]

1947
yarn.lock

File diff suppressed because it is too large Load Diff