You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ParameterizedTB3Runner.java 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. * Copyright 2000-2016 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.tests.tb3;
  17. import java.lang.reflect.Method;
  18. import java.lang.reflect.Modifier;
  19. import java.util.ArrayList;
  20. import java.util.Collection;
  21. import java.util.LinkedHashMap;
  22. import java.util.List;
  23. import java.util.Map;
  24. import java.util.Objects;
  25. import org.junit.runners.Parameterized.Parameters;
  26. import org.junit.runners.model.FrameworkMethod;
  27. import org.junit.runners.model.InitializationError;
  28. /**
  29. * TestBench test runner which supports static @Parameters annotated methods
  30. * providing parameters for the corresponding setter.
  31. * <p>
  32. * {@code @Parameters public static Collection<String> getThemes() } creates one
  33. * permutation for each value returned by {@code getThemes()}. The value is
  34. * automatically assigned to the test instance using {@code setTheme(String)}
  35. * before invoking the test method
  36. *
  37. * @author Vaadin Ltd
  38. */
  39. public class ParameterizedTB3Runner extends TB3Runner {
  40. public ParameterizedTB3Runner(Class<?> klass) throws InitializationError {
  41. super(klass);
  42. }
  43. @Override
  44. protected List<FrameworkMethod> computeTestMethods() {
  45. List<FrameworkMethod> methods = super.computeTestMethods();
  46. Map<Method, Collection<String>> parameters = new LinkedHashMap<>();
  47. // Find all @Parameters methods and invoke them to find out permutations
  48. for (Method m : getTestClass().getJavaClass().getMethods()) {
  49. Parameters p = m.getAnnotation(Parameters.class);
  50. if (p == null) {
  51. continue;
  52. }
  53. if (!m.getName().startsWith("get") || !m.getName().endsWith("s")) {
  54. throw new IllegalStateException("Method " + m.getName()
  55. + " is annotated with @Parameter but is not named getSomeThings() as it should");
  56. }
  57. if (m.getParameterTypes().length != 0) {
  58. throw new IllegalStateException("Method " + m.getName()
  59. + " annotated with @Parameter should not have any arguments");
  60. }
  61. if (!Modifier.isStatic(m.getModifiers())) {
  62. throw new IllegalStateException("Method " + m.getName()
  63. + " annotated with @Parameter must be static");
  64. }
  65. // getThemes -> setTheme
  66. String setter = "set" + m.getName().substring("get".length());
  67. setter = setter.substring(0, setter.length() - 1);
  68. // property = property.substring(0, 1).toLowerCase()
  69. // + property.substring(1);
  70. Method setterMethod;
  71. try {
  72. setterMethod = getTestClass().getJavaClass().getMethod(setter,
  73. String.class);
  74. } catch (Exception e) {
  75. throw new IllegalStateException(
  76. "No setter " + setter + " found in "
  77. + getTestClass().getJavaClass().getName(),
  78. e);
  79. }
  80. Collection<String> values;
  81. try {
  82. values = (Collection<String>) m.invoke(null);
  83. if (!values.isEmpty()) {
  84. // Ignore any empty collections to allow e.g. integration
  85. // tests to use "/demo" path by default without adding that
  86. // to the screenshot name
  87. parameters.put(setterMethod, values);
  88. }
  89. } catch (Exception e) {
  90. throw new IllegalStateException(
  91. "The setter " + m.getName() + " could not be invoked",
  92. e);
  93. }
  94. }
  95. // Add method permutations for all @Parameters
  96. for (Method setter : parameters.keySet()) {
  97. List<FrameworkMethod> newMethods = new ArrayList<>();
  98. for (FrameworkMethod m : methods) {
  99. if (!(m instanceof TBMethod)) {
  100. System.err.println(
  101. "Unknown method type: " + m.getClass().getName());
  102. newMethods.add(m);
  103. continue;
  104. }
  105. // testFoo
  106. // testBar
  107. // ->
  108. // testFoo[valo]
  109. // testFoo[runo]
  110. // testBar[valo]
  111. // testBar[runo]
  112. for (final String value : parameters.get(setter)) {
  113. newMethods.add(new TBMethodWithBefore((TBMethod) m, setter,
  114. value));
  115. }
  116. }
  117. // Update methods so next parameters will use all expanded methods
  118. methods = newMethods;
  119. }
  120. return methods;
  121. }
  122. public static class TBMethodWithBefore extends TBMethod {
  123. private Method setter;
  124. private String value;
  125. private TBMethod parent;
  126. public TBMethodWithBefore(TBMethod m, Method setter, String value) {
  127. super(m.getMethod(), m.getCapabilities());
  128. parent = m;
  129. this.setter = setter;
  130. this.value = value;
  131. }
  132. @Override
  133. public Object invokeExplosively(Object target, Object... params)
  134. throws Throwable {
  135. setter.invoke(target, value);
  136. return parent.invokeExplosively(target, params);
  137. }
  138. @Override
  139. public String getName() {
  140. return parent.getName() + "[" + value + "]";
  141. };
  142. @Override
  143. public boolean equals(Object obj) {
  144. if (!TBMethodWithBefore.class.isInstance(obj)) {
  145. return false;
  146. }
  147. TBMethodWithBefore otherTbMethod = (TBMethodWithBefore) obj;
  148. return super.equals(obj)
  149. && Objects.equals(otherTbMethod.parent, parent)
  150. && Objects.equals(otherTbMethod.setter, setter)
  151. && Objects.equals(otherTbMethod.value, value);
  152. }
  153. }
  154. }