The goal of this lab is to practice object-oriented design on a problem that will help you review the object-oriented features of Java and prepare for an exploration of object-oriented design techniques. Secondary purposes of this lab are to introduce you to the concept of revision control systems and to practice using linked structures.
Review the prelab reading as necessary for the premise, problem, and specification for the revision control system you'll be implementing.
Copy the starter code
from the course directory (this will also make a lab4
directory):
mkdir lab4 cd lab4 cp -r ~tvandrun/Public/cs245/lab4/. .
(Notice this is slightly different from the usual command---it has a '.' instead of a '*'. Since there's so much else that's new in this lab, I will skip an explanation, but ask me after lab if you're curious.)
Then open Eclipse and make a new workspace and project for this. I will walk you through this on the big screen.
The code for this lab is organized into two packages.
In the revctrl
package you will find the following files:
Controller
, the class that serves as the
brains for the version control system.
It contains stubs for methods that correspond to the
buttons on the window that the user will see.
For example, when the user presses the "<" button,
the previous()
method will
be called on an object of the Controller
class.
You will need to finish this class by filling in the body of the
method stubs.
VCWindow
, an interface specifying how
to interact with the window that the user sees.
The Controller
object will have a reference to
some object of some class that implements this.
You will not need to change this file, but you will have to look at
it to know how to change what appears on the window.
RealVCWindow
, a class implementing
VCWindow
that displays the window
to the user.
You do not need to look at this file at all.
Treat it like a black box---you only need to know the interface.
CommitActionListener
and other
action listener classes.
These are the glue between the window and the controller,
causing the controller's methods to be called when the user
clicks appropriate buttons.
Look at one of them (they're all about the same),
but don't modify them.
VersionControl
, which contains
the main method that starts everything going,
including instantiating the classes for the components.
Glance at it to see how it sets things up, but don't modify it.
In addition to this, you will need to write another class to model versions of the text the user is editing; details will be given below.
The package test
has files
containing JUnit test cases for the various steps in this lab.
It also has a class MockVCWindow
,
which implements the VCWindow
interface
but doesn't actually make a window appear on the screen.
As it's name suggests, it is a stand-in for RealVCWindow
for testing purposes.
Run VersionControl.java
.
You'll see that a window appears on the screen, and you can type in it,
but nothing happens when you click on the buttons.
You'll be implementing the features of the buttons as you go along.
The first feature you will implement in the system is the ability to commit a version. When the user clicks the commit button, the text currently on the textfield should be stored (in computer memory; we won't be doing file I/O in this lab), that version should be given a new version number, and the "max" and "current" version indicators should be incremented.
You will use the JUnit test SteP1TestCommit
to test this.
Open the class tests/Step1TestCommit
.
Run the test.
You'll get the red bar, although some of the test cases will
actually pass out of the box.
Write a class to represent versions of the text.
It should be in the revctrl
package.
Think about what information would need to be stored in
a version object, and write a constructor.
Don't worry about methods yet, you'll write those as we go along.
Controller
will need an instance variable to refer to the current
version and it will need a counter to keep track of the latest version number.
Finally, fill in the commit()
method in
Controller
so that it makes a new version and updates the indicators on the window.
Now test this "by hand", that is,
by running the program (VersionControl
)
and manipulating the
window as the user would.
While that will help you with an intuitive feel for the program,
it's not a rigorous way of testing your program
since humans generally don't have the discipline or patience
to test out all usage scenarios.
So, go back to the class tests/Step1TestCommit
.
Run the test.
If you don't get the green bar, then use the test results
to figure out what went wrong.
(You'll probably need to ask the instructor or TA for
help the first time you interpret the results of a failed test case.)
Now that the program has the ability to label the versions, we want to be able to retrieve an earlier version. Pressing the "previous" button should bring back the version that the current version was based on.
Run Step2TestPrevious
, the JUnit test
that will exercise this feature.
Confirm that it fails.
Now, what information should your version class have in order for that to be retrieved? What method would the class need so that the controller can retrieve the previous version?
Implement this change in your version class and
in the previous()
method in Controller.java
.
Make sure all the instance variables of your
version class are private.
If the user tries to move to the "previous" version of version 1, nothing should happen (but the program shouldn't crash). Also, make sure that if the user navigates to an older version, edits, and commits, that the new version is given the next version number and is hooked properly into the chain of versions. At this point in development, it's ok if the later versions get lost; you'll fix that in the next step 4.
Test this feature before moving on:
Step1TestCommit
to make
sure the things you added didn't break anything from
the previous step.
Once you've confirmed that that still works, then
Step2TestPrevious
.
Anytime you make a change, make sure that you run the tests not only for the feature you're currently working on but all of the earlier tests also---again, to make sure that nothing you changed broke something that previously was working.
Once both Step1TestCommit
and Step2TestPrevious
give you green bars,
move on.
Now update your version class and fill in the next()
method of Controller
so that we can move
to the next version.
Make sure Step3TestNext
fails first.
Then implement the feature.
Test it by hand, by running the earlier tests, and
finally make sure that it passes Step3TestNext
and the older tests.
Now update the program so that if someone edits and commits based on an earlier version, the later versions are no longer lost, and the "-" button can be used to navigate among siblings, as described in the pre-lab.
Test this by hand, by running the earlier tests, and
the new test, Step4TestParallel
.
Update the program so that the user can jump
directly to a version by giving its number.
(Hint: use an ArrayList
.)
Test this by hand, by running the earlier tests, and
the new test, Step5TestNext
.