| /* |
| * Copyright 2009 Google Inc. |
| * |
| * Licensed 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 com.google.gwt.uibinder.rebind.model; |
| |
| import com.google.gwt.core.ext.TreeLogger; |
| import com.google.gwt.core.ext.UnableToCompleteException; |
| import com.google.gwt.core.ext.typeinfo.JClassType; |
| import com.google.gwt.core.ext.typeinfo.JMethod; |
| import com.google.gwt.core.ext.typeinfo.JParameter; |
| import com.google.gwt.core.ext.typeinfo.JType; |
| import com.google.gwt.core.ext.typeinfo.TypeOracle; |
| import com.google.gwt.dev.javac.CompilationState; |
| import com.google.gwt.dev.javac.CompilationStateBuilder; |
| import com.google.gwt.dev.javac.impl.MockJavaResource; |
| import com.google.gwt.dev.resource.Resource; |
| import com.google.gwt.dev.util.log.PrintWriterTreeLogger; |
| import com.google.gwt.uibinder.client.UiHandler; |
| import com.google.gwt.uibinder.rebind.MortalLogger; |
| import com.google.gwt.uibinder.rebind.UiBinderContext; |
| import com.google.gwt.uibinder.test.UiJavaResources; |
| |
| import junit.framework.TestCase; |
| |
| import java.io.PrintWriter; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| /** |
| * Tests for the owner class descriptor. |
| */ |
| public class OwnerClassTest extends TestCase { |
| |
| private static TreeLogger createCompileLogger() { |
| PrintWriterTreeLogger logger = new PrintWriterTreeLogger(new PrintWriter( |
| System.err, true)); |
| logger.setMaxDetail(TreeLogger.ERROR); |
| return logger; |
| } |
| |
| private TypeOracle types; |
| private JClassType labelType; |
| private JClassType buttonType; |
| private JClassType clickEventType; |
| private JClassType mouseOverEventType; |
| private UiBinderContext uiBinderCtx; |
| |
| @Override |
| protected void setUp() throws Exception { |
| super.setUp(); |
| CompilationState state = CompilationStateBuilder.buildFrom( |
| createCompileLogger(), getJavaResources()); |
| types = state.getTypeOracle(); |
| uiBinderCtx = new UiBinderContext(); |
| labelType = types.findType("com.google.gwt.user.client.ui.Label"); |
| buttonType = types.findType("com.google.gwt.user.client.ui.Button"); |
| clickEventType = types.findType("com.google.gwt.event.dom.client.ClickEvent"); |
| mouseOverEventType = types.findType("com.google.gwt.event.dom.client.MouseOverEvent"); |
| } |
| |
| private Set<Resource> getJavaResources() { |
| MockJavaResource[] javaFiles = { |
| new MockJavaResource( |
| "com.google.gwt.uibinder.rebind.model.EmptyOwnerClass") { |
| @Override |
| protected CharSequence getContent() { |
| StringBuffer code = new StringBuffer(); |
| code.append("package com.google.gwt.uibinder.rebind.model;\n"); |
| code.append("public class EmptyOwnerClass {\n"); |
| code.append("}\n"); |
| return code; |
| } |
| }, |
| new MockJavaResource( |
| "com.google.gwt.uibinder.rebind.model.BadUiFactoryClass") { |
| @Override |
| protected CharSequence getContent() { |
| StringBuffer code = new StringBuffer(); |
| code.append("package com.google.gwt.uibinder.rebind.model;\n"); |
| code.append("import com.google.gwt.uibinder.client.UiFactory;\n"); |
| code.append("public class BadUiFactoryClass {\n"); |
| code.append(" @UiFactory int thisShouldntWork() { return 0; }\n"); |
| code.append("}\n"); |
| return code; |
| } |
| }, |
| new MockJavaResource( |
| "com.google.gwt.uibinder.rebind.model.UiFieldsClass") { |
| @Override |
| protected CharSequence getContent() { |
| StringBuffer code = new StringBuffer(); |
| code.append("package com.google.gwt.uibinder.rebind.model;\n"); |
| code.append("import com.google.gwt.user.client.ui.Button;\n"); |
| code.append("import com.google.gwt.user.client.ui.Label;\n"); |
| code.append("import com.google.gwt.uibinder.client.UiField;\n"); |
| code.append("public class UiFieldsClass {\n"); |
| code.append(" @UiField Label label1;"); |
| code.append(" @UiField(provided=true) Button button1;"); |
| code.append("}\n"); |
| return code; |
| } |
| }, |
| new MockJavaResource( |
| "com.google.gwt.uibinder.rebind.model.UiHandlersClass") { |
| @Override |
| protected CharSequence getContent() { |
| StringBuffer code = new StringBuffer(); |
| code.append("package com.google.gwt.uibinder.rebind.model;\n"); |
| code.append("import com.google.gwt.event.dom.client.ClickEvent;\n"); |
| code.append("import com.google.gwt.event.dom.client.MouseOverEvent;\n"); |
| code.append("import com.google.gwt.uibinder.client.UiHandler;\n"); |
| code.append("public class UiHandlersClass {\n"); |
| code.append(" @UiHandler(\"myField\") void onMyFieldClicked(ClickEvent ev) {}"); |
| code.append(" @UiHandler( {\"myField\", \"myOtherField\"}) void onMouseOver(MouseOverEvent ev){}"); |
| code.append("}\n"); |
| return code; |
| } |
| }, |
| new MockJavaResource( |
| "com.google.gwt.uibinder.rebind.model.BadUiFieldsClass") { |
| @Override |
| protected CharSequence getContent() { |
| StringBuffer code = new StringBuffer(); |
| code.append("package com.google.gwt.uibinder.rebind.model;\n"); |
| code.append("import com.google.gwt.uibinder.client.UiField;\n"); |
| code.append("public class BadUiFieldsClass {\n"); |
| code.append(" @UiField int thisShouldntWork;"); |
| code.append("}\n"); |
| return code; |
| } |
| }, |
| new MockJavaResource( |
| "com.google.gwt.uibinder.rebind.model.UiFactoryClass") { |
| @Override |
| protected CharSequence getContent() { |
| StringBuffer code = new StringBuffer(); |
| code.append("package com.google.gwt.uibinder.rebind.model;\n"); |
| code.append("import com.google.gwt.uibinder.client.UiFactory;\n"); |
| code.append("import com.google.gwt.user.client.ui.Label;\n"); |
| code.append("public class UiFactoryClass {"); |
| code.append(" @UiFactory"); |
| code.append(" Label createLabel() { return null; }"); |
| code.append("}\n"); |
| return code; |
| } |
| }, |
| new MockJavaResource("com.google.gwt.uibinder.rebind.model.Abstract") { |
| @Override |
| protected CharSequence getContent() { |
| StringBuffer code = new StringBuffer(); |
| code.append("package com.google.gwt.uibinder.rebind.model;\n"); |
| code.append("public class Abstract<T> {"); |
| code.append("}\n"); |
| return code; |
| } |
| }, |
| new MockJavaResource( |
| "com.google.gwt.uibinder.rebind.model.WildcardWidgetFactory") { |
| @Override |
| protected CharSequence getContent() { |
| StringBuffer code = new StringBuffer(); |
| code.append("package com.google.gwt.uibinder.rebind.model;\n"); |
| code.append("import com.google.gwt.uibinder.client.UiFactory;\n"); |
| code.append("public class WildcardWidgetFactory {"); |
| code.append(" @UiFactory"); |
| code.append(" Abstract<?> createOne() { return null; }"); |
| code.append("}\n"); |
| return code; |
| } |
| }, |
| new MockJavaResource( |
| "com.google.gwt.uibinder.rebind.model.ParamterizedWidgetFactory") { |
| @Override |
| protected CharSequence getContent() { |
| StringBuffer code = new StringBuffer(); |
| code.append("package com.google.gwt.uibinder.rebind.model;\n"); |
| code.append("import com.google.gwt.uibinder.client.UiFactory;\n"); |
| code.append("public class ParamterizedWidgetFactory {"); |
| code.append(" @UiFactory"); |
| code.append(" Abstract<String> createOne() { return null; }"); |
| code.append("}\n"); |
| return code; |
| } |
| }, |
| new MockJavaResource( |
| "com.google.gwt.uibinder.rebind.model.TooManyGenerics") { |
| @Override |
| protected CharSequence getContent() { |
| StringBuffer code = new StringBuffer(); |
| code.append("package com.google.gwt.uibinder.rebind.model;\n"); |
| code.append("import com.google.gwt.uibinder.client.UiFactory;\n"); |
| code.append("public class TooManyGenerics {"); |
| code.append(" @UiFactory"); |
| code.append(" Abstract<?> createSomething() { return null; }"); |
| code.append(" @UiFactory"); |
| code.append(" Abstract<String> createStringThing() { return null; }"); |
| code.append("}\n"); |
| return code; |
| } |
| }, |
| new MockJavaResource( |
| "com.google.gwt.uibinder.rebind.model.DuplicateUiFactoryClass") { |
| @Override |
| protected CharSequence getContent() { |
| StringBuffer code = new StringBuffer(); |
| code.append("package com.google.gwt.uibinder.rebind.model;\n"); |
| code.append("import com.google.gwt.uibinder.client.UiFactory;\n"); |
| code.append("import com.google.gwt.user.client.ui.Label;\n"); |
| code.append("public class DuplicateUiFactoryClass {"); |
| code.append(" @UiFactory"); |
| code.append(" Label labelFactory1() { return null; }"); |
| code.append(" @UiFactory"); |
| code.append(" Label labelFactory2() { return null; }"); |
| code.append("}\n"); |
| return code; |
| } |
| }, |
| new MockJavaResource( |
| "com.google.gwt.uibinder.rebind.model.ParentUiBinderClass") { |
| @Override |
| protected CharSequence getContent() { |
| StringBuffer code = new StringBuffer(); |
| code.append("package com.google.gwt.uibinder.rebind.model;\n"); |
| code.append("import com.google.gwt.event.dom.client.MouseOverEvent;\n"); |
| code.append("import com.google.gwt.uibinder.client.UiField;\n"); |
| code.append("import com.google.gwt.uibinder.client.UiFactory;\n"); |
| code.append("import com.google.gwt.uibinder.client.UiHandler;\n"); |
| code.append("import com.google.gwt.user.client.ui.Label;\n"); |
| code.append("public class ParentUiBinderClass {"); |
| code.append(" @UiField Label label1;"); |
| code.append(" @UiFactory Label createLabel() { return null; }"); |
| code.append(" @UiHandler(\"label1\")"); |
| code.append(" void onLabelMouseOver(MouseOverEvent e) { }"); |
| code.append("}\n"); |
| return code; |
| } |
| }, |
| new MockJavaResource( |
| "com.google.gwt.uibinder.rebind.model.ChildUiBinderClass") { |
| @Override |
| protected CharSequence getContent() { |
| StringBuffer code = new StringBuffer(); |
| code.append("package com.google.gwt.uibinder.rebind.model;\n"); |
| code.append("import com.google.gwt.event.dom.client.ClickEvent;\n"); |
| code.append("import com.google.gwt.uibinder.client.UiField;\n"); |
| code.append("import com.google.gwt.uibinder.client.UiFactory;\n"); |
| code.append("import com.google.gwt.uibinder.client.UiHandler;\n"); |
| code.append("import com.google.gwt.user.client.ui.Button;\n"); |
| code.append("public class ChildUiBinderClass extends ParentUiBinderClass {"); |
| code.append(" @UiField(provided = true) Button button1;"); |
| code.append(" @UiFactory Button createButton() { return null; }"); |
| code.append(" @UiHandler(\"button1\")"); |
| code.append(" void onButtonClicked(ClickEvent e) { }"); |
| code.append("}\n"); |
| return code; |
| } |
| },}; |
| |
| Set<Resource> rtn = new HashSet<Resource>(UiJavaResources.getUiResources()); |
| rtn.addAll(Arrays.asList(javaFiles)); |
| return rtn; |
| } |
| |
| @SuppressWarnings("deprecation") |
| public void testOwnerClass_empty() throws UnableToCompleteException { |
| JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.EmptyOwnerClass"); |
| OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL, |
| uiBinderCtx); |
| |
| assertNull(ownerClass.getUiFactoryMethod(labelType)); |
| assertNull(ownerClass.getUiField("fieldName")); |
| assertNull(ownerClass.getUiFieldForType(labelType)); |
| assertTrue(ownerClass.getUiFields().isEmpty()); |
| assertTrue(ownerClass.getUiHandlers().isEmpty()); |
| } |
| |
| public void testOwnerClass_uiFactory() throws UnableToCompleteException { |
| JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.UiFactoryClass"); |
| OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL, |
| uiBinderCtx); |
| |
| JMethod uiFactoryMethod = ownerClass.getUiFactoryMethod(labelType); |
| assertNotNull(uiFactoryMethod); |
| assertEquals("createLabel", uiFactoryMethod.getName()); |
| assertEquals(labelType, uiFactoryMethod.getReturnType()); |
| JParameter[] parameters = uiFactoryMethod.getParameters(); |
| assertNotNull(parameters); |
| assertEquals(0, parameters.length); |
| } |
| |
| public void testParameterizedWidgets() throws UnableToCompleteException { |
| JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.ParamterizedWidgetFactory"); |
| JClassType abstractType = types.findType("com.google.gwt.uibinder.rebind.model.Abstract"); |
| OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL, |
| uiBinderCtx); |
| |
| JMethod expected = ownerType.findMethod("createOne", new JType[] {}); |
| JMethod uiFactoryMethod = ownerClass.getUiFactoryMethod(abstractType); |
| |
| assertEquals(expected, uiFactoryMethod); |
| } |
| |
| public void testWildcardWidgets() throws UnableToCompleteException { |
| JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.WildcardWidgetFactory"); |
| JClassType abstractType = types.findType("com.google.gwt.uibinder.rebind.model.Abstract"); |
| OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL, |
| uiBinderCtx); |
| |
| JMethod expected = ownerType.findMethod("createOne", new JType[] {}); |
| JMethod uiFactoryMethod = ownerClass.getUiFactoryMethod(abstractType); |
| |
| assertEquals(expected, uiFactoryMethod); |
| } |
| |
| public void testHowSuckyWeReallyAreWithGenerics() { |
| JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.TooManyGenerics"); |
| |
| try { |
| new OwnerClass(ownerType, MortalLogger.NULL, uiBinderCtx); |
| fail(); |
| } catch (UnableToCompleteException e) { |
| /* pass */ |
| } |
| } |
| |
| public void testOwnerClass_uiFactoryBadType() { |
| JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.BadUiFactoryClass"); |
| try { |
| new OwnerClass(ownerType, MortalLogger.NULL, uiBinderCtx); |
| fail("Expected exception not thrown."); |
| } catch (UnableToCompleteException utce) { |
| // Expected |
| } |
| } |
| |
| public void testOwnerClass_uiFactoryDuplicateType() { |
| JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.DuplicateUiFactoryClass"); |
| try { |
| new OwnerClass(ownerType, MortalLogger.NULL, uiBinderCtx); |
| fail("Expected exception not thrown."); |
| } catch (UnableToCompleteException utce) { |
| // Expected |
| } |
| } |
| |
| @SuppressWarnings("deprecation") |
| public void testOwnerClass_uiFields() throws UnableToCompleteException { |
| JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.UiFieldsClass"); |
| OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL, |
| uiBinderCtx); |
| |
| OwnerField labelField = ownerClass.getUiField("label1"); |
| OwnerField labelField2 = ownerClass.getUiFieldForType(labelType); |
| assertNotNull(labelField); |
| assertNotNull(labelField2); |
| assertEquals(labelField, labelField2); |
| assertFalse(labelField.isProvided()); |
| assertEquals(labelType, labelField.getType().getRawType()); |
| assertEquals("label1", labelField.getName()); |
| |
| OwnerField buttonField = ownerClass.getUiField("button1"); |
| OwnerField buttonField2 = ownerClass.getUiFieldForType(buttonType); |
| assertNotNull(buttonField); |
| assertNotNull(buttonField2); |
| assertEquals(buttonField, buttonField2); |
| assertTrue(buttonField.isProvided()); |
| assertEquals(buttonType, buttonField.getType().getRawType()); |
| assertEquals("button1", buttonField.getName()); |
| |
| Collection<OwnerField> uiFields = ownerClass.getUiFields(); |
| Set<OwnerField> uiFieldSet = new HashSet<OwnerField>(uiFields); |
| Set<OwnerField> expectedFieldSet = new HashSet<OwnerField>(); |
| expectedFieldSet.add(labelField); |
| expectedFieldSet.add(buttonField); |
| assertEquals(expectedFieldSet, uiFieldSet); |
| } |
| |
| public void testOwnerClass_uiFieldsBadType() { |
| JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.BadUiFieldsClass"); |
| try { |
| new OwnerClass(ownerType, MortalLogger.NULL, uiBinderCtx); |
| fail("Expected exception not thrown."); |
| } catch (UnableToCompleteException utce) { |
| // Expected |
| } |
| } |
| |
| public void testOwnerClass_uiHandlers() throws UnableToCompleteException { |
| JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.UiHandlersClass"); |
| OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL, |
| uiBinderCtx); |
| |
| // Assert the two expected handlers are there |
| List<JMethod> uiHandlers = ownerClass.getUiHandlers(); |
| assertEquals(2, uiHandlers.size()); |
| JMethod clickMethod = null, mouseOverMethod = null; |
| |
| // Don't care about ordering |
| for (JMethod method : uiHandlers) { |
| if (method.getName().equals("onMyFieldClicked")) { |
| clickMethod = method; |
| } else if (method.getName().equals("onMouseOver")) { |
| mouseOverMethod = method; |
| } |
| } |
| |
| assertNotNull(clickMethod); |
| assertNotNull(mouseOverMethod); |
| |
| // Check the click handler |
| JParameter[] clickParams = clickMethod.getParameters(); |
| assertEquals(1, clickParams.length); |
| assertEquals(clickEventType, clickParams[0].getType()); |
| assertTrue(clickMethod.isAnnotationPresent(UiHandler.class)); |
| UiHandler clickAnnotation = clickMethod.getAnnotation(UiHandler.class); |
| String[] clickFields = clickAnnotation.value(); |
| assertEquals(1, clickFields.length); |
| assertEquals("myField", clickFields[0]); |
| |
| // Check the mouse over handler |
| JParameter[] mouseOverParams = mouseOverMethod.getParameters(); |
| assertEquals(1, mouseOverParams.length); |
| assertEquals(mouseOverEventType, mouseOverParams[0].getType()); |
| assertTrue(mouseOverMethod.isAnnotationPresent(UiHandler.class)); |
| UiHandler mouseOverAnnotation = mouseOverMethod.getAnnotation(UiHandler.class); |
| String[] mouseOverFields = mouseOverAnnotation.value(); |
| assertEquals(2, mouseOverFields.length); |
| assertEquals("myField", mouseOverFields[0]); |
| assertEquals("myOtherField", mouseOverFields[1]); |
| } |
| |
| @SuppressWarnings("deprecation") |
| public void testOwnerClass_withParent() throws UnableToCompleteException { |
| JClassType ownerType = types.findType("com.google.gwt.uibinder.rebind.model.ChildUiBinderClass"); |
| OwnerClass ownerClass = new OwnerClass(ownerType, MortalLogger.NULL, |
| uiBinderCtx); |
| |
| // Test fields |
| OwnerField labelField = ownerClass.getUiField("label1"); |
| OwnerField labelField2 = ownerClass.getUiFieldForType(labelType); |
| assertNotNull(labelField); |
| assertNotNull(labelField2); |
| assertEquals(labelField, labelField2); |
| assertFalse(labelField.isProvided()); |
| assertEquals(labelType, labelField.getType().getRawType()); |
| assertEquals("label1", labelField.getName()); |
| |
| OwnerField buttonField = ownerClass.getUiField("button1"); |
| OwnerField buttonField2 = ownerClass.getUiFieldForType(buttonType); |
| assertNotNull(buttonField); |
| assertNotNull(buttonField2); |
| assertEquals(buttonField, buttonField2); |
| assertTrue(buttonField.isProvided()); |
| assertEquals(buttonType, buttonField.getType().getRawType()); |
| assertEquals("button1", buttonField.getName()); |
| |
| Collection<OwnerField> uiFields = ownerClass.getUiFields(); |
| Set<OwnerField> uiFieldSet = new HashSet<OwnerField>(uiFields); |
| Set<OwnerField> expectedFieldSet = new HashSet<OwnerField>(); |
| expectedFieldSet.add(labelField); |
| expectedFieldSet.add(buttonField); |
| assertEquals(expectedFieldSet, uiFieldSet); |
| |
| // Test factories |
| JMethod labelFactoryMethod = ownerClass.getUiFactoryMethod(labelType); |
| assertNotNull(labelFactoryMethod); |
| assertEquals("createLabel", labelFactoryMethod.getName()); |
| assertEquals(labelType, labelFactoryMethod.getReturnType()); |
| JParameter[] labelParams = labelFactoryMethod.getParameters(); |
| assertNotNull(labelParams); |
| assertEquals(0, labelParams.length); |
| |
| JMethod buttonFactoryMethod = ownerClass.getUiFactoryMethod(labelType); |
| assertNotNull(buttonFactoryMethod); |
| assertEquals("createLabel", buttonFactoryMethod.getName()); |
| assertEquals(labelType, buttonFactoryMethod.getReturnType()); |
| JParameter[] buttonParams = buttonFactoryMethod.getParameters(); |
| assertNotNull(buttonParams); |
| assertEquals(0, buttonParams.length); |
| |
| // Test handlers |
| List<JMethod> uiHandlers = ownerClass.getUiHandlers(); |
| assertEquals(2, uiHandlers.size()); |
| JMethod clickMethod = null, mouseOverMethod = null; |
| |
| for (JMethod method : uiHandlers) { |
| if (method.getName().equals("onButtonClicked")) { |
| clickMethod = method; |
| } else if (method.getName().equals("onLabelMouseOver")) { |
| mouseOverMethod = method; |
| } |
| } |
| |
| assertNotNull(clickMethod); |
| assertNotNull(mouseOverMethod); |
| |
| JParameter[] clickParams = clickMethod.getParameters(); |
| assertEquals(1, clickParams.length); |
| assertEquals(clickEventType, clickParams[0].getType()); |
| assertTrue(clickMethod.isAnnotationPresent(UiHandler.class)); |
| UiHandler clickAnnotation = clickMethod.getAnnotation(UiHandler.class); |
| String[] clickFields = clickAnnotation.value(); |
| assertEquals(1, clickFields.length); |
| assertEquals("button1", clickFields[0]); |
| |
| JParameter[] mouseOverParams = mouseOverMethod.getParameters(); |
| assertEquals(1, mouseOverParams.length); |
| assertEquals(mouseOverEventType, mouseOverParams[0].getType()); |
| assertTrue(mouseOverMethod.isAnnotationPresent(UiHandler.class)); |
| UiHandler mouseOverAnnotation = mouseOverMethod.getAnnotation(UiHandler.class); |
| String[] mouseOverFields = mouseOverAnnotation.value(); |
| assertEquals(1, mouseOverFields.length); |
| assertEquals("label1", mouseOverFields[0]); |
| } |
| } |