Skip to content
Merged
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
38 changes: 38 additions & 0 deletions src/DiffEngine.Tests/DisabledTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/// <summary>
/// <see cref="DiffRunner.Disabled" /> was captured at type initialisation, so a build server or AI
/// CLI reported after that - which is when a test host reports one, having only just loaded - left
/// diff tools launching anyway.
/// </summary>
[NotInParallel]
public class DisabledTests
{
[Test]
public async Task A_build_server_detected_after_first_use_still_disables()
{
// As the module initializer left it, and as any consumer that ever set it leaves it
DiffRunner.Disabled = false;

DiffRunner.ResetDisabled();
BuildServerDetector.Detected = true;

await Assert.That(DiffRunner.Disabled).IsTrue();
}

[Test]
public async Task Setting_it_pins_it()
{
DiffRunner.ResetDisabled();
BuildServerDetector.Detected = true;

DiffRunner.Disabled = false;

await Assert.That(DiffRunner.Disabled).IsFalse();
}

/// <summary>
/// Every other test in this assembly runs with it off, which the module initializer does once.
/// </summary>
[After(Test)]
public void Restore() =>
DiffRunner.Disabled = false;
}
28 changes: 27 additions & 1 deletion src/DiffEngine/DiffRunner.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,33 @@ namespace DiffEngine;
/// </summary>
public static partial class DiffRunner
{
public static bool Disabled { get; set; } = DisabledChecker.IsDisable();
/// <summary>
/// Whether launching a diff tool is turned off, for this process or for this async context.
/// <para>
/// Read rather than captured, so that the overrides feeding it - <see cref="BuildServerDetector.Detected" />
/// and <see cref="AiCliDetector.Detected" />, both of which a test host sets after it has
/// loaded - are honoured whenever they are set. Captured once at type initialisation, they
/// were inert the moment anything had touched this class, and an AsyncLocal override could
/// never have reached a value read into a static anyway.
/// </para>
/// <para>
/// Setting it pins it, and nothing is read from the environment after that.
/// </para>
/// </summary>
public static bool Disabled
{
get => disabled ?? DisabledChecker.IsDisable();
set => disabled = value;
}

static bool? disabled;

/// <summary>
/// Forgets an explicit <see cref="Disabled" />, so it is read from the environment again. For
/// tests, which is where anything sets it and then wants the detectors back.
/// </summary>
internal static void ResetDisabled() =>
disabled = null;

public static void MaxInstancesToLaunch(int value) =>
MaxInstance.SetForAppDomain(value);
Expand Down
Loading