Fix (Boilerplate): Add Event Parameter to test, Remove Infosec Requriements, Add Lowercase Requirement (#12)

* Fix missing event, correct example conversion

* Fix unit case

* Remove Infosec items, add lowercase requirement

* Convert to ES6, Update Packages, Fix display

* Applying @nhcarrigan's changes from site tests

* Removed unneeded mongodb ref

* Remove User Stories, Reformat README

* Apply suggestions from code review - Remove "Quality Assurance Project" Prefix

Co-authored-by: Shaun Hamilton <51722130+Sky020@users.noreply.github.com>

* Re-add the example text, clean up formatting

* Update Favicon

* Fix repo link, remove zombie.js

* Remove unused files, add sample.env

Co-authored-by: Shaun Hamilton <51722130+Sky020@users.noreply.github.com>
Co-authored-by: Rex Schrader <rex.schader@gmail.com>
This commit is contained in:
Rex Schrader 2020-11-25 07:09:04 -08:00 committed by GitHub
parent 14cd901870
commit 87ebc9c36a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 1085 additions and 1158 deletions

111
.bashrc
View File

@ -1,111 +0,0 @@
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth
# append to the history file, don't overwrite it
shopt -s histappend
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000
# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize
# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar
# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
debian_chroot=$(cat /etc/debian_chroot)
fi
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color|*-256color) color_prompt=yes;;
esac
# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
color_prompt=yes
else
color_prompt=
fi
fi
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@${PROJECT_NAME}\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u@${PROJECT_NAME}:\w\$ '
fi
unset color_prompt force_color_prompt
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
;;
*)
;;
esac
# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
#alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
fi
# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
# Add an "alert" alias for long running commands. Use like so:
# sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s
/[;&|]\s*alert$//'\'')"'
# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
export NVM_DIR="/home/nvm/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm

View File

@ -1,2 +0,0 @@
[core]
excludesfile = /etc/.gitignore-global

View File

@ -1,5 +0,0 @@
{"name":"drag-in-files.svg","date":"2016-10-22T16:17:49.954Z","url":"https://cdn.hyperdev.com/drag-in-files.svg","type":"image/svg","size":7646,"imageWidth":276,"imageHeight":276,"thumbnail":"https://cdn.hyperdev.com/drag-in-files.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(102, 153, 205)","uuid":"adSBq97hhhpFNUna"}
{"name":"click-me.svg","date":"2016-10-23T16:17:49.954Z","url":"https://cdn.hyperdev.com/click-me.svg","type":"image/svg","size":7116,"imageWidth":276,"imageHeight":276,"thumbnail":"https://cdn.hyperdev.com/click-me.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(243, 185, 186)","uuid":"adSBq97hhhpFNUnb"}
{"name":"paste-me.svg","date":"2016-10-24T16:17:49.954Z","url":"https://cdn.hyperdev.com/paste-me.svg","type":"image/svg","size":7242,"imageWidth":276,"imageHeight":276,"thumbnail":"https://cdn.hyperdev.com/paste-me.svg","thumbnailWidth":276,"thumbnailHeight":276,"dominantColor":"rgb(42, 179, 185)","uuid":"adSBq97hhhpFNUnc"}
{"name":"Screen Shot 2016-12-16 at 1.35.56 AM.png","date":"2016-12-16T06:36:32.934Z","url":"https://cdn.gomix.com/d7932c52-287f-4dae-b175-631fef453000%2FScreen%20Shot%202016-12-16%20at%201.35.56%20AM.png","type":"image/png","size":18223,"imageWidth":499,"imageHeight":80,"thumbnail":"https://cdn.gomix.com/d7932c52-287f-4dae-b175-631fef453000%2Fthumbnails%2FScreen%20Shot%202016-12-16%20at%201.35.56%20AM.png","thumbnailWidth":330,"thumbnailHeight":53,"dominantColor":"rgb(236,236,236)","uuid":"IHJDL7lzupnoDep4"}
{"uuid":"IHJDL7lzupnoDep4","deleted":true}

View File

@ -1,17 +0,0 @@
# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.
# see /usr/share/doc/bash/examples/startup-files for examples.
# the files are located in the bash-doc package.
# the default umask is set in /etc/profile; for setting the umask
# for ssh logins, install and configure the libpam-umask package.
#umask 022
# if running bash
if [ -n "$BASH_VERSION" ]; then
# include .bashrc if it exists
if [ -f "$HOME/.bashrc" ]; then
. "$HOME/.bashrc"
fi
fi
# set PATH so it includes user's private bin directories
PATH="$HOME/bin:$HOME/.local/bin:$HOME/node_modules/.bin:$PATH"

View File

@ -1,9 +1 @@
**FreeCodeCamp**- Information Security and Quality Assurance # [Metric-Imperial Converter](https://www.freecodecamp.org/learn/quality-assurance/quality-assurance-projects/metric-imperial-converter)
------
[![Run on Repl.it](https://repl.it/badge/github/freeCodeCamp/boilerplate-project-metricimpconverter)](https://repl.it/github/freeCodeCamp/boilerplate-project-metricimpconverter)
1) SET NODE_ENV to `test` without quotes
2) Most logic will need done in `controllers/convertHandler.js` but do complete `routes/api.js`
3) You will add any security features to `server.js`
4) You will create all of the functional/unit tests in `tests/2_functional-tests.js` and `tests/1_unit-tests.js`

View File

@ -28,18 +28,20 @@
function objParser(str, init) { function objParser(str, init) {
// finds objects, arrays, strings, and function arguments // finds objects, arrays, strings, and function arguments
// between parens, because they may contain ',' // between parens, because they may contain ','
var openSym = ['[', '{', '"', "'", '(']; let openSym = ['[', '{', '"', "'", '('];
var closeSym = [']', '}', '"', "'", ')']; let closeSym = [']', '}', '"', "'", ')'];
var type; let type;
for(var i = (init || 0); i < str.length; i++ ) { let i;
for(i = (init || 0); i < str.length; i++ ) {
type = openSym.indexOf(str[i]); type = openSym.indexOf(str[i]);
if( type !== -1) break; if( type !== -1) break;
} }
if (type === -1) return null; if (type === -1) return null;
var open = openSym[type]; let open = openSym[type];
var close = closeSym[type]; let close = closeSym[type];
var count = 1; let count = 1;
for(var k = i+1; k < str.length; k++) { let k;
for(k = i+1; k < str.length; k++) {
if(open === '"' || open === "'") { if(open === '"' || open === "'") {
if(str[k] === close) count--; if(str[k] === close) count--;
if(str[k] === '\\') k++; if(str[k] === '\\') k++;
@ -50,7 +52,7 @@ function objParser(str, init) {
if(count === 0) break; if(count === 0) break;
} }
if(count !== 0) return null; if(count !== 0) return null;
var obj = str.slice(i, k+1); let obj = str.slice(i, k+1);
return { return {
start : i, start : i,
end: k, end: k,
@ -60,9 +62,9 @@ function objParser(str, init) {
function replacer(str) { function replacer(str) {
// replace objects with a symbol ( __#n) // replace objects with a symbol ( __#n)
var obj; let obj;
var cnt = 0; let cnt = 0;
var data = []; let data = [];
while(obj = objParser(str)) { while(obj = objParser(str)) {
data[cnt] = obj.obj; data[cnt] = obj.obj;
str = str.substring(0, obj.start) + '__#' + cnt++ + str.substring(obj.end+1) str = str.substring(0, obj.start) + '__#' + cnt++ + str.substring(obj.end+1)
@ -75,10 +77,10 @@ function replacer(str) {
function splitter(str) { function splitter(str) {
// split on commas, then restore the objects // split on commas, then restore the objects
var strObj = replacer(str); let strObj = replacer(str);
var args = strObj.str.split(','); let args = strObj.str.split(',');
args = args.map(function(a){ args = args.map(function(a){
var m = a.match(/__#(\d+)/); let m = a.match(/__#(\d+)/);
while (m) { while (m) {
a = a.replace(/__#(\d+)/, strObj.dictionary[m[1]]); a = a.replace(/__#(\d+)/, strObj.dictionary[m[1]]);
m = a.match(/__#(\d+)/); m = a.match(/__#(\d+)/);
@ -100,23 +102,29 @@ function assertionAnalyser(body) {
// replace assertions bodies, so that they cannot // replace assertions bodies, so that they cannot
// contain the word 'assertion' // contain the word 'assertion'
var body = body.match(/(?:browser\s*\.\s*)?assert\s*\.\s*\w*\([\s\S]*\)/)[0]; let cleanedBody = body.match(/(?:browser\s*\.\s*)?assert\s*\.\s*\w*\([\s\S]*\)/)
var s = replacer(body); if(cleanedBody && Array.isArray(cleanedBody)) {
body = cleanedBody[0];
} else {
// No assertions present
return [];
}
let s = replacer(body);
// split on 'assertion' // split on 'assertion'
var splittedAssertions = s.str.split('assert'); let splittedAssertions = s.str.split('assert');
var assertions = splittedAssertions.slice(1); let assertions = splittedAssertions.slice(1);
// match the METHODS // match the METHODS
var assertionBodies = []; let assertionBodies = [];
var methods = assertions.map(function(a, i){ let methods = assertions.map(function(a, i){
var m = a.match(/^\s*\.\s*(\w+)__#(\d+)/); let m = a.match(/^\s*\.\s*(\w+)__#(\d+)/);
assertionBodies.push(parseInt(m[2])); assertionBodies.push(parseInt(m[2]));
var pre = splittedAssertions[i].match(/browser\s*\.\s*/) ? 'browser.' : ''; let pre = splittedAssertions[i].match(/browser\s*\.\s*/) ? 'browser.' : '';
return pre + m[1]; return pre + m[1];
}); });
if(methods.some(function(m){ return !m })) return "invalid assertion"; if(methods.some(function(m){ return !m })) return "invalid assertion";
// remove parens from the assertions bodies // remove parens from the assertions bodies
var bodies = assertionBodies.map(function(b){ let bodies = assertionBodies.map(function(b){
return s.dictionary[b].slice(1,-1).trim(); return s.dictionary[b].slice(1,-1).trim();
}); });
assertions = methods.map(function(m, i) { assertions = methods.map(function(m, i) {

View File

@ -9,25 +9,25 @@
function ConvertHandler() { function ConvertHandler() {
this.getNum = function(input) { this.getNum = function(input) {
var result; let result;
return result; return result;
}; };
this.getUnit = function(input) { this.getUnit = function(input) {
var result; let result;
return result; return result;
}; };
this.getReturnUnit = function(initUnit) { this.getReturnUnit = function(initUnit) {
var result; let result;
return result; return result;
}; };
this.spellOutUnit = function(unit) { this.spellOutUnit = function(unit) {
var result; let result;
return result; return result;
}; };
@ -36,13 +36,13 @@ function ConvertHandler() {
const galToL = 3.78541; const galToL = 3.78541;
const lbsToKg = 0.453592; const lbsToKg = 0.453592;
const miToKm = 1.60934; const miToKm = 1.60934;
var result; let result;
return result; return result;
}; };
this.getString = function(initNum, initUnit, returnNum, returnUnit) { this.getString = function(initNum, initUnit, returnNum, returnUnit) {
var result; let result;
return result; return result;
}; };

1826
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,35 +1,30 @@
{ {
"//1": "describes your app and its dependencies", "name": "fcc-imperial-metric-converter-boilerplate",
"//2": "https://docs.npmjs.com/files/package.json", "version": "1.0.0",
"//3": "updating this file will download and update your packages", "description": "Metric / Imperial Unit Converter",
"name": "my-hyperdev-app",
"version": "0.0.1",
"description": "What am I about?",
"main": "server.js", "main": "server.js",
"scripts": { "scripts": {
"start": "node server.js" "start": "node server.js"
}, },
"dependencies": { "dependencies": {
"express": "^4.14.0", "body-parser": "^1.19.0",
"cors": "^2.8.1", "chai": "^4.2.0",
"body-parser": "^1.15.2", "chai-http": "^4.3.0",
"chai": "^3.5.0", "cors": "^2.8.5",
"mongodb": "^2.2.16", "dotenv": "^8.2.0",
"chai-http": "^3.0.0", "express": "^4.17.1",
"mocha": "^3.2.0", "mocha": "^8.1.3"
"zombie": "^5.0.5",
"helmet": "^3.1.0"
}, },
"engines": { "engines": {
"node": "4.4.3" "node": "12.*"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://hyperdev.com/#!/project/welcome-project" "url": "https://github.com/freeCodeCamp/boilerplate-project-metricimpconverter"
}, },
"keywords": [ "keywords": [
"node", "node",
"hyperdev", "freeCodeCamp",
"express" "express"
], ],
"license": "MIT" "license": "MIT"

View File

@ -0,0 +1,7 @@
code {
background-color: whitesmoke;
}
section, header {
margin: 50px;
}

View File

@ -8,21 +8,21 @@
'use strict'; 'use strict';
var expect = require('chai').expect; const expect = require('chai').expect;
var ConvertHandler = require('../controllers/convertHandler.js'); const ConvertHandler = require('../controllers/convertHandler.js');
module.exports = function (app) { module.exports = function (app) {
var convertHandler = new ConvertHandler(); let convertHandler = new ConvertHandler();
app.route('/api/convert') app.route('/api/convert')
.get(function (req, res){ .get(function (req, res){
var input = req.query.input; let input = req.query.input;
var initNum = convertHandler.getNum(input); let initNum = convertHandler.getNum(input);
var initUnit = convertHandler.getUnit(input); let initUnit = convertHandler.getUnit(input);
var returnNum = convertHandler.convert(initNum, initUnit); let returnNum = convertHandler.convert(initNum, initUnit);
var returnUnit = convertHandler.getReturnUnit(initUnit); let returnUnit = convertHandler.getReturnUnit(initUnit);
var toString = convertHandler.getString(initNum, initUnit, returnNum, returnUnit); let toString = convertHandler.getString(initNum, initUnit, returnNum, returnUnit);
//res.json //res.json
}); });

View File

@ -27,9 +27,9 @@
'use strict'; 'use strict';
var cors = require('cors'); const cors = require('cors');
var fs = require('fs'); const fs = require('fs');
var runner = require('../test-runner'); const runner = require('../test-runner');
module.exports = function (app) { module.exports = function (app) {
@ -58,7 +58,7 @@ module.exports = function (app) {
}); });
}); });
var error; let error;
app.get('/_api/get-tests', cors(), function(req, res, next){ app.get('/_api/get-tests', cors(), function(req, res, next){
console.log(error); console.log(error);
if(!error && process.env.NODE_ENV === 'test') return next(); if(!error && process.env.NODE_ENV === 'test') return next();
@ -74,9 +74,9 @@ module.exports = function (app) {
}); });
}); });
app.get('/_api/app-info', function(req, res) { app.get('/_api/app-info', function(req, res) {
var hs = Object.keys(res._headers) let hs = Object.keys(res._headers)
.filter(h => !h.match(/^access-control-\w+/)); .filter(h => !h.match(/^access-control-\w+/));
var hObj = {}; let hObj = {};
hs.forEach(h => {hObj[h] = res._headers[h]}); hs.forEach(h => {hObj[h] = res._headers[h]});
delete res._headers['strict-transport-security']; delete res._headers['strict-transport-security'];
res.json({headers: hObj}); res.json({headers: hObj});
@ -85,7 +85,7 @@ module.exports = function (app) {
}; };
function testFilter(tests, type, n) { function testFilter(tests, type, n) {
var out; let out;
switch (type) { switch (type) {
case 'unit' : case 'unit' :
out = tests.filter(t => t.context.match('Unit Tests')); out = tests.filter(t => t.context.match('Unit Tests'));

2
sample.env Normal file
View File

@ -0,0 +1,2 @@
PORT=
NODE_ENV=test

View File

@ -1,15 +1,16 @@
'use strict'; 'use strict';
var express = require('express'); const express = require('express');
var bodyParser = require('body-parser'); const bodyParser = require('body-parser');
var expect = require('chai').expect; const expect = require('chai').expect;
var cors = require('cors'); const cors = require('cors');
require('dotenv').config();
var apiRoutes = require('./routes/api.js'); const apiRoutes = require('./routes/api.js');
var fccTestingRoutes = require('./routes/fcctesting.js'); const fccTestingRoutes = require('./routes/fcctesting.js');
var runner = require('./test-runner'); const runner = require('./test-runner');
var app = express(); let app = express();
app.use('/public', express.static(process.cwd() + '/public')); app.use('/public', express.static(process.cwd() + '/public'));
@ -46,7 +47,7 @@ app.listen(process.env.PORT || 3000, function () {
try { try {
runner.run(); runner.run();
} catch(e) { } catch(e) {
var error = e; let error = e;
console.log('Tests are not valid:'); console.log('Tests are not valid:');
console.log(error); console.log(error);
} }

View File

@ -25,15 +25,15 @@
* *
*/ */
var analyser = require('./assertion-analyser'); const analyser = require('./assertion-analyser');
var EventEmitter = require('events').EventEmitter; const EventEmitter = require('events').EventEmitter;
var Mocha = require('mocha'), const Mocha = require('mocha'),
fs = require('fs'), fs = require('fs'),
path = require('path'); path = require('path');
var mocha = new Mocha(); let mocha = new Mocha();
var testDir = './tests' let testDir = './tests'
// Add each .js file to the mocha instance // Add each .js file to the mocha instance
@ -47,21 +47,21 @@ fs.readdirSync(testDir).filter(function(file){
); );
}); });
var emitter = new EventEmitter(); let emitter = new EventEmitter();
emitter.run = function() { emitter.run = function() {
var tests = []; let tests = [];
var context = ""; let context = "";
var separator = ' -> '; let separator = ' -> ';
// Run the tests. // Run the tests.
try { try {
var runner = mocha.ui('tdd').run() let runner = mocha.ui('tdd').run()
.on('test end', function(test) { .on('test end', function(test) {
// remove comments // remove comments
var body = test.body.replace(/\/\/.*\n|\/\*.*\*\//g, ''); let body = test.body.replace(/\/\/.*\n|\/\*.*\*\//g, '');
// collapse spaces // collapse spaces
body = body.replace(/\s+/g,' '); body = body.replace(/\s+/g,' ');
var obj = { let obj = {
title: test.title, title: test.title,
context: context.slice(0, -separator.length), context: context.slice(0, -separator.length),
state: test.state, state: test.state,

View File

@ -6,18 +6,18 @@
* (if additional are added, keep them at the very end!) * (if additional are added, keep them at the very end!)
*/ */
var chai = require('chai'); const chai = require('chai');
var assert = chai.assert; let assert = chai.assert;
var ConvertHandler = require('../controllers/convertHandler.js'); const ConvertHandler = require('../controllers/convertHandler.js');
var convertHandler = new ConvertHandler(); let convertHandler = new ConvertHandler();
suite('Unit Tests', function(){ suite('Unit Tests', function(){
suite('Function convertHandler.getNum(input)', function() { suite('Function convertHandler.getNum(input)', function() {
test('Whole number input', function(done) { test('Whole number input', function(done) {
var input = '32L'; let input = '32L';
assert.equal(convertHandler.getNum(input),32); assert.equal(convertHandler.getNum(input),32);
done(); done();
}); });
@ -52,7 +52,7 @@ suite('Unit Tests', function(){
suite('Function convertHandler.getUnit(input)', function() { suite('Function convertHandler.getUnit(input)', function() {
test('For Each Valid Unit Inputs', function(done) { test('For Each Valid Unit Inputs', function(done) {
var input = ['gal','l','mi','km','lbs','kg','GAL','L','MI','KM','LBS','KG']; let input = ['gal','l','mi','km','lbs','kg','GAL','L','MI','KM','LBS','KG'];
input.forEach(function(ele) { input.forEach(function(ele) {
//assert //assert
}); });
@ -69,8 +69,8 @@ suite('Unit Tests', function(){
suite('Function convertHandler.getReturnUnit(initUnit)', function() { suite('Function convertHandler.getReturnUnit(initUnit)', function() {
test('For Each Valid Unit Inputs', function(done) { test('For Each Valid Unit Inputs', function(done) {
var input = ['gal','l','mi','km','lbs','kg']; let input = ['gal','l','mi','km','lbs','kg'];
var expect = ['l','gal','km','mi','kg','lbs']; let expect = ['L','gal','km','mi','kg','lbs'];
input.forEach(function(ele, i) { input.forEach(function(ele, i) {
assert.equal(convertHandler.getReturnUnit(ele), expect[i]); assert.equal(convertHandler.getReturnUnit(ele), expect[i]);
}); });
@ -91,8 +91,8 @@ suite('Unit Tests', function(){
suite('Function convertHandler.convert(num, unit)', function() { suite('Function convertHandler.convert(num, unit)', function() {
test('Gal to L', function(done) { test('Gal to L', function(done) {
var input = [5, 'gal']; let input = [5, 'gal'];
var expected = 18.9271; let expected = 18.9271;
assert.approximately(convertHandler.convert(input[0],input[1]),expected,0.1); //0.1 tolerance assert.approximately(convertHandler.convert(input[0],input[1]),expected,0.1); //0.1 tolerance
done(); done();
}); });

View File

@ -6,10 +6,10 @@
* (if additional are added, keep them at the very end!) * (if additional are added, keep them at the very end!)
*/ */
var chaiHttp = require('chai-http'); const chaiHttp = require('chai-http');
var chai = require('chai'); const chai = require('chai');
var assert = chai.assert; let assert = chai.assert;
var server = require('../server'); const server = require('../server');
chai.use(chaiHttp); chai.use(chaiHttp);
@ -26,7 +26,7 @@ suite('Functional Tests', function() {
.end(function(err, res){ .end(function(err, res){
assert.equal(res.status, 200); assert.equal(res.status, 200);
assert.equal(res.body.initNum, 10); assert.equal(res.body.initNum, 10);
assert.equal(res.body.initUnit, 'L'); assert.equal(res.body.initUnit, 'l');
assert.approximately(res.body.returnNum, 2.64172, 0.1); assert.approximately(res.body.returnNum, 2.64172, 0.1);
assert.equal(res.body.returnUnit, 'gal'); assert.equal(res.body.returnUnit, 'gal');
done(); done();

View File

@ -1,9 +1,9 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>Welcome to HyperDev!</title> <title>Metric/Imperial Converter</title>
<meta name="description" content="A cool thing made with HyperDev"> <meta name="description" content="An example of the Free Code Camp Metric/Imperial Converter Project">
<link id="favicon" rel="icon" href="https://hyperdev.com/favicon-app.ico" type="image/x-icon"> <link id="favicon" rel="icon" href="https://cdn.freecodecamp.org/universal/favicons/favicon-32x32.png" type="image/x-icon">
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
@ -11,47 +11,30 @@
</head> </head>
<body> <body>
<header> <header>
<h1> <h1>Metric/Imperial Converter</h1>
ISQA_2 - Metric/Imp Converter
</h1>
</header> </header>
<div id='userstories' style='margin-left: 5%; margin-top: 5%'> <hr style='margin: 50px'>
<h3>User Stories</h3> <section>
<ol> <h3>Example usage</h3>
<li>I will help prevent the client from trying to guess(sniff) the MIME type.</li>
<li>I will prevent cross-site scripting (XSS) attacks.</li>
<li>I can <b>GET</b> <code>/api/convert</code> with a single parameter containing an accepted number and unit and have it converted.</li>
<li>Hint: Split the input by looking for the index of the first character.</li>
<li>I can convert 'gal' to 'L' and vice versa. <b>(1 gal to 3.78541 L)</b></li>
<li>I can convert 'lbs' to 'kg' and vice versa. <b>(1 lbs to 0.453592 kg)</b></li>
<li>I can convert 'mi' to 'km' and vice versa. <b>(1 mi to 1.60934 km)</b></li>
<li>If my unit of measurement is invalid, returned will be 'invalid unit'.</li>
<li>If my number is invalid, returned with will 'invalid number'.</li>
<li>If both are invalid, return will be 'invalid number and unit'.</li>
<li>I can use fractions, decimals or both in my parameter(ie. 5, 1/2, 2.5/6), but if nothing is provided it will default to 1.</li>
<li>My return will consist of the initNum, initUnit, returnNum, returnUnit, and string spelling out units in format <code>{initNum} {initial_Units} converts to {returnNum} {return_Units}</code> with the result rounded to 5 decimals.</li>
<li>All 16 unit tests are complete and passing.</li>
<li>All 5 functional tests are complete and passing.</li>
</ol>
<h3>Example usage:</h3>
<code>/api/convert?input=4gal</code><br> <code>/api/convert?input=4gal</code><br>
<code>/api/convert?input=1/2km</code><br> <code>/api/convert?input=1/2km</code><br>
<code>/api/convert?input=5.4/3lbs</code><br> <code>/api/convert?input=5.4/3lbs</code><br>
<code>/api/convert?input=kg</code><br> <code>/api/convert?input=kg</code><br>
<h3>Example return:</h3> <h3>Example return</h3>
<code>{initNum: 3.1, initUnit: 'mi', returnNum: 5.0000008, returnUnit: 'km', string: '3.1 miles converts to 5.00002 kilometers'}</code> <code>{ initNum: 3.1, initUnit: 'mi', returnNum: 4.98895, returnUnit: 'km', string: '3.1 miles converts to 4.98895 kilometers' }</code>
</div> </section>
<hr style='margin: 50px'> <hr style='margin: 50px'>
<div id='testui' style='margin-left: 5%'> <section>
<h2 style="text-align: left">Front-End:</h2> <div id='testui' >
<form id="convertForm" class="border"> <h3 style="text-align: left">Front-End</h3>
<input type="text" id="convertField" name="input" placeholder="3.1mi" style="width: 200px"> <form id="convertForm" class="border">
<input id="convert" type="submit" value='Convert!'> <input type="text" id="convertField" name="input" placeholder="3.1mi" style="width: 200px">
</form> <input id="convert" type="submit" value='Convert!'>
<p id='result'></p> </form>
<code id='jsonResult'></code> <p id='result'></p>
</div> <code id='jsonResult'></code>
<hr style='margin: 50px; margin-top: 200px'> </div>
</section>
<!-- Your web-app is https, so your scripts need to be too --> <!-- Your web-app is https, so your scripts need to be too -->
<script src="https://code.jquery.com/jquery-2.2.1.min.js" <script src="https://code.jquery.com/jquery-2.2.1.min.js"
integrity="sha256-gvQgAFzTH6trSrAWoH1iPo9Xc96QxSZ3feW6kem+O00=" integrity="sha256-gvQgAFzTH6trSrAWoH1iPo9Xc96QxSZ3feW6kem+O00="