Add task list demo application

This commit is contained in:
Steve Kinney
2024-09-17 15:38:26 -06:00
parent b13029bffc
commit 4971bda81b
40 changed files with 2545 additions and 773 deletions

View File

@@ -3,7 +3,7 @@
<head>
<title>Accident Counter</title>
</head>
<script type="module" lang="jsx">
<script type="module">
import { createElement } from 'react';
import { createRoot } from 'react-dom/client';
import { Counter } from './src/counter.tsx';
@@ -11,10 +11,7 @@
createRoot(document.getElementById('root')).render(createElement(Counter));
</script>
<body>
<div
class="container flex items-center justify-center h-screen"
id="root"
></div>
<body class="container flex items-center justify-center min-h-screen">
<div class="" id="root"></div>
</body>
</html>

View File

@@ -4,8 +4,9 @@
"main": "src/index.js",
"type": "module",
"scripts": {
"start": "vitest --ui",
"test": "vitest"
"start": "vite dev",
"test": "vitest",
"test:ui": "vitest --ui"
},
"repository": {
"type": "git",
@@ -18,11 +19,12 @@
},
"homepage": "https://github.com/stevekinney/testing-javascript#readme",
"devDependencies": {
"@tailwindcss/nesting": "^0.0.0-insiders.565cd3e",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.5.0",
"@testing-library/react": "^16.0.1",
"@types/react": "^18.3.6",
"@types/react-dom": "^18.3.0",
"@types/testing-library__jest-dom": "^5.14.9",
"@vitejs/plugin-react": "^4.3.1",
"@vitest/ui": "^2.1.1",
"react": "^18.3.1",

View File

@@ -1,7 +0,0 @@
export default {
plugins: {
'@tailwindcss/nesting': {},
tailwindcss: {},
autoprefixer: {},
},
};

View File

@@ -0,0 +1,85 @@
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Counter } from './counter';
import '@testing-library/jest-dom';
describe('Counter Component', () => {
beforeEach(() => {
render(<Counter />);
});
it('renders with an initial count of 0', () => {
const countElement = screen.getByTestId('counter-count');
expect(countElement).toHaveTextContent('0');
});
it('displays "days" when the count is 0', () => {
const unitElement = screen.getByTestId('counter-unit');
expect(unitElement).toHaveTextContent('days');
});
it('increments the count when the "Increment" button is clicked', async () => {
const incrementButton = screen.getByText('Increment');
await userEvent.click(incrementButton); // Using userEvent for a real click event
const countElement = screen.getByTestId('counter-count');
expect(countElement).toHaveTextContent('1');
});
it('displays "day" when the count is 1', async () => {
const incrementButton = screen.getByText('Increment');
await userEvent.click(incrementButton); // Increment the count
const unitElement = screen.getByTestId('counter-unit');
expect(unitElement).toHaveTextContent('day');
});
it('decrements the count when the "Decrement" button is clicked', async () => {
const incrementButton = screen.getByText('Increment');
const decrementButton = screen.getByText('Decrement');
await userEvent.click(incrementButton); // Increment first
await userEvent.click(decrementButton); // Then decrement
const countElement = screen.getByTestId('counter-count');
expect(countElement).toHaveTextContent('0');
});
it('does not allow decrementing below 0', async () => {
const decrementButton = screen.getByText('Decrement');
await userEvent.click(decrementButton); // Should not decrement below 0
const countElement = screen.getByTestId('counter-count');
expect(countElement).toHaveTextContent('0');
});
it('resets the count when the "Reset" button is clicked', async () => {
const incrementButton = screen.getByText('Increment');
const resetButton = screen.getByText('Reset');
await userEvent.click(incrementButton); // Increment first
await userEvent.click(resetButton); // Then reset
const countElement = screen.getByTestId('counter-count');
expect(countElement).toHaveTextContent('0');
});
it('disables the "Decrement" and "Reset" buttons when the count is 0', () => {
const decrementButton = screen.getByText('Decrement');
const resetButton = screen.getByText('Reset');
expect(decrementButton).toBeDisabled();
expect(resetButton).toBeDisabled();
});
it('updates the document title based on the count', async () => {
const incrementButton = screen.getByText('Increment');
await userEvent.click(incrementButton);
expect(document.title).toBe('1 day');
await userEvent.click(incrementButton);
expect(document.title).toBe('2 days');
});
});

View File

@@ -1,4 +1,4 @@
import React, { useReducer, useEffect } from 'react';
import { useReducer, useEffect } from 'react';
import { reducer } from './reducer';
export const Counter = () => {
@@ -12,12 +12,12 @@ export const Counter = () => {
return (
<div className="p-8 space-y-8 text-center bg-white border rounded-md shadow-lg border-slate-400">
<div className="space-y-4">
<div data-test-id="counter-count" className="font-semibold text-8xl">
<div data-testid="counter-count" className="font-semibold text-8xl">
{state.count}
</div>
<p>
<span data-test-id="counter-unit">{unit}</span> since the last
accident.
<span data-testid="counter-unit">{unit}</span> since the last
JavaScript-related accident.
</p>
</div>
<div className="flex gap-4">

View File

@@ -1,4 +1,3 @@
import { describe, it, expect } from 'vitest';
import { reducer } from './reducer';
describe('reducer', () => {

View File

@@ -1,13 +0,0 @@
/** @type {import('tailwindcss').Config} */
export default {
content: ['./**/*.{html,js,jsx,ts,tsx}'],
theme: {
extend: {
container: {
center: true,
padding: '1rem',
},
},
},
plugins: [],
};

View File

@@ -1,6 +1,9 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { css } from 'css-configuration';
export default defineConfig({
plugins: [react()],
css,
});

View File

@@ -4,5 +4,6 @@ import config from './vite.config';
export default mergeConfig(config, {
test: {
environment: 'happy-dom',
globals: true,
},
});