At the end of Part 2 I had barely working tests for the core logic of the kata.
Referring back to the original Birthday Greetings Kata, it’s clear that
Employees know about more than just their birth date.
So, let’s get populating those extra fields.
Object subclass: Employee [ <comment: 'I represent an Employee in the Kata.'> <category: 'BirthdayKata'> | birthDate firstName lastName email |
Expanding the set of instance variables is the first stage…
Updating the initialization
Employee class >> newBirthdate: aDate firstName: aFirstname lastName: aLastname email: anEmail [ "Answer a new instance of the receiver." <category: 'basic'> ^self basicNew initBirthdate: aDate firstName: aFirstname lastName: aLastname email: anEmail ] initBirthdate: aDate firstName: aFirstname lastName: aLastname email: anEmail [ "Initialize the receiver." <category: 'private-initialization'> birthDate := aDate. firstName := aFirstname. lastName := aLastname. email := anEmail. ]
This simplifies the construction of the
Employee class a bit.
Refactoring the tests
There was a bit of repetition in the instantiation of the
Employee in the
tests, this can easily be refactored to a factory method.
testIsBirthdayWhenDateIsBirthday [ <category: 'tests'> | e today birthDate | birthDate := Date newDay: 14 month: #Feb year: 1990. today := Date newDay: 14 month: #Feb year: 2019. e := self newEmployee: birthDate. self assert: (e isBirthday: today) ] newEmployee: aBirthdate [ ^Employee newBirthdate: aBirthdate firstName: 'John' lastName: 'Smith' email: 'firstname.lastname@example.org'. ]
Updating the console representation
With the new fields, I need to update the
printOn: stream [ <category: 'printing'> super printOn: stream. stream nextPutAll: ' '; nextPutAll: firstName; nextPutAll: ' '; nextPutAll: lastName; nextPutAll: ' born on '; print: birthDate; nextPutAll: ' with email '; nextPutAll: email ]
There’s some subtlety going on here,
nextPutAll: iterates over the things that
it’s putting on to the stream, for strings, that’s fine, they are series of
characters, but for
birthDate it’s not so simple, it’s not a string, by
print: on the stream, with the
birthDate, it delegates to
Date class, and provides the stream, this makes the
display itself in a nice human-readable mannner.
$ gst GNU Smalltalk ready st> FileStream fileIn: 'Employee.st'. FileStream st> birthDate:= Date newDay: 26 month: #Jul year: 1956. 26-Jul-1956. st> Employee newBirthdate: birthDate firstName: 'John' lastName: 'Smith' email: 'email@example.com'. an Employee John Smith born on 26-Jul-1956 with email firstname.lastname@example.org
Why not use print: on all lines?
print: is used to provide a printable represententation, which for strings means that they come out with
' wrapped around them, which we don’t want for the other parts.
an Employee' ''John'' ''Smith'' born on '26-Jul-1956' with email ''email@example.com'
Next: reading and parsing
Employees from the sample CSV data file.