The Tokenizer converts a whole expression into an array of tokens. Now we’ll convert it to an Enumerator.
Convert Tokenizer to Enumerator
We are going to convert this in place while maintaining the tests.
Add Required Interfaces
Add the interfaces to the class:
Run your tests. They fail due to missing required methods.
Add each of the following methods stubbed out to get our existing tests running again:
Run your tests, they now should be back to passing.
Next, we’ll add a new test that uses the Tokenizer as an iterator and get it passing.
Add only the first test to keep this as simple as possible:
Now write just enough of the interface method to get this test passing:
There are a few things to note in this first version:
We used a constructor in the new test that takes in the expression and stores it. Adding a constructor taking a single argument will make PowerShell remove the default no-argument constructor. To keep the tests passing, we add in an empty no-argument constructor as well as a one-agument constructor. We’re migrating this code so this is an intermediate form. When we’ve finished converting this from its original form to an enumerator, it will no longer need the no-argument constructor.
The property get_Current needs something to return. That’s what $this.currentExpression is. It’s assigned in the one-argument constructor. That’s fine for now. As we add more tests, this will change.
Run your tests, they should pass.
Now, we copy the second test case and work on getting it to pass as well:
Run your tests, they fail:
Here are a few changes to make that work. Notice that some of this code is copied from the interpret method.
Run your tests, they should all pass.
Add the next test:
Run your tests, they all pass.
Add all of the remaining tests:
The only test failing deals with spaces in the expression:
Add the missing line into MoveNext (right before the foreach):
Run your tests, and all tests pass.
Now we can remove the first test and the original methods:
Also, remove the old code from the Tokenizer:
Notice that we have no tests for Reset? It is required to get the code to run but we don’t use it in a test. Time to add a missing test and write its implementation.
Add one final test:
Run the test, it fails:
Update Tokenizer to store the original expression in the constructor and implement the reset method.
Comments