In this section we’re building up the components of the previous section into a system with a generic interface. This system will be gradually altered over the course of 2.5, but its core functionality will remain the same. As we’ll see, the interface will largely be unchanged as well. This means that our tests can be re-used, or will only require slight alterations, even as we change the underlying system.
The tests for this section use a simple testing system that I wrote, as detailed in the previous post. The definitions and tests in a separate file. You can use it with the exercises just by including it in your library directory (or however you choose to organize your files) and replace the file name at the top of the exercises file. If you want a better understanding of how these tests function, refer to the previous post.
In order to demonstrate the advantage of using lambdas for the test functions, I have left in a comparison of what happens if only the
check functions are used. This is done for Exercise 2.79. When we try to do something that the system can’t handle (in this case, comparing a ‘regular’ Scheme number with a rational number), an error occurs. With the
test functions, the error is still indicated but the program can continue. Those
check functions in the file will need to be commented out or deleted, as our system cannot make this sort of comparison [yet].
If you take a look at the test file for the arithmetic system, you can see that we’re reaping the benefits of the generic interface by using the same set of tests for multiple types of numbers. There’s a test for basic arithmetic properties that is called in this fashion:
Essentially we give it what we’ve defined as ‘zero’, ‘one’, and two different non-zero numbers, along with the inverses for one of the numbers (i.e. its negative value and reciprocal value). By using arguments of the appropriate type, we’re able to apply these tests to any new number type we add to the system. Even as we change the implementation or add features in the coming sections, this set of tests will remain useful to ensure that the number type still satisfies some simple conditions. Because these are a full set of tests, that also means that until we’ve fully implemented the arithmetic system, some of the tests will raise errors. Luckily, our test framework can handle this and continue past them.
There are also a few tests that may be optional, as they cover aspects not specifically required of the system. Depending on what you think of as appropriate behavior to define, those tests can be included, altered, or ignored.
Finally, there is a noted flaw in the complex number implementation as written. It should be easy enough to fix, however. As an extra exercise, you may try to write some tests to cover the specific problem exhibited.
See the previous post for the required testing files.