Compare commits

..

No commits in common. "master" and "v0.1.0" have entirely different histories.

14 changed files with 811 additions and 3168 deletions

2
.gitignore vendored
View file

@ -26,5 +26,3 @@ dist-ssr
houhou.db houhou.db
src/data/kanadata.json src/data/kanadata.json
.direnv .direnv
/coverage

View file

@ -1,10 +0,0 @@
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",
};

3883
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,6 @@
"dev": "vite", "dev": "vite",
"build": "tsc && vite build", "build": "tsc && vite build",
"preview": "vite preview", "preview": "vite preview",
"test": "vitest",
"tauri": "tauri" "tauri": "tauri"
}, },
"dependencies": { "dependencies": {
@ -30,27 +29,23 @@
}, },
"devDependencies": { "devDependencies": {
"@eslint/js": "^8.42.0", "@eslint/js": "^8.42.0",
"@swc/core": "^1.3.64",
"@tauri-apps/cli": "^1.4.0", "@tauri-apps/cli": "^1.4.0",
"@testing-library/react": "^14.0.0",
"@types/lodash-es": "^4.17.7", "@types/lodash-es": "^4.17.7",
"@types/node": "^20.3.1", "@types/node": "^18.7.10",
"@types/react": "^18.0.15", "@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6", "@types/react-dom": "^18.0.6",
"@types/react-timeago": "^4.1.3", "@types/react-timeago": "^4.1.3",
"@typescript-eslint/eslint-plugin": "^5.59.11", "@typescript-eslint/eslint-plugin": "^5.59.11",
"@typescript-eslint/parser": "^5.59.11", "@typescript-eslint/parser": "^5.59.11",
"@vitejs/plugin-react": "^4.0.0", "@vitejs/plugin-react": "^3.0.0",
"@vitejs/plugin-react-swc": "^3.3.2", "@vitejs/plugin-react-swc": "^3.3.2",
"@vitest/coverage-v8": "^0.32.0",
"autoprefixer": "^10.4.14", "autoprefixer": "^10.4.14",
"eslint": "^8.42.0", "eslint": "^8.42.0",
"eslint-plugin-react": "^7.32.2", "eslint-plugin-react": "^7.32.2",
"postcss": "^8.4.24", "postcss": "^8.4.24",
"prettier": "^2.8.8", "prettier": "^2.8.8",
"sass": "^1.62.1", "sass": "^1.62.1",
"typescript": "^5.1.3", "typescript": "^4.9.5",
"vite": "^4.2.1", "vite": "^4.2.1"
"vitest": "^0.32.0"
} }
} }

View file

@ -5,11 +5,11 @@ import { createBrowserRouter } from "react-router-dom";
import { Outlet, Route, createRoutesFromElements, matchPath, useLocation } from "react-router"; import { Outlet, Route, createRoutesFromElements, matchPath, useLocation } from "react-router";
import { StrictMode } from "react"; import { StrictMode } from "react";
import KanjiPane from "./panes/KanjiPane"; import { Component as KanjiPane } from "./panes/KanjiPane";
import SettingsPane from "./panes/SettingsPane"; import { Component as SettingsPane } from "./panes/SettingsPane";
import SrsPane from "./panes/SrsPane"; import { Component as SrsPane } from "./panes/SrsPane";
import SrsReviewPane from "./panes/SrsReviewPane"; import { Component as SrsReviewPane } from "./panes/SrsReviewPane";
import VocabPane from "./panes/VocabPane"; import { Component as VocabPane } from "./panes/VocabPane";
import styles from "./App.module.scss"; import styles from "./App.module.scss";

View file

@ -21,7 +21,6 @@ export default function DashboardItemStats({ srsStats }: DashboardItemStatsProps
{srsLevels.groups.map((group) => { {srsLevels.groups.map((group) => {
const groupLevels = srsLevelsByGroups.get(group); const groupLevels = srsLevelsByGroups.get(group);
if (!groupLevels) return null; if (!groupLevels) return null;
groupLevels.sort((a, b) => (a.delay == null || b.delay == null ? 0 : a.delay - b.delay));
const groupCount = groupLevels const groupCount = groupLevels
.map((level) => grades.get(level.value) ?? 0) .map((level) => grades.get(level.value) ?? 0)

View file

@ -16,7 +16,7 @@ export interface GetKanjiResult {
kanji: Kanji[]; kanji: Kanji[];
} }
export default function KanjiPane() { export function Component() {
const { selectedKanji } = useParams(); const { selectedKanji } = useParams();
const [searchQuery, setSearchQuery] = useState(""); const [searchQuery, setSearchQuery] = useState("");
@ -85,3 +85,5 @@ export default function KanjiPane() {
</Flex> </Flex>
); );
} }
Component.displayName = "KanjiPane";

View file

@ -11,7 +11,7 @@ interface ApplicationInfo {
srs_db_path: string; srs_db_path: string;
} }
export default function SettingsPane() { export function Component() {
const { data: info } = useSWR("application_info", () => const { data: info } = useSWR("application_info", () =>
invoke<ApplicationInfo>("application_info"), invoke<ApplicationInfo>("application_info"),
); );
@ -55,3 +55,5 @@ export default function SettingsPane() {
</main> </main>
); );
} }
Component.displayName = "SettingsPane";

View file

@ -19,7 +19,7 @@ export interface SrsStats {
num_failure: number; num_failure: number;
} }
export default function SrsPane() { export function Component() {
const { data: srsStats, error } = useSWR(["get_srs_stats"], ([command]) => const { data: srsStats, error } = useSWR(["get_srs_stats"], ([command]) =>
invoke<SrsStats>(command), invoke<SrsStats>(command),
); );
@ -38,3 +38,5 @@ export default function SrsPane() {
</main> </main>
); );
} }
Component.displayName = "SrsPane";

View file

@ -1,15 +0,0 @@
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 />);
});
});

View file

@ -18,7 +18,7 @@ import {
import InputBox from "../components/srsReview/InputBox"; import InputBox from "../components/srsReview/InputBox";
import SelectOnClick from "../components/utils/SelectOnClick"; import SelectOnClick from "../components/utils/SelectOnClick";
export default function SrsReviewPane() { export function Component() {
// null = has not started, (.length == 0) = finished // null = has not started, (.length == 0) = finished
const [reviewQueue, setReviewQueue] = useState<ReviewItem[] | null>(null); const [reviewQueue, setReviewQueue] = useState<ReviewItem[] | null>(null);
const [completedQueue, setCompletedQueue] = useState<ReviewItem[]>([]); const [completedQueue, setCompletedQueue] = useState<ReviewItem[]>([]);
@ -147,9 +147,7 @@ export default function SrsReviewPane() {
/> />
)} )}
<h1 className={styles.testWord} data-testid="testWord"> <h1 className={styles.testWord}>{nextItem.challenge}</h1>
{nextItem.challenge}
</h1>
<InputBox <InputBox
submit={formSubmit} submit={formSubmit}
@ -198,3 +196,5 @@ export default function SrsReviewPane() {
</main> </main>
); );
} }
Component.displayName = "SrsReviewPane";

View file

@ -1,10 +1,12 @@
import VocabList from "../components/VocabList"; import VocabList from "../components/VocabList";
import styles from "./VocabPane.module.scss"; import styles from "./VocabPane.module.scss";
export default function VocabPane() { export function Component() {
return ( return (
<main className={styles.main}> <main className={styles.main}>
<VocabList /> <VocabList />
</main> </main>
); );
} }
Component.displayName = "VocabPane";

View file

@ -1,7 +0,0 @@
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 });
}

View file

@ -1,8 +0,0 @@
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
globals: true,
environment: "jsdom",
},
});