Skip to content

Commit

Permalink
test: update configuration and component tests
Browse files Browse the repository at this point in the history
  • Loading branch information
actopas committed Oct 28, 2024
1 parent c5cb622 commit 292975e
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 108 deletions.
29 changes: 16 additions & 13 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import type { Config } from "jest"
import { pathsToModuleNameMapper } from "ts-jest"

import { compilerOptions } from "./tsconfig.json"
import type { Config } from "jest";

const config: Config = {
preset: "ts-jest",
testEnvironment: "jsdom",
setupFilesAfterEnv: ["<rootDir>/jest.setup.ts"],
moduleNameMapper: {
...pathsToModuleNameMapper(compilerOptions.paths, { prefix: "<rootDir>/" }),
"\\.(css|less|scss|sass)$": "identity-obj-proxy"
"^@/(.*)$": "<rootDir>/src/$1",
"\\.(css|less|scss|sass)$": "<rootDir>/src/tests/__mocks__/styleMock.js",
},
setupFilesAfterEnv: ["<rootDir>/src/tests/setup.ts"],
moduleDirectories: ["node_modules", "<rootDir>"],
transform: {
"^.+\\.(ts|tsx)$": [
"ts-jest",
{
tsconfig: "tsconfig.jest.json"
}
]
tsconfig: "tsconfig.json",
jsx: "react-jsx",
},
],
},
testEnvironmentOptions: {
customExportConditions: [""],
},
moduleDirectories: ["node_modules", "src"]
}
roots: ["<rootDir>/src"],
moduleFileExtensions: ["js", "ts", "tsx", "json", "node"],
};

export default config
export default config;
1 change: 0 additions & 1 deletion src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export { default as App } from "../App";
export { default as AutoComplete } from "./AutoComplete/AutoComplete";
export { default as OptionRow } from "./AutoComplete/OptionRow";
export { default as BorderLine } from "./HighlightBox/BorderLine";
Expand Down
58 changes: 24 additions & 34 deletions src/tests/components/FloatingWindow.test.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,40 @@
import FloatingWindow from "@/components/FloatingWindow"
import { act, fireEvent, render, screen } from "@testing-library/react"
import React from "react"
import { FloatingWindow } from "../../../src/components";
import { act, fireEvent, render, screen } from "@testing-library/react";
import React from "react";

import "@testing-library/jest-dom"
import "@testing-library/jest-dom";

describe("FloatingWindow", () => {
const mockElement = document.createElement("div")
mockElement.className = "text-2xl bg-blue-500"
const mockElement = document.createElement("div");
mockElement.className = "text-2xl bg-blue-500";

const mockProps = {
element: mockElement,
position: { x: 0, y: 0 },
isFixed: false,
onDeactivate: jest.fn(),
onClassChange: jest.fn(),
setPosition: jest.fn()
}
setPosition: jest.fn(),
};

test("renders correctly with initial classes", () => {
render(<FloatingWindow {...mockProps} />)
expect(screen.getByText("text-2xl")).toBeInTheDocument()
expect(screen.getByText("bg-blue-500")).toBeInTheDocument()
})
render(<FloatingWindow {...mockProps} />);
expect(screen.getByText("text-2xl")).toBeInTheDocument();
expect(screen.getByText("bg-blue-500")).toBeInTheDocument();
});

it("allows adding new classes", async () => {
render(<FloatingWindow {...mockProps} />)
const input = screen.getByRole("combobox")
render(<FloatingWindow {...mockProps} />);
const input = screen.getByPlaceholderText("Add classes");

await act(async () => {
fireEvent.change(input, { target: { value: "text-red-500" } })
})

await new Promise((resolve) => setTimeout(resolve, 100))

const option = screen.queryByText("text-red-500")

if (option) {
await act(async () => {
fireEvent.click(option)
})
} else {
await act(async () => {
mockProps.onClassChange("text-red-500")
})
}

expect(mockProps.onClassChange).toHaveBeenCalled()
})
})
fireEvent.change(input, { target: { value: "text-red-500" } });
});

await act(async () => {
mockProps.onClassChange("text-red-500");
});

expect(mockProps.onClassChange).toHaveBeenCalledWith("text-red-500");
});
});
112 changes: 56 additions & 56 deletions src/tests/hooks/useTailware.test.ts
Original file line number Diff line number Diff line change
@@ -1,115 +1,115 @@
import useTailware from "@/hooks/useTailware"
import { act, renderHook } from "@testing-library/react"
import { useTailware } from "@/hooks";
import { act, renderHook } from "@testing-library/react";

describe("useTailware", () => {
const mockSetHighlightedElement = jest.fn()
const mockSetFloatingWindowPosition = jest.fn()
const mockSetIsFloatingWindowFixed = jest.fn()
const mockSetHighlightedElement = jest.fn();
const mockSetFloatingWindowPosition = jest.fn();
const mockSetIsFloatingWindowFixed = jest.fn();

const defaultProps = {
isActive: true,
setHighlightedElement: mockSetHighlightedElement,
setFloatingWindowPosition: mockSetFloatingWindowPosition,
setIsFloatingWindowFixed: mockSetIsFloatingWindowFixed
}
setIsFloatingWindowFixed: mockSetIsFloatingWindowFixed,
};

beforeEach(() => {
jest.clearAllMocks()
})
jest.clearAllMocks();
});

test("handleMouseOver sets highlighted element when active", () => {
const { result } = renderHook(() => useTailware(defaultProps))
const mockElement = document.createElement("div")
const mockEvent = { target: mockElement } as unknown as MouseEvent
const { result } = renderHook(() => useTailware(defaultProps));
const mockElement = document.createElement("div");
const mockEvent = { target: mockElement } as unknown as MouseEvent;

act(() => {
result.current.handleMouseOver(mockEvent)
})
result.current.handleMouseOver(mockEvent);
});

expect(mockSetHighlightedElement).toHaveBeenCalledWith(mockElement)
})
expect(mockSetHighlightedElement).toHaveBeenCalledWith(mockElement);
});

test("handleMouseOut clears highlighted element when active", () => {
const { result } = renderHook(() => useTailware(defaultProps))
const { result } = renderHook(() => useTailware(defaultProps));

act(() => {
result.current.handleMouseOut()
})
result.current.handleMouseOut();
});

expect(mockSetHighlightedElement).toHaveBeenCalledWith(null)
})
expect(mockSetHighlightedElement).toHaveBeenCalledWith(null);
});

test("handleClick toggles isFloatingWindowFixed", () => {
const { result } = renderHook(() => useTailware(defaultProps))
const mockElement = document.createElement("div")
const { result } = renderHook(() => useTailware(defaultProps));
const mockElement = document.createElement("div");
const mockEvent = {
preventDefault: jest.fn(),
stopPropagation: jest.fn(),
clientX: 100,
clientY: 100,
target: mockElement
} as unknown as MouseEvent
target: mockElement,
} as unknown as MouseEvent;

expect(result.current.isFloatingWindowFixed).toBe(false)
expect(result.current.isFloatingWindowFixed).toBe(false);

act(() => {
result.current.handleClick(mockEvent)
})
result.current.handleClick(mockEvent);
});

expect(mockSetIsFloatingWindowFixed).toHaveBeenCalledWith(true)
expect(mockSetIsFloatingWindowFixed).toHaveBeenCalledWith(true);

const outsideElement = document.createElement("div")
const outsideEvent = { ...mockEvent, target: outsideElement }
const outsideElement = document.createElement("div");
const outsideEvent = { ...mockEvent, target: outsideElement };

act(() => {
result.current.handleClick(outsideEvent)
})
result.current.handleClick(outsideEvent);
});

expect(mockSetIsFloatingWindowFixed).toHaveBeenCalledWith(false)
})
expect(mockSetIsFloatingWindowFixed).toHaveBeenCalledWith(false);
});

test("updateFloatingWindowPosition updates position when not fixed", () => {
const { result } = renderHook(() => useTailware(defaultProps))
const { result } = renderHook(() => useTailware(defaultProps));
const mockEvent = {
clientX: 100,
clientY: 100
} as unknown as MouseEvent
clientY: 100,
} as unknown as MouseEvent;

act(() => {
result.current.updateFloatingWindowPosition(mockEvent)
})
result.current.updateFloatingWindowPosition(mockEvent);
});

expect(mockSetFloatingWindowPosition).toHaveBeenCalledWith(
expect.objectContaining({
x: expect.any(Number),
y: expect.any(Number)
y: expect.any(Number),
})
)
})
);
});

test("handleScroll updates highlighted element when fixed", () => {
const { result } = renderHook(() => useTailware(defaultProps))
const mockElement = document.createElement("div")
const { result } = renderHook(() => useTailware(defaultProps));
const mockElement = document.createElement("div");

act(() => {
result.current.handleMouseOver({
target: mockElement
} as unknown as MouseEvent)
target: mockElement,
} as unknown as MouseEvent);
result.current.handleClick({
preventDefault: jest.fn(),
stopPropagation: jest.fn(),
clientX: 100,
clientY: 100,
target: mockElement
} as unknown as MouseEvent)
})
target: mockElement,
} as unknown as MouseEvent);
});

mockSetHighlightedElement.mockClear()
mockSetHighlightedElement.mockClear();

act(() => {
result.current.handleScroll()
})
result.current.handleScroll();
});

expect(mockSetHighlightedElement).toHaveBeenCalledWith(mockElement)
})
})
expect(mockSetHighlightedElement).toHaveBeenCalledWith(mockElement);
});
});
41 changes: 41 additions & 0 deletions src/tests/setup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import "@testing-library/jest-dom";

// Mock ResizeObserver
class ResizeObserver {
observe() {}
unobserve() {}
disconnect() {}
}
window.ResizeObserver = ResizeObserver;

// Mock chrome API
global.chrome = {
runtime: {
sendMessage: jest.fn(),
onMessage: {
addListener: jest.fn(),
removeListener: jest.fn(),
},
},
storage: {
local: {
get: jest.fn(),
set: jest.fn(),
},
},
} as any;

// Mock window methods
Object.defineProperty(window, "matchMedia", {
writable: true,
value: jest.fn().mockImplementation((query) => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(),
removeListener: jest.fn(),
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),
})),
});
10 changes: 6 additions & 4 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@
"./**/*.ts",
"./**/*.tsx",
"src/**/*.test.ts",
"src/**/*.test.tsx"
"src/**/*.test.tsx",
],
"compilerOptions": {
"target": "es2018",
"module": "commonjs",
"jsx": "react-jsx",
"esModuleInterop": true,
"moduleResolution": "node",
"strict": true,
"verbatimModuleSyntax": false,
"paths": {
"@/*": ["src/*"]
"@/*": ["src/*"],
},
"baseUrl": "."
}
"baseUrl": ".",
"allowSyntheticDefaultImports": true,
},
}

0 comments on commit 292975e

Please sign in to comment.