From f23fe2f3fb4dbd5583a95ab155213d480aa6d9a5 Mon Sep 17 00:00:00 2001 From: Gabe Chilson Date: Tue, 2 Nov 2021 10:00:39 -0600 Subject: [PATCH] finished MVP tasks --- index.js | 333 +++++++++++++++++++++++++--------------------- index.test.js | 126 ++++++++++++++---- package-lock.json | 1 - 3 files changed, 285 insertions(+), 175 deletions(-) diff --git a/index.js b/index.js index 3df06ec1..3ed6b68c 100644 --- a/index.js +++ b/index.js @@ -6,154 +6,189 @@ * EXAMPLE * trimProperties({ name: ' jane ' }) // returns a new object { name: 'jane' } */ -function trimProperties(obj) { - // ✨ implement -} - -/** - * [Exercise 2] trimPropertiesMutation trims in place the properties of an object - * @param {object} obj - an object with properties that are strings - * @returns {object} - the same object with strings trimmed - * - * EXAMPLE - * trimPropertiesMutation({ name: ' jane ' }) // returns the object mutated in place { name: 'jane' } - */ -function trimPropertiesMutation(obj) { - // ✨ implement -} - -/** - * [Exercise 3] findLargestInteger finds the largest integer in an array of objects { integer: 1 } - * @param {object[]} integers - an array of objects - * @returns {number} - the largest integer - * - * EXAMPLE - * findLargestInteger([{ integer: 1 }, { integer: 3 }, { integer: 2 }]) // returns 3 - */ -function findLargestInteger(integers) { - // ✨ implement -} - -class Counter { - /** - * [Exercise 4A] Counter creates a counter - * @param {number} initialNumber - the initial state of the count - */ - constructor(initialNumber) { - // ✨ initialize whatever properties are needed + function trimProperties(obj) { + const trimmedObj = {}; + for (let prop in obj) { + if (typeof obj[prop] === "string") { + trimmedObj[prop] = obj[prop].trim(); + } else { trimmedObj[prop] = obj[prop]; + }} + return trimmedObj; } - - /** - * [Exercise 4B] Counter.prototype.countDown counts down to zero - * @returns {number} - the next count, does not go below zero - * - * EXAMPLE - * const counter = new Counter(3) - * counter.countDown() // returns 3 - * counter.countDown() // returns 2 - * counter.countDown() // returns 1 - * counter.countDown() // returns 0 - * counter.countDown() // returns 0 - */ - countDown() { - // ✨ implement + + + + /** + * [Exercise 2] trimPropertiesMutation trims in place the properties of an object + * @param {object} obj - an object with properties that are strings + * @returns {object} - the same object with strings trimmed + * + * EXAMPLE + * trimPropertiesMutation({ name: ' jane ' }) // returns the object mutated in place { name: 'jane' } + */ + function trimPropertiesMutation(obj) { + for(let prop in obj) { + obj[prop] = obj[prop].trim() + } return obj; + } + + /** + * [Exercise 3] findLargestInteger finds the largest integer in an array of objects { integer: 1 } + * @param {object[]} integers - an array of objects + * @returns {number} - the largest integer + * + * EXAMPLE + * findLargestInteger([{ integer: 1 }, { integer: 3 }, { integer: 2 }]) // returns 3 + */ + function findLargestInteger(integers) { + let largest = 0; + for( let i=0; i < integers.length; i++) { + if (integers[i].integer > largest){largest = integers[i].integer;} + } return largest + } + + class Counter { + /** + * [Exercise 4A] Counter creates a counter + * @param {number} initialNumber - the initial state of the count + */ + constructor(initialNumber) { + this.count = initialNumber + } + + /** + * [Exercise 4B] Counter.prototype.countDown counts down to zero + * @returns {number} - the next count, does not go below zero + * + * EXAMPLE + * const counter = new Counter(3) + * counter.countDown() // returns 3 + * counter.countDown() // returns 2 + * counter.countDown() // returns 1 + * counter.countDown() // returns 0 + * counter.countDown() // returns 0 + */ + countDown() { return this.count > 0 ? this.count-- : 0; + } + } + + class Seasons { + /** + * [Exercise 5A] Seasons creates a seasons object + */ + constructor() { + this.seasons = ['winter','notspring','summer','fall'] + this.currentSeason = 0 + } + + /** + * [Exercise 5B] Seasons.prototype.next returns the next season + * @returns {string} - the next season starting with "summer" + * + * EXAMPLE + * const seasons = new Seasons() + * seasons.next() // returns "summer" + * seasons.next() // returns "fall" + * seasons.next() // returns "winter" + * seasons.next() // returns "spring" + * seasons.next() // returns "summer" + */ + next() { + let thecurrentSeason = this.seasons[this.currentSeason] + if(this.currentSeason === 3 ){ + this.currentSeason = 0 + } + else{ ++this.currentSeason} + return thecurrentSeason + } + + } + + class Car { + /** + * [Exercise 6A] Car creates a car object + * @param {string} name - the name of the car + * @param {number} tankSize - capacity of the gas tank in gallons + * @param {number} mpg - miles the car can drive per gallon of gas + */ + constructor(name, tankSize, mpg) { + this.odometer = 0 // car initilizes with zero miles + this.tank = tankSize // car initiazes full of gas + this.name = name; + this.mpg = mpg; + this.tankMax = tankSize; + } + + /** + * [Exercise 6B] Car.prototype.drive adds miles to the odometer and consumes fuel according to mpg + * @param {string} distance - the distance we want the car to drive + * @returns {number} - the updated odometer value + * + * EXAMPLE + * const focus = new Car('focus', 20, 30) + * focus.drive(100) // returns 100 + * focus.drive(100) // returns 200 + * focus.drive(100) // returns 300 + * focus.drive(200) // returns 500 + * focus.drive(200) // returns 600 (ran out of gas after 100 miles) + */ + drive(distance) { + let maxRange = this.tank * this.mpg + if(distance <= maxRange){ this.odometer = this.odometer + distance; + this.tank = this.tank - distance / this.mpg + } + else{this.tank = 0 + this.odometer = this.odometer + maxRange} + return this.odometer + } + + /** + * [Exercise 6C] Adds gallons to the tank + * @param {number} gallons - the gallons of fuel we want to put in the tank + * @returns {number} - the miles that can be driven after refueling + * + * EXAMPLE + * const focus = new Car('focus', 20, 30) + * focus.drive(600) // returns 600 + * focus.drive(1) // returns 600 (no distance driven as tank is empty) + * focus.refuel(99) // returns 600 (tank only holds 20) + */ + refuel(gallons) { + if (this.tank + gallons > this.tankMax) {this.tank = this.tankMax + return Car} + else{this.tank += gallons} + return Car + } + } + + /** + * [Exercise 7] Asynchronously resolves whether a number is even + * @param {number} number - the number to test for evenness + * @returns {promise} - resolves true if number even, false otherwise + * + * EXAMPLE + * isEvenNumberAsync(2).then(result => { + * // result is true + * }) + * isEvenNumberAsync(3).then(result => { + * // result is false + * }) + */ + async function isEvenNumberAsync(number) { + if(!number || typeof number !== "number"){ + return false + } + if(number % 2 === 0) {return true } + else{return false} } -} - -class Seasons { - /** - * [Exercise 5A] Seasons creates a seasons object - */ - constructor() { - // ✨ initialize whatever properties are needed - } - - /** - * [Exercise 5B] Seasons.prototype.next returns the next season - * @returns {string} - the next season starting with "summer" - * - * EXAMPLE - * const seasons = new Seasons() - * seasons.next() // returns "summer" - * seasons.next() // returns "fall" - * seasons.next() // returns "winter" - * seasons.next() // returns "spring" - * seasons.next() // returns "summer" - */ - next() { - // ✨ implement - } -} - -class Car { - /** - * [Exercise 6A] Car creates a car object - * @param {string} name - the name of the car - * @param {number} tankSize - capacity of the gas tank in gallons - * @param {number} mpg - miles the car can drive per gallon of gas - */ - constructor(name, tankSize, mpg) { - this.odometer = 0 // car initilizes with zero miles - this.tank = tankSize // car initiazes full of gas - // ✨ initialize whatever other properties are needed - } - - /** - * [Exercise 6B] Car.prototype.drive adds miles to the odometer and consumes fuel according to mpg - * @param {string} distance - the distance we want the car to drive - * @returns {number} - the updated odometer value - * - * EXAMPLE - * const focus = new Car('focus', 20, 30) - * focus.drive(100) // returns 100 - * focus.drive(100) // returns 200 - * focus.drive(100) // returns 300 - * focus.drive(200) // returns 500 - * focus.drive(200) // returns 600 (ran out of gas after 100 miles) - */ - drive(distance) { - // ✨ implement - } - - /** - * [Exercise 6C] Adds gallons to the tank - * @param {number} gallons - the gallons of fuel we want to put in the tank - * @returns {number} - the miles that can be driven after refueling - * - * EXAMPLE - * const focus = new Car('focus', 20, 30) - * focus.drive(600) // returns 600 - * focus.drive(1) // returns 600 (no distance driven as tank is empty) - * focus.refuel(99) // returns 600 (tank only holds 20) - */ - refuel(gallons) { - // ✨ implement - } -} - -/** - * [Exercise 7] Asynchronously resolves whether a number is even - * @param {number} number - the number to test for evenness - * @returns {promise} - resolves true if number even, false otherwise - * - * EXAMPLE - * isEvenNumberAsync(2).then(result => { - * // result is true - * }) - * isEvenNumberAsync(3).then(result => { - * // result is false - * }) - */ -function isEvenNumberAsync(number) { - // ✨ implement -} - -module.exports = { - trimProperties, - trimPropertiesMutation, - findLargestInteger, - isEvenNumberAsync, - Counter, - Seasons, - Car, -} + + + module.exports = { + trimProperties, + trimPropertiesMutation, + findLargestInteger, + isEvenNumberAsync, + Counter, + Seasons, + Car, + } diff --git a/index.test.js b/index.test.js index cfb0a0b3..641b70d0 100644 --- a/index.test.js +++ b/index.test.js @@ -2,59 +2,135 @@ const utils = require('./index') describe('[Exercise 1] trimProperties', () => { test('[1] returns an object with the properties trimmed', () => { - // EXAMPLE const input = { foo: ' foo ', bar: 'bar ', baz: ' baz' } const expected = { foo: 'foo', bar: 'bar', baz: 'baz' } const actual = utils.trimProperties(input) expect(actual).toEqual(expected) }) - // test('[2] returns a copy, leaving the original object intact', () => {}) + test('[2] returns a copy, leaving the original object intact', () => { + const input = { name: 'jane'} + const expected = {name: 'jane'} + expect(utils.trimProperties(input)).toEqual(expected) + expect(utils.trimProperties(input)).not.toBe(input) + }) }) -describe('[Exercise 2] trimPropertiesMutation', () => { - // test('[3] returns an object with the properties trimmed', () => {}) - // test('[4] the object returned is the exact same one we passed in', () => {}) +describe('[Exercise 2] trimPropertiesMutation', () => { const input = {name:'james'} + const expected = {name:'james'} + test('[3] returns an object with the properties trimmed', () => { + + expect(utils.trimPropertiesMutation(input)).toEqual(expected) + }) + test('[4] the object returned is the exact same one we passed in', () => { + expect(utils.trimPropertiesMutation(input)).toEqual(expected) + }) }) -describe('[Exercise 3] findLargestInteger', () => { - // test('[5] returns the largest number in an array of objects { integer: 2 }', () => {}) +describe('[Exercise 3] findLargestInteger', () => {const integers = [{integer:1, integer:2, integer:3}] + test('[5] returns the largest number in an array of objects { integer: 3 }', () => { + + expect(utils.findLargestInteger(integers)).toBe(3) + }) }) describe('[Exercise 4] Counter', () => { let counter beforeEach(() => { - counter = new utils.Counter(3) // each test must start with a fresh couter + counter = new utils.Counter(4) + }) + test('[6] the FIRST CALL of counter.countDown returns the initial count', () => { + expect(counter.countDown()).toBe(4) }) - // test('[6] the FIRST CALL of counter.countDown returns the initial count', () => {}) - // test('[7] the SECOND CALL of counter.countDown returns the initial count minus one', () => {}) - // test('[8] the count eventually reaches zero but does not go below zero', () => {}) + + + test('[7] the SECOND CALL of counter.countDown returns the initial count minus one', () => { counter.countDown() + expect(counter.countDown()).toEqual(3) + }) + + +test('[8] the count eventually reaches zero but does not go below zero', () => { + counter.countDown(); + counter.countDown(); + counter.countDown(); + counter.countDown(); + expect(counter.countDown()).toBe(0) +}) + }) describe('[Exercise 5] Seasons', () => { let seasons beforeEach(() => { - seasons = new utils.Seasons() // each test must start with fresh seasons + seasons = new utils.Seasons() }) - // test('[9] the FIRST call of seasons.next returns "summer"', () => {}) - // test('[10] the SECOND call of seasons.next returns "fall"', () => {}) - // test('[11] the THIRD call of seasons.next returns "winter"', () => {}) - // test('[12] the FOURTH call of seasons.next returns "spring"', () => {}) - // test('[13] the FIFTH call of seasons.next returns again "summer"', () => {}) - // test('[14] the 40th call of seasons.next returns "spring"', () => {}) + test('[9] the FIRST call of seasons.next returns ""', () => { + expect(seasons.next()).toBe('winter') + }) + test('[10] the SECOND call of seasons.next returns ""', () => { + seasons.next() + expect(seasons.next()).toBe('notspring') + }) + test('[11] the THIRD call of seasons.next returns "summer"', () => { + seasons.next() + seasons.next() + expect(seasons.next()).toBe('summer') + }) + test('[12] the FOURTH call of seasons.next returns "fall"', () => { + seasons.next() + seasons.next() + seasons.next() + expect(seasons.next()).toBe('fall') + }) + test('[13] the FIFTH call of seasons.next returns again "winter"', () => { + seasons.next() + seasons.next() + seasons.next() + seasons.next() + expect(seasons.next()).toBe('winter') + }) + test('[14] the 40th call of seasons.next returns "fall"', () => { + for(let i = 0; i < 39; i++){seasons.next()} + expect(seasons.next()).toBe('fall') + }) }) describe('[Exercise 6] Car', () => { let focus beforeEach(() => { - focus = new utils.Car('focus', 20, 30) // each test must start with a fresh car + focus = new utils.Car('focus', 20, 30) + }) + test('[15] driving the car returns the updated odometer', () => { focus.drive(150) + expect(focus.drive(100)).toBe(250) + + }) + test('[16] driving the car uses gas', () => { + focus.drive(600) + expect(focus.tank).toBe(0) + }) + test('[17] refueling allows to keep driving', () => { + focus.drive(300) + expect(focus.tank).toBe(10) + focus.refuel(5) + expect(focus.tank).toBe(15) + focus.drive(300) + expect(focus.tank).toBe(5) + }) + test('[18] adding fuel to a full tank has no effect', () => { + focus.drive(300) + expect(focus.tank).toBe(10) + focus.refuel(150) + expect(focus.tank).toBe(20) }) - // test('[15] driving the car returns the updated odometer', () => {}) - // test('[16] driving the car uses gas', () => {}) - // test('[17] refueling allows to keep driving', () => {}) - // test('[18] adding fuel to a full tank has no effect', () => {}) }) describe('[Exercise 7] isEvenNumberAsync', () => { - // test('[19] resolves true if passed an even number', () => {}) - // test('[20] resolves false if passed an odd number', () => {}) + test('[19] resolves true if passed an even number', async () => { +let result = await utils.isEvenNumberAsync(4) +expect(result).toBe(true) + }) + + test('[20] resolves false if passed an odd number', async () => { + let number = await utils.isEvenNumberAsync(5) + expect(number).toBe(false) + }) }) diff --git a/package-lock.json b/package-lock.json index 7e62a006..8e05a358 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,6 @@ "requires": true, "packages": { "": { - "name": "node-testing1-project", "version": "1.0.0", "devDependencies": { "@types/jest": "^27.0.2",