2018-10-04 14:37:37 +01:00
---
id: 587d8249367417b2b2512c41
title: Metric-Imperial Converter
challengeType: 4
2019-08-05 09:17:33 -07:00
forumTopicId: 301570
2018-10-04 14:37:37 +01:00
---
## Description
< section id = 'description' >
2020-11-20 12:02:31 -08:00
Build a full stack JavaScript app that is functionally similar to this: < a href = "https://metric-imperial-converter.freecodecamp.rocks/" target = "_blank" > https://metric-imperial-converter.freecodecamp.rocks/< / a > . Working on this project will involve you writing your code using one of the following methods:
- Clone < a href = 'https://github.com/freeCodeCamp/boilerplate-project-metricimpconverter/' target = '_blank' > this GitHub repo</ a > and complete your project locally.
- Use < a href = 'https://repl.it/github/freeCodeCamp/boilerplate-project-metricimpconverter' target = '_blank' > our repl.it starter project</ a > to complete your project.
- Use a site builder of your choice to complete the project. Be sure to incorporate all the files from our GitHub repo.
When you are done, make sure a working demo of your project is hosted somewhere public. Then submit the URL to it in the `Solution Link` field. Optionally, also submit a link to your project's source code in the `GitHub Link` field.
2018-10-04 14:37:37 +01:00
< / section >
## Instructions
< section id = 'instructions' >
< / section >
## Tests
< section id = 'tests' >
```yml
tests:
2020-10-05 11:11:27 -07:00
- text: I can provide my own project, not the example URL.
testString: |
getUserInput => {
assert(!/.*\/metric-imperial-converter\.freecodecamp\.rocks/.test(getUserInput('url')));
}
2018-10-04 14:37:37 +01:00
- text: 'I can GET /api/convert with a single parameter containing an accepted number and unit and have it converted. (Hint: Split the input by looking for the index of the first character which will mark the start of the unit)'
2018-10-08 12:52:10 +01:00
testString: ''
2020-09-03 05:09:01 -04:00
- text: I can convert < code > 'gal'</ code > to < code > 'L'</ code > and vice versa. (1 gal to 3.78541 L)
testString: "async getUserInput => {
try {
const data1 = await $.get(getUserInput('url') + '/api/convert?input=1gal');
assert.equal(data1.returnNum, 3.78541);
2020-11-24 12:19:49 -08:00
assert.equal(data1.returnUnit, 'L');
2020-09-03 05:09:01 -04:00
const data2 = await $.get(getUserInput('url') + '/api/convert?input=10gal');
assert.equal(data2.returnNum, 37.8541);
2020-11-24 12:19:49 -08:00
assert.equal(data2.returnUnit, 'L');
2020-09-03 05:09:01 -04:00
const data3 = await $.get(getUserInput('url') + '/api/convert?input=1l');
assert.equal(data3.returnNum, 0.26417);
assert.equal(data3.returnUnit, 'gal');
const data4 = await $.get(getUserInput('url') + '/api/convert?input=10l');
assert.equal(data4.returnNum, 2.64172);
assert.equal(data4.returnUnit, 'gal');
} catch(xhr) {
2020-11-24 12:19:49 -08:00
throw new Error(xhr.responseText || xhr.message);
2020-09-03 05:09:01 -04:00
}
}
"
- text: I can convert < code > 'lbs'</ code > to < code > 'kg'</ code > and vice versa. (1 lbs to 0.453592 kg)
testString: "async getUserInput => {
try {
const data1 = await $.get(getUserInput('url') + '/api/convert?input=1lbs');
assert.equal(data1.returnNum, 0.45359);
assert.equal(data1.returnUnit, 'kg');
const data2 = await $.get(getUserInput('url') + '/api/convert?input=10lbs');
assert.equal(data2.returnNum, 4.53592);
assert.equal(data2.returnUnit, 'kg');
const data3 = await $.get(getUserInput('url') + '/api/convert?input=1kg');
assert.equal(data3.returnNum, 2.20462);
assert.equal(data3.returnUnit, 'lbs');
const data4 = await $.get(getUserInput('url') + '/api/convert?input=10kg');
assert.equal(data4.returnNum, 22.04624);
assert.equal(data4.returnUnit, 'lbs');
} catch(xhr) {
2020-11-24 12:19:49 -08:00
throw new Error(xhr.responseText || xhr.message);
2020-09-03 05:09:01 -04:00
}
}
"
- text: I can convert < code > 'mi'</ code > to < code > 'km'</ code > and vice versa. (1 mi to 1.60934 km)
testString: "async getUserInput => {
try {
const data1 = await $.get(getUserInput('url') + '/api/convert?input=1mi');
assert.equal(data1.returnNum, 1.60934);
assert.equal(data1.returnUnit, 'km');
const data2 = await $.get(getUserInput('url') + '/api/convert?input=10mi');
assert.equal(data2.returnNum, 16.0934);
assert.equal(data2.returnUnit, 'km');
const data3 = await $.get(getUserInput('url') + '/api/convert?input=1km');
assert.equal(data3.returnNum, 0.62137);
assert.equal(data3.returnUnit, 'mi');
const data4 = await $.get(getUserInput('url') + '/api/convert?input=10km');
assert.equal(data4.returnNum, 6.21373);
assert.equal(data4.returnUnit, 'mi');
} catch(xhr) {
2020-11-24 12:19:49 -08:00
throw new Error(xhr.responseText || xhr.message);
2020-09-03 05:09:01 -04:00
}
}
"
2020-11-24 12:19:49 -08:00
- text: All incoming units should be accepted in both upper and lower case, but should be returned in both the < code > initUnit</ code > and < code > returnUnit</ code > in lower case, except for liter, which should be represented as an uppercase < code > 'L'</ code > .
testString: "async getUserInput => {
try {
const data1 = await $.get(getUserInput('url') + '/api/convert?input=1gal');
assert.equal(data1.initUnit, 'gal');
assert.equal(data1.returnUnit, 'L');
const data2 = await $.get(getUserInput('url') + '/api/convert?input=10L');
assert.equal(data2.initUnit, 'L');
assert.equal(data2.returnUnit, 'gal');
const data3 = await $.get(getUserInput('url') + '/api/convert?input=1l');
assert.equal(data3.initUnit, 'L');
assert.equal(data3.returnUnit, 'gal');
const data4 = await $.get(getUserInput('url') + '/api/convert?input=10KM');
assert.equal(data4.initUnit, 'km');
assert.equal(data4.returnUnit, 'mi');
} catch(xhr) {
throw new Error(xhr.responseText || xhr.message);
}
}"
2020-09-03 05:09:01 -04:00
- text: If my unit of measurement is invalid, returned will be < code > 'invalid unit'</ code > .
testString: "async getUserInput => {
try {
const data = await $.get(getUserInput('url') + '/api/convert?input=1min');
2020-11-24 12:19:49 -08:00
assert(data.error === 'invalid unit' || data === 'invalid unit');
2020-09-03 05:09:01 -04:00
} catch(xhr) {
2020-11-24 12:19:49 -08:00
throw new Error(xhr.responseText || xhr.message);
2020-09-03 05:09:01 -04:00
}
}
"
2020-11-24 12:19:49 -08:00
- text: If my number is invalid, returned will be < code > 'invalid number'</ code > .
testString: "async getUserInput => {
try {
const data = await $.get(getUserInput('url') + '/api/convert?input=1//2gal');
assert(data.error === 'invalid number' || data === 'invalid number');
} catch(xhr) {
throw new Error(xhr.responseText || xhr.message);
}
}"
- text: If both the unit and number are invalid, returned will be < code > 'invalid number and unit'</ code > .
testString: "async getUserInput => {
try {
const data = await $.get(getUserInput('url') + '/api/convert?input=1//2min');
assert(data.error === 'invalid number and unit' || data === 'invalid number and unit');
} catch(xhr) {
throw new Error(xhr.responseText || xhr.message);
}
}"
2018-10-20 21:02:47 +03:00
- text: 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.
2020-11-24 12:19:49 -08:00
testString: "async getUserInput => {
try {
const data1 = await $.get(getUserInput('url') + '/api/convert?input=mi');
assert.approximately(data1.initNum, 1, 0.001);
assert.approximately(data1.returnNum, 1.60934, 0.001);
assert.equal(data1.returnUnit, 'km');
const data2 = await $.get(getUserInput('url') + '/api/convert?input=1/5mi');
assert.approximately(data2.initNum, 1/5, 0.1);
assert.approximately(data2.returnNum, 0.32187, 0.001);
assert.equal(data2.returnUnit, 'km');
const data3 = await $.get(getUserInput('url') + '/api/convert?input=1.5/7km');
assert.approximately(data3.initNum, 1.5/7, 0.001);
assert.approximately(data3.returnNum, 0.13315, 0.001);
assert.equal(data3.returnUnit, 'mi');
const data4 = await $.get(getUserInput('url') + '/api/convert?input=3/2.7km');
assert.approximately(data4.initNum, 3/2.7, 0.001);
assert.approximately(data4.returnNum, 0.69041, 0.001);
assert.equal(data4.returnUnit, 'mi');
} catch(err) {
throw new Error(err.responseText || err.message);
}
}
"
- text: My return will consist of the < code > initNum</ code > , < code > initUnit</ code > , < code > returnNum</ code > , < code > returnUnit</ code > , and < code > string</ code > spelling out units in the format < code > '{initNum} {initial_Units} converts to {returnNum} {return_Units}'</ code > with the result rounded to 5 decimals.
testString: "async getUserInput => {
try {
const data = await $.get(getUserInput('url') + '/api/convert?input=2mi');
assert.equal(data.initNum, 2);
assert.equal(data.initUnit, 'mi');
assert.approximately(data.returnNum, 3.21868, 0.001);
assert.equal(data.returnUnit, 'km', 'returnUnit did not match');
assert.equal(data.string, '2 miles converts to 3.21868 kilometers')
} catch(xhr) {
throw new Error(xhr.responseText || xhr.message);
}
}"
2018-10-04 14:37:37 +01:00
- text: All 16 unit tests are complete and passing.
2020-11-24 12:19:49 -08:00
testString: "async getUserInput => {
try {
const getTests = await $.get(getUserInput('url') + '/_api/get-tests' );
assert.isArray(getTests);
const unitTests = getTests.filter((test) => {
return !!test.context.match(/Unit Tests ->/ig);
});
assert.isAtLeast(unitTests.length, 16, 'At least 16 tests passed');
unitTests.forEach(test => {
assert.equal(test.state, 'passed', 'Tests in Passed State');
assert.isAtLeast(test.assertions.length, 1, 'At least one assertion per test');
});
} catch(err) {
throw new Error(err.responseText || err.message);
}
}"
2018-10-04 14:37:37 +01:00
- text: All 5 functional tests are complete and passing.
2020-11-24 12:19:49 -08:00
testString: "async getUserInput => {
try {
const getTests = await $.get(getUserInput('url') + '/_api/get-tests' );
assert.isArray(getTests);
const functTests = getTests.filter((test) => {
return !!test.context.match(/Functional Tests ->/ig);
});
assert.isAtLeast(functTests.length, 5, 'At least 5 tests passed');
functTests.forEach(test => {
assert.equal(test.state, 'passed', 'Tests in Passed State');
assert.isAtLeast(test.assertions.length, 1, 'At least one assertion per test');
});
} catch(err) {
throw new Error(err.responseText || err.message);
}
}"
2018-10-04 14:37:37 +01:00
```
< / section >
## Challenge Seed
< section id = 'challengeSeed' >
< / section >
## Solution
< section id = 'solution' >
```js
2019-10-14 21:00:42 +05:30
/**
Backend challenges don't need solutions,
because they would need to be tested against a full working project.
Please check our contributing guidelines to learn more.
*/
2018-10-04 14:37:37 +01:00
```
2019-07-18 08:24:12 -07:00
2018-10-04 14:37:37 +01:00
< / section >