All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.seedstack.business.internal.EventFixtureInternal Maven / Gradle / Ivy

There is a newer version: 2.0.0
Show newest version
/**
 * Copyright (c) 2013-2015 by The SeedStack authors. All rights reserved.
 *
 * This file is part of SeedStack, An enterprise-oriented full development stack.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */
package org.seedstack.business.internal;

import com.google.inject.Injector;
import org.seedstack.business.api.*;
import org.seedstack.seed.core.api.SeedException;

import javax.inject.Inject;
import java.lang.reflect.Method;
import java.util.*;


class EventFixtureInternal implements EventFixture {

    static final String EVENT = "event";
    static final String EXPECTED = "expected";
    static final String HANDLERS = "handlers";
    static final String HANDLER = "handler";

    @Inject
    private Injector injector;

    @Inject
    private ContextLink contextLink;

    @Inject
    private EventService eventService;

    /////////////////////////////// Test on event handler ////////////////

    @Override
    public EventProvider given(Event event) {
        return new EventProviderInternal(event);
    }

    class EventProviderInternal implements EventProvider, EventServiceProvider {

        private final Event event;

        EventProviderInternal(Event event) {
            this.event = event;
        }

        @Override
        public EventServiceProvider whenFired() {
            eventService.fire(this.event);
            return this;
        }

        @Override
        public void wasHandledBy(Class... handlers) {
            Set> calledHandlers = contextLink.peek().keySet();

            for (Class handler : handlers) {
                if (!calledHandlers.contains(handler)) {
                    throw SeedException.createNew(EventTestErrorCodes.EVENT_WAS_NOT_HANDLER_BY)
                            .put(EVENT, event).put(HANDLER, handler);
                }
            }
        }

        @Override
        public void wasHandledExactlyBy(Class... handlers) {
            Set> calledHandlers = contextLink.peek().keySet();

            for (Class handler : handlers) {
                if (!calledHandlers.contains(handler)) {
                    throw SeedException.createNew(EventTestErrorCodes.EVENT_WAS_NOT_EXACTLY_HANDLER_BY)
                            .put(EVENT, event).put(EXPECTED, handlers).put(HANDLERS, calledHandlers);
                }
            }
            if (handlers.length != calledHandlers.size()) {
                throw SeedException.createNew(EventTestErrorCodes.EVENT_WAS_NOT_EXACTLY_HANDLER_BY)
                        .put(EVENT, event).put(EXPECTED, handlers).put(HANDLERS, calledHandlers);
            }
        }

        @Override
        public void wasNotHandledBy(Class... handlers) {
            Set> calledHandlers = contextLink.peek().keySet();

            for (Class handler : handlers) {
                if (calledHandlers.contains(handler)) {
                    throw SeedException.createNew(EventTestErrorCodes.EVENT_WAS_HANDLER_BY)
                            .put(EVENT, event).put(HANDLERS, calledHandlers).put(EXPECTED, handlers);
                }
            }
        }
    }

    /////////////////////////////// Test on service method ////////////////

    @Override
    public ServiceProvider given(Class aClass) {
        return new ServiceProviderInternal(aClass);
    }

    class ServiceProviderInternal implements ServiceProvider, HandlerProvider {

        private List argClasses;

        private final Class underTest;

        private String method;

        private Object[] args;

        ServiceProviderInternal(Class underTest) {
            this.underTest = underTest;
        }


        @Override
        public HandlerProvider whenCalled(String method, Object... args) {
            this.method = method;
            this.args = args;
            this.argClasses = new ArrayList(args.length);
            for (Object arg : args) {
                argClasses.add(arg.getClass());
            }
            return this;
        }

        @Override
        public void eventWasHandledBy(Event event, Class handler) {
            Map, Event> handlerMap = new HashMap, Event>();
            handlerMap.put(handler, event);
            eventWasHandledBy(handlerMap);
        }

        @SuppressWarnings("unchecked")
        @Override
        public void eventWasHandledBy(Map, Event> handlerMap) {
            try {
                Method declaredMethod = this.underTest.getDeclaredMethod(this.method, this.argClasses.toArray(new Class[this.args.length]));
                Object instance = injector.getInstance(underTest);
                declaredMethod.invoke(instance, args);
            } catch (Exception e) {
                throw SeedException.wrap(e, EventTestErrorCodes.FAILED_TO_INVOKE_METHOD);
            }
            Map, Event> callMap = contextLink.peek();
            for (Map.Entry, Event> entry : handlerMap.entrySet()) {
                Event event = callMap.get(entry.getKey());
                if (event == null) {
                    throw SeedException.createNew(EventTestErrorCodes.HANDLER_WAS_NOT_CALLED)
                            .put(HANDLER, entry.getKey());
                }

                if (entry.getValue() == null || !entry.getValue().equals(event)) {
                    throw SeedException.createNew(EventTestErrorCodes.HANDLER_WAS_NOT_CALLED_WITH_EXPECTED_EVENT)
                            .put(HANDLER, entry.getKey()).put(EVENT, entry.getValue());
                }
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy