diff --git a/svelte.config.js b/svelte.config.js index 20342dd..4b5b7c4 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -14,6 +14,7 @@ const config = { }, alias: { $components: "src/components", + $routes: "src/routes", $stores: "src/stores", $states: "src/states", $services: "src/services", diff --git a/tests/setup.ts b/tests/setup.ts index e69de29..407f804 100644 --- a/tests/setup.ts +++ b/tests/setup.ts @@ -0,0 +1 @@ +import "@testing-library/jest-dom/vitest"; diff --git a/tests/unit/errorUtils.test.ts b/tests/unit/errorUtils.test.ts new file mode 100644 index 0000000..16f5fff --- /dev/null +++ b/tests/unit/errorUtils.test.ts @@ -0,0 +1,155 @@ +import { AppError, ImageError, TextError, CanvasError, StorageError } from "$lib/error.types"; +import { formatError, createError, logError } from "$lib/utils/errorUtils"; +import { describe, expect, it, vi } from "vitest"; + +describe("errorUtils", () => { + describe("formatError", () => { + it("should format AppError", () => { + const error = new AppError("Test error", "TEST_CODE"); + const result = formatError(error, "Default message"); + + expect(result).toBe("Default message: Test error"); + }); + + it("should format Error", () => { + const error = new Error("Test error"); + const result = formatError(error, "Default message"); + + expect(result).toBe("Default message: Test error"); + }); + + it("should format string error", () => { + const error = "String error message"; + const result = formatError(error, "Default message"); + + expect(result).toBe("Default message: String error message"); + }); + + it("should format unknown error", () => { + const error = { custom: "object" }; + const result = formatError(error, "Default message"); + + expect(result).toBe("Default message: Произошла неизвестная ошибка"); + }); + + it("should use default message when not provided", () => { + const error = new Error("Test error"); + const result = formatError(error); + + expect(result).toBe("Произошла ошибка: Test error"); + }); + + it("should format ImageError", () => { + const error = new ImageError("Image failed"); + const result = formatError(error, "Default message"); + + expect(result).toBe("Default message: Image failed"); + }); + + it("should format TextError", () => { + const error = new TextError("Text failed"); + const result = formatError(error, "Default message"); + + expect(result).toBe("Default message: Text failed"); + }); + + it("should format CanvasError", () => { + const error = new CanvasError("Canvas failed"); + const result = formatError(error, "Default message"); + + expect(result).toBe("Default message: Canvas failed"); + }); + + it("should format StorageError", () => { + const error = new StorageError("Storage failed"); + const result = formatError(error, "Default message"); + + expect(result).toBe("Default message: Storage failed"); + }); + }); + + describe("createError", () => { + it("should create AppError with message and code", () => { + const error = createError("Test error", "TEST_CODE"); + + expect(error).toBeInstanceOf(AppError); + expect(error.message).toBe("Test error"); + expect(error.code).toBe("TEST_CODE"); + expect(error.details).toBeUndefined(); + }); + + it("should create AppError with message, code and details", () => { + const details = { userId: 123, action: "test" }; + const error = createError("Test error", "TEST_CODE", details); + + expect(error.details).toEqual(details); + expect(error.message).toBe("Test error"); + expect(error.code).toBe("TEST_CODE"); + }); + }); + + describe("logError", () => { + it("should log Error with stack", () => { + const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => {}); + const error = new Error("Test error"); + + logError(error, "Test context"); + + expect(consoleSpy).toHaveBeenCalledWith("Error occurred:", { + error, + context: "Test context", + timestamp: expect.any(String), + stack: expect.any(String), + }); + + consoleSpy.mockRestore(); + }); + + it("should log AppError with stack", () => { + const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => {}); + const error = new AppError("Test error", "TEST_CODE"); + + logError(error, "Test context"); + + expect(consoleSpy).toHaveBeenCalledWith("Error occurred:", { + error, + context: "Test context", + timestamp: expect.any(String), + stack: expect.any(String), + }); + + consoleSpy.mockRestore(); + }); + + it("should log string error without stack", () => { + const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => {}); + + logError("String error", "Test context"); + + expect(consoleSpy).toHaveBeenCalledWith("Error occurred:", { + error: "String error", + context: "Test context", + timestamp: expect.any(String), + stack: undefined, + }); + + consoleSpy.mockRestore(); + }); + + it("should log error without context", () => { + const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => {}); + const error = new Error("Test error"); + + logError(error); + + expect(consoleSpy).toHaveBeenCalledWith("Error occurred:", { + error, + context: undefined, + timestamp: expect.any(String), + stack: expect.any(String), + }); + + consoleSpy.mockRestore(); + }); + }); +}); diff --git a/tests/unit/routes/layout.settings.test.ts b/tests/unit/routes/layout.settings.test.ts new file mode 100644 index 0000000..786bb55 --- /dev/null +++ b/tests/unit/routes/layout.settings.test.ts @@ -0,0 +1,12 @@ +import { prerender, ssr } from "$routes/+layout"; +import { describe, expect, it } from "vitest"; + +describe("+layout.ts", () => { + it("should export ssr as false", () => { + expect(ssr).toBe(false); + }); + + it("should export prerender as true", () => { + expect(prerender).toBe(true); + }); +}); diff --git a/tests/unit/routes/layout.test.ts b/tests/unit/routes/layout.test.ts new file mode 100644 index 0000000..ec33e11 --- /dev/null +++ b/tests/unit/routes/layout.test.ts @@ -0,0 +1,50 @@ +import { themeState } from "$states/theme.svelte"; +import { beforeEach, describe, expect, it, vi } from "vitest"; + +describe("+layout.svelte", () => { + beforeEach(() => { + themeState.theme = "dark"; + vi.clearAllMocks(); + }); + + it("should apply dark theme", () => { + themeState.theme = "dark"; + + expect(themeState.theme).toBe("dark"); + }); + + it("should apply light theme", () => { + themeState.theme = "light"; + + expect(themeState.theme).toBe("light"); + }); + + it("should toggle theme", () => { + themeState.theme = "dark"; + themeState.toggle(); + + expect(themeState.theme).toBe("light"); + }); +}); + +import Layout from "$routes/+layout.svelte"; +import { render, screen } from "@testing-library/svelte"; +import { createRawSnippet } from "svelte"; + +describe("Layout Component Coverage", () => { + it("should render children snippet and initialize props", () => { + const testId = "test-child"; + const childrenSnippet = createRawSnippet(() => ({ + render: () => `Hello`, + })); + + render(Layout, { + props: { + children: childrenSnippet, + }, + }); + + expect(screen.getByTestId(testId)).toBeInTheDocument(); + expect(screen.getByRole("banner")).toBeInTheDocument(); + }); +}); diff --git a/tests/unit/services/downloadService.test.ts b/tests/unit/services/downloadService.test.ts index 51d72be..0de60f1 100644 --- a/tests/unit/services/downloadService.test.ts +++ b/tests/unit/services/downloadService.test.ts @@ -10,13 +10,11 @@ vi.mock("file-saver", () => { }); vi.mock("jszip", () => { - // Создаем объект с методами заранее, чтобы иметь к ним доступ const mockZipInstance = { file: vi.fn().mockReturnThis(), generateAsync: vi.fn().mockResolvedValue(new Blob([])), }; - // Возвращаем функцию-конструктор return { default: vi.fn(function () { return mockZipInstance; diff --git a/tests/unit/states/konvaAllStages.test.ts b/tests/unit/states/konvaAllStages.test.ts index 1d46446..b7e72f4 100644 --- a/tests/unit/states/konvaAllStages.test.ts +++ b/tests/unit/states/konvaAllStages.test.ts @@ -3,7 +3,6 @@ import { konvaAllStagesState } from "$states/konvaAllStages.svelte"; describe("konvaAllStages.svelte", () => { beforeEach(() => { - // Clear the array before each test konvaAllStagesState.length = 0; });