Skip to content

Commit

Permalink
test: add test to check that all setters trigger a change event
Browse files Browse the repository at this point in the history
  • Loading branch information
monperrus committed May 27, 2018
1 parent 597a52e commit 61cc069
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 21 deletions.
12 changes: 12 additions & 0 deletions src/main/java/spoon/reflect/declaration/CtAnonymousExecutable.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@
*/
package spoon.reflect.declaration;

import spoon.reflect.annotations.PropertySetter;
import spoon.reflect.reference.CtTypeReference;
import spoon.support.UnsettableProperty;

import java.util.List;
import java.util.Set;

import static spoon.reflect.path.CtRole.PARAMETER;

/**
* This element defines an anonymous executable block declaration in a class.
*
Expand All @@ -42,4 +45,13 @@ public interface CtAnonymousExecutable extends CtExecutable<Void>, CtTypeMember
@Override
@UnsettableProperty
<C extends CtTypedElement> C setType(CtTypeReference<Void> type);

@Override
@UnsettableProperty
<T extends CtExecutable<Void>> T addParameter(CtParameter<?> parameter);

@Override
@UnsettableProperty
<T extends CtExecutable<Void>> T addThrownType(CtTypeReference<? extends Throwable> throwType);

}
17 changes: 17 additions & 0 deletions src/main/java/spoon/reflect/declaration/CtTypeParameter.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ public interface CtTypeParameter extends CtType<Object> {
@UnsettableProperty
<C extends CtType<Object>> C setSuperInterfaces(Set<CtTypeReference<?>> interfaces);

@Override
@UnsettableProperty
<S, C extends CtType<Object>> C addSuperInterface(CtTypeReference<S> interfac);

@Override
@UnsettableProperty
<C extends CtType<Object>> C setTypeMembers(List<CtTypeMember> members);
Expand All @@ -64,7 +68,20 @@ public interface CtTypeParameter extends CtType<Object> {
@UnsettableProperty
<C extends CtType<Object>> C setMethods(Set<CtMethod<?>> methods);

@Override
@UnsettableProperty
<M, C extends CtType<Object>> C addMethod(CtMethod<M> method);

@Override
@UnsettableProperty
<C extends CtType<Object>> C setNestedTypes(Set<CtType<?>> nestedTypes);

@Override
@UnsettableProperty
<N, C extends CtType<Object>> C addNestedType(CtType<N> nestedType);

@Override
@UnsettableProperty
public <F, C extends CtType<Object>> C addFieldAtTop(CtField<F> field);

}
6 changes: 5 additions & 1 deletion src/test/java/spoon/test/SpoonTestHelpers.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.visitor.filter.OverridingMethodFilter;
import spoon.support.DerivedProperty;
import spoon.support.UnsettableProperty;
import spoon.test.metamodel.SpoonMetaModel;

import java.io.File;
Expand Down Expand Up @@ -84,7 +85,10 @@ public static List<CtMethod<?>> getAllSetters(CtType<?> baseType) {
//parent is a special kind of setter, which does not influence model properties of element, but link to parent element.
continue;
}
if (!m.getSimpleName().startsWith("set")) {
if (! (m.getSimpleName().startsWith("set") || m.getSimpleName().startsWith("add"))) {
continue;
}
if (m.hasAnnotation(UnsettableProperty.class)) {
continue;
}
if (m.getParameters().size()!=1) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@
import java.util.List;

import static org.junit.Assert.fail;
import static spoon.test.parent.ParentContractTest.createCompatibleObject;
import static spoon.test.parent.ContractOnSettersParametrizedTest.createCompatibleObject;

// contract: one can call all setters with null as parameter (no problem with parent)
@RunWith(Parameterized.class)
public class IntercessionContractTest {
public class OneCanCallSetterWithNullParameterizedTest {

@Parameterized.Parameters(name = "{1}")
public static Collection<Object[]> data() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import spoon.SpoonException;
import spoon.experimental.modelobs.ActionBasedChangeListenerImpl;
import spoon.experimental.modelobs.action.Action;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtMethod;
Expand All @@ -15,6 +17,7 @@
import spoon.reflect.reference.CtReference;
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.visitor.CtVisitable;
import spoon.support.DerivedProperty;
import spoon.support.UnsettableProperty;
import spoon.test.SpoonTestHelpers;

Expand All @@ -36,9 +39,13 @@
import static org.mockito.Mockito.verify;
import static spoon.testing.utils.ModelUtils.createFactory;

// check that all setters of the metamodel call setParent in a correct manner
/**
* check that all setters of the metamodel do the right things:
* - call setParent
* - trigger a change event
*/
@RunWith(Parameterized.class)
public class ParentContractTest<T extends CtVisitable> {
public class ContractOnSettersParametrizedTest<T extends CtVisitable> {

private static Factory factory = createFactory();
private static final List<CtType<? extends CtElement>> allInstantiableMetamodelInterfaces = SpoonTestHelpers.getAllInstantiableMetamodelInterfaces();
Expand All @@ -61,6 +68,19 @@ public static Collection<Object[]> createReceiverList() throws Exception {
@Parameterized.Parameter(0)
public CtType<?> toTest;

class ModelChangeListener extends ActionBasedChangeListenerImpl {
int nbCallsToOnAction = 0;
List changedElements = new ArrayList();
@Override
public void onAction(Action action) {
super.onAction(action);
changedElements.add(action.getContext().getElementWhereChangeHappens());
nbCallsToOnAction++;
}
}

ModelChangeListener changeListener = new ModelChangeListener();

public static Object createCompatibleObject(CtTypeReference<?> parameterType) {
Class<?> c = parameterType.getActualClass();
for(CtType t : allInstantiableMetamodelInterfaces) {
Expand Down Expand Up @@ -93,11 +113,13 @@ public static Object createCompatibleObject(CtTypeReference<?> parameterType) {

@Test
public void testContract() throws Throwable {
factory.getEnvironment().setModelChangeListener(changeListener);
int nSetterCalls= 0;
int nAssertsOnParent = 0;
int nAssertsOnParentInList = 0;
// contract: all setters/adders must set the parent (not necessarily the direct parent, can be upper in the parent tree, for instance when injecting blocks
Object o = factory.Core().create((Class<? extends CtElement>) toTest.getActualClass());

for (CtMethod<?> setter : SpoonTestHelpers.getAllSetters(toTest)) {

Object argument = createCompatibleObject(setter.getParameters().get(0).getType());
Expand All @@ -108,7 +130,18 @@ public void testContract() throws Throwable {

// we invoke the setter
Method actualMethod = setter.getReference().getActualMethod();

int nBefore = changeListener.nbCallsToOnAction;
changeListener.changedElements = new ArrayList();

// here we actually call the setter
actualMethod.invoke(receiver, new Object[] { argument });

int nAfter = changeListener.nbCallsToOnAction;

// contract: at least one change event is well fired (sometimes it is more than one for complex setters)
assertTrue(actualMethod.getName(), nBefore < nAfter);

nSetterCalls++;
nTotalSetterCalls++;
// if it's a settable property
Expand All @@ -130,7 +163,8 @@ public void testContract() throws Throwable {


} catch (AssertionError e) {
Assert.fail("call setParent contract failed for " + setter.toString() + " " + e.toString());
System.err.println("one contract failed for " + setter.toString());
throw e;
} catch (InvocationTargetException e) {
if (e.getCause() instanceof UnsupportedOperationException) {
// fail-safe contract: we can always call a setter
Expand Down
29 changes: 14 additions & 15 deletions src/test/java/spoon/test/replace/ReplaceParametrizedTest.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,8 @@
package spoon.test.replace;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static spoon.test.parent.ParentContractTest.createCompatibleObject;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import spoon.SpoonException;
import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtFieldAccess;
Expand All @@ -32,11 +19,23 @@
import spoon.reflect.visitor.CtScanner;
import spoon.reflect.visitor.CtVisitable;
import spoon.reflect.visitor.Filter;
import spoon.test.metamodel.MetamodelProperty;
import spoon.test.metamodel.MetamodelConcept;
import spoon.test.metamodel.MMTypeKind;
import spoon.test.metamodel.MetamodelConcept;
import spoon.test.metamodel.MetamodelProperty;
import spoon.test.metamodel.SpoonMetaModel;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static spoon.test.parent.ContractOnSettersParametrizedTest.createCompatibleObject;

@RunWith(Parameterized.class)
public class ReplaceParametrizedTest<T extends CtVisitable> {

Expand Down

0 comments on commit 61cc069

Please sign in to comment.