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