diff --git a/CHANGES.txt b/CHANGES.txt index 9fed42440d..590c36fed9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ Current (7.11.0) +Fixed: GITHUB-3111: Replacement API for IClass.getInstanceHashCodes() and IClass.getInstances(boolean) (Krishnan Mahadevan) 7.10.2 Fixed: GITHUB-3117: ListenerComparator doesn't work (Krishnan Mahadevan) diff --git a/testng-core-api/src/main/java/org/testng/IFactoryMethod.java b/testng-core-api/src/main/java/org/testng/IFactoryMethod.java new file mode 100644 index 0000000000..6b11bef48c --- /dev/null +++ b/testng-core-api/src/main/java/org/testng/IFactoryMethod.java @@ -0,0 +1,12 @@ +package org.testng; + +import java.util.Optional; + +/** Represents a factory method */ +public interface IFactoryMethod { + + /** + * @return - Returns parameters associated with a factory method wrapped within a {@link Optional} + */ + Optional getParameters(); +} diff --git a/testng-core-api/src/main/java/org/testng/ITestClassInstance.java b/testng-core-api/src/main/java/org/testng/ITestClassInstance.java new file mode 100644 index 0000000000..509b609599 --- /dev/null +++ b/testng-core-api/src/main/java/org/testng/ITestClassInstance.java @@ -0,0 +1,33 @@ +package org.testng; + +/** Represents the ability to retrieve the parameters associated with a factory method. */ +public interface ITestClassInstance { + + /** @return - The actual instance associated with a factory method */ + T getInstance(); + + /** + * @return - The actual index of instance associated with a factory method. This index has a 1:1 + * correspondence with what were specified via the indices attribute of the + * @Factory annotation. For e.g., lets say you specified the indices to the "1" + * and your factory returned 4 instances, then the instance on which this method is invoked + * would have the value as "1". + */ + int getIndex(); + + /** + * @return - returns an index which indicates the running position in the array of test class + * instances that were produced by a @Factory annotated constructor or static + * method. For e.g., lets say your @Factory method returned 4 instances, then + * each of the invocations to this method would return a value from 0 to 3 + * + */ + int getInvocationIndex(); + + static Object embeddedInstance(Object original) { + if (original instanceof ITestClassInstance) { + return ((ITestClassInstance) original).getInstance(); + } + return original; + } +} diff --git a/testng-core-api/src/main/java/org/testng/ITestNGMethod.java b/testng-core-api/src/main/java/org/testng/ITestNGMethod.java index bff0385de1..add31af349 100644 --- a/testng-core-api/src/main/java/org/testng/ITestNGMethod.java +++ b/testng-core-api/src/main/java/org/testng/ITestNGMethod.java @@ -2,6 +2,7 @@ import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.Callable; import org.testng.annotations.CustomAttribute; @@ -269,6 +270,14 @@ default IParameterInfo getFactoryMethodParamsInfo() { return null; } + /** + * @return - A {@link IFactoryMethod} implementation that contains attributes associated with a + * factory method, wrapped within an {@link Optional}. + */ + default Optional getFactoryMethod() { + return Optional.empty(); + } + /** * @return - An array of {@link CustomAttribute} that represents the custom attributes associated * with a test. diff --git a/testng-core-api/src/main/java/org/testng/internal/IParameterInfo.java b/testng-core-api/src/main/java/org/testng/internal/IParameterInfo.java index 6ccf1b041c..99ed97cf5f 100644 --- a/testng-core-api/src/main/java/org/testng/internal/IParameterInfo.java +++ b/testng-core-api/src/main/java/org/testng/internal/IParameterInfo.java @@ -1,21 +1,20 @@ package org.testng.internal; -/** Represents the ability to retrieve the parameters associated with a factory method. */ -public interface IParameterInfo { +import org.testng.ITestClassInstance; +import org.testng.ITestNGMethod; - /** @return - The actual instance associated with a factory method */ - Object getInstance(); - - /** @return - The actual index of instance associated with a factory method */ - int getIndex(); - - /** @return - The parameters associated with the factory method as an array. */ +/** + * Represents the ability to retrieve the parameters associated with a factory method. + * + * @deprecated - This interface stands deprecated as of TestNG 7.11.0. + */ +@Deprecated +public interface IParameterInfo extends ITestClassInstance { + /** + * @return - The parameters associated with the factory method as an array. + * @deprecated - This method stands deprecated as of TestNG 7.11.0 Please use {@link + * ITestNGMethod#getFactoryMethod()} to retrieve the parameters. + */ + @Deprecated Object[] getParameters(); - - static Object embeddedInstance(Object original) { - if (original instanceof IParameterInfo) { - return ((IParameterInfo) original).getInstance(); - } - return original; - } } diff --git a/testng-core/src/main/java/org/testng/DependencyMap.java b/testng-core/src/main/java/org/testng/DependencyMap.java index 7d834ff7d2..d998f73d54 100644 --- a/testng-core/src/main/java/org/testng/DependencyMap.java +++ b/testng-core/src/main/java/org/testng/DependencyMap.java @@ -107,8 +107,7 @@ private static boolean hasInstance( Object derivedInstance = derivedClassMethod.getInstance(); boolean result = derivedInstance != null || baseInstance != null; boolean params = - null != baseClassMethod.getFactoryMethodParamsInfo() - && null != derivedClassMethod.getFactoryMethodParamsInfo().getParameters(); + baseClassMethod.getFactoryMethod().flatMap(IFactoryMethod::getParameters).isPresent(); if (result && params && RuntimeBehavior.enforceThreadAffinity()) { return hasSameParameters(baseClassMethod, derivedClassMethod); @@ -118,10 +117,17 @@ private static boolean hasInstance( private static boolean hasSameParameters( ITestNGMethod baseClassMethod, ITestNGMethod derivedClassMethod) { - return baseClassMethod - .getFactoryMethodParamsInfo() - .getParameters()[0] - .equals(derivedClassMethod.getFactoryMethodParamsInfo().getParameters()[0]); + Optional first = baseClassMethod.getFactoryMethod(); + Optional second = derivedClassMethod.getFactoryMethod(); + if (first.isPresent() && second.isPresent()) { + Optional firstParams = first.get().getParameters(); + Optional secondParams = second.get().getParameters(); + if (firstParams.isPresent() && secondParams.isPresent()) { + return firstParams.get()[0].equals(secondParams.get()[0]); + } + return false; + } + return false; } private static boolean isSameInstance( diff --git a/testng-core/src/main/java/org/testng/TestClass.java b/testng-core/src/main/java/org/testng/TestClass.java index 7e9dea897d..518121c49c 100644 --- a/testng-core/src/main/java/org/testng/TestClass.java +++ b/testng-core/src/main/java/org/testng/TestClass.java @@ -126,7 +126,7 @@ private void initTestClassesAndInstances() { IObject.IdentifiableObject[] instances = getObjects(true, this.m_errorMsgPrefix); Arrays.stream(instances) .map(IdentifiableObject::getInstance) - .map(IParameterInfo::embeddedInstance) + .map(ITestClassInstance::embeddedInstance) .filter(it -> it instanceof ITest) .findFirst() .ifPresent(it -> testName = ((ITest) it).getTestName()); @@ -208,7 +208,7 @@ private void initMethods() { true, xmlTest, eachInstance); - Object instance = IParameterInfo.embeddedInstance(eachInstance.getInstance()); + Object instance = ITestClassInstance.embeddedInstance(eachInstance.getInstance()); beforeClassConfig.put(instance, m_beforeClassMethods); m_afterClassMethods = ConfigurationMethod.createClassConfigurationMethods( diff --git a/testng-core/src/main/java/org/testng/internal/BaseTestMethod.java b/testng-core/src/main/java/org/testng/internal/BaseTestMethod.java index c0ad3379f9..28765c8350 100644 --- a/testng-core/src/main/java/org/testng/internal/BaseTestMethod.java +++ b/testng-core/src/main/java/org/testng/internal/BaseTestMethod.java @@ -17,8 +17,10 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import org.testng.IClass; +import org.testng.IFactoryMethod; import org.testng.IRetryAnalyzer; import org.testng.ITestClass; +import org.testng.ITestClassInstance; import org.testng.ITestNGMethod; import org.testng.ITestObjectFactory; import org.testng.ITestResult; @@ -103,6 +105,10 @@ public BaseTestMethod( m_instance = instance; } + protected final IObject.IdentifiableObject identifiableObject() { + return m_instance; + } + /** {@inheritDoc} */ @Override public boolean isAlwaysRun() { @@ -153,7 +159,7 @@ public String getMethodName() { public Object getInstance() { return Optional.ofNullable(m_instance) .map(IObject.IdentifiableObject::getInstance) - .map(IParameterInfo::embeddedInstance) + .map(ITestClassInstance::embeddedInstance) .orElse(null); } @@ -299,6 +305,19 @@ public void setTimeOut(long timeOut) { m_timeOut = timeOut; } + @Override + public Optional getFactoryMethod() { + IObject.IdentifiableObject identifiable = identifiableObject(); + if (identifiable == null) { + return Optional.empty(); + } + Object instance = identifiableObject().getInstance(); + if (instance instanceof ParameterInfo) { + return Optional.of(() -> Optional.of(((ParameterInfo) instance).getParameters())); + } + return ITestNGMethod.super.getFactoryMethod(); + } + /** * {@inheritDoc} * @@ -538,11 +557,10 @@ public String getSimpleName() { } private String instanceParameters() { - IParameterInfo instance = getFactoryMethodParamsInfo(); - if (instance != null) { - return ", instance params:" + Arrays.toString(instance.getParameters()); - } - return ""; + return getFactoryMethod() + .flatMap(IFactoryMethod::getParameters) + .map(it -> ", instance params:" + Arrays.toString(it)) + .orElse(""); } protected String getSignature() { diff --git a/testng-core/src/main/java/org/testng/internal/ClassImpl.java b/testng-core/src/main/java/org/testng/internal/ClassImpl.java index f893b60086..2cbc2add19 100644 --- a/testng-core/src/main/java/org/testng/internal/ClassImpl.java +++ b/testng-core/src/main/java/org/testng/internal/ClassImpl.java @@ -5,6 +5,7 @@ import java.util.Map; import org.testng.IClass; import org.testng.ITest; +import org.testng.ITestClassInstance; import org.testng.ITestContext; import org.testng.ITestObjectFactory; import org.testng.annotations.ITestAnnotation; @@ -162,7 +163,7 @@ public void addInstance(Object instance) { } private static int computeHashCode(Object instance) { - return IParameterInfo.embeddedInstance(instance).hashCode(); + return ITestClassInstance.embeddedInstance(instance).hashCode(); } private DetailedAttributes newDetailedAttributes(boolean create, String errMsgPrefix) { diff --git a/testng-core/src/main/java/org/testng/internal/FactoryMethod.java b/testng-core/src/main/java/org/testng/internal/FactoryMethod.java index c5bf4de1fe..97c851d388 100644 --- a/testng-core/src/main/java/org/testng/internal/FactoryMethod.java +++ b/testng-core/src/main/java/org/testng/internal/FactoryMethod.java @@ -7,11 +7,13 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import org.testng.DataProviderHolder; import org.testng.IDataProviderInterceptor; import org.testng.IDataProviderListener; import org.testng.IInstanceInfo; +import org.testng.ITestClassInstance; import org.testng.ITestContext; import org.testng.ITestMethodFinder; import org.testng.ITestNGListener; @@ -144,8 +146,8 @@ private static String[] getAllGroups( return groups.toArray(new String[0]); } - public IParameterInfo[] invoke() { - List result = Lists.newArrayList(); + public ITestClassInstance[] invoke() { + List result = Lists.newArrayList(); Map allParameterNames = Maps.newHashMap(); Parameters.MethodParameters methodParameters = @@ -174,6 +176,7 @@ public IParameterInfo[] invoke() { try { List indices = factoryAnnotation.getIndices(); int position = 0; + AtomicInteger invocationCounter = new AtomicInteger(0); while (parameterIterator.hasNext()) { Object[] parameters = parameterIterator.next(); if (parameters == null) { @@ -196,13 +199,24 @@ public IParameterInfo[] invoke() { final int instancePosition = position; result.addAll( Arrays.stream(testInstances) - .map(instance -> new ParameterInfo(instance, instancePosition, parameters)) + .map( + instance -> + new ParameterInfo( + instance, + instancePosition, + parameters, + invocationCounter.getAndIncrement())) .collect(Collectors.toList())); } else { for (Integer index : indices) { int i = index - position; if (i >= 0 && i < testInstances.length) { - result.add(new ParameterInfo(testInstances[i], position, parameters)); + result.add( + new ParameterInfo( + testInstances[i], + position, + parameters, + invocationCounter.getAndIncrement())); } } } @@ -210,7 +224,9 @@ public IParameterInfo[] invoke() { } else { if (indices == null || indices.isEmpty() || indices.contains(position)) { Object instance = m_objectFactory.newInstance(com.getConstructor(), parameters); - result.add(new ParameterInfo(instance, position, parameters)); + result.add( + new ParameterInfo( + instance, position, parameters, invocationCounter.getAndIncrement())); } position++; } diff --git a/testng-core/src/main/java/org/testng/internal/MethodSorting.java b/testng-core/src/main/java/org/testng/internal/MethodSorting.java index c2e455922e..b7e6e2fe13 100644 --- a/testng-core/src/main/java/org/testng/internal/MethodSorting.java +++ b/testng-core/src/main/java/org/testng/internal/MethodSorting.java @@ -5,6 +5,7 @@ import java.util.Objects; import java.util.Optional; import java.util.UUID; +import org.testng.IFactoryMethod; import org.testng.ITestNGMethod; public enum MethodSorting implements Comparator { @@ -31,8 +32,10 @@ public int compare(ITestNGMethod o1, ITestNGMethod o2) { .thenComparing(Object::toString) .thenComparing( method -> - Optional.ofNullable(method.getFactoryMethodParamsInfo()) - .map(it -> Arrays.toString(it.getParameters())) + method + .getFactoryMethod() + .flatMap(IFactoryMethod::getParameters) + .map(Arrays::toString) .orElse("")) .thenComparing(this::objectEquality); return comparator.compare(o1, o2); diff --git a/testng-core/src/main/java/org/testng/internal/ParameterInfo.java b/testng-core/src/main/java/org/testng/internal/ParameterInfo.java index 7b514d1da4..9a10491dea 100644 --- a/testng-core/src/main/java/org/testng/internal/ParameterInfo.java +++ b/testng-core/src/main/java/org/testng/internal/ParameterInfo.java @@ -1,14 +1,16 @@ package org.testng.internal; public class ParameterInfo implements IParameterInfo { - private Object instance; + private final Object instance; private final int index; - private Object[] parameters; + private final Object[] parameters; + private final int invocationIndex; - public ParameterInfo(Object instance, int index, Object[] parameters) { + public ParameterInfo(Object instance, int index, Object[] parameters, int invocationIndex) { this.instance = instance; this.index = index; this.parameters = parameters; + this.invocationIndex = invocationIndex; } @Override @@ -21,6 +23,11 @@ public int getIndex() { return index; } + @Override + public int getInvocationIndex() { + return invocationIndex; + } + @Override public Object[] getParameters() { return parameters; diff --git a/testng-core/src/main/java/org/testng/internal/TestNGClassFinder.java b/testng-core/src/main/java/org/testng/internal/TestNGClassFinder.java index b8d00d8889..e8b9dfb09d 100644 --- a/testng-core/src/main/java/org/testng/internal/TestNGClassFinder.java +++ b/testng-core/src/main/java/org/testng/internal/TestNGClassFinder.java @@ -14,6 +14,7 @@ import org.testng.DataProviderHolder; import org.testng.IClass; import org.testng.IInstanceInfo; +import org.testng.ITestClassInstance; import org.testng.ITestContext; import org.testng.ITestObjectFactory; import org.testng.TestNGException; @@ -178,7 +179,7 @@ private ClassInfoMap processFactory(IClass ic, ConstructorOrMethod factoryMethod // If the factory returned IInstanceInfo, get the class from it, // otherwise, just call getClass() on the returned instances int i = 0; - for (IParameterInfo o : fm.invoke()) { + for (ITestClassInstance o : fm.invoke()) { if (o == null) { throw new TestNGException( "The factory " + fm + " returned a null instance" + "at index " + i); @@ -329,8 +330,8 @@ private void addInstance(IInstanceInfo ii) { private void addInstance(IObject.IdentifiableObject o) { Class key = o.getInstance().getClass(); - if (o.getInstance() instanceof IParameterInfo) { - key = ((IParameterInfo) o.getInstance()).getInstance().getClass(); + if (o.getInstance() instanceof ITestClassInstance) { + key = ((ITestClassInstance) o.getInstance()).getInstance().getClass(); } addInstance(key, o); } diff --git a/testng-core/src/test/java/test/configuration/issue2426/MyMethodListener.java b/testng-core/src/test/java/test/configuration/issue2426/MyMethodListener.java index 8d32e31518..a123f8405c 100644 --- a/testng-core/src/test/java/test/configuration/issue2426/MyMethodListener.java +++ b/testng-core/src/test/java/test/configuration/issue2426/MyMethodListener.java @@ -3,6 +3,7 @@ import java.util.HashMap; import java.util.Map; import org.testng.IConfigurationListener; +import org.testng.IFactoryMethod; import org.testng.ITestResult; import org.testng.annotations.*; @@ -12,7 +13,11 @@ public class MyMethodListener implements IConfigurationListener { @Override public void onConfigurationSuccess(ITestResult tr) { - Object[] values = tr.getMethod().getFactoryMethodParamsInfo().getParameters(); + Object[] values = + tr.getMethod() + .getFactoryMethod() + .flatMap(IFactoryMethod::getParameters) + .orElse(new Object[0]); if (tr.getMethod().isBeforeSuiteConfiguration()) { contents.put(BeforeSuite.class, values); } diff --git a/testng-core/src/test/java/test/factory/FactoryIntegrationTest.java b/testng-core/src/test/java/test/factory/FactoryIntegrationTest.java index f18c8289d0..76ff2ed763 100644 --- a/testng-core/src/test/java/test/factory/FactoryIntegrationTest.java +++ b/testng-core/src/test/java/test/factory/FactoryIntegrationTest.java @@ -3,13 +3,24 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; import org.testng.Assert; +import org.testng.ITestClassInstance; +import org.testng.ITestListener; +import org.testng.ITestResult; import org.testng.TestListenerAdapter; import org.testng.TestNG; import org.testng.TestNGException; +import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import test.InvokedMethodNameListener; import test.SimpleBaseTest; +import test.factory.issue3111.SimpleFactoryPoweredTestSample; +import test.factory.issue3111.SimpleFactoryPoweredTestWithIndicesSample; +import test.factory.issue3111.SimpleFactoryPoweredTestWithoutDataProviderSample; +import test.factory.issue3111.SimpleFactoryPoweredTestWithoutDataProviderWithIndicesSample; public class FactoryIntegrationTest extends SimpleBaseTest { @@ -22,7 +33,9 @@ public void testExceptionWithNonStaticFactoryMethod() { } catch (TestNGException e) { assertThat(e) .hasMessage( - "\nCan't invoke public java.lang.Object[] test.factory.GitHub876Sample.createInstances(): either make it static or add a no-args constructor to your class"); + "\nCan't invoke public java.lang.Object[] test.factory.GitHub876Sample" + + ".createInstances(): either make it static or add a no-args constructor to " + + "your class"); } } @@ -46,7 +59,8 @@ public void testExceptionWithBadFactoryMethodReturnType() { } catch (TestNGException e) { assertThat(e) .hasMessage( - "\ntest.factory.BadMethodReturnTypeFactory.createInstances MUST return [ java.lang.Object[] or org.testng.IInstanceInfo[] ] but returns java.lang.Object"); + "\ntest.factory.BadMethodReturnTypeFactory.createInstances MUST return [ java.lang" + + ".Object[] or org.testng.IInstanceInfo[] ] but returns java.lang.Object"); } } @@ -65,4 +79,34 @@ public void doubleFactoryMethodShouldWork() { "FactoryBaseSample{1}#f", "FactoryBaseSample{2}#f", "FactoryBaseSample{3}#f", "FactoryBaseSample{4}#f"); } + + @Test(dataProvider = "testdata", description = "GITHUB-3111") + public void ensureCurrentIndexWorksForFactoryPoweredTests(Class klass, Integer[] expected) { + List params = new ArrayList<>(); + TestNG testng = create(klass); + testng.addListener( + new ITestListener() { + @Override + public void onTestSuccess(ITestResult result) { + params.add(result.getMethod().getFactoryMethodParamsInfo()); + } + }); + testng.run(); + List actualIndices = + params.stream() + .map(ITestClassInstance::getInvocationIndex) + .sorted() + .collect(Collectors.toList()); + assertThat(actualIndices).containsExactly(expected); + } + + @DataProvider(name = "testdata") + public Object[][] testdata() { + return new Object[][] { + {SimpleFactoryPoweredTestSample.class, new Integer[] {0, 1, 2}}, + {SimpleFactoryPoweredTestWithIndicesSample.class, new Integer[] {0}}, + {SimpleFactoryPoweredTestWithoutDataProviderSample.class, new Integer[] {0, 1, 2}}, + {SimpleFactoryPoweredTestWithoutDataProviderWithIndicesSample.class, new Integer[] {0}}, + }; + } } diff --git a/testng-core/src/test/java/test/factory/issue3111/SimpleFactoryPoweredTestSample.java b/testng-core/src/test/java/test/factory/issue3111/SimpleFactoryPoweredTestSample.java new file mode 100644 index 0000000000..a85ba3e2b0 --- /dev/null +++ b/testng-core/src/test/java/test/factory/issue3111/SimpleFactoryPoweredTestSample.java @@ -0,0 +1,26 @@ +package test.factory.issue3111; + +import org.testng.Reporter; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Factory; +import org.testng.annotations.Test; + +public class SimpleFactoryPoweredTestSample { + + private final int i; + + @Factory(dataProvider = "data") + public SimpleFactoryPoweredTestSample(int i) { + this.i = i; + } + + @Test + public void test() { + Reporter.log(Integer.toString(i)); + } + + @DataProvider + public static Object[][] data() { + return new Object[][] {{1}, {2}, {3}}; + } +} diff --git a/testng-core/src/test/java/test/factory/issue3111/SimpleFactoryPoweredTestWithIndicesSample.java b/testng-core/src/test/java/test/factory/issue3111/SimpleFactoryPoweredTestWithIndicesSample.java new file mode 100644 index 0000000000..3a745ac1bc --- /dev/null +++ b/testng-core/src/test/java/test/factory/issue3111/SimpleFactoryPoweredTestWithIndicesSample.java @@ -0,0 +1,28 @@ +package test.factory.issue3111; + +import org.testng.Reporter; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Factory; +import org.testng.annotations.Test; + +public class SimpleFactoryPoweredTestWithIndicesSample { + + private final int i; + + @Factory( + dataProvider = "data", + indices = {1}) + public SimpleFactoryPoweredTestWithIndicesSample(int i) { + this.i = i; + } + + @Test + public void test() { + Reporter.log(Integer.toString(i)); + } + + @DataProvider + public static Object[][] data() { + return new Object[][] {{1}, {2}, {3}}; + } +} diff --git a/testng-core/src/test/java/test/factory/issue3111/SimpleFactoryPoweredTestWithoutDataProviderSample.java b/testng-core/src/test/java/test/factory/issue3111/SimpleFactoryPoweredTestWithoutDataProviderSample.java new file mode 100644 index 0000000000..fb8bb9dac3 --- /dev/null +++ b/testng-core/src/test/java/test/factory/issue3111/SimpleFactoryPoweredTestWithoutDataProviderSample.java @@ -0,0 +1,28 @@ +package test.factory.issue3111; + +import org.testng.Reporter; +import org.testng.annotations.Factory; +import org.testng.annotations.Test; + +public class SimpleFactoryPoweredTestWithoutDataProviderSample { + + private final int i; + + public SimpleFactoryPoweredTestWithoutDataProviderSample(int i) { + this.i = i; + } + + @Test + public void test() { + Reporter.log(Integer.toString(i)); + } + + @Factory + public static Object[] data() { + return new Object[] { + new SimpleFactoryPoweredTestWithoutDataProviderSample(1), + new SimpleFactoryPoweredTestWithoutDataProviderSample(2), + new SimpleFactoryPoweredTestWithoutDataProviderSample(3), + }; + } +} diff --git a/testng-core/src/test/java/test/factory/issue3111/SimpleFactoryPoweredTestWithoutDataProviderWithIndicesSample.java b/testng-core/src/test/java/test/factory/issue3111/SimpleFactoryPoweredTestWithoutDataProviderWithIndicesSample.java new file mode 100644 index 0000000000..be564b3022 --- /dev/null +++ b/testng-core/src/test/java/test/factory/issue3111/SimpleFactoryPoweredTestWithoutDataProviderWithIndicesSample.java @@ -0,0 +1,28 @@ +package test.factory.issue3111; + +import org.testng.Reporter; +import org.testng.annotations.Factory; +import org.testng.annotations.Test; + +public class SimpleFactoryPoweredTestWithoutDataProviderWithIndicesSample { + + private final int i; + + public SimpleFactoryPoweredTestWithoutDataProviderWithIndicesSample(int i) { + this.i = i; + } + + @Test + public void test() { + Reporter.log(Integer.toString(i)); + } + + @Factory(indices = {1}) + public static Object[] data() { + return new Object[] { + new SimpleFactoryPoweredTestWithoutDataProviderWithIndicesSample(1), + new SimpleFactoryPoweredTestWithoutDataProviderWithIndicesSample(2), + new SimpleFactoryPoweredTestWithoutDataProviderWithIndicesSample(3), + }; + } +} diff --git a/testng-runner-api/src/main/java/org/testng/internal/TestResult.java b/testng-runner-api/src/main/java/org/testng/internal/TestResult.java index e48352d8c0..0817dd11eb 100644 --- a/testng-runner-api/src/main/java/org/testng/internal/TestResult.java +++ b/testng-runner-api/src/main/java/org/testng/internal/TestResult.java @@ -12,7 +12,9 @@ import javax.annotation.Nonnull; import org.testng.IAttributes; import org.testng.IClass; +import org.testng.IFactoryMethod; import org.testng.ITest; +import org.testng.ITestClassInstance; import org.testng.ITestContext; import org.testng.ITestNGMethod; import org.testng.ITestResult; @@ -298,16 +300,15 @@ public void setParameters(Object[] parameters) { @Override public Object getInstance() { - return IParameterInfo.embeddedInstance(this.m_method.getInstance()); + return ITestClassInstance.embeddedInstance(this.m_method.getInstance()); } @Override public Object[] getFactoryParameters() { - IParameterInfo instance = this.m_method.getFactoryMethodParamsInfo(); - if (instance != null) { - return instance.getParameters(); - } - return new Object[0]; + return this.m_method + .getFactoryMethod() + .flatMap(IFactoryMethod::getParameters) + .orElse(new Object[0]); } @Override