See Converting Numbers To Words Part I.
The next test will test 20-99. I think in real TDD, you’re supposed to write tests that test just one thing. But I’m not doing real TDD, so I’m testing in groups.
1 2 3 4 5 6 7 8 9 |
Sub TEST_Tens() Debug.Assert NumbersToWords(20) = "twenty" Debug.Assert NumbersToWords(21) = "twenty-one" Debug.Assert NumbersToWords(30) = "thirty" Debug.Assert NumbersToWords(77) = "seventy-seven" Debug.Assert NumbersToWords(99) = "ninety-nine" End Sub |
Again, I’m testing the edges and few in between. Now that I have two test procedures, I’ll need to create a procedure to run them both.
1 2 3 4 5 6 7 8 |
Sub TEST_All() TEST_Singles TEST_Tens Debug.Print "tests passed" End Sub |
Now I can run TEST_All and make sure I don’t break any previous tests with the changes I make. Of course, TEST_Tens fails so it’s time to write some code to make it pass. I tried to write the simplest code possible, but it didn’t work out for me.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Function NumbersToWords(ByVal dNumbers As Double) As String Dim vaSingles As Variant Dim vaTens As Variant Dim sReturn As String vaSingles = Split("zero,one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen", ",") vaTens = Split("NA,NA,twenty,thirty,forty,fifty,sixty,seventy,eighty,ninety", ",") If dNumbers > 19 Then sReturn = vaTens(dNumbers \ 10) & "-" & vaSingles(dNumbers - ((dNumbers \ 10) * 10)) Else sReturn = vaSingles(dNumbers) End If NumbersToWords = Trim$(sReturn) End Function |
That fails because NumbersToWords(20) returns twenty-zero. So there’s a special case that needs to be handled.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
Function NumbersToWords(ByVal dNumbers As Double) As String Dim vaSingles As Variant Dim vaTens As Variant Dim sReturn As String vaSingles = Split("zero,one,two,three,four,five,six,seven,eight,nine,ten,eleven,twelve,thirteen,fourteen,fifteen,sixteen,seventeen,eighteen,nineteen", ",") vaTens = Split("NA,NA,twenty,thirty,forty,fifty,sixty,seventy,eighty,ninety", ",") If dNumbers > 19 Then sReturn = vaTens(dNumbers \ 10) If dNumbers Mod 10 <> 0 Then sReturn = sReturn & "-" & vaSingles(dNumbers - ((dNumbers \ 10) * 10)) End If Else sReturn = vaSingles(dNumbers) End If NumbersToWords = Trim$(sReturn) End Function |
That works. But I can see this special case handling becoming a problem. Maybe. We’ll see what happens when we test in the hundreds.
Posting code? Use <pre> tags for VBA and <code> tags for inline.