|
// 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.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using Castle.Core.Internal;
using Microsoft.VisualStudio.Shell.Interop;
using Roslyn.Test.Utilities;
using Roslyn.VisualStudio.IntegrationTests;
using Xunit;
namespace Roslyn.VisualStudio.NewIntegrationTests
{
public class MefCompositionTests : AbstractIntegrationTest
{
[IdeFact]
public async Task AssertNoCompositionFailures()
{
// Read the .err file that contains errors; this isn't a great way to do it but we have no
// better option at this point.
var shell = await TestServices.Shell.GetRequiredGlobalServiceAsync<SVsSettingsManager, IVsSettingsManager>(HangMitigatingCancellationToken);
Marshal.ThrowExceptionForHR(shell.GetApplicationDataFolder((uint)__VsApplicationDataFolder.ApplicationDataFolder_LocalSettings, out var applicationDataFolder));
var compositionErrorFileLines = File.ReadAllLines(Path.Combine(applicationDataFolder, @"ComponentModelCache\Microsoft.VisualStudio.Default.err"));
var compositionErrors = new List<string>();
for (var i = 0; i < compositionErrorFileLines.Length; i++)
{
var line = compositionErrorFileLines[i];
if (line.EndsWith("expected exactly 1 export matching constraints:") &&
StartsWithApplicableSymbol(line))
{
var entireError = string.Join(Environment.NewLine, compositionErrorFileLines.Skip(i).TakeWhile(s => !string.IsNullOrWhiteSpace(s)));
compositionErrors.Add(entireError);
}
}
// Ideally I'd write Assert.Empty(compositionErrors), but since the string gets truncated we'll do this instead
AssertEx.EqualOrDiff("", string.Join(Environment.NewLine, compositionErrors));
}
private static bool StartsWithApplicableSymbol(string s)
{
// ExternalAccess missing exports may mean the langauge isn't installed, or you aren't running
// on fully matched bits; rather than flag them let's keep the noise down.
if (s.StartsWith("Microsoft.CodeAnalysis.ExternalAccess"))
return false;
// Not actually our code
if (s.StartsWith("Microsoft.CodeAnalysis.Editor.TypeScript"))
return false;
return s.StartsWith("Microsoft.CodeAnalysis") ||
s.StartsWith("Microsoft.VisualStudio.LanguageServices") ||
s.StartsWith("Roslyn");
}
}
}
|