From 3e86c784e756bb76522bc6dd7133cc577dab8b96 Mon Sep 17 00:00:00 2001 From: SinusFox <61253950+SinusFox@users.noreply.github.com> Date: Fri, 11 Oct 2024 14:26:40 +0200 Subject: [PATCH] adding tests --- __tests__/render_home_page.test.js | 22 ++++++ __tests__/scripts.test.js | 109 +++++++++++++++++++++++++---- src/app/page.tsx | 6 +- src/app/scripts.ts | 97 +------------------------ 4 files changed, 124 insertions(+), 110 deletions(-) create mode 100644 __tests__/render_home_page.test.js diff --git a/__tests__/render_home_page.test.js b/__tests__/render_home_page.test.js new file mode 100644 index 0000000..663eb50 --- /dev/null +++ b/__tests__/render_home_page.test.js @@ -0,0 +1,22 @@ +import { render, screen, fireEvent, waitFor } from '@testing-library/react'; +import '@testing-library/jest-dom'; +import Home from "../src/app/page"; +import { customLog, customLogClear } from '../src/app/scripts'; + +jest.mock('../src/app/scripts', () => ({ + customLog: jest.fn(), + customLogClear: jest.fn(), +})); + +jest.mock('../src/solver/glpk.min.js', () => ({ + LPF_ECOND: 2, +})); + +test('render home page', () => { + // render website + render(); + + // check if text is in document + const headingElement = screen.getByText(/OR-Tool/i); // text search in document + expect(headingElement).toBeInTheDocument(); +}); diff --git a/__tests__/scripts.test.js b/__tests__/scripts.test.js index 7ca3f96..5df2024 100644 --- a/__tests__/scripts.test.js +++ b/__tests__/scripts.test.js @@ -1,21 +1,104 @@ -import { render, screen, fireEvent, waitFor } from '@testing-library/react'; -import '@testing-library/jest-dom'; -import Home from "../src/app/page"; - -jest.mock('../src/app/scripts', () => ({ - customLog: jest.fn(), - customLogClear: jest.fn(), -})); +import { render, fireEvent, screen } from '@testing-library/react'; +import { + customLog, + customLogClear, + getTranslation, + isInputValidRegex, + isInputFilled, + downloadLPFormatting, + downloadLP, + calculate_click +} from '../src/app/scripts'; +import Home from '../src/app/page' +import text from '../src/app/lang'; +// Mocking GLPKAPI and console log jest.mock('../src/solver/glpk.min.js', () => ({ LPF_ECOND: 2, })); -test('render home page', () => { - // render website +// Mocking console.log +const consoleLogMock = jest.spyOn(console, 'log').mockImplementation(() => {}); + +beforeEach(() => { + document.body.innerHTML = ` +
+ + + + + + +
+
+ `; + jest.clearAllMocks(); // Clear any previous mocks +}); + +test('customLog should append message to output box', () => { + const message = 'Test message'; + customLog(message); + const outputElement = document.getElementById('out'); + expect(outputElement.innerHTML).toContain(message); +}); + +test('customLogClear should clear the output box', () => { + const message = 'Test message'; + customLog(message); + customLogClear(); + const outputElement = document.getElementById('out'); + expect(outputElement.innerHTML).toBe(''); +}); + +test('getTranslation should return translation based on selected language', () => { + const result = getTranslation('header_title'); + expect(result).toBe(text('eng', 'header_title')); // Assuming text function provides correct translation +}); + +test('isInputValidRegex should validate input regex correctly', () => { + expect(isInputValidRegex("x + y", "+1 x + 2 y <= 15\n+3 x + 1 y <= 20", "x >= 0\ny >= 0", "x\ny")).toBe(true); + expect(isInputValidRegex("x + y", "+1 x + 2 y <= 15\n+3 x + 1 y <= 20", "x >= 0\ny >= 0", "")).toBe(false); // Invalid objective +}); + +test('isInputFilled should check for filled inputs', () => { + expect(isInputFilled('3x + 5y', 'x + y <= 10', 'x <= 5', 'x\ny')).toBe(true); + expect(isInputFilled('', 'x + y <= 10', 'x <= 5', 'x\ny')).toBe(false); // Objective empty +}); + +test('downloadLPFormatting should format LP correctly', () => { + const formattedLP = downloadLPFormatting('3x + 5y', 'x + y <= 10', 'x <= 5'); + expect(formattedLP).toContain('obj: 3x + 5y'); + expect(formattedLP).toContain('Subject To'); + expect(formattedLP).toContain('Bounds'); +}); + +test('calculate_click should display "Calculating" in the output box', () => { render(); - // check if text is in document - const headingElement = screen.getByText(/OR-Tool/i); // text search in document - expect(headingElement).toBeInTheDocument(); + // Spy on customLog and customLogClear to prevent actual logging and check the calls + const mockClear = jest.spyOn({ customLogClear }, 'customLogClear').mockImplementation(); + const mockLog = jest.spyOn({ customLog }, 'customLog').mockImplementation(); + + // Set valid inputs + document.getElementById('objective').value = '3x + 5y'; + document.getElementById('subject').value = 'x + y <= 10'; + document.getElementById('bounds').value = 'x <= 5'; + document.getElementById('vars').value = 'x\ny'; + + // Simuliere den Button-Klick, der die Berechnung startet + fireEvent.click(screen.getByText('Calculate')); + + // Check the contents of out box + const outputElement = document.getElementById('out'); + expect(outputElement.innerHTML).toContain('Calculating'); + + // Clear mock + mockClear.mockRestore(); + mockLog.mockRestore(); }); + diff --git a/src/app/page.tsx b/src/app/page.tsx index 88b5ed9..332c116 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -2,12 +2,12 @@ import React, { useState } from 'react'; import { Box, Button, Output } from "./modules"; -import { calculate_click, downloadLP, import_click } from "./scripts"; +import { calculate_click, downloadLP } from "./scripts"; import text from "./lang"; export default function Home() { const [language, setLanguage] = useState('eng'); - const [maxminOption, setMaxminOption] = useState('maximize'); // Zustand für den MaxMin-Switch + const [maxminOption, setMaxminOption] = useState('maximize'); const tr_hTitle = text(language, 'header_title'); const tr_hSubtitle = text(language, 'header_subtitle'); @@ -30,7 +30,7 @@ export default function Home() { }; const handleMaxMinChange = (event: React.ChangeEvent) => { - setMaxminOption(event.target.value); // Update den Zustand basierend auf dem Wert des Selects + setMaxminOption(event.target.value); }; return ( diff --git a/src/app/scripts.ts b/src/app/scripts.ts index b46dae5..d01f4a7 100644 --- a/src/app/scripts.ts +++ b/src/app/scripts.ts @@ -62,7 +62,7 @@ function walltimeStart() { return Date.now(); } -function isInputValidRegex(obj: string | undefined, subj: string | undefined, bounds: string | undefined, vars: string | undefined): boolean { +export function isInputValidRegex(obj: string | undefined, subj: string | undefined, bounds: string | undefined, vars: string | undefined): boolean { customLog("input_checks_start"); // standard case: input is undefined - invalid @@ -108,7 +108,7 @@ function isInputValidRegex(obj: string | undefined, subj: string | undefined, bo return true; } -function isInputFilled(obj: string | undefined, subj: string | undefined, bounds: string | undefined, vars: string | undefined) { +export function isInputFilled(obj: string | undefined, subj: string | undefined, bounds: string | undefined, vars: string | undefined): boolean { if (obj == "" || obj == null || obj == undefined) { customLog("err_emptyBox"); return false; @@ -158,56 +158,6 @@ export function calculate_click() { variables = (varsElement as HTMLInputElement).value; } - // let funcs:string[] = functions.split(/;/); - // let vars:string[] = variables.split(/;/); - - // let direction = null; - - // let namesVars:string[] = []; - - // let variablesMIP:VariableMIP[]; - // let variablesLP:VariableLP[]; - - // // console.log(vars); - - // for (const decider of vars) { - - // // match comments - // let regexMatch:RegExpMatchArray|null = decider.match(/#.*/); - // if (regexMatch != null) - // continue; - - // regexMatch = decider.match(/var/); - // if (regexMatch != null) - // namesVars.push(regexMatch[1]); - - - - // console.log(regexMatch); - // } - - - // for (const decider of funcs) { - // let dir = decider.match(/(min|max) .*/); - // if (direction != null && dir != null) { - // document.getElementById('out').innerHTML = "ERROR: Multiple Functions!"; - // return; - // } - // if (direction == null && dir != null) { - // direction = dir[1]; - // let test = parseFunction(decider); - // console.log(test?.name); - // variablesLP. - // continue; - // } - - // console.log(direction); - - // document.getElementById('out').innerHTML = direction; - - // console.log(parseFunction(decider)); - - // catch error: empty input field(s) if (!isInputFilled(objective, subject, bounds, variables)) return; @@ -225,8 +175,6 @@ export function calculate_click() { + "\nGenerals \n" + variables + "\nEnd"; - // customLog("

DEBUGGING

\nfunctions:
" + functions + "

variables:
" + variables + "

DEBUGGING END
"); - customLog(getTranslation("run_optimization") + ": \"" + wholeText + "\""); customLog(""); run(wholeText); @@ -276,7 +224,7 @@ function run(text: string) { customLog(""); } -function downloadLPFormatting(objective: any, subject: any, bounds: any) { +export function downloadLPFormatting(objective: any, subject: any, bounds: any) { customLog(getTranslation("downloadPrepFileString")); customLog(""); @@ -294,7 +242,6 @@ function downloadLPFormatting(objective: any, subject: any, bounds: any) { const header = "\\ Your problem\n"; // format objective - const objectiveFunction = operator + `\n obj: ${formattedObjective}\n`; // turn each subject into a single line @@ -358,41 +305,3 @@ export function downloadLP() { downloadProblemDownload(exportString); } - -// Irgend ein Interface -// document.getElementById('out').innerHTML = funcs; - -// output.innerHTML = functions.innerHTML; - -// createProblemMIP(); - -// LPAPI.default(); - - -export function import_click() { - console.log("importing"); -} - - -// export function export_click() { -// console.log("Exporting..."); - -// } - -// function parseFunction(toParse: string) { -// var regex = toParse.match(/([a-zA-Z][a-zA-Z0-9]*):/); -// if (regex == null) -// return; -// var name = regex[1]; - -// regex = toParse.match(/(?:([0-9]*) *\* *([a-zA-Z][a-zA-Z0-9]*))/g); - -// let coefs:number[] = []; -// let vars:string[] = []; - -// for (const rg of regex) { -// coefs.push(+rg.match(/([0-9]+)/g)); -// vars.push(rg.match(/([a-zA-Z][a-zA-Z0-9]*)/g)[0]); -// } -// return {name, coefs, vars}; -// }