File: Intermediate\LazyContentTests.cs
Web Access
Project: src\src\Razor\src\Compiler\Microsoft.AspNetCore.Razor.Language\test\Microsoft.AspNetCore.Razor.Language.UnitTests.csproj (Microsoft.AspNetCore.Razor.Language.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System;
using System.Threading;
using Xunit;
 
namespace Microsoft.AspNetCore.Razor.Language.Intermediate;
 
public class LazyContentTests
{
    [Fact]
    public void Create_ThrowsIfFactoryIsNull()
    {
        // Arrange, Act & Assert
        Assert.Throws<ArgumentNullException>(() => LazyContent.Create("x", null!));
    }
 
    [Fact]
    public void Value_ReturnsContentFromFactory()
    {
        // Arrange
        var args = (x: 19, y: 23);
        var lazy = LazyContent.Create(args, static arg => (arg.x + arg.y).ToString());
 
        // Act
        var content = lazy.Value;
 
        // Assert
        Assert.NotNull(content);
        Assert.Equal("42", content);
    }
 
    [Fact]
    public void Value_InvokesFactoryOnlyOnce()
    {
        // Arrange
        var callCount = 0;
        var text = "test";
 
        var lazy = LazyContent.Create(text, arg =>
        {
            Interlocked.Increment(ref callCount);
            return arg;
        });
 
        // Act
        var value1 = lazy.Value;
        var value2 = lazy.Value;
 
        // Assert
        Assert.Equal(value1, value2);
        Assert.Equal(1, callCount);
    }
 
    [Fact]
    public void Value_IsThreadSafe()
    {
        const int ThreadCount = 20;
 
        // Arrange
        var callCount = 0;
 
        var lazy = LazyContent.Create("thread", arg =>
        {
            Interlocked.Increment(ref callCount);
            Thread.Sleep(10); // Simulate work
 
            return arg;
        });
 
        var threads = new Thread[ThreadCount];
        var results = new string?[ThreadCount];
 
        // Act
        for (var i = 0; i < threads.Length; i++)
        {
            var idx = i; // Capture the current index
 
            threads[i] = new Thread(() => results[idx] = lazy.Value);
            threads[i].Start();
        }
 
        foreach (var thread in threads)
        {
            thread.Join();
        }
 
        // Assert that all of the results are equal.
        for (var i = 1; i < results.Length; i++)
        {
            Assert.Equal(results[0], results[i]);
        }
 
        // Assert that the factory was called only once.
        Assert.Equal(1, callCount);
    }
}