// FIXME(integers): add tests that perform the same checks in generic code

%{
from SwiftIntTypes import all_integer_types, int_max, int_min
from SwiftFloatingPointTypes import all_floating_point_types, getFtoIBounds

from decimal import Decimal
}%

import StdlibUnittest

var FixedPointConversionTraps = TestSuite("FixedPointToFixedPointConversionTraps")
var FixedPointConversionFailure = TestSuite("FixedPointToFixedPointConversionFailures")

var FloatingPointConversionTruncations = TestSuite("FloatingPointToFixedPointConversionTruncations")
var FloatingPointConversionTraps = TestSuite("FloatingPointConversionTraps")
var FloatingPointConversionFailures = TestSuite("FloatingPointToFixedPointConversionFailures")

func getInfiniteOrNaNMessage() -> String {
  if _isDebugAssertConfiguration() {
    return "either infinite or NaN"
  }
  return ""
}

func getTooSmallMessage() -> String {
  if _isDebugAssertConfiguration() {
    return "would be less than"
  }
  return ""
}

func getTooLargeMessage() -> String {
  if _isDebugAssertConfiguration() {
    return "would be greater than"
  }
  return ""
}

% word_bits = int(target_ptrsize)
% for self_ty in all_integer_types(word_bits):
%   selfBits = self_ty.bits
%   selfSigned = self_ty.is_signed
%   selfMin = self_ty.min
%   selfMax = self_ty.max
%   Self = self_ty.stdlib_name

%   # Test conversion behaviors for all integer types
%   for other_ty in all_integer_types(word_bits):
%     otherBits = other_ty.bits
%     otherSigned = other_ty.is_signed
%     otherMin = other_ty.min
%     otherMax = other_ty.max
%     Other = other_ty.stdlib_name

%     for testValue in [selfMin, selfMax, selfMin - 1, selfMax + 1, otherMin, otherMax]:

%       if testValue < otherMin or testValue > otherMax:
%         # Can't construct `other` value, do nothing and continue.
%         pass
%       elif testValue >= selfMin and testValue <= selfMax:
%         # Test value can be represented by Self, test conversion succeeds

/// Always-safe conversion from ${Other}(${testValue}) to ${Self}.
FixedPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}") {
  // Test that nothing interesting happens and we end up with the same result after converting.
  let input = get${Other}(${testValue})
  expectEqual(${testValue}, ${Self}(input))
}

/// Never-nil failable conversion from ${Other}(${testValue}) to ${Self}.
FixedPointConversionFailure.test("${Other}To${Self}FailableConversion/dest=${testValue}") {
  // Test that nothing interesting happens and we end up with a non-nil, identical result.
  let input = get${Other}(${testValue})
  let result = ${Self}(exactly: input)
  expectEqual(${testValue}, result)
}

%       else:
%         # Test value is out of range of Self, test conversion fails

/// Always-failing conversion from ${Other}(${testValue}) to ${Self}.
FixedPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValue}") {
  // Test that we check if we fail and crash when an integer would be truncated in conversion.
  let input = get${Other}(${testValue})
  expectCrashLater()
  let result = ${Self}(input)
  _blackHole(result)
}

/// Always-nil failable conversion from ${Other}(${testValue}) to ${Self}.
FixedPointConversionFailure.test("${Other}To${Self}Conversion/dest=${testValue}") {
  // Test that we check if we return nil when an integer would be truncated in conversion.
  let input = get${Other}(${testValue})
  expectNil(${Self}(exactly: input))
}

%       end
%     end # for testValue in ...
%   end # for in all_integer_types (Other)

%   # Test conversion behaviors for all floating-point types
%   for other_type in all_floating_point_types():
%     Other = "Float" + str(other_type.bits)
%     otherMin = -int_max(bits=other_type.explicit_significand_bits, signed=False)
%     otherMax = int_max(bits=other_type.explicit_significand_bits, signed=False)
%     (selfFtoIMin, selfFtoIMax) = getFtoIBounds(other_type.bits, selfBits, selfSigned)

%     if Other == 'Float80':
#if !os(Windows) && (arch(i386) || arch(x86_64))
%     end

%     testValues = [
%       Decimal(selfMin),
%       Decimal(selfMax),
%       Decimal(selfFtoIMin) - Decimal('0.1'),
%       Decimal(selfFtoIMax) + Decimal('0.1'),
%       Decimal(otherMin),
%       Decimal(otherMax),
%       Decimal('0.0'),
%       Decimal('-0.0'),
%       Decimal('0.1'),
%       Decimal('-0.1')
%     ]
%     for testValue in testValues:
%       testValueStr = str(testValue)

%       if testValue < otherMin or testValue > otherMax:
%         # Can't construct `other` value to test from, do nothing and continue.
%         pass
%       elif testValue >= selfFtoIMin and testValue <= selfFtoIMax and (testValue % 1).is_zero():
%         # Test value can be represented exactly by Self, test two-way conversion

FloatingPointConversionTruncations.test("${Other}To${Self}Conversion/dest=${testValueStr}") {
  let input = get${Other}(${testValueStr})
  let result = ${Self}(input)
  let resultConvertedBack = ${Other}(result)
  expectEqual(${testValueStr}, resultConvertedBack)
}

FloatingPointConversionFailures.test("${Other}To${Self}FailableConversion/dest=${testValueStr}") {
  let input = get${Other}(${testValueStr})
  expectNotNil(${Self}(exactly: input))
}

%       else:
%         if testValue > selfFtoIMax:
%           # Test value exceeds maximum value of Self, test for too large message
FloatingPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValueStr}")
.crashOutputMatches(getTooLargeMessage()).code {
  expectCrashLater()
%         elif testValue < selfFtoIMin:
%           # Test value doesn't reach minimum value of Self, test for too small message
FloatingPointConversionTraps.test("${Other}To${Self}Conversion/dest=${testValueStr}")
.crashOutputMatches(getTooSmallMessage()).code {
  expectCrashLater()
%         else:
%           # Test value can be represented inexactly by Self, test for truncation
FloatingPointConversionTruncations.test("${Other}To${Self}Conversion/dest=${testValueStr}") {
%         end
  let input = get${Other}(${testValueStr})
  let result = ${Self}(input)
  let resultConvertedBack = ${Other}(result)
  expectNotEqual(input, resultConvertedBack)
}

FloatingPointConversionFailures.test("${Other}To${Self}Conversion/dest=${testValueStr}") {
  let input = get${Other}(${testValueStr})
  expectNil(${Self}(exactly: input))
}
%       end
%     end # for in testValues

// Test Always-Trapping conversions.

%     if not selfSigned:

FloatingPointConversionTraps.test("${Self}/${Other}/negative")
  .crashOutputMatches(getTooSmallMessage()).code {
  expectCrashLater()
  _blackHole(${Self}(get${Other}(-123.0)))
}

FloatingPointConversionFailures.test("${Self}/${Other}/negative") {
  expectNil(${Self}(exactly: get${Other}(-123.0)))
}

%     end

FloatingPointConversionTraps.test("${Self}/${Other}/+inf")
  .crashOutputMatches(getInfiniteOrNaNMessage()).code {
  expectCrashLater()
  _blackHole(${Self}(get${Other}(${Other}.infinity)))
}

FloatingPointConversionFailures.test("${Self}/${Other}/+inf") {
  expectNil(${Self}(exactly: get${Other}(${Other}.infinity)))
}

FloatingPointConversionTraps.test("${Self}/${Other}/-inf")
  .crashOutputMatches(getInfiniteOrNaNMessage()).code {
  expectCrashLater()
  _blackHole(${Self}(get${Other}(-${Other}.infinity)))
}

FloatingPointConversionFailures.test("${Self}/${Other}/-inf") {
  expectNil(${Self}(exactly: get${Other}(-${Other}.infinity)))
}

FloatingPointConversionTraps.test("${Self}/${Other}/NaN")
  .crashOutputMatches(getInfiniteOrNaNMessage()).code {
  expectCrashLater()
  _blackHole(${Self}(get${Other}(${Other}.nan)))
}

FloatingPointConversionFailures.test("${Self}/${Other}/NaN") {
  expectNil(${Self}(exactly: get${Other}(${Other}.nan)))
}

%     if Other == 'Float80':
#endif
%     end

%   end # for in all_floating_point_types (Other)
% end # for in all_integer_types (Self)

runAllTests()
