// ---------------------------------------------------------------------------
// BT.Framework.Tests
// ValidationExTests.cs — ValidationEx 가드 단위 테스트
// ---------------------------------------------------------------------------
using System;
using System.Collections.Generic;
using NUnit.Framework;
using BurningTimes.Core.Util;

namespace BurningTimes.Tests.Core.Util
{
    public class ValidationExTests
    {
        [Test]
        public void NotNull_NonNull_ReturnsValue()
        {
            var obj = new object();
            Assert.AreSame(obj, ValidationEx.NotNull(obj, "x"));
        }

        [Test]
        public void NotNull_Null_Throws()
        {
            Assert.Throws<ArgumentNullException>(() => ValidationEx.NotNull<object>(null, "x"));
        }

        [Test]
        public void NotNullOrEmpty_String_ThrowsForEmpty()
        {
            Assert.Throws<ArgumentException>(() => ValidationEx.NotNullOrEmpty("", "x"));
            Assert.Throws<ArgumentException>(() => ValidationEx.NotNullOrEmpty((string)null, "x"));
            Assert.That(ValidationEx.NotNullOrEmpty("abc", "x"), Is.EqualTo("abc"));
        }

        [Test]
        public void NotNullOrWhiteSpace_ThrowsForWhitespace()
        {
            Assert.Throws<ArgumentException>(() => ValidationEx.NotNullOrWhiteSpace("   ", "x"));
            Assert.That(ValidationEx.NotNullOrWhiteSpace("abc", "x"), Is.EqualTo("abc"));
        }

        [Test]
        public void NotNullOrEmpty_Collection_ThrowsForEmpty()
        {
            var empty = new List<int>();
            Assert.Throws<ArgumentException>(() => ValidationEx.NotNullOrEmpty(empty, "x"));

            var nonEmpty = new List<int> { 1 };
            Assert.AreSame(nonEmpty, ValidationEx.NotNullOrEmpty(nonEmpty, "x"));
        }

        [Test]
        public void InRange_Int_BoundsChecked()
        {
            Assert.That(ValidationEx.InRange(5, 0, 10, "x"), Is.EqualTo(5));
            Assert.That(ValidationEx.InRange(0, 0, 10, "x"), Is.EqualTo(0));
            Assert.That(ValidationEx.InRange(10, 0, 10, "x"), Is.EqualTo(10));
            Assert.Throws<ArgumentOutOfRangeException>(() => ValidationEx.InRange(-1, 0, 10, "x"));
            Assert.Throws<ArgumentOutOfRangeException>(() => ValidationEx.InRange(11, 0, 10, "x"));
        }

        [Test]
        public void Positive_ThrowsForZeroAndNegative()
        {
            Assert.That(ValidationEx.Positive(1, "x"), Is.EqualTo(1));
            Assert.Throws<ArgumentOutOfRangeException>(() => ValidationEx.Positive(0, "x"));
            Assert.Throws<ArgumentOutOfRangeException>(() => ValidationEx.Positive(-1, "x"));
        }

        [Test]
        public void NonNegative_AllowsZero()
        {
            Assert.That(ValidationEx.NonNegative(0, "x"), Is.EqualTo(0));
            Assert.That(ValidationEx.NonNegative(1, "x"), Is.EqualTo(1));
            Assert.Throws<ArgumentOutOfRangeException>(() => ValidationEx.NonNegative(-1, "x"));
        }

        [Test]
        public void State_ThrowsInvalidOperationOnFalse()
        {
            Assert.Throws<InvalidOperationException>(() => ValidationEx.State(false, "bad"));
            Assert.DoesNotThrow(() => ValidationEx.State(true, "ok"));
        }
    }
}
