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 ANY 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.UUID;
022
023import tech.sirwellington.alchemy.annotations.access.Internal;
024import tech.sirwellington.alchemy.annotations.access.NonInstantiable;
025import tech.sirwellington.alchemy.generator.AlchemyGenerator;
026
027import static java.lang.annotation.ElementType.FIELD;
028import static java.lang.annotation.RetentionPolicy.RUNTIME;
029import static tech.sirwellington.alchemy.generator.StringGenerators.*;
030import static tech.sirwellington.alchemy.test.Checks.Internal.checkNotNull;
031import static tech.sirwellington.alchemy.test.Checks.Internal.checkThat;
032
033/*
034 * <pre>
035 * 
036 * {@code
037 * `@RunWith(AlchemyTestRunner.class)
038 * public class ExampleTest
039 * {
040 *   `@GenerateString(HEXADECIMAL)
041 *   private String username;
042 * 
043 *  ...
044 * }
045 * 
046 * </pre>
047 */
048
049/**
050 * Used in with the {@link AlchemyTestRunner}, this Annotations allows the
051 * Runtime Injection of Generated Strings from the {@link AlchemyGenerator} library.
052 * <p>
053 * Example:
054 * <pre>
055 * {@code
056 * `@RunWith(AlchemyTestRunner.class)
057 * public class ExampleTest
058 * {
059 *   `@GenerateString(HEXADECIMAL)
060 *   private String username;
061 *
062 * }
063 * }
064 * </pre>
065 * <p>
066 * Note, '`' (ticks) used to escape Javadocs.
067 *
068 * @author SirWellington
069 * @see GenerateInteger
070 */
071@Target(FIELD)
072@Retention(RUNTIME)
073public @interface GenerateString
074{
075
076    /*
077     * Named value because it allows for @StringGenerator(ALPHABETIC) instead of @StringGenerator(type = ALPHABETIC)
078     */
079
080    /**
081     * The type of String to Generate
082     *
083     * @return
084     */
085    Type value() default Type.ALPHABETIC;
086
087    /**
088     * The length of the string, must be {@code > 0}.
089     *
090     * @return
091     */
092    int length() default 10;
093
094    public static enum Type
095    {
096        ALPHABETIC,
097        ALPHANUMERIC,
098        HEXADECIMAL,
099        NUMERIC,
100        /**
101         * For UUIDS, the {@link #length() } property will be ignored, and instead the standard UUID size from {@link UUID#randomUUID()
102         * } is used.
103         */
104        UUID;
105
106    }
107
108    @Internal
109    @NonInstantiable
110    static class Values
111    {
112
113        private Values() throws IllegalAccessException
114        {
115            throw new IllegalAccessException("cannot instantiate");
116        }
117
118        static AlchemyGenerator<String> createGeneratorFor(GenerateString annotation)
119        {
120            checkNotNull(annotation, "annotation is missing");
121
122            int length = annotation.length();
123            checkThat(length > 0, "Invalid @GenerateString use, length must be positive");
124
125            Type type = annotation.value();
126            checkNotNull(type, "@GenerateString Annotation missing type");
127
128            switch (type)
129            {
130                case ALPHABETIC:
131                    return alphabeticStrings(length);
132                case ALPHANUMERIC:
133                    return alphanumericStrings(length);
134                case HEXADECIMAL:
135                    return hexadecimalString(length);
136                case NUMERIC:
137                    return numericStrings(length);
138                case UUID:
139                    return uuids;
140                default:
141                    return alphabeticStrings(length);
142            }
143
144        }
145    }
146
147}