public void GetInheritedImmutableExceptions_WhenImmutableInheritedTypes_ReturnsEachInheritedTypesExceptions() { TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(@" [Immutable( Except = Except.ItHasntBeenLookedAt )] public interface IFoo { } [Immutable( Except = Except.ItsUgly | Except.ItsSketchy )] public class FooBase { } public sealed class Foo : FooBase, IFoo { } "); ImmutableDictionary <ISymbol, ImmutableHashSet <string> > inheritedExceptions = ty.Symbol.GetInheritedImmutableExceptions(); Assert.That(inheritedExceptions, Has.Count.EqualTo(2)); ISymbol ifooSymbol = inheritedExceptions.Keys.FirstOrDefault(s => s.Name == "IFoo"); Assert.That(ifooSymbol, Is.Not.Null); Assert.That(inheritedExceptions[ifooSymbol], Is.EquivalentTo(new[] { "ItHasntBeenLookedAt" })); ISymbol fooBaseSymbol = inheritedExceptions.Keys.FirstOrDefault(s => s.Name == "FooBase"); Assert.That(fooBaseSymbol, Is.Not.Null); Assert.That(inheritedExceptions[fooBaseSymbol], Is.EquivalentTo(new[] { "ItsUgly", "ItsSketchy" })); }
public void When_Name_is_explicitly_set_then_adding_aliases_does_not_change_it() { var symbol = new TestSymbol(new[] { "-a", "--zzzzzz" }, ""); symbol.Name = "bbb"; symbol.Name.Should().Be("bbb"); }
public void GetAllImmutableExceptions_WhenNotImmutableAndNoInheritedTypes_ThrowsException() { TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(@" public sealed class Foo { } "); Assert.That(() => ty.Symbol.GetAllImmutableExceptions(), Throws.Exception); }
public void TryGetDirectImmutableExceptions_WhenTypeDoesNotHaveImmutableAttribute_ReturnsFalse() { TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(@"public class Foo { }"); ImmutableHashSet <string> exceptions; bool result = ty.Symbol.TryGetDirectImmutableExceptions(out exceptions); Assert.That(result, Is.False); }
public void Name_cannot_be_prefixed(string name) { var symbol = new TestSymbol(new[] { "-a" }, ""); symbol.Invoking(s => s.Name = name) .Should() .Throw <ArgumentException>() .WithMessage($"Property {typeof(TestSymbol).Name}.Name cannot have a prefix."); }
public void Symbol_retains_argument_name_when_it_is_provided() { var symbol = new TestSymbol(new[] { "-alias" }, "", new Argument() { Name = "arg", Arity = ArgumentArity.ZeroOrOne }); symbol.Argument.Name.Should().Be("arg"); }
public void Symbol_defaults_argument_to_alias_name_when_it_is_not_provided() { var symbol = new TestSymbol(new[] { "-alias" }, "", new Argument() { Arity = ArgumentArity.ZeroOrOne }); symbol.Argument.Name.Should().Be("ALIAS"); }
public void Symbol_does_not_default_argument_name_when_arity_is_zero() { var symbol = new TestSymbol(new[] { "-alias" }, "", new Argument()); symbol.Argument.Name.Should().BeNull(); }
public void GetInheritedImmutableExceptions_WhenNoInheritedTypes_ReturnsEmptyDict() { TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(@" public class Foo { } "); ImmutableDictionary <ISymbol, ImmutableHashSet <string> > inheritedExceptions = ty.Symbol.GetInheritedImmutableExceptions(); Assert.That(inheritedExceptions, Is.Empty); }
public void InspectType_TypeHasNoMembers_NoUnauditedReasons() { const string source = AnnotationsPreamble + @" sealed class Foo {} "; TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(source); AssertUnauditedReasonsResult(ty); }
public void TryGetUnauditedReason_WhenSymbolDoesNotHaveUnauditedAttribute_ThrowsException() { TestSymbol <IFieldSymbol> field = CompileAndGetFooField(@" public class Foo { public string foo; } "); Assert.That(() => BecauseHelpers.GetUnauditedReason(field.Symbol), Throws.Exception); }
private void AssertUnauditedReasonsResult(TestSymbol <ITypeSymbol> ty, params string[] expectedUnauditedReasons) { var inspector = new MutabilityInspector(ty.Compilation); var expected = MutabilityInspectionResult.NotMutable( ImmutableHashSet.Create(expectedUnauditedReasons) ); var actual = inspector.InspectType(ty.Symbol, MutabilityInspectionFlags.IgnoreImmutabilityAttribute); AssertResultsAreEqual(expected, actual); }
public void InspectType_TypeHasOneUnauditedMember_ReturnsUnauditedReasonAsSeenUnauditedReasons() { const string source = AnnotationsPreamble + @" sealed class Foo { [Mutability.Unaudited( Because.ItsSketchy )] public Func<string> Bar { get; } } "; TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(source); AssertUnauditedReasonsResult(ty, "ItsSketchy"); }
public void TryGetDirectImmutableExceptions_WhenNoSpecifiedExceptions_ReturnsDefaultReasons() { TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(@" [Immutable] public class Foo { } "); ImmutableHashSet <string> immutabilityExceptions; bool result = ty.Symbol.TryGetDirectImmutableExceptions(out immutabilityExceptions); Assert.That(result, Is.True); Assert.That(immutabilityExceptions, Is.EquivalentTo(ImmutableHelpers.DefaultImmutabilityExceptions)); }
public void TryGetUnauditedReason_WhenSymbolIsAnnotatedWithUnauditedReasonAndHasBucket_ReturnsCorrectReason(string expectedReason) { TestSymbol <IFieldSymbol> field = CompileAndGetFooField($@" public class Foo {{ [Mutability.Unaudited( Because.{expectedReason}, UndiffBucket.Core )] public string foo; }} "); string reason = BecauseHelpers.GetUnauditedReason(field.Symbol); Assert.That(reason, Is.EqualTo(expectedReason)); }
public void TryGetDirectImmutableExceptions_WhenSpecifiedNoneReasons_ReturnsEmptySet() { TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(@" [Immutable( Except = Except.None )] public class Foo { } "); ImmutableHashSet <string> immutabilityExceptions; bool result = ty.Symbol.TryGetDirectImmutableExceptions(out immutabilityExceptions); Assert.That(result, Is.True); Assert.That(immutabilityExceptions, Is.Empty); }
public void GetAllImmutableExceptions_WhenImmutableAndNoImmutableInheritedTypes_ReturnsDefinedExceptions() { TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(@" public interface IFoo { } public class FooBase { } [Immutable( Except = Except.ItsUgly | Except.ItsSketchy )] public sealed class Foo : FooBase, IFoo { } "); ImmutableHashSet <string> allExceptions = ty.Symbol.GetAllImmutableExceptions(); Assert.That(allExceptions, Is.EquivalentTo(new[] { "ItsUgly", "ItsSketchy" })); }
public void InspectType_TypeHasImmutableMemberWithSpecifiedExceptions_ReturnsThoseExceptionsAsSeenUnauditedReasons() { const string source = AnnotationsPreamble + @" sealed class Foo { public Bar Bar { get; } } [Immutable( Except = Except.ItsUgly | Except.ItsSketchy )] sealed class Bar { } "; TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(source); AssertUnauditedReasonsResult(ty, "ItsUgly", "ItsSketchy"); }
public void InspectType_TypeHasDefaultImmutableMember_ReturnsDefaultImmutabilityExceptionsAsSeenUnauditedReasons() { const string source = AnnotationsPreamble + @" sealed class Foo { public Bar Bar { get; } } [Immutable] sealed class Bar { } "; TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(source); AssertUnauditedReasonsResult(ty, ImmutableHelpers.DefaultImmutabilityExceptions.ToArray()); }
public void InspectType_TypeHasUniqueNestedUnauditedMembers_DoesNotReturnNestedUnauditedReasonsAsSeenUnauditedReasons() { const string source = AnnotationsPreamble + @" sealed class Foo { [Mutability.Unaudited( Because.ItsSketchy )] public Bar XYZ { get; } } sealed class Bar { [Mutability.Unaudited( Because.ItsUgly )] public Func<string> Baz { get; } }"; TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(source); AssertUnauditedReasonsResult(ty, "ItsSketchy"); }
public void TryGetDirectImmutableExceptions_WhenSpecifiedExceptions_ReturnsSpecifiedExceptions() { TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(@" [Immutable( Except = Except.ItsUgly | Except.WeNeedToMakeTheAnalyzerConsiderThisSafe | Except.ItsSketchy )] public class Foo { } "); ImmutableHashSet <string> immutabilityExceptions; bool result = ty.Symbol.TryGetDirectImmutableExceptions(out immutabilityExceptions); Assert.That(result, Is.True); Assert.That(immutabilityExceptions, Is.EquivalentTo(new[] { "WeNeedToMakeTheAnalyzerConsiderThisSafe", "ItsUgly", "ItsSketchy" })); }
public void InspectType_TypeHasImmutableCollectionMember_ReturnsUnionOfExceptionsInCollectionTypes() { const string source = AnnotationsPreamble + @" sealed class Foo { public IReadOnlyDictionary<Bar, Baz> XYZ { get; } } [Immutable( Except = Except.ItsUgly )] sealed class Bar { } [Immutable( Except = Except.ItHasntBeenLookedAt )] sealed class Baz { } "; TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(source); AssertUnauditedReasonsResult(ty, "ItsUgly", "ItHasntBeenLookedAt"); }
public void InspectType_LambdaInitializerReferencingField_NotMutable() { const string source = AnnotationsPreamble + @" sealed class Foo { private readonly int m_int = 3; private readonly Func<int> m_func = () => { return m_int; }; } "; TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(source); var inspector = new MutabilityInspector(ty.Compilation); var result = inspector.InspectType(ty.Symbol); Assert.IsFalse(result.IsMutable); }
private static TestSymbol <IFieldSymbol> CompileAndGetFooField(string source) { source = $"namespace D2L {{ {source} }}"; source = s_preamble + source; var compilation = Compile(source); var symbol = compilation.GetSymbolsWithName( predicate: n => n == "Foo", filter: SymbolFilter.Type ).OfType <ITypeSymbol>().FirstOrDefault(); Assert.IsNotNull(symbol); Assert.AreNotEqual(TypeKind.Error, symbol.TypeKind); TestSymbol <ITypeSymbol> fooType = new TestSymbol <ITypeSymbol>(symbol, compilation); IFieldSymbol fooField = fooType.Symbol.GetMembers().OfType <IFieldSymbol>().FirstOrDefault(s => s.Name == "foo"); return(new TestSymbol <IFieldSymbol>(fooField, fooType.Compilation)); }
public void InspectType_TypeHasNonDefaultUnauditedMembersAndDefaultImmutableMember_ReturnsUnionOfDefaultExceptionsAndNonDefaultReasonAsSeenUnauditedReasons() { const string source = AnnotationsPreamble + @" sealed class Foo { [Mutability.Unaudited( Because.ItsSketchy )] public Func<string> Bar { get; } [Mutability.Unaudited( Because.SomeNewReason )] public Func<string> Baz { get; } public Bar XYZ { get; } } [Immutable] sealed class Bar { } "; TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(source); AssertUnauditedReasonsResult(ty, ImmutableHelpers.DefaultImmutabilityExceptions.Add("SomeNewReason").ToArray()); }
public void InspectType_TypeHasUnauditedMembersAndImmutableMemberWithNoExceptions_ReturnsUnauditedReasonsAsSeenUnauditedReasons() { const string source = AnnotationsPreamble + @" sealed class Foo { [Mutability.Unaudited( Because.ItsSketchy )] public Func<string> Bar { get; } [Mutability.Unaudited( Because.ItsUgly )] public Func<string> Baz { get; } public Bar XYZ { get; } } [Immutable( Except = Except.None )] sealed class Bar { } "; TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(source); AssertUnauditedReasonsResult(ty, "ItsSketchy", "ItsUgly"); }
public void GetInheritedImmutableExceptions_WhenInterfaceIndirectlyImmutable_ReturnsInheritedTypesExceptions() { TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(@" [Immutable( Except = Except.ItHasntBeenLookedAt )] public interface IFoo { } public interface IFoo2 : IFoo { } public sealed class Foo : IFoo2 { } "); ImmutableDictionary <ISymbol, ImmutableHashSet <string> > inheritedExceptions = ty.Symbol.GetInheritedImmutableExceptions(); Assert.That(inheritedExceptions, Has.Count.EqualTo(1)); ISymbol ifooSymbol = inheritedExceptions.Keys.FirstOrDefault(s => s.Name == "IFoo"); Assert.That(ifooSymbol, Is.Not.Null); Assert.That(inheritedExceptions[ifooSymbol], Is.EquivalentTo(new[] { "ItHasntBeenLookedAt" })); }