content: /*
   * Copyright (C) 2012 ${project.organization.name}
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  package io.airlift.drift.codec.metadata;
  
  import com.google.common.collect.ImmutableMap;
  import io.airlift.drift.annotations.ThriftEnum;
  import io.airlift.drift.annotations.ThriftEnumUnknownValue;
  import io.airlift.drift.annotations.ThriftEnumValue;
  import io.airlift.drift.codec.Letter;
  import org.testng.annotations.Test;
  
  import java.util.Optional;
  
  import static io.airlift.drift.codec.metadata.ThriftEnumMetadataBuilder.thriftEnumMetadata;
  import static org.testng.Assert.assertEquals;
  
  public class TestThriftEnumMetadata
  {
      @Test
      public void testValid()
      {
          ThriftEnumMetadata<Letter> metadata = thriftEnumMetadata(Letter.class);
          assertEquals(metadata.getEnumClass(), Letter.class);
          assertEquals(metadata.getEnumName(), "Letter");
          assertEquals(metadata.getByEnumConstant(), ImmutableMap.<Letter, Integer>builder()
                  .put(Letter.A, 65)
                  .put(Letter.B, 66)
                  .put(Letter.C, 67)
                  .put(Letter.D, 68)
                  .put(Letter.UNKNOWN, -1)
                  .build());
          assertEquals(metadata.getByEnumValue(), ImmutableMap.<Integer, Letter>builder()
                  .put(65, Letter.A)
                  .put(66, Letter.B)
                  .put(67, Letter.C)
                  .put(68, Letter.D)
                  .put(-1, Letter.UNKNOWN)
                  .build());
          assertEquals(metadata.getUnknownEnumConstant(), Optional.of(Letter.UNKNOWN));
      }
  
      @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Enum class .*MissingEnumAnnotation is not annotated with @ThriftEnum")
      public void testMissingEnumAnnotation()
      {
          thriftEnumMetadata(MissingEnumAnnotation.class);
      }
  
      @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Enum class .*MissingValueMethod must have a method annotated with @ThriftEnumValue")
      public void testMissingValueMethod()
      {
          thriftEnumMetadata(MissingValueMethod.class);
      }
  
      @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Enum class .*MultipleValueMethods has multiple methods annotated with @ThriftEnumValue")
      public void testMultipleValueMethods()
      {
          thriftEnumMetadata(MultipleValueMethods.class);
      }
  
      @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Enum class .*DuplicateValues returned duplicate enum values: 42")
      public void testDuplicateValues()
      {
          thriftEnumMetadata(DuplicateValues.class);
      }
  
      @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Enum class .*MultipleUnknownValues has multiple constants annotated with @ThriftEnumUnknownValue")
      public void testMultipleUnknownValues()
      {
          thriftEnumMetadata(MultipleUnknownValues.class);
      }
  
      public enum MissingEnumAnnotation
      {
          FOO;
  
          @ThriftEnumValue
          public int value()
          {
              return 42;
          }
      }
  
      @ThriftEnum
      public enum MissingValueMethod
      {
          FOO
      }
  
      @ThriftEnum
      public enum MultipleValueMethods
      {
          FOO;
  
          @ThriftEnumValue
          public int value1()
          {
              return 1;
          }
  
          @ThriftEnumValue
          public int value2()
          {
              return 2;
          }
      }
  
      @ThriftEnum
      public enum DuplicateValues
      {
          FOO, BAR;
  
          @ThriftEnumValue
          public int value()
          {
              return 42;
          }
      }
  
      @ThriftEnum
      public enum MultipleUnknownValues
      {
          @ThriftEnumUnknownValue
          FOO,
          @ThriftEnumUnknownValue
          BAR;
  
          @ThriftEnumValue
          public int value()
          {
              return this.ordinal();
          }
      }
  }
  