blob: 2e172e1d559dd864962c7d1bdd23bed583e8ca81 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.netbeans.swing.tabcontrol;
import java.awt.Component;
import java.awt.Graphics;
import java.util.Arrays;
import java.util.EventObject;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.event.ListDataEvent;
import junit.framework.TestCase;
import org.netbeans.swing.tabcontrol.event.ComplexListDataEvent;
import org.netbeans.swing.tabcontrol.event.ComplexListDataListener;
/** Some basic tests for DefaultTabDataModel, etc. Can be fleshed out into proper
* unit tests later.
*
* @author Tim Boudreau
*/
public class DataModelTest extends TestCase implements ComplexListDataListener {
ComplexListDataEvent lastEvent = null;
String lastListenerCall=null;
public DataModelTest(String testName) {
super(testName);
}
TabDataModel mdl=null;
Icon ic = new Icon () {
public int getIconWidth() {
return 16;
}
public int getIconHeight() {
return 16;
}
public void paintIcon (Component c, Graphics g, int x, int y) {
//do nothing
}
};
Icon sameSizeIcon = new Icon () {
public int getIconWidth() {
return 16;
}
public int getIconHeight() {
return 16;
}
public void paintIcon (Component c, Graphics g, int x, int y) {
//do nothing
}
};
Icon biggerIcon = new Icon () {
public int getIconWidth() {
return 22;
}
public int getIconHeight() {
return 22;
}
public void paintIcon (Component c, Graphics g, int x, int y) {
//do nothing
}
};
public void setUp () {
prepareModel();
mdl.addComplexListDataListener(this);
}
/** Weird, but this class was adapted from a standalone test written
* long ago and rescued from cvs history. It didn't use JUnit, and
* the assertTrue argument order was reversed. So in the interest of
* laziness... */
private void assertPravda (boolean val, String msg) {
assertTrue (msg, val);
}
private void assertText (String name, int index) {
TabData td = mdl.getTab (index);
assertPravda (td.getText().equals (name), "Text at " + index + " was not " + name + " it was " + td.getText());
}
private void assertData (int index, TabData data) {
TabData other = mdl.getTab (index);
assertPravda (data.equals(other), "TabData at " + index + " is not " + data + " it is " + other);
}
private void assertListenerCall (String call) {
assertPravda (lastEvent != null, "Last listener call should be non-null");
assertPravda (call.equals (lastListenerCall), "Last listener call should have been " + call + " but was " + lastListenerCall);
}
private void assertEventIndices (int indices[]) {
assertPravda (lastEvent != null, "Last event should have been fired but is null");
int[] ids = lastEvent.getIndices();
Arrays.sort (indices);
Arrays.sort (ids);
assertPravda (ids.length == indices.length, "Indices length in last change should be " + indices.length + " but is " + ids.length + " expected indices: " + arrToStr (indices) + " actual indices " + arrToStr(ids));
for (int i=0; i < ids.length; i++) {
assertPravda (ids[i] == indices[i], "Event indices should be " + arrToStr(indices) + " but are " + arrToStr(ids));
}
}
private void assertEventIndices (int start, int end) {
assertPravda (lastEvent != null, "Last event should have been fired but is null");
assertPravda (start == lastEvent.getIndex0(), "Event start index should be " + start + " but is " + lastEvent.getIndex0());
assertPravda (end == lastEvent.getIndex1(), "Event end index should be " + end + " but is " + lastEvent.getIndex1());
}
private void assertWidthChanged () {
assertPravda (lastEvent != null, "Last event should have been fired but is null");
assertPravda (lastEvent.isTextChanged(), "Last event should have been a text change event but wasn't");
}
private void assertWidthNotChanged () {
assertPravda (lastEvent != null, "Last event should have been fired but is null");
assertPravda (!lastEvent.isTextChanged(), "Last event should not have been a text change event but was");
}
/**
* Since this test was written in non-junit style, the order of the tests
* is important, so we have one junit method for all of the actual tests.
*/
public void testEverything() {
doTestContentsValid();
doTestAdd();
doTestRemove();
doTestAddContiguous();
doTestRemoveContiguous();
doTestAddNonContiguous();
doTestRemoveNonContiguous();
doTestSetTab();
doTestSetTextNonContiguous();
doTestSetIconNonContiguous();
doTestSetIconAndTextNonContiguous();
System.err.println("All tests passed");
}
public void doTestContentsValid () {
System.err.println("testContentsValid");
_testContentsValid();
}
private void _testContentsValid () {
int ct=0;
for (char c='a'; c < 'z'; c++) {
TabData td = mdl.getTab(ct);
assertPravda (td.getText().charAt(0) == c, "Name at " + ct + " is not " + c + " it is " + td.getText());
ct++;
}
}
public void doTestAdd () {
System.err.println("testAdd");
TabData td = new TabData (new JLabel ("testAdd"), ic, "testAdd", "Tip:testAdd");
mdl.addTabs(0, new TabData[] {td});
assertData (0, td);
}
public void doTestRemove () {
System.err.println("testRemove");
mdl.removeTab(0);
assertText ("a", 0);
}
public void doTestAddContiguous() {
System.err.println("testAddContiguous");
int formerSize = mdl.size();
TabData[] td = new TabData[10];
for (int i=0; i < 10; i++) {
String name = Integer.toString (i);
Component comp = new JLabel();
td[i] = new TabData (comp, ic, name, "Tip:"+name);
}
mdl.addTabs(10, td);
int expectedSize=formerSize+10;
assertPravda (mdl.size() == expectedSize, "Model size should be " + expectedSize + " after adding 10 items, but is " + mdl.size());
for (int i=10; i < 20; i++) {
assertData (i, td[i-10]);
}
}
public void doTestRemoveContiguous() {
System.err.println("testRemoveContiguous");
int formerSize = mdl.size();
mdl.removeTabs (10, 20);
int expectedSize=formerSize - 10;
assertPravda (mdl.size() == expectedSize, "Model size should be " + expectedSize + " after removing 10 items, but is " + mdl.size());
try {
_testContentsValid();
} catch (RuntimeException e) {
e.printStackTrace();
fail("After removing 10 items, contents should be original contents, but are " + mdl.toString());
}
}
TabData[] data=null;
public void doTestAddNonContiguous () {
System.err.println("testAddNonContiguous");
int[] indices = new int[] {3, 1, 5};
data = new TabData[3];
for (int i=0; i < indices.length; i++) {
String name = Integer.toString (indices[i]);
data[i] = new TabData (new JLabel(), ic, name, "Tip:"+name);
}
mdl.addTabs(indices, data);
assertData (3, data[0]);
assertData (1, data[1]);
assertData (5, data[2]);
Arrays.sort (indices);
assertEventIndices (indices);
assertListenerCall ("indicesAdded");
}
public void doTestRemoveNonContiguous () {
int[] indices = new int[] {5, 1, 3};
mdl.removeTabs(indices);
try {
_testContentsValid();
} catch (RuntimeException e) {
System.err.println("After non-contiguous removal of " + arrToStr(indices) + ", contents should be original contents, but are " + mdl.toString());
throw e;
}
Arrays.sort(indices);
assertEventIndices (indices);
assertListenerCall ("indicesRemoved");
}
public void doTestSetTab () {
System.err.println("testSetTab");
TabData former = mdl.getTab (22);
TabData nue = new TabData (new JLabel(), ic, "foo", "Tip:foo");
mdl.setTab (22, nue);
assertData (22, nue);
mdl.setTab (22, former);
assertListenerCall ("contentsChanged");
assertEventIndices (22, 22);
//Make sure an event is not generated for changes that should not generate one
noEvent = true;
mdl.setTab (22, former);
mdl.setText(22, former.getText());
mdl.setIcon (22, ic);
noEvent = false;
}
public void doTestSetTextNonContiguous() {
System.err.println("testSetTextNonContiguous");
String[] names = new String [5];
int[] indices = new int[] {22,11,15,8,3};
for (int i=0; i < names.length; i++) {
names[i] = mdl.getTab(indices[i]).getText();
}
noEvent = true;
//should produce no event since the names haven't changed
mdl.setText(indices, names);
noEvent = false;
String[] s = new String[names.length];
for (int i=0; i < s.length; i++) {
s[i] = names[i] + "modified";
}
mdl.setText(indices, s);
for (int i=0; i < s.length; i++) {
assertText(s[i], indices[i]);
}
Arrays.sort (indices);
assertEventIndices(indices);
assertListenerCall("contentsChanged");
assertWidthChanged();
//restore the original text
mdl.setText(indices, names);
}
public void doTestSetIcon () {
System.err.println("testSetIcon");
TabData td = mdl.getTab (20);
noEvent = true;
mdl.setIcon(20, td.getIcon());
noEvent = false;
mdl.setIcon(20, sameSizeIcon);
assertEventIndices(20,20);
assertListenerCall("contentsChanged");
assertPravda (td.getIcon() == sameSizeIcon, "Icon was changed but same old still returned from TabData");
assertWidthNotChanged();
EventObject last = lastEvent;
mdl.setIcon(20, biggerIcon);
assertWidthChanged();
assertPravda (last != lastEvent, "Icon changed but no event fired");
//restore the state
mdl.setIcon(20,ic);
}
public void doTestSetIconNonContiguous() {
System.err.println("testSetIconNonContiguous");
Icon[] icons = new Icon[5];
int[] indices = new int[] {22,11,15,8,3};
for (int i=0; i < icons.length; i++) {
icons[i] = mdl.getTab(indices[i]).getIcon();
}
noEvent = true;
//should produce no event since the names haven't changed
mdl.setIcon(indices, icons);
noEvent = false;
EventObject last = lastEvent;
Arrays.fill (icons, sameSizeIcon);
mdl.setIcon (indices, icons);
assertPravda (last != lastEvent, "Icons changed but no event fired");
last = lastEvent;
assertListenerCall("contentsChanged");
assertWidthNotChanged();
Arrays.fill (icons, biggerIcon);
icons[2] = sameSizeIcon;
int[] expectedIndices = new int[]{3,8,22,11};
mdl.setIcon(indices, icons);
assertPravda (last != lastEvent, "Icons changed but no event fired");
assertListenerCall("contentsChanged");
assertWidthChanged();
assertEventIndices(expectedIndices);
Arrays.fill (icons, ic);
//restore the original text
mdl.setIcon(indices, icons);
}
public void doTestSetIconAndTextNonContiguous() {
System.err.println("testSetIconAndTextNonContiguous");
int indices[] = new int[] {3, 10, 5};
Icon[] icons = new Icon[3];
Arrays.fill (icons, ic);
String[] sts = new String[3];
for (int i=0; i < 3; i++) {
sts[i] = mdl.getTab(i).getText();
}
//ensure expected results
mdl.setIconsAndText (indices, sts, icons);
noEvent = true;
mdl.setIconsAndText(indices, sts, icons);
noEvent = false;
String[] realText = new String[sts.length];
System.arraycopy(sts, 0, realText, 0, sts.length);
EventObject last = lastEvent;
icons[0] = sameSizeIcon;
mdl.setIconsAndText(indices, sts, icons);
assertPravda (last != lastEvent, "Icons and text changed but no event fired");
assertWidthNotChanged();
assertEventIndices(new int[] {3});
last = lastEvent;
icons[0] = biggerIcon;
sts[1] = "foobar";
mdl.setIconsAndText(indices, sts, icons);
assertPravda (last != lastEvent, "Icons and text changed but no event fired");
assertWidthChanged();
assertEventIndices(new int[] {3, 10});
last = lastEvent;
//Also test the simpler firing code for when all changed icons have changed text
icons[0] = ic;
sts[1] = "boo";
mdl.setIconsAndText(indices, sts, icons);
assertPravda (last != lastEvent, "Icons and text changed but no event fired");
assertWidthChanged();
assertEventIndices(new int[] {3, 10});
//restore the state
Arrays.fill (icons, ic);
mdl.setIconsAndText (indices, realText, icons);
}
static String arrToStr (int[] ints) {
if (ints == null) return "null";
StringBuffer out = new StringBuffer (ints.length * 3);
for (int i=0; i < ints.length; i++) {
out.append (ints[i]);
if (i != ints.length-1) {
out.append (",");
}
}
return out.toString();
}
static String arrToStr (Object[] o) {
if (o == null) return "null";
StringBuffer out = new StringBuffer (o.length * 3);
for (int i=0; i < o.length; i++) {
out.append (o[i]);
if (i != o.length-1) {
out.append (",");
}
}
return out.toString();
}
private void prepareModel() {
if (mdl != null) {
mdl.removeComplexListDataListener(this);
}
TabData[] td = new TabData[25];
int ct = 0;
for (char c='a'; c < 'z'; c++) {
String name = new String (new char[]{c});
Component comp = new JLabel(name);
comp.setName (name);
td[ct] = new TabData (comp, ic, name, "tip:"+name);
ct++;
}
mdl = new DefaultTabDataModel (td);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
new DataModelTest("foo").run();
}
public void contentsChanged(ListDataEvent e) {
lastListenerCall="contentsChanged";
lastEvent = (ComplexListDataEvent)e;
if (noEvent) {
assertPravda (false, "No event expected but " + e + " receieved");
}
}
public void indicesAdded(ComplexListDataEvent e) {
lastListenerCall="indicesAdded";
lastEvent = e;
if (noEvent) {
assertPravda (false, "No event expected but " + e + " receieved");
}
}
public void indicesChanged(ComplexListDataEvent e) {
lastListenerCall="indicesChanged";
lastEvent = e;
if (noEvent) {
assertPravda (false, "No event expected but " + e + " receieved");
}
}
public void indicesRemoved(ComplexListDataEvent e) {
lastListenerCall="indicesRemoved";
lastEvent = e;
if (noEvent) {
assertPravda (false, "No event expected but " + e + " receieved");
}
}
public void intervalAdded(ListDataEvent e) {
lastListenerCall="intervalAdded";
assertPravda (e.getIndex0() <= e.getIndex1(), "Event start index > end index");
lastEvent = (ComplexListDataEvent)e;
if (noEvent) {
assertPravda (false, "No event expected but " + e + " receieved");
}
}
public void intervalRemoved(ListDataEvent e) {
lastListenerCall="intervalRemoved";
lastEvent = (ComplexListDataEvent)e;
if (noEvent) {
assertPravda (false, "No event expected but " + e + " receieved");
}
}
boolean noEvent = false;
}