gmrchk/cli-testing-library

BUG: need clarity and/or flexibility around filesystem paths

vassudanagunta opened this issue · 0 comments

I'm considering using your library because i like its notion of a sandboxed filesystem for testing and the ability to clean it up. I also prefer the simplicity over cli-testing-tool . But I hesitate as this tool doesn't seem to have any users or Issue activity. But someone's got to be first, so here I am!

The documentation say cli-testing-library creates an "enclosed" temporary filesystem, and describes an API for querying/manipulating files/directories within it. The docs also imply that all paths used in tests are within (relative to) this sandbox. This is not entirely true: obviously the path to the command being tested (e.g. ./my-cli.js --help in your examples). I was also able to confirm that path arguments on the command line are treated the same as the command path: they are relative where the command that invokes the tests runs from.

But I have a CLI command that has both input path and an output path args. To test this command, I need it the input path to point to pre-existing test input files, but the output path to point to the sandbox filesystem so the test output can be cleaned up. I was able to achieve this as follows:

it('command with input path and output path args', async () => {
    const { execute, path, readFile, exists, ls, cleanup } = await prepareEnvironment()
    const { code, stdout, stderr } = await execute(
        'node',
        `./bin/cli.js ./test/data/set1 ${path}/subdir`
    )
    // validate the output using readFile, exists, ls...
    await cleanup();
});

Questions

  1. Is my approach the intended way to do this?
  2. How do I access files outside the sandbox within the test but not on the command line? The documentation says readFile will not allow it. Do I just use Node fs directly to do that? See question 4 below.
  3. When I don't prepend paths on the command line with ./ or ../, I get errors that it is a bad path with a message such as:
    Error: Cannot find module '{{base}}/bin/cli.js'
    
    Is this error a bug? I would assume that {{base}} stands for the path from which the test is executed, i.e. the same as ./. But then why the error? I've also seen a valid path that showed up in an error message prepended with {{homedir}}. If I correctly understand the intent of these symbolic path prefixes, then '{{base}}/bin/cli.js' should have resolved to a valid path, and not result in an error?
  4. I didn't have time to test it, especially since tests against my actual file system make me nervous, but can the user use these symbols themselves when providing path arguments to cli-testing-library functions? Is there symbolic prefix for sandbox paths? For example, can I use {{base}}/test/data to reference existing files for test input, and then {{sandbox}}/output.data to reference output?
  5. I haven't tested this, but I don't think the temp directory created by cli-testing-library is a true sandbox, as i probably can append /.. to it to navigate outside it. Is this true? Would you consider adding code to prevent it? My own code implements a filesystem sandbox for other reasons, so I know it is very doable.

I tried to figure out the answers to the questions looking at the source, but it was taking a lot of time and I also decided that it is better that I ask you because:

  1. It needs to be documented, so that people can use your library efficiently and correctly, and also so they can evaluate your library without reading all of the source code.
  2. It's important to make it clear cli-testing-library's model or philosophy around this, especially since the sandbox is its primary selling point from what I can tell.