Initial commit

This commit is contained in:
Steve Kinney
2024-09-13 15:59:51 -06:00
commit a028678660
36 changed files with 5932 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
<section id="calculator" class="calculator">
<input id="display" class="display" type="number" placeholder="0" disabled />
<button id="digit-7" class="number" data-value="7">7</button>
<button id="digit-8" class="number" data-value="8">8</button>
<button id="digit-9" class="number" data-value="9">9</button>
<button id="divide" class="operator">/</button>
<button id="digit-4" class="number" data-value="4">4</button>
<button id="digit-5" class="number" data-value="5">5</button>
<button id="digit-6" class="number" data-value="6">6</button>
<button id="multiply" class="operator">*</button>
<button id="digit-1" class="number" data-value="1">1</button>
<button id="digit-2" class="number" data-value="2">2</button>
<button id="digit-3" class="number" data-value="3">3</button>
<button id="subtract" class="operator">-</button>
<button id="digit-0" class="number" data-value="0">0</button>
<button id="add" class="operator">+</button>
<button id="clear" data-value="C">C</button>
<button id="equals" data-value="=">=</button>
</section>

View File

@@ -0,0 +1,49 @@
import calculator from './calculator.html?raw';
/**
* Renders the calculator component into the target element.
* @param {HTMLElement} target The target element to render the calculator into.
*/
export function renderCalculator(target) {
target.innerHTML = calculator;
let buffer = 0;
/** @type {HTMLInputElement} */
const display = target.querySelector('#display');
/** @type {NodeListOf<HTMLButtonElement>} */
const numbers = target.querySelectorAll('.number');
/** @type {NodeListOf<HTMLButtonElement>} */
const operators = target.querySelectorAll('.operator');
/** @type {HTMLButtonElement} */
const clear = target.querySelector('#clear');
/** @type {HTMLButtonElement} */
const equals = target.querySelector('#equals');
numbers.forEach((number) => {
number.addEventListener('click', () => {
display.value += number.dataset.value;
});
});
operators.forEach((operator) => {
operator.addEventListener('click', () => {
buffer = display.valueAsNumber;
display.value = '';
});
});
clear.addEventListener('click', () => {
buffer = 0;
display.value = '';
});
equals.addEventListener('click', () => {
const result = buffer + display.valueAsNumber;
display.value = String(result);
});
}

View File

@@ -0,0 +1,63 @@
import { beforeEach, describe, expect, it } from 'vitest';
import { fireEvent } from '@testing-library/dom';
import { renderCalculator } from './calculator.js';
it('is running our test in a browser-like environment', () => {
expect(typeof window).not.toBe('undefined');
});
describe('Calculator', () => {
let display;
beforeEach(() => {
renderCalculator(document.body);
display = document.getElementById('display');
});
it('displays number when a number button is clicked', () => {
/** @type {NodeListOf<HTMLButtonElement>} */
const [button] = document.querySelectorAll('button');
const value = button.dataset.value;
fireEvent.click(button);
expect(display.value).toBe(value);
});
it('display the sum of multiple numbers when the equals button is clicked', () => {
const one = document.getElementById('digit-1');
const two = document.getElementById('digit-2');
const three = document.getElementById('digit-3');
fireEvent.click(one);
fireEvent.click(two);
fireEvent.click(three);
expect(display.value).toBe('123');
});
it('supports addings two numbers and displaying the result', () => {
const one = document.getElementById('digit-1');
const two = document.getElementById('digit-2');
const add = document.getElementById('add');
const equals = document.getElementById('equals');
fireEvent.click(one);
fireEvent.click(add);
fireEvent.click(two);
fireEvent.click(equals);
expect(display.value).toBe('3');
});
it('clears the display when the clear button is clicked', () => {
const one = document.getElementById('digit-1');
const clear = document.getElementById('clear');
fireEvent.click(one);
fireEvent.click(clear);
expect(display.value).toBe('');
});
});