From c39de4c3a3f2c063d64a62f76baa25e244df9781 Mon Sep 17 00:00:00 2001 From: Nachtmusiks <70234914+Nachtmusiks@users.noreply.github.com> Date: Mon, 28 Aug 2023 16:25:54 -0500 Subject: [PATCH 01/12] Adding test document --- elevator/package.json | 73 ++++++++++++++++++++++++ elevator/platocheck.js | 9 +++ elevator/test/elevator.test.js | 101 +++++++++++++++++++++++++++++++++ elevator/tests.txt | 1 + 4 files changed, 184 insertions(+) create mode 100644 elevator/package.json create mode 100644 elevator/platocheck.js create mode 100644 elevator/test/elevator.test.js create mode 100644 elevator/tests.txt diff --git a/elevator/package.json b/elevator/package.json new file mode 100644 index 0000000..2ed5fbd --- /dev/null +++ b/elevator/package.json @@ -0,0 +1,73 @@ +{ + "name": "elevator.application", + "version": "1.0.0", + "description": "", + "main": "elevator.js", + "scripts": { + "test": "jest --collect-coverage --no-cache", + "lint": "eslint src test", + "plato": "plato -d report -r src", + "start": "node src/elevator" + }, + "author": "", + "license": "ISC", + "eslintConfig": { + "globals": { + "expect": true, + "Wordle": true + }, + "env": { + "browser": true, + "node": true, + "es6": true, + "mocha": true + }, + "extends": "eslint:recommended", + "parserOptions": { + "ecmaVersion": 9, + "sourceType": "module" + }, + "rules": { + "eqeqeq": "error", + "strict": "error", + "no-var": "error", + "no-unused-vars": [ + "off" + ], + "prefer-const": "error", + "no-console": "off", + "indent": [ + "error", + 2 + ], + "quotes": [ + "error", + "single", + "avoid-escape" + ], + "semi": [ + "error", + "always" + ] + } + }, + "jest": { + "coveragePathIgnorePatterns": [ + "/src" + ] + }, + "babel": { + "plugins": [ + "@babel/plugin-transform-modules-commonjs" + ] + }, + "devDependencies": { + "@babel/plugin-transform-modules-commonjs": "^7.21.2", + "eslint": "^8.37.0", + "jest": "^29.5.0", + "plato": "^1.7.0" + }, + "dependencies": { + "directory-import": "^2.3.1" + } +} diff --git a/elevator/platocheck.js b/elevator/platocheck.js new file mode 100644 index 0000000..f666f37 --- /dev/null +++ b/elevator/platocheck.js @@ -0,0 +1,9 @@ +require(`${process.cwd()}/report/report`); + +const maintainability = __report.summary.total.maintainability; + +if(maintainability < 70) { + console.log(`Plato reported total maintainability as ${maintainability}`); +} + +process.exitCode = maintainability >= 70 ? 0 : 1; diff --git a/elevator/test/elevator.test.js b/elevator/test/elevator.test.js new file mode 100644 index 0000000..7641c61 --- /dev/null +++ b/elevator/test/elevator.test.js @@ -0,0 +1,101 @@ +import { getLowestPrice } from '../src/price.finder.js'; + +test('canary', () => { + expect(true).toBe(true); +}); + +test('getLowestPrice when no vendors are available', () => { + expect(() => getLowestPrice(1, [])).toThrow('No vendors available'); +}); + +test('getLowestPrice when number of days is negative', () => { + expect(() => getLowestPrice(-1)).toThrow('Number of days must be positive'); +}); + +test('getLowestPrice for one day when one vendor is available', () => { + const vendor1PriceFinder = () => ({vendorName: 'Vendor1', price: 100}); + + expect(getLowestPrice(1, [vendor1PriceFinder])).toStrictEqual({vendorNames: ['Vendor1'], dailyPrice: 100, totalPrice: 100}); +}); + +test('getLowestPrice for three days when one vendor is available', () => { + const vendor1PriceFinder = () => ({vendorName: 'Vendor1', price: 100}); + + expect(getLowestPrice(3, [vendor1PriceFinder])).toStrictEqual({vendorNames: ['Vendor1'], dailyPrice: 100, totalPrice: 300}); +}); + +test('getLowestPrice for one day when two vendors are available, first with better price', () => { + const vendor1PriceFinder = () => ({vendorName: 'Vendor1', price: 50}); + + const vendor2PriceFinder = () => ({vendorName: 'Vendor2', price: 100}); + + expect(getLowestPrice(1, [vendor1PriceFinder, vendor2PriceFinder])).toStrictEqual({vendorNames: ['Vendor1'], dailyPrice: 50, totalPrice: 50}); +}); + +test('getLowestPrice for one day when two vendors are available, second with better price', () => { + const vendor1PriceFinder = () => ({vendorName: 'Vendor1', price: 50}); + + const vendor2PriceFinder = () => ({vendorName: 'Vendor2', price: 25}); + + expect(getLowestPrice(1, [vendor1PriceFinder, vendor2PriceFinder])).toStrictEqual({vendorNames: ['Vendor2'], dailyPrice: 25, totalPrice: 25}); +}); + +test('getLowestPrice for one day when three vendors are available, first with better price', () => { + const vendor1PriceFinder = () => ({vendorName: 'Vendor1', price: 25}); + + const vendor2PriceFinder = () => ({vendorName: 'Vendor2', price: 40}); + + const vendor3PriceFinder = () => ({vendorName: 'Vendor3', price: 30}); + + expect(getLowestPrice(1, [vendor1PriceFinder, vendor2PriceFinder, vendor3PriceFinder])).toStrictEqual({vendorNames: ['Vendor1'], dailyPrice: 25, totalPrice: 25}); +}); + +test('getLowestPrice for one day when three vendors are available, second with better price', () => { + const vendor1PriceFinder = () => ({vendorName: 'Vendor1', price: 50}); + + const vendor2PriceFinder = () => ({vendorName: 'Vendor2', price: 25}); + + const vendor3PriceFinder = () => ({vendorName: 'Vendor3', price: 30}); + + expect(getLowestPrice(1, [vendor1PriceFinder, vendor2PriceFinder, vendor3PriceFinder])).toStrictEqual({vendorNames: ['Vendor2'], dailyPrice: 25, totalPrice: 25}); +}); + +test('getLowestPrice for one day when three vendors are available, third with better price', () => { + const vendor1PriceFinder = () => ({vendorName: 'Vendor1', price: 50}); + + const vendor2PriceFinder = () => ({vendorName: 'Vendor2', price: 30}); + + const vendor3PriceFinder = () => ({vendorName: 'Vendor3', price: 25}); + + expect(getLowestPrice(1, [vendor1PriceFinder, vendor2PriceFinder, vendor3PriceFinder])).toStrictEqual({vendorNames: ['Vendor3'], dailyPrice: 25, totalPrice: 25}); +}); + +test('getLowestPrice for one day when three vendors are available, first one fails request, second has better price', () => { + const vendor1PriceFinder = () => {throw new Error('Vendor1 is not available');}; + + const vendor2PriceFinder = () => ({vendorName: 'Vendor2', price: 25}); + + const vendor3PriceFinder = () => ({vendorName: 'Vendor3', price: 30}); + + expect(getLowestPrice(1, [vendor1PriceFinder, vendor2PriceFinder, vendor3PriceFinder])).toStrictEqual({vendorNames: ['Vendor2'], dailyPrice: 25, totalPrice: 25}); +}); + +test('getLowestPrice for one day when three vendors are available, all vendors failed to request', () => { + const vendor1PriceFinder = () => {throw new Error('Vendor1 is not available');}; + + const vendor2PriceFinder = () => {throw new Error('Vendor2 is not available');}; + + const vendor3PriceFinder = () => {throw new Error('Vendor3 is not available');}; + + expect(() => getLowestPrice(1, [vendor1PriceFinder, vendor2PriceFinder, vendor3PriceFinder])).toThrow('No vendors available'); +}); + +test('getLowestPrice for one day when three vendors are available, the first and the third have the same lower price than the second', () => { + const vendor1PriceFinder = () => ({vendorName: 'Vendor1', price: 25}); + + const vendor2PriceFinder = () => ({vendorName: 'Vendor2', price: 30}); + + const vendor3PriceFinder = () => ({vendorName: 'Vendor3', price: 25}); + + expect(getLowestPrice(1, [vendor1PriceFinder, vendor2PriceFinder, vendor3PriceFinder])).toStrictEqual({vendorNames: ['Vendor1', 'Vendor3'], dailyPrice: 25, totalPrice: 25}); +}); \ No newline at end of file diff --git a/elevator/tests.txt b/elevator/tests.txt new file mode 100644 index 0000000..c8a473f --- /dev/null +++ b/elevator/tests.txt @@ -0,0 +1 @@ +xcanary test From a3b2b5bf5092feafb0403918f48fa82f770ec779 Mon Sep 17 00:00:00 2001 From: Nachtmusiks <70234914+Nachtmusiks@users.noreply.github.com> Date: Mon, 28 Aug 2023 16:29:46 -0500 Subject: [PATCH 02/12] updating test --- elevator/test/elevator.test.js | 98 ---------------------------------- 1 file changed, 98 deletions(-) diff --git a/elevator/test/elevator.test.js b/elevator/test/elevator.test.js index 7641c61..9e27101 100644 --- a/elevator/test/elevator.test.js +++ b/elevator/test/elevator.test.js @@ -1,101 +1,3 @@ -import { getLowestPrice } from '../src/price.finder.js'; - test('canary', () => { expect(true).toBe(true); }); - -test('getLowestPrice when no vendors are available', () => { - expect(() => getLowestPrice(1, [])).toThrow('No vendors available'); -}); - -test('getLowestPrice when number of days is negative', () => { - expect(() => getLowestPrice(-1)).toThrow('Number of days must be positive'); -}); - -test('getLowestPrice for one day when one vendor is available', () => { - const vendor1PriceFinder = () => ({vendorName: 'Vendor1', price: 100}); - - expect(getLowestPrice(1, [vendor1PriceFinder])).toStrictEqual({vendorNames: ['Vendor1'], dailyPrice: 100, totalPrice: 100}); -}); - -test('getLowestPrice for three days when one vendor is available', () => { - const vendor1PriceFinder = () => ({vendorName: 'Vendor1', price: 100}); - - expect(getLowestPrice(3, [vendor1PriceFinder])).toStrictEqual({vendorNames: ['Vendor1'], dailyPrice: 100, totalPrice: 300}); -}); - -test('getLowestPrice for one day when two vendors are available, first with better price', () => { - const vendor1PriceFinder = () => ({vendorName: 'Vendor1', price: 50}); - - const vendor2PriceFinder = () => ({vendorName: 'Vendor2', price: 100}); - - expect(getLowestPrice(1, [vendor1PriceFinder, vendor2PriceFinder])).toStrictEqual({vendorNames: ['Vendor1'], dailyPrice: 50, totalPrice: 50}); -}); - -test('getLowestPrice for one day when two vendors are available, second with better price', () => { - const vendor1PriceFinder = () => ({vendorName: 'Vendor1', price: 50}); - - const vendor2PriceFinder = () => ({vendorName: 'Vendor2', price: 25}); - - expect(getLowestPrice(1, [vendor1PriceFinder, vendor2PriceFinder])).toStrictEqual({vendorNames: ['Vendor2'], dailyPrice: 25, totalPrice: 25}); -}); - -test('getLowestPrice for one day when three vendors are available, first with better price', () => { - const vendor1PriceFinder = () => ({vendorName: 'Vendor1', price: 25}); - - const vendor2PriceFinder = () => ({vendorName: 'Vendor2', price: 40}); - - const vendor3PriceFinder = () => ({vendorName: 'Vendor3', price: 30}); - - expect(getLowestPrice(1, [vendor1PriceFinder, vendor2PriceFinder, vendor3PriceFinder])).toStrictEqual({vendorNames: ['Vendor1'], dailyPrice: 25, totalPrice: 25}); -}); - -test('getLowestPrice for one day when three vendors are available, second with better price', () => { - const vendor1PriceFinder = () => ({vendorName: 'Vendor1', price: 50}); - - const vendor2PriceFinder = () => ({vendorName: 'Vendor2', price: 25}); - - const vendor3PriceFinder = () => ({vendorName: 'Vendor3', price: 30}); - - expect(getLowestPrice(1, [vendor1PriceFinder, vendor2PriceFinder, vendor3PriceFinder])).toStrictEqual({vendorNames: ['Vendor2'], dailyPrice: 25, totalPrice: 25}); -}); - -test('getLowestPrice for one day when three vendors are available, third with better price', () => { - const vendor1PriceFinder = () => ({vendorName: 'Vendor1', price: 50}); - - const vendor2PriceFinder = () => ({vendorName: 'Vendor2', price: 30}); - - const vendor3PriceFinder = () => ({vendorName: 'Vendor3', price: 25}); - - expect(getLowestPrice(1, [vendor1PriceFinder, vendor2PriceFinder, vendor3PriceFinder])).toStrictEqual({vendorNames: ['Vendor3'], dailyPrice: 25, totalPrice: 25}); -}); - -test('getLowestPrice for one day when three vendors are available, first one fails request, second has better price', () => { - const vendor1PriceFinder = () => {throw new Error('Vendor1 is not available');}; - - const vendor2PriceFinder = () => ({vendorName: 'Vendor2', price: 25}); - - const vendor3PriceFinder = () => ({vendorName: 'Vendor3', price: 30}); - - expect(getLowestPrice(1, [vendor1PriceFinder, vendor2PriceFinder, vendor3PriceFinder])).toStrictEqual({vendorNames: ['Vendor2'], dailyPrice: 25, totalPrice: 25}); -}); - -test('getLowestPrice for one day when three vendors are available, all vendors failed to request', () => { - const vendor1PriceFinder = () => {throw new Error('Vendor1 is not available');}; - - const vendor2PriceFinder = () => {throw new Error('Vendor2 is not available');}; - - const vendor3PriceFinder = () => {throw new Error('Vendor3 is not available');}; - - expect(() => getLowestPrice(1, [vendor1PriceFinder, vendor2PriceFinder, vendor3PriceFinder])).toThrow('No vendors available'); -}); - -test('getLowestPrice for one day when three vendors are available, the first and the third have the same lower price than the second', () => { - const vendor1PriceFinder = () => ({vendorName: 'Vendor1', price: 25}); - - const vendor2PriceFinder = () => ({vendorName: 'Vendor2', price: 30}); - - const vendor3PriceFinder = () => ({vendorName: 'Vendor3', price: 25}); - - expect(getLowestPrice(1, [vendor1PriceFinder, vendor2PriceFinder, vendor3PriceFinder])).toStrictEqual({vendorNames: ['Vendor1', 'Vendor3'], dailyPrice: 25, totalPrice: 25}); -}); \ No newline at end of file From 2dcccd5569fc1b9d97982cc21dfb2fe870169c18 Mon Sep 17 00:00:00 2001 From: Nachtmusiks <70234914+Nachtmusiks@users.noreply.github.com> Date: Mon, 28 Aug 2023 17:57:22 -0500 Subject: [PATCH 03/12] Setting up the project --- .gitignore | 12 ++++++++++++ elevator/package.json | 4 ++-- elevator/src/elevator.request.js | 0 elevator/src/elevator.service.js | 1 + .../{elevator.test.js => elevator.request.test.js} | 0 5 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 elevator/src/elevator.request.js create mode 100644 elevator/src/elevator.service.js rename elevator/test/{elevator.test.js => elevator.request.test.js} (100%) diff --git a/.gitignore b/.gitignore index 3e759b7..a952c17 100644 --- a/.gitignore +++ b/.gitignore @@ -328,3 +328,15 @@ ASALocalRun/ # MFractors (Xamarin productivity tool) working folder .mfractor/ +elevator/coverage/clover.xml +elevator/coverage/coverage-final.json +elevator/coverage/lcov.info +elevator/coverage/lcov-report/base.css +elevator/coverage/lcov-report/block-navigation.js +elevator/coverage/lcov-report/favicon.png +elevator/coverage/lcov-report/index.html +elevator/coverage/lcov-report/prettify.css +elevator/coverage/lcov-report/prettify.js +elevator/coverage/lcov-report/sort-arrow-sprite.png +elevator/coverage/lcov-report/sorter.js +elevator/package-lock.json diff --git a/elevator/package.json b/elevator/package.json index 2ed5fbd..c98b4b3 100644 --- a/elevator/package.json +++ b/elevator/package.json @@ -2,12 +2,12 @@ "name": "elevator.application", "version": "1.0.0", "description": "", - "main": "elevator.js", + "main": "elevator.service.js", "scripts": { "test": "jest --collect-coverage --no-cache", "lint": "eslint src test", "plato": "plato -d report -r src", - "start": "node src/elevator" + "start": "node src/elevator.service" }, "author": "", "license": "ISC", diff --git a/elevator/src/elevator.request.js b/elevator/src/elevator.request.js new file mode 100644 index 0000000..e69de29 diff --git a/elevator/src/elevator.service.js b/elevator/src/elevator.service.js new file mode 100644 index 0000000..ae37063 --- /dev/null +++ b/elevator/src/elevator.service.js @@ -0,0 +1 @@ +//This is the main file to run the elevator service and it will act as the interface \ No newline at end of file diff --git a/elevator/test/elevator.test.js b/elevator/test/elevator.request.test.js similarity index 100% rename from elevator/test/elevator.test.js rename to elevator/test/elevator.request.test.js From ea2eb0463b40eae3ce80610982b36c9ce752f6dc Mon Sep 17 00:00:00 2001 From: Nachtmusiks <70234914+Nachtmusiks@users.noreply.github.com> Date: Mon, 28 Aug 2023 22:04:28 -0500 Subject: [PATCH 04/12] Modifying to follow SLAP and SRP rules --- elevator/src/elevator.log.js | 0 elevator/src/elevator.request.js | 30 ++++++++++++++++++++++++++ elevator/test/elevator.request.test.js | 14 ++++++++++++ elevator/tests.txt | 8 ++++++- 4 files changed, 51 insertions(+), 1 deletion(-) create mode 100644 elevator/src/elevator.log.js diff --git a/elevator/src/elevator.log.js b/elevator/src/elevator.log.js new file mode 100644 index 0000000..e69de29 diff --git a/elevator/src/elevator.request.js b/elevator/src/elevator.request.js index e69de29..3a4a7f5 100644 --- a/elevator/src/elevator.request.js +++ b/elevator/src/elevator.request.js @@ -0,0 +1,30 @@ +const maxFloor = 10; +const minFloor = 1; +const maxWeight = 1000; + +const elevatorSensor = { + currentFloor: 1, + nextFloor: 2, + direction: 'up', + isMoving: false, + weightLimit: false, +} + +function validateFloor(floorNum) { + if (floorNum > maxFloor || floorNum < minFloor || floorNum === elevatorSensor.currentFloor) { + throw new Error('Invalid floor number'); + } + return floorNum; +} + +function insideElevatorRequest(floorNum) { + validateFloor(floorNum); //SLAP +} +//5U for example will be parsed as 5 and U in elevator.service.js first +function outsideElevatorRequest(floorNum, direction) { + //Validate floor only after we check the next floor number + validateFloor(floorNum); +} + +module.exports.validateFloor = validateFloor; + diff --git a/elevator/test/elevator.request.test.js b/elevator/test/elevator.request.test.js index 9e27101..6a4e894 100644 --- a/elevator/test/elevator.request.test.js +++ b/elevator/test/elevator.request.test.js @@ -1,3 +1,17 @@ +import { validateFloor } from '../src/elevator.request.js'; + test('canary', () => { expect(true).toBe(true); }); + +test('validateFloor request returns floor number', () => { + expect(validateFloor(5)).toBe(5); +}); + +test('validateFloor request throws error going past max floor', () => { + expect(() => validateFloor(11)).toThrow('Invalid floor number'); +}); + +test('validateFloor request throws error going past min floor', () => { + expect(() => validateFloor(0)).toThrow('Invalid floor number'); +}); diff --git a/elevator/tests.txt b/elevator/tests.txt index c8a473f..599c925 100644 --- a/elevator/tests.txt +++ b/elevator/tests.txt @@ -1 +1,7 @@ -xcanary test +x canary test +x validateFloor request to 5th floor return position at 5 +x validateFloor request past max floor throw error +x validateFloor request past min floor throw error +-inside elevator travel request on existing floor throw error + +-outside elevator request \ No newline at end of file From e2d6d7f75500ab4ba9d2b332b4b31df178406c1d Mon Sep 17 00:00:00 2001 From: Nachtmusiks <70234914+Nachtmusiks@users.noreply.github.com> Date: Tue, 29 Aug 2023 01:19:18 -0500 Subject: [PATCH 05/12] Created function elevatorTimer and added new tests --- .gitignore | 2 ++ elevator/src/elevator.request.js | 25 +++++++++++++++++++------ elevator/test/elevator.request.test.js | 26 +++++++++++++++++++++++++- elevator/tests.txt | 5 ++++- 4 files changed, 50 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index a952c17..0a3e8ee 100644 --- a/.gitignore +++ b/.gitignore @@ -340,3 +340,5 @@ elevator/coverage/lcov-report/prettify.js elevator/coverage/lcov-report/sort-arrow-sprite.png elevator/coverage/lcov-report/sorter.js elevator/package-lock.json +elevator/.vscode/launch.json +elevator/elevator.code-workspace diff --git a/elevator/src/elevator.request.js b/elevator/src/elevator.request.js index 3a4a7f5..c4467e3 100644 --- a/elevator/src/elevator.request.js +++ b/elevator/src/elevator.request.js @@ -4,22 +4,35 @@ const maxWeight = 1000; const elevatorSensor = { currentFloor: 1, - nextFloor: 2, - direction: 'up', + nextFloor: 1, + direction: '', isMoving: false, weightLimit: false, } -function validateFloor(floorNum) { +function validateFloor(floorNum) { //SLAP if (floorNum > maxFloor || floorNum < minFloor || floorNum === elevatorSensor.currentFloor) { throw new Error('Invalid floor number'); } return floorNum; } -function insideElevatorRequest(floorNum) { - validateFloor(floorNum); //SLAP +function elevatorTimer(time) { + return new Promise((resolve) => { + setTimeout(() => { + resolve('resolving'); + }, time); + }); } + +async function insideElevatorRequest(floorNum) { + floorNum = validateFloor(floorNum); + + elevatorSensor.nextFloor = floorNum; + + return elevatorSensor; +} + //5U for example will be parsed as 5 and U in elevator.service.js first function outsideElevatorRequest(floorNum, direction) { //Validate floor only after we check the next floor number @@ -27,4 +40,4 @@ function outsideElevatorRequest(floorNum, direction) { } module.exports.validateFloor = validateFloor; - +module.exports.elevatorTimer = elevatorTimer; diff --git a/elevator/test/elevator.request.test.js b/elevator/test/elevator.request.test.js index 6a4e894..d86015c 100644 --- a/elevator/test/elevator.request.test.js +++ b/elevator/test/elevator.request.test.js @@ -1,4 +1,4 @@ -import { validateFloor } from '../src/elevator.request.js'; +import { validateFloor, elevatorTimer } from '../src/elevator.request.js'; test('canary', () => { expect(true).toBe(true); @@ -15,3 +15,27 @@ test('validateFloor request throws error going past max floor', () => { test('validateFloor request throws error going past min floor', () => { expect(() => validateFloor(0)).toThrow('Invalid floor number'); }); + +test('elevatorTimer given 10ms await 10ms', async () => { + const startTime = Date.now(); + + await elevatorTimer(10); + + const endTime = Date.now(); + + const elapsedSeconds = (endTime - startTime) / 1000; + + expect(elapsedSeconds).toBeCloseTo(.01, 1); +}); + +test('elevatorTimer given 100ms await 100ms', async () => { + const startTime = Date.now(); + + await elevatorTimer(100); + + const endTime = Date.now(); + + const elapsedSeconds = (endTime - startTime) / 1000; + + expect(elapsedSeconds).toBeCloseTo(.1, 1); +}); \ No newline at end of file diff --git a/elevator/tests.txt b/elevator/tests.txt index 599c925..abf7d83 100644 --- a/elevator/tests.txt +++ b/elevator/tests.txt @@ -2,6 +2,9 @@ x canary test x validateFloor request to 5th floor return position at 5 x validateFloor request past max floor throw error x validateFloor request past min floor throw error --inside elevator travel request on existing floor throw error +- inside elevator travel request on existing floor throw error + +x elevatorTimer given 10ms await 10ms +x elevatorTimer given 100ms await 100ms -outside elevator request \ No newline at end of file From 8ae2fe99faef3b02c51439546ff0b6faddf2325a Mon Sep 17 00:00:00 2001 From: Nachtmusiks <70234914+Nachtmusiks@users.noreply.github.com> Date: Tue, 29 Aug 2023 22:08:03 -0500 Subject: [PATCH 06/12] Successfully implemented elevator service, needs further refactorization and testing. --- elevator/src/elevator.request.js | 90 +++++++++++++++++++++++++++++++- elevator/src/elevator.service.js | 3 +- elevator/tests.txt | 3 +- 3 files changed, 92 insertions(+), 4 deletions(-) diff --git a/elevator/src/elevator.request.js b/elevator/src/elevator.request.js index c4467e3..5525149 100644 --- a/elevator/src/elevator.request.js +++ b/elevator/src/elevator.request.js @@ -5,6 +5,7 @@ const maxWeight = 1000; const elevatorSensor = { currentFloor: 1, nextFloor: 1, + requestedFloor: [], direction: '', isMoving: false, weightLimit: false, @@ -25,19 +26,104 @@ function elevatorTimer(time) { }); } +async function elevatorTravel() { + + while (elevatorSensor.requestedFloor.length > 0) { + if (elevatorSensor.currentFloor < elevatorSensor.nextFloor) { + elevatorSensor.direction = 'U'; + } + + else { + elevatorSensor.direction = 'D'; + } + + elevatorSensor.isMoving = true; + + while (elevatorSensor.nextFloor != elevatorSensor.currentFloor) { + elevatorSensor.nextFloor = getNextPickup(); + + if (elevatorSensor.direction === 'U') { + elevatorSensor.currentFloor++; + } + + else { + elevatorSensor.currentFloor--; + } + + await elevatorTimer(300); + } + + elevatorSensor.isMoving = false; + + await elevatorTimer(100); + + elevatorSensor.requestedFloor.splice(elevatorSensor.requestedFloor.indexOf(elevatorSensor.currentFloor), 1); + + elevatorSensor.nextFloor = getNextPickup(); + } + +} + +function getNextPickup() { + if (elevatorSensor.requestedFloor.length === 0) { + return null; + } + + // Filter floors that match the current direction + const floorsInDirection = elevatorSensor.requestedFloor.filter(floor => { + if (elevatorSensor.direction === 'U') { + return floor > elevatorSensor.currentFloor; + } + + else { + return floor < elevatorSensor.currentFloor; + } + }); + + // If no matching floors, consider all floors in pickupQueue + const floorsToConsider = floorsInDirection.length > 0 ? floorsInDirection : elevatorSensor.requestedFloor; + + // Prioritize floors based on distance + const distances = floorsToConsider.map(floor => Math.abs(floor - elevatorSensor.currentFloor)); + const sortedFloors = floorsToConsider.slice().sort((a, b) => distances[floorsToConsider.indexOf(a)] - distances[floorsToConsider.indexOf(b)]); + + elevatorSensor.nextFloor = sortedFloors[0]; + + return sortedFloors[0]; +} + async function insideElevatorRequest(floorNum) { floorNum = validateFloor(floorNum); + //Timestamp here + if (elevatorSensor.requestedFloor.length === 0) { + elevatorSensor.nextFloor = floorNum; + } + elevatorSensor.requestedFloor.push(floorNum); - elevatorSensor.nextFloor = floorNum; + await (elevatorTravel()); return elevatorSensor; } //5U for example will be parsed as 5 and U in elevator.service.js first -function outsideElevatorRequest(floorNum, direction) { +async function outsideElevatorRequest(floorNum, direction) { + //Validate floor only after we check the next floor number validateFloor(floorNum); + + //Timestamp here + + if (elevatorSensor.requestedFloor.length === 0) { + elevatorSensor.nextFloor = floorNum; + } + + elevatorSensor.requestedFloor.push(floorNum); } module.exports.validateFloor = validateFloor; module.exports.elevatorTimer = elevatorTimer; + +insideElevatorRequest(6); +outsideElevatorRequest(3); +insideElevatorRequest(7); +outsideElevatorRequest(2); \ No newline at end of file diff --git a/elevator/src/elevator.service.js b/elevator/src/elevator.service.js index ae37063..0603661 100644 --- a/elevator/src/elevator.service.js +++ b/elevator/src/elevator.service.js @@ -1 +1,2 @@ -//This is the main file to run the elevator service and it will act as the interface \ No newline at end of file +//This is the main file to run the elevator service and it will act as the interface +//Work the 'Q' logic here \ No newline at end of file diff --git a/elevator/tests.txt b/elevator/tests.txt index abf7d83..2c2216c 100644 --- a/elevator/tests.txt +++ b/elevator/tests.txt @@ -7,4 +7,5 @@ x validateFloor request past min floor throw error x elevatorTimer given 10ms await 10ms x elevatorTimer given 100ms await 100ms --outside elevator request \ No newline at end of file +- elevator travel 3 floors up log correct output +- elevator travel 1 floor up and 2 floor down log correct output From a326b91025f5050e127e66c0af86304f3d6dc0af Mon Sep 17 00:00:00 2001 From: Nachtmusiks <70234914+Nachtmusiks@users.noreply.github.com> Date: Wed, 30 Aug 2023 02:40:31 -0500 Subject: [PATCH 07/12] Refactored elevator.request and add new functions to elevator.log.js --- elevator/elevator.log.json | 7 +++++ elevator/src/elevator.log.js | 25 +++++++++++++++ elevator/src/elevator.request.js | 50 +++++++++++++++++------------- elevator/test/elevator.log.test.js | 5 +++ elevator/tests.txt | 3 +- 5 files changed, 68 insertions(+), 22 deletions(-) create mode 100644 elevator/elevator.log.json create mode 100644 elevator/test/elevator.log.test.js diff --git a/elevator/elevator.log.json b/elevator/elevator.log.json new file mode 100644 index 0000000..3674b45 --- /dev/null +++ b/elevator/elevator.log.json @@ -0,0 +1,7 @@ +[ + { + "timestamp": "2:35:17 AM", + "event": "inside request", + "floorNum": 5 + } +] \ No newline at end of file diff --git a/elevator/src/elevator.log.js b/elevator/src/elevator.log.js index e69de29..b0c1cfa 100644 --- a/elevator/src/elevator.log.js +++ b/elevator/src/elevator.log.js @@ -0,0 +1,25 @@ +import fs from 'fs'; + +const elevatorLogs = []; + +const typeOfEvent = { + INSIDE: 'inside request', + OUTSIDE: 'outside request', + MOVE: 'move', + STOP: 'stop', +} + +function logEvent(event, floorNum) { + const timestamp = new Date().toLocaleTimeString(); + elevatorLogs.push({timestamp, event, floorNum }); + return elevatorLogs; +} + +function writeLog() { + const log = JSON.stringify(elevatorLogs, null, 2); + fs.writeFileSync('./elevator.log.json', log); +} + +module.exports.typeOfEvent = typeOfEvent; +module.exports.writeLog = writeLog; +module.exports.logEvent = logEvent; \ No newline at end of file diff --git a/elevator/src/elevator.request.js b/elevator/src/elevator.request.js index 5525149..183ac80 100644 --- a/elevator/src/elevator.request.js +++ b/elevator/src/elevator.request.js @@ -1,5 +1,9 @@ -const maxFloor = 10; -const minFloor = 1; +import { logEvent, typeOfEvent } from './elevator.log.js'; + +const MAX_FLOOR = 10; +const MIN_FLOOR = 1; +const MOVE_DELAY = 300; +const STOP_DELAY = 100; const maxWeight = 1000; const elevatorSensor = { @@ -11,23 +15,20 @@ const elevatorSensor = { weightLimit: false, } -function validateFloor(floorNum) { //SLAP - if (floorNum > maxFloor || floorNum < minFloor || floorNum === elevatorSensor.currentFloor) { +function validateFloor(floorNum) { + if (floorNum > MAX_FLOOR || floorNum < MIN_FLOOR) { throw new Error('Invalid floor number'); } return floorNum; } -function elevatorTimer(time) { +async function elevatorTimer(time) { return new Promise((resolve) => { - setTimeout(() => { - resolve('resolving'); - }, time); + setTimeout(resolve, time); }); } -async function elevatorTravel() { - +async function handleRequests() { while (elevatorSensor.requestedFloor.length > 0) { if (elevatorSensor.currentFloor < elevatorSensor.nextFloor) { elevatorSensor.direction = 'U'; @@ -50,12 +51,12 @@ async function elevatorTravel() { elevatorSensor.currentFloor--; } - await elevatorTimer(300); + await elevatorTimer(MOVE_DELAY); } elevatorSensor.isMoving = false; - await elevatorTimer(100); + await elevatorTimer(STOP_DELAY); elevatorSensor.requestedFloor.splice(elevatorSensor.requestedFloor.indexOf(elevatorSensor.currentFloor), 1); @@ -64,6 +65,9 @@ async function elevatorTravel() { } +function resetElevatorPosition() { + +} function getNextPickup() { if (elevatorSensor.requestedFloor.length === 0) { return null; @@ -80,11 +84,10 @@ function getNextPickup() { } }); - // If no matching floors, consider all floors in pickupQueue const floorsToConsider = floorsInDirection.length > 0 ? floorsInDirection : elevatorSensor.requestedFloor; - // Prioritize floors based on distance const distances = floorsToConsider.map(floor => Math.abs(floor - elevatorSensor.currentFloor)); + const sortedFloors = floorsToConsider.slice().sort((a, b) => distances[floorsToConsider.indexOf(a)] - distances[floorsToConsider.indexOf(b)]); elevatorSensor.nextFloor = sortedFloors[0]; @@ -100,15 +103,13 @@ async function insideElevatorRequest(floorNum) { } elevatorSensor.requestedFloor.push(floorNum); - await (elevatorTravel()); + await (handleRequests()); return elevatorSensor; } -//5U for example will be parsed as 5 and U in elevator.service.js first -async function outsideElevatorRequest(floorNum, direction) { +async function outsideElevatorRequest(floorNum) { - //Validate floor only after we check the next floor number validateFloor(floorNum); //Timestamp here @@ -117,13 +118,20 @@ async function outsideElevatorRequest(floorNum, direction) { elevatorSensor.nextFloor = floorNum; } - elevatorSensor.requestedFloor.push(floorNum); + if (elevatorSensor.isMoving && Math.abs(floorNum - elevatorSensor.currentFloor) >= 1 || !elevatorSensor.isMoving) { + elevatorSensor.requestedFloor.push(floorNum); + } + + else { + elevatorTimer(MOVE_DELAY); + elevatorSensor.requestedFloor.push(floorNum); + } } module.exports.validateFloor = validateFloor; module.exports.elevatorTimer = elevatorTimer; insideElevatorRequest(6); -outsideElevatorRequest(3); -insideElevatorRequest(7); +outsideElevatorRequest(1); +//insideElevatorRequest(7); outsideElevatorRequest(2); \ No newline at end of file diff --git a/elevator/test/elevator.log.test.js b/elevator/test/elevator.log.test.js new file mode 100644 index 0000000..bfcd8cd --- /dev/null +++ b/elevator/test/elevator.log.test.js @@ -0,0 +1,5 @@ +import { logEvent, writeLog, typeOfEvent } from '../src/elevator.log.js'; + +test('Log event when elevator stopped', () => { + +}); \ No newline at end of file diff --git a/elevator/tests.txt b/elevator/tests.txt index 2c2216c..c27adb7 100644 --- a/elevator/tests.txt +++ b/elevator/tests.txt @@ -6,6 +6,7 @@ x validateFloor request past min floor throw error x elevatorTimer given 10ms await 10ms x elevatorTimer given 100ms await 100ms - +- logEvent successfully record an accurate event +- writeLog successfully output a file - elevator travel 3 floors up log correct output - elevator travel 1 floor up and 2 floor down log correct output From c7b668197a80e14c300faf5ea3f373aa6a2d6273 Mon Sep 17 00:00:00 2001 From: Nachtmusiks <70234914+Nachtmusiks@users.noreply.github.com> Date: Sat, 2 Sep 2023 00:00:30 -0500 Subject: [PATCH 08/12] Completed the program --- elevator/.vscode/settings.json | 3 + elevator/elevator.log.json | 26 +++++++- elevator/package.json | 2 +- elevator/src/elevator.log.js | 27 ++++++-- elevator/src/elevator.request.js | 88 +++++++++++++++++--------- elevator/src/elevator.service.js | 55 +++++++++++++++- elevator/test/elevator.log.test.js | 17 ++++- elevator/test/elevator.request.test.js | 67 +++++++++++++++++++- elevator/tests.txt | 15 +++-- 9 files changed, 247 insertions(+), 53 deletions(-) create mode 100644 elevator/.vscode/settings.json diff --git a/elevator/.vscode/settings.json b/elevator/.vscode/settings.json new file mode 100644 index 0000000..eb7750c --- /dev/null +++ b/elevator/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cmake.configureOnOpen": false +} \ No newline at end of file diff --git a/elevator/elevator.log.json b/elevator/elevator.log.json index 3674b45..9993b22 100644 --- a/elevator/elevator.log.json +++ b/elevator/elevator.log.json @@ -1,7 +1,27 @@ [ { - "timestamp": "2:35:17 AM", - "event": "inside request", - "floorNum": 5 + "timestamp": "2023-09-02T04:57:40.619Z", + "event": "inside elevator request", + "floorNumber": 2 + }, + { + "timestamp": "2023-09-02T04:57:40.930Z", + "event": "move", + "floorNumber": 2 + }, + { + "timestamp": "2023-09-02T04:57:41.038Z", + "event": "stop", + "floorNumber": 2 + }, + { + "timestamp": "2023-09-02T04:57:41.755Z", + "event": "move", + "floorNumber": 1 + }, + { + "timestamp": "2023-09-02T04:57:41.864Z", + "event": "stop", + "floorNumber": 1 } ] \ No newline at end of file diff --git a/elevator/package.json b/elevator/package.json index c98b4b3..fe80864 100644 --- a/elevator/package.json +++ b/elevator/package.json @@ -7,7 +7,7 @@ "test": "jest --collect-coverage --no-cache", "lint": "eslint src test", "plato": "plato -d report -r src", - "start": "node src/elevator.service" + "start": "node src/elevator.service.js" }, "author": "", "license": "ISC", diff --git a/elevator/src/elevator.log.js b/elevator/src/elevator.log.js index b0c1cfa..cd3c082 100644 --- a/elevator/src/elevator.log.js +++ b/elevator/src/elevator.log.js @@ -1,25 +1,38 @@ -import fs from 'fs'; +"use strict"; + +const fs = require('fs'); const elevatorLogs = []; const typeOfEvent = { - INSIDE: 'inside request', - OUTSIDE: 'outside request', + INSIDE: 'inside elevator request', + OUTSIDE: 'outside elevator request', MOVE: 'move', STOP: 'stop', } -function logEvent(event, floorNum) { - const timestamp = new Date().toLocaleTimeString(); - elevatorLogs.push({timestamp, event, floorNum }); +function getLog() { + return elevatorLogs; +} + +function clearLog() { + elevatorLogs.length = 0; +} + +function logEvent(event, floorNumber, timestamp = new Date().toISOString()) { + elevatorLogs.push({ timestamp, event, floorNumber }); + return elevatorLogs; } function writeLog() { const log = JSON.stringify(elevatorLogs, null, 2); + fs.writeFileSync('./elevator.log.json', log); } module.exports.typeOfEvent = typeOfEvent; module.exports.writeLog = writeLog; -module.exports.logEvent = logEvent; \ No newline at end of file +module.exports.logEvent = logEvent; +module.exports.getLog = getLog; +module.exports.clearLog = clearLog; \ No newline at end of file diff --git a/elevator/src/elevator.request.js b/elevator/src/elevator.request.js index 183ac80..9b54288 100644 --- a/elevator/src/elevator.request.js +++ b/elevator/src/elevator.request.js @@ -1,25 +1,42 @@ -import { logEvent, typeOfEvent } from './elevator.log.js'; +"use strict"; + +const elevatorLogging = require('./elevator.log.js'); + +const typeOfEvent = elevatorLogging.typeOfEvent; const MAX_FLOOR = 10; const MIN_FLOOR = 1; const MOVE_DELAY = 300; const STOP_DELAY = 100; -const maxWeight = 1000; const elevatorSensor = { currentFloor: 1, - nextFloor: 1, + nextFloor: null, requestedFloor: [], direction: '', isMoving: false, - weightLimit: false, } -function validateFloor(floorNum) { - if (floorNum > MAX_FLOOR || floorNum < MIN_FLOOR) { +async function allRequestsCompleted() { + while (elevatorSensor.requestedFloor.length > 0) { + await new Promise((resolve) => { + setTimeout(resolve, 100); + }); + } + + // Reset elevator position to floor 1 + await resetElevatorPosition(); + + elevatorLogging.writeLog(); + + return true; +} + +function validateFloor(floorNumber) { + if (floorNumber > MAX_FLOOR || floorNumber < MIN_FLOOR) { throw new Error('Invalid floor number'); } - return floorNum; + return floorNumber; } async function elevatorTimer(time) { @@ -52,28 +69,39 @@ async function handleRequests() { } await elevatorTimer(MOVE_DELAY); + + elevatorLogging.logEvent(typeOfEvent.MOVE, elevatorSensor.currentFloor); } elevatorSensor.isMoving = false; await elevatorTimer(STOP_DELAY); + elevatorLogging.logEvent(typeOfEvent.STOP, elevatorSensor.currentFloor); + elevatorSensor.requestedFloor.splice(elevatorSensor.requestedFloor.indexOf(elevatorSensor.currentFloor), 1); elevatorSensor.nextFloor = getNextPickup(); } - } -function resetElevatorPosition() { +async function resetElevatorPosition() { + elevatorSensor.requestedFloor = [1]; + elevatorSensor.nextFloor = 1; + + await handleRequests(); + + elevatorSensor.nextFloor = null; + + elevatorSensor.direction = ''; } + function getNextPickup() { if (elevatorSensor.requestedFloor.length === 0) { return null; } - // Filter floors that match the current direction const floorsInDirection = elevatorSensor.requestedFloor.filter(floor => { if (elevatorSensor.direction === 'U') { return floor > elevatorSensor.currentFloor; @@ -95,43 +123,43 @@ function getNextPickup() { return sortedFloors[0]; } -async function insideElevatorRequest(floorNum) { - floorNum = validateFloor(floorNum); - //Timestamp here +async function insideElevatorRequest(floorNumber) { + floorNumber = validateFloor(floorNumber); + + elevatorLogging.logEvent(typeOfEvent.INSIDE, floorNumber); + if (elevatorSensor.requestedFloor.length === 0) { - elevatorSensor.nextFloor = floorNum; + elevatorSensor.nextFloor = floorNumber; } - elevatorSensor.requestedFloor.push(floorNum); + elevatorSensor.requestedFloor.push(floorNumber); await (handleRequests()); - - return elevatorSensor; } -async function outsideElevatorRequest(floorNum) { - - validateFloor(floorNum); +async function outsideElevatorRequest(floorNumber) { + validateFloor(floorNumber); - //Timestamp here + elevatorLogging.logEvent(typeOfEvent.OUTSIDE, floorNumber); if (elevatorSensor.requestedFloor.length === 0) { - elevatorSensor.nextFloor = floorNum; + elevatorSensor.nextFloor = floorNumber; } - if (elevatorSensor.isMoving && Math.abs(floorNum - elevatorSensor.currentFloor) >= 1 || !elevatorSensor.isMoving) { - elevatorSensor.requestedFloor.push(floorNum); + if (elevatorSensor.isMoving && Math.abs(floorNumber - elevatorSensor.currentFloor) >= 1 || !elevatorSensor.isMoving) { + elevatorSensor.requestedFloor.push(floorNumber); } else { elevatorTimer(MOVE_DELAY); - elevatorSensor.requestedFloor.push(floorNum); + + elevatorSensor.requestedFloor.push(floorNumber); } + await (handleRequests()); } module.exports.validateFloor = validateFloor; module.exports.elevatorTimer = elevatorTimer; - -insideElevatorRequest(6); -outsideElevatorRequest(1); -//insideElevatorRequest(7); -outsideElevatorRequest(2); \ No newline at end of file +module.exports.insideElevatorRequest = insideElevatorRequest; +module.exports.outsideElevatorRequest = outsideElevatorRequest; +module.exports.allRequestsCompleted = allRequestsCompleted; +module.exports.resetElevatorPosition = resetElevatorPosition; diff --git a/elevator/src/elevator.service.js b/elevator/src/elevator.service.js index 0603661..cae97b9 100644 --- a/elevator/src/elevator.service.js +++ b/elevator/src/elevator.service.js @@ -1,2 +1,53 @@ -//This is the main file to run the elevator service and it will act as the interface -//Work the 'Q' logic here \ No newline at end of file +"use strict"; +const readline = require('readline'); +const elevatorRequest = require('./elevator.request.js'); +let completed = false; + +function handleUserInput(floorNumber) { + console.log('Floor Number:', floorNumber); + + if (floorNumber === 'Q' || floorNumber === 'q') { + console.log('Quitting...'); + + completed = true; + + return + } + + if (!isNaN(floorNumber)) { + console.log('Inside elevator request'); + + elevatorRequest.insideElevatorRequest(parseInt(floorNumber)); + } + + else { + console.log('Outside elevator request'); + + elevatorRequest.outsideElevatorRequest(parseInt(floorNumber.replace(/\D/g, ''))); + } +} + +const userInterface = readline.createInterface({ + input: process.stdin, + output: process.stdout, +}); + +async function processUserInput() { + while (completed === false) { + const userInput = await new Promise((resolve) => { + userInterface.question('Please enter console command: ', resolve); + }); + + handleUserInput(userInput); + + } + const allCompleted = await elevatorRequest.allRequestsCompleted(); + + console.log('All requests completed:', allCompleted); + + userInterface.close(); +} + +processUserInput().catch((error) => { + console.error('An error occurred:', error); +}); diff --git a/elevator/test/elevator.log.test.js b/elevator/test/elevator.log.test.js index bfcd8cd..8d88487 100644 --- a/elevator/test/elevator.log.test.js +++ b/elevator/test/elevator.log.test.js @@ -1,5 +1,16 @@ import { logEvent, writeLog, typeOfEvent } from '../src/elevator.log.js'; -test('Log event when elevator stopped', () => { - -}); \ No newline at end of file +test('logEvent successfully record an event', () => { + const mockedTimestamp = '2023-08-30T13:00:00.000Z'; + + Date.now = jest.fn(() => new Date(mockedTimestamp).getTime()); + + const log = logEvent(typeOfEvent.INSIDE, 5, mockedTimestamp); + + expect(log).toEqual([{ + "timestamp":"2023-08-30T13:00:00.000Z", + "event":"inside elevator request", + "floorNumber":5 + }]); +}); + diff --git a/elevator/test/elevator.request.test.js b/elevator/test/elevator.request.test.js index d86015c..618d9c0 100644 --- a/elevator/test/elevator.request.test.js +++ b/elevator/test/elevator.request.test.js @@ -1,4 +1,6 @@ -import { validateFloor, elevatorTimer } from '../src/elevator.request.js'; +const elevatorLogging = require('../src/elevator.log.js'); +import { resetElevatorPosition, insideElevatorRequest, outsideElevatorRequest, validateFloor, elevatorTimer, allRequestsCompleted } from '../src/elevator.request.js'; +import { typeOfEvent, getLog, clearLog } from '../src/elevator.log.js'; test('canary', () => { expect(true).toBe(true); @@ -38,4 +40,65 @@ test('elevatorTimer given 100ms await 100ms', async () => { const elapsedSeconds = (endTime - startTime) / 1000; expect(elapsedSeconds).toBeCloseTo(.1, 1); -}); \ No newline at end of file +}); + +test('elevator made a request inside return correct output', async () => { + await insideElevatorRequest(3); + + const log = getLog(); + + expect(log).toEqual([ + expect.objectContaining({ event: typeOfEvent.INSIDE, floorNumber: 3 }), + expect.objectContaining({ event: typeOfEvent.MOVE, floorNumber: 2 }), + expect.objectContaining({ event: typeOfEvent.MOVE, floorNumber: 3 }), + expect.objectContaining({ event: typeOfEvent.STOP, floorNumber: 3 }) + ]); +}); + +test('elevator made a request inside return correct output', async () => { + await resetElevatorPosition(); + + clearLog(); + + await outsideElevatorRequest(3); + + const log = getLog(); + + expect(log).toEqual([ + expect.objectContaining({ event: typeOfEvent.OUTSIDE, floorNumber: 3 }), + expect.objectContaining({ event: typeOfEvent.MOVE, floorNumber: 2 }), + expect.objectContaining({ event: typeOfEvent.MOVE, floorNumber: 3 }), + expect.objectContaining({ event: typeOfEvent.STOP, floorNumber: 3 }) + ]); +}); + +test('elevator made a request inside and outside, inside request is processed first', async () => { + await resetElevatorPosition(); + + clearLog(); + + await insideElevatorRequest(3); + + await outsideElevatorRequest(1); + + const log = getLog(); + + expect(log).toEqual([ + expect.objectContaining({ event: typeOfEvent.INSIDE, floorNumber: 3 }), + expect.objectContaining({ event: typeOfEvent.MOVE, floorNumber: 2 }), + expect.objectContaining({ event: typeOfEvent.MOVE, floorNumber: 3 }), + expect.objectContaining({ event: typeOfEvent.STOP, floorNumber: 3 }), + expect.objectContaining({ event: typeOfEvent.OUTSIDE, floorNumber: 1 }), + expect.objectContaining({ event: typeOfEvent.MOVE, floorNumber: 2 }), + expect.objectContaining({ event: typeOfEvent.MOVE, floorNumber: 1 }), + expect.objectContaining({ event: typeOfEvent.STOP, floorNumber: 1 }) + ]); +}); + +test('allRequestsCompleted called writeLog', async () => { + const writeLogSpy = jest.spyOn(elevatorLogging, 'writeLog'); + + await allRequestsCompleted(); + + expect(writeLogSpy).toHaveBeenCalled(); +}); diff --git a/elevator/tests.txt b/elevator/tests.txt index c27adb7..54dc16e 100644 --- a/elevator/tests.txt +++ b/elevator/tests.txt @@ -1,12 +1,17 @@ x canary test + x validateFloor request to 5th floor return position at 5 x validateFloor request past max floor throw error x validateFloor request past min floor throw error -- inside elevator travel request on existing floor throw error x elevatorTimer given 10ms await 10ms x elevatorTimer given 100ms await 100ms -- logEvent successfully record an accurate event -- writeLog successfully output a file -- elevator travel 3 floors up log correct output -- elevator travel 1 floor up and 2 floor down log correct output + +x allRequestsCompleted called for writeLog + +x elevator made a request inside return correct output +x elevator made a request outside return correct output +x elevator made a request inside then outside return correct output + +x logEvent successfully record an event + From 81322d3fa7973fc3024189aaf23d93747ff87ed5 Mon Sep 17 00:00:00 2001 From: Nachtmusiks <70234914+Nachtmusiks@users.noreply.github.com> Date: Sat, 2 Sep 2023 00:05:17 -0500 Subject: [PATCH 09/12] update .gitignore --- .gitignore | 1 + elevator/elevator.log.json | 57 ++++++++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 0a3e8ee..54cf5c1 100644 --- a/.gitignore +++ b/.gitignore @@ -342,3 +342,4 @@ elevator/coverage/lcov-report/sorter.js elevator/package-lock.json elevator/.vscode/launch.json elevator/elevator.code-workspace +elevator/elevator.log.json diff --git a/elevator/elevator.log.json b/elevator/elevator.log.json index 9993b22..4b69c33 100644 --- a/elevator/elevator.log.json +++ b/elevator/elevator.log.json @@ -1,26 +1,71 @@ [ { - "timestamp": "2023-09-02T04:57:40.619Z", + "timestamp": "2023-09-02T05:04:27.796Z", "event": "inside elevator request", - "floorNumber": 2 + "floorNumber": 1 + }, + { + "timestamp": "2023-09-02T05:04:27.908Z", + "event": "stop", + "floorNumber": 1 + }, + { + "timestamp": "2023-09-02T05:04:35.891Z", + "event": "inside elevator request", + "floorNumber": 3 }, { - "timestamp": "2023-09-02T04:57:40.930Z", + "timestamp": "2023-09-02T05:04:36.194Z", "event": "move", "floorNumber": 2 }, { - "timestamp": "2023-09-02T04:57:41.038Z", + "timestamp": "2023-09-02T05:04:36.437Z", + "event": "inside elevator request", + "floorNumber": 2 + }, + { + "timestamp": "2023-09-02T05:04:36.506Z", + "event": "move", + "floorNumber": 3 + }, + { + "timestamp": "2023-09-02T05:04:36.551Z", "event": "stop", + "floorNumber": 3 + }, + { + "timestamp": "2023-09-02T05:04:36.613Z", + "event": "stop", + "floorNumber": 2 + }, + { + "timestamp": "2023-09-02T05:04:36.862Z", + "event": "move", "floorNumber": 2 }, { - "timestamp": "2023-09-02T04:57:41.755Z", + "timestamp": "2023-09-02T05:04:37.170Z", + "event": "move", + "floorNumber": 1 + }, + { + "timestamp": "2023-09-02T05:04:37.481Z", + "event": "move", + "floorNumber": 0 + }, + { + "timestamp": "2023-09-02T05:04:37.793Z", + "event": "move", + "floorNumber": 0 + }, + { + "timestamp": "2023-09-02T05:04:37.919Z", "event": "move", "floorNumber": 1 }, { - "timestamp": "2023-09-02T04:57:41.864Z", + "timestamp": "2023-09-02T05:04:38.029Z", "event": "stop", "floorNumber": 1 } From 11650258062d5455fcd4400e3112c16d6abbff97 Mon Sep 17 00:00:00 2001 From: Nachtmusiks <70234914+Nachtmusiks@users.noreply.github.com> Date: Sat, 2 Sep 2023 00:22:07 -0500 Subject: [PATCH 10/12] Fixing syntaxes for lint and adding build script --- .gitignore | 1 + elevator/build.sh | 11 ++++ elevator/elevator.log.json | 72 -------------------------- elevator/src/elevator.log.js | 4 +- elevator/src/elevator.request.js | 6 +-- elevator/src/elevator.service.js | 3 +- elevator/test/elevator.log.test.js | 8 +-- elevator/test/elevator.request.test.js | 12 +++-- 8 files changed, 28 insertions(+), 89 deletions(-) create mode 100644 elevator/build.sh delete mode 100644 elevator/elevator.log.json diff --git a/.gitignore b/.gitignore index 54cf5c1..cefeef4 100644 --- a/.gitignore +++ b/.gitignore @@ -343,3 +343,4 @@ elevator/package-lock.json elevator/.vscode/launch.json elevator/elevator.code-workspace elevator/elevator.log.json +elevator/elevator.log.json diff --git a/elevator/build.sh b/elevator/build.sh new file mode 100644 index 0000000..6a762b3 --- /dev/null +++ b/elevator/build.sh @@ -0,0 +1,11 @@ +npm install +[ $? -eq 0 ] || exit 1 + +npm run lint +[ $? -eq 0 ] || exit 1 + +npm test +[ $? -eq 0 ] || exit 1 + +npm run start +[ $? -eq 0 ] || exit 1 diff --git a/elevator/elevator.log.json b/elevator/elevator.log.json deleted file mode 100644 index 4b69c33..0000000 --- a/elevator/elevator.log.json +++ /dev/null @@ -1,72 +0,0 @@ -[ - { - "timestamp": "2023-09-02T05:04:27.796Z", - "event": "inside elevator request", - "floorNumber": 1 - }, - { - "timestamp": "2023-09-02T05:04:27.908Z", - "event": "stop", - "floorNumber": 1 - }, - { - "timestamp": "2023-09-02T05:04:35.891Z", - "event": "inside elevator request", - "floorNumber": 3 - }, - { - "timestamp": "2023-09-02T05:04:36.194Z", - "event": "move", - "floorNumber": 2 - }, - { - "timestamp": "2023-09-02T05:04:36.437Z", - "event": "inside elevator request", - "floorNumber": 2 - }, - { - "timestamp": "2023-09-02T05:04:36.506Z", - "event": "move", - "floorNumber": 3 - }, - { - "timestamp": "2023-09-02T05:04:36.551Z", - "event": "stop", - "floorNumber": 3 - }, - { - "timestamp": "2023-09-02T05:04:36.613Z", - "event": "stop", - "floorNumber": 2 - }, - { - "timestamp": "2023-09-02T05:04:36.862Z", - "event": "move", - "floorNumber": 2 - }, - { - "timestamp": "2023-09-02T05:04:37.170Z", - "event": "move", - "floorNumber": 1 - }, - { - "timestamp": "2023-09-02T05:04:37.481Z", - "event": "move", - "floorNumber": 0 - }, - { - "timestamp": "2023-09-02T05:04:37.793Z", - "event": "move", - "floorNumber": 0 - }, - { - "timestamp": "2023-09-02T05:04:37.919Z", - "event": "move", - "floorNumber": 1 - }, - { - "timestamp": "2023-09-02T05:04:38.029Z", - "event": "stop", - "floorNumber": 1 - } -] \ No newline at end of file diff --git a/elevator/src/elevator.log.js b/elevator/src/elevator.log.js index cd3c082..390d8a4 100644 --- a/elevator/src/elevator.log.js +++ b/elevator/src/elevator.log.js @@ -1,5 +1,3 @@ -"use strict"; - const fs = require('fs'); const elevatorLogs = []; @@ -9,7 +7,7 @@ const typeOfEvent = { OUTSIDE: 'outside elevator request', MOVE: 'move', STOP: 'stop', -} +}; function getLog() { return elevatorLogs; diff --git a/elevator/src/elevator.request.js b/elevator/src/elevator.request.js index 9b54288..b602bc8 100644 --- a/elevator/src/elevator.request.js +++ b/elevator/src/elevator.request.js @@ -1,5 +1,3 @@ -"use strict"; - const elevatorLogging = require('./elevator.log.js'); const typeOfEvent = elevatorLogging.typeOfEvent; @@ -15,7 +13,7 @@ const elevatorSensor = { requestedFloor: [], direction: '', isMoving: false, -} +}; async function allRequestsCompleted() { while (elevatorSensor.requestedFloor.length > 0) { @@ -57,7 +55,7 @@ async function handleRequests() { elevatorSensor.isMoving = true; - while (elevatorSensor.nextFloor != elevatorSensor.currentFloor) { + while (elevatorSensor.nextFloor !== elevatorSensor.currentFloor) { elevatorSensor.nextFloor = getNextPickup(); if (elevatorSensor.direction === 'U') { diff --git a/elevator/src/elevator.service.js b/elevator/src/elevator.service.js index cae97b9..ed655a8 100644 --- a/elevator/src/elevator.service.js +++ b/elevator/src/elevator.service.js @@ -1,4 +1,3 @@ -"use strict"; const readline = require('readline'); const elevatorRequest = require('./elevator.request.js'); let completed = false; @@ -11,7 +10,7 @@ function handleUserInput(floorNumber) { completed = true; - return + return; } if (!isNaN(floorNumber)) { diff --git a/elevator/test/elevator.log.test.js b/elevator/test/elevator.log.test.js index 8d88487..a41b08e 100644 --- a/elevator/test/elevator.log.test.js +++ b/elevator/test/elevator.log.test.js @@ -1,3 +1,5 @@ +/* eslint-env jest */ + import { logEvent, writeLog, typeOfEvent } from '../src/elevator.log.js'; test('logEvent successfully record an event', () => { @@ -8,9 +10,9 @@ test('logEvent successfully record an event', () => { const log = logEvent(typeOfEvent.INSIDE, 5, mockedTimestamp); expect(log).toEqual([{ - "timestamp":"2023-08-30T13:00:00.000Z", - "event":"inside elevator request", - "floorNumber":5 + 'timestamp':'2023-08-30T13:00:00.000Z', + 'event':'inside elevator request', + 'floorNumber':5 }]); }); diff --git a/elevator/test/elevator.request.test.js b/elevator/test/elevator.request.test.js index 618d9c0..23e0e74 100644 --- a/elevator/test/elevator.request.test.js +++ b/elevator/test/elevator.request.test.js @@ -1,3 +1,5 @@ +/* eslint-env jest */ + const elevatorLogging = require('../src/elevator.log.js'); import { resetElevatorPosition, insideElevatorRequest, outsideElevatorRequest, validateFloor, elevatorTimer, allRequestsCompleted } from '../src/elevator.request.js'; import { typeOfEvent, getLog, clearLog } from '../src/elevator.log.js'; @@ -48,11 +50,11 @@ test('elevator made a request inside return correct output', async () => { const log = getLog(); expect(log).toEqual([ - expect.objectContaining({ event: typeOfEvent.INSIDE, floorNumber: 3 }), - expect.objectContaining({ event: typeOfEvent.MOVE, floorNumber: 2 }), - expect.objectContaining({ event: typeOfEvent.MOVE, floorNumber: 3 }), - expect.objectContaining({ event: typeOfEvent.STOP, floorNumber: 3 }) - ]); + expect.objectContaining({ event: typeOfEvent.INSIDE, floorNumber: 3 }), + expect.objectContaining({ event: typeOfEvent.MOVE, floorNumber: 2 }), + expect.objectContaining({ event: typeOfEvent.MOVE, floorNumber: 3 }), + expect.objectContaining({ event: typeOfEvent.STOP, floorNumber: 3 }) + ]); }); test('elevator made a request inside return correct output', async () => { From 300f03f4bc2e66c430d9978e790123ae1832ee8f Mon Sep 17 00:00:00 2001 From: Nachtmusiks <70234914+Nachtmusiks@users.noreply.github.com> Date: Sat, 2 Sep 2023 00:24:57 -0500 Subject: [PATCH 11/12] Updated build script to include plato check --- .gitignore | 72 +++++++++++++++++++++++++++++++++++++++++++++++ elevator/build.sh | 7 +++++ 2 files changed, 79 insertions(+) diff --git a/.gitignore b/.gitignore index cefeef4..39f698b 100644 --- a/.gitignore +++ b/.gitignore @@ -344,3 +344,75 @@ elevator/.vscode/launch.json elevator/elevator.code-workspace elevator/elevator.log.json elevator/elevator.log.json +elevator/report/display.html +elevator/report/index.html +elevator/report/report.history.js +elevator/report/report.history.json +elevator/report/report.js +elevator/report/report.json +elevator/report/assets/css/morris.css +elevator/report/assets/css/plato-display.css +elevator/report/assets/css/plato-file.css +elevator/report/assets/css/plato-overview.css +elevator/report/assets/css/plato.css +elevator/report/assets/css/vendor/bootstrap.css +elevator/report/assets/css/vendor/codemirror.css +elevator/report/assets/css/vendor/font-awesome.css +elevator/report/assets/css/vendor/morris.css +elevator/report/assets/font/fontawesome-webfont.eot +elevator/report/assets/font/fontawesome-webfont.svg +elevator/report/assets/font/fontawesome-webfont.ttf +elevator/report/assets/font/fontawesome-webfont.woff +elevator/report/assets/scripts/codemirror.markpopovertext.js +elevator/report/assets/scripts/plato-display.js +elevator/report/assets/scripts/plato-file.js +elevator/report/assets/scripts/plato-overview.js +elevator/report/assets/scripts/plato-sortable-file-list.js +elevator/report/assets/scripts/bundles/codemirror.js +elevator/report/assets/scripts/bundles/core-bundle.js +elevator/report/assets/scripts/vendor/bootstrap-popover.js +elevator/report/assets/scripts/vendor/bootstrap-tooltip.js +elevator/report/assets/scripts/vendor/jquery-1.8.3.min.js +elevator/report/assets/scripts/vendor/jquery.fittext.js +elevator/report/assets/scripts/vendor/lodash.min.js +elevator/report/assets/scripts/vendor/morris.min.js +elevator/report/assets/scripts/vendor/raphael-min.js +elevator/report/assets/scripts/vendor/codemirror/codemirror.js +elevator/report/assets/scripts/vendor/codemirror/javascript.js +elevator/report/assets/scripts/vendor/codemirror/util/closetag.js +elevator/report/assets/scripts/vendor/codemirror/util/colorize.js +elevator/report/assets/scripts/vendor/codemirror/util/continuecomment.js +elevator/report/assets/scripts/vendor/codemirror/util/continuelist.js +elevator/report/assets/scripts/vendor/codemirror/util/dialog.css +elevator/report/assets/scripts/vendor/codemirror/util/dialog.js +elevator/report/assets/scripts/vendor/codemirror/util/foldcode.js +elevator/report/assets/scripts/vendor/codemirror/util/formatting.js +elevator/report/assets/scripts/vendor/codemirror/util/javascript-hint.js +elevator/report/assets/scripts/vendor/codemirror/util/loadmode.js +elevator/report/assets/scripts/vendor/codemirror/util/match-highlighter.js +elevator/report/assets/scripts/vendor/codemirror/util/matchbrackets.js +elevator/report/assets/scripts/vendor/codemirror/util/multiplex.js +elevator/report/assets/scripts/vendor/codemirror/util/overlay.js +elevator/report/assets/scripts/vendor/codemirror/util/pig-hint.js +elevator/report/assets/scripts/vendor/codemirror/util/runmode-standalone.js +elevator/report/assets/scripts/vendor/codemirror/util/runmode.js +elevator/report/assets/scripts/vendor/codemirror/util/search.js +elevator/report/assets/scripts/vendor/codemirror/util/searchcursor.js +elevator/report/assets/scripts/vendor/codemirror/util/simple-hint.css +elevator/report/assets/scripts/vendor/codemirror/util/simple-hint.js +elevator/report/assets/scripts/vendor/codemirror/util/xml-hint.js +elevator/report/files/src_elevator_log_js/index.html +elevator/report/files/src_elevator_log_js/report.history.js +elevator/report/files/src_elevator_log_js/report.history.json +elevator/report/files/src_elevator_log_js/report.js +elevator/report/files/src_elevator_log_js/report.json +elevator/report/files/src_elevator_request_js/index.html +elevator/report/files/src_elevator_request_js/report.history.js +elevator/report/files/src_elevator_request_js/report.history.json +elevator/report/files/src_elevator_request_js/report.js +elevator/report/files/src_elevator_request_js/report.json +elevator/report/files/src_elevator_service_js/index.html +elevator/report/files/src_elevator_service_js/report.history.js +elevator/report/files/src_elevator_service_js/report.history.json +elevator/report/files/src_elevator_service_js/report.js +elevator/report/files/src_elevator_service_js/report.json diff --git a/elevator/build.sh b/elevator/build.sh index 6a762b3..cc77f1d 100644 --- a/elevator/build.sh +++ b/elevator/build.sh @@ -7,5 +7,12 @@ npm run lint npm test [ $? -eq 0 ] || exit 1 +npm run plato +[ $? -eq 0 ] || exit 1 + +node ../platocheck.js +[ $? -eq 0 ] || exit 1 + npm run start [ $? -eq 0 ] || exit 1 + From 5ed72c3aee27f5a45bbec4d885a95101ad478832 Mon Sep 17 00:00:00 2001 From: Nachtmusiks <70234914+Nachtmusiks@users.noreply.github.com> Date: Sat, 2 Sep 2023 00:32:54 -0500 Subject: [PATCH 12/12] Fixed build script ``` --- elevator/build.sh | 3 --- 1 file changed, 3 deletions(-) diff --git a/elevator/build.sh b/elevator/build.sh index cc77f1d..39ce6d4 100644 --- a/elevator/build.sh +++ b/elevator/build.sh @@ -10,9 +10,6 @@ npm test npm run plato [ $? -eq 0 ] || exit 1 -node ../platocheck.js -[ $? -eq 0 ] || exit 1 - npm run start [ $? -eq 0 ] || exit 1