Contents

  1. ./Birthday.java
  2. ./BirthdayTest.java
  3. ./Chicken.java
  4. ./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: &lt;name&gt;
     * <br/>weight: &lt;weight&gt; pounds
     * <br/>height: &lt;height&gt; 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.