from typing import Any
from toolbox import format_time_ns

def Assert(name: str, expected: Any, result: Any):
	if expected != result:
		print(f"For test name {name} Expected '{expected}' but got '{result}' instead")
		assert False

def format_time_ns_test() -> None:
	# https://en.wikipedia.org/wiki/Unit_of_time
	Assert("format_time_ns null",                      "0ns",                              format_time_ns(0));
	Assert("format_time_ns nanosecond",                "1ns",                              format_time_ns(1));
	Assert("format_time_ns shake",                     "10ns",                             format_time_ns(10));
	Assert("format_time_ns microsecond",               "1µs",                              format_time_ns(int(1e3)));
	Assert("format_time_ns millisecond",               "1ms",                              format_time_ns(int(1e6)));
	Assert("format_time_ns centisecond",               "10ms",                             format_time_ns(int(1e7)));
	Assert("format_time_ns decisecond",                "100ms",                            format_time_ns(int(1e8)));
	Assert("format_time_ns second",                    "1s",                               format_time_ns(int(1e9)));
	Assert("format_time_ns decasecond",                "10s",                              format_time_ns(int(1e10)));
	Assert("format_time_ns minute",                    "1m",                               format_time_ns(int(6e10)));
	Assert("format_time_ns milliday",                  "1m 26s 400ms",                     format_time_ns(int(864e8)));
	Assert("format_time_ns hectosecond",               "1m 40s",                           format_time_ns(int(1e11)));
	Assert("format_time_ns kilosecond",                "16m 40s",                          format_time_ns(int(1e12)));
	Assert("format_time_ns hour",                      "1h",                               format_time_ns(int(36e11)));
	Assert("format_time_ns day",                       "1j",                               format_time_ns(int(864e11)));
	Assert("format_time_ns week/sennight",             "1w",                               format_time_ns(int(6048e11)));
	Assert("format_time_ns megasecond",                "1w 4j 13h 46m 40s",                format_time_ns(int(1e15)));
	Assert("format_time_ns fortnight",                 "2w",                               format_time_ns(int(12096e11)));
	Assert("format_time_ns lunar month (draconitic)",  "3w 6j 5h 5m 35s 800ms",            format_time_ns(int(23511358e8)));
	Assert("format_time_ns lunar month (tropical)",    "3w 6j 7h 43m 4s 700ms",            format_time_ns(int(23605847e8)));
	Assert("format_time_ns lunar month (sidereal)",    "3w 6j 7h 43m 11s 600ms",           format_time_ns(int(23605916e8)));
	Assert("format_time_ns lunar month (anomalistic)", "3w 6j 13h 18m 33s 200ms",          format_time_ns(int(23807132e8)));
	Assert("format_time_ns lunar month (synodic)",     "4w 1j 12h 44m 2s 900ms",           format_time_ns(int(25514429e8)));
	Assert("format_time_ns month",                     "1M",                               format_time_ns(int(26784e11)));
	Assert("format_time_ns quarantine",                "1M 1w 2j",                         format_time_ns(int(3456e12)));
	Assert("format_time_ns semester",                  "4M 2j",                            format_time_ns(int(108864e11)));
	Assert("format_time_ns lunar year",                "11M 1w 6j 8h 52m 48s",             format_time_ns(int(30617568e9)));
	Assert("format_time_ns year",                      "1y",                               format_time_ns(int(31536e12)));
	Assert("format_time_ns tropical year",             "1y 5h 48m 45s 216ms",              format_time_ns(int(31556925216e6)));
	Assert("format_time_ns gregorian year",            "1y 5h 49m 12s",                    format_time_ns(int(31556952e9)));
	Assert("format_time_ns sidereal year",             "1y 6h 9m 9s 763ms 545µs 600ns",    format_time_ns(int(315581497635456e2)));
	Assert("format_time_ns leap year",                 "1y 1j",                            format_time_ns(int(316224e11)));
	Assert("format_time_ns olympiad",                  "4y",                               format_time_ns(int(126144e12)));
	Assert("format_time_ns lusturm",                   "5y",                               format_time_ns(int(15768e13)));
	Assert("format_time_ns decade",                    "10y",                              format_time_ns(int(31536e13)));
	Assert("format_time_ns indiction",                 "15y",                              format_time_ns(int(47304e13)));
	Assert("format_time_ns score",                     "20y",                              format_time_ns(int(63072e13)));
	Assert("format_time_ns gigasecond",                "31y 8M 1w 4j 1h 46m 40s",          format_time_ns(int(1e18)));
	Assert("format_time_ns jubilee",                   "50y",                              format_time_ns(int(15768e14)));
	Assert("format_time_ns century",                   "1c",                               format_time_ns(int(31536e14)));
	Assert("format_time_ns millennium",                "10c",                              format_time_ns(int(31536e15)));
	Assert("format_time_ns age",                       "257c 72y",                         format_time_ns(int(812745792e12)));
	Assert("format_time_ns terasecond",                "3170c 97y 10M 3w 4j 17h 46m 40s",  format_time_ns(int(1e22)));
	Assert("format_time_ns megaannum",                 "10000c",                           format_time_ns(int(31536e18)));
	# Cannot use number bigger than currently supported ISO Python
	#Assert("format_time_ns petasecond",                "317097c 91y 11M 2w 4j 1h 46m 40s", format_time_ns(int(1e24)));
	#Assert("format_time_ns galactic year",             "2300000c",                         format_time_ns(int(725328e19)));
	#Assert("format_time_ns eon",                       "10000000c",                        format_time_ns(int(31536e21)));
	#Assert("format_time_ns kalpa",                     "43200000c",                        format_time_ns(int(13623552e19)));
	#Assert("format_time_ns exasecond",                 "317097919c 83y 9M 1h 46m 40s",     format_time_ns(int(1e27)));
	#Assert("format_time_ns zettasecond",               "",                                 format_time_ns(int(1e30)));
	#Assert("format_time_ns yottasecond",               "",                                 format_time_ns(int(1e33)));
	#Assert("format_time_ns ronnasecond",               "",                                 format_time_ns(int(1e36)));
	#Assert("format_time_ns quettasecond",              "",                                 format_time_ns(int(1e39)));
	# uint64_t_MAX == 2**64 == 18446744073709551615I64u == -1
	Assert("format_time_ns max",                       "5c 84y 11M 2j 23h 34m 33s 709ms 551µs 615ns", format_time_ns(2**64 - 1))