package com.vaadin.tests.design; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import org.junit.Assert; import com.vaadin.shared.Connector; import com.vaadin.ui.Component; import com.vaadin.ui.Flash; public abstract class DeclarativeTestBase extends DeclarativeTestBaseBase { private static final boolean debug = false; private final Map, EqualsAsserter> comparators = new HashMap<>(); private static final EqualsAsserter standardEqualsComparator = (EqualsAsserter) Assert::assertEquals; public class IntrospectorEqualsAsserter implements EqualsAsserter { private final Class clazz; public IntrospectorEqualsAsserter(Class clazz) { this.clazz = clazz; } @Override public void assertObjectEquals(C object1, C object2) { try { BeanInfo bi = Introspector.getBeanInfo(clazz); for (PropertyDescriptor pd : bi.getPropertyDescriptors()) { Method readMethod = pd.getReadMethod(); Method writeMethod = pd.getWriteMethod(); if (acceptProperty(clazz, readMethod, writeMethod)) { Object property1 = readMethod.invoke(object1); Object property2 = readMethod.invoke(object2); assertEquals(pd.getDisplayName(), property1, property2); } } } catch (Exception e) { throw new RuntimeException(e); } } } { comparators.put(Flash.class, new IntrospectorEqualsAsserter(Flash.class) { @Override public void assertObjectEquals(Flash o1, Flash o2) { super.assertObjectEquals(o1, o2); assertEquals("parameterNames", o1.getParameterNames(), o2.getParameterNames()); for (String name : o1.getParameterNames()) { assertEquals("Parameter " + name, o1.getParameter(name), o2.getParameter(name)); } } }); } protected boolean acceptProperty(Class clazz, Method readMethod, Method writeMethod) { if (readMethod == null || writeMethod == null) { return false; } // Needed to access public properties inherited from a // nonpublic superclass, see #17425 readMethod.setAccessible(true); writeMethod.setAccessible(true); if (Connector.class.isAssignableFrom(clazz) && readMethod.getName().equals("getParent")) { // Hack to break cycles in the connector hierarchy return false; } try { clazz.getDeclaredMethod(readMethod.getName()); } catch (Exception e) { // Not declared in this class, will be tested by parent // class tester if (debug) { System.out.println("Skipped " + clazz.getSimpleName() + "." + readMethod.getName()); } return false; } if (debug) { System.out.println("Testing " + clazz.getSimpleName() + "." + readMethod.getName()); } return true; } @Override protected EqualsAsserter getComparator(Class c) { com.vaadin.tests.design.DeclarativeTestBaseBase.EqualsAsserter comp = comparators .get(c); if (comp == null) { if (c.isEnum()) { return standardEqualsComparator; } if (debug) { System.out.println("No comparator found for " + c.getName() + ". Using introspector."); } return new IntrospectorEqualsAsserter<>(c); } return comp; } }