Mummifiers need a framework for testing conversion of actual files. This would involve at the least taking an existing file in a source directory and producing output in a target directory. Because it involves copying files, it should probably be classified as an integration test and run separately. This will help with some of the testing needed in GUISE-126.
The current idea is to have a base test that sets up a project as in MarkdownPageMummifierTest for example.
It would allow subclasses to provide files or directories to use to populate the source directory.
It would allow subclasses to specify certain configuration values to override the defaults.
Once this is put in place, the most basic tests for OpaqueFileMummifier can be added, for example, to show that the file was copied and has identical content.
Another very interesting library is Google's Jimfs, an in-memory implementation of a file system. (See also the Baeldung tutorial.) This would be very useful as the target for integration tests. In fact we could use it for both the source and the target as described in this ticket, as we were planning on prepopulating the source tree anyway—now we could just do it with an in-memory file system implementation.
A test MummyContext could create two Jifs file systems and then return root files in MummyContext.getSiteSourceDirectory(), MummyContext.getSiteTargetDirectory(), and MummyContext.getSiteDescriptionTargetDirectory(), which are what I believe kick things off.
This could be complementary to abstracting file system operations in the Artifact interface for finer-grained unit testing.
While we want to keep the number of integration tests from getting out of control, it would probably be useful to have at minimum a high-level sanity test that makes sure that a general tree layout of several types is being mummified to a the correct structure and types. This would be just to make sure the whole thing isn't broken.
So for example we might have:
Then we have to decide how to kick this off. Currently the CLI calls this:
That creates the MummyContext from the given GuiseProject during the LifeCyclePhase.INITIALIZE phase, and then manually performs planning during the LifeCyclePhase.PLAN phase. Because the LifeCyclePhase.INITIALIZE phase always happens (and must happen to initialize things), but because how initialization happens depends on the how things are kicked off (here from the CLI), we should probably have a separate GuiseMummy method that one could call if initialization has already happened:
Obviously the refactored method above would delegate to this method. And this method would require a life cycle phase of something greater than LifeCyclePhase.INITIALIZE. (Otherwise it would have nothing to do, and it's unclear the semantics of requesting a phase that has already been executed.) Thus the integration test could set up the context the way it saw fit and then mummification would call GuiseMummy.mummify(integrationTestContext, LifeCyclePhase.MUMMIFY. Likely we would instead have an abstract class mummify(@Nonnull final LifeCyclePhase phase) that would allow the actual integration tests to call mummify(LifeCyclePhase.MUMMIFY) and let the abstract test class call GuiseMummy with the test context. This might pave the way for integration tests of deployment and such later.
We may want to implement this ticket before starting on GUISE-147 as a sanity test just to see that image files are getting processed.
We may want to remove getDirectory() from the GuiseProject interface, although leaving it in some sort of default implementation (more likely a SourcePathGuiseProject or something). Currently it looks like we only use this in the CLI to log the project location. The CLI context initializes from this, but we want to have mummification function by pulling the directory from the context. So in tests we may set up a project with no directory whatsoever, and set up a context that gets its directory from Jimfs and not from the project at all.
This will be a good exercise in itself to abstract mummification from a source tree, allowing it to be used in a more abstract setting (e.g. in memory for some sort of CMS site generation).
Because the LifeCyclePhase.INITIALIZE phase always happens (and must happen to initialize things), but because how initialization happens depends on the how things are kicked off (here from the CLI), we should probably have a separate GuiseMummy method that one could call if initialization has already happened.
After getting back deep into this code, I'm not so sure about this. Part of the thing that initialization does is checks to see if there is a .guise-mummy.* configuration file in the site source directory. We could find a way to keep this from occurring, but why? Why is loading this config file any less part of the mummificiation than mummifying an actual file (which may also load e.g. sidecars and other config files.)
Creation of the project allows designation of a configuration file; this should be sufficient for tests. maybe we should just leave the original mummify(@Nonnull final GuiseProject project, @Nonnull final LifeCyclePhase phase) form and let it do what it's going to do.
I think one of the original goals was to get rid of the getDirectory() from the project, to remove file system references from the project level. This would be a step toward removing references to the file system from the entire infrastructure, using some plugin module for requesting content and working with paths. But we're a long ways from that, and it's not clear how yet how we would do that so we don't even know what we want at this stage. I think for the moment just leaving it like it is and allowing the integration tests to configure the project is good enough, since they will still need to configure some file system anyway.