read-frog/vitest.setup.ts
ananaBMaster 52a70ff89a
feat: add providers and upgrade deps (#1127)
* feat: add Alibaba Cloud (Bailian) as AI provider

Add Alibaba Cloud Model Studio as a new built-in provider with @ai-sdk/alibaba.

Models: Qwen series (qwen3-max, qwen3.5-plus, qwen3.5-flash, qwen-plus,
qwen-flash, qwen-turbo, qwq-plus, qwen3-coder-plus), DeepSeek (v3.2, v3.1,
r1, v3), Kimi (k2.5), MiniMax (M2.5), GLM (glm-5).

Default model: qwen3.5-flash. Includes i18n for all 8 locales.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add Moonshot AI and Hugging Face as AI providers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: bump dependencies and pnpm to 10.32.1

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: resolve eslint errors from dependency bump

- Disable perfectionist/sort-imports for markdown files to fix
  getAllComments crash on .md files
- Move inline regex literals to module scope (e18e/prefer-static-regex)
- Apply auto-fixes: spread syntax, .at(-1), Array.from with mapper,
  timer args
- Add alt text to README images and remove unused definitions
- Add non-null assertions for .at(-1) to satisfy TypeScript

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 14:57:15 -07:00

114 lines
3.1 KiB
TypeScript

import { vi } from "vitest"
import "@testing-library/jest-dom"
// Keep test output quiet by default. Individual tests can still spy on these
// methods when they need to assert logging behavior.
// eslint-disable-next-line no-console
console.log = () => {}
// eslint-disable-next-line no-console
console.info = () => {}
console.warn = () => {}
console.error = () => {}
class MemoryStorage implements Storage {
#store = new Map<string, string>()
get length() {
return this.#store.size
}
clear() {
this.#store.clear()
}
getItem(key: string) {
return this.#store.get(key) ?? null
}
key(index: number) {
return [...this.#store.keys()][index] ?? null
}
removeItem(key: string) {
this.#store.delete(key)
}
setItem(key: string, value: string) {
this.#store.set(key, value)
}
}
// Node 22 exposes built-in Web Storage. In worker processes without a configured
// backing file, reading it emits `--localstorage-file` warnings. Replace it with
// an in-memory test double before app modules import Jotai utils.
Object.defineProperty(globalThis, "localStorage", {
configurable: true,
value: new MemoryStorage(),
})
Object.defineProperty(globalThis, "sessionStorage", {
configurable: true,
value: new MemoryStorage(),
})
// Mock @wxt-dev/i18n module to avoid browser.i18n.getMessage not implemented error
vi.mock("#i18n", () => ({
i18n: {
t: (key: string) => key,
},
}))
// Mock the fakeBrowser's i18n.getMessage method which is not implemented in fake-browser
// This is used when WxtVitest plugin replaces browser imports with fake-browser
vi.mock("wxt/testing", async () => {
const actual = await vi.importActual<any>("wxt/testing")
return {
...actual,
fakeBrowser: {
...actual.fakeBrowser,
i18n: {
...actual.fakeBrowser.i18n,
getMessage: (key: string) => key.replaceAll("_", "."),
},
identity: {
...actual.fakeBrowser.identity,
getRedirectURL: () => "https://mock-redirect-url.chromiumapp.org/",
},
runtime: {
...actual.fakeBrowser.runtime,
getManifest: () => ({
manifest_version: 3,
name: "Read Frog",
version: "1.0.0",
description: "Test manifest",
}),
},
},
}
})
// JSDom + Vitest don't play well with each other. Long story short - default
// TextEncoder produces Uint8Array objects that are _different_ from the global
// Uint8Array objects, so some functions that compare their types explode.
// https://github.com/vitest-dev/vitest/issues/4043#issuecomment-1905172846
class ESBuildAndJSDOMCompatibleTextEncoder extends TextEncoder {
constructor() {
super()
}
encode(input: string) {
if (typeof input !== "string") {
throw new TypeError("`input` must be a string")
}
const decodedURI = decodeURIComponent(encodeURIComponent(input))
const arr = new Uint8Array(decodedURI.length)
const chars = decodedURI.split("")
for (let i = 0; i < chars.length; i++) {
arr[i] = decodedURI[i].charCodeAt(0)
}
return arr
}
}
globalThis.TextEncoder = ESBuildAndJSDOMCompatibleTextEncoder