Rewrite TestTree traversal explicitly

The `TestTree` is filtered using a custom traversal now, rather than a
`TreeFold`. This gives better guarantees that the `TestTree` is only
reduced and that nodes (such as `WithResources`) continue to work. The
resulting filtered `TestTree` now has the same shape as the original
tree, but filtered tests are transformed into `TestGroup`s with no
tests.  This is a fairly major change to how the filtering is performed,
so this is a new major release, and previous versions are now considered
deprecated.