001/* 002 * Copyright © 2018. Sir Wellington. 003 * Licensed under the Apache License, Version 2.0 (the "License"); 004 * you may not use this file except in compliance with the License. 005 * 006 * You may obtain a copy of the License at 007 * http://www.apache.org/licenses/LICENSE-2.0 008 * 009 * Unless required by applicable law or agreed to in writing, software 010 * distributed under the License is distributed on an "AS IS" BASIS, 011 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 * See the License for the specific language governing permissions and 013 * limitations under the License. 014 */ 015 016package tech.sirwellington.alchemy.test.junit.runners; 017 018import java.lang.annotation.Retention; 019import java.lang.annotation.Target; 020import java.util.Date; 021 022import tech.sirwellington.alchemy.annotations.access.Internal; 023import tech.sirwellington.alchemy.annotations.access.NonInstantiable; 024import tech.sirwellington.alchemy.generator.AlchemyGenerator; 025import tech.sirwellington.alchemy.generator.DateGenerators; 026 027import static java.lang.annotation.ElementType.FIELD; 028import static java.lang.annotation.RetentionPolicy.RUNTIME; 029import static tech.sirwellington.alchemy.test.Checks.Internal.checkNotNull; 030import static tech.sirwellington.alchemy.test.Checks.Internal.checkThat; 031 032/** 033 * Used in with the {@link AlchemyTestRunner}, this Annotations allows the Runtime Injection of Generated {@linkplain Date Dates} 034 * using {@link DateGenerators} from the {@link AlchemyGenerator} library. 035 * <p> 036 * Example: 037 * <pre> 038 * {@code 039 * `@RunWith(AlchemyTestRunner.class) 040 * public class ExampleTest 041 * { 042 * `@GenerateDate(ANYTIME) 043 * private Date dateOfOrder; 044 * 045 * ... 046 * } 047 * } 048 * </pre> 049 * Note, ticks (`) used to escape Javadocs. 050 * 051 * @author SirWellington 052 * @see GenerateString 053 */ 054@Target(FIELD) 055@Retention(RUNTIME) 056public @interface GenerateDate 057{ 058 059 Type value() default Type.ANYTIME; 060 061 /** 062 * If using the {@link Type#RANGE} type, specify a beginning date, in Epoch Millis. 063 * 064 * @return 065 */ 066 long startDate() default 0; 067 068 /** 069 * If using the {@link Type#RANGE} type, specify an end date, in Epoch Millis. 070 * 071 * @return 072 */ 073 long endDate() default 0; 074 075 public enum Type 076 { 077 PAST, 078 PRESENT, 079 FUTURE, 080 ANYTIME, 081 RANGE 082 } 083 084 @Internal 085 @NonInstantiable 086 static class Values 087 { 088 089 private Values() throws IllegalAccessException 090 { 091 throw new IllegalAccessException("cannot instantiate"); 092 } 093 094 static AlchemyGenerator<Date> createGeneratorFor(GenerateDate annotation) throws IllegalArgumentException 095 { 096 checkNotNull(annotation, "missing annotation"); 097 098 switch (annotation.value()) 099 { 100 case PAST: 101 return DateGenerators.pastDates(); 102 case PRESENT: 103 return DateGenerators.presentDates(); 104 case FUTURE: 105 return DateGenerators.futureDates(); 106 case ANYTIME: 107 return DateGenerators.anyTime(); 108 case RANGE: 109 return datesInRange(annotation.startDate(), annotation.endDate()); 110 default: 111 return DateGenerators.anyTime(); 112 } 113 } 114 115 private static AlchemyGenerator<Date> datesInRange(long startDate, long endDate) 116 { 117 checkThat(startDate < endDate, "startDate must come before endDate"); 118 119 Date start = new Date(startDate); 120 Date end = new Date(endDate); 121 122 return DateGenerators.datesBetween(start, end); 123 } 124 } 125 126}