How to test if a function mutates arguments in JavaScript

If you want to treat JavaScript as a functional language, an important thing to design you functions for is immutability. Some functional languages like Haskell and Clojure enforce this by making it part of the design of the language. However, JavaScript was designed in a multi-paradigm way.

A useful tool for this is the deepFreeze library. When called on an object or array, it will recursively go through the object and call Object.freeze on it each property.

Here is a simple example of how to use it:

const concat = (list, element) => {
  // list.push(element);
  return list.concat(element);
};

const testConcat = () => {
   const listBefore = [];
   const listAfter = [0];
  deepFreeze(listBefore);
   expect(
     concat(listBefore, 0)
   ).toEqual(listAfter);
};

As this snippet stands right now, testConcat would succeed with any exceptions. If you uncommented the first line of the concat function, it would fail since push is a mutating operation.

You can see it in action by using this JSFiddle I have prepared.