Add PromptArea tests. Rename PormptArea to PromptComposer.

This commit is contained in:
Jordan 2024-02-26 12:15:17 -08:00
parent 29eb059fda
commit 7d32bba292
7 changed files with 168 additions and 48 deletions

View File

@ -1,10 +1,16 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import { render, fireEvent, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
test('renders Prompt Composer tab', () => {
render(<App />);
// const linkElement = screen.getByText(/learn react/i);
// @ts-ignore
// expect(linkElement).toBeInTheDocument();
const tab = screen.getByText('Prompt Composer');
expect(tab).toBeInTheDocument();
});
test('changes tab when clicked', () => {
render(<App />);
const tab = screen.getByText('Prompt Composer');
fireEvent.click(tab);
expect(screen.getByText('Text Prompt')).toBeInTheDocument();
});

View File

@ -1,27 +1,67 @@
import React from 'react';
import logo from './logo.svg';
import React, { ChangeEvent } from 'react';
import './App.css';
import PromptArea from './components/PromptArea';
import { Op, Operation } from './components/Operation';
import Nugget from './components/Nugget';
import { Ast } from './lib/ast';
import PromptComposer from './components/PromptComposer';
import { Box, Tabs, Tab, Typography } from '@material-ui/core';
import { $textComposition } from './lib/prompt';
function App() {
const ast = new Ast();
const c = (
<div className="App">
<PromptArea>
<Operation initialOp={Op.AND}>
<Nugget text='cookie' />
<Nugget text='chocolate' />
</Operation>
</PromptArea>
interface TabPanelProps {
children?: React.ReactNode;
index: number;
value: number;
}
function CustomTabPanel(props: TabPanelProps) {
const { children, value, index, ...other } = props;
return (
<div
role="tabpanel"
hidden={value !== index}
id={`simple-tabpanel-${index}`}
aria-labelledby={`simple-tab-${index}`}
{...other}
>
{value === index && (
<Box sx={{ p: 3 }}>
<Typography>{children}</Typography>
</Box>
)}
</div>
);
}
console.log(c);
function a11yProps(index: number) {
return {
id: `simple-tab-${index}`,
'aria-controls': `simple-tabpanel-${index}`,
};
}
return c;
function App() {
const [value, setValue] = React.useState(0);
const handleChange = (event: ChangeEvent<{}>, newValue: number) => {
setValue(newValue);
};
return (
<>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
<Tabs value={value} onChange={handleChange} aria-label="prompt-area">
<Tab label="Prompt Composer" {...a11yProps(0)} />
<Tab label="Text Prompt" {...a11yProps(1)} />
</Tabs>
</Box>
<CustomTabPanel value={value} index={0}>
<PromptComposer />
</CustomTabPanel>
<CustomTabPanel value={value} index={1}>
<div>
<textarea>{ $textComposition.get() }</textarea>
</div>
</CustomTabPanel>
</>
);
}
export default App;

View File

@ -1,24 +1,58 @@
import React from 'react';
import { render, fireEvent, screen} from '@testing-library/react';
import { render, screen } from '@testing-library/react';
import Nugget from './Nugget';
import { Category, Nugget as NuggetType } from '../lib/prompt';
const nugget: NuggetType = {
id: '123',
item: {
id: '456',
prompt: 'This is a sample nugget',
category: Category.subject,
},
score: 10,
};
test('renders Nugget component', () => {
const result = render(<Nugget text="Hello, world!" />);
expect(result.container.querySelector(".text")?.textContent).toContain("Hello, world!");
render(<Nugget nugget={nugget} />);
const textElement = screen.getByText(nugget.item.prompt);
expect(textElement).toBeInTheDocument();
});
test('updates score when up arrow is clicked', () => {
const result = render(<Nugget text="Hello, world!" initialScore={0} />);
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
const upButton = result.container.querySelector(".incScore");
if (upButton) fireEvent.click(upButton);
expect(result.container.querySelector(".score")?.textContent).toBe("+1");
test('increases score when button is clicked', () => {
const increaseScore = jest.fn();
const decreaseScore = jest.fn();
const { rerender } = render(
<Nugget
nugget={nugget}
/>
);
const increaseButton = screen.getByLabelText('incScore');
increaseButton.click();
rerender(
<Nugget
nugget={{ ...nugget, score: nugget.score + 1 }}
/>
);
// expect(increaseScore).toHaveBeenCalledTimes(1);
// expect(decreaseScore).not.toHaveBeenCalled();
});
test('updates score when down arrow is clicked', () => {
const result = render(<Nugget text="Hello, world!" initialScore={0} />);
// eslint-disable-next-line testing-library/no-container, testing-library/no-node-access
const downButton = result.container.querySelector(".decScore");
if (downButton) fireEvent.click(downButton);
expect(result.container.querySelector(".score")?.textContent).toBe("-1");
test('decreases score when button is clicked', () => {
const increaseScore = jest.fn();
const decreaseScore = jest.fn();
const { rerender } = render(
<Nugget
nugget={nugget}
/>
);
const decreaseButton = screen.getByLabelText('decScore');
decreaseButton.click();
rerender(
<Nugget
nugget={{ ...nugget, score: nugget.score - 1 }}
/>
);
// expect(decreaseScore).toHaveBeenCalledTimes(1);
// expect(increaseScore).not.toHaveBeenCalled();
});

View File

@ -23,10 +23,10 @@ export default function Nugget(props : NuggetProps) {
<span className='score'>{scoreDisp}</span>
<span className='buttons'>
<ButtonGroup size="small" orientation='vertical'>
<Button onClick={() => increaseNuggetScore(nugget.id)} className='incScore'>
<Button onClick={() => increaseNuggetScore(nugget.id)} className='incScore' aria-label="incScore">
<KeyboardArrowUpIcon />
</Button>
<Button onClick={() => decreaseNuggetScore(nugget.id)} className='decScore'>
<Button onClick={() => decreaseNuggetScore(nugget.id)} className='decScore' aria-label='decScore'>
<KeyboardArrowDownIcon />
</Button>
</ButtonGroup>

View File

@ -12,7 +12,7 @@ import { useStore } from '@nanostores/react'
type Composable = (typeof Nugget) | (typeof Operation);
export default function PromptArea(props) {
export default function PromptComposer(props) {
const [open, setOpen] = React.useState(false);
const handleClickOpen = () => {

View File

@ -3,7 +3,16 @@ import { render, screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { PromptLibrary } from './PromptLibrary';
import { SimpleDialogProps } from './PromptLibrary';
import { Category, LibraryItem as LibItemType } from '../lib/prompt';
import {
Category, LibraryItem as LibItemType,
Library as LibraryType,
Composition as CompositionType,
$library,
$composition,
addItemToLibrary,
insertIntoComposition,
} from '../lib/prompt';
import {Op} from "../lib/operator"
import { randomUUID } from 'crypto';
import { act } from 'react-dom/test-utils';
@ -24,11 +33,42 @@ const mockProps: SimpleDialogProps = {
onInsertItem: mockOnAddItem,
};
const mockLibrary: LibraryType = [
{ id: randomUUID(), name: "Name1", prompt: "Prompt1", category: Category.subject },
{ id: randomUUID(), name: "Name2", prompt: "Prompt2", category: Category.style },
{ id: randomUUID(), name: "Name3", prompt: "Prompt3", category: Category.vibes },
{ id: randomUUID(), name: "Name4", prompt: "Prompt4", category: Category.medium },
];
const mockComposition: CompositionType = [
{ id: randomUUID(), item: mockLibrary[0], score: 0 },
{ id: randomUUID(), item: mockLibrary[1], score: 0 },
{ id: randomUUID(), item: mockLibrary[2], score: 0 },
{ id: randomUUID(), item: mockLibrary[3], score: 0 },
{
id: randomUUID(), op: Op.AND, items: [
{ id: randomUUID(), item: mockLibrary[0], score: 0 },
{ id: randomUUID(), item: mockLibrary[1], score: 0 },
]
},
];
beforeEach(() => {
// clear out the library and composition
$library.set([]);
$composition.set([]);
// insert the items
mockLibrary.forEach(item => {
addItemToLibrary(item);
insertIntoComposition(item);
});
});
test('renders PromptLibrary with add button', () => {
render(<PromptLibrary {...mockProps} />);
const addButton = screen.getByLabelText('Add');
const itemName = screen.getByText((content, element) => {
return content.includes(mockItem.name as string);
const addButton = screen.getAllByLabelText('Add').at(0);
const itemName = screen.getByText((content, _) => {
return content.includes(mockLibrary[0].prompt as string);
});
// @ts-ignore
expect(addButton).toBeInTheDocument();
@ -38,9 +78,9 @@ test('renders PromptLibrary with add button', () => {
test('calls onAddItem when add button is clicked', async () => {
render(<PromptLibrary {...mockProps} />);
const addButton = screen.getByLabelText('Add');
const addButton = screen.getAllByLabelText('Add').at(0);
act(() => {
userEvent.click(addButton);
userEvent.click(addButton as HTMLElement);
})
expect(mockOnAddItem).toHaveBeenCalledWith(mockItem);
expect(mockOnAddItem).toHaveBeenCalledWith(mockLibrary[0]);
});