001/* 002 * Copyright 2015 SirWellington Tech. 003 * 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 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 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 ANYTIME KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package tech.sirwellington.alchemy.test.junit.runners; 018 019import java.lang.annotation.Retention; 020import java.lang.annotation.Target; 021import java.util.Date; 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 * 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 * @see GenerateString 052 * @see GenerateInstant 053 * 054 * @author SirWellington 055 */ 056@Target(FIELD) 057@Retention(RUNTIME) 058public @interface GenerateDate 059{ 060 061 Type value() default Type.ANYTIME; 062 063 /** 064 * If using the {@link Type#RANGE} type, specify a beginning date, in Epoch Millis. 065 * 066 * @return 067 */ 068 long startDate() default 0; 069 070 /** 071 * If using the {@link Type#RANGE} type, specify an end date, in Epoch Millis. 072 * 073 * @return 074 */ 075 long endDate() default 0; 076 077 public enum Type 078 { 079 PAST, 080 PRESENT, 081 FUTURE, 082 ANYTIME, 083 RANGE 084 } 085 086 @Internal 087 @NonInstantiable 088 static class Values 089 { 090 091 private Values() throws IllegalAccessException 092 { 093 throw new IllegalAccessException("cannot instantiate"); 094 } 095 096 static AlchemyGenerator<Date> createGeneratorFor(GenerateDate annotation) throws IllegalArgumentException 097 { 098 checkNotNull(annotation, "missing annotation"); 099 100 switch (annotation.value()) 101 { 102 case PAST: 103 return DateGenerators.pastDates(); 104 case PRESENT: 105 return DateGenerators.presentDates(); 106 case FUTURE: 107 return DateGenerators.futureDates(); 108 case ANYTIME: 109 return DateGenerators.anyTime(); 110 case RANGE: 111 return datesInRange(annotation.startDate(), annotation.endDate()); 112 default: 113 return DateGenerators.anyTime(); 114 } 115 } 116 117 private static AlchemyGenerator<Date> datesInRange(long startDate, long endDate) 118 { 119 checkThat(startDate < endDate, "startDate must come before endDate"); 120 121 Date start = new Date(startDate); 122 Date end = new Date(endDate); 123 124 return DateGenerators.datesBetween(start, end); 125 } 126 } 127 128}