Compare commits
1 commit
Author | SHA1 | Date | |
---|---|---|---|
51d635c452 |
14 changed files with 3168 additions and 811 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -26,3 +26,5 @@ dist-ssr
|
|||
houhou.db
|
||||
src/data/kanadata.json
|
||||
.direnv
|
||||
|
||||
/coverage
|
10
jest.config.js
Normal file
10
jest.config.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
export default {
|
||||
preset: "vite-jest",
|
||||
|
||||
setupFilesAfterEnv: ["<rootDir>/src/setupTests.js"],
|
||||
testMatch: [
|
||||
"<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
|
||||
"<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}",
|
||||
],
|
||||
testEnvironment: "jest-environment-jsdom",
|
||||
};
|
3889
package-lock.json
generated
3889
package-lock.json
generated
File diff suppressed because it is too large
Load diff
13
package.json
13
package.json
|
@ -7,6 +7,7 @@
|
|||
"dev": "vite",
|
||||
"build": "tsc && vite build",
|
||||
"preview": "vite preview",
|
||||
"test": "vitest",
|
||||
"tauri": "tauri"
|
||||
},
|
||||
"dependencies": {
|
||||
|
@ -29,23 +30,27 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^8.42.0",
|
||||
"@swc/core": "^1.3.64",
|
||||
"@tauri-apps/cli": "^1.4.0",
|
||||
"@testing-library/react": "^14.0.0",
|
||||
"@types/lodash-es": "^4.17.7",
|
||||
"@types/node": "^18.7.10",
|
||||
"@types/node": "^20.3.1",
|
||||
"@types/react": "^18.0.15",
|
||||
"@types/react-dom": "^18.0.6",
|
||||
"@types/react-timeago": "^4.1.3",
|
||||
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
||||
"@typescript-eslint/parser": "^5.59.11",
|
||||
"@vitejs/plugin-react": "^3.0.0",
|
||||
"@vitejs/plugin-react": "^4.0.0",
|
||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||
"@vitest/coverage-v8": "^0.32.0",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"eslint": "^8.42.0",
|
||||
"eslint-plugin-react": "^7.32.2",
|
||||
"postcss": "^8.4.24",
|
||||
"prettier": "^2.8.8",
|
||||
"sass": "^1.62.1",
|
||||
"typescript": "^4.9.5",
|
||||
"vite": "^4.2.1"
|
||||
"typescript": "^5.1.3",
|
||||
"vite": "^4.2.1",
|
||||
"vitest": "^0.32.0"
|
||||
}
|
||||
}
|
||||
|
|
10
src/App.tsx
10
src/App.tsx
|
@ -5,11 +5,11 @@ import { createBrowserRouter } from "react-router-dom";
|
|||
import { Outlet, Route, createRoutesFromElements, matchPath, useLocation } from "react-router";
|
||||
import { StrictMode } from "react";
|
||||
|
||||
import { Component as KanjiPane } from "./panes/KanjiPane";
|
||||
import { Component as SettingsPane } from "./panes/SettingsPane";
|
||||
import { Component as SrsPane } from "./panes/SrsPane";
|
||||
import { Component as SrsReviewPane } from "./panes/SrsReviewPane";
|
||||
import { Component as VocabPane } from "./panes/VocabPane";
|
||||
import KanjiPane from "./panes/KanjiPane";
|
||||
import SettingsPane from "./panes/SettingsPane";
|
||||
import SrsPane from "./panes/SrsPane";
|
||||
import SrsReviewPane from "./panes/SrsReviewPane";
|
||||
import VocabPane from "./panes/VocabPane";
|
||||
|
||||
import styles from "./App.module.scss";
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ export default function DashboardItemStats({ srsStats }: DashboardItemStatsProps
|
|||
{srsLevels.groups.map((group) => {
|
||||
const groupLevels = srsLevelsByGroups.get(group);
|
||||
if (!groupLevels) return null;
|
||||
groupLevels.sort((a, b) => (a.delay == null || b.delay == null ? 0 : a.delay - b.delay));
|
||||
|
||||
const groupCount = groupLevels
|
||||
.map((level) => grades.get(level.value) ?? 0)
|
||||
|
|
|
@ -16,7 +16,7 @@ export interface GetKanjiResult {
|
|||
kanji: Kanji[];
|
||||
}
|
||||
|
||||
export function Component() {
|
||||
export default function KanjiPane() {
|
||||
const { selectedKanji } = useParams();
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
|
||||
|
@ -85,5 +85,3 @@ export function Component() {
|
|||
</Flex>
|
||||
);
|
||||
}
|
||||
|
||||
Component.displayName = "KanjiPane";
|
||||
|
|
|
@ -11,7 +11,7 @@ interface ApplicationInfo {
|
|||
srs_db_path: string;
|
||||
}
|
||||
|
||||
export function Component() {
|
||||
export default function SettingsPane() {
|
||||
const { data: info } = useSWR("application_info", () =>
|
||||
invoke<ApplicationInfo>("application_info"),
|
||||
);
|
||||
|
@ -55,5 +55,3 @@ export function Component() {
|
|||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
Component.displayName = "SettingsPane";
|
||||
|
|
|
@ -19,7 +19,7 @@ export interface SrsStats {
|
|||
num_failure: number;
|
||||
}
|
||||
|
||||
export function Component() {
|
||||
export default function SrsPane() {
|
||||
const { data: srsStats, error } = useSWR(["get_srs_stats"], ([command]) =>
|
||||
invoke<SrsStats>(command),
|
||||
);
|
||||
|
@ -38,5 +38,3 @@ export function Component() {
|
|||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
Component.displayName = "SrsPane";
|
||||
|
|
15
src/panes/SrsReviewPane.test.tsx
Normal file
15
src/panes/SrsReviewPane.test.tsx
Normal file
|
@ -0,0 +1,15 @@
|
|||
import SrsReviewPane from "./SrsReviewPane";
|
||||
import { wrappedRender } from "../test/setup";
|
||||
import { vi, Mock } from "vitest";
|
||||
|
||||
describe("SrsReviewPane", () => {
|
||||
beforeEach(() => {});
|
||||
|
||||
afterEach(() => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
test("renders without exploding", () => {
|
||||
wrappedRender(<SrsReviewPane />);
|
||||
});
|
||||
});
|
|
@ -18,7 +18,7 @@ import {
|
|||
import InputBox from "../components/srsReview/InputBox";
|
||||
import SelectOnClick from "../components/utils/SelectOnClick";
|
||||
|
||||
export function Component() {
|
||||
export default function SrsReviewPane() {
|
||||
// null = has not started, (.length == 0) = finished
|
||||
const [reviewQueue, setReviewQueue] = useState<ReviewItem[] | null>(null);
|
||||
const [completedQueue, setCompletedQueue] = useState<ReviewItem[]>([]);
|
||||
|
@ -147,7 +147,9 @@ export function Component() {
|
|||
/>
|
||||
)}
|
||||
|
||||
<h1 className={styles.testWord}>{nextItem.challenge}</h1>
|
||||
<h1 className={styles.testWord} data-testid="testWord">
|
||||
{nextItem.challenge}
|
||||
</h1>
|
||||
|
||||
<InputBox
|
||||
submit={formSubmit}
|
||||
|
@ -196,5 +198,3 @@ export function Component() {
|
|||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
Component.displayName = "SrsReviewPane";
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import VocabList from "../components/VocabList";
|
||||
import styles from "./VocabPane.module.scss";
|
||||
|
||||
export function Component() {
|
||||
export default function VocabPane() {
|
||||
return (
|
||||
<main className={styles.main}>
|
||||
<VocabList />
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
Component.displayName = "VocabPane";
|
||||
|
|
7
src/test/setup.ts
Normal file
7
src/test/setup.ts
Normal file
|
@ -0,0 +1,7 @@
|
|||
import { render } from "@testing-library/react";
|
||||
import { ReactElement } from "react";
|
||||
import { BrowserRouter } from "react-router-dom";
|
||||
|
||||
export function wrappedRender(ui: ReactElement) {
|
||||
return render(ui, { wrapper: BrowserRouter });
|
||||
}
|
8
vitest.config.ts
Normal file
8
vitest.config.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import { defineConfig } from "vitest/config";
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
globals: true,
|
||||
environment: "jsdom",
|
||||
},
|
||||
});
|
Loading…
Reference in a new issue