Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 32 additions & 11 deletions EasyAssertions/SourceExpressions/SourceExpressionProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ class SourceExpressionProvider : ITestExpressionProvider
List<AssertionFrame> stack = new();
int currentStackIndex;
int lastStackIndex;
readonly object lockObject = new {};

static readonly AsyncLocal<SourceExpressionProvider> LocalInstance = new();
public static SourceExpressionProvider Current => LocalInstance.Value ??= new SourceExpressionProvider();
Expand All @@ -21,16 +22,19 @@ public void InvokeAssertion(Expression<Action> callAssertionMethod, string actua

void TrackAssertion(Action<IAssertionContext> assert, AssertionCall assertion, string actualSuffix, string expectedSuffix)
{
try
lock (lockObject)
{
EnterAssertion(assertion, actualSuffix, expectedSuffix);
assert(new AssertionContext());
ExitAssertion(true);
}
catch
{
ExitAssertion(false);
throw;
try
{
EnterAssertion(assertion, actualSuffix, expectedSuffix);
assert(new AssertionContext());
ExitAssertion(true);
}
catch
{
ExitAssertion(false);
throw;
}
}
}

Expand Down Expand Up @@ -63,8 +67,17 @@ void ExitAssertion(bool success)
lastStackIndex--;
}

public string GetActualExpression() => NormalizeIndentation(LastAssertionFrame?.GetActualExpression() ?? string.Empty);
public string GetExpectedExpression() => NormalizeIndentation(LastAssertionFrame?.GetExpectedExpression() ?? string.Empty);
public string GetActualExpression()
{
lock (lockObject)
return NormalizeIndentation(LastAssertionFrame?.GetActualExpression() ?? string.Empty);
}

public string GetExpectedExpression()
{
lock (lockObject)
return NormalizeIndentation(LastAssertionFrame?.GetExpectedExpression() ?? string.Empty);
}

static string NormalizeIndentation(string input)
{
Expand All @@ -86,4 +99,12 @@ static string NormalizeIndentation(string input)

AssertionFrame? CurrentAssertionFrame => stack.ElementAtOrDefault(currentStackIndex);
AssertionFrame? LastAssertionFrame => stack.ElementAtOrDefault(lastStackIndex);
internal int CurrentStackIndex
{
get
{
lock(lockObject)
return currentStackIndex;
}
}
}
20 changes: 20 additions & 0 deletions UnitTests/SourceExpressionProviderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,26 @@ public void ExpectedExpression_PassedThroughIndexedUserAssertion()
Assert.AreEqual($"{nameof(expectedExpression)}[{expectedIndex}]", sut.GetExpectedExpression());
}

[Test]
public void MultiThreads_ShouldNotMessUpStack()
{
RunTasksParallel(200, TimeSpan.FromSeconds(30), InnerAssertionTask);
void InnerAssertionTask()
{
0.ShouldBe(0);
Assert.AreEqual(0, sut.CurrentStackIndex);
}
void RunTasksParallel(int count, TimeSpan maxRunTime, Action action)
{
Task[] tasks = Enumerable.Range(0, count)
.Select(i => Task.Factory.StartNew(action))
.ToArray();

Task.WaitAll(tasks, maxRunTime).ShouldBe(true);
Assert.AreEqual(0, sut.CurrentStackIndex);
}
}

class TestClass
{
public readonly int Value;
Expand Down