Add examples

This commit is contained in:
Steve Kinney
2024-09-24 15:56:02 -06:00
parent 410a6c72ff
commit 61485cc73c
8 changed files with 150 additions and 24 deletions

View File

@@ -0,0 +1,33 @@
export class Game {
/**
* A number guessing game.
* @param {number} minimum - The minimum number to guess.
* @param {number} maximum - The maximum number to guess.
*/
constructor(minimum, maximum) {
this.secretNumber = Math.ceil(Math.random() * maximum - minimum) + minimum;
this.guesses = new Set();
console.log(`Guess the number between ${minimum} and ${maximum}.`);
}
/**
* Make a guess for the secret number.
* @param {number} number - The number to guess.
*/
guess(number) {
if (this.guesses.has(number)) {
return 'You already guessed that number!';
}
this.guesses.add(number);
if (number < this.secretNumber) {
return 'Too low!';
} else if (number > this.secretNumber) {
return 'Too high!';
} else if (number === this.secretNumber) {
return `Correct! You guessed the number in ${this.guesses.size} attempts.`;
}
}
}

View File

@@ -1,38 +1,34 @@
// Import the readline module to handle user input import { Game } from './game.js';
import chalk from 'chalk';
import { createInterface } from 'readline'; import { createInterface } from 'readline';
// Create an interface for reading from stdin (standard input)
const rl = createInterface({ const rl = createInterface({
input: process.stdin, input: process.stdin,
output: process.stdout, output: process.stdout,
}); });
// Generate a random number between 1 and 100 let game = new Game(1, 100);
const randomNumber = Math.floor(Math.random() * 100) + 1;
let attempts = 0;
// Function to handle user's guess function startGame() {
function askQuestion() { rl.question(`Guess ${chalk.cyanBright('→')} `, (answer) => {
rl.question('Guess the number (between 1 and 100): ', (answer) => {
const guess = parseInt(answer, 10); const guess = parseInt(answer, 10);
attempts++;
// Check if the user's guess is correct // Check if the user's guess is correct
if (isNaN(guess)) { if (isNaN(guess)) {
console.log('Please enter a valid number.'); console.log(chalk.red('Please enter a valid number.'));
askQuestion(); // Ask again if input is invalid startGame();
} else if (guess < randomNumber) { }
console.log('Too low!');
askQuestion(); // Ask again const result = game.guess(guess);
} else if (guess > randomNumber) {
console.log('Too high!'); console.log(result);
askQuestion(); // Ask again
if (result.startsWith('Correct')) {
rl.close();
} else { } else {
console.log(`Correct! You guessed the number in ${attempts} attempts.`); startGame();
rl.close(); // End the game
} }
}); });
} }
// Start the game by asking the first question startGame();
askQuestion();

View File

@@ -21,5 +21,8 @@
"@vitest/ui": "^2.1.1", "@vitest/ui": "^2.1.1",
"vite": "^5.4.5", "vite": "^5.4.5",
"vitest": "^2.1.1" "vitest": "^2.1.1"
},
"dependencies": {
"chalk": "^5.3.0"
} }
} }

View File

@@ -0,0 +1,24 @@
{
"name": "yearbook",
"version": "1.0.0",
"main": "index.js",
"type": "module",
"scripts": {
"test": "vitest"
},
"repository": {
"type": "git",
"url": "git+https://github.com/stevekinney/testing-javascript.git"
},
"author": "Steve Kinney <hello@stevekinney.net>",
"license": "MIT",
"bugs": {
"url": "https://github.com/stevekinney/testing-javascript/issues"
},
"homepage": "https://github.com/stevekinney/testing-javascript#readme",
"devDependencies": {
"@vitest/ui": "^2.1.1",
"vite": "^5.4.5",
"vitest": "^2.1.1"
}
}

View File

@@ -0,0 +1,31 @@
export class Person {
/**
* A person in the yearbook.
* @param {string} firstName
* @param {string} lastName
* @param {string} dateOfBirth
*/
constructor(firstName, lastName, dateOfBirth) {
this.firstName = firstName;
this.lastName = lastName;
this.dateOfBirth = dateOfBirth;
}
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
get age() {
const today = new Date();
const birthDate = new Date(this.dateOfBirth);
let age = today.getFullYear() - birthDate.getFullYear();
const month = today.getMonth() - birthDate.getMonth();
if (month < 0 || (month === 0 && today.getDate() < birthDate.getDate())) {
age--;
}
return age;
}
}

View File

@@ -0,0 +1,9 @@
import { describe, expect, it } from 'vitest';
import { Person } from './person';
describe('Person', () => {
it('should be an instance of a Person', () => {
const person = new Person('John', 'Doe', '2000-01-01');
expect(person).toBeInstanceOf(Person);
});
});

31
package-lock.json generated
View File

@@ -18,7 +18,8 @@
"examples/characters", "examples/characters",
"examples/accident-counter", "examples/accident-counter",
"packages/css-configuration", "packages/css-configuration",
"packages/utility-belt" "packages/utility-belt",
"examples/yearbook"
], ],
"devDependencies": { "devDependencies": {
"prettier": "^3.3.3", "prettier": "^3.3.3",
@@ -102,12 +103,27 @@
"examples/guess-the-number": { "examples/guess-the-number": {
"version": "1.0.0", "version": "1.0.0",
"license": "MIT", "license": "MIT",
"dependencies": {
"chalk": "^5.3.0"
},
"devDependencies": { "devDependencies": {
"@vitest/ui": "^2.1.1", "@vitest/ui": "^2.1.1",
"vite": "^5.4.5", "vite": "^5.4.5",
"vitest": "^2.1.1" "vitest": "^2.1.1"
} }
}, },
"examples/guess-the-number/node_modules/chalk": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
"integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
"license": "MIT",
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"examples/task-list": { "examples/task-list": {
"version": "1.0.0", "version": "1.0.0",
"license": "MIT", "license": "MIT",
@@ -153,6 +169,15 @@
"vitest": "^2.1.1" "vitest": "^2.1.1"
} }
}, },
"examples/yearbook": {
"version": "1.0.0",
"license": "MIT",
"devDependencies": {
"@vitest/ui": "^2.1.1",
"vite": "^5.4.5",
"vitest": "^2.1.1"
}
},
"node_modules/@adobe/css-tools": { "node_modules/@adobe/css-tools": {
"version": "4.4.0", "version": "4.4.0",
"resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz", "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.4.0.tgz",
@@ -6609,6 +6634,10 @@
"node": ">=8" "node": ">=8"
} }
}, },
"node_modules/yearbook": {
"resolved": "examples/yearbook",
"link": true
},
"packages/css-configuration": { "packages/css-configuration": {
"version": "1.0.0", "version": "1.0.0",
"license": "MIT", "license": "MIT",

View File

@@ -4,7 +4,7 @@
"description": "A set of examples and exercises for Steve Kinney's \"Introduction to Testing\" course for Frontend Masters.", "description": "A set of examples and exercises for Steve Kinney's \"Introduction to Testing\" course for Frontend Masters.",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"test": "vitest", "test": "echo \"Please run the tests from inside one of the examples!\" && exit 0",
"format": "prettier --write ." "format": "prettier --write ."
}, },
"repository": { "repository": {
@@ -35,7 +35,8 @@
"examples/characters", "examples/characters",
"examples/accident-counter", "examples/accident-counter",
"packages/css-configuration", "packages/css-configuration",
"packages/utility-belt" "packages/utility-belt",
"examples/yearbook"
], ],
"devDependencies": { "devDependencies": {
"prettier": "^3.3.3", "prettier": "^3.3.3",