Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sandevh/stu 307 generate tests with an llm #1122

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Prev Previous commit
Next Next commit
draggable generated test
izi-on committed Feb 29, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 844c3ec36cf9b90e3aceed50221c11354ec885cd
1 change: 1 addition & 0 deletions src/renderer/hooks/useTestSequencerState.ts
Original file line number Diff line number Diff line change
@@ -143,6 +143,7 @@ export function useTestSequencerState() {
setElements(candidateElems);
setUnsaved(true);

console.log("elements set successfully");
/* _________________________ */

//creates tree to send to backend
20 changes: 17 additions & 3 deletions src/renderer/routes/test_sequencer_panel/components/Panels.tsx
Original file line number Diff line number Diff line change
@@ -13,13 +13,15 @@ import {
} from "@/renderer/components/ui/tabs";
import { CloudPanel } from "./panels/CloudPanel";
import { ControlPanel } from "./panels/ControlPanel";
import { TestGeneratorPanel } from "./panels/TestGeneratorPanel/TestGeneratorPanel";

export function TabsDemo() {
return (
<Tabs defaultValue="control" className="w-[400px]">
<TabsList className="grid w-full grid-cols-2">
<Tabs defaultValue="control" className="w-full">
<TabsList className="grid w-full grid-cols-3">
<TabsTrigger value="control">Control Panel</TabsTrigger>
<TabsTrigger value="cloud">Cloud Panel</TabsTrigger>
<TabsTrigger value="generate">Generate Panel</TabsTrigger>
</TabsList>
<TabsContent value="cloud">
<Card>
@@ -39,14 +41,26 @@ export function TabsDemo() {
<CardHeader>
<CardTitle>Control</CardTitle>
<CardDescription>
Hanlde test sequence file management
Handle test sequence file management
</CardDescription>
</CardHeader>
<CardContent>
cloud
<ControlPanel />
</CardContent>
</Card>
</TabsContent>
<TabsContent value="generate">
<Card>
<CardHeader>
<CardTitle>Generate</CardTitle>
<CardDescription>Generate tests using AI</CardDescription>
</CardHeader>
<CardContent>
<TestGeneratorPanel />
</CardContent>
</Card>
</TabsContent>
</Tabs>
);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { DataTable } from "./data-table/DataTable";
import { DataTable } from "./data_table/DataTable";
import { SummaryTable } from "./SummaryTable";
import { LockedContextProvider } from "@/renderer/context/lock.context";
import {
Original file line number Diff line number Diff line change
@@ -28,7 +28,6 @@ import {
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
@@ -50,14 +49,15 @@ import { ChevronUpIcon, ChevronDownIcon, TrashIcon } from "lucide-react";
import { WriteConditionalModal } from "../AddWriteConditionalModal";
import LockableButton from "../lockable/LockedButtons";
import { useRef, useState, useEffect } from "react";
import TestNameCell from "./test-name-cell";
import TestNameCell from "./TestNameCell";
import { DraggableRow } from "../dnd/DraggableRow";
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card";
import PythonTestFileModal from "../PythonTestFileModal";
import { DroppableEmptyRow } from "../dnd/DroppableEmptyRow";

function renderErrorMessage(text: string): JSX.Element {
const lines = text.split("\n");
@@ -486,14 +486,7 @@ export function DataTable() {
</ContextMenu>
))
) : (
<TableRow>
<TableCell
colSpan={columns.length}
className="h-24 text-center"
>
No results.
</TableCell>
</TableRow>
<DroppableEmptyRow colSpan={columns.length + 1} />
)}
</TableBody>
</Table>
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import { useDrag, useDrop } from "react-dnd";
import {
Droppable,
ItemTypes,
TestSequenceDropResult,
} from "../../models/drag_and_drop";
import { useDrag } from "react-dnd";
import { ItemTypes, TestSequenceDropResult } from "../../models/drag_and_drop";
import { TableCell, TableRow } from "@/renderer/components/ui/table";
import { TestSequenceElement } from "@/renderer/types/testSequencer";
import { Row, flexRender } from "@tanstack/react-table";
import { parseInt } from "lodash";
import { useTestSequencerState } from "@/renderer/hooks/useTestSequencerState";
import { useConfigureDropRef } from "./utils";

export const DraggableRow = ({
row,
@@ -35,7 +32,7 @@ export const DraggableRow = ({
const [{ isDragging }, drag] = useDrag(
() => ({
type: ItemTypes.TestElementRow,
item: { rowIdx: parseInt(row.id) },
item: { rowIdx: parseInt((row as Row<TestSequenceElement>).id) },
end: (item, monitor) => {
const dropResult = monitor.getDropResult<TestSequenceDropResult>();
if (item && dropResult) {
@@ -49,28 +46,14 @@ export const DraggableRow = ({
[elems],
);

//define behaviour for drop
const useConfigureDropRef = (idx: number) => {
return useDrop(() => ({
accept: [ItemTypes.TestElementRow],
drop: (): TestSequenceDropResult => {
return { type: Droppable.TestSequenceTable, targetIdx: idx };
},
collect: (monitor) => ({
isOver: monitor.isOver(),
canDrop: monitor.canDrop(),
}),
}));
};

//create drop below context
const [{ isOver: isOverBelow, canDrop: canDropBelow }, dropBelow] =
useConfigureDropRef(parseInt(row.id) + 1);
useConfigureDropRef(parseInt((row as Row<TestSequenceElement>).id) + 1);
const isActiveBelow = isOverBelow && canDropBelow;

//create drop above context
const [{ isOver: isOverAbove, canDrop: canDropAbove }, dropAbove] =
useConfigureDropRef(parseInt(row.id));
useConfigureDropRef(parseInt((row as Row<TestSequenceElement>).id));
const isActiveAbove = isOverAbove && canDropAbove;

return (
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { TableCell, TableRow } from "@/renderer/components/ui/table";
import { useConfigureDropRef } from "./utils";

export const DroppableEmptyRow = ({ colSpan }: { colSpan: number }) => {
//create drop below context
const [{ isOver: isOverEmpty, canDrop: canDropEmpty }, dropEmpty] =
useConfigureDropRef();
const isActive = isOverEmpty && canDropEmpty;

return (
<TableRow className="relative">
{/* capture drag below */}
<div ref={dropEmpty} className="absolute z-10 h-full w-full" />

{isActive && (
<div
style={{ height: 2 }}
className="absolute top-0 w-full bg-blue-700"
/>
)}

<TableCell colSpan={colSpan} className="h-24 w-full text-center">
Add tests to get started!
</TableCell>
</TableRow>
);
};
20 changes: 20 additions & 0 deletions src/renderer/routes/test_sequencer_panel/components/dnd/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useDrop } from "react-dnd";
import {
Droppable,
ItemTypes,
TestSequenceDropResult,
} from "../../models/drag_and_drop";

//define behaviour for drop
export const useConfigureDropRef = (idx = 0) => {
return useDrop(() => ({
accept: [ItemTypes.TestElementRow],
drop: (): TestSequenceDropResult => {
return { type: Droppable.TestSequenceTable, targetIdx: idx };
},
collect: (monitor) => ({
isOver: monitor.isOver(),
canDrop: monitor.canDrop(),
}),
}));
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { TableCell, TableRow } from "@/renderer/components/ui/table";
import { Test } from "@/renderer/types/testSequencer";
import { Row, flexRender } from "@tanstack/react-table";
import { useDrag } from "react-dnd";
import {
ItemTypes,
TestSequenceDropResult,
} from "../../../models/drag_and_drop";
import { useTestSequencerState } from "@/renderer/hooks/useTestSequencerState";

export const GeneratedTest = ({ row }: { row: Row<Test> }) => {
const { setElems } = useTestSequencerState();
const [, drag] = useDrag(() => ({
type: ItemTypes.TestElementRow,
item: { row: row },
end: (item, monitor) => {
const dropResult = monitor.getDropResult<TestSequenceDropResult>();
if (item && dropResult) {
setElems((elems) => {
const newElems = [...elems];
newElems.splice(dropResult.targetIdx, 0, item.row.original);
return newElems;
});
}
},
}));
return (
<TableRow
key={row.id}
data-state={row.getIsSelected() && "selected"}
ref={drag}
>
{row.getVisibleCells().map((cell) => (
<TableCell key={cell.id}>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { Button } from "@/renderer/components/ui/button";
import { Input } from "@/renderer/components/ui/input";
import { Label } from "@/renderer/components/ui/label";
import { Separator } from "@/renderer/components/ui/separator";
import {
Table,
TableBody,
TableCell,
TableHead,
TableHeader,
TableRow,
} from "@/renderer/components/ui/table";
import { Test } from "@/renderer/types/testSequencer";
import {
ColumnDef,
flexRender,
getCoreRowModel,
useReactTable,
} from "@tanstack/react-table";
import { useState } from "react";
import { GeneratedTest } from "./GeneratedTest";

export const columns: ColumnDef<Test>[] = [
{
id: "name",
header: "Test Name",
cell: ({ row }) => {
return <div>{row.original.testName}</div>;
},
},
{
id: "type",
header: "Test Type",
cell: ({ row }) => {
return <div>{row.original.testType}</div>;
},
},
];

export const TestGeneratorPanel = () => {
const [data] = useState<Test[]>([
{
type: "test",
id: "sadasd",
groupId: "sadasdfassf",
path: "/sadkjnad",
testName: "test",
testType: "Pytest",
runInParallel: false,
status: "pending",
error: null,
completionTime: undefined,
isSavedToCloud: false,
},
] as Test[]);
const table = useReactTable({
data,
columns,
getCoreRowModel: getCoreRowModel(),
});
return (
<div className="flex w-full flex-col space-y-4">
<Label htmlFor="prompt">Enter prompt:</Label>
<Input
type="text"
id="prompt"
placeholder="Example: Test basic arithmetic operations"
/>
<Button type="submit">Generate</Button>
<Separator />
<Label htmlFor="generated-test">Generated tests:</Label>
<div className="rounded-md border">
<Table id="generated-test">
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead key={header.id}>
{header.isPlaceholder
? null
: flexRender(
header.column.columnDef.header,
header.getContext(),
)}
</TableHead>
);
})}
</TableRow>
))}
</TableHeader>
<TableBody>
{table.getRowModel().rows?.length ? (
table.getRowModel().rows.map((row) => <GeneratedTest row={row} />)
) : (
<TableRow>
<TableCell colSpan={columns.length} className="text-center">
Generated tests will appear here
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</div>
</div>
);
};