Add examples
This commit is contained in:
33
examples/guess-the-number/game.js
Normal file
33
examples/guess-the-number/game.js
Normal 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.`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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();
|
|
||||||
|
|||||||
@@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
24
examples/yearbook/package.json
Normal file
24
examples/yearbook/package.json
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
||||||
31
examples/yearbook/person.js
Normal file
31
examples/yearbook/person.js
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
9
examples/yearbook/person.test.js
Normal file
9
examples/yearbook/person.test.js
Normal 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
31
package-lock.json
generated
@@ -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",
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
Reference in New Issue
Block a user