context: // Copyright (c) .NET Foundation. All rights reserved.
  // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
  
  using System;
  using System.Collections.Generic;
  using System.Globalization;
  using Xunit;
  
  namespace Microsoft.AspNet.Mvc.ModelBinding
  {
      public class ValueProviderResultTest
      {
          [Fact]
          public void ConvertTo_ReturnsNullForReferenceTypes_WhenValueIsNull()
          {
              var valueProviderResult = new ValueProviderResult(null, null, CultureInfo.InvariantCulture);
  
              var convertedValue = valueProviderResult.ConvertTo(typeof(string));
  
              Assert.Null(convertedValue);
          }
  
          [Fact]
          public void ConvertTo_ReturnsDefaultForValueTypes_WhenValueIsNull()
          {
              var valueProviderResult = new ValueProviderResult(null, null, CultureInfo.InvariantCulture);
  
              var convertedValue = valueProviderResult.ConvertTo(typeof(int));
  
              Assert.Equal(0, convertedValue);
          }
  
          [Fact]
          public void ConvertToCanConvertArraysToSingleElements()
          {
              // Arrange
              var vpr = new ValueProviderResult(new int[] { 1, 20, 42 }, "", CultureInfo.InvariantCulture);
  
              // Act
              var converted = (string)vpr.ConvertTo(typeof(string));
  
              // Assert
              Assert.Equal("1", converted);
          }
  
          [Fact]
          public void ConvertToCanConvertSingleElementsToArrays()
          {
              // Arrange
              var vpr = new ValueProviderResult(42, "", CultureInfo.InvariantCulture);
  
              // Act
              var converted = (string[])vpr.ConvertTo(typeof(string[]));
  
              // Assert
              Assert.NotNull(converted);
              var result = Assert.Single(converted);
              Assert.Equal("42", result);
          }
  
          [Fact]
          public void ConvertToCanConvertSingleElementsToSingleElements()
          {
              // Arrange
              var vpr = new ValueProviderResult(42, "", CultureInfo.InvariantCulture);
  
              // Act
              var converted = (string)vpr.ConvertTo(typeof(string));
  
              // Assert
              Assert.NotNull(converted);
              Assert.Equal("42", converted);
          }
  
          [Fact]
          public void ConvertingNullStringToNullableIntReturnsNull()
          {
              // Arrange
              object original = null;
              var vpr = new ValueProviderResult(original, "", CultureInfo.InvariantCulture);
  
              // Act
              var returned = (int?)vpr.ConvertTo(typeof(int?));
  
              // Assert
              Assert.Equal(returned, null);
          }
  
          [Fact]
          public void ConvertingWhiteSpaceStringToNullableIntReturnsNull()
          {
              // Arrange
              var original = " ";
              var vpr = new ValueProviderResult(original, "", CultureInfo.InvariantCulture);
  
              // Act
              var returned = (int?)vpr.ConvertTo(typeof(int?));
  
              // Assert
              Assert.Equal(returned, null);
          }
  
          [Fact]
          public void ConvertToReturnsNullIfArrayElementValueIsNull()
          {
              // Arrange
              var vpr = new ValueProviderResult(new string[] { null }, null, CultureInfo.InvariantCulture);
  
              // Act
              var outValue = vpr.ConvertTo(typeof(int));
  
              // Assert
              Assert.Null(outValue);
          }
  
          [Fact]
          public void ConvertToReturnsNullIfTryingToConvertEmptyArrayToSingleElement()
          {
              // Arrange
              var vpr = new ValueProviderResult(new int[0], "", CultureInfo.InvariantCulture);
  
              // Act
              var outValue = vpr.ConvertTo(typeof(int));
  
              // Assert
              Assert.Null(outValue);
          }
  
          [Theory]
          [InlineData("")]
          [InlineData(" \t \r\n ")]
          public void ConvertToReturnsNullIfTrimmedValueIsEmptyString(object value)
          {
              // Arrange
              var vpr = new ValueProviderResult(value, null, CultureInfo.InvariantCulture);
  
              // Act
              var outValue = vpr.ConvertTo(typeof(int));
  
              // Assert
              Assert.Null(outValue);
          }
  
          [Fact]
          public void ConvertToReturnsNullIfTrimmedValueIsEmptyString()
          {
              // Arrange
              var vpr = new ValueProviderResult(rawValue: null,
                                                attemptedValue: null,
                                                culture: CultureInfo.InvariantCulture);
  
              // Act
              var outValue = vpr.ConvertTo(typeof(int[]));
  
              // Assert
              Assert.Null(outValue);
          }
  
          [Fact]
          public void ConvertToReturnsValueIfArrayElementIsIntegerAndDestinationTypeIsEnum()
          {
              // Arrange
              var result = new ValueProviderResult(new object[] { 1 }, null, CultureInfo.InvariantCulture);
  
              // Act
              var outValue = result.ConvertTo(typeof(IntEnum));
  
              // Assert
              Assert.Equal(outValue, IntEnum.Value1);
          }
  
          [Theory]
          [InlineData(1, typeof(IntEnum), IntEnum.Value1)]
          [InlineData(1L, typeof(LongEnum), LongEnum.Value1)]
          [InlineData(long.MaxValue, typeof(LongEnum), LongEnum.MaxValue)]
          [InlineData(1U, typeof(UnsignedIntEnum), UnsignedIntEnum.Value1)]
          [InlineData(1UL, typeof(IntEnum), IntEnum.Value1)]
          [InlineData((byte)1, typeof(ByteEnum), ByteEnum.Value1)]
          [InlineData(byte.MaxValue, typeof(ByteEnum), ByteEnum.MaxValue)]
          [InlineData((sbyte)1, typeof(ByteEnum), ByteEnum.Value1)]
          [InlineData((short)1, typeof(IntEnum), IntEnum.Value1)]
          [InlineData((ushort)1, typeof(IntEnum), IntEnum.Value1)]
          [InlineData(int.MaxValue, typeof(IntEnum?), IntEnum.MaxValue)]
          [InlineData(null, typeof(IntEnum?), null)]
          [InlineData(1L, typeof(LongEnum?), LongEnum.Value1)]
          [InlineData(null, typeof(LongEnum?), null)]
          [InlineData(uint.MaxValue, typeof(UnsignedIntEnum?), UnsignedIntEnum.MaxValue)]
          [InlineData((byte)1, typeof(ByteEnum?), ByteEnum.Value1)]
          [InlineData(null, typeof(ByteEnum?), null)]
          [InlineData((ushort)1, typeof(LongEnum?), LongEnum.Value1)]
          public void ConvertToReturnsValueIfArrayElementIsAnyIntegerTypeAndDestinationTypeIsEnum(
              object input,
              Type enumType,
              object expected)
          {
              // Arrange
              var result = new ValueProviderResult(new object[] { input }, null, CultureInfo.InvariantCulture);
  
              // Act
              var outValue = result.ConvertTo(enumType);
  
              // Assert
              Assert.Equal(expected, outValue);
          }
  
          [Fact]
          public void ConvertToReturnsValueIfArrayElementIsStringValueAndDestinationTypeIsEnum()
          {
              // Arrange
              var vpr = new ValueProviderResult(new object[] { "1" }, null, CultureInfo.InvariantCulture);
  
              // Act
              var outValue = vpr.ConvertTo(typeof(IntEnum));
  
              // Assert
              Assert.Equal(outValue, IntEnum.Value1);
          }
  
          [Fact]
          public void ConvertToReturnsValueIfArrayElementIsStringKeyAndDestinationTypeIsEnum()
          {
              // Arrange
              var vpr = new ValueProviderResult(new object[] { "Value1" }, null, CultureInfo.InvariantCulture);
  
              // Act
              var outValue = vpr.ConvertTo(typeof(IntEnum));
  
              // Assert
              Assert.Equal(outValue, IntEnum.Value1);
          }
  
          [Fact]
          public void ConvertToReturnsValueIfElementIsStringAndDestinationIsNullableInteger()
          {
              // Arrange
              var vpr = new ValueProviderResult("12", null, CultureInfo.InvariantCulture);
  
              // Act
              var outValue = vpr.ConvertTo(typeof(int?));
  
              // Assert
              Assert.Equal(12, outValue);
          }
  
          [Fact]
          public void ConvertToReturnsValueIfElementIsStringAndDestinationIsNullableDouble()
          {
              // Arrange
              var vpr = new ValueProviderResult("12.5", null, CultureInfo.InvariantCulture);
  
              // Act
              var outValue = vpr.ConvertTo(typeof(double?));
  
              // Assert
              Assert.Equal(12.5, outValue);
          }
  
          [Fact]
          public void ConvertToReturnsValueIfElementIsDecimalAndDestinationIsNullableInteger()
          {
              // Arrange
              var vpr = new ValueProviderResult(12M, null, CultureInfo.InvariantCulture);
  
              // Act
              var outValue = vpr.ConvertTo(typeof(int?));
  
              // Assert
              Assert.Equal(12, outValue);
          }
  
          [Fact]
          public void ConvertToReturnsValueIfElementIsDecimalAndDestinationIsNullableDouble()
          {
              // Arrange
              var vpr = new ValueProviderResult(12.5M, null, CultureInfo.InvariantCulture);
  
              // Act
              var outValue = vpr.ConvertTo(typeof(double?));
  
              // Assert
              Assert.Equal(12.5, outValue);
          }
  
          [Fact]
          public void ConvertToReturnsValueIfElementIsDecimalDoubleAndDestinationIsNullableInteger()
          {
              // Arrange
              var vpr = new ValueProviderResult(12.5M, null, CultureInfo.InvariantCulture);
  
              // Act
              var outValue = vpr.ConvertTo(typeof(int?));
  
              // Assert
              Assert.Equal(12, outValue);
          }
  
          [Fact]
          public void ConvertToReturnsValueIfElementIsDecimalDoubleAndDestinationIsNullableLong()
          {
              // Arrange
              var vpr = new ValueProviderResult(12.5M, null, CultureInfo.InvariantCulture);
  
              // Act
              var outValue = vpr.ConvertTo(typeof(long?));
  
              // Assert
              Assert.Equal(12L, outValue);
          }
  
          [Fact]
          public void ConvertToReturnsValueIfArrayElementInstanceOfDestinationType()
          {
              // Arrange
              var vpr = new ValueProviderResult(new object[] { "some string" }, null, CultureInfo.InvariantCulture);
  
              // Act
              var outValue = vpr.ConvertTo(typeof(string));
  
              // Assert
              Assert.Equal("some string", outValue);
          }
  
          [Theory]
          [InlineData(new object[] { new[] { 1, 0 } })]
          [InlineData(new object[] { new[] { "Value1", "Value0" } })]
          [InlineData(new object[] { new[] { "Value1", "value0" } })]
          public void ConvertTo_ConvertsEnumArrays(object value)
          {
              // Arrange
              var vpr = new ValueProviderResult(value, null, CultureInfo.InvariantCulture);
  
              // Act
              var outValue = vpr.ConvertTo(typeof(IntEnum[]));
  
              // Assert
  
gt:             var result = Assert.IsType<IntEnum[]>(outValue);