<commit_before>﻿using NUnit.Framework;
using System;
using System.Linq;
using System.Linq.Expressions;

namespace EasyAssertions.UnitTests
{
    [TestFixture]
    public class SourceExpressionProviderTests
    {
        [Test]
        public void ResultOnSameLine()
        {
            TestClass actualExpression = new TestClass(12);
            TestClass expectedExpression = new TestClass(2);
            Assert.Throws<EasyAssertionException>(() => actualExpression.ShouldBe(expectedExpression));

            Assert.AreEqual("actualExpression", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void ResultOnPreviousLine()
        {
            TestClass actualExpression = new TestClass(12);
            TestClass expectedExpression = new TestClass(2);
            Assert.Throws<EasyAssertionException>(() => actualExpression
                .ShouldBe(expectedExpression));

            Assert.AreEqual("actualExpression", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void MultiAssertionMessage_TakesExpressionFromFirstAssertion()
        {
            TestClass actualExpression = new TestClass(12);
            TestClass expectedExpression = new TestClass(2);
            Assert.Throws<EasyAssertionException>(() =>
                actualExpression.ShouldBeA<TestClass>()
                    .And.ShouldBe(expectedExpression));

            Assert.AreEqual("actualExpression", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void ContinuedAssertion_CombinesChainedExpressions()
        {
            TestClass actualExpression = new TestClass(12);
            int expectedExpression = 2;

            Assert.Throws<EasyAssertionException>(() =>
                actualExpression.ShouldBeA<TestClass>()
                    .And.Value.ShouldBe(expectedExpression));

            Assert.AreEqual("actualExpression.Value", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void ExpressionInsideNestedAssertion_CombinesOuterAndInnerExpressions()
        {
            TestClass actualExpression = new TestClass(12);
            int expectedExpression = 2;

            Assert.Throws<EasyAssertionException>(() =>
                actualExpression.Assert(a => a.Value.ShouldBe(expectedExpression)));

            Assert.AreEqual("actualExpression.Value", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void ExpressionSecondInsideNestedAssertion_CombinesOuterAndInnerExpressions()
        {
            TestClass actualExpression = new TestClass(12);
            int expectedExpression = 2;

            Assert.Throws<EasyAssertionException>(() =>
                actualExpression.Assert(tc =>
                    {
                        tc.Value.ShouldBe(12);
                        tc.Value.ShouldBe(expectedExpression);
                    }));

            Assert.AreEqual("actualExpression.Value", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void ExpressionTwoLevelsIn_CombinesOuterMiddleAndInnerExpressions()
        {
            TestClass actualExpression = new TestClass(12);
            Assert.Throws<EasyAssertionException>(() =>
                actualExpression
                    .Assert(a => a.Value.ShouldBe(12)
                        .And(b => b.ToString().ShouldBe("2"))));

            Assert.AreEqual("actualExpression.Value.ToString()", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void ExpressionAfterNestedAssertion_CombinesChainedExpressions()
        {
            TestClass actualExpression = new TestClass(12);
            int expectedExpression = 2;

            Assert.Throws<EasyAssertionException>(() =>
                actualExpression
                    .Assert(tc => tc.ShouldBeA<TestClass>())
                    .And.Value.ShouldBe(expectedExpression));

            Assert.AreEqual("actualExpression.Value", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void ExpressionInsideIndexedAssertion_IncludesIndex()
        {
            TestClass[] actualExpression = { null, new TestClass(12) };
            int expectedExpression = 2;

            Assert.Throws<EasyAssertionException>(() =>
                actualExpression.ItemsSatisfy(
                    tc => { },
                    tc => tc.Value.ShouldBe(expectedExpression)));

            Assert.AreEqual("actualExpression[1].Value", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void ExpressionAfterIndexedAssertions_CombinesChainedExpressions()
        {
            TestClass[] actualExpression = { new TestClass(12) };
            TestClass expectedExpression = new TestClass(2);

            Assert.Throws<EasyAssertionException>(() =>
                actualExpression
                    .ItemsSatisfy(tc => { })
                    .And.Single().ShouldBe(expectedExpression));

            Assert.AreEqual("actualExpression.Single()", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void SeparateExpressionAfterIndexedAssertion()
        {
            TestClass actualExpression = new TestClass(12);
            TestClass expectedExpression = new TestClass(2);

            Assert.Throws<EasyAssertionException>(() =>
                {
                    new[] { 1 }
                        .ItemsSatisfy(i => { });

                    actualExpression
                        .ShouldBe(expectedExpression);
                });

            Assert.AreEqual("actualExpression", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void AssertionNestsAnotherAssertionInAction_TakesExpressionFromOuterAssertion()
        {
            object actualExpression = null;

            Assert.Throws<EasyAssertionException>(() => actualExpression.TestActionAssert());

            Assert.AreEqual("actualExpression", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void AssertionNestsAnotherAssertionInFunc_TakesExpressionFromOuterAssertion()
        {
            object actualExpression = null;

            Assert.Throws<EasyAssertionException>(() => actualExpression.TestFuncAssert());

            Assert.AreEqual("actualExpression", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void StackFrameHasNoSource_IsIgnored()
        {
            Expression<Action> assert = () => ObjectAssertions.ShouldBe("foo", "bar", null);    // Compiled expression has no source file

            Assert.Throws<EasyAssertionException>(() => assert.Compile()());

            Assert.AreEqual(string.Empty, SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void SameAssertionCalledTwice()
        {
            const string foo = "foo";
            for (int i = 0; i < 2; i++)
                Assert.Throws<EasyAssertionException>(() => foo.ShouldBe("bar"));

            Assert.AreEqual("foo", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        private class TestClass
        {
            public readonly int Value;<commit_msg>Disabling StackFrameHasNoSource_IsIgnored tests, which no longer works in .NET 4<commit_after>﻿using NUnit.Framework;
using System;
using System.Linq;
using System.Linq.Expressions;

namespace EasyAssertions.UnitTests
{
    [TestFixture]
    public class SourceExpressionProviderTests
    {
        [Test]
        public void ResultOnSameLine()
        {
            TestClass actualExpression = new TestClass(12);
            TestClass expectedExpression = new TestClass(2);
            Assert.Throws<EasyAssertionException>(() => actualExpression.ShouldBe(expectedExpression));

            Assert.AreEqual("actualExpression", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void ResultOnPreviousLine()
        {
            TestClass actualExpression = new TestClass(12);
            TestClass expectedExpression = new TestClass(2);
            Assert.Throws<EasyAssertionException>(() => actualExpression
                .ShouldBe(expectedExpression));

            Assert.AreEqual("actualExpression", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void MultiAssertionMessage_TakesExpressionFromFirstAssertion()
        {
            TestClass actualExpression = new TestClass(12);
            TestClass expectedExpression = new TestClass(2);
            Assert.Throws<EasyAssertionException>(() =>
                actualExpression.ShouldBeA<TestClass>()
                    .And.ShouldBe(expectedExpression));

            Assert.AreEqual("actualExpression", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void ContinuedAssertion_CombinesChainedExpressions()
        {
            TestClass actualExpression = new TestClass(12);
            int expectedExpression = 2;

            Assert.Throws<EasyAssertionException>(() =>
                actualExpression.ShouldBeA<TestClass>()
                    .And.Value.ShouldBe(expectedExpression));

            Assert.AreEqual("actualExpression.Value", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void ExpressionInsideNestedAssertion_CombinesOuterAndInnerExpressions()
        {
            TestClass actualExpression = new TestClass(12);
            int expectedExpression = 2;

            Assert.Throws<EasyAssertionException>(() =>
                actualExpression.Assert(a => a.Value.ShouldBe(expectedExpression)));

            Assert.AreEqual("actualExpression.Value", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void ExpressionSecondInsideNestedAssertion_CombinesOuterAndInnerExpressions()
        {
            TestClass actualExpression = new TestClass(12);
            int expectedExpression = 2;

            Assert.Throws<EasyAssertionException>(() =>
                actualExpression.Assert(tc =>
                    {
                        tc.Value.ShouldBe(12);
                        tc.Value.ShouldBe(expectedExpression);
                    }));

            Assert.AreEqual("actualExpression.Value", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void ExpressionTwoLevelsIn_CombinesOuterMiddleAndInnerExpressions()
        {
            TestClass actualExpression = new TestClass(12);
            Assert.Throws<EasyAssertionException>(() =>
                actualExpression
                    .Assert(a => a.Value.ShouldBe(12)
                        .And(b => b.ToString().ShouldBe("2"))));

            Assert.AreEqual("actualExpression.Value.ToString()", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void ExpressionAfterNestedAssertion_CombinesChainedExpressions()
        {
            TestClass actualExpression = new TestClass(12);
            int expectedExpression = 2;

            Assert.Throws<EasyAssertionException>(() =>
                actualExpression
                    .Assert(tc => tc.ShouldBeA<TestClass>())
                    .And.Value.ShouldBe(expectedExpression));

            Assert.AreEqual("actualExpression.Value", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void ExpressionInsideIndexedAssertion_IncludesIndex()
        {
            TestClass[] actualExpression = { null, new TestClass(12) };
            int expectedExpression = 2;

            Assert.Throws<EasyAssertionException>(() =>
                actualExpression.ItemsSatisfy(
                    tc => { },
                    tc => tc.Value.ShouldBe(expectedExpression)));

            Assert.AreEqual("actualExpression[1].Value", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void ExpressionAfterIndexedAssertions_CombinesChainedExpressions()
        {
            TestClass[] actualExpression = { new TestClass(12) };
            TestClass expectedExpression = new TestClass(2);

            Assert.Throws<EasyAssertionException>(() =>
                actualExpression
                    .ItemsSatisfy(tc => { })
                    .And.Single().ShouldBe(expectedExpression));

            Assert.AreEqual("actualExpression.Single()", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void SeparateExpressionAfterIndexedAssertion()
        {
            TestClass actualExpression = new TestClass(12);
            TestClass expectedExpression = new TestClass(2);

            Assert.Throws<EasyAssertionException>(() =>
                {
                    new[] { 1 }
                        .ItemsSatisfy(i => { });

                    actualExpression
                        .ShouldBe(expectedExpression);
                });

            Assert.AreEqual("actualExpression", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void AssertionNestsAnotherAssertionInAction_TakesExpressionFromOuterAssertion()
        {
            object actualExpression = null;

            Assert.Throws<EasyAssertionException>(() => actualExpression.TestActionAssert());

            Assert.AreEqual("actualExpression", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void AssertionNestsAnotherAssertionInFunc_TakesExpressionFromOuterAssertion()
        {
            object actualExpression = null;

            Assert.Throws<EasyAssertionException>(() => actualExpression.TestFuncAssert());

            Assert.AreEqual("actualExpression", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test, Ignore("After upgrade to .NET 4.0, compiled expression now has a source file")]
        public void StackFrameHasNoSource_IsIgnored()
        {
            Expression<Action> assert = () => ObjectAssertions.ShouldBe("foo", "bar", null);    // Compiled expression has no source file

            Assert.Throws<EasyAssertionException>(() => assert.Compile()());

            Assert.AreEqual(string.Empty, SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        [Test]
        public void SameAssertionCalledTwice()
        {
            const string foo = "foo";
            for (int i = 0; i < 2; i++)
                Assert.Throws<EasyAssertionException>(() => foo.ShouldBe("bar"));

            Assert.AreEqual("foo", SourceExpressionProvider.ForCurrentThread.GetActualExpression());
        }

        private class TestClass
        {
            public readonly int Value;
{'fraction_non_alphanumeric': 0.09278013721006208, 'fraction_numerical': 0.00555374060764456, 'mean_word_length': 2.3266681156270375, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 91, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6427476', 'n_tokens_mistral': 3705, 'n_tokens_neox': 3479, 'n_words': 562}