001/* 002 * Copyright 2023 the original author or authors. 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package de.cuioss.test.valueobjects.api.contracts; 017 018import java.lang.annotation.ElementType; 019import java.lang.annotation.Retention; 020import java.lang.annotation.RetentionPolicy; 021import java.lang.annotation.Target; 022import java.util.Collection; 023 024import de.cuioss.test.valueobjects.api.property.PropertyBuilderConfig; 025import de.cuioss.test.valueobjects.api.property.PropertyConfig; 026import de.cuioss.test.valueobjects.contract.BuilderContractImpl; 027import de.cuioss.test.valueobjects.property.PropertyMetadata; 028import de.cuioss.test.valueobjects.property.impl.PropertyMetadataImpl; 029import de.cuioss.test.valueobjects.property.impl.PropertyMetadataImpl.PropertyMetadataBuilder; 030import de.cuioss.test.valueobjects.property.util.AssertionStrategy; 031import de.cuioss.tools.property.PropertyMemberInfo; 032import de.cuioss.tools.property.PropertyReadWrite; 033 034/** 035 * If used on ValueObjectTest this test checks / tests builder of value objects. 036 * <p> 037 * As default the test assumes a static factory method with the name "builder", 038 * e.g. {@link PropertyMetadataImpl#builder()} being present on the type to be 039 * tested. This can be controlled using {@link #builderFactoryMethodName()}, 040 * {@link #builderFactoryProvidingClass()} and {@link #builderMethodName()}. In 041 * case you have a builder that can be instantiated directly by using a no-args 042 * public constructor directly you can use {@link #builderClass()} instead. 043 * </p> 044 * <p> 045 * The builder methods for the individual properties are assumed to use the 046 * property-name only as method-name, e.g. 047 * {@link PropertyMetadataBuilder#propertyClass(Class)}. In case you prefer a 048 * prefix you can either configure it using {@link #methodPrefix()} or can do 049 * some more fine grained configuration with {@link PropertyBuilderConfig} 050 * </p> 051 * 052 * @author Oliver Wolff 053 */ 054@Retention(RetentionPolicy.RUNTIME) 055@Target({ ElementType.TYPE }) 056public @interface VerifyBuilder { 057 058 /** 059 * @return the name of the factory method for creating the builder instances. It 060 * is assumed that it is parameter-free static method. If not set it 061 * defaults to 062 * {@value BuilderContractImpl#DEFAULT_BUILDER_FACTORY_METHOD_NAME} 063 */ 064 String builderFactoryMethodName() default BuilderContractImpl.DEFAULT_BUILDER_FACTORY_METHOD_NAME; 065 066 /** 067 * @return the name of the build method on the {@link #builderClass()}. It is 068 * assumed that it is parameter-free method on the builderType and 069 * returns instances of the type on unit class level of ValueObjectTest. 070 * Defaults to {@value BuilderContractImpl#DEFAULT_BUILD_METHOD_NAME} 071 */ 072 String builderMethodName() default BuilderContractImpl.DEFAULT_BUILD_METHOD_NAME; 073 074 /** 075 * This attribute defines the actual type of the concrete builder. The default 076 * value {@link VerifyBuilder} acts as {@code null} value. If it is set it will 077 * be used instead of any factory. It is assumed to have a no args public 078 * constructor. 079 * 080 * @return the builder-class 081 */ 082 Class<?> builderClass() default VerifyBuilder.class; 083 084 /** 085 * Optional attribute. The default assumes that the factory method for creating 086 * the concrete builder is located at the object under test. This method is only 087 * necessary if it is located on another type, e.g the actual unit-test-class. 088 * The default value {@link VerifyBuilder} acts as null value 089 * 090 * @return the type where the builderFactoryMethod is defined, the name of this 091 * method is defined within {@link #builderFactoryMethodName()} 092 */ 093 Class<?> builderFactoryProvidingClass() default VerifyBuilder.class; 094 095 /** 096 * @return an array of properties, identified by their names that are not to be 097 * considered for this test: black-list 098 */ 099 String[] exclude() default {}; 100 101 /** 102 * @return an array of properties, identified by their names that are to be 103 * considered for this test: white-list 104 */ 105 String[] of() default {}; 106 107 /** 108 * @return an array of properties, identified by their names that are to be 109 * treated as required properties, see 110 * {@link PropertyMetadata#isRequired()} 111 */ 112 String[] required() default {}; 113 114 /** 115 * @return an array of properties, identified by their names that are to be 116 * treated as transient properties, see 117 * {@link PropertyMemberInfo#TRANSIENT} 118 */ 119 String[] transientProperties() default {}; 120 121 /** 122 * @return an array of properties, identified by their names that are to be 123 * treated as having a default values, see 124 * {@link PropertyMetadata#isDefaultValue()} 125 */ 126 String[] defaultValued() default {}; 127 128 /** 129 * @return an array of properties, identified by their names that are to be 130 * treated as being read-only, see {@link PropertyReadWrite#READ_ONLY}, 131 * usually used in conjunction with {@link #defaultValued()} 132 */ 133 String[] readOnly() default {}; 134 135 /** 136 * @return an array of properties, identified by their names that are to be 137 * treated as being write-only, see 138 * {@link PropertyReadWrite#WRITE_ONLY}, usually used in cases where a 139 * property to be written will result in other properties but itself can 140 * not be accessed directly 141 */ 142 String[] writeOnly() default {}; 143 144 /** 145 * @return an array of properties, identified by their names representing at 146 * least a {@link Collection} that are to be asserted ignoring the 147 * concrete order, see {@link PropertyConfig#assertionStrategy()} and 148 * {@link AssertionStrategy#COLLECTION_IGNORE_ORDER}. The default 149 * implementation will always respect / assert the same order of 150 * elements. 151 */ 152 String[] assertUnorderedCollection() default {}; 153 154 /** 155 * In case methodPrefix is not set the corresponding build method to be accessed 156 * for setting the value is the name of the attribute: propertyName(), in case 157 * it is a concrete value, e.g. 'with' it will taken into account: 158 * withPropertName(). 159 * 160 * @return the method prefix, defaults to empty string 161 */ 162 String methodPrefix() default ""; 163 164}