001/**
002 * Powerunit - A JDK1.8 test framework
003 * Copyright (C) 2014 Mathieu Boretti.
004 *
005 * This file is part of Powerunit
006 *
007 * Powerunit is free software: you can redistribute it and/or modify
008 * it under the terms of the GNU General Public License as published by
009 * the Free Software Foundation, either version 3 of the License, or
010 * (at your option) any later version.
011 *
012 * Powerunit is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
015 * GNU General Public License for more details.
016 *
017 * You should have received a copy of the GNU General Public License
018 * along with Powerunit. If not, see <http://www.gnu.org/licenses/>.
019 */
020package ch.powerunit.extensions.async.lang;
021
022import static ch.powerunit.extensions.async.lang.WaitResult.predicateWithToString;
023import static java.util.Arrays.stream;
024import static java.util.Objects.requireNonNull;
025
026import java.util.Objects;
027import java.util.concurrent.CompletableFuture;
028import java.util.function.Predicate;
029
030/**
031 * Second Step of the builder of {@link CompletableFuture} to specify the
032 * condition to accept a result.
033 * 
034 * @param <T>
035 *            The type of result of the {@link CompletableFuture}
036 *
037 */
038public interface WaitResultBuilder2<T> {
039        /**
040         * Specify the condition that accept the result.
041         * 
042         * @param acceptingClause
043         *            the {@link Predicate} to validate the result
044         * @return {@link WaitResultBuilder3 the next step of the builder}
045         */
046        WaitResultBuilder3<T> expecting(Predicate<T> acceptingClause);
047
048        /**
049         * Specify that the returned result must be equals to the received object.
050         * 
051         * @param other
052         *            the object to compare with. May be null.
053         * @return {@link WaitResultBuilder3 the next step of the builder}
054         * @see Predicate#isEqual(Object)
055         * @since 1.0.0
056         */
057        default WaitResultBuilder3<T> expectingEqualsTo(T other) {
058                return expecting(
059                                predicateWithToString(Predicate.isEqual(other), () -> String.format("is equals to %s", other)));
060        }
061
062        /**
063         * Specify that the returned result must be not null.
064         * 
065         * @return {@link WaitResultBuilder3 the next step of the builder}
066         * @see Objects#nonNull(Object)
067         * @since 1.0.0
068         */
069        default WaitResultBuilder3<T> expectingNotNull() {
070                return expecting(predicateWithToString(Objects::nonNull, () -> "is not null"));
071        }
072
073        /**
074         * Specify the condition that doesn't accept the result.
075         * 
076         * @param notAcceptingClause
077         *            the {@link Predicate} to validate the result
078         * @return {@link WaitResultBuilder3 the next step of the builder}
079         * @since 1.0.0
080         */
081        default WaitResultBuilder3<T> expectingNot(Predicate<T> notAcceptingClause) {
082                requireNonNull(notAcceptingClause, "notAcceptingClause can't be null");
083                return expecting(
084                                predicateWithToString(notAcceptingClause.negate(), () -> String.format("not %s", notAcceptingClause)));
085        }
086
087        /**
088         * Specify that at least one condition must accept the result.
089         * 
090         * @param acceptingClause1
091         *            {@link Predicate first condition} to accept the result.
092         * @param next
093         *            all the following condition to accept the result.
094         * @return {@link WaitResultBuilder3 the next step of the builder}
095         * @since 1.0.0
096         */
097        default WaitResultBuilder3<T> expectingAnyOf(Predicate<T> acceptingClause1,
098                        @SuppressWarnings("unchecked") Predicate<T>... next) {
099                Predicate<T> base = requireNonNull(acceptingClause1, "acceptingClause1 can't be null");
100                return expecting(stream(next).reduce(base, Predicate::or));
101        }
102
103        /**
104         * Specify that at all conditions must accept the result.
105         * 
106         * @param acceptingClause1
107         *            {@link Predicate first condition} to accept the result.
108         * @param next
109         *            all the following condition to accept the result.
110         * @return {@link WaitResultBuilder3 the next step of the builder}
111         * @since 1.0.0
112         */
113        default WaitResultBuilder3<T> expectingAllOf(Predicate<T> acceptingClause1,
114                        @SuppressWarnings("unchecked") Predicate<T>... next) {
115                Predicate<T> base = requireNonNull(acceptingClause1, "acceptingClause1 can't be null");
116                return expecting(stream(next).reduce(base, Predicate::and));
117
118        }
119}