// Copyright 2025-2026 Gabriel Bjørnager Jensen.
//
// SPDX: MIT OR Apache-2.0

//! Tests for [`NString`].

#![cfg(test)]

use core::cmp::Ordering::{Equal, Greater, Less};
use nvec::NString;

#[cfg(feature = "alloc")]
use alloc::borrow::Cow;

#[cfg(feature = "alloc")]
use alloc::string::String;

#[test]
fn test_n_string_add_add_assign() {
	let mut s = NString::<16>::new() + "WHO IS";

	assert_eq!(s.len(), 6);
	assert_eq!(s,       "WHO IS");

	s += " U????";

	assert_eq!(s.len(), 12);
	assert_eq!(s,       "WHO IS U????");
}

#[test]
#[should_panic]
fn test_n_string_add_assign_out_of_memory() {
	let mut s = NString::<4>::new();

	s += "hell";
	s += "hellO";
}

#[test]
fn test_n_string_new() {
	let s = NString::<256>::new();

	assert_eq!(s.capacity(), 256);
	assert_eq!(s.len(),      000);
	assert_eq!(s,            "");
}

#[test]
fn test_n_string_partial_ord() {
	let s0 = NString::<64>::try_from_str("nVec").unwrap();
	let s1 = NString::<64>::try_from_str("nVecIsNice").unwrap();
	let s2 = NString::<10>::try_from_str("nVec").unwrap();
	let s3 = NString::<10>::try_from_str("nVecIsNice").unwrap();
	let s4 = "nVec";
	let s5 = "nVecIsNice";

	#[cfg(feature = "alloc")]
	let s6 = String::from("nVec");

	#[cfg(feature = "alloc")]
	let s7 = String::from("nVecIsNice");

	#[cfg(feature = "alloc")]
	let s8 = Cow::Borrowed("nVec");

	#[cfg(feature = "alloc")]
	let s9 = Cow::Borrowed("nVecIsNice");

	#[cfg(feature = "alloc")]
	let s10 = Cow::<'_, str>::Owned("nVec".into());

	#[cfg(feature = "alloc")]
	let s11 = Cow::<'_, str>::Owned("nVecIsNice".into());

	assert_eq!(s0.partial_cmp(&s0), Some(Equal));
	assert_eq!(s0.partial_cmp(&s1), Some(Less));
	assert_eq!(s0.partial_cmp(&s2), Some(Equal));
	assert_eq!(s0.partial_cmp(&s3), Some(Less));
	assert_eq!(s0,                  s4);
	assert_ne!(s0,                  s5);

	assert_eq!(s1.partial_cmp(&s0), Some(Greater));
	assert_eq!(s1.partial_cmp(&s1), Some(Equal));
	assert_eq!(s1.partial_cmp(&s2), Some(Greater));
	assert_eq!(s1.partial_cmp(&s3), Some(Equal));
	assert_ne!(s1,                  s4);
	assert_eq!(s1,                  s5);

	assert_eq!(s2.partial_cmp(&s0), Some(Equal));
	assert_eq!(s2.partial_cmp(&s1), Some(Less));
	assert_eq!(s2.partial_cmp(&s2), Some(Equal));
	assert_eq!(s2.partial_cmp(&s3), Some(Less));
	assert_eq!(s2,                  s4);
	assert_ne!(s2,                  s5);

	assert_eq!(s3.partial_cmp(&s0), Some(Greater));
	assert_eq!(s3.partial_cmp(&s1), Some(Equal));
	assert_eq!(s3.partial_cmp(&s2), Some(Greater));
	assert_eq!(s3.partial_cmp(&s3), Some(Equal));
	assert_ne!(s3,                  s4);
	assert_eq!(s3,                  s5);

	assert_eq!(s4.partial_cmp(&s0), Some(Equal));
	assert_eq!(s4.partial_cmp(&s1), Some(Less));
	assert_eq!(s4.partial_cmp(&s2), Some(Equal));
	assert_eq!(s4.partial_cmp(&s3), Some(Less));
	assert_eq!(s4,                  s4);
	assert_ne!(s4,                  s5);

	assert_eq!(s5.partial_cmp(&s0), Some(Greater));
	assert_eq!(s5.partial_cmp(&s1), Some(Equal));
	assert_eq!(s5.partial_cmp(&s2), Some(Greater));
	assert_eq!(s5.partial_cmp(&s3), Some(Equal));
	assert_ne!(s5,                  s4);
	assert_eq!(s5,                  s5);

	#[cfg(feature = "alloc")]
	{
		assert_eq!(s0,                  s6);
		assert_ne!(s0,                  s7);
		assert_eq!(s0,                  s8);
		assert_ne!(s0,                  s9);
		assert_eq!(s0,                  s10);
		assert_ne!(s0,                  s11);

		assert_ne!(s1,                  s6);
		assert_eq!(s1,                  s7);
		assert_ne!(s1,                  s8);
		assert_eq!(s1,                  s9);
		assert_ne!(s1,                  s10);
		assert_eq!(s1,                  s11);

		assert_eq!(s2,                  s6);
		assert_ne!(s2,                  s7);
		assert_eq!(s2,                  s8);
		assert_ne!(s2,                  s9);
		assert_eq!(s2,                  s10);
		assert_ne!(s2,                  s11);

		assert_ne!(s3,                  s6);
		assert_eq!(s3,                  s7);
		assert_ne!(s3,                  s8);
		assert_eq!(s3,                  s9);
		assert_ne!(s3,                  s10);
		assert_eq!(s3,                  s11);

		assert_eq!(s4,                  s6);
		assert_ne!(s4,                  s7);
		assert_eq!(s4,                  s8);
		assert_ne!(s4,                  s9);
		assert_eq!(s4,                  s10);
		assert_ne!(s4,                  s11);

		assert_ne!(s5,                  s6);
		assert_eq!(s5,                  s7);
		assert_ne!(s5,                  s8);
		assert_eq!(s5,                  s9);
		assert_ne!(s5,                  s10);
		assert_eq!(s5,                  s11);

		assert_eq!(s6, s0);
		assert_ne!(s6, s1);
		assert_eq!(s6, s2);
		assert_ne!(s6, s3);
		assert_eq!(s6, s4);
		assert_ne!(s6, s5);
		assert_eq!(s6, s6);
		assert_ne!(s6, s7);
		assert_eq!(s6, s8);
		assert_ne!(s6, s9);
		assert_eq!(s6, s10);
		assert_ne!(s6, s11);

		assert_ne!(s7, s0);
		assert_eq!(s7, s1);
		assert_ne!(s7, s2);
		assert_eq!(s7, s3);
		assert_ne!(s7, s4);
		assert_eq!(s7, s5);
		assert_ne!(s7, s6);
		assert_eq!(s7, s7);
		assert_ne!(s7, s8);
		assert_eq!(s7, s9);
		assert_ne!(s7, s10);
		assert_eq!(s7, s11);

		assert_eq!(s8, s0);
		assert_ne!(s8, s1);
		assert_eq!(s8, s2);
		assert_ne!(s8, s3);
		assert_eq!(s8, s4);
		assert_ne!(s8, s5);
		assert_eq!(s8, s6);
		assert_ne!(s8, s7);
		assert_eq!(s8, s8);
		assert_ne!(s8, s9);
		assert_eq!(s8, s10);
		assert_ne!(s8, s11);

		assert_ne!(s9, s0);
		assert_eq!(s9, s1);
		assert_ne!(s9, s2);
		assert_eq!(s9, s3);
		assert_ne!(s9, s4);
		assert_eq!(s9, s5);
		assert_ne!(s9, s6);
		assert_eq!(s9, s7);
		assert_ne!(s9, s8);
		assert_eq!(s9, s9);
		assert_ne!(s9, s10);
		assert_eq!(s9, s11);

		assert_eq!(s10, s0);
		assert_ne!(s10, s1);
		assert_eq!(s10, s2);
		assert_ne!(s10, s3);
		assert_eq!(s10, s4);
		assert_ne!(s10, s5);
		assert_eq!(s10, s6);
		assert_ne!(s10, s7);
		assert_eq!(s10, s8);
		assert_ne!(s10, s9);
		assert_eq!(s10, s10);
		assert_ne!(s10, s11);

		assert_ne!(s11, s0);
		assert_eq!(s11, s1);
		assert_ne!(s11, s2);
		assert_eq!(s11, s3);
		assert_ne!(s11, s4);
		assert_eq!(s11, s5);
		assert_ne!(s11, s6);
		assert_eq!(s11, s7);
		assert_ne!(s11, s8);
		assert_eq!(s11, s9);
		assert_ne!(s11, s10);
		assert_eq!(s11, s11);
	}
}

#[test]
fn test_n_string_try_push() {
	let mut s = NString::<64>::new();

	assert_eq!(s, "");

	s.try_push('K').unwrap();
	assert_eq!(s, "K");

	s.try_push('O').unwrap();
	assert_eq!(s, "KO");

	s.try_push('N').unwrap();
	assert_eq!(s, "KON");

	s.try_push_str("NICHI").unwrap();
	assert_eq!(s, "KONNICHI");

	s.try_push_str(" WA").unwrap();
	assert_eq!(s, "KONNICHI WA");
}
