text: ///////////////////////////////////////////////////////////////////////////////
  // Copyright (c) Lewis Baker
  // Licenced under MIT license. See LICENSE.txt for details.
  ///////////////////////////////////////////////////////////////////////////////
  
  #include <cppcoro/net/ipv4_address.hpp>
  
  #include "doctest/cppcoro_doctest.h"
  
  
  TEST_SUITE_BEGIN("ipv4_address");
  
  using cppcoro::net::ipv4_address;
  
  TEST_CASE("DefaultConstructToZeroes")
  {
  	CHECK(ipv4_address{}.to_integer() == 0u);
  }
  
  TEST_CASE("to_integer() is BigEndian")
  {
  	ipv4_address address{ 10, 11, 12, 13 };
  	CHECK(address.to_integer() == 0x0A0B0C0Du);
  }
  
  TEST_CASE("is_loopback()")
  {
  	CHECK(ipv4_address{ 127, 0, 0, 1 }.is_loopback());
  	CHECK(ipv4_address{ 127, 0, 0, 50 }.is_loopback());
  	CHECK(ipv4_address{ 127, 5, 10, 15 }.is_loopback());
  	CHECK(!ipv4_address{ 10, 11, 12, 13 }.is_loopback());
  }
  
  TEST_CASE("bytes()")
  {
  	ipv4_address ip{ 19, 63, 129, 200 };
  	CHECK(ip.bytes()[0] == 19);
  	CHECK(ip.bytes()[1] == 63);
  	CHECK(ip.bytes()[2] == 129);
  	CHECK(ip.bytes()[3] == 200);
  }
  
  TEST_CASE("to_string()")
  {
  	CHECK(ipv4_address(0, 0, 0, 0).to_string() == "0.0.0.0");
  	CHECK(ipv4_address(10, 125, 255, 7).to_string() == "10.125.255.7");
  	CHECK(ipv4_address(123, 234, 101, 255).to_string() == "123.234.101.255");
  }
  
  TEST_CASE("from_string")
  {
  	// Check for some invalid strings.
  	CHECK(ipv4_address::from_string("") == std::nullopt);
  	CHECK(ipv4_address::from_string("asdf") == std::nullopt);
  	CHECK(ipv4_address::from_string(" 123.34.56.8") == std::nullopt);
  	CHECK(ipv4_address::from_string("123.34.56.8 ") == std::nullopt);
  	CHECK(ipv4_address::from_string("123.") == std::nullopt);
  	CHECK(ipv4_address::from_string("123.1") == std::nullopt);
  	CHECK(ipv4_address::from_string("123.12") == std::nullopt);
  	CHECK(ipv4_address::from_string("123.12.") == std::nullopt);
  	CHECK(ipv4_address::from_string("123.12.4") == std::nullopt);
  	CHECK(ipv4_address::from_string("123.12.45") == std::nullopt);
  	CHECK(ipv4_address::from_string("123.12.45.") == std::nullopt);
  
  	// Overflow of individual parts
  	CHECK(ipv4_address::from_string("456.12.45.30") == std::nullopt);
  	CHECK(ipv4_address::from_string("45.256.45.30") == std::nullopt);
  	CHECK(ipv4_address::from_string("45.25.677.30") == std::nullopt);
  	CHECK(ipv4_address::from_string("123.12.45.301") == std::nullopt);
  
  	// Can't parse octal yet.
  	CHECK(ipv4_address::from_string("00") == std::nullopt);
  	CHECK(ipv4_address::from_string("012345") == std::nullopt);
  	CHECK(ipv4_address::from_string("045.25.67.30") == std::nullopt);
  	CHECK(ipv4_address::from_string("45.025.67.30") == std::nullopt);
  	CHECK(ipv4_address::from_string("45.25.067.30") == std::nullopt);
  	CHECK(ipv4_address::from_string("45.25.67.030") == std::nullopt);
  
  	// Parse single integer format
  	CHECK(ipv4_address::from_string("0") == ipv4_address(0));
  	CHECK(ipv4_address::from_string("1") == ipv4_address(0, 0, 0, 1));
  	CHECK(ipv4_address::from_string("255") == ipv4_address(0, 0, 0, 255));
  	CHECK(ipv4_address::from_string("43534243") == ipv4_address(43534243));
  
  	// Parse dotted decimal format
  	CHECK(ipv4_address::from_string("45.25.67.30") == ipv4_address(45, 25, 67, 30));
  	CHECK(ipv4_address::from_string("0.0.0.0") == ipv4_address(0, 0, 0, 0));
  	CHECK(ipv4_address::from_string("1.2.3.4") == ipv4_address(1, 2, 3, 4));
  }
  TEST_SUITE_END();
  