Copyright © Cay S. Horstmann 2010-2015
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 United States License.
Modified by:
Get the lab2
from your buddy who worked on it last week.
Remember our goal -- we don't want to click through a file chooser when we are testing. Fortunately, the program will switch to a console UI if we specify the name of the file from the command line:
java -classpath /path/to/classes AddressBookDemo deptdir.txt
When main
starts, args[0]
is the first argument after the program name, i.e. deptdir.txt
.
If you've ever wondered what the String[] args
is good for in public static void main(String[] args)
, now you know. It is an array containing the command line arguments
How does the AddressBookDemo
program switch between GUI and console mode? Look in AddressBookDemo.java
java -classpath /path/to/classes AddressBookDemo
Again, replace the /path/to
with the actual path.
What happens? Why? (Click Cancel to stop the program)
Ok, we need to supply a file name if we want to specify the file on the command line.
java -classpath /path/to/classes AddressBookDemo deptdir.txt
What happens?
For now, type option 5.
Run the program from the console again (with two keystrokes ☺)
Select option 2, then enter the name Horstmann
and the key Phone
Then select option 5 to quit:
1: Add/Change Entry 2: Look Up Entry 3: Remove Entry 4: Save Directory 5: Exit Enter command: 2 Enter name: Horstmann Enter key: Phone Value: (408) 924-5085 1: Add/Change Entry 2: Look Up Entry 3: Remove Entry 4: Save Directory 5: Exit Enter command: 5
Now we don't even want to type the inputs! Using Emacs, make a file input.txt
(Click File → Visit New File
) containing the four lines
2 Horstmann Phone 5
Put in the four lines, save the file in your home directory, and quit the text editor. Now run
java -classpath /path/to/classes AddressBookDemo deptdir.txt < input.txt
As always, remember to hit ↑ and just add the < input.txt
to the end of the command line.
What happens? Can find the phone number?
The <
symbol means “read keystrokes from a file”, or, more formally “redirect System.in
to a file”.
Now edit input.txt
to add a lookup for Diaz
.
What is the content of input.txt
now?
What happens when you run the program with this input.txt
?
Now we are ready to do some serious test automation. We want to test that adding an entry works correctly. Here is the plan:
What input.txt
file tests this scenario?
Now let's capture the output. Run this command.
java -classpath /path/to/classes AddressBookDemo deptdir.txt < input.txt > output.txt
Remember to hit ↑ and just add the > output.txt
to the end of the command line...
What is the contents of output.txt
? How do you know?
Another way of checking contents of a file is the cat
command. Type
cat output.txt
What happens?
Here is a good reason for saving the output. It often happens that you make a change to a program, and you want to run a test case again to check that it still works. Save the output file
cp -v output.txt expected.txt.
What is the contents of expected.txt
? How did you check it?
Run the program again and capture its output in output.txt
. Then compare the two:
diff output.txt expected.txt
The diff
command compares two files and prints their differences. If there aren't any, it prints nothing.
Run the AddressBookDemo
program, and the diff
command as described. What happens? Why?
Change input.txt
by adding a 4
before the last line, i.e.
... 2 Diaz Phone 4 5
With the new input.txt
, run the AddressBookDemo
program and the diff
command as described. Then do it again. What happens? Why?
We'll do more test automation when we implement removal in the next lab.
For each of these commands, give a one-sentence description what they do: ls
, pwd
, cp
, cat
, diff
.
if (x > y) { y = x; }
is actually
if (x > y) { \ty=x; }
where \t
denotes a tab.
When the file is displayed, the tab is shown as some number of spaces. How many spaces? That's the problem—nobody agrees. Eclipse thinks it should be 4. Windows Notepad thinks it should be 8.
Here is how you can see the tabs. Load the file into Emacs and type
Alt-X hexl-mode Enter
That is, first type Alt-X. [You might need to hit the esc (escape) key, and then x, for Alt-X. You can hit-and-release the esc key, and then hit lower-case x.]
The text will appear in the status line at the bottom of the window. Once you have gotten to the status line, type the 9 character string hexl-mode there, and then hit Enter.
Never seen one of these? Congratulations, you've reached level 3.
You are seeing the hexadecimal encoding of each byte in the file. To the right, you see the characters, and if you look carefully as you move the arrow keys, you can see how they correspond.
For example, move the cursor on the lowercase b in public
on the right hand side. In the hex display, you will see 62
. That's the code for b.
What is the code for lowercase c? How do you know?
Look for spaces (with code 20
) and tabs (with code 09
). What is the first line of code in which you see each?
In the right panel on the left side, check Enable project specific settings, then click the New... button to create a new profile. Name it SJSU.
Choose Indentation tab, Set Tab policy to Whitespace only
How do you turn off tabs in Emacs? Hint: Look into your ~/.emacs
file.
Don't use tabs. There is no advantage and only pain. I am not the only one who thinks this. Some people say that you should only use tabs and never spaces. In theory, that would work—it's the mixture of tabs and spaces that causes the problem. But how confident are you that you and your collaborators won't ever mix them? BTW, I didn't say “Don't use the Tab key”. The Tab key is fine. Just tell your editor to insert spaces when you press it.
If you click the Braces tab in the Formatter, you can tell Eclipse to align the braces vertically. That is the style you see in the textbook. I suggest setting all except the last two to Next line.
0A
. In Windows, however, two characters are expected: a "carriage return" with code 0D
and then a newline OA
.
What's a carriage return?
Remember these? Maybe not.
In the olden days when dinosaurs roamed the earth, you had to move the "carriage" back to the left of the paper, and then advance the paper one line. Or, you could not advance the paper and print over the same line multiple times, for example to style='text-decoration: line-through;' strike out
characters.
Just in case you ever need to run Windows on a typewriter, every line must end with 0D 0A
. It is totally useless and a major pain, but it is the Windows way.
Look at ExhibitB.txt in hexl-mode. What do you see at the end of each line?
And they are not the only culprit. Download this file (ExhibitC.txt) and remember where you put it. Now look at it in hexl-mode. This file was created in Notepad. What do you see at the end of each line?
sh /path/to/ExhibitC.txt
What happens?
0D
that it doesn't expect. You'd think that it could figure out how to ignore them, but it doesn't.
To fix this, run
dos2unix /path/to/ExhibitC.txt
DOS is the precursor to Windows.
Your system might have you install dos2unix before you can run it. If so, on the command line in the virtual machine, enter:
sudo apt-get install dos2unix
Now look at the file in hexl-mode again. (Close the old one and reload it.)
What happens?
sh /path/to/ExhibitC.txt
What happens? Why does it work now?
Always use Unix-style line endings. The Emacs configuration that I gave you takes care of that. And don't use Notepad.
ExhibitB.txt
so that Notepad won't choke?What is the UTF-8 encoding for é? (Hint: it is 2 bytes)
What is the ISO 8859-1 encoding for é? (Just one byte this time)
cat ExhibitD.txt cat ExhibitE.txt
Which one looks correct? (This depends entirely on how your system is configured.)
Always use UTF-8 for your files unless you have an ironclad reason not to do so. (“I didn't know” isn't such a reason.) The Emacs configuration that I gave you makes UTF-8. When you read a file in a Java program, always open the scanner with UTF-8: new Scanner(file, "UTF-8")
. Otherwise, your program will use the character encoding of the grader's operating system, and you don't know what that is.
import java.util.*; public class Test1 { public static void main(String[] args) { Scanner in = new Scanner(System.in); String line = in.nextLine(); if (line.startsWith(args[0])) System.out.println("match"); else System.out.println("no match"); } }
What do you expect to happen when you run
java Test Bahrain < test1.out
test1.out
, the program will run and print something.)test1.out
file in Emacs with hexl-mode. What are the first five bytes?xxxx xxxx | xxxx xxxx <-byte1-> <-byte0->
There are two possible ways of saving these two bytes in a file
Which one do you think is more reasonable?
Why does that help with reading a file with a 16-bit encoding?
Test.java
so that the last line reads:
System.out.printf("no match: %x\n" , Integer.valueOf(line.charAt(0)));
Run
java Test Bahrain < test1.out
again. What happens?
Scanner
class?