text: ﻿using System;
  using System.Diagnostics;
  using System.Globalization;
  using NetTopologySuite.IO;
  using NUnit.Framework;
  
  namespace NetTopologySuite.Tests.NUnit.IO
  {
      public class OrdinateFormatTest
      {
          [Test]
          public void TestLargeNumber()
          {
              // ensure scientific notation is not used
              CheckFormat(1234567890.0, "1234567890");
          }
  
          [Test]
          public void TestDoubleMinMaxEpsilon()
          {
              CheckFormat(double.MaxValue, "179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
              CheckFormat(double.MinValue, "-179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
  
              // note: .NET Framework and .NET Core pre-3.0 fail this check.
              // see https://devblogs.microsoft.com/dotnet/floating-point-parsing-and-formatting-improvements-in-net-core-3-0/
              CheckFormat(double.Epsilon, "0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005");
          }
  
          [Test]
          public void TestVeryLargeNumber()
          {
              // ensure scientific notation is not used
              // note output is rounded since it exceeds double precision accuracy
              CheckFormat(12345678901234567890.0, "12345678901234567000");
          }
  
          [Test]
          public void TestDecimalPoint()
          {
              CheckFormat(1.123, "1.123");
          }
  
          [Test]
          public void TestNegative()
          {
              CheckFormat(-1.123, "-1.123");
          }
  
          [Test]
          public void TestFractionDigits()
          {
              CheckFormat(1.123456789012345, "1.123456789012345");
              CheckFormat(0.0123456789012345, "0.0123456789012345");
              CheckFormat(1.123456789012345E4, "11234.56789012345");
          }
  
          [Test]
          public void TestLimitedFractionDigits2()
          {
              CheckFormat(1.123456789012345, 2, "1.12");
              CheckFormat(1.123456789012345, 3, "1.123");
              CheckFormat(1.123456789012345, 4, "1.1235");
              CheckFormat(1.123456789012345, 5, "1.12346");
              CheckFormat(1.123456789012345, 6, "1.123457");
          }
  
          [Test]
          public void TestMaximumFractionDigits()
          {
              CheckFormat(0.0000000000123456789012345, "0.0000000000123456789012345");
          }
  
          [TestCase(0.84551240822557006, "0.8455124082255701")]
          public void TestValue(double value, string expected)
          {
              // note: .NET Framework and .NET Core pre-3.0 fail this check.
              // see https://devblogs.microsoft.com/dotnet/floating-point-parsing-and-formatting-improvements-in-net-core-3-0/
              CheckFormat(value, expected);
          }
  
          [Test]
          public void TestPi()
          {
              // note: .NET Framework and .NET Core pre-3.0 fail this check.
              // see https://devblogs.microsoft.com/dotnet/floating-point-parsing-and-formatting-improvements-in-net-core-3-0/
              CheckFormat(Math.PI, "3.141592653589793");
          }
  
          /*
          [Test, Ignore("Just testing")]
          public void TestFormat()
          {
              Console.WriteLine(string.Format(NumberFormatInfo.InvariantInfo,
                  $"{{0:0.{new string('#', 325)}}}", double.MaxValue));
              Console.WriteLine(string.Format(NumberFormatInfo.InvariantInfo,
                  "{0:G17}", double.MaxValue));
  
              double parsed1 = double.Parse(string.Format(NumberFormatInfo.InvariantInfo,
                  $"{{0:0.{new string('#', 325)}}}", double.MaxValue), NumberFormatInfo.InvariantInfo);
  
              double parsed2 = double.Parse(string.Format(NumberFormatInfo.InvariantInfo,
                  "{0:G17}", double.MaxValue), NumberFormatInfo.InvariantInfo);
              Assert.That(parsed1, Is.EqualTo(double.MaxValue));
  
              Console.WriteLine(string.Format(NumberFormatInfo.InvariantInfo, $"{{0:0.{new string('#', 325)}}}", Math.PI));
              Console.WriteLine(string.Format(NumberFormatInfo.InvariantInfo, $"{{0:R}}", Math.PI));
              Console.WriteLine(string.Format(NumberFormatInfo.InvariantInfo, $"{{0:G17}}", Math.PI));
          }
          */
  
          [Test]
          public void TestNaN()
          {
              CheckFormat(double.NaN, "NaN");
          }
  
          [Test]
          public void TestInf()
          {
              CheckFormat(double.PositiveInfinity, "Inf");
              CheckFormat(double.NegativeInfinity, "-Inf");
          }
  
          private void CheckFormat(double d, string expected)
          {
              string actual = OrdinateFormat.Default.Format(d);
              Assert.That(actual, Is.EqualTo(expected));
          }
  
          private void CheckFormat(double d, int maxFractionDigits, string expected)
          {
              var format = new OrdinateFormat(maxFractionDigits);
              string actual = format.Format(d);
              Assert.That(actual, Is.EqualTo(expected));
          }
      }
  }
  