Okay, let's see what's the minimal configuration I can get set up and tested. I believe that would be "locate a config file". Here's what I have in mind:
- If no configuration file is provided, the program recurses up into parent directories until it locates it, with a default name.
- If an argument is provided, the program will not recurse upward; it will check the exact path given.
- If the path is a directory, it will look for the default name in that directory.
- If the path is a file, it will look for that exact file path.
(Since paths don't inherently have "directory-nature", I guess this means it needs to check whether the path exists before doing any specific logic to it.)
Test cases when the path is not given:
- Find the file in the directory
- Find the file in a parent directory
- Handle file not existing
Test cases when the path is given:
- File exists/does not exist
- (For the specific case of absolute+cousin, have a test for not cd-ing to a tmpdir first, as well as doing so)
To check when the file exists: that the current directory is the directory that contains the file. (This is fine to check even with the error case, because it's being set in-process, and will be cleaned up by the test finalizer.)
Error cases to handle when the file does exist:
- File is not syntactically valid
- File raises a runtime exception
- File does not produce configuration object
- Configuration object is not valid
I don't want to get as far as actually consuming the configuration object; that's an entire set of extra dimensions to deal with. And that up there is already plenty to mess around with.
I think I basically want execution to happen in phases:
- Parse command line (handled by Cement); do not inspect the filesystem at this point
- Resolve the configuration file
- Evaluate the configuration file
- (Update defaults from the configuration file. Not quite a thing to do, because I haven't yet planned config that would do anything)
- Check whether to list targets from configuration, exit early if so
- Determine which targets to include (this has no bearing on the target listing, so can be done after)
- Queue all targets via the runner - Runner updates progress bar or something
- Report successes, failures, and errors.
I'm trying to figure out the best order to work on this. In the first prototype, I focused on the core runner logic, and left the fine details of input and output to the wayside. I guess the first question I should ask is, does Cement have any opinions germane to this kind of structure? Let's see...
Not seeing anything from a kind of superficial look.
The last thing I want to work out tonight is how to only test the outer layers. I was imagining some fancy stuff, but as I think about it, I realize the answer is to just stub out the low-level logic with functions that always succeed. Anyway, when it comes time to test those, I want to either make the tests really fast, or restrict the scope of config file location shenanigans.
So, that's the kind of stuff that I'll want to test with the external interface. Good rubber-duck session. Not sure when I'll be good to start implementing these tests, but at least I have a solid foundation to start from.