mirror of
https://github.com/mengxi-ream/read-frog.git
synced 2026-04-30 01:56:46 +00:00
* 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>
114 lines
3.1 KiB
TypeScript
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
|