Use icecave/isolator to mock filesystem calls.  Fixes #7.

The tests were either using the real filesystem or were using the
somewhat unusual vfs stream wrapper that doesn't use "normal" filesystem
paths.  These tests were fragile and would not all work well on a
Windows environment.

Isolator provides an entry point for someone needing to override
behavior (in this case executability testing) and solves the testing
issue.  Tests now operate using realistic-looking paths without actually
relying on a filesystem (so that portability of the tests is high).

I don't want to add icecave/isolator as a dependency.  I want this to be
a fully decoupled package with no requirements on any other packages,
even something as light and anti-dependency as isolator.  Isolator
documentation itself defines usage patterns that would require adding
isolator as a dependency.  This pattern also means a potential
performance issue as all calls are forced to go through the isolator.

Instead, I allow the isolator reference to remain null.  When null, I
call the global function directly.  This means that Isolator does not
need to be a dependency and there is no method call overhead when not
using the isolator (the default usecase).  The major downside here is
that I don't test all the branches of code.  In order to still pass the
code coverage requirements I use ternary statements so that line
coverage is still 100%, but the null isolator is never tested.

I extracted the executable test logic into its own invokable class.
Handling the isolator logic in the Locator class wasn't very nice
looking, and making it a separate class makes it easy to override the
behavior and to isolate the tests.

Speaking of tests, I started using setUp to help reduce the boilerplate
in the tests.
Use assertNull(...) rather than assertSame(null, ...).