From 357f86f8321981ffac5fde9b64c529e5cf141700 Mon Sep 17 00:00:00 2001 From: Mark Tyers Date: Tue, 8 Oct 2019 20:17:44 +0100 Subject: [PATCH 1/9] added open file debug option --- .vscode/launch.json | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.vscode/launch.json b/.vscode/launch.json index 5c075a55..2253084f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -2,6 +2,12 @@ { "version": "0.2.0", "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Launch Current Opened File", + "program": "${file}" + }, { "type": "node", "request": "launch", From 21c2366e40c133db53a5f5f9158c897cbf8b768a Mon Sep 17 00:00:00 2001 From: Mark Tyers Date: Wed, 9 Oct 2019 07:38:48 +0100 Subject: [PATCH 2/9] replaced api used --- exercises/06_code_quality/list.js | 23 ++++++++++++++++++++ exercises/06_code_quality/nestedCallbacks.js | 4 ++-- exercises/06_code_quality/package.json | 2 ++ 3 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 exercises/06_code_quality/list.js diff --git a/exercises/06_code_quality/list.js b/exercises/06_code_quality/list.js new file mode 100644 index 00000000..69912d5b --- /dev/null +++ b/exercises/06_code_quality/list.js @@ -0,0 +1,23 @@ +#!/usr/bin/env node + +'use strict' + +const readline = require('readline-sync') +const items = [] +let action + +while(true) { + action = String(readline.question('enter a command (add, list, quit): ')) + switch(action) { + case 'add': + const item = String(readline.question('item name: ')) + const qty = Number(readline.question(`now many items of type "${item}": `)) + items.push({item, qty}) + case 'list': + items.forEach( item => console.log(`${item.item}: ${item.qty}`)) + case 'quit': + process.exit() + default: + console.log('command not recognised') + } +} diff --git a/exercises/06_code_quality/nestedCallbacks.js b/exercises/06_code_quality/nestedCallbacks.js index cd3fcc12..6d89b729 100644 --- a/exercises/06_code_quality/nestedCallbacks.js +++ b/exercises/06_code_quality/nestedCallbacks.js @@ -14,7 +14,7 @@ getInput('enter base currency', (err, base) => { console.log(err.message) process.exit() } - getData(`http://api.fixer.io/latest?base=${base}`, (err, data) => { + getData(`https://api.exchangeratesapi.io/latest?base=${base}`, (err, data) => { if (err) { console.log(err.message) process.exit() @@ -39,7 +39,7 @@ function getInput(prompt, callback) { function checkValidCurrencyCode(code, callback) { code = code.trim() - request('http://api.fixer.io/latest', (err, res, body) => { + request('https://api.exchangeratesapi.io/latest', (err, res, body) => { if (err) callback(new Error('invalid API call')) const rates = JSON.parse(body).rates if (!rates.hasOwnProperty(code)) callback(new Error(`invalid currency code ${code}`)) diff --git a/exercises/06_code_quality/package.json b/exercises/06_code_quality/package.json index 6c5393de..a4821bce 100644 --- a/exercises/06_code_quality/package.json +++ b/exercises/06_code_quality/package.json @@ -34,6 +34,8 @@ "koa-static": "^5.0.0", "koa-views": "^6.1.5", "mime-types": "^2.1.22", + "readline-sync": "^1.4.10", + "request": "^2.88.0", "sqlite-async": "^1.0.11" }, "devDependencies": { From 393a730fd2e2405c96f0815808197b0ae1336054 Mon Sep 17 00:00:00 2001 From: Mark Tyers Date: Wed, 9 Oct 2019 08:01:24 +0100 Subject: [PATCH 3/9] added a currencies data file --- 06 Code Quality.md | 11 +- exercises/06_code_quality/currencies.json | 173 ++++++++++++++++++++++ 2 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 exercises/06_code_quality/currencies.json diff --git a/06 Code Quality.md b/06 Code Quality.md index 9e99995f..feed4717 100644 --- a/06 Code Quality.md +++ b/06 Code Quality.md @@ -135,7 +135,16 @@ The callbacks are already nested 3 deep. To test your knowledge of deeply nested 1. modify the script to ask for the currency to convert to and display only the one conversion rate. 2. instead of printing the exchange rate, ask for the amount to be converted and them return the equivalent in the chosen currency -3. use the [OpenExchangeRates](https://openexchangerates.org/api/currencies.json) API to display the full name of the chosen currency. +3. The `currencies.json` file contains a map between the currency code and the country name. Load this file into the script using the [`fs`](https://nodejs.org/api/fs.html) module, convert to a JavaScript object using the [`JSON`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON) object and use it to display the full name of the chosen currency. Below is some code to get you started. + +You will need to import the `fs` module and use the `fs.readFile()` function which takes a callback! + +```javascript +fs.readFile('currencies.json', 'utf8', (err, contents) => { + if(err) console.log('you need to handle this properly') + console.log(contents) +}) +``` Even though the script is still simple you are probably already getting in a tangle! Imagine a more complex script with conditions, it would quickly get out of hand and become practically impossible to debug. diff --git a/exercises/06_code_quality/currencies.json b/exercises/06_code_quality/currencies.json new file mode 100644 index 00000000..08407277 --- /dev/null +++ b/exercises/06_code_quality/currencies.json @@ -0,0 +1,173 @@ +{ + "AED": "United Arab Emirates Dirham", + "AFN": "Afghan Afghani", + "ALL": "Albanian Lek", + "AMD": "Armenian Dram", + "ANG": "Netherlands Antillean Guilder", + "AOA": "Angolan Kwanza", + "ARS": "Argentine Peso", + "AUD": "Australian Dollar", + "AWG": "Aruban Florin", + "AZN": "Azerbaijani Manat", + "BAM": "Bosnia-Herzegovina Convertible Mark", + "BBD": "Barbadian Dollar", + "BDT": "Bangladeshi Taka", + "BGN": "Bulgarian Lev", + "BHD": "Bahraini Dinar", + "BIF": "Burundian Franc", + "BMD": "Bermudan Dollar", + "BND": "Brunei Dollar", + "BOB": "Bolivian Boliviano", + "BRL": "Brazilian Real", + "BSD": "Bahamian Dollar", + "BTC": "Bitcoin", + "BTN": "Bhutanese Ngultrum", + "BWP": "Botswanan Pula", + "BYN": "Belarusian Ruble", + "BZD": "Belize Dollar", + "CAD": "Canadian Dollar", + "CDF": "Congolese Franc", + "CHF": "Swiss Franc", + "CLF": "Chilean Unit of Account (UF)", + "CLP": "Chilean Peso", + "CNH": "Chinese Yuan (Offshore)", + "CNY": "Chinese Yuan", + "COP": "Colombian Peso", + "CRC": "Costa Rican Colón", + "CUC": "Cuban Convertible Peso", + "CUP": "Cuban Peso", + "CVE": "Cape Verdean Escudo", + "CZK": "Czech Republic Koruna", + "DJF": "Djiboutian Franc", + "DKK": "Danish Krone", + "DOP": "Dominican Peso", + "DZD": "Algerian Dinar", + "EGP": "Egyptian Pound", + "ERN": "Eritrean Nakfa", + "ETB": "Ethiopian Birr", + "EUR": "Euro", + "FJD": "Fijian Dollar", + "FKP": "Falkland Islands Pound", + "GBP": "British Pound Sterling", + "GEL": "Georgian Lari", + "GGP": "Guernsey Pound", + "GHS": "Ghanaian Cedi", + "GIP": "Gibraltar Pound", + "GMD": "Gambian Dalasi", + "GNF": "Guinean Franc", + "GTQ": "Guatemalan Quetzal", + "GYD": "Guyanaese Dollar", + "HKD": "Hong Kong Dollar", + "HNL": "Honduran Lempira", + "HRK": "Croatian Kuna", + "HTG": "Haitian Gourde", + "HUF": "Hungarian Forint", + "IDR": "Indonesian Rupiah", + "ILS": "Israeli New Sheqel", + "IMP": "Manx pound", + "INR": "Indian Rupee", + "IQD": "Iraqi Dinar", + "IRR": "Iranian Rial", + "ISK": "Icelandic Króna", + "JEP": "Jersey Pound", + "JMD": "Jamaican Dollar", + "JOD": "Jordanian Dinar", + "JPY": "Japanese Yen", + "KES": "Kenyan Shilling", + "KGS": "Kyrgystani Som", + "KHR": "Cambodian Riel", + "KMF": "Comorian Franc", + "KPW": "North Korean Won", + "KRW": "South Korean Won", + "KWD": "Kuwaiti Dinar", + "KYD": "Cayman Islands Dollar", + "KZT": "Kazakhstani Tenge", + "LAK": "Laotian Kip", + "LBP": "Lebanese Pound", + "LKR": "Sri Lankan Rupee", + "LRD": "Liberian Dollar", + "LSL": "Lesotho Loti", + "LYD": "Libyan Dinar", + "MAD": "Moroccan Dirham", + "MDL": "Moldovan Leu", + "MGA": "Malagasy Ariary", + "MKD": "Macedonian Denar", + "MMK": "Myanma Kyat", + "MNT": "Mongolian Tugrik", + "MOP": "Macanese Pataca", + "MRO": "Mauritanian Ouguiya (pre-2018)", + "MRU": "Mauritanian Ouguiya", + "MUR": "Mauritian Rupee", + "MVR": "Maldivian Rufiyaa", + "MWK": "Malawian Kwacha", + "MXN": "Mexican Peso", + "MYR": "Malaysian Ringgit", + "MZN": "Mozambican Metical", + "NAD": "Namibian Dollar", + "NGN": "Nigerian Naira", + "NIO": "Nicaraguan Córdoba", + "NOK": "Norwegian Krone", + "NPR": "Nepalese Rupee", + "NZD": "New Zealand Dollar", + "OMR": "Omani Rial", + "PAB": "Panamanian Balboa", + "PEN": "Peruvian Nuevo Sol", + "PGK": "Papua New Guinean Kina", + "PHP": "Philippine Peso", + "PKR": "Pakistani Rupee", + "PLN": "Polish Zloty", + "PYG": "Paraguayan Guarani", + "QAR": "Qatari Rial", + "RON": "Romanian Leu", + "RSD": "Serbian Dinar", + "RUB": "Russian Ruble", + "RWF": "Rwandan Franc", + "SAR": "Saudi Riyal", + "SBD": "Solomon Islands Dollar", + "SCR": "Seychellois Rupee", + "SDG": "Sudanese Pound", + "SEK": "Swedish Krona", + "SGD": "Singapore Dollar", + "SHP": "Saint Helena Pound", + "SLL": "Sierra Leonean Leone", + "SOS": "Somali Shilling", + "SRD": "Surinamese Dollar", + "SSP": "South Sudanese Pound", + "STD": "São Tomé and Príncipe Dobra (pre-2018)", + "STN": "São Tomé and Príncipe Dobra", + "SVC": "Salvadoran Colón", + "SYP": "Syrian Pound", + "SZL": "Swazi Lilangeni", + "THB": "Thai Baht", + "TJS": "Tajikistani Somoni", + "TMT": "Turkmenistani Manat", + "TND": "Tunisian Dinar", + "TOP": "Tongan Pa'anga", + "TRY": "Turkish Lira", + "TTD": "Trinidad and Tobago Dollar", + "TWD": "New Taiwan Dollar", + "TZS": "Tanzanian Shilling", + "UAH": "Ukrainian Hryvnia", + "UGX": "Ugandan Shilling", + "USD": "United States Dollar", + "UYU": "Uruguayan Peso", + "UZS": "Uzbekistan Som", + "VEF": "Venezuelan Bolívar Fuerte (Old)", + "VES": "Venezuelan Bolívar Soberano", + "VND": "Vietnamese Dong", + "VUV": "Vanuatu Vatu", + "WST": "Samoan Tala", + "XAF": "CFA Franc BEAC", + "XAG": "Silver Ounce", + "XAU": "Gold Ounce", + "XCD": "East Caribbean Dollar", + "XDR": "Special Drawing Rights", + "XOF": "CFA Franc BCEAO", + "XPD": "Palladium Ounce", + "XPF": "CFP Franc", + "XPT": "Platinum Ounce", + "YER": "Yemeni Rial", + "ZAR": "South African Rand", + "ZMW": "Zambian Kwacha", + "ZWL": "Zimbabwean Dollar" +} From ca82a7516f1fb27827b82368d2341cc6d1bb4d0d Mon Sep 17 00:00:00 2001 From: Mark Tyers Date: Wed, 9 Oct 2019 08:12:43 +0100 Subject: [PATCH 4/9] fixed all urls --- 06 Code Quality.md | 31 ++++++++++++++------------- exercises/06_code_quality/promises.js | 5 +++-- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/06 Code Quality.md b/06 Code Quality.md index feed4717..a65ca43d 100644 --- a/06 Code Quality.md +++ b/06 Code Quality.md @@ -164,6 +164,7 @@ A promise represents the result of an asynchronous operation. As such it can be Promises are created using the `new` keyword. This function is called immediately with two arguments. The first argument resolves the promise and the second one rejects it. Once the appropriate argument is called the promise state changes. ```javascript +const url = 'https://api.exchangeratesapi.io/latest?base=GBP' const getData = url => new Promise( (resolve, reject) => { request(url, (err, res, body) => { if (err) reject(new Error('invalid API call')) @@ -182,7 +183,7 @@ As you can see it it simple to wrap any async callbacks in promises but how are To use promises we need a mechanism that gets triggered as soon as a promise changes state. A promise includes a `then()` method which gets called if the state changes to _fulfilled_ and a `catch()` method that gets called if the state changes to _rejected_. ```javascript -const aPromise = getData('http://api.fixer.io/latest?base=GBP') +const aPromise = getData('https://api.exchangeratesapi.io/latest?base=GBP') aPromise.then( data => console.log(data)) @@ -194,7 +195,7 @@ If the state of the promise changes to _rejected_, the `catch()` method is calle This code can be written in a more concise way by _chaining_ the promise methods. ```javascript -getData('http://api.fixer.io/latest?base=GBP') +getData('https://api.exchangeratesapi.io/latest?base=GBP') .then( data => console.log(data)) .catch( err => console.error(`error: ${err.message}`)) ``` @@ -223,7 +224,7 @@ const exit = () => new Promise( () => { process.exit() }) -getData('http://api.fixer.io/latest?base=GBP') +getData('https://api.exchangeratesapi.io/latest?base=GBP') .then( data => printObject(data)) .then( () => exit()) .catch(err => console.error(`error: ${err.message}`)) @@ -238,7 +239,7 @@ Despite the code in the `printObject` promise being _synchronous_ it is better t If a promise only takes a single parameter and this matches the data passed back when the previous promise _fulfills_ there is a more concise way to write this. ```javascript -getData('http://api.fixer.io/latest?base=GBP') +getData('https://api.exchangeratesapi.io/latest?base=GBP') .then(printObject) .then(exit) .catch(err => console.error(`error: ${err.message}`)) @@ -249,7 +250,7 @@ getData('http://api.fixer.io/latest?base=GBP') There are some situations where you can't simply pass the output from one promise to the input of the next one. Sometimes you need to store data for use further down the promise chain. This can be achieved by storing the data in the `this` object. ```javascript -getData('http://api.fixer.io/latest?base=GBP') +getData('https://api.exchangeratesapi.io/latest?base=GBP') .then( data => this.jsonData = data) .then( () => printObject(this.jsonData)) .then(exit) @@ -265,9 +266,9 @@ Run the `promises.js` script. Its functionality should be familiar to the `curre Study the code carefully. Notice that it defines 5 promises and chains them together. You are going to extend the functionality by defining some additional promises and adding them to the promise chain. -1. modify the script to ask for the currency to convert to and display only the one conversion rate. -2. instead of printing the exchange rate, ask for the amount to be converted and them return the equivalent in the chosen currency -3. use the [OpenExchangeRates](https://openexchangerates.org/api/currencies.json) API to display the full name of the chosen currency +1. Modify the script to ask for the currency to convert to and display only the one conversion rate. +2. Instead of printing the exchange rate, ask for the amount to be converted and them return the equivalent in the chosen currency. +3. The `currencies.json` file contains a map between the currency code and the country name. Load this file into the script using the [`fs`](https://nodejs.org/api/fs.html) module, convert to a JavaScript object using the [`JSON`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON) object and use it to display the full name of the chosen currency. ### 6.5 Executing Code Concurrently @@ -290,7 +291,7 @@ const dataArray = ['USD', 'EUR'] const promiseArray = [] dataArray.forEach( curr => { promiseArray.push(new Promise( (resolve, reject) => { - const url = `http://api.fixer.io/latest?base=GBP&symbols=${curr}` + const url = `https://api.exchangeratesapi.io/latest?base=GBP&symbols=${curr}` request.get(url, (err, res, body) => { if (err) reject(new Error(`could not get conversion rate for ${curr}`)) resolve(body) @@ -356,7 +357,7 @@ const printObject = data => new Promise( resolve => { async function main() { try { - const data = await getData('http://api.fixer.io/latest?base=GBP') + const data = await getData('https://api.exchangeratesapi.io/latest?base=GBP') await printObject(data) process.exit() } catch (err) { @@ -395,8 +396,8 @@ both `printObjectPromise` and `printObjectAsync` behave in exactly the same mann Run the `asyncFunctions.js` script, located in the otherScripts folder. Note that it works in the same way as the previous ones. Open the script and study it carefully. -1. modify the script to ask for the currency to convert to and display only the one conversion rate. -2. instead of printing the exchange rate, ask for the amount to be converted and them return the equivalent in the chosen currency -3. use the [OpenExchangeRates](https://openexchangerates.org/api/currencies.json) API to display the full name of the chosen currency -4. rewrite the `printObject` promise as an _async function_. -5. rewrite another promise as an _async function_. +1. Modify the script to ask for the currency to convert to and display only the one conversion rate. +2. Instead of printing the exchange rate, ask for the amount to be converted and them return the equivalent in the chosen currency +3. The `currencies.json` file contains a map between the currency code and the country name. Load this file into the script using the [`fs`](https://nodejs.org/api/fs.html) module, convert to a JavaScript object using the [`JSON`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON) object and use it to display the full name of the chosen currency. +4. Rewrite the `printObject` promise as an _async function_. +5. Rewrite another promise as an _async function_. diff --git a/exercises/06_code_quality/promises.js b/exercises/06_code_quality/promises.js index 74c13396..64de978b 100644 --- a/exercises/06_code_quality/promises.js +++ b/exercises/06_code_quality/promises.js @@ -2,6 +2,7 @@ 'use strict' const request = require('request') +const baseURL = 'https://api.exchangeratesapi.io/latest' const getInput = prompt => new Promise( (resolve) => { process.stdin.resume() @@ -12,7 +13,7 @@ const getInput = prompt => new Promise( (resolve) => { const checkValidCurrencyCode = code => new Promise( (resolve, reject) => { code = code.trim() - request('http://api.fixer.io/latest', (err, res, body) => { + request(baseURL, (err, res, body) => { if (err) reject(new Error('invalid API call')) const rates = JSON.parse(body).rates if (!rates.hasOwnProperty(code)) reject(new Error(`invalid currency code ${code}`)) @@ -21,7 +22,7 @@ const checkValidCurrencyCode = code => new Promise( (resolve, reject) => { }) const getData = code => new Promise( (resolve, reject) => { - request(`http://api.fixer.io/latest?base=${code}`, (err, res, body) => { + request(`${baseURL}?base=${code}`, (err, res, body) => { if (err) reject(new Error('invalid API call')) resolve(body) }) From 7564ca2747dbe87e41bf7779853f4bba8809ebaa Mon Sep 17 00:00:00 2001 From: Mark Tyers Date: Wed, 9 Oct 2019 08:17:18 +0100 Subject: [PATCH 5/9] added async functions file --- exercises/06_code_quality/asyncFunctions.js | 51 +++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 exercises/06_code_quality/asyncFunctions.js diff --git a/exercises/06_code_quality/asyncFunctions.js b/exercises/06_code_quality/asyncFunctions.js new file mode 100644 index 00000000..6e483683 --- /dev/null +++ b/exercises/06_code_quality/asyncFunctions.js @@ -0,0 +1,51 @@ + +'use strict' + +const request = require('request') +const baseURL = 'https://api.exchangeratesapi.io/latest' + +async function main() { + try { + const base = await getInput('enter base currency') + await checkValidCurrencyCode(base) + const data = await getData(`${baseURL}?base=${base}`) + await printObject(data) + process.exit() + } catch (err) { + console.log(`error: ${err.message}`) + } +} + +const getInput = prompt => new Promise( (resolve) => { + process.stdin.resume() + process.stdin.setEncoding('utf8') + process.stdout.write(`${prompt}: `) + process.stdin.on('data', text => resolve(text)) +}) + +const checkValidCurrencyCode = code => new Promise( (resolve, reject) => { + code = code.trim() + request(baseURL, (err, res, body) => { + if (err) reject(new Error('invalid API call')) + const rates = JSON.parse(body).rates + if (!rates.hasOwnProperty(code)) it.throw(new Error(`invalid currency code ${code}`)) + resolve() + }) +}) + +const getData = url => new Promise( (resolve, reject) => { + request(url, (err, res, body) => { + if (err) reject(new Error('invalid API call')) + resolve(body) + }) +}) + +const printObject = data => new Promise( (resolve) => { + const indent = 2 + data = JSON.parse(data) + const str = JSON.stringify(data, null, indent) + console.log(str) + resolve() +}) + +main() From 053389aa39fb76e740172946b4a162f77a7f6e53 Mon Sep 17 00:00:00 2001 From: Mark Tyers Date: Wed, 9 Oct 2019 08:19:04 +0100 Subject: [PATCH 6/9] deleted old readme file --- exercises/06_code_quality/README.md | 8 -------- 1 file changed, 8 deletions(-) delete mode 100644 exercises/06_code_quality/README.md diff --git a/exercises/06_code_quality/README.md b/exercises/06_code_quality/README.md deleted file mode 100644 index 19df846d..00000000 --- a/exercises/06_code_quality/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Assignment Template - -This repository contains the base files for the assignment. To make use of this carry out the following steps: - -1. Fork this repository but change its name (replace `xxx` with your university username): - 1. If this is your original assignment, `xxx-coursework`. - 2. If this is your resit assignment code, `xxx-resit`. -2. Replace the contents of this file with the details of the topic you have been assigned. From d4ddbc764b44c5b03d239ffeb1216a9a998cb8e4 Mon Sep 17 00:00:00 2001 From: Mark Tyers Date: Wed, 9 Oct 2019 15:17:04 +0100 Subject: [PATCH 7/9] started mocking file system --- .../filesystem/modules/file.js | 35 +++++++++++++++++++ .../07_unit_testing/filesystem/package.json | 14 ++++++++ .../filesystem/unit tests/file.spec.js | 33 +++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 exercises/07_unit_testing/filesystem/modules/file.js create mode 100644 exercises/07_unit_testing/filesystem/package.json create mode 100644 exercises/07_unit_testing/filesystem/unit tests/file.spec.js diff --git a/exercises/07_unit_testing/filesystem/modules/file.js b/exercises/07_unit_testing/filesystem/modules/file.js new file mode 100644 index 00000000..ec5e4202 --- /dev/null +++ b/exercises/07_unit_testing/filesystem/modules/file.js @@ -0,0 +1,35 @@ + +'use strict' + +const fs = require('fs') + +module.exports = class File { + + constructor(name) { + return async() => { + this.filename = name + } + } + + async add(item, qty) { + fs.readFile(this.filename, 'utf8', (err, data) => { + if (err) throw new Error('file not found') + data = JSON.parse(data) + data.append({ item, qty }) + data = JSON.stringify(data) + fs.writeFile(this.filename, data, 'utf8', (err) => { + if(err) throw err + } ) + }) + } + + get records() { + return async() => { + fs.readFile(this.filename, 'utf8', (err, data) => { + if (err) throw new Error('file not found') + return JSON.parse(data) + }) + } + } + +} diff --git a/exercises/07_unit_testing/filesystem/package.json b/exercises/07_unit_testing/filesystem/package.json new file mode 100644 index 00000000..2cc74c64 --- /dev/null +++ b/exercises/07_unit_testing/filesystem/package.json @@ -0,0 +1,14 @@ +{ + "name": "filesystem", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "mock-fs": "^4.10.1" + } +} diff --git a/exercises/07_unit_testing/filesystem/unit tests/file.spec.js b/exercises/07_unit_testing/filesystem/unit tests/file.spec.js new file mode 100644 index 00000000..8bdf4f84 --- /dev/null +++ b/exercises/07_unit_testing/filesystem/unit tests/file.spec.js @@ -0,0 +1,33 @@ + +'use strict' + +const File = require('../modules/file.js') +const mock = require('mock-fs') + +beforeAll( async() => { + mock({ + 'data': { + 'test.json': '["item": "bread", "qty": 42]' + } + }) +}) + +describe('xxx', () => { + + beforeEach( async() => { + const file = new File() + }) + afterEach( async() => { + // runs after each test completes + }) + test('xxx', async done => { + expect.assertions(1) + try { + // XXX + } catch(err) { + // XXX + } finally { + done() + } + }) +}) From 87c1585d8dc97aa72724570a00de5e39e18f5365 Mon Sep 17 00:00:00 2001 From: Mark Tyers Date: Fri, 11 Oct 2019 09:14:30 +0100 Subject: [PATCH 8/9] fixed text input issue --- exercises/06_code_quality/asyncFunctions.js | 16 +++++++++++----- exercises/06_code_quality/package.json | 1 + exercises/06_code_quality/promises.js | 14 +++++++++----- 3 files changed, 21 insertions(+), 10 deletions(-) diff --git a/exercises/06_code_quality/asyncFunctions.js b/exercises/06_code_quality/asyncFunctions.js index 6e483683..35f1e2b4 100644 --- a/exercises/06_code_quality/asyncFunctions.js +++ b/exercises/06_code_quality/asyncFunctions.js @@ -2,6 +2,8 @@ 'use strict' const request = require('request') +const readline = require('readline') + const baseURL = 'https://api.exchangeratesapi.io/latest' async function main() { @@ -10,17 +12,21 @@ async function main() { await checkValidCurrencyCode(base) const data = await getData(`${baseURL}?base=${base}`) await printObject(data) + const to = await getInput('convert to') + console.log(to) process.exit() } catch (err) { console.log(`error: ${err.message}`) } } -const getInput = prompt => new Promise( (resolve) => { - process.stdin.resume() - process.stdin.setEncoding('utf8') - process.stdout.write(`${prompt}: `) - process.stdin.on('data', text => resolve(text)) +const getInput = prompt => new Promise(resolve => { + const read = readline.createInterface({ input: process.stdin, output: process.stdout }) + read.question(`${prompt}: `, value => { + console.log(`You entered ${value}`) + read.close() + resolve(value) + }) }) const checkValidCurrencyCode = code => new Promise( (resolve, reject) => { diff --git a/exercises/06_code_quality/package.json b/exercises/06_code_quality/package.json index a4821bce..6eb0a08d 100644 --- a/exercises/06_code_quality/package.json +++ b/exercises/06_code_quality/package.json @@ -34,6 +34,7 @@ "koa-static": "^5.0.0", "koa-views": "^6.1.5", "mime-types": "^2.1.22", + "readline": "^1.3.0", "readline-sync": "^1.4.10", "request": "^2.88.0", "sqlite-async": "^1.0.11" diff --git a/exercises/06_code_quality/promises.js b/exercises/06_code_quality/promises.js index 64de978b..30397aea 100644 --- a/exercises/06_code_quality/promises.js +++ b/exercises/06_code_quality/promises.js @@ -2,13 +2,17 @@ 'use strict' const request = require('request') +const readline = require('readline') + const baseURL = 'https://api.exchangeratesapi.io/latest' -const getInput = prompt => new Promise( (resolve) => { - process.stdin.resume() - process.stdin.setEncoding('utf8') - process.stdout.write(`${prompt}: `) - process.stdin.on('data', text => resolve(text)) +const getInput = prompt => new Promise(resolve => { + const read = readline.createInterface({ input: process.stdin, output: process.stdout }) + read.question(`${prompt}: `, value => { + console.log(`You entered ${value}`) + read.close() + resolve(value) + }) }) const checkValidCurrencyCode = code => new Promise( (resolve, reject) => { From 111e50081e594b741e9715acc073e5a9a1b3a34d Mon Sep 17 00:00:00 2001 From: "Mark Tyers (aa7401)" Date: Sat, 12 Oct 2019 07:53:17 +0100 Subject: [PATCH 9/9] Updated Git Installation Lab did not explain how to install git on different OS. Now covers how to install git on MacOS using either Xcode or HomeBrew. Covers apt command for Ubuntu and reminds not to install any GUI tools. --- 01 Setup.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/01 Setup.md b/01 Setup.md index a1a4e284..7f94b616 100644 --- a/01 Setup.md +++ b/01 Setup.md @@ -3,7 +3,9 @@ In this worksheet you will learn how to configure your work environment using VS Code. You should start by installing **Visual Studio Code** (NOT VISUAL STUDIO!) from the [website](https://code.visualstudio.com), note that it might already be installed. If you are using a Coventry University computer and the software is not installed you can do this using AppsAnywhere. -If you are using Windows 10 you will also need to install [Git](https://git-scm.com/download/win), this may already be installed on a Coventry University computer. +If you are using Windows 10 you will also need to install [Git](https://git-scm.com/download/win), this may already be installed on a Coventry University computer. If you are on MacOS you may already have it installed as it comes with the XCode IDE but if you have recently updated your OS you may need to run the `xcode-select --install` command to update the **Xcode Command-line Tools** but if you don't want to install XCode you can install git using [HomeBrew](http://brew.sh/) using the `brew install git` command. If you are running Ubuntu you can install it using the `sudo apt install git` command. + +DO NOT INSTALL THE GIT GUI TOOLS! Visual Studio Code comes with an integrated **Terminal** that can be used instead of the standard _Command Prompt_ or _Terminal_. If you are using Linux or MacOS this will give you a Bash prompt however on Windows 10 it defaults to the _Command Prompt_ and will need to be changed to the _Bash Shell_.