Let's try out our new test code. From the open... menu select Test Runner. Find FileListTest in the list, select it and click on the RUN button.
We can see that 7 tests were run and 6 passed. The test count looks correct since we just added one. And we know we have not written the actual method to do any work on FileList yet, so it's expected that our test failed. The bottom pane of TestRunner indicates that the failure was in our new test:
Click on that entry and Squeak fires up the debugger for us at the point of failure.
We should take a second here and discuss a "feature" of the Skins II package, if you installed it. Whenever a debugger is opened, the preference for automatic application of skins is turned off. This is done because a fault in the skins package itself could prohibit the debugger from working. If a bug is detected within the skins framework itself and if the preference for automatic application of skins is enabled, the debugger will generate recursive errors when it opens as it tries to skin it's own window. Hence, the preference gets disabled automatically. We just called up the debugger in our test run above, so you may have noticed that windows are no longer being skinned. You can open up the Preferences for skins and turn it back on since we know this bug is "safe".
Let's create the #copySelectedFileToDirectory: method on FileList but not have it do anything yet. SUnit should exercise our test code and show us that it didn't work as expected. I created the method in the "file list menu" category of the FileList class.
Open the TestRunner window again and select the FileListTest in the list pane. Click the "RUN" button on the right side of the TestRunner window.
7 tests were run and 1 failed. The failed test is in the list pane. Click on it to bring up the debugger. I selected the line before the "halt" in the debugger.
I kept stepping the debugger until I got to the #assert: statement after our call to the new non-functioning method.
Open a browser on FileList and select our #copySelectedFileToDirectory: method. One of the enhancements we installed earlier added a variables pane to the class browser. We can see that there are instance variables named "fileName" and "directory". With the argument passed to us of "aDirectory", we should be able to write some very straightforward code to copy our file.
Open up a second class browser and examine the FileDirectory class again. There's a method #copyFile:toFile: and #copyFileNamed:toFileNamed: to review. It looked as though the #copyFile:toFile: does what we want but it assumes we already have file streams open on the files. The #copyFileNamed:toFileNamed: method doesn't do exactly what we want either since (from the comments) it assumes that both files exist in the same directory. Looks like we will have to write a method on FileDirectory that does what we need.
I created this method in the "file operations" category of FileDirectory.
copyFileNamed: fileName toDirectory: aDirectory
"Copy the contents of the existing file into a directory."
| file1 file2 |
self = aDirectory ifTrue: [^ nil].
file1 := (self readOnlyFileNamed: fileName) binary.
file2 := (aDirectory newFileNamed: fileName) binary.
self copyFile: file1 toFile: file2.
directory copyFileNamed: fileName toDirectory: aDirectory
Continue on to the next page of second FileList enhancement.
Back to the beginning of this example.surface deep