package controller; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import java.io.File; import junit.framework.Assert; import org.junit.After; import org.junit.Before; import org.junit.Test; import util.Operator; import db.Database; import db.DatabaseAccessException; import db.DatabaseConfiguration; import db.IncompatibleVersionException; import db.InvalidDriverException; /** * The class is used to test all group functionalities, including the {@link Group}, {@link StaticConstraint} and * {@link DynamicConstraint} classes. */ public class GroupControllerTest { private final String path = System.getProperty("java.io.tmpdir") + "/bsv_controller_tests"; private final String dbFile = this.path + "/database-junit-group.bsv"; private Database database = null; private GroupController groupController; private SubspaceController subspaceController; /** * Set up a clean database before we do the testing on it and init the group controller */ @Before public void setup() { // create working directory (new File(this.path)).mkdirs(); // make sure the old file is deleted (new File(this.dbFile)).delete(); try { // create a new database with two features this.database = new Database(this.dbFile); String[] features = { "Feature 1", "Feature 2" }; boolean[] outlier = { false, false }; this.database.initFeatures(features, outlier); this.subspaceController = new SubspaceController(this.database); this.groupController = new GroupController(this.database, this.subspaceController); } catch (InvalidDriverException e) { Assert.fail(e.getMessage()); } catch (IncompatibleVersionException e) { Assert.fail(e.getMessage()); } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } } /** * Clean up, after testing. */ @After public void tearDown() { // shutdown try { this.database.shutdown(); } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } // clean up database if (this.database != null) { assertEquals(true, (new File(this.dbFile)).delete()); } } /** * This method tests the given group * * @param group * the group to test * @param id * the expected id * @param name * the expected name * @param ColorFeature * the expected color feature */ private void groupTest(Group group, int id, String name, Feature colorFeature) { assertEquals("Inappropriate id", id, group.getId()); assertEquals("Inappropriate name", name, group.getName()); assertEquals("Inappropriate id", "", group.getDescription()); assertEquals("Inappropriate color feature", colorFeature, group.getColorFeature()); assertTrue("Inappropriate visibility", group.isVisible()); } /** * Test the group controller and its methods */ @Test public void groupControllerTest() { // Test constructor try { new GroupController(null, this.subspaceController); Assert.fail("Database was null"); } catch (IllegalArgumentException e) { } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } try { new GroupController(this.database, null); Assert.fail("subspace controller was null"); } catch (IllegalArgumentException e) { } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } // Test create methods try { this.groupController.createGroup(null); Assert.fail("name was null"); } catch (IllegalArgumentException e) { } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } try { this.groupController.createGroup("aaaaaaaaaaaaaaaaaaaaaaaaa"); Assert.fail("name was to long"); } catch (IllegalArgumentException e) { } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } assertEquals("Incorrect max length for String", groupController.maxStringLength(), DatabaseConfiguration.VARCHARLENGTH); } /** * Test if there is no group returned from a new database, create one and test its parameters */ @Test public void initialStateAndCreateGroupTest() { try { // test if there is no group in database and create one initial assertEquals("There was a initial group in database", 0, this.groupController.getGroups().length); Group testingGroup = this.groupController.createGroup("testing group 1"); assertEquals("The group was not created", 1, this.groupController.getGroups().length); // test parameter of initial group groupTest(testingGroup, 1, "testing group 1", null); // create another group this.groupController.createGroup("testing group 2"); assertEquals("The second group was not created", 2, groupController.getGroups().length); // test parameter of groups after getting them from database testingGroup = this.groupController.getGroups()[0]; groupTest(testingGroup, 1, "testing group 1", null); testingGroup = this.groupController.getGroups()[1]; groupTest(testingGroup, 2, "testing group 2", null); } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } } /** * Test creation and removing of groups */ @Test public void createAndRemoveGroupTest() { try { // check state of group count and create two new ones assertEquals("False number of groups", 0, this.groupController.getGroups().length); this.groupController.createGroup("testing group 1"); this.groupController.createGroup("testing group 2"); groupTest(this.groupController.getGroups()[0], 1, "testing group 1", null); groupTest(this.groupController.getGroups()[1], 2, "testing group 2", null); // remove the first one and test again Group testingGroup = this.groupController.getGroups()[0]; this.groupController.removeGroup(testingGroup); assertEquals("False number of groups", 1, this.groupController.getGroups().length); // check the remaining group groupTest(this.groupController.getGroups()[0], 2, "testing group 2", null); // create new groups and test the parameters this.groupController.createGroup("testing group 3"); this.groupController.createGroup("testing group 4"); groupTest(this.groupController.getGroups()[0], 2, "testing group 2", null); groupTest(this.groupController.getGroups()[1], 3, "testing group 3", null); groupTest(this.groupController.getGroups()[2], 4, "testing group 4", null); assertEquals("False number of groups", 3, this.groupController.getGroups().length); // remove another group and test the parameters again this.groupController.removeGroup(new Group(this.groupController, this.database, 3, "testing group 3", true, -1, null, "")); assertEquals("False number of groups", 2, this.groupController.getGroups().length); groupTest(this.groupController.getGroups()[0], 2, "testing group 2", null); groupTest(this.groupController.getGroups()[1], 4, "testing group 4", null); } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } } /** * Test a single group and modify single parameters */ @Test public void singleGroupTest() { try { Group group = this.groupController.createGroup("testing group"); groupTest(group, 1, "testing group", null); assertEquals("Incorrect to string", "testing group", group.toString()); assertEquals("Incorrect max string length", group.maxStringLength(), DatabaseConfiguration.VARCHARLENGTH); group.setName("new Name"); assertEquals("Incorrect name", "new Name", group.getName()); group.setColor(-1); assertEquals("Incorrect color", -1, group.getColor()); group.setDescription("Testing the description"); assertEquals("Incorrect description", "Testing the description", group.getDescription()); group.setVisible(false); assertFalse("Incorrect visibility", group.isVisible()); group.setColorFeature(new Feature(this.groupController.getSubspaceController(), this.database, 1, "Feature 1", false, false, 0, 1)); assertEquals("Incorrect color feature", 1, group.getColorFeature().getId()); group.setColorFeature(new Feature(this.groupController.getSubspaceController(), this.database, -1, "Effect.", false, true, 0, 1)); assertEquals("Incorrect color feature", -1, group.getColorFeature().getId()); group.setColorFeature(null); assertEquals("Incorrect color feature", group.getColorFeature(), null); // test if all changes are done in database group = this.groupController.getGroups()[0]; assertEquals("Incorrect name in database", "new Name", group.getName()); assertEquals("Incorrect color in database", -1, group.getColor()); assertEquals("Incorrect description in database", "Testing the description", group.getDescription()); assertFalse("Incorrect visibility in database", group.isVisible()); // assertEquals("Incorrect color feature in database", -1, group.getColorFeature().getId()); // check remove single group assertEquals("Incorrect number of groups", 1, this.groupController.getGroups().length); group.createDynamicConstraint(new Feature(this.groupController.getSubspaceController(), this.database, 1, "test", false, false, 0, 1), Operator.EQUAL, 0.0f); int[] selection = { 1, 2 }; group.createStaticConstraint(selection); group.remove(); assertEquals("Incorrect number of groups", 0, this.groupController.getGroups().length); // Test color features Group groupNull = this.groupController.createGroup("group null"); groupNull.setColorFeature(null); Group groupFeature = this.groupController.createGroup("group Feature"); groupFeature.setColorFeature(new Feature(this.subspaceController, this.database, 1, "Feature 1", false, false, 0, 1)); Group groupEffectOut = this.groupController.createGroup("group outlierness"); groupEffectOut.setColorFeature(new Feature(this.subspaceController, this.database, -1, "Effect. Out.", false, true, 0, 1)); assertEquals("Incorrect number of groups", 3, this.groupController.getGroups().length); } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } } /** * Test the creation and removing of static and dynamic Constraints */ @Test public void singleGroupConstraintTest() { try { Group group = this.groupController.createGroup("testing group"); assertEquals("Incorrect number of constraints", 0, group.getConstraints().length); // test dynamic constraint group.createDynamicConstraint(new Feature(this.groupController.getSubspaceController(), this.database, 1, "Feature 1", false, false, 0, 1), Operator.EQUAL, 0.0f); assertEquals("Incorrect number of constraints", 1, group.getConstraints().length); group.removeConstraint(group.getConstraints()[0]); assertEquals("Incorrect number of constraints", 0, group.getConstraints().length); // test static constraint int[] selection = { 1, 2, 3, 4, 5, 6 }; group.createStaticConstraint(selection); assertEquals("Incorrect number of constraints", 1, group.getConstraints().length); group.removeConstraint(group.getConstraints()[0]); assertEquals("Incorrect number of constraints", 0, group.getConstraints().length); // test the rebuilding of constraints from database group.createDynamicConstraint(new Feature(this.groupController.getSubspaceController(), this.database, 1, "Feature 1", false, false, 0, 1), Operator.EQUAL, 0.0f); group.createDynamicConstraint(new Feature(this.groupController.getSubspaceController(), this.database, 1, "Outlierness 1", true, false, 0, 1), Operator.EQUAL, 0.0f); group.createDynamicConstraint(new Feature(this.groupController.getSubspaceController(), this.database, -1, "Effect. Out.", false, true, 0, 1), Operator.EQUAL, 0.0f); group.createStaticConstraint(selection); group = this.groupController.getGroups()[0]; assertEquals("Incorrect number of constraints", 4, group.getConstraints().length); } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } } /** * Test a single dynamic constraint and set, get parameters */ @Test public void singleDynamicConstraintTest() { try { Group group = this.groupController.createGroup("testing group"); group.createDynamicConstraint(new Feature(this.groupController.getSubspaceController(), this.database, 1, "Feature 1", false, false, 0, 1), Operator.EQUAL, 0.0f); assertEquals("Incorrect number of constraints", group.getConstraints().length, 1); DynamicConstraint constraint = (DynamicConstraint) group.getConstraints()[0]; // test the dynamic constraint assertEquals("Incorrect id", constraint.getId(), 1); assertEquals("Incorrect feature", constraint.getFeature().getId(), 1); assertEquals("Incorrect operator", constraint.getOperator(), Operator.EQUAL); assertEquals("Incorrect value", constraint.getValue(), 0.0f, 0.000000001f); assertTrue("Incorrect active flag", constraint.isActive()); // set all values and check their changes constraint.setFeature(new Feature(this.groupController.getSubspaceController(), this.database, 2, "Feature 2", false, false, 0, 0)); assertEquals("Incorrect feature", constraint.getFeature().getId(), 2); constraint.setOperator(Operator.GREATER); assertEquals("Incorrect operator", constraint.getOperator(), Operator.GREATER); constraint.setValue(1.0f); assertEquals("Incorrect value", constraint.getValue(), 1.0f, 0.000000001f); constraint.setActive(false); assertFalse("Incorrect active flag", constraint.isActive()); constraint.remove(); } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } } /** * Test a single static constraint and its set and get methods */ @Test public void singleStaticConstraintTest() { try { Group group = this.groupController.createGroup("testing group"); int[] selection = { 1, 2, 3, 4 }; group.createStaticConstraint(selection); assertEquals("Incorrect number of constraints", group.getConstraints().length, 1); StaticConstraint constraint = (StaticConstraint) group.getConstraints()[0]; // testing the static constraint assertEquals("Incorrect id", constraint.getId(), 1); assertEquals("Incorrect number of items in selection", constraint.getSelection().length, selection.length); assertEquals("Incorrect id in selection", constraint.getSelection()[0], selection[0]); assertEquals("Incorrect id in selection", constraint.getSelection()[1], selection[1]); assertEquals("Incorrect id in selection", constraint.getSelection()[2], selection[2]); assertEquals("Incorrect id in selection", constraint.getSelection()[3], selection[3]); assertTrue("Incorrect is active flag", constraint.isActive()); // set valus and test them constraint.setActive(false); assertFalse("Incorrect is active flag", constraint.isActive()); int[] newSelection = { 5, 6 }; constraint.setSelection(newSelection); assertEquals("Incorrect number of items in the selection", constraint.getSelection().length, newSelection.length); assertEquals("Incorrect id in selection", constraint.getSelection()[0], newSelection[0]); assertEquals("Incorrect id in selection", constraint.getSelection()[1], newSelection[1]); constraint.remove(); } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } } /** * Tests all constructors and setters in class {@link Group } for illegal argument exceptions */ @Test public void groupArgumentTest() { // Test constructor try { new Group(null, this.database, 1, "test", true, 0, null, ""); Assert.fail("Group controller was null"); } catch (IllegalArgumentException e) { } try { new Group(this.groupController, null, 1, "test", true, 0, null, ""); Assert.fail("Database was null"); } catch (IllegalArgumentException e) { } try { new Group(this.groupController, this.database, -1, "test", true, 0, null, ""); Assert.fail("id was negative"); } catch (IllegalArgumentException e) { } try { new Group(this.groupController, this.database, 1, null, true, 0, null, ""); Assert.fail("Name was null"); } catch (IllegalArgumentException e) { } try { new Group(this.groupController, this.database, 1, "aaaaaaaaaaaaaaaaaaaaaaaaaa", true, 0, null, ""); Assert.fail("Name was to long"); } catch (IllegalArgumentException e) { } try { new Group(this.groupController, this.database, 1, "test", true, 0, null, null); Assert.fail("Description was null"); } catch (IllegalArgumentException e) { } // Test setters Group group = new Group(this.groupController, this.database, 1, "testing group", true, 0, null, ""); try { group.setDescription(null); Assert.fail("Description was null"); } catch (IllegalArgumentException e) { } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } try { group.setName(null); Assert.fail("Name was null"); } catch (IllegalArgumentException e) { } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } try { group.setName("aaaaaaaaaaaaaaaaaaaaaaaaa"); Assert.fail("Name was to long"); } catch (IllegalArgumentException e) { } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } // Test create methods try { group.createDynamicConstraint(null, Operator.EQUAL, 0.0f); Assert.fail("Feature was null"); } catch (IllegalArgumentException e) { } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } try { group.createDynamicConstraint(new Feature(this.subspaceController, this.database, 1, "Feature 1", false, false, 0, 1), null, 0.0f); Assert.fail("Operator was null"); } catch (IllegalArgumentException e) { } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } try { group.createStaticConstraint(null); Assert.fail("Selection was null"); } catch (IllegalArgumentException e) { } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } try { int[] selection = new int[0]; group.createStaticConstraint(selection); Assert.fail("Selection has length zero"); } catch (IllegalArgumentException e) { } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } } /** * Tests all constructors and setters in class {@link DynamicConstraint} for illegal argument exceptions */ @Test public void dynamicConstraintArgumentTest() { // Test constructor try { new DynamicConstraint(null, this.database, 1, new Feature(this.groupController.getSubspaceController(), this.database, 1, "Feature 1", false, false, 0, 1), Operator.EQUAL, 0.0f, true); Assert.fail("Group controller was null"); } catch (IllegalArgumentException e) { } try { new DynamicConstraint(this.groupController, null, 1, new Feature(this.groupController .getSubspaceController(), this.database, 1, "Feature 1", false, false, 0, 1), Operator.EQUAL, 0.0f, true); Assert.fail("Database was null"); } catch (IllegalArgumentException e) { } try { new DynamicConstraint(this.groupController, this.database, -1, new Feature(this.groupController .getSubspaceController(), this.database, 1, "Feature 1", false, false, 0, 1), Operator.EQUAL, 0.0f, true); Assert.fail("Id was negative"); } catch (IllegalArgumentException e) { } try { new DynamicConstraint(this.groupController, this.database, 1, null, Operator.EQUAL, 0.0f, true); Assert.fail("Feature was null"); } catch (IllegalArgumentException e) { } try { new DynamicConstraint(this.groupController, this.database, 1, new Feature(this.groupController .getSubspaceController(), this.database, 1, "Feature 1", false, false, 0, 1), null, 0.0f, true); Assert.fail("Operator was null"); } catch (IllegalArgumentException e) { } // Test setters DynamicConstraint constraint = new DynamicConstraint(this.groupController, this.database, 1, new Feature( this.groupController.getSubspaceController(), this.database, 1, "Feature 1", false, false, 0, 1), Operator.EQUAL, 0.0f, true); try { constraint.setFeature(null); Assert.fail("Feature was null"); } catch (IllegalArgumentException e) { } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } try { constraint.setOperator(null); Assert.fail("Operator was null"); } catch (IllegalArgumentException e) { } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } } /** * Tests all constructors and setters in class {@link StaticConstraint} for illegal argument exceptions */ @Test public void staticConstraintArgumentTest() { int[] selection = { 1, 2, 3 }; // Test constructor try { new StaticConstraint(null, this.database, 1, 1, selection, true); Assert.fail("Group controller was null"); } catch (IllegalArgumentException e) { } try { new StaticConstraint(this.groupController, null, 1, 1, selection, true); Assert.fail("Database was null"); } catch (IllegalArgumentException e) { } try { new StaticConstraint(this.groupController, this.database, -1, 1, selection, true); Assert.fail("Id was negative"); } catch (IllegalArgumentException e) { } try { new StaticConstraint(this.groupController, this.database, 1, -1, selection, true); Assert.fail("Group id was nnegative"); } catch (IllegalArgumentException e) { } try { new StaticConstraint(this.groupController, this.database, 1, 1, null, true); Assert.fail("Selection was null"); } catch (IllegalArgumentException e) { } try { int[] shortSelection = new int[0]; new StaticConstraint(this.groupController, this.database, 1, 1, shortSelection, true); Assert.fail("Selection has length zero"); } catch (IllegalArgumentException e) { } // Test setters StaticConstraint constraint = new StaticConstraint(this.groupController, this.database, 1, 1, selection, true); try { constraint.setSelection(null); Assert.fail("Selection was null"); } catch (IllegalArgumentException e) { } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } try { int[] shortSelection = new int[0]; constraint.setSelection(shortSelection); Assert.fail("Selection has length zero"); } catch (IllegalArgumentException e) { } catch (DatabaseAccessException e) { Assert.fail(e.getMessage()); } } }