Search code examples
javascriptdecorator-chaining

Chaining member variables with side-effect with the chain not ending in a function


In the JavaScript chaijs testing library it is possible to chain members like this:

pm.expect (entry.NAME).to.be.a('string').that.is.not.empty;

This question is not about the testing library, but about the library's internal technique. I understand it works something like this: pm.expect is a function that returns an object that contains at least { to: { be: { a } } } where a is another function that returns at least { that: { is: { not: { empty } } } }.

The interesting thing is that empty apparently is not a function. If it was, I would have to call it like this: that.is.not.empty() (note the parentheses). So the chain ends with a member variable that is not a function.

How is it possible in JavaScript to consume that member variable to cause a side-effect? Can you show me a minimal JS snippet that allows me to end an expression with something that is not a function call (like empty;) and still act like it was a function call?


Solution

  •   function expect(value) {
          return {
             get empty() { return !value.length; },
          };
      }
    
     expect("test").empty // false
     expect("").empty // true
    

    That's done with a getter, have a look at the ChaiJS sourcecode.