The specs for `vector/_emptyvector`, `vector/_first`, and `vector/_last` all called `prop/for-all` within their 'check' functions, whereas the other specs all called it within their macros. This change makes the three specs mentioned more consistent with the rest of the specs by having them also call `prop/for-all` within their macros.
This introduces some fancy macro action that allows us to skip the four calls to `(concat-spec …)` with the different generators and types.
@ErikRauer and I wrestled with this for a _long_ time today, and it turned out that it was absolutely necessary to quote the generators in `gen-type-pairs on lines 10-13. I'm not 100% sure why, but it seems that without that something (perhaps a level of macro-ness) got unwrapped too early and then it couldn't find the generator because it had lost the namespace it belonged in.
Whether this actually _simplifies_ things is really up for debate. If this is as far as we get, it's probably not worth it. If we can find a reasonable way to reduce the other sources of duplication, however, it might be worth it?
Similar to `vector/_first`, this didn't check for the empty vector case, so I've changed it to return `:ignore-instruction` in that case.
There's a lot of duplication between `_first` and `_last`, which makes me think there's some refactoring opportunities.
This adds test.check tests for `vector/_last`. This is _really_ similar to `vector/_first` (and the other vector tests), so I think there are definitely ways to extract common logic from these.
The original version just used the built-in `first`, which returns `nil` if you give it an empty collection, which is almost certainly not a useful behavior.
This changes it to return `:ignore-instruction` if the vector is empty, thereby leaving all the stacks unchanged.
`make-instruction` will ignore any instructions that return `:ignore-instruction`. This allows instructions to be skipped without consuming their arguments.
There were two independent bugs in `vector/_subvec` that were turned up by our `test.check` testing.
The first was that the order of the arguments was wrong and `stop-raw` and `start-raw` were flipped.
The second was that `stop` wasn't max'ed with 0, which meant it could sometimes be negative, leading to an `IndexOutOfBoundsException`.
This is a start on using `test.check` to write tests for the vector instructions. We currently have tests for:
* `vector/_emptyvector`
* `vector/_indexof`
* `vector/_subvec`
There are _lots_ of other functions still to be tested.
This did reveal errors in `vector/_subvec`, which will be addressed in the next commit.
We used macros to make it easy to generate tests for each of the four vector types; this should be extensible to additional vector types in the future if needed.
The `random-int` function in both `number-io` and `smallest` subtracted a floating point value (`100.0`), which means they were both _actually_ returning a float instead of an int.
This removes both of the ".0"s so that they return integers as advertised.