Files
freeCodeCamp/curriculum/challenges/english/06-quality-assurance/quality-assurance-projects/metric-imperial-converter.md
Rex Schrader 79e3cb51e5 feat(learn): add/remove tests for Imperial-Metric Converter (#39615)
* Remove Infosoc Tests, Add tests, fix error reporting

* Add capital 'L' for liter requirement, check unit/funct test counts

* Apply suggestions from code review

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

* Apply suggestions from code review

Co-authored-by: Nicholas Carrigan <nhcarrigan@gmail.com>

* Apply suggestions from code review

Co-authored-by: Tom <20648924+moT01@users.noreply.github.com>

Co-authored-by: Shaun Hamilton <51722130+Sky020@users.noreply.github.com>
Co-authored-by: Nicholas Carrigan <nhcarrigan@gmail.com>
Co-authored-by: Tom <20648924+moT01@users.noreply.github.com>
2020-11-24 20:19:49 +00:00

11 KiB

id, title, challengeType, forumTopicId
id title challengeType forumTopicId
587d8249367417b2b2512c41 Metric-Imperial Converter 4 301570

Description

Build a full stack JavaScript app that is functionally similar to this: https://metric-imperial-converter.freecodecamp.rocks/. Working on this project will involve you writing your code using one of the following methods:
  • Clone this GitHub repo and complete your project locally.
  • Use our repl.it starter project 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.

Instructions

Tests

tests:
  - text: I can provide my own project, not the example URL.
    testString: |
      getUserInput => {
        assert(!/.*\/metric-imperial-converter\.freecodecamp\.rocks/.test(getUserInput('url')));
      }
  - 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)'
    testString: ''
  - 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);
        assert.equal(data1.returnUnit, 'L');
        const data2 = await $.get(getUserInput('url') + '/api/convert?input=10gal');
        assert.equal(data2.returnNum, 37.8541);
        assert.equal(data2.returnUnit, 'L');
        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) {
        throw new Error(xhr.responseText || xhr.message);
      }
    }
    "
  - 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) {
        throw new Error(xhr.responseText || xhr.message);
      }
    }
    "
  - 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) {
        throw new Error(xhr.responseText || xhr.message);
      }
    }
    "
  - 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);
      }
    }"
  - 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');
        assert(data.error === 'invalid unit' || data === 'invalid unit');
      } catch(xhr) {
        throw new Error(xhr.responseText || xhr.message);
      }
    }
    "
  - 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);
      }
    }"
  - 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.
    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);
      }
    }"
  - text: All 16 unit tests are complete and passing.
    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);
      }
    }"
  - text: All 5 functional tests are complete and passing.
    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);
      }
    }"

Challenge Seed

Solution

/**
  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.
*/