|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis.Shared.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.UnitTests
{
public class ExtensionOrdererTests
{
private class Extension { }
[Fact]
public void TestNoCycle1()
{
var a = CreateExtension(name: "a", before: new[] { "b" });
var b = CreateExtension(name: "b", before: new[] { "c" });
var c = CreateExtension(name: "c", before: new[] { "d" });
var d = CreateExtension(name: "d", before: new[] { "e" });
var e = CreateExtension(name: "e");
var extensions = new List<Lazy<Extension, OrderableMetadata>>() { d, b, a, c, e };
// ExtensionOrderer.TestAccessor.CheckForCycles() will throw ArgumentException if cycle is detected.
ExtensionOrderer.TestAccessor.CheckForCycles(extensions);
var order = ExtensionOrderer.Order(extensions);
VerifyOrder("abcde", order);
}
[Fact]
public void TestNoCycle2()
{
var a = CreateExtension(name: "a", after: new[] { "b" });
var b = CreateExtension(name: "b", after: new[] { "c" });
var c = CreateExtension(name: "c", after: new[] { "d" });
var d = CreateExtension(name: "d", after: new[] { "e" });
var e = CreateExtension(name: "e");
var extensions = new List<Lazy<Extension, OrderableMetadata>>() { d, b, a, c, e };
// ExtensionOrderer.TestAccessor.CheckForCycles() will throw ArgumentException if cycle is detected.
ExtensionOrderer.TestAccessor.CheckForCycles(extensions);
var order = ExtensionOrderer.Order(extensions);
VerifyOrder("edcba", order);
}
[Fact]
public void TestNoCycle3()
{
var a = CreateExtension(name: "a", before: new[] { "b", "c", "d", "e" });
var b = CreateExtension(name: "b", before: new[] { "c", "d", "e" }, after: new[] { "a" });
var c = CreateExtension(name: "c", before: new[] { "d", "e" }, after: new[] { "b", "a" });
var d = CreateExtension(name: "d", before: new[] { "e" }, after: new[] { "c", "b", "a" });
var e = CreateExtension(name: "e", after: new[] { "d", "c", "b", "a" });
var extensions = new List<Lazy<Extension, OrderableMetadata>>() { d, b, a, c, e };
// ExtensionOrderer.TestAccessor.CheckForCycles() will throw ArgumentException if cycle is detected.
ExtensionOrderer.TestAccessor.CheckForCycles(extensions);
var order = ExtensionOrderer.Order(extensions);
VerifyOrder("abcde", order);
}
[Fact]
public void TestCycle1()
{
var a = CreateExtension(name: "a", before: new[] { "b" });
var b = CreateExtension(name: "b", before: new[] { "c" });
var c = CreateExtension(name: "c", before: new[] { "d" });
var d = CreateExtension(name: "d", before: new[] { "e" });
var e = CreateExtension(name: "e", before: new[] { "a" });
var extensions = new List<Lazy<Extension, OrderableMetadata>>() { a, b, c, d, e };
// ExtensionOrderer.TestAccessor.CheckForCycles() will throw ArgumentException when cycle is detected.
Assert.Throws<ArgumentException>(() => ExtensionOrderer.TestAccessor.CheckForCycles(extensions));
var order = ExtensionOrderer.Order(extensions);
VerifyOrder("bcdea", order);
}
[Fact]
public void TestCycle2()
{
var a = CreateExtension(name: "a", after: new[] { "b" });
var b = CreateExtension(name: "b", after: new[] { "c" });
var c = CreateExtension(name: "c", after: new[] { "d" });
var d = CreateExtension(name: "d", after: new[] { "e" });
var e = CreateExtension(name: "e", after: new[] { "a" });
var extensions = new List<Lazy<Extension, OrderableMetadata>>() { a, b, c, d, e };
// ExtensionOrderer.TestAccessor.CheckForCycles() will throw ArgumentException when cycle is detected.
Assert.Throws<ArgumentException>(() => ExtensionOrderer.TestAccessor.CheckForCycles(extensions));
var order = ExtensionOrderer.Order(extensions);
VerifyOrder("edcba", order);
}
[Fact]
public void TestCycle3()
{
var a = CreateExtension(name: "a");
var b = CreateExtension(name: "b", before: new[] { "a" }, after: new[] { "a" });
var c = CreateExtension(name: "c");
var extensions = new List<Lazy<Extension, OrderableMetadata>>() { a, b, c };
// ExtensionOrderer.TestAccessor.CheckForCycles() will throw ArgumentException when cycle is detected.
Assert.Throws<ArgumentException>(() => ExtensionOrderer.TestAccessor.CheckForCycles(extensions));
var order = ExtensionOrderer.Order(extensions);
VerifyOrder("bac", order);
}
[Fact]
public void TestCycle4()
{
var a = CreateExtension(name: "a");
var b = CreateExtension(name: "b", before: new[] { "b" }, after: new[] { "b" });
var c = CreateExtension(name: "c");
var extensions = new List<Lazy<Extension, OrderableMetadata>>() { a, b, c };
// ExtensionOrderer.TestAccessor.CheckForCycles() will throw ArgumentException when cycle is detected.
Assert.Throws<ArgumentException>(() => ExtensionOrderer.TestAccessor.CheckForCycles(extensions));
var order = ExtensionOrderer.Order(extensions);
VerifyOrder("abc", order);
}
[Fact]
public void TestCycle5()
{
var a = CreateExtension(name: "a", before: new[] { "b" });
var b = CreateExtension(name: "b", before: new[] { "c" });
var c = CreateExtension(name: "c", before: new[] { "d" });
var d = CreateExtension(name: "d", before: new[] { "e" });
var e = CreateExtension(name: "e", before: new[] { "c" });
var f = CreateExtension(name: "f", before: new[] { "g" });
var g = CreateExtension(name: "g");
var extensions = new List<Lazy<Extension, OrderableMetadata>>() { a, b, c, d, e, f, g };
// ExtensionOrderer.TestAccessor.CheckForCycles() will throw ArgumentException when cycle is detected.
Assert.Throws<ArgumentException>(() => ExtensionOrderer.TestAccessor.CheckForCycles(extensions));
var order = ExtensionOrderer.Order(extensions);
VerifyOrder("abdecfg", order);
}
[Fact]
public void TestCycle6()
{
var a = CreateExtension(name: "a", before: new[] { "b" });
var b = CreateExtension(name: "b", before: new[] { "c" });
var c = CreateExtension(name: "c", before: new[] { "d" });
var d = CreateExtension(name: "d", before: new[] { "e" });
var e = CreateExtension(name: "e", before: new[] { "a" });
var f = CreateExtension(name: "f", before: new[] { "g" });
var g = CreateExtension(name: "g");
var extensions = new List<Lazy<Extension, OrderableMetadata>>() { a, b, c, d, e, f, g };
// ExtensionOrderer.TestAccessor.CheckForCycles() will throw ArgumentException when cycle is detected.
Assert.Throws<ArgumentException>(() => ExtensionOrderer.TestAccessor.CheckForCycles(extensions));
var order = ExtensionOrderer.Order(extensions);
VerifyOrder("bcdeafg", order);
}
[Fact]
public void TestCycle7()
{
var a = CreateExtension(name: "a", before: new[] { "b" });
var b = CreateExtension(name: "b", before: new[] { "c" });
var c = CreateExtension(name: "c", before: new[] { "a" });
var d = CreateExtension(name: "d", before: new[] { "e" });
var e = CreateExtension(name: "e", before: new[] { "f" });
var f = CreateExtension(name: "f", before: new[] { "d" });
var extensions = new List<Lazy<Extension, OrderableMetadata>>() { a, b, c, d, e, f };
// ExtensionOrderer.TestAccessor.CheckForCycles() will throw ArgumentException when cycle is detected.
Assert.Throws<ArgumentException>(() => ExtensionOrderer.TestAccessor.CheckForCycles(extensions));
var order = ExtensionOrderer.Order(extensions);
VerifyOrder("bcaefd", order);
}
[Fact]
public void TestCycle8()
{
var a = CreateExtension(name: "a", before: new[] { "b" });
var b = CreateExtension(name: "b", before: new[] { "c" });
var c = CreateExtension(name: "c", before: new[] { "d" });
var d = CreateExtension(name: "d", before: new[] { "e", "c" });
var e = CreateExtension(name: "e", before: new[] { "f" });
var f = CreateExtension(name: "f", before: new[] { "a" });
var extensions = new List<Lazy<Extension, OrderableMetadata>>() { a, b, c, d, e, f };
// ExtensionOrderer.TestAccessor.CheckForCycles() will throw ArgumentException when cycle is detected.
Assert.Throws<ArgumentException>(() => ExtensionOrderer.TestAccessor.CheckForCycles(extensions));
var order = ExtensionOrderer.Order(extensions);
VerifyOrder("bcdefa", order);
}
#region Helpers
private static Lazy<Extension, OrderableMetadata> CreateExtension(string? name = null, IEnumerable<string>? before = null, IEnumerable<string>? after = null)
=> new Lazy<Extension, OrderableMetadata>(new OrderableMetadata(name, before: before, after: after));
private static IEnumerable<string?> GetNames(IEnumerable<Lazy<Extension, OrderableMetadata>> actual)
=> actual.Select(i => i.Metadata.Name);
private static void VerifyOrder(string expected, IEnumerable<Lazy<Extension, OrderableMetadata>> actual)
{
var actualOrder = string.Join(string.Empty, GetNames(actual));
Assert.Equal(expected, actualOrder);
}
#endregion
}
}
|