public async Task ReturnsAndCachesCompiledResultIfCacheMisses()
            {
                // Arrange
                var compiled = new Mock <Type>();
                TestableDefaultCompilationManager cm = CreateManager();
                TestFile file     = TestData.CreateDummyFile();
                var      compiler = new Mock <ICompiler>();

                cm.Compilers.Add(compiler.Object);
                cm.MockContentIdentifier
                .Setup(i => i.GenerateContentId(file)).Returns("Foo");
                compiler.Setup(c => c.CanCompile(file)).Returns(true);
                compiler.Setup(c => c.Compile(file)).Returns(Task.FromResult(CompilationResult.Successful(It.IsAny <string>(), compiled.Object, new[]
                {
                    new CompilationMessage(MessageLevel.Info, "Foo")
                })));

                // Act
                CompilationResult result = await cm.Compile(file, NullTrace.Instance);

                // Assert
                Assert.True(result.Success);
                Assert.False(result.SatisfiedFromCache);
                Assert.Equal("Foo", result.Messages.Single().Message);
                Assert.Same(compiled.Object, result.GetCompiledType());

                Type cached;

                Assert.True(cm.Cache["Foo"].TryGetTarget(out cached));
                Assert.Same(compiled.Object, cached);
            }
            public async Task ReturnsFailedResultIfNoCompilersRegistered()
            {
                // Arrange
                var compiled = new Mock <Type>();
                TestableDefaultCompilationManager cm = CreateManager();
                TestFile file = TestData.CreateDummyFile();

                cm.MockContentIdentifier
                .Setup(i => i.GenerateContentId(file)).Returns("Foo");

                // Act
                CompilationResult result = await cm.Compile(file, NullTrace.Instance);

                // Assert
                Assert.False(result.Success);
                Assert.Equal(
                    Resources.DefaultCompilationManager_CannotFindCompiler,
                    result.Messages.Single().Message);
            }
            public async Task ReturnsCacheIfHitAndReferenceValid()
            {
                // Arrange
                var cached = new Mock <Type>();
                TestableDefaultCompilationManager cm = CreateManager();
                TestFile file = TestData.CreateDummyFile();

                cm.Cache["Foo"] = new WeakReference <Type>(cached.Object);
                cm.MockContentIdentifier
                .Setup(i => i.GenerateContentId(file)).Returns("Foo");

                // Act
                CompilationResult result = await cm.Compile(file, NullTrace.Instance);

                // Assert
                Assert.True(result.Success);
                Assert.True(result.SatisfiedFromCache);
                Assert.Equal(0, result.Messages.Count);
                Assert.Same(cached.Object, result.GetCompiledType());
            }
            public void ReturnsAndCachesCompiledResultIfCachedValueHasBeenCollected()
            {
                // Arrange
                var compiled = new Mock <Type>();
                TestableDefaultCompilationManager cm = CreateManager();
                TestFile file     = TestData.CreateDummyFile();
                var      compiler = new Mock <ICompiler>();

                cm.Compilers.Add(compiler.Object);
                cm.MockContentIdentifier
                .Setup(i => i.GenerateContentId(file)).Returns("Foo");
                compiler.Setup(c => c.CanCompile(file)).Returns(true);
                compiler.Setup(c => c.Compile(file)).Returns(Task.FromResult(CompilationResult.Successful(It.IsAny <string>(), compiled.Object, new[]
                {
                    new CompilationMessage(MessageLevel.Info, "Foo")
                })));

                // Add a cache entry, but collect it.
                cm.Cache["Foo"] = new WeakReference <Type>(new FakeType());
                GC.Collect();

                // Act
                // Using ".Result" because making this Async causes a reference to the cached type to be held.
                CompilationResult result = cm.Compile(file, NullTrace.Instance).Result;

                // Assert
                Assert.True(result.Success);
                Assert.False(result.SatisfiedFromCache);
                Assert.Equal("Foo", result.Messages.Single().Message);
                Assert.Same(compiled.Object, result.GetCompiledType());

                Type cached;

                Assert.True(cm.Cache["Foo"].TryGetTarget(out cached));
                Assert.Same(compiled.Object, cached);
            }