Beispiel #1
0
        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" }));
        }
Beispiel #2
0
        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");
        }
Beispiel #3
0
        public void GetAllImmutableExceptions_WhenNotImmutableAndNoInheritedTypes_ThrowsException()
        {
            TestSymbol <ITypeSymbol> ty = CompileAndGetFooType(@"
public sealed class Foo { }
");

            Assert.That(() => ty.Symbol.GetAllImmutableExceptions(), Throws.Exception);
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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");
        }
Beispiel #8
0
        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();
        }
Beispiel #9
0
        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");
        }
Beispiel #14
0
        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));
        }
Beispiel #16
0
        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);
        }
Beispiel #17
0
        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");
        }
Beispiel #21
0
        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");
        }
Beispiel #27
0
        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" }));
        }