static async Task AddAssemblyReference(MonoDevelopWorkspace ws, DotNetProject from, DotNetProject to, string name) { var manager = ws.MetadataReferenceManager; var assemblies = await from.GetReferencedAssemblies(IdeApp.Workspace?.ActiveConfiguration ?? ConfigurationSelector.Default); var messagingAsm = assemblies.Single(x => x.Metadata.GetValue <string> ("Filename") == name); var metadataReference = manager.GetOrCreateMetadataReference(messagingAsm.FilePath, MetadataReferenceProperties.Assembly); await FileWatcherService.Update(); var roslynProj = ws.GetProjectId(to); var oldRefs = ws.CurrentSolution.GetProject(roslynProj).MetadataReferences; var newRefs = oldRefs.ToImmutableArray().Add(metadataReference.CurrentSnapshot); var newSolution = ws.CurrentSolution.WithProjectMetadataReferences(roslynProj, newRefs); Assert.IsTrue(ws.TryApplyChanges(newSolution)); await ws.ProjectSaveTask; var reference = to.References.Single(x => x.Include == name); Assert.IsTrue(reference.HintPath.IsNull); Assert.AreEqual(ReferenceType.Package, reference.ReferenceType); }
public async Task ReferenceCacheSnapshotUpdates() { string solFile = Util.GetSampleProject("console-project", "ConsoleProject.sln"); var tempPath = Path.GetFullPath(Path.GetTempFileName()); var oldAsm = typeof(MonoDevelopMetadataReferenceManagerTests).Assembly.Location; File.Copy(oldAsm, tempPath, true); try { using (var sol = (MonoDevelop.Projects.Solution) await Services.ProjectService.ReadWorkspaceItem(Util.GetMonitor(), solFile)) using (var ws = await TypeSystemServiceTestExtensions.LoadSolution(sol)) { await FileWatcherService.Add(sol); var manager = ws.MetadataReferenceManager; var item = manager.GetOrCreateMetadataReference(tempPath, MetadataReferenceProperties.Assembly); Assert.IsNotNull(item); await FileWatcherService.Update(); var initialId = item.CurrentSnapshot.GetMetadataId(); var taskForNewAsm = WaitForSnapshotChange(item); // Replace the assembly with another one. var newAsm = typeof(MonoDevelopMetadataReference).Assembly.Location; File.Copy(newAsm, tempPath, true); var argsForNewAsm = await taskForNewAsm; Assert.AreSame(item.CurrentSnapshot, argsForNewAsm.OldSnapshot); Assert.AreNotSame(argsForNewAsm.OldSnapshot, argsForNewAsm.NewSnapshot.Value); // item.CurrentSnapshot is now updated Assert.AreNotEqual(initialId, item.CurrentSnapshot.GetMetadataId()); var taskForOldAsm = WaitForSnapshotChange(item); File.Copy(newAsm, tempPath, true); var argsForOldAsm = await taskForOldAsm; Assert.AreSame(item.CurrentSnapshot, argsForOldAsm.OldSnapshot); Assert.AreNotSame(argsForNewAsm.OldSnapshot, argsForNewAsm.NewSnapshot.Value); // Even though the old assembly was put back, it has a new id this time. Assert.AreNotEqual(initialId, item.CurrentSnapshot.GetMetadataId()); } await FileWatcherService.Update(); // At this point, the metadata reference should be disposed. // Check to see if file updates will trigger a file service noification var tcsShouldTimeout = new TaskCompletionSource <bool> (); var ctsFail = new CancellationTokenSource(); ctsFail.Token.Register(() => tcsShouldTimeout.TrySetResult(true)); Core.FileService.FileChanged += (sender, args) => { foreach (var file in args) { if (file.FileName == tempPath) { tcsShouldTimeout.TrySetResult(false); } } }; ctsFail.CancelAfter(1000 * 5); File.WriteAllText(tempPath, ""); Assert.AreEqual(true, await tcsShouldTimeout.Task); } finally { File.Delete(tempPath); } }