diff --git a/.gitignore b/.gitignore index 1e234a3..ccd9b67 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .gradle .studio +.idea *.ipr *.iml *.iws @@ -7,4 +8,5 @@ build/* deploy/* modules/*/build/* out -test-run \ No newline at end of file +test-run +classes/* diff --git a/build.gradle b/build.gradle index 37b21d6..0b9ed28 100644 --- a/build.gradle +++ b/build.gradle @@ -1,4 +1,3 @@ - buildscript { ext.cubaVersion = '6.8.0' repositories { @@ -36,7 +35,7 @@ def bintrayRepositoryUrl = "https://api.bintray.com/maven/balvi/cuba-components/ cuba { artifact { group = 'de.balvi.cuba.declarativecontrollers' - version = '0.5.0' + version = '0.5.1' isSnapshot = false } tomcat { @@ -84,7 +83,7 @@ cobertura { coverageCheckTotalLineRate = 40 coverageCheckHaltOnFailure = true coverageSourceDirs = sourceDirs -// coverageCheckLineRate = 1 + coverageCheckLineRate = 40 coverageCheckRegexes = [[regex: '.*\\$.*', branchRate: 0, lineRate: 0]] } diff --git a/modules/web/src/de/balvi/cuba/declarativecontrollers/web/annotationexecutor/AbstractAnnotationDispatcherBean.java b/modules/web/src/de/balvi/cuba/declarativecontrollers/web/annotationexecutor/AbstractAnnotationDispatcherBean.java index adc0e35..186a205 100644 --- a/modules/web/src/de/balvi/cuba/declarativecontrollers/web/annotationexecutor/AbstractAnnotationDispatcherBean.java +++ b/modules/web/src/de/balvi/cuba/declarativecontrollers/web/annotationexecutor/AbstractAnnotationDispatcherBean.java @@ -1,6 +1,9 @@ package de.balvi.cuba.declarativecontrollers.web.annotationexecutor; +import com.haulmont.cuba.core.global.AppBeans; import com.haulmont.cuba.gui.components.Frame; +import de.balvi.cuba.declarativecontrollers.web.annotationexecutor.browse.BrowseAnnotationExecutor; +import de.balvi.cuba.declarativecontrollers.web.annotationexecutor.browse.BrowseFieldAnnotationExecutor; import java.lang.annotation.Annotation; import java.lang.reflect.Field; @@ -28,14 +31,14 @@ protected Annotation[] getClassAnnotations(Frame frame) { return frame.getClass().getAnnotations(); } - protected Collection getSupportedAnnotationExecutors(Collection potentialAnnotationExecutors, Annotation annotation) { + protected Collection getSupportedAnnotationExecutors(Collection potentialAnnotationExecutors, Annotation annotation) { Collection result = new ArrayList(); for (AnnotationExecutor annotationExecutor : potentialAnnotationExecutors) { if (annotationExecutor.supports(annotation)) { result.add(annotationExecutor); } } - return result; - + return (Collection) result; } + } diff --git a/modules/web/src/de/balvi/cuba/declarativecontrollers/web/browse/BrowseAnnotationDispatcherBean.java b/modules/web/src/de/balvi/cuba/declarativecontrollers/web/browse/BrowseAnnotationDispatcherBean.java index fc6c009..0c02348 100644 --- a/modules/web/src/de/balvi/cuba/declarativecontrollers/web/browse/BrowseAnnotationDispatcherBean.java +++ b/modules/web/src/de/balvi/cuba/declarativecontrollers/web/browse/BrowseAnnotationDispatcherBean.java @@ -26,7 +26,7 @@ private void executeInitForFieldAnnotations(AnnotatableAbstractLookup browse, Ma for (Annotation annotation : fieldAnnotations) { - Collection supportedAnnotationExecutors = getSupportedBrowseFieldAnnotationExecutors(annotation); + Collection supportedAnnotationExecutors = getSupportedAnnotationExecutors(getBrowseFieldAnnotationExecutors(), annotation); if (supportedAnnotationExecutors != null && supportedAnnotationExecutors.size() > 0) { com.haulmont.cuba.gui.components.Component fieldValue = getFieldValue(browse, field); @@ -41,7 +41,7 @@ private void executeInitForFieldAnnotations(AnnotatableAbstractLookup browse, Ma private void executeInitForClassAnnotations(AnnotatableAbstractLookup browse, Map params) { for (Annotation annotation : getClassAnnotations(browse)) { - Collection supportedAnnotationExecutors = getSupportedBrowseAnnotationExecutors(annotation); + Collection supportedAnnotationExecutors = getSupportedAnnotationExecutors(getBrowseAnnotationExecutors(), annotation); for (BrowseAnnotationExecutor annotationExecutor : supportedAnnotationExecutors) { annotationExecutor.init(annotation, browse, params); @@ -50,7 +50,6 @@ private void executeInitForClassAnnotations(AnnotatableAbstractLookup browse, Ma } - @Override public void executeReady(AnnotatableAbstractLookup browse, Map params) { executeReadyForClassAnnotations(browse, params); @@ -63,7 +62,7 @@ private void executeReadyForFieldAnnotations(AnnotatableAbstractLookup browse, M Annotation[] fieldAnnotations = field.getAnnotations(); for (Annotation annotation : fieldAnnotations) { - Collection supportedAnnotationExecutors = getSupportedBrowseFieldAnnotationExecutors(annotation); + Collection supportedAnnotationExecutors = getSupportedAnnotationExecutors(getBrowseFieldAnnotationExecutors(), annotation); if (supportedAnnotationExecutors != null && supportedAnnotationExecutors.size() > 0) { com.haulmont.cuba.gui.components.Component fieldValue = getFieldValue(browse, field); @@ -78,7 +77,7 @@ private void executeReadyForFieldAnnotations(AnnotatableAbstractLookup browse, M private void executeReadyForClassAnnotations(AnnotatableAbstractLookup browse, Map params) { for (Annotation annotation : getClassAnnotations(browse)) { - Collection supportedAnnotations = getSupportedBrowseAnnotationExecutors(annotation); + Collection supportedAnnotations = getSupportedAnnotationExecutors(getBrowseAnnotationExecutors(), annotation); for (BrowseAnnotationExecutor annotationExecutor : supportedAnnotations) { annotationExecutor.ready(annotation, browse, params); @@ -87,6 +86,7 @@ private void executeReadyForClassAnnotations(AnnotatableAbstractLookup browse, M } + /* protected Collection getSupportedBrowseAnnotationExecutors(Annotation annotation) { Collection annotationExecutors = getBrowseAnnotationExecutors(); return (Collection) getSupportedAnnotationExecutors(annotationExecutors, annotation); @@ -96,7 +96,7 @@ protected Collection getSupportedBrowseFieldAnnot Collection annotationExecutors = getBrowseFieldAnnotationExecutors(); return (Collection) getSupportedAnnotationExecutors(annotationExecutors, annotation); } - + */ protected Collection getBrowseAnnotationExecutors() { return AppBeans.getAll(BrowseAnnotationExecutor.class).values(); } diff --git a/modules/web/src/de/balvi/cuba/declarativecontrollers/web/editor/EditorAnnotationDispatcherBean.java b/modules/web/src/de/balvi/cuba/declarativecontrollers/web/editor/EditorAnnotationDispatcherBean.java index 6746d69..c8c3c97 100644 --- a/modules/web/src/de/balvi/cuba/declarativecontrollers/web/editor/EditorAnnotationDispatcherBean.java +++ b/modules/web/src/de/balvi/cuba/declarativecontrollers/web/editor/EditorAnnotationDispatcherBean.java @@ -25,7 +25,7 @@ public void executeInit(AnnotatableAbstractEditor editor, Map pa private void executeInitForClassAnnotations(AnnotatableAbstractEditor editor, Map params) { for (Annotation annotation : getClassAnnotations(editor)) { - Collection supportedAnnotationExecutors = getSupportedEditorAnnotationExecutors(annotation); + Collection supportedAnnotationExecutors = getSupportedAnnotationExecutors(getEditorAnnotationExecutors(), annotation); for (EditorAnnotationExecutor annotationExecutor : supportedAnnotationExecutors) { annotationExecutor.init(annotation, editor, params); @@ -38,7 +38,7 @@ private void executeInitForFieldAnnotations(AnnotatableAbstractEditor editor, Ma Annotation[] fieldAnnotations = field.getAnnotations(); for (Annotation annotation : fieldAnnotations) { - Collection supportedAnnotationExecutors = getSupportedEditorFieldAnnotationExecutors(annotation); + Collection supportedAnnotationExecutors = getSupportedAnnotationExecutors(getEditorFieldAnnotationExecutors(), annotation); if (supportedAnnotationExecutors != null && supportedAnnotationExecutors.size() > 0) { com.haulmont.cuba.gui.components.Component fieldValue = getFieldValue(editor, field); @@ -62,7 +62,7 @@ private void executeInitForFieldAnnotations(AnnotatableAbstractEditor editor) { for (Field field : getDeclaredFields(editor)) { Annotation[] fieldAnnotations = field.getAnnotations(); for (Annotation annotation : fieldAnnotations) { - Collection supportedAnnotationExecutors = getSupportedEditorFieldAnnotationExecutors(annotation); + Collection supportedAnnotationExecutors = getSupportedAnnotationExecutors(getEditorFieldAnnotationExecutors(), annotation); if (supportedAnnotationExecutors != null && supportedAnnotationExecutors.size() > 0) { com.haulmont.cuba.gui.components.Component fieldValue = getFieldValue(editor, field); @@ -78,7 +78,7 @@ private void executePostInitForClassAnnotations(AnnotatableAbstractEditor editor for (Annotation annotation : getClassAnnotations(editor)) { - Collection supportedAnnotationExecutors = getSupportedEditorAnnotationExecutors(annotation); + Collection supportedAnnotationExecutors = getSupportedAnnotationExecutors(getEditorAnnotationExecutors(), annotation); for (EditorAnnotationExecutor annotationExecutor : supportedAnnotationExecutors) { annotationExecutor.postInit(annotation, editor); @@ -86,6 +86,7 @@ private void executePostInitForClassAnnotations(AnnotatableAbstractEditor editor } } + /* protected Collection getSupportedEditorAnnotationExecutors(Annotation annotation) { Collection annotationExecutors = getEditorAnnotationExecutors(); return (Collection) getSupportedAnnotationExecutors(annotationExecutors, annotation); @@ -96,6 +97,7 @@ protected Collection getSupportedEditorFieldAnnot return (Collection) getSupportedAnnotationExecutors(annotationExecutors, annotation); } + */ protected Collection getEditorAnnotationExecutors() { return AppBeans.getAll(EditorAnnotationExecutor.class).values(); diff --git a/modules/web/src/de/balvi/cuba/declarativecontrollers/web/entitycombined/AnnotatableAbstractCombined.java b/modules/web/src/de/balvi/cuba/declarativecontrollers/web/entitycombined/AnnotatableAbstractCombined.java new file mode 100644 index 0000000..bdf052a --- /dev/null +++ b/modules/web/src/de/balvi/cuba/declarativecontrollers/web/entitycombined/AnnotatableAbstractCombined.java @@ -0,0 +1,27 @@ +package de.balvi.cuba.declarativecontrollers.web.entitycombined; + +import com.haulmont.cuba.gui.components.EntityCombinedScreen; + +import javax.inject.Inject; +import java.util.Map; + +public class AnnotatableAbstractCombined extends EntityCombinedScreen { + + @Inject + protected CombinedAnnotationDispatcher combinedAnnotationDispatcher; + + private Map params; + + @Override + public void init(Map params) { + super.init(params); + this.params = params; + combinedAnnotationDispatcher.executeInit(this, params); + } + + @Override + public void ready() { + combinedAnnotationDispatcher.executeReady(this, params); + } + +} diff --git a/modules/web/src/de/balvi/cuba/declarativecontrollers/web/entitycombined/CombinedAnnotationDispatcher.java b/modules/web/src/de/balvi/cuba/declarativecontrollers/web/entitycombined/CombinedAnnotationDispatcher.java new file mode 100644 index 0000000..7d5566d --- /dev/null +++ b/modules/web/src/de/balvi/cuba/declarativecontrollers/web/entitycombined/CombinedAnnotationDispatcher.java @@ -0,0 +1,11 @@ +package de.balvi.cuba.declarativecontrollers.web.entitycombined; + +import java.util.Map; + +public interface CombinedAnnotationDispatcher { + + String NAME = "dbcdc_CombinedAnnotationExecutorService"; + + void executeInit(AnnotatableAbstractCombined browse, Map params); + void executeReady(AnnotatableAbstractCombined browse, Map params); +} \ No newline at end of file diff --git a/modules/web/src/de/balvi/cuba/declarativecontrollers/web/entitycombined/CombinedAnnotationDispatcherBean.java b/modules/web/src/de/balvi/cuba/declarativecontrollers/web/entitycombined/CombinedAnnotationDispatcherBean.java new file mode 100644 index 0000000..a017814 --- /dev/null +++ b/modules/web/src/de/balvi/cuba/declarativecontrollers/web/entitycombined/CombinedAnnotationDispatcherBean.java @@ -0,0 +1,110 @@ +package de.balvi.cuba.declarativecontrollers.web.entitycombined; + +import com.haulmont.cuba.core.global.AppBeans; +import de.balvi.cuba.declarativecontrollers.web.annotationexecutor.AbstractAnnotationDispatcherBean; +import de.balvi.cuba.declarativecontrollers.web.annotationexecutor.browse.BrowseAnnotationExecutor; +import de.balvi.cuba.declarativecontrollers.web.annotationexecutor.browse.BrowseFieldAnnotationExecutor; +import org.springframework.stereotype.Component; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.util.Collection; +import java.util.Map; + +@Component(CombinedAnnotationDispatcher.NAME) +class CombinedAnnotationDispatcherBean extends AbstractAnnotationDispatcherBean implements CombinedAnnotationDispatcher { + + @Override + public void executeInit(AnnotatableAbstractCombined browse, Map params) { + executeInitForClassAnnotations(browse, params); + executeInitForFieldAnnotations(browse, params); + } + + private void executeInitForFieldAnnotations(AnnotatableAbstractCombined browse, Map params) { + for (Field field : getDeclaredFields(browse)) { + Annotation[] fieldAnnotations = field.getAnnotations(); + + for (Annotation annotation : fieldAnnotations) { + + Collection supportedAnnotationExecutors = getSupportedAnnotationExecutors(getCombinedFieldAnnotationExecutors(), annotation); + + if (supportedAnnotationExecutors != null && supportedAnnotationExecutors.size() > 0) { + com.haulmont.cuba.gui.components.Component fieldValue = getFieldValue(browse, field); + for (BrowseFieldAnnotationExecutor annotationExecutor : supportedAnnotationExecutors) { + annotationExecutor.init(annotation, browse, fieldValue, params); + } + } + + } + } + } + + private void executeInitForClassAnnotations(AnnotatableAbstractCombined browse, Map params) { + for (Annotation annotation : getClassAnnotations(browse)) { + Collection supportedAnnotationExecutors = getSupportedAnnotationExecutors(getCombinedAnnotationExecutors(), annotation); + + for (BrowseAnnotationExecutor annotationExecutor : supportedAnnotationExecutors) { + annotationExecutor.init(annotation, browse, params); + } + } + } + + + @Override + public void executeReady(AnnotatableAbstractCombined browse, Map params) { + executeReadyForClassAnnotations(browse, params); + executeReadyForFieldAnnotations(browse, params); + } + + private void executeReadyForFieldAnnotations(AnnotatableAbstractCombined browse, Map params) { + for (Field field : getDeclaredFields(browse)) { + + Annotation[] fieldAnnotations = field.getAnnotations(); + for (Annotation annotation : fieldAnnotations) { + + Collection supportedAnnotationExecutors = getSupportedAnnotationExecutors(getCombinedFieldAnnotationExecutors(), annotation); + + if (supportedAnnotationExecutors != null && supportedAnnotationExecutors.size() > 0) { + com.haulmont.cuba.gui.components.Component fieldValue = getFieldValue(browse, field); + for (BrowseFieldAnnotationExecutor annotationExecutor : supportedAnnotationExecutors) { + annotationExecutor.ready(annotation, browse, fieldValue, params); + } + } + } + } + } + + private void executeReadyForClassAnnotations(AnnotatableAbstractCombined browse, Map params) { + for (Annotation annotation : getClassAnnotations(browse)) { + + Collection supportedAnnotations = getSupportedAnnotationExecutors(getCombinedAnnotationExecutors(), annotation); + + for (BrowseAnnotationExecutor annotationExecutor : supportedAnnotations) { + annotationExecutor.ready(annotation, browse, params); + } + } + } + + /* + protected Collection getSupportedCombinedAnnotationExecutors(Annotation annotation) { + Collection annotationExecutors = getCombinedAnnotationExecutors(); + return (Collection) getSupportedAnnotationExecutors(annotationExecutors, annotation); + } + + protected Collection getSupportedCombinedFieldAnnotationExecutors(Annotation annotation) { + Collection annotationExecutors = getCombinedFieldAnnotationExecutors(); + return (Collection) getSupportedAnnotationExecutors(annotationExecutors, annotation); + } + */ + protected Collection getCombinedAnnotationExecutors() { + return AppBeans.getAll(BrowseAnnotationExecutor.class).values(); + } + + + protected Collection getCombinedFieldAnnotationExecutors() { + return AppBeans.getAll(BrowseFieldAnnotationExecutor.class).values(); + + } + +} + diff --git a/modules/web/test/de/balvi/cuba/declarativecontrollers/web/combined/AnnotatableAbstractCombinedSpec.groovy b/modules/web/test/de/balvi/cuba/declarativecontrollers/web/combined/AnnotatableAbstractCombinedSpec.groovy new file mode 100644 index 0000000..1c35ee6 --- /dev/null +++ b/modules/web/test/de/balvi/cuba/declarativecontrollers/web/combined/AnnotatableAbstractCombinedSpec.groovy @@ -0,0 +1,136 @@ +package de.balvi.cuba.declarativecontrollers.web.combined + +import com.haulmont.cuba.core.global.Messages +import com.haulmont.cuba.core.sys.AppContext +import com.haulmont.cuba.gui.components.FieldGroup +import com.haulmont.cuba.gui.components.ListComponent +import com.haulmont.cuba.gui.components.Table +import com.haulmont.cuba.gui.data.CollectionDatasource +import com.haulmont.cuba.gui.data.Datasource +import de.balvi.cuba.declarativecontrollers.web.entitycombined.AnnotatableAbstractCombined +import de.balvi.cuba.declarativecontrollers.web.entitycombined.CombinedAnnotationDispatcher +import org.springframework.context.ApplicationContext +import spock.lang.Specification + +class AnnotatableAbstractCombinedSpec extends Specification { + + AnnotatableAbstractCombined sut + CombinedAnnotationDispatcher combinedAnnotationExecutorService + + ApplicationContext applicationContext = Mock(ApplicationContext) + Messages messages = Mock(Messages) + + Table tableMock = Mock(Table) + CollectionDatasource dsMock = Mock(CollectionDatasource) + FieldGroup fieldGroupMock = Mock(FieldGroup) + Datasource editDsMock = Mock(Datasource) + + def setup() { + + combinedAnnotationExecutorService = Mock(CombinedAnnotationDispatcher) + + sut = new AnnotatableAbstractCombinedMock( + combinedAnnotationDispatcher: combinedAnnotationExecutorService, + tableMock: tableMock, + fieldGroupMock: fieldGroupMock + ) + + AppContext.Internals.setApplicationContext(applicationContext) + applicationContext.getBean(Messages) >> messages + + tableMock.getDatasource() >> dsMock + fieldGroupMock.getDatasource() >> editDsMock + + } + + def cleanup() { + AppContext.Internals.setApplicationContext(null) + } + + def "init triggers the execution of the annotations"() { + + when: + sut.init([:]) + + then: + 1 * combinedAnnotationExecutorService.executeInit(sut, [:]) + } + + def "ready triggers the execution of the annotations"() { + + when: + sut.ready() + + then: + 1 * combinedAnnotationExecutorService.executeReady(sut, _) + } + + def "ready saves the parameters and passes them to the executorService"() { + + given: + def params = [my: 'param'] + sut.init(params) + + when: + sut.ready() + + then: + 1 * combinedAnnotationExecutorService.executeReady(sut, params) + } + + +} + +class AnnotatableAbstractCombinedMock extends AnnotatableAbstractCombined { + + + Table tableMock + FieldGroup fieldGroupMock + + @Override + protected ListComponent getTable() { + tableMock + } + + @Override + protected FieldGroup getFieldGroup() { + fieldGroupMock + } + + @Override + protected void initBrowseCreateAction() { + } + + @Override + protected void initBrowseEditAction() { + } + + @Override + protected void initBrowseRemoveAction() { + } + + @Override + protected void initShortcuts() { + } + + @Override + protected void disableEditControls() { + } + +// getter setter + Table getTableMock() { + tableMock + } + + void setTableMock(Table tableMock) { + this.tableMock = tableMock + } + + FieldGroup getFieldGroupMock() { + return fieldGroupMock + } + + void setFieldGroupMock(FieldGroup fieldGroupMock) { + this.fieldGroupMock = fieldGroupMock + } +} \ No newline at end of file diff --git a/modules/web/test/de/balvi/cuba/declarativecontrollers/web/combined/CombinedAnnotationDispatcherBeanSpec.groovy b/modules/web/test/de/balvi/cuba/declarativecontrollers/web/combined/CombinedAnnotationDispatcherBeanSpec.groovy new file mode 100644 index 0000000..3ebb37a --- /dev/null +++ b/modules/web/test/de/balvi/cuba/declarativecontrollers/web/combined/CombinedAnnotationDispatcherBeanSpec.groovy @@ -0,0 +1,163 @@ +package de.balvi.cuba.declarativecontrollers.web.combined + +import de.balvi.cuba.declarativecontrollers.web.annotationexecutor.browse.BrowseAnnotationExecutor +import de.balvi.cuba.declarativecontrollers.web.entitycombined.AnnotatableAbstractCombined +import de.balvi.cuba.declarativecontrollers.web.entitycombined.CombinedAnnotationDispatcher +import de.balvi.cuba.declarativecontrollers.web.entitycombined.CombinedAnnotationDispatcherBean +import groovy.transform.EqualsAndHashCode +import groovy.transform.ToString +import spock.lang.Ignore +import spock.lang.Specification + +@Ignore +class CombinedAnnotationDispatcherBeanSpec extends Specification { + CombinedAnnotationDispatcher combinedAnnotationExecutorService + BrowseAnnotationExecutor executor + BrowseAnnotationExecutor executor2 + + def setup() { + executor = Mock() + executor2 = Mock() + + combinedAnnotationExecutorService = new CombinedAnnotationDispatcherMock([executor, executor2]) + } + + void 'executeInit does nothing if the browser has no annotations'() { + + given: + AnnotatableAbstractCombined browse = Mock() + + when: + combinedAnnotationExecutorService.executeInit(browse, [:]) + + then: + 0 * executor.init(_, _, _) + } + + void 'executeInit executes init if an Annotation is supported'() { + + given: + AnnotatableAbstractCombined browse = new MyCombinedWithAnnotation() + + and: + executor.supports(_ as ToString) >> true + + when: + combinedAnnotationExecutorService.executeInit(browse, [:]) + + then: + 1 * executor.init(_, _, _) + 0 * executor2.init(_, _, _) + } + + void 'executeInit executes init on every AnnotationExecutor that supports the Annotation'() { + + given: + AnnotatableAbstractCombined browse = new MyCombinedWithAnnotation() + + and: + executor.supports(_ as ToString) >> true + executor2.supports(_ as ToString) >> true + + when: + combinedAnnotationExecutorService.executeInit(browse, [:]) + + then: + 1 * executor.init(_, _, _) + 1 * executor2.init(_, _, _) + } + + void 'executeInit does nothing if there is no AnnotationExecutor for this Annotation'() { + + given: + AnnotatableAbstractCombined browse = new MyCombinedWithAnnotation() + + and: + executor.supports(_ as EqualsAndHashCode) >> false + + when: + combinedAnnotationExecutorService.executeInit(browse, [:]) + + then: + 0 * executor.init(_, _, _) + } + + + void 'executeReady does nothing if the browser has no annotations'() { + + given: + AnnotatableAbstractCombined browse = Mock() + + when: + combinedAnnotationExecutorService.executeReady(browse, [:]) + + then: + 0 * executor.ready(_, _, _) + } + + void 'executeReady executes init if an Annotation is supported'() { + + given: + AnnotatableAbstractCombined browse = new MyCombinedWithAnnotation() + + and: + executor.supports(_ as ToString) >> true + + when: + combinedAnnotationExecutorService.executeReady(browse, [:]) + + then: + 1 * executor.ready(_, _, _) + 0 * executor2.ready(_, _, _) + } + + void 'executeReady executes init on every AnnotationExecutor that supports the Annotation'() { + + given: + AnnotatableAbstractCombined browse = new MyCombinedWithAnnotation() + + and: + executor.supports(_ as ToString) >> true + executor2.supports(_ as ToString) >> true + + when: + combinedAnnotationExecutorService.executeReady(browse, [:]) + + then: + 1 * executor.ready(_, _, _) + 1 * executor2.ready(_, _, _) + } + + void 'executeReady does nothing if there is no AnnotationExecutor for this Annotation'() { + + given: + AnnotatableAbstractCombined browse = new MyCombinedWithAnnotation() + + and: + executor.supports(_ as EqualsAndHashCode) >> false + + when: + combinedAnnotationExecutorService.executeReady(browse, [:]) + + then: + 0 * executor.ready(_, _, _) + } +} + +class CombinedAnnotationDispatcherMock extends CombinedAnnotationDispatcherBean { + + Collection annotationExecutorCollection + + CombinedAnnotationDispatcherMock(Collection annotationExecutorCollection) { + this.annotationExecutorCollection = annotationExecutorCollection + } + + @Override + protected Collection getCombinedAnnotationExecutors() { + return annotationExecutorCollection + } +} + +@ToString +class MyCombinedWithAnnotation extends AnnotatableAbstractCombined { +}