| /* |
| * 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; |
| } |