The final project
Picture a storekeeper with a notebook. Each line in it holds an item's name and the number of units on the shelves. When goods arrive, the storekeeper adds to the number on that line. When someone comes to take goods, the storekeeper first checks that there are enough units and only then subtracts. If there are not enough, the storekeeper refuses, and the notebook entry stays as it was.
A class in a real program usually rests on several ideas at once. It keeps data in a collection, changes it through methods and throws an error when an operation is impossible. The final exercise works the same way: it introduces no new constructs; you combine familiar ones.
The warehouse
The exercise is a warehouse that counts the units of each item. The class Inventory plays the storekeeper's notebook: it keeps the quantities. Its methods do four jobs:
addputs an item into the warehouse;taketakes an item out of the warehouse;countreports the quantity of an item;namesreturns the list of items.
A warehouse instance is created by the function createInventory, which the starter code already contains. In the closures theme, a factory was a function that creates closures. A factory can create objects too, and that is what createInventory does. The tests cannot see the class but can see a function declaration, so they call the factory, not new Inventory().
| Part of the exercise | What it needs |
|---|---|
| storage | a class field holding new Map() |
add and count | get and set of a Map, ?? |
take | a comparison, throw new RangeError(…) |
names | for…of, push, sort |
Keep the quantities in a Map, not in a plain object {}. An object has properties inherited from its prototype: {}["constructor"] is a function, not undefined. A new Map has no such keys, and get returns undefined for any unknown name.
This is where the notebook analogy ends. The lines in the notebook follow the order they were written in, but names must return the names in alphabetical order: your code does the sorting.
The take method
If there are not enough units, take throws a RangeError and leaves the quantity unchanged. So in the method, first check that there are enough units, and only then change the quantity. The storekeeper does the same: nothing is crossed out until the goods are known to be there.
The tests call take inside try…catch and check that the caught error is a RangeError. An item with no units left does not appear in the names list.
How to proceed
Work step by step:
- Start with the storage: without it, the other methods have nothing to work with.
- Write one method.
- Run the tests and move on to the next method.
Each test creates its own warehouse through createInventory(), so a failure in one test does not affect another.
Reading the test output
A test that passes prints a PASS line with its name. A test that fails prints FAIL with its name, and under it, what happened. This is how the starter code answers the first test:
FAIL test_add_and_count
add("apple", 5), add("apple", 3): count("apple") = -1, want 8Let's go through the second line:
- before the colon come the calls the test made beforehand;
- after the colon comes the call being checked;
- to the right of
=is what your code returned; - after
wantcomes the expected value.
Here -1 comes from the starter code: the count method is not written yet. The last line of the output shows how many tests passed and how many did not; for the starter code it is 0 passed, 8 failed.
After the course
This exercise completes the course. Large programs are split into files with ES modules and their import and export; they are not part of this course. Next, test yourself in the JavaScript interview simulator on this site. It asks questions on the same topics, from types and closures to classes, errors and promises, and grades your answers.
Key points
- The final exercise combines familiar constructs: a class, a
Map,throwandtry…catch. - The tests create a warehouse through the ready factory
createInventory, not throughnew Inventory(). - In
takethe check comes first and the change second: when units are short, the quantity stays the same. - The line under
FAILshows the test's calls, the value you returned and the expected one afterwant.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.