|
| 1 | +using static Microsoft.VisualStudio.TestTools.UnitTesting.Assert; |
| 2 | +using static SqlServerSimulator.TestHelpers; |
| 3 | + |
| 4 | +namespace SqlServerSimulator; |
| 5 | + |
| 6 | +/// <summary> |
| 7 | +/// Behavioral tests for <c>ISNUMERIC(expression)</c>. Famously lossy on real |
| 8 | +/// SQL Server — bare <c>-</c> / <c>.</c> / <c>,</c> / <c>$</c> all return 1, |
| 9 | +/// hex strings return 0, and internal whitespace breaks the match. These |
| 10 | +/// cases are all probe-confirmed against SQL Server 2025. |
| 11 | +/// </summary> |
| 12 | +[TestClass] |
| 13 | +public sealed class IsNumericTests |
| 14 | +{ |
| 15 | + [TestMethod] public void Integer() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC('123')")); |
| 16 | + [TestMethod] public void NegativeInteger() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC('-123')")); |
| 17 | + [TestMethod] public void PositiveInteger() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC('+123')")); |
| 18 | + [TestMethod] public void Decimal() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC('1.5')")); |
| 19 | + [TestMethod] public void ScientificNotation_e() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC('1e10')")); |
| 20 | + [TestMethod] public void ScientificNotation_e_LargeExp() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC('1e308')")); |
| 21 | + [TestMethod] public void ScientificNotation_d() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC('1d10')")); |
| 22 | + [TestMethod] public void ScientificNotation_SignedExponent() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC('1e+10')")); |
| 23 | + [TestMethod] public void Currency() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC('$1')")); |
| 24 | + [TestMethod] public void CurrencyDecimal() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC('$1.50')")); |
| 25 | + [TestMethod] public void NonDollarCurrency() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC(N'£1')")); |
| 26 | + [TestMethod] public void SignThenCurrency() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC('-$1')")); |
| 27 | + [TestMethod] public void CurrencyThenSign() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC('$-1')")); |
| 28 | + |
| 29 | + /// <summary>Quirky probe-confirmed acceptance: a bare sign returns 1.</summary> |
| 30 | + [TestMethod] public void SignAlone() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC('-')")); |
| 31 | + |
| 32 | + /// <summary>Quirky probe-confirmed acceptance: a bare decimal point returns 1.</summary> |
| 33 | + [TestMethod] public void DecimalPointAlone() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC('.')")); |
| 34 | + |
| 35 | + [TestMethod] public void CommaAlone() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC(',')")); |
| 36 | + [TestMethod] public void CurrencyAlone() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC('$')")); |
| 37 | + |
| 38 | + [TestMethod] public void SpaceAlone_ReturnsZero() => AreEqual(0, ExecuteScalar<int>("select ISNUMERIC(' ')")); |
| 39 | + [TestMethod] public void EmptyString_ReturnsZero() => AreEqual(0, ExecuteScalar<int>("select ISNUMERIC('')")); |
| 40 | + [TestMethod] public void Null_ReturnsZero() => AreEqual(0, ExecuteScalar<int>("select ISNUMERIC(NULL)")); |
| 41 | + |
| 42 | + [TestMethod] public void ExponentWithoutLeadingDigit_ReturnsZero() => AreEqual(0, ExecuteScalar<int>("select ISNUMERIC('e10')")); |
| 43 | + [TestMethod] public void ExponentWithoutTrailingDigit_ReturnsZero() => AreEqual(0, ExecuteScalar<int>("select ISNUMERIC('1e')")); |
| 44 | + [TestMethod] public void HexPrefix_ReturnsZero() => AreEqual(0, ExecuteScalar<int>("select ISNUMERIC('0x10')")); |
| 45 | + [TestMethod] public void InternalWhitespace_ReturnsZero() => AreEqual(0, ExecuteScalar<int>("select ISNUMERIC(' 1 2 ')")); |
| 46 | + [TestMethod] public void TrailingNonDigit_ReturnsZero() => AreEqual(0, ExecuteScalar<int>("select ISNUMERIC('1L')")); |
| 47 | + [TestMethod] public void FExponentRejected() => AreEqual(0, ExecuteScalar<int>("select ISNUMERIC('1f10')")); |
| 48 | + |
| 49 | + [TestMethod] public void IntegerInput_ReturnsOne() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC(123)")); |
| 50 | + [TestMethod] public void FloatInput_ReturnsOne() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC(cast(1.5 as float))")); |
| 51 | + |
| 52 | + /// <summary>Probe-confirmed: bit is the one numeric-category type that returns 0.</summary> |
| 53 | + [TestMethod] public void BitInput_ReturnsZero() => AreEqual(0, ExecuteScalar<int>("select ISNUMERIC(cast(1 as bit))")); |
| 54 | + |
| 55 | + [TestMethod] public void LeadingAndTrailingWhitespace_TrimmedAccepted() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC(' 123 ')")); |
| 56 | + [TestMethod] public void ThousandsSeparated_Accepted() => AreEqual(1, ExecuteScalar<int>("select ISNUMERIC('1,000')")); |
| 57 | +} |
0 commit comments