Contents
- ./Birthday.java
- ./BirthdayTest.java
- ./Chicken.java
- ./ChickenTest.java
./Birthday.java 1/4
[top][prev][next]
package edu.wlu.cs.sprenkle;
/**
* Demonstrates use of throwing IllegalArgumentExceptions to prevent errors.
* Rewritten since class.
*
* @author CSCI209
*/
public class Birthday implements Comparable<Birthday> {
private int day;
private int month;
private static int[] DAYS_IN_MONTH = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
private static String[] MONTHS = { "January", "February", "March", "April", "May", "June", "July", "August",
"September", "October", "November", "December" };
/**
* Creates a new Birthday object with the given month and day
*
* @param month the integer month of the birthday, e.g., January is 1, February
* is 2
* @param day the day of the month of the birthday
*/
public Birthday(int month, int day) {
super();
setBirthday(month, day);
}
/**
* Returns a String representation of the Birthday as "month/day"
*
* @return the Birthday as a string in the format "month/day"
*/
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append(month);
builder.append("/");
builder.append(day);
return builder.toString();
}
/**
* Returns a String reperesentation of the Birthday as "month_name day"
* @return the Birthday as a string in the format "month_name day"
*/
public String longStringFormat() {
StringBuilder builder = new StringBuilder();
builder.append(MONTHS[month-1]);
builder.append(" ");
builder.append(day);
return builder.toString();
}
/**
* Rather than setting the month and the day in separate methods, this is a
* better way to implement setting the month and the day. Why?
*
* @param month the integer month of the birthday, e.g., January is 1, February
* is 2
* @param day the day of the month of the birthday
*/
public void setBirthday(int month, int day) {
if (month < 1 || month > 12) {
throw new IllegalArgumentException("month must be between 1 and 12");
}
if (day < 1 || day > 31) {
throw new IllegalArgumentException("day must be between 1 and 31");
}
if (day > DAYS_IN_MONTH[month - 1]) {
throw new IllegalArgumentException(MONTHS[month - 1] + " has only " + DAYS_IN_MONTH[month - 1] + " days.");
}
// only set the month and day after we know that
// the month and day are valid.
this.month = month;
this.day = day;
}
/**
* Determines equality if both the month and the day match
*/
@Override
public boolean equals(Object obj) {
if( obj == this) {
return true;
}
if( ! (obj instanceof Birthday )) {
return false;
}
Birthday other = (Birthday) obj;
if( other.getDay() != day ) {
return false;
}
return other.getMonth() == month;
}
/**
* Returns the day of the month of the Birthday
*
* @return the day of the month of the Birthday
*/
public final int getDay() {
return day;
}
/**
* Returns the month of the Birthday, where 1 is January, 2 is February, ...
*
* @return the month of the Birthday, where 1 is January, 2 is February, ...
*/
public final int getMonth() {
return month;
}
/**
* Compares birthdays within the year. There is no year associated with this
* Birthday class.
*/
@Override
public int compareTo(Birthday other) {
if (month < other.getMonth()) {
return -1;
}
if (month > other.getMonth()) {
return 1;
}
// We know it's the same month.
return day - other.getDay();
}
/**
* @param args
*/
public static void main(String[] args) {
Birthday b = new Birthday(1, 1);
System.out.println("New Year's Baby: " + b);
Birthday leapYearBaby = new Birthday(2, 29);
System.out.println("Leap Year Baby: " + leapYearBaby);
b.setBirthday(4, 30); // this should work
System.out.println("End of April birthday: " + b);
// Test calling the method with the exceptions:
// Each of the statements below, separately, will throw an exception. // Comment
// out the others to see what one of them does.
// (Wouldn't it be great if we had a better way to test exceptions?)
b.setBirthday(1, 32); // should throw an exception
b.setBirthday(2, 30); // we'll never get to here because the last statement threw an exception
b.setBirthday(0, 30);
Birthday b2 = new Birthday(1, 32);
}
}
./BirthdayTest.java 2/4
[top][prev][next]
package edu.wlu.cs.sprenkle.tests;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import edu.wlu.cs.sprenkle.Birthday;
/**
* Tests the Birthday class
*
* @author Sara Sprenkle
*
*/
class BirthdayTest {
private Birthday newYearsBirthday;
private Birthday endOfJuneBirthday;
private Birthday aBirthday;
@BeforeEach
void setUp() throws Exception {
newYearsBirthday = new Birthday(1, 1);
endOfJuneBirthday = new Birthday(6, 30);
}
@Test
final void testBirthdayConstructor() {
assertEquals(1, newYearsBirthday.getMonth());
assertEquals(1, newYearsBirthday.getDay());
assertEquals(6, endOfJuneBirthday.getMonth());
assertEquals(30, endOfJuneBirthday.getDay());
// confirm no problem with a leap year birthday:
assertDoesNotThrow(() -> {
Birthday leapYearBirthday = new Birthday(2, 29);
});
}
@Test
final void testBadConstructorUse() {
assertThrows(IllegalArgumentException.class, () -> {
aBirthday = new Birthday(0, 1);
});
assertThrows(IllegalArgumentException.class, () -> {
aBirthday = new Birthday(1, 0);
});
assertThrows(IllegalArgumentException.class, () -> {
aBirthday = new Birthday(12, 32);
});
assertThrows(IllegalArgumentException.class, () -> {
aBirthday = new Birthday(2, -1);
});
assertThrows(IllegalArgumentException.class, () -> {
aBirthday = new Birthday(4, 31);
});
assertThrows(IllegalArgumentException.class, () -> {
aBirthday = new Birthday(2, 30);
});
}
@Test
final void testToString() {
String nydayString = "1/1";
String juneString = "6/30";
assertEquals(nydayString, newYearsBirthday.toString());
assertEquals(juneString, endOfJuneBirthday.toString());
}
@Test
final void testLongStringFormat() {
String nydayString = "January 1";
String juneString = "June 30";
assertEquals(nydayString, newYearsBirthday.longStringFormat());
assertEquals(juneString, endOfJuneBirthday.longStringFormat());
}
@Test
final void testSetBirthday() {
newYearsBirthday.setBirthday(1, 2);
assertEquals(1, newYearsBirthday.getMonth());
assertEquals(2, newYearsBirthday.getDay());
}
@Test
final void testGetDay() {
assertEquals(1, newYearsBirthday.getDay());
assertEquals(30, endOfJuneBirthday.getDay());
}
@Test
final void testGetMonth() {
assertEquals(1, newYearsBirthday.getMonth());
assertEquals(6, endOfJuneBirthday.getMonth());
}
@Test
final void testCompareTo() {
assertEquals(-1, newYearsBirthday.compareTo(endOfJuneBirthday));
assertEquals(1, endOfJuneBirthday.compareTo(newYearsBirthday));
Birthday sameMonth = new Birthday(6, 27);
assertEquals(-3, sameMonth.compareTo(endOfJuneBirthday));
assertEquals(3, endOfJuneBirthday.compareTo(sameMonth));
Birthday sameDay = new Birthday(1, 1);
assertEquals(0, sameDay.compareTo(newYearsBirthday));
assertEquals(0, newYearsBirthday.compareTo(sameDay));
}
@Test
final void testEquals() {
assertFalse(newYearsBirthday.equals(endOfJuneBirthday));
assertFalse(endOfJuneBirthday.equals(newYearsBirthday));
Birthday sameMonth = new Birthday(6, 27);
assertFalse(sameMonth.equals(endOfJuneBirthday));
assertFalse(endOfJuneBirthday.equals(sameMonth));
Birthday sameDay = new Birthday(1, 1);
assertTrue(sameDay.equals(newYearsBirthday));
assertTrue(newYearsBirthday.equals(sameDay));
}
@Test
final void testThrownExceptions() {
aBirthday = new Birthday(1, 1);
assertThrows(IllegalArgumentException.class, () -> {
aBirthday.setBirthday(0, 1);
});
assertThrows(IllegalArgumentException.class, () -> {
aBirthday.setBirthday(1, 0);
});
assertThrows(IllegalArgumentException.class, () -> {
aBirthday.setBirthday(12, -1);
});
assertThrows(IllegalArgumentException.class, () -> {
aBirthday.setBirthday(6, 31);
});
assertThrows(IllegalArgumentException.class, () -> {
aBirthday.setBirthday(10, 32);
});
assertThrows(IllegalArgumentException.class, () -> {
aBirthday.setBirthday(-1, 1);
});
}
}
./Chicken.java 3/4
[top][prev][next]
package edu.wlu.cs.sprenkle;
/**
* A simple Java class that models a Chicken. The state of the chicken is its
* name, height, weight, and sex.
*
* This is the original Chicken class, where the instance variables are
* private.
*
* @author Sara Sprenkle
*/
public class Chicken {
// ------------ INSTANCE VARIABLES -------------------
/** the chicken's name */
private String name;
/** the height of the chicken in centimeters */
private int height;
/** the weight of the chicken in pounds */
private double weight;
/** true iff the chicken is a female */
private boolean isFemale;
/** default name for chickens */
public static String DEFAULT_NAME = "BUBBA";
/** the name of the farm the chickens are on */
public static String FARM = "McDonald";
/** the amount of weight the chicken gains during feeding */
private static double WEIGHT_GAIN = .3;
/** the amount of height the chicken gains during feeding */
private static int HEIGHT_GAIN = 1;
/** the amount of weight difference we are okay with */
public static double ERROR_TOLERANCE = .0001;
/**
* Constructs a chicken with the given characteristics.
*
* @param name the name of the chicken
* @param height the height of the chicken in centimeters
* @param weight the weight of the chicken in pounds
* @param isFemale whether the chicken is female
*/
public Chicken(String name, int height, double weight, boolean isFemale ) {
this.name = name;
this.height = height;
this.weight = weight;
this.isFemale = isFemale;
}
/**
* Constructs a chicken with the given characteristics and assumes
* the chicken is female.
*
* @param name the name of the chicken
* @param height the height of the chicken in centimeters
* @param weight the weight of the chicken in pounds
*/
public Chicken(String name, int height, double weight) {
this( name, height, weight, true );
}
/**
* Constructs a chicken with the given characteristics, assumes
* the chicken's name is Bubba (defined by DEFAULT_NAME) and that
* it is female.
* @param height the height of the chicken in centimeters
* @param weight the weight of the chicken in pounds
*/
public Chicken( int height, double weight ) {
this( DEFAULT_NAME, height, weight, true);
}
/**
* Returns a string representation of the chicken.
* Format:
* <br/>Chicken name: <name>
* <br/>weight: <weight> pounds
* <br/>height: <height> cm
* <br/>female/male
* <p>Weight is displayed to one decimal place
* @return a string representation of this Chicken
*/
@Override
public String toString() {
StringBuffer rep = new StringBuffer("Chicken name: ");
rep.append(name);
rep.append("\nweight: ");
rep.append(String.format("%.1f", weight));
rep.append(" pounds\nheight: ");
rep.append(height);
rep.append(" cm\n");
rep.append( isFemale? "female" : "male"); // Java ternary operator; also available in C
return rep.toString();
}
/**
* Determines if two Chickens are equivalent, based on their
* name, height, weight, and sex.
*/
@Override
public boolean equals(Object o) {
if( o == this ) {
return true;
}
Chicken other = (Chicken) o;
if( ! other.getName().equals(this.getName() ) ) {
return false;
}
if( other.getHeight() != this.getHeight() ) {
return false;
}
double difference = this.getWeight() - this.getWeight();
if( difference > ERROR_TOLERANCE ) {
return false;
}
if( this.isFemale() ) {
return other.isFemale();
} else {
return ! other.isFemale();
}
}
//
// ----------- GETTER METHODS ------------
// (also Accessor methods)
/**
* Returns the height of the chicken in centimeters
* @return the height of the chicken, in centimeters
*/
public int getHeight() {
return height;
}
/**
* Returns the weight of the chicken in pounds
* @return the weight of the chicken, in pounds
*/
public double getWeight() {
return weight;
}
/**
* Returns the chicken's name
* @return the name of the chicken
*/
public String getName() {
return name;
}
/**
* Returns whether this chicken is female.
*
* @return true if the chicken is female and false otherwise.
*/
public boolean isFemale() {
return isFemale;
}
//
// ------------- MUTATORS -----------
//
/**
* Feeds the chicken--making the chicken grow
*/
public void feed() {
weight += WEIGHT_GAIN;
height += HEIGHT_GAIN;
}
//
// ------------- SETTERS ----------
//
/**
* Sets the name of the chicken
*
* @param n
* the name of the chicken
*/
public void setName(String n) {
name = n;
}
/**
* Sets the height of the chicken
*
* @param h
* the height of the chicken, in cm
*/
public void setHeight(int h) {
height = h;
}
/**
* Sets the weight of the chicken
*
* @param w
* the weight of the chicken, in pounds
*/
public void setWeight(double w) {
weight = w;
}
/**
* @param args
* the command-line arguments
*/
public static void main(String args[]) {
int fredHeight = 38;
Chicken chicken = new Chicken("Fred", fredHeight, 2.0, false);
System.out.println(chicken);
if( chicken.getHeight() != fredHeight ) {
System.err.println("Problem likely in constructor setting height");
}
if( !chicken.getName().equals("Fred") ) {
System.err.println("Problem likely in constructor setting name");
}
chicken.feed();
int newFredHeight = chicken.getHeight();
System.out.println(chicken.getName() + " is now " + newFredHeight +
" cm tall.");
chicken.feed();
System.out.println("He's a growing boy at " + chicken.getHeight() + " cm tall and " + chicken.getWeight() + " pounds");
String expectedRep = "Chicken name: Fred\nweight: 2.6 pounds\nheight: 40 cm\nmale";
String actualRep = chicken.toString();
// Demonstrates trickiness with testing with doubles
if( ! actualRep.equals(expectedRep) ) {
System.err.println("Problem in toString");
System.err.println("\tActual: " + actualRep);
System.err.println("\tExpected: " + expectedRep);
}
Chicken trivialMatch = chicken;
if( ! chicken.equals(trivialMatch) ) {
System.err.println("Problem in equals");
System.err.println("\tActual: " + chicken.equals(trivialMatch) );
System.err.println("\tExpected: " + true);
}
Chicken grownFred = new Chicken("Fred", 40, 2.6, false);
// This doesn't work -- again issue with comparing doubles
if( ! chicken.equals(grownFred) ) {
System.err.println("Problem in equals");
System.err.println("\tActual: " + chicken.equals(grownFred) );
System.err.println("\tExpected: " + true);
}
// ---- creating tests for chickens -----
String[] names = {"Rocky", "Baby Chicken"};
double[] weights = {4.0, .8};
int[] heights = {50, 4};
for( int i=0; i < names.length; i++ ) {
Chicken thisChicken = new Chicken( names[i], heights[i], weights[i] );
if( !thisChicken.getName().equals(names[i]) ) {
System.err.println("Problem likely in constructor setting name");
System.err.println("\tActual: " + thisChicken.getName());
System.err.println("\tExpected: " + names[i]);
}
if( thisChicken.getWeight() != weights[i] ) {
System.err.println("\tError in getWeight for Chicken " + i );
System.err.println("\tActual: " + thisChicken.getWeight());
System.err.println("\tExpected: " + weights[i] );
}
// feed the chicken and check the state
thisChicken.feed();
if( thisChicken.getWeight() != weights[i] + WEIGHT_GAIN ) {
System.err.println("Error in feed weight for Chicken " + i);
System.err.println("\tActual: " + thisChicken.getWeight());
System.err.println("\tExpected: " + (weights[i] + WEIGHT_GAIN) );
}
if( thisChicken.getHeight() != heights[i] + HEIGHT_GAIN ) {
System.err.println("Error in feed height for Chicken " + i);
System.err.println("\tActual: " + thisChicken.getHeight());
System.err.println("\tExpected: " + (heights[i] + HEIGHT_GAIN) );
}
// feed the chicken again and check the state
thisChicken.feed();
// NOTE: this test may fail, but tried to address by giving some
// error tolerance on the weight
double expectedWeight2 = weights[i] + 2 * WEIGHT_GAIN;
int comparison = Double.compare(thisChicken.getWeight(), expectedWeight2 );
if( comparison != 0 ) {
if( thisChicken.getWeight() - expectedWeight2 > ERROR_TOLERANCE ) {
System.err.println("Error in second feed weight for Chicken " + i);
System.err.println("\tActual: " + thisChicken.getWeight());
System.err.println("\tExpected: " + (expectedWeight2 ));
}
}
if( thisChicken.getHeight() != heights[i] + 2 * HEIGHT_GAIN ) {
System.err.println("Error in second feed height for Chicken " + i);
System.err.println("\tActual: " + thisChicken.getHeight());
System.err.println("\tExpected: " + (heights[i] + 2 * HEIGHT_GAIN ));
}
// TODO: test setName method
}
}
}
./ChickenTest.java 4/4
[top][prev][next]
package edu.wlu.cs.sprenkle.tests;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import edu.wlu.cs.sprenkle.Chicken;
/**
* Does not test everything -- trying to give examples of different
* types of tests
*
* @author Sara Sprenkle
*
*/
class ChickenTest {
private final static double ERROR_TOLERANCE = .0001;
private Chicken maleChicken;
private String maleName = "Fred";
private int maleHeight = 38;
private int femaleHeight = 30;
private Chicken femaleChicken;
@BeforeEach
void setUp() throws Exception {
maleChicken = new Chicken(maleName, maleHeight, 2.0, false);
femaleChicken = new Chicken("Sallie Mae", femaleHeight, 1.5);
}
@Test
final void testConstructors() {
assertEquals(maleHeight, maleChicken.getHeight());
assertEquals(2.0, maleChicken.getWeight(), ERROR_TOLERANCE);
assertFalse(maleChicken.isFemale());
assertEquals(maleName, maleChicken.getName());
assertEquals(femaleHeight, femaleChicken.getHeight());
assertEquals(1.5, femaleChicken.getWeight(), ERROR_TOLERANCE);
assertTrue(femaleChicken.isFemale());
assertEquals("Sallie Mae", femaleChicken.getName());
}
@Test
final void testToString() {
String expected = "Chicken name: Fred\nweight: 2.0 pounds\nheight: 38 cm\nmale";
assertEquals(expected, maleChicken.toString());
expected = "Chicken name: Sallie Mae\nweight: 1.5 pounds\nheight: " + femaleHeight + " cm\nfemale";
assertEquals(expected, femaleChicken.toString());
}
@Test
final void testEqualsObject() {
Chicken anotherMale = new Chicken(maleName, maleHeight, 2.0, false);
assertFalse(maleChicken.equals(femaleChicken));
assertFalse(femaleChicken.equals(maleChicken));
assertTrue(maleChicken.equals(anotherMale));
assertTrue(anotherMale.equals(maleChicken));
}
@Test
final void testGetName() {
assertEquals("Fred", maleChicken.getName());
assertEquals("Sallie Mae", femaleChicken.getName());
// more tests in testSetName and testConstructor
}
@Test
final void testFeed() {
maleChicken.feed();
assertEquals(2.3, maleChicken.getWeight(), ERROR_TOLERANCE); // should grow by .3 lbs
assertEquals(maleHeight + 1, maleChicken.getHeight()); // should grow by 1 cm
maleChicken.feed();
assertEquals(2.6, maleChicken.getWeight(), ERROR_TOLERANCE); // should grow by .3 lbs
assertEquals(maleHeight + 2, maleChicken.getHeight()); // should grow by an additional 1
maleChicken.feed();
assertEquals(2.9, maleChicken.getWeight(), ERROR_TOLERANCE); // should grow by .3 lbs
assertEquals(maleHeight + 3, maleChicken.getHeight()); // should grow by an additional 1
// feed shouldn't have changed these...
assertEquals("Fred", maleChicken.getName());
assertFalse(maleChicken.isFemale());
// should test female chicken too
}
@Test
final void testSetName() {
String newName = "Mr. Fred";
maleChicken.setName(newName);
assertEquals(newName, maleChicken.getName());
}
@Test
final void testSetWeight() {
double newWeight = 3.1326;
femaleChicken.setWeight(newWeight);
assertEquals(newWeight, femaleChicken.getWeight(), ERROR_TOLERANCE);
}
}
Generated by GNU Enscript 1.6.6.