Description
Specifications – Use arrays in this project; ArrayLists are not allowed!
Overview: This project consists of four classes: (1) Tetrahedron is a class representing a Tetrahedron
object; (2) TetrahedronTest class is a JUnit test class which contains one or more test methods for
each method in the Tetrahedron class; (3) TetrahedronList is a class representing a Tetrahedron list
object; and (4) TetrahedronListTest class is a JUnit test class which contains one or more test
methods for each method in the TetrahedronList class. Note that there is no requirement for a class
with a main method in this project.
You should create a new folder to hold the files for this project and add your files from Part 2
(Tetrahedron.java file and TetrahedronTest.java). You should create a new jGRASP project for Part
3 and add Tetrahedron.java file and TetrahedronTest.java to the project; you should see the two files
in their respective categories – Source Files and Test Files. If TetrahedronTest.java appears in source
File category, you should right-click on the file and select “Mark As Test” from the right-click menu.
You will then be able to run the test file by clicking the JUnit run button on the Open Projects toolbar.
After TetrahedronList.java and TetrahedronListTest.java are created as specified below, these should
be added to your jGRASP project for Part 3 as well.
If you have successfully completed Tetrahedron.java and TetrahedronTest.java in Part 2, you
should go directly to TetrahedronList.java on page 5.
• Tetrahedron.java (The specification of the Tetrahedron class is repeated below for your
convenience from Part 2; there are no modifications for this class in Part 3)
Requirements: Create a Tetrahedron class that stores the label and edge, where edge is nonnegative (>= 0). The Tetrahedron class also includes methods to set and get each of these fields,
as well as methods to calculate the height, surface area, and volume of a Tetrahedron object, and
a method to provide a String value that describes a Tetrahedron object.
The Tetrahedron class
includes a one static field (or class variable) to track the number of Tetrahedron objects that have
been created, as well appropriate static methods to access and reset this field. And finally, this
class provides a method that JUnit will use to test Tetrahedron objects for equality as well as a
method required by Checkstyle. In addition, Tetrahedron must implement the Comparable
interface for objects of type Tetrahedron.
A regular tetrahedron is a tetrahedron in which all four faces are equilateral triangles
with edge length a. When lying on one face, the tetrahedron is a pyramid with height h.
(Source: https://en.wikipedia.org/wiki/Tetrahedron)
The variables are
abbreviated as
follows:
a is edge length
h is height
A is surface area
V is volume
Design: The Tetrahedron class implements the Comparable interface for objects of type
Tetrahedron and has fields, a constructor, and methods as outlined below (last method is new).
(1) Fields: Instance Variables – label of type String and edge of type double. Initialize the
String to “” and the double variable to 0 in their respective declarations. These instance
variables should be private so that they are not directly accessible from outside of the
Tetrahedron class, and these should be the only instance variables (fields) in the class.
Class Variable – count of type int should be private and static, and it should be initialized to
zero.
(2) Constructor: Your Tetrahedron class must contain a public constructor that accepts two
parameters (see types of above) representing the label and edge length. Instead of assigning
the parameters directly to the fields, the respective set method for each field (described
below) should be called since they are checking the validity of the parameter. For example,
instead of using the statement label = labelIn; use the statement
setLabel(labelIn); The constructor should increment the class variable count each
time a Tetrahedron is constructed.
Below are examples of how the constructor could be used to create Tetrahedron objects.
Note that although String and numeric literals are used for the actual parameters (or
arguments) in these examples, variables of the required type could have been used instead of
the literals.
Tetrahedron example1 = new Tetrahedron(“Small Example”, 0.5);
Tetrahedron example2 = new Tetrahedron(” Medium Example “, 12.8);
Tetrahedron example3 = new Tetrahedron(“Large Example”, 97.36);
(3) Methods: Usually a class provides methods to access and modify each of its instance
variables (known as get and set methods) along with any other required methods. The
methods for Tetrahedron, which should each be public, are described below. See the
formulas in the figure above and the Code and Test section below for information on
constructing these methods.
o getLabel: Accepts no parameters and returns a String representing the label field.
o setLabel: Takes a String parameter and returns a boolean. If the String
parameter is not null, then the “trimmed” String is set to the label field and the
method returns true. Otherwise, the method returns false and the label is not set.
o getEdge: Accepts no parameters and returns a double representing the edge field.
o setEdge: Takes a double parameter and returns a boolean. If the double
parameter is non-negative, then the parameter is set to the edge field and the method
returns true. Otherwise, the method returns false and the edge field is not set.
o height: Accepts no parameters and returns the double value for the height of the
Tetrahedron. [Be sure to avoid integer division in your expression.]
o surfaceArea: Accepts no parameters and returns the double value for the total
surface area of the Tetrahedron.
o volume: Accepts no parameters and returns the double value for the volume of the
Tetrahedron. [Be sure to avoid integer division in your expression.]
o toString: Returns a String containing the information about the Tetrahedron object
formatted as shown below, including decimal formatting (“#,##0.0##”) for the double
values. Newline and tab escape sequences should be used to achieve the proper layout
within the String but it should not begin or end with a newline.
In addition to the field
values (or corresponding “get” methods), the following methods should be used to
compute appropriate values in the toString method: height(), surfaceArea(),
and volume(). Each line should have no trailing spaces (e.g., there should be no
spaces before a newline (\n) character). The toString value for example1,
example2, and example3 respectively are shown below (the blank lines are not part
of the toString values).
Tetrahedron “Small Example” with six edges of length 0.5 has:
height = 0.408 units
surface area = 0.433 square units
volume = 0.015 cubic units
Tetrahedron “Medium Example” with six edges of length 12.8 has:
height = 10.451 units
surface area = 283.779 square units
volume = 247.152 cubic units
Tetrahedron “Large Example” with six edges of length 97.36 has:
height = 79.494 units
surface area = 16,418.057 square units
volume = 108,761.565 cubic units
o getCount: A static method that accepts no parameters and returns an int representing
the static count field.
o resetCount: A static method that returns nothing, accepts no parameters, and sets the
static count field to zero.
o equals: An instance method that accepts a parameter of type Object and returns false if
the Object is a not a Tetrahedron; otherwise, when cast to a Tetrahedron, if it has the
same field values as the Tetrahedron upon which the method was called, it returns true.
Otherwise, it returns false. Note that this equals method with parameter type Object will
be called by the JUnit Assert.assertEquals method when two Tetrahedron objects are
checked for equality.
Below is a version you are free to use.
public boolean equals(Object obj) {
if (!(obj instanceof Tetrahedron)) {
return false;
}
else {
Tetrahedron d = (Tetrahedron) obj;
return (label.equalsIgnoreCase(d.getLabel())
&& Math.abs(edge – d.getEdge()) < .000001);
}
}
o hashCode(): Accepts no parameters and returns zero of type int. This method is
required by Checkstyle if the equals method above is implemented.
o compareTo: Accepts a parameter of type Tetrahedron and returns an int as follows: a
negative value if this.volume() is less than the parameter’s volume; a positive value
if this.volume() is greater than the parameter’s volume; zero if the two volumes are
essentially equal. For a hint, see the activity for this module.
Code and Test: As you implement the methods in your Tetrahedron class, you should compile it
and then create test methods as described below for the TetrahedronTest class.
• TetrahedronTest.java
Requirements: Create a TetrahedronTest class that contains a set of test methods to test each of
the methods in Tetrahedron. The goal for Part 2 is method, statement, and condition coverage.
Design: Typically, in each test method, you will need to create an instance of Tetrahedron, call
the method you are testing, and then make an assertion about the expected result and the actual
result (note that the actual result is commonly the result of invoking the method unless it has a
void return type).
You can think of a test method as simply formalizing or codifying what you
could be doing in jGRASP interactions to make sure a method is working correctly. That is, the
sequence of statements that you would enter in interactions to test a method should be entered
into a single test method.
You should have sufficient test methods so that each method,
statement, and condition in Tetrahedron are covered. Collectively, these test methods are a set of
test cases that can be invoked with a single click to test all of the methods in your Tetrahedron
class.
Code and Test: A good strategy would be to begin by writing test methods for those methods in
Tetrahedron that you “know” are correct. By doing this, you will be able to concentrate on the
getting the test methods correct. That is, if the test method fails, it is most likely due to a defect
in the test method itself rather the Tetrahedron method being testing.
As you become more
familiar with the process of writing test methods, you will be better prepared to write the test
methods as new methods are developed. Be sure to call the Tetrahedron toString method in
one of your test cases so that the grading system will consider the toString method to be
“covered” in its coverage analysis.
Remember that you can set a breakpoint in a JUnit test
method and run the test file in Debug mode. Then, when you have an instance in the Debug tab,
you can unfold it to see its values or you can open a canvas window and drag items from the
Debug tab onto the canvas. You can also step-in to the method being called by the test method
and then single-step through it, looking for the error.
• TetrahedronList.java (new for Part 3) – Consider implementing this file in parallel with its test
file, TetrahedronListTest.java, which is described after this class.
Requirements: Create a TetrahedronList class that stores the name of the list and an array of
Tetrahedron objects. It also includes methods that return the name of the list, number of
Tetrahedron objects in the TetrahedronList, total surface area, total volume, average surface area,
and average volume for all Tetrahedron objects in the TetrahedronList. The toString method
returns summary information about the list (see below).
Design: The TetrahedronList class has three fields, a constructor, and methods as outlined below.
(1) Fields (or instance variables): (1) a String representing the name of the list, (2) an array of
Tetrahedron objects, and (3) an int representing the number of Tetrahedron objects in the
array, which be less than the length of the array of Tetrahedron objects. These instance
variables should be private so that they are not directly accessible from outside of the
TetrahedronList class. These should be the only fields (or instance variables) in this class,
and they should be initialized in the constructor described below.
(2) Constructor: Your TetrahedronList class must contain a constructor that accepts three
parameters: (1) a parameter of type String representing the name of the list, (2) a parameter of
type Tetrahedron[], representing the list of Tetrahedron objects, and (3) a parameter of
type int representing the number of Tetrahedron objects in the array. These parameters
should be used to assign the fields described above (i.e., the instance variables).
(3) Methods: The methods for TetrahedronList are described below.
o getName: Returns a String representing the name of the list.
o numberOfTetrahedrons: Returns an int representing the number of Tetrahedron
objects in the TetrahedronList. If there are zero Tetrahedron objects in the list, zero
should be returned.
o totalSurfaceArea: Returns a double representing the total surface areas for all
Tetrahedron objects in the list. If there are zero Tetrahedron objects in the list, zero
should be returned.
o totalVolume: Returns a double representing the total volumes for all Tetrahedron
objects in the list. If there are zero Tetrahedron objects in the list, zero should be
returned.
o averageSurfaceArea: Returns a double representing the average surface area for
all Tetrahedron objects in the list. If there are zero Tetrahedron objects in the list, zero
should be returned.
o averageVolume: Returns a double representing the average volume for all
Tetrahedron objects in the list. If there are zero Tetrahedron objects in the list, zero
should be returned.
o toString: Returns a String (does not begin with \n) containing the name of the list
(which can change depending on the name of the list passed as a parameter to the
constructor) followed by various summary items: number of Tetrahedrons, total surface
area, total volume, average surface area, and average volume. Use “#,##0.0##” as the
pattern to format the double values.
Below is an example of the formatted String
returned by the toString method, where the name of the list (name field) is
Tetrahedron Test List and the array of Tetrahedron objects contains the three
examples described above (top of page 2). —– Summary for Tetrahedron Test List —–
Number of Tetrahedrons: 3
Total Surface Area: 16,702.269 square units
Total Volume: 109,008.731 cubic units
Average Surface Area: 5,567.423 square units
Average Volume: 36,336.244 cubic units
o getList: Returns the array of Tetrahedron objects (the second field above).
o addTetrahedron: Returns nothing but takes two parameters (label and edge), creates
a new Tetrahedron object, and adds it to the TetrahedronList object. Be sure to increment
the int field containing the number of Tetrahedron objects in the TetrahedronList object.
o findTetrahedron: Takes a label of a Tetrahedron as the String parameter and
returns the corresponding Tetrahedron object if found in the TetrahedronList object;
otherwise returns null. Case should be ignored when attempting to match the label.
o deleteTetrahedron: Takes a String as a parameter that represents the label of the
Tetrahedron and returns the Tetrahedron if it is found in the TetrahedronList object and
deleted; otherwise returns null. Case should be ignored when attempting to match the
label. When an element is deleted from an array, elements to the right of the deleted
element must be shifted to the left. After shifting the items to the left, the last Tetrahedron
element in the array should be set to null. Finally, the number of elements field must be
decremented.
o editTetrahedron: Takes two parameters (label and edge), uses the label to find the
corresponding the Tetrahedron object in the list. If found, sets the edge to the value
passed in as the parameter, and returns true. If not found, returns false.
(Note that the label should not be changed by this method.)
o findTetrahedronWithLargestVolume: Returns the Tetrahedron with the
largest volume; if the list contains no Tetrahedron objects, returns null.
Code and Test: Some of the methods above require that you use a loop to go through the objects
in the array. You should implement the class below in parallel with this one to facilitate testing.
That is, after implementing one to the methods above, you can implement the corresponding test
method in the test file described below.
• TetrahedronListTest.java (new for Part 3) – Consider implementing this file in parallel with its
source file, TetrahedronList.java, which is described above this class.
Requirements: Create a TetrahedronListTest class that contains a set of test methods to test each
of the methods in TetrahedronList.
Design: Typically, in each test method, you will need to create an instance of TetrahedronList,
call the method you are testing, and then make an assertion about the expected result and the
actual result (note that the actual result is usually the result of invoking the method unless it has a
void return type).
You can think of a test method as simply formalizing or codifying what you
have been doing in interactions to make sure a method is working correctly. That is, the sequence
of statements that you would enter in interactions to test a method should be entered into a single
test method. You should have at least one test method for each method in TetrahedronList.
However, if a method contains conditional statements (e.g., an if statement) that results in more
than one distinct outcome, you need a test method for each outcome. For example, if the method
returns boolean, you should have one test method where the expected return value is false and
another test method that expects the return value to be true.
Also, each condition in boolean
expression must be exercised true and false. Collectively, these test methods are a set of test
cases that can be invoked with a single click to test all of the methods in your TetrahedronList
class.
Code and Test: A good strategy would be to begin by writing test methods for those methods in
TetrahedronList that you “know” are correct. By doing this, you will be able to concentrate on
the getting the test methods correct.
That is, if the test method fails, it is most likely due to a
defect in the test method itself rather the TetrahedronList method being testing. As you become
more familiar with the process of writing test methods, you will be better prepared to write the
test methods for the new methods in TetrahedronList.
Be sure to call the TetrahedronList
toString method in one of your test cases so that the grading system will consider the toString
method to be “covered” in its coverage analysis. Remember that when a test method fails, you
can set a breakpoint in a JUnit test method and run the test file in Debug mode. Then, when you
have an instance in the Debug tab, you can unfold it to see its values or you can open a canvas
window and drag items from the Debug tab onto the canvas. You can also step-in to the method
being called by the test method and then single-step through it, looking for the error.
Finally, when comparing two arrays for equality in JUnit, be sure to use Assert.assertArrayEquals
rather than Assert.assertEquals. Assert.assertArrayEquals will return true only if the two arrays
are the same length and the elements are equal based on an element by element comparison using
the equals method.
The Grading System
When you submit your files (Tetrahedron.java, TetrahedronTest.java, TetrahedronList.java, and
TetrahedronListTest.java), the grading system will use the results of your test methods and their level of
coverage of your source files as well as the results of our reference correctness tests to determine your
grade. In this project, your test files should provide method, statement, and condition coverage. Each
condition in your source file must be exercised both true and false.