private EditProjectFileCommand CreateInstance(
            UnconfiguredProject unconfiguredProject = null,
            bool implementCapabilities       = true,
            IMsBuildAccessor msbuildAccessor = null,
            IFileSystem fileSystem           = null,
            ITextDocumentFactoryService textDocumentService      = null,
            IVsEditorAdaptersFactoryService editorAdapterService = null,
            IProjectThreadingService threadingService            = null,
            IVsShellUtilitiesHelper shellUtilities = null,
            IExportFactory <IMsBuildModelWatcher> watcherFactory = null
            )
        {
            UnitTestHelper.IsRunningUnitTests = true;
            var uProj        = unconfiguredProject ?? IUnconfiguredProjectFactory.Create();
            var capabilities = IProjectCapabilitiesServiceFactory.ImplementsContains(CapabilityChecker(implementCapabilities));
            var msbuild      = msbuildAccessor ?? IMsBuildAccessorFactory.Create();
            var fs           = fileSystem ?? new IFileSystemMock();
            var tds          = textDocumentService ?? ITextDocumentFactoryServiceFactory.Create();
            var eas          = editorAdapterService ?? IVsEditorAdaptersFactoryServiceFactory.Create();
            var threadServ   = threadingService ?? IProjectThreadingServiceFactory.Create();
            var shellUt      = shellUtilities ?? new TestShellUtilitiesHelper(
                (sp, path) => Tuple.Create(IVsHierarchyFactory.Create(), (uint)1, IVsPersistDocDataFactory.Create(), (uint)1),
                (sp, path, edType, logView) => IVsWindowFrameFactory.Create());
            var wFact = watcherFactory ?? IExportFactoryFactory.CreateInstance <IMsBuildModelWatcher>();

            return(new EditProjectFileCommand(uProj, capabilities, IServiceProviderFactory.Create(), msbuild, fs, tds, eas, threadServ, shellUt, wFact));
        }
        public async Task AbstractEditProjectFileCommand_NonSaveAction_DoesNotOverwriteProjectFile(FileActionTypes actionType)
        {
            var projectPath   = $"C:\\Project1\\Project1.{EditProjectFileCommand.Extension}";
            var tempDirectory = "C:\\Temp\\asdf.xyz";
            var tempProjFile  = $"{tempDirectory}\\Project1.{EditProjectFileCommand.Extension}";
            var projectXml    = @"<Project></Project>";

            var fileSystem    = new IFileSystemMock();
            var textDoc       = ITextDocumentFactory.Create();
            var frame         = IVsWindowFrameFactory.ImplementShowAndSetProperty(VSConstants.S_OK, (prop, obj) => VSConstants.S_OK);
            var exportFactory = IExportFactoryFactory.ImplementCreateValue(() => IMsBuildModelWatcherFactory.CreateInstance());

            var command = SetupScenario(projectXml, tempDirectory, tempProjFile, projectPath, fileSystem, textDoc, frame, exportFactory);
            var tree    = ProjectTreeParser.Parse(@"
Root (flags: {ProjectRoot})
");
            var nodes   = ImmutableHashSet.Create(tree);

            // Verify the frame was setup correctly
            Assert.True(await command.TryHandleCommandAsync(nodes, CommandId, true, 0, IntPtr.Zero, IntPtr.Zero));

            var args = new TextDocumentFileActionEventArgs(tempProjFile, DateTime.Now, actionType);

            Mock.Get(textDoc).Raise(t => t.FileActionOccurred += null, args);
            Assert.False(fileSystem.FileExists(projectPath));
        }
        public async Task AbstractEditProjectFileCommand_CorrectNode_CreatesWindowCorrectly()
        {
            var projectPath   = $"C:\\Project1\\Project1.{EditProjectFileCommand.Extension}";
            var tempDirectory = "C:\\Temp\\asdf.xyz";
            var tempProjFile  = $"{tempDirectory}\\Project1.{EditProjectFileCommand.Extension}";
            var projectXml    = @"<Project></Project>";
            var autoOpenSet   = false;
            var listenerSet   = false;
            IVsWindowFrameNotify2 notifier = null;

            var fileSystem = new IFileSystemMock();
            var textDoc    = ITextDocumentFactory.Create();
            var frame      = IVsWindowFrameFactory.ImplementShowAndSetProperty(VSConstants.S_OK, (property, obj) =>
            {
                switch (property)
                {
                case (int)__VSFPROPID5.VSFPROPID_DontAutoOpen:
                    autoOpenSet = true;
                    break;

                case (int)__VSFPROPID.VSFPROPID_ViewHelper:
                    listenerSet = true;
                    Assert.IsAssignableFrom <IVsWindowFrameNotify2>(obj);
                    notifier = obj as IVsWindowFrameNotify2;
                    break;

                default:
                    Assert.False(true, $"Unexpected property ID {property}");
                    break;
                }

                return(VSConstants.S_OK);
            });

            var modelWatcher        = IMsBuildModelWatcherFactory.CreateInstance();
            var modelWatcherFactory = IExportFactoryFactory.ImplementCreateValue(() => modelWatcher);

            var command = SetupScenario(projectXml, tempDirectory, tempProjFile, projectPath, fileSystem, textDoc, frame, modelWatcherFactory);
            var tree    = ProjectTreeParser.Parse(@"
Root (flags: {ProjectRoot})
");
            var nodes   = ImmutableHashSet.Create(tree);

            // Verify the frame was setup correctly
            Assert.True(await command.TryHandleCommandAsync(nodes, CommandId, true, 0, IntPtr.Zero, IntPtr.Zero));
            Assert.True(fileSystem.DirectoryExists(tempDirectory));
            Assert.Equal(projectXml, fileSystem.ReadAllText(tempProjFile));
            Mock.Get(frame).Verify(f => f.Show());
            Assert.True(autoOpenSet);
            Assert.True(listenerSet);
            Assert.NotNull(notifier);

            // Verify that the model watcher was correctly initialized
            Mock.Get(modelWatcher).Verify(m => m.InitializeAsync(tempProjFile), Times.Once);
            Mock.Get(modelWatcher).Verify(m => m.Dispose(), Times.Never);

            // Now see if the event correctly saved the text from the buffer into the project file
            var args = new TextDocumentFileActionEventArgs(tempProjFile, DateTime.Now, FileActionTypes.ContentSavedToDisk);

            Mock.Get(textDoc).Raise(t => t.FileActionOccurred += null, args);
            Assert.Equal(projectXml, fileSystem.ReadAllText(projectPath));
            Mock.Get(modelWatcher).Verify(m => m.Dispose(), Times.Never);

            // Finally, ensure the cleanup works as expected. We don't do anything with the passed option. The notifier
            // should remove the file temp file from the filesystem.
            Assert.Equal(VSConstants.S_OK, notifier.OnClose(0));
            Assert.False(fileSystem.DirectoryExists(tempDirectory));
            Assert.False(fileSystem.FileExists(tempProjFile));

            // Verify that dispose was called on the model watcher when the window was closed
            Mock.Get(modelWatcher).Verify(m => m.Dispose(), Times.Once);
        }