inventables / check

Ergonomic assertion library
7 stars 0 forks source link

Comparison functions don't close local variables #1

Open nevernormal1 opened 6 years ago

nevernormal1 commented 6 years ago

If you have a block like this:

const FOO = "BAR";
check(thing, function(thing) {
  thing == FOO;
});

You'll get an error that FOO is not defined. This can make it awkward to refer to constants or other useful local variables inside check tests.

Note: I've shown the FOO variable being very close to the comparison function, but it would probably be higher up (at the top of the file or in a beforeEach block) in a real example.

rodovich commented 6 years ago

This is a result of the check function rewriting the provided function to a sequence of assertions.

AFAIK there's no way in JS (even node) to list local variables programmatically or access them by name, so I think this might require making Check operate on test files at a higher level.

One approach would be to make Check less test-runner-agnostic and make check calls able to contain test runner blocks like describe, beforeEach, and it blocks, but only rewrite the code inside the it blocks into assertions:

check(function() {
  describe('MyClass', function() {
    describe('myMethod', function() {
      const FOO = 'FOO'
      let instance
      beforeEach(function() {
        instance = new MyClass()
      })

      it('returns FOO', function() {
        instance.myMethod() === FOO
      })
    })
  })
})

could produce something like

describe('MyClass', function() {
  describe('myMethod', function() {
    // lines outside of `it` were not rewritten
    const FOO = 'FOO'
    let instance
    beforeEach(function() {
      instance = new MyClass()
    })

    it('returns FOO', function() {
      // lines inside `it` were rewritten to assertions
      let result = instance.myMethod();
      assert(result === FOO,
        "Expected `instance.myMethod() === FOO`. " +
        "Got `instance.myMethod()`: " + JSON.stringify(result) + ".")
    })
  })
})

A second approach would be to make Check preprocess the entire test file and find & rewrite individual assert calls to add descriptive failure messages. This might be a little cleaner conceptually compared to the current approach.