package org.eclipse.swt.tests.junit;

/*
 * (c) Copyright IBM Corp. 2000, 2001.
 * All Rights Reserved
 */

import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import junit.framework.*;
import junit.textui.*;

/**
 * Automated Test Suite for class org.eclipse.swt.graphics.Rectangle
 *
 * @see org.eclipse.swt.graphics.Rectangle
 */
public class Test_org_eclipse_swt_graphics_Rectangle extends SwtTestCase {

public Test_org_eclipse_swt_graphics_Rectangle(String name) {
	super(name);
}

public static void main(String[] args) {
	TestRunner.run(suite());
}

protected void setUp() {
}

protected void tearDown() {
}

public void test_ConstructorIIII(){
	// Test new Rectangle (int x, int y, int width, int height)
	Rectangle r = new Rectangle(3, 4, 5, 6);
	assertEquals(3, r.x);
	assertEquals(4, r.y);
	assertEquals(5, r.width);
	assertEquals(6, r.height);

	r = new Rectangle(-4, -3, -2, -1);
	assertEquals(-4, r.x);
	assertEquals(-3, r.y);
	assertEquals(-2, r.width);
	assertEquals(-1, r.height);

	r = new Rectangle(500000, 700000, 200000, 100000);
	assertEquals(500000, r.x);
	assertEquals(700000, r.y);
	assertEquals(200000, r.width);
	assertEquals(100000, r.height);
}

/**
 * Destructively replaces the x, y, width and height values
 * in the receiver with ones which represent the union of the
 * rectangles specified by the receiver and the given rectangle.
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
 * </ul>
 */
public void test_addLorg_eclipse_swt_graphics_Rectangle(){
	Rectangle r1 = new Rectangle(1, 2, 3, 4);
	Rectangle r2 = new Rectangle(3, 3, 2, 2);
	r1.add(r2);
	assertEquals("Rectangle add incorrect", new Rectangle(1, 2, 4, 4), r1);

	r1.add(r2);
	assertEquals("Rectangle add incorrect", new Rectangle(1, 2, 4, 4), r1);
	
	r1 = new Rectangle(1, 2, 3, 4);
	r2 = new Rectangle(3, 3, 0, 0);
	r1.add(r2);
	assertEquals("Rectangle add incorrect", new Rectangle(1, 2, 3, 4), r1);

	r1 = new Rectangle(1, 2, 3, 4);
	r2 = new Rectangle(6, 6, 0, 0);
	r1.add(r2);
	assertEquals("Rectangle add incorrect", new Rectangle(1, 2, 5, 4), r1);

	try {
		r1.add(null);
		fail("No exception thrown for rectangle == null");
	} catch (IllegalArgumentException e) {
	}
}

/**
 * Returns <code>true</code> if the point specified by the
 * arguments is inside the area specified by the receiver.
 */
public void test_containsII(){
	Rectangle r = new Rectangle(1, 2, 3, 4);
	assertTrue("Rectangle should contain point (1, 2)", r.contains(1, 2));

	assertTrue("Rectangle should contain point (3, 4)", r.contains(3, 4));

	assertTrue("Rectangle should contain point (3, 5)", r.contains(3, 5));

//	assertTrue("Rectangle should contain point (3, 6)", r.contains(3, 6));
//
//	assertTrue("Rectangle should contain point (4, 5)", r.contains(4, 5));
//
//	assertTrue("Rectangle should contain point (4, 6)", r.contains(4, 6));

	assertTrue("Rectangle should not contain point (9, 10)", !r.contains(9, 10));

	assertTrue("Rectangle should not contain point (-1, -1)", !r.contains(-1, -1));
}

/**
 * Returns <code>true</code> if the given point is inside the
 * area specified by the receiver.
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
 * </ul>
 */
public void test_containsLorg_eclipse_swt_graphics_Point(){
	Rectangle r = new Rectangle(1, 2, 3, 4);
	assertTrue("Rectangle should contain Point(1, 2)", r.contains(new Point(1, 2)));

	assertTrue("Rectangle should contain Point(3, 4)", r.contains(new Point(3, 4)));

	assertTrue("Rectangle should contain point (3, 5)", r.contains(new Point(3, 5)));

//	assertTrue("Rectangle should contain point (3, 6)", r.contains(new Point(3, 6)));
//
//	assertTrue("Rectangle should contain point (4, 5)", r.contains(new Point(4, 5)));
//
//	assertTrue("Rectangle should contain Point(4, 6)", r.contains(new Point(4, 6)));

	assertTrue("Rectangle should not contain Point(9, 10)", !r.contains(new Point(9, 10)));

	assertTrue("Rectangle should not contain point (-1, -1)", !r.contains(new Point(-1, -1)));

	try {
		r.contains(null);
		fail("No exception thrown for rectangle == null");
	} catch (IllegalArgumentException e) {
	}
}

public void test_equalsLjava_lang_Object(){
	Rectangle r1 = new Rectangle(5, 4, 3, 2);
	Rectangle r2 = new Rectangle(5, 4, 3, 2);
	assertTrue("Rectangles should be equal", r1.equals(r2));

	r2 = new Rectangle(3, 4, 5, 6);
	assertTrue("Rectangles should not be equal", !r1.equals(r2));

	r2 = new Rectangle(2, 3, 4, 5);
	assertTrue("Rectangles should not be equal", !r1.equals(r2));

	r2 = new Rectangle(5, 4, 2, 3);
	assertTrue("Rectangles should not be equal", !r1.equals(r2));

	r2 = new Rectangle(4, 5, 3, 2);
	assertTrue("Rectangles should not be equal", !r1.equals(r2));
}

public void test_hashCode(){
	Rectangle r1 = new Rectangle(5, 4, 3, 2);
	Rectangle r2 = new Rectangle(5, 4, 3, 2);
	assertTrue("Rectangles should have the same hashCode", r1.hashCode() == r2.hashCode());
}

/**
 * Returns a new rectangle which represents the intersection
 * of the receiver and the given rectangle. 
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
 * </ul>
 */
public void test_intersectionLorg_eclipse_swt_graphics_Rectangle(){
	Rectangle r1 = new Rectangle(1, 2, 3, 4);
	Rectangle r2 = new Rectangle(3, 3, 2, 2);
	assertEquals("Rectangle intersection incorrect", new Rectangle(3, 3, 1, 2), r1.intersection(r2));

	r2 = new Rectangle(3, 3, 0, 0);
	assertEquals("Rectangle intersection incorrect", new Rectangle(3, 3, 0, 0), r1.intersection(r2));

	r2 = new Rectangle(3, 3, -1, -1);
	assertEquals("Rectangle intersection incorrect", new Rectangle(3, 3, -1, -1), r1.intersection(r2));

	try {
		r1.intersection(null);
		fail("No exception thrown for rectangle == null");
	} catch (IllegalArgumentException e) {
	}
}

/**
 * Returns <code>true</code> if the given rectangle intersects
 * with the receiver and <code>false</code> otherwise.
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
 * </ul>
 */
public void test_intersectsLorg_eclipse_swt_graphics_Rectangle(){
	Rectangle r1 = new Rectangle(1, 2, 3, 4);
	Rectangle r2 = new Rectangle(2, 3, 7, 8);
	assertTrue("Rectangle(1, 2, 3, 4) should intersect Rectangle(2, 3, 7, 8)", r1.intersects(r2));
	assertTrue("Rectangle(2, 3, 7, 8) should intersect Rectangle(1, 2, 3, 4)", r2.intersects(r1));

	r2 = new Rectangle(200, 300, 400, 500);
	assertTrue("Rectangle(1, 2, 3, 4) should not intersect Rectangle(200, 300, 400, 500)", !r1.intersects(r2));
	assertTrue("Rectangle(200, 300, 400, 500) should not intersect Rectangle(1, 2, 3, 4)", !r2.intersects(r1));
	
	r2 = new Rectangle(3, 3, 0, 0);
	assertTrue("Rectangle(1, 2, 3, 4) should intersect Rectangle(3, 3, 0, 0)", r1.intersects(r2));
	assertTrue("Rectangle(3, 3, 0, 0) should intersect Rectangle(1, 2, 3, 4)", r2.intersects(r1));

	r2 = new Rectangle(3, 3, -1, -1);
	assertTrue("Rectangle(1, 2, 3, 4) should not intersect Rectangle(3, 3, -1, -1)", !r1.intersects(r2));
	assertTrue("Rectangle(3, 3, -1, -1) should not intersect Rectangle(1, 2, 3, 4)", !r2.intersects(r1));

	try {
		r1.intersects(null);
		fail("No exception thrown for rectangle == null");
	} catch (IllegalArgumentException e) {
	}
}

/**
 * Returns <code>true</code> if the receiver does not cover any
 * area in the (x, y) coordinate plane, and <code>false</code> if
 * the receiver does cover some area in the plane.
 * <p>
 * A rectangle is considered to <em>cover area</em> in the 
 * (x, y) coordinate plane if both its width and height are 
 * non-zero.
 * </p>
 */
public void test_isEmpty(){
	Rectangle r = new Rectangle(1, 2, 0, 0);
	assertTrue("Rectangle is empty", r.isEmpty());

	r = new Rectangle(1, 2, -3, -4);
	assertTrue("Rectangle is empty", r.isEmpty());

	r = new Rectangle(1, 2, 3, 4);
	assertTrue("Rectangle is not empty", !r.isEmpty());
}

public void test_toString(){
	Rectangle r = new Rectangle(3, 4, 5, 6);
	assertNotNull(r.toString());
	assertTrue(r.toString().length() > 0);
	assertEquals("Rectangle {3, 4, 5, 6}", r.toString());
}

/**
 * Returns a new rectangle which represents the union of
 * the receiver and the given rectangle.
 *
 * @exception IllegalArgumentException <ul>
 *    <li>ERROR_NULL_ARGUMENT - if the argument is null</li>
 * </ul>
 */
public void test_unionLorg_eclipse_swt_graphics_Rectangle(){
	Rectangle r1 = new Rectangle(1, 2, 3, 4);
	Rectangle r2 = new Rectangle(3, 3, 2, 2);
	assertEquals("Rectangle union incorrect", new Rectangle(1, 2, 4, 4), r1.union(r2));
	
	r2 = new Rectangle(3, 3, 0, 0);
	assertEquals("Rectangle union incorrect", new Rectangle(1, 2, 3, 4), r1.union(r2));

	r2 = new Rectangle(3, 3, -1, -1);
	assertEquals("Rectangle union incorrect", new Rectangle(1, 2, 3, 4), r1.union(r2));

	try {
		r1.union(null);
		fail("No exception thrown for rectangle == null");
	} catch (IllegalArgumentException e) {
	}
}

public static Test suite() {
	TestSuite suite = new TestSuite();
	java.util.Vector methodNames = methodNames();
	java.util.Enumeration e = methodNames.elements();
	while (e.hasMoreElements()) {
		suite.addTest(new Test_org_eclipse_swt_graphics_Rectangle((String)e.nextElement()));
	}
	return suite;
}
public static java.util.Vector methodNames() {
	java.util.Vector methodNames = new java.util.Vector();
	methodNames.addElement("test_ConstructorIIII");
	methodNames.addElement("test_addLorg_eclipse_swt_graphics_Rectangle");
	methodNames.addElement("test_containsII");
	methodNames.addElement("test_containsLorg_eclipse_swt_graphics_Point");
	methodNames.addElement("test_equalsLjava_lang_Object");
	methodNames.addElement("test_hashCode");
	methodNames.addElement("test_intersectionLorg_eclipse_swt_graphics_Rectangle");
	methodNames.addElement("test_intersectsLorg_eclipse_swt_graphics_Rectangle");
	methodNames.addElement("test_isEmpty");
	methodNames.addElement("test_toString");
	methodNames.addElement("test_unionLorg_eclipse_swt_graphics_Rectangle");
	return methodNames;
}
protected void runTest() throws Throwable {
	if (getName().equals("test_ConstructorIIII")) test_ConstructorIIII();
	else if (getName().equals("test_addLorg_eclipse_swt_graphics_Rectangle")) test_addLorg_eclipse_swt_graphics_Rectangle();
	else if (getName().equals("test_containsII")) test_containsII();
	else if (getName().equals("test_containsLorg_eclipse_swt_graphics_Point")) test_containsLorg_eclipse_swt_graphics_Point();
	else if (getName().equals("test_equalsLjava_lang_Object")) test_equalsLjava_lang_Object();
	else if (getName().equals("test_hashCode")) test_hashCode();
	else if (getName().equals("test_intersectionLorg_eclipse_swt_graphics_Rectangle")) test_intersectionLorg_eclipse_swt_graphics_Rectangle();
	else if (getName().equals("test_intersectsLorg_eclipse_swt_graphics_Rectangle")) test_intersectsLorg_eclipse_swt_graphics_Rectangle();
	else if (getName().equals("test_isEmpty")) test_isEmpty();
	else if (getName().equals("test_toString")) test_toString();
	else if (getName().equals("test_unionLorg_eclipse_swt_graphics_Rectangle")) test_unionLorg_eclipse_swt_graphics_Rectangle();
}
}
