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

com.github.jinahya.assertj.validation.PathAssert Maven / Gradle / Ivy

The newest version!
package com.github.jinahya.assertj.validation;

/*-
 * #%L
 * assertj-bean-validation-javax
 * %%
 * Copyright (C) 2021 - 2022 Jinahya, Inc.
 * %%
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * #L%
 */

import org.assertj.core.api.AbstractAssert;
import org.assertj.core.api.AbstractBooleanAssert;
import org.assertj.core.api.AbstractClassAssert;
import org.assertj.core.api.AbstractComparableAssert;
import org.assertj.core.api.AbstractIntegerAssert;
import org.assertj.core.api.AbstractListAssert;
import org.assertj.core.api.AbstractObjectAssert;
import org.assertj.core.api.AbstractStringAssert;
import org.assertj.core.api.Assert;
import org.assertj.core.api.AssertFactory;
import org.assertj.core.api.Assertions;
import org.assertj.core.api.ClassAssert;
import org.assertj.core.api.EnumerableAssert;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.assertj.core.api.ObjectAssertFactory;

import javax.validation.ElementKind;
import javax.validation.Path;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * An interface for verifying {@link Path} values.
 *
 * @param  self type parameter
 * @author Jin Kwon <onacit_at_gmail.com>
 */
public interface PathAssert>
        extends Assert,
                EnumerableAssert {

    /**
     * An interface for verifying {@link Path.Node} values.
     *
     * @param    self type parameter
     * @param  type of {@link Path.Node}
     * @author Jin Kwon <onacit_at_gmail.com>
     */
    interface NodeAssert, ACTUAL extends Path.Node> {

        interface HasContainerClass> {

            > ASSERT extractingContainerClass(
                    AssertFactory, ? extends ASSERT> factory
            );

            @SuppressWarnings({"unchecked"})
            default > SELF hasContainerClassSatisfying(
                    final AssertFactory, ? extends ASSERT> factory,
                    final Consumer consumer) {
                Objects.requireNonNull(consumer, "consumer is null");
                consumer.accept(extractingContainerClass(factory));
                return (SELF) this;
            }

            default AbstractClassAssert extractingContainerClass() {
                return extractingContainerClass(InstanceOfAssertFactories.CLASS);
            }

            default SELF hasContainerClassSatisfying(final Consumer> consumer) {
                return hasContainerClassSatisfying(InstanceOfAssertFactories.CLASS, consumer);
            }

            @SuppressWarnings({
                    "unchecked"
            })
            default SELF hasContainerClass(final Class expectedContainerClass) {
                extractingContainerClass().isEqualTo(expectedContainerClass);
                return (SELF) this;
            }
        }

        interface HasTypeArgumentIndex> {

            > ASSERT extractingTypeArgumentIndex(
                    AssertFactory factory
            );

            @SuppressWarnings({"unchecked"})
            default > SELF hasTypeArgumentIndexSatisfying(
                    final AssertFactory factory,
                    final Consumer consumer) {
                Objects.requireNonNull(consumer, "consumer is null");
                consumer.accept(extractingTypeArgumentIndex(factory));
                return (SELF) this;
            }

            default AbstractIntegerAssert extractingTypeArgumentIndex() {
                return extractingTypeArgumentIndex(InstanceOfAssertFactories.INTEGER);
            }

            default SELF hasTypeArgumentIndexSatisfying(final Consumer> consumer) {
                return hasTypeArgumentIndexSatisfying(InstanceOfAssertFactories.INTEGER, consumer);
            }

            @SuppressWarnings({
                    "unchecked"
            })
            default SELF hasTypeArgumentIndex(final Integer expectedTypeArgumentIndex) {
                extractingTypeArgumentIndex().isEqualTo(expectedTypeArgumentIndex);
                return (SELF) this;
            }

            default SELF doesNotHaveTypeArgumentIndex() {
                return hasTypeArgumentIndexSatisfying(AbstractAssert::isNull);
            }
        }

        interface HasParameterTypes> {

            >, Class, ? extends AbstractClassAssert>>
            ASSERT extractingParameterTypes(AssertFactory>, ? extends ASSERT> factory);

            @SuppressWarnings({"unchecked"})
            default >, Class, ? extends AbstractClassAssert>>
            SELF hasParameterTypesSatisfying(final AssertFactory>, ? extends ASSERT> factory,
                                             final Consumer consumer) {
                Objects.requireNonNull(consumer, "consumer is null");
                consumer.accept(extractingParameterTypes(factory));
                return (SELF) this;
            }

            default AbstractListAssert>, Class, ? extends AbstractClassAssert> extractingParameterTypes() {
                return extractingParameterTypes(
                        a -> Assertions.>, Class, ClassAssert>assertThat(a, ClassAssert::new)
                );
            }
        }

        interface HasParameterIndex> {

            > ASSERT extractingParameterIndex(
                    AssertFactory factory
            );

            @SuppressWarnings({"unchecked"})
            default > SELF hasParameterIndexSatisfying(
                    final AssertFactory factory,
                    final Consumer consumer) {
                Objects.requireNonNull(consumer, "consumer is null");
                consumer.accept(extractingParameterIndex(factory));
                return (SELF) this;
            }

            default AbstractIntegerAssert extractingParameterIndex() {
                return extractingParameterIndex(InstanceOfAssertFactories.INTEGER);
            }

            default SELF hasParameterIndexSatisfying(final Consumer> consumer) {
                return hasParameterIndexSatisfying(InstanceOfAssertFactories.INTEGER, consumer);
            }

            @SuppressWarnings({
                    "unchecked"
            })
            default SELF hasParameterIndex(final Integer expectedParameterIndex) {
                extractingParameterIndex().isEqualTo(expectedParameterIndex);
                return (SELF) this;
            }

            default SELF doesNotHaveParameterIndex() {
                return hasParameterIndexSatisfying(AbstractAssert::isNull);
            }
        }
        // ---------------------------------------------------------------------------------------------------------- as
//        > ASSERT extractingAs(
//                final Class nodeType,
//                final AssertFactory assertFactory
//        );

        // ------------------------------------------------------------------------------------------------------- index
        > ASSERT extractingIndex(
                AssertFactory factory
        );

        @SuppressWarnings({"unchecked"})
        default > SELF hasIndexSatisfying(
                final AssertFactory factory,
                final Consumer consumer) {
            Objects.requireNonNull(consumer, "consumer is null");
            consumer.accept(extractingIndex(factory));
            return (SELF) this;
        }

        /**
         * Returns an assert for verifying {@link Path.Node#getIndex() actual.index} value.
         *
         * @return an assert for verifying {@link Path.Node#getIndex() actual.index} value.
         * @see #extractingIndex(AssertFactory)
         */
        default AbstractIntegerAssert extractingIndex() {
            return extractingIndex(InstanceOfAssertFactories.INTEGER);
        }

        /**
         * Verifies that {@link Path.Node#getIndex() actual.index} value satisfies according to specified consumer.
         *
         * @param consumer the consumer verifies the {@link Path.Node#getIndex() actual.index} value.
         * @return this assertion object
         * @see #extractingIndex()
         */
        @SuppressWarnings({"unchecked"})
        default SELF hasIndexSatisfying(final Consumer> consumer) {
            Objects.requireNonNull(consumer, "consumer is null");
            consumer.accept(extractingIndex());
            return (SELF) this;
        }

        /**
         * Verifies that {@link Path.Node#getIndex() actual.index} is equal to specified value.
         *
         * @param expectedIndex expected value of {@link Path.Node#getIndex() actual.index}.
         * @return this assertion object.
         * @see #hasIndexSatisfying(Consumer)
         */
        default SELF hasIndex(final Integer expectedIndex) {
            return hasIndexSatisfying(a -> a.isEqualTo(expectedIndex));
        }

        default SELF doesNotHaveIndex() {
            return hasIndex(null);
        }

        // --------------------------------------------------------------------------------------------------------- key

        /**
         * Returns an assert for verifying {@link Path.Node#getKey()} actual.key} value.
         *
         * @param extractor a function for extracting {@link Path.Node#getKey() actual.key} value.
         * @param factory   an assertion factory.
         * @return an assert for verifying {@link Path.Node#getKey() actual.key} value.
         * @see #extractingKey()
         */
        > ASSERT extractingKey(
                Function extractor,
                AssertFactory factory
        );

        @SuppressWarnings({"unchecked"})
        default > SELF hasKeySatisfying(
                final Function extractor,
                final AssertFactory factory,
                final Consumer consumer) {
            Objects.requireNonNull(consumer, "consumer is null");
            consumer.accept(extractingKey(extractor, factory));
            return (SELF) this;
        }

        /**
         * Returns an assert for verifying {@link Path.Node#getKey()} actual.key} value.
         *
         * @return an assert for verifying {@link Path.Node#getKey() actual.key} value.
         * @see #extractingKey()
         */
        default AbstractObjectAssert extractingKey() {
            return extractingKey(Path.Node::getKey, new ObjectAssertFactory<>());
        }

        @SuppressWarnings({"unchecked"})
        default SELF hasKeySatisfying(final Consumer> consumer) {
            consumer.accept(extractingKey());
            return (SELF) this;
        }

        /**
         * Verifies that {@link Path.Node#getKey() actual.key} is {@link #isEqualTo(Object) equal} to specified value.
         *
         * @param expectedKey expected value of {@link Path.Node#getKey() actual.key}.
         * @return this assertion object.
         * @see #hasKeySatisfying(Consumer)
         */
        default SELF hasKey(final Object expectedKey) {
            return hasKeySatisfying(a -> a.isEqualTo(expectedKey));
        }

        // -------------------------------------------------------------------------------------------------------- kind
        > ASSERT extractingKind(
                AssertFactory factory
        );

        @SuppressWarnings({"unchecked"})
        default > SELF hasKindSatisfying(
                final AssertFactory factory,
                final Consumer consumer) {
            Objects.requireNonNull(consumer, "consumer is null");
            consumer.accept(extractingKind(factory));
            return (SELF) this;
        }

        /**
         * Returns an assert for verifying {@link Path.Node#getKind() actual.kind} value.
         *
         * @return an assert for verifying {@link Path.Node#getKind() actual.kind} value.
         */
        default AbstractComparableAssert extractingKind() {
            return extractingKind(InstanceOfAssertFactories.comparable(ElementKind.class));
        }

        default SELF hasKindSatisfying(
                final Consumer> consumer) {
            Objects.requireNonNull(consumer, "consumer is null");
            return hasKindSatisfying(InstanceOfAssertFactories.comparable(ElementKind.class), consumer);
        }

        /**
         * Verifies that {@link Path.Node#getKind() actual.kind} value is {@link #isEqualTo(Object) equal} to specified
         * value.
         *
         * @return this assertion object.
         */
        default SELF hasKind(final ElementKind expectedKind) {
            return hasKindSatisfying(a -> a.isSameAs(expectedKind));
        }

        // -------------------------------------------------------------------------------------------------------- name
        > ASSERT extractingName(
                AssertFactory factory
        );

        @SuppressWarnings({"unchecked"})
        default > SELF hasNameSatisfying(
                final AssertFactory factory,
                final Consumer consumer) {
            Objects.requireNonNull(consumer, "consumer is null");
            consumer.accept(extractingName(factory));
            return (SELF) this;
        }

        /**
         * Returns an assert for verifying {@link Path.Node#getName() actual.name} value.
         *
         * @return an assert for verifying {@link Path.Node#getName() actual.name} value.
         */
        default AbstractStringAssert extractingName() {
            return extractingName(InstanceOfAssertFactories.STRING);
        }

        default SELF hasNameSatisfying(final Consumer> consumer) {
            return hasNameSatisfying(InstanceOfAssertFactories.STRING, consumer);
        }

        /**
         * Verifies that {@link Path.Node#getName() actual.name} value is {@link #isEqualTo(Object) equal} to specified
         * value.
         *
         * @return this assertion object.
         */
        default SELF hasName(final String expectedName) {
            return hasNameSatisfying(a -> a.isEqualTo(expectedName));
        }

        // -------------------------------------------------------------------------------------------------- inIterable
        > ASSERT extractingInIterable(
                AssertFactory factory
        );

        @SuppressWarnings({"unchecked"})
        default > SELF hasInIterableSatisfying(
                final AssertFactory factory,
                final Consumer consumer) {
            Objects.requireNonNull(consumer, "consumer is null");
            consumer.accept(extractingInIterable(factory));
            return (SELF) this;
        }

        default AbstractBooleanAssert extractingInIterable() {
            return extractingInIterable(InstanceOfAssertFactories.BOOLEAN);
        }

        default SELF hasInIterableSatisfying(final Consumer> consumer) {
            return hasInIterableSatisfying(InstanceOfAssertFactories.BOOLEAN, consumer);
        }

        @SuppressWarnings({"unchecked"})
        default SELF isInIterable() {
            extractingInIterable().isTrue();
            return (SELF) this;
        }

        default SELF isNotInIterable() {
            return hasInIterableSatisfying(AbstractBooleanAssert::isFalse);
        }
    }

    // -------------------------------------------------------------------------------------------------------- BeanNode
    interface BeanNodeAssert>
            extends NodeAssert,
                    NodeAssert.HasContainerClass,
                    NodeAssert.HasTypeArgumentIndex {

    }

    // ------------------------------------------------------------------------------------------------- ConstructorNode
    interface ConstructorNodeAssert>
            extends NodeAssert,
                    NodeAssert.HasParameterTypes {

    }

    // -------------------------------------------------------------------------------------------- ContainerElementNode
    interface ContainerElementNodeAssert>
            extends NodeAssert,
                    NodeAssert.HasContainerClass,
                    NodeAssert.HasTypeArgumentIndex {

    }

    // ---------------------------------------------------------------------------------------------- CrossParameterNode
    interface CrossParameterNodeAssert>
            extends NodeAssert {

    }

    // ------------------------------------------------------------------------------------------------------ MethodNode
    interface MethodNodeAssert>
            extends NodeAssert,
                    NodeAssert.HasParameterTypes {

    }

    // --------------------------------------------------------------------------------------------------- ParameterNode
    interface ParameterNodeAssert>
            extends NodeAssert,
                    NodeAssert.HasParameterIndex {

    }

    // ---------------------------------------------------------------------------------------------------- PropertyNode
    interface PropertyNodeAssert>
            extends NodeAssert,
                    NodeAssert.HasContainerClass,
                    NodeAssert.HasTypeArgumentIndex {

    }

    // ------------------------------------------------------------------------------------------------- ReturnValueNode
    interface ReturnValueNodeAssert>
            extends NodeAssert {

    }

    // -----------------------------------------------------------------------------------------------------------------
    , N extends Path.Node> A extractingNode(
            int index, Class nodeType, AssertFactory factory);

    @SuppressWarnings({"unchecked"})
    default , N extends Path.Node>
    SELF hasNodeSatisfying(final int index, final Class nodeType,
                           final AssertFactory factory, final Consumer consumer) {
        Objects.requireNonNull(consumer, "consumer is null");
        consumer.accept(extractingNode(index, nodeType, factory));
        return (SELF) this;
    }

    > A extractingNode(
            int index, AssertFactory factory);

    AbstractPathAssert.AbstractNodeAssert extractingNode(int index);

    @SuppressWarnings({"unchecked"})
    default SELF hasNodeSatisfying(final int index,
                                   final Consumer> consumer) {
        Objects.requireNonNull(consumer, "consumer is null");
        consumer.accept(extractingNode(index));
        return (SELF) this;
    }

    > A extractingBeanNode(
            int index, AssertFactory factory);

    AbstractPathAssert.AbstractBeanNodeAssert extractingBeanNode(int index);

    > A extractingPropertyNode(
            int index, AssertFactory factory);

    AbstractPathAssert.AbstractPropertyNodeAssert extractingPropertyNode(int index);

    @SuppressWarnings({"unchecked"})
    default SELF hasPropertyNodeSatisfying(final int index, final Consumer> consumer) {
        Objects.requireNonNull(consumer, "consumer is null");
        consumer.accept(extractingPropertyNode(index));
        return (SELF) this;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy