public void TestSccMenuCommands()
        {
            int  result       = 0;
            Guid badGuid      = new Guid();
            Guid guidCmdGroup = GuidList.guidSccProviderCmdSet;

            OLECMD[] cmdAddToScc = new OLECMD[1];
            cmdAddToScc[0].cmdID = CommandId.icmdAddToSourceControl;
            OLECMD[] cmdCheckin = new OLECMD[1];
            cmdCheckin[0].cmdID = CommandId.icmdCheckin;
            OLECMD[] cmdCheckout = new OLECMD[1];
            cmdCheckout[0].cmdID = CommandId.icmdCheckout;
            OLECMD[] cmdUseSccOffline = new OLECMD[1];
            cmdUseSccOffline[0].cmdID = CommandId.icmdUseSccOffline;
            OLECMD[] cmdViewToolWindow = new OLECMD[1];
            cmdViewToolWindow[0].cmdID = CommandId.icmdViewToolWindow;
            OLECMD[] cmdToolWindowToolbarCommand = new OLECMD[1];
            cmdToolWindowToolbarCommand[0].cmdID = CommandId.icmdToolWindowToolbarCommand;
            OLECMD[] cmdUnsupported = new OLECMD[1];
            cmdUnsupported[0].cmdID = 0;

            // Initialize the provider, etc
            SccProviderService target = GetSccProviderServiceInstance;

            // Mock a service implementing IVsMonitorSelection
            BaseMock monitorSelection = MockIVsMonitorSelectionFactory.GetMonSel();

            serviceProvider.AddService(typeof(IVsMonitorSelection), monitorSelection, true);

            // Commands that don't belong to our package should not be supported
            result = _sccProvider.QueryStatus(ref badGuid, 1, cmdAddToScc, IntPtr.Zero);
            Assert.AreEqual((int)Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED, result);

            // The command should be invisible when there is no solution
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdAddToScc);

            // Activate the provider and test the result
            target.SetActive();
            Assert.AreEqual(true, target.Active, "Microsoft.Samples.VisualStudio.SourceControlIntegration.SccProvider.SccProviderService.Active was not reported correctly.");

            // The commands should be invisible when there is no solution
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdUseSccOffline);

            // Commands that don't belong to our package should not be supported
            result = _sccProvider.QueryStatus(ref guidCmdGroup, 1, cmdUnsupported, IntPtr.Zero);
            Assert.AreEqual((int)Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED, result);

            // Deactivate the provider and test the result
            target.SetInactive();
            Assert.AreEqual(false, target.Active, "Microsoft.Samples.VisualStudio.SourceControlIntegration.SccProvider.SccProviderService.Active was not reported correctly.");

            // Create a solution
            solution.SolutionFile = Path.GetTempFileName();
            MockIVsProject project = new MockIVsProject(Path.GetTempFileName());

            project.AddItem(Path.GetTempFileName());
            solution.AddProject(project);

            // The commands should be invisible when the provider is not active
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdUseSccOffline);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdViewToolWindow);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdToolWindowToolbarCommand);

            // Activate the provider and test the result
            target.SetActive();
            Assert.AreEqual(true, target.Active, "Microsoft.Samples.VisualStudio.SourceControlIntegration.SccProvider.SccProviderService.Active was not reported correctly.");

            // The command should be visible but disabled now, except the toolwindow ones
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdUseSccOffline);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdViewToolWindow);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdToolWindowToolbarCommand);

            // Set selection to solution node
            VSITEMSELECTION selSolutionRoot;

            selSolutionRoot.pHier         = _solution as IVsHierarchy;
            selSolutionRoot.itemid        = VSConstants.VSITEMID_ROOT;
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selSolutionRoot };

            // The add command should be available, rest should be disabled
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdUseSccOffline);

            // Still solution hierarchy, but other way
            selSolutionRoot.pHier         = null;
            selSolutionRoot.itemid        = VSConstants.VSITEMID_ROOT;
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selSolutionRoot };

            // The add command should be available, rest should be disabled
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdUseSccOffline);

            // Set selection to project node
            VSITEMSELECTION selProjectRoot;

            selProjectRoot.pHier          = project as IVsHierarchy;
            selProjectRoot.itemid         = VSConstants.VSITEMID_ROOT;
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selProjectRoot };

            // The add command should be available, rest should be disabled
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdUseSccOffline);

            // Set selection to project item
            VSITEMSELECTION selProjectItem;

            selProjectItem.pHier          = project as IVsHierarchy;
            selProjectItem.itemid         = 0;
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selProjectItem };

            // The add command should be available, rest should be disabled
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdUseSccOffline);

            // Set selection to project and item node and add project to scc
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selProjectRoot, selProjectItem };
            VerifyCommandExecution(cmdAddToScc);

            // The add command and checkin should be disabled, rest should be available now
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdUseSccOffline);

            // Checkout the project
            VerifyCommandExecution(cmdCheckout);

            // The add command and checkout should be disabled, rest should be available now
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdUseSccOffline);

            // Select the solution
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selSolutionRoot };

            // The checkout and offline should be disabled, rest should be available now
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdUseSccOffline);

            // Checkin the project
            VerifyCommandExecution(cmdCheckin);

            // The add command and checkout should be enabled, rest should be disabled
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdUseSccOffline);

            // Add the solution to scc
            VerifyCommandExecution(cmdAddToScc);

            // The add command and checkin should be disabled, rest should be available now
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdUseSccOffline);

            // Select the solution and project
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selSolutionRoot, selProjectRoot };

            // Take the project and solution offline
            VerifyCommandExecution(cmdUseSccOffline);

            // The offline command should be latched
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED | OLECMDF.OLECMDF_LATCHED, cmdUseSccOffline);

            // Select the solution only
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selSolutionRoot };

            // Take the solution online
            VerifyCommandExecution(cmdUseSccOffline);

            // The offline command should be normal again
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdUseSccOffline);

            // Select the solution and project
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selSolutionRoot, selProjectRoot };

            // The offline command should be disabled for mixed selection
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdUseSccOffline);

            // Add a new item to the project
            project.AddItem(Path.GetTempFileName());

            // Select the new item
            selProjectItem.pHier          = project as IVsHierarchy;
            selProjectItem.itemid         = 1;
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selProjectItem };

            // The add command and checkout should be disabled, rest should be available now
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED | OLECMDF.OLECMDF_LATCHED, cmdUseSccOffline);

            // Checkin the new file (this should do an add)
            VerifyCommandExecution(cmdCheckin);

            // The add command and checkout should be disabled, rest should be available now
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED | OLECMDF.OLECMDF_LATCHED, cmdUseSccOffline);
        }
        public void TestTPDEvents()
        {
            int result = 0;

            SccProviderService target = GetSccProviderServiceInstance;

            solution.SolutionFile = Path.GetTempFileName();
            MockIVsProject project = new MockIVsProject(Path.GetTempFileName());

            solution.AddProject(project);

            Hashtable uncontrolled = new Hashtable();

            uncontrolled[project as IVsSccProject2] = true;
            target.AddProjectsToSourceControl(ref uncontrolled, true);
            // In real live, a QueryEdit call on the project file would be necessary to add/rename/delete items

            // Add a new item and fire the appropriate events
            string pendingAddFile = Path.GetTempFileName();

            VSQUERYADDFILERESULTS[] pSummaryResultAdd = new VSQUERYADDFILERESULTS[1];
            VSQUERYADDFILERESULTS[] rgResultsAdd      = new VSQUERYADDFILERESULTS[1];
            result = target.OnQueryAddFiles(project as IVsProject, 1, new string[] { pendingAddFile }, null, pSummaryResultAdd, rgResultsAdd);
            Assert.AreEqual <int>(VSConstants.E_NOTIMPL, result);
            project.AddItem(pendingAddFile);
            result = target.OnAfterAddFilesEx(1, 1, new IVsProject[] { project as IVsProject }, new int[] { 0 }, new string[] { pendingAddFile }, null);
            Assert.AreEqual <int>(VSConstants.E_NOTIMPL, result);
            Assert.AreEqual(SourceControlStatus.scsUncontrolled, target.GetFileStatus(pendingAddFile), "Incorrect status returned");

            // Checkin the pending add file
            target.AddFileToSourceControl(pendingAddFile);

            // Rename the item and verify the file remains is controlled
            string newName = pendingAddFile + ".renamed";

            VSQUERYRENAMEFILERESULTS[] pSummaryResultRen = new VSQUERYRENAMEFILERESULTS[1];
            VSQUERYRENAMEFILERESULTS[] rgResultsRen      = new VSQUERYRENAMEFILERESULTS[1];
            result = target.OnQueryRenameFiles(project as IVsProject, 1, new string[] { pendingAddFile }, new string[] { newName }, null, pSummaryResultRen, rgResultsRen);
            Assert.AreEqual <int>(VSConstants.E_NOTIMPL, result);
            project.RenameItem(pendingAddFile, newName);
            result = target.OnAfterRenameFiles(1, 1, new IVsProject[] { project as IVsProject }, new int[] { 0 }, new string[] { pendingAddFile }, new string[] { newName }, new VSRENAMEFILEFLAGS[] { VSRENAMEFILEFLAGS.VSRENAMEFILEFLAGS_NoFlags });
            Assert.AreEqual <int>(VSConstants.S_OK, result);
            Assert.AreEqual(SourceControlStatus.scsUncontrolled, target.GetFileStatus(pendingAddFile), "Incorrect status returned");
            Assert.AreEqual(SourceControlStatus.scsCheckedIn, target.GetFileStatus(newName), "Incorrect status returned");

            // Mock the UIShell service to answer Cancel to the dialog invocation
            BaseMock mockUIShell = MockUiShellProvider.GetShowMessageBoxCancel();

            serviceProvider.AddService(typeof(IVsUIShell), mockUIShell, true);
            // Try to delete the file from project; the delete should not be allowed
            VSQUERYREMOVEFILERESULTS[] pSummaryResultDel = new VSQUERYREMOVEFILERESULTS[1];
            VSQUERYREMOVEFILERESULTS[] rgResultsDel      = new VSQUERYREMOVEFILERESULTS[1];
            result = target.OnQueryRemoveFiles(project as IVsProject, 1, new string[] { newName }, null, pSummaryResultDel, rgResultsDel);
            Assert.AreEqual <int>(VSConstants.S_OK, result);
            Assert.AreEqual <VSQUERYREMOVEFILERESULTS>(VSQUERYREMOVEFILERESULTS.VSQUERYREMOVEFILERESULTS_RemoveNotOK, pSummaryResultDel[0]);
            // Mock the UIShell service to answer Yes to the dialog invocation
            serviceProvider.RemoveService(typeof(IVsUIShell));
            mockUIShell = MockUiShellProvider.GetShowMessageBoxYes();
            serviceProvider.AddService(typeof(IVsUIShell), mockUIShell, true);
            // Try to delete the file from project; the delete should be allowed this time
            result = target.OnQueryRemoveFiles(project as IVsProject, 1, new string[] { newName }, null, pSummaryResultDel, rgResultsDel);
            Assert.AreEqual <int>(VSConstants.S_OK, result);
            Assert.AreEqual <VSQUERYREMOVEFILERESULTS>(VSQUERYREMOVEFILERESULTS.VSQUERYREMOVEFILERESULTS_RemoveOK, pSummaryResultDel[0]);
            // Remove the file from project
            project.RemoveItem(newName);
            result = target.OnAfterRemoveFiles(1, 1, new IVsProject[] { project as IVsProject }, new int[] { 0 }, new string[] { newName }, null);
            Assert.AreEqual <int>(VSConstants.E_NOTIMPL, result);
        }
        public void TestFileStatus()
        {
            SccProviderService target = GetSccProviderServiceInstance;

            solution.SolutionFile = Path.GetTempFileName();
            MockIVsProject project = new MockIVsProject(Path.GetTempFileName());

            project.AddItem(Path.GetTempFileName());
            solution.AddProject(project);

            VsStateIcon [] rgsiGlyphs           = new VsStateIcon[1];
            VsStateIcon [] rgsiGlyphsFromStatus = new VsStateIcon[1];
            uint[]         rgdwSccStatus        = new uint[1];
            int            result = 0;
            string         strTooltip;

            // Check glyphs and statuses for uncontrolled items
            IList <string> files = new string[] { solution.SolutionFile, project.ProjectFile, project.ProjectItems[0] };

            foreach (string file in files)
            {
                Assert.AreEqual(SourceControlStatus.scsUncontrolled, target.GetFileStatus(file), "Incorrect status returned");

                result = target.GetSccGlyph(1, new string[] { file }, rgsiGlyphs, rgdwSccStatus);
                Assert.AreEqual <int>(VSConstants.S_OK, result);
                Assert.AreEqual <VsStateIcon>(VsStateIcon.STATEICON_BLANK, rgsiGlyphs[0]);
                Assert.AreEqual <uint>((uint)__SccStatus.SCC_STATUS_NOTCONTROLLED, rgdwSccStatus[0]);

                result = target.GetSccGlyphFromStatus(rgdwSccStatus[0], rgsiGlyphsFromStatus);
                Assert.AreEqual <int>(VSConstants.S_OK, result);
                Assert.AreEqual <VsStateIcon>(rgsiGlyphs[0], rgsiGlyphsFromStatus[0]);
            }

            // Uncontrolled items should not have tooltips
            target.GetGlyphTipText(project as IVsHierarchy, VSConstants.VSITEMID_ROOT, out strTooltip);
            Assert.IsTrue(strTooltip.Length == 0);

            Hashtable uncontrolled = new Hashtable();

            uncontrolled[project as IVsSccProject2] = true;
            target.AddProjectsToSourceControl(ref uncontrolled, true);

            foreach (string file in files)
            {
                Assert.AreEqual(SourceControlStatus.scsCheckedIn, target.GetFileStatus(file), "Incorrect status returned");

                result = target.GetSccGlyph(1, new string[] { file }, rgsiGlyphs, rgdwSccStatus);
                Assert.AreEqual <int>(VSConstants.S_OK, result);
                Assert.AreEqual <VsStateIcon>(VsStateIcon.STATEICON_CHECKEDIN, rgsiGlyphs[0]);
                Assert.AreEqual <uint>((uint)__SccStatus.SCC_STATUS_CONTROLLED, rgdwSccStatus[0]);

                result = target.GetSccGlyphFromStatus(rgdwSccStatus[0], rgsiGlyphsFromStatus);
                Assert.AreEqual <int>(VSConstants.S_OK, result);
                Assert.AreEqual <VsStateIcon>(rgsiGlyphs[0], rgsiGlyphsFromStatus[0]);
            }

            // Checked in items should have tooltips
            target.GetGlyphTipText(project as IVsHierarchy, VSConstants.VSITEMID_ROOT, out strTooltip);
            Assert.IsTrue(strTooltip.Length > 0);

            foreach (string file in files)
            {
                target.CheckoutFile(file);
                Assert.AreEqual(SourceControlStatus.scsCheckedOut, target.GetFileStatus(file), "Incorrect status returned");

                result = target.GetSccGlyph(1, new string[] { file }, rgsiGlyphs, rgdwSccStatus);
                Assert.AreEqual <int>(VSConstants.S_OK, result);
                Assert.AreEqual <VsStateIcon>(VsStateIcon.STATEICON_CHECKEDOUT, rgsiGlyphs[0]);
                Assert.AreEqual <uint>((uint)__SccStatus.SCC_STATUS_CHECKEDOUT, rgdwSccStatus[0]);

                result = target.GetSccGlyphFromStatus(rgdwSccStatus[0], rgsiGlyphsFromStatus);
                Assert.AreEqual <int>(VSConstants.S_OK, result);
                Assert.AreEqual <VsStateIcon>(rgsiGlyphs[0], rgsiGlyphsFromStatus[0]);
            }

            // Checked out items should have tooltips, too
            target.GetGlyphTipText(project as IVsHierarchy, VSConstants.VSITEMID_ROOT, out strTooltip);
            Assert.IsTrue(strTooltip.Length > 0);

            foreach (string file in files)
            {
                target.CheckinFile(file);
                Assert.AreEqual(SourceControlStatus.scsCheckedIn, target.GetFileStatus(file), "Incorrect status returned");

                result = target.GetSccGlyph(1, new string[] { file }, rgsiGlyphs, rgdwSccStatus);
                Assert.AreEqual <int>(VSConstants.S_OK, result);
                Assert.AreEqual <VsStateIcon>(VsStateIcon.STATEICON_CHECKEDIN, rgsiGlyphs[0]);
                Assert.AreEqual <uint>((uint)__SccStatus.SCC_STATUS_CONTROLLED, rgdwSccStatus[0]);
            }

            // Add a new file to the project (don't worry about TPD events for now)
            string pendingAddFile = Path.GetTempFileName();

            project.AddItem(pendingAddFile);
            Assert.AreEqual(SourceControlStatus.scsUncontrolled, target.GetFileStatus(pendingAddFile), "Incorrect status returned");

            result = target.GetSccGlyph(1, new string[] { pendingAddFile }, rgsiGlyphs, rgdwSccStatus);
            Assert.AreEqual <int>(VSConstants.S_OK, result);
            Assert.AreEqual <VsStateIcon>(VsStateIcon.STATEICON_CHECKEDOUT, rgsiGlyphs[0]);
            Assert.AreEqual <uint>((uint)__SccStatus.SCC_STATUS_CHECKEDOUT, rgdwSccStatus[0]);

            // Pending add items should have tooltips, too
            target.GetGlyphTipText(project as IVsHierarchy, 1, out strTooltip);
            Assert.IsTrue(strTooltip.Length > 0);

            // Checkin the pending add file
            target.AddFileToSourceControl(pendingAddFile);
            Assert.AreEqual(SourceControlStatus.scsCheckedIn, target.GetFileStatus(pendingAddFile), "Incorrect status returned");

            result = target.GetSccGlyph(1, new string[] { pendingAddFile }, rgsiGlyphs, rgdwSccStatus);
            Assert.AreEqual <int>(VSConstants.S_OK, result);
            Assert.AreEqual <VsStateIcon>(VsStateIcon.STATEICON_CHECKEDIN, rgsiGlyphs[0]);
            Assert.AreEqual <uint>((uint)__SccStatus.SCC_STATUS_CONTROLLED, rgdwSccStatus[0]);
        }
        public void TestTPDEvents()
        {
            int result = 0;

            SccProviderService target = GetSccProviderServiceInstance;
            solution.SolutionFile = Path.GetTempFileName();
            MockIVsProject project = new MockIVsProject(Path.GetTempFileName());
            solution.AddProject(project);

            Hashtable uncontrolled = new Hashtable();
            uncontrolled[project as IVsSccProject2] = true;
            target.AddProjectsToSourceControl(ref uncontrolled, true);
            // In real live, a QueryEdit call on the project file would be necessary to add/rename/delete items

            // Add a new item and fire the appropriate events
            string pendingAddFile = Path.GetTempFileName();
            VSQUERYADDFILERESULTS[] pSummaryResultAdd = new VSQUERYADDFILERESULTS[1];
            VSQUERYADDFILERESULTS[] rgResultsAdd = new VSQUERYADDFILERESULTS[1];
            result = target.OnQueryAddFiles(project as IVsProject, 1, new string[] {pendingAddFile},  null, pSummaryResultAdd, rgResultsAdd);
            Assert.AreEqual<int>(VSConstants.E_NOTIMPL, result);
            project.AddItem(pendingAddFile);
            result = target.OnAfterAddFilesEx(1, 1, new IVsProject[] { project as IVsProject }, new int[] { 0 }, new string[] { pendingAddFile }, null);
            Assert.AreEqual<int>(VSConstants.E_NOTIMPL, result);
            Assert.AreEqual(SourceControlStatus.scsUncontrolled, target.GetFileStatus(pendingAddFile), "Incorrect status returned");

            // Checkin the pending add file
            target.AddFileToSourceControl(pendingAddFile);

            // Rename the item and verify the file remains is controlled
            string newName = pendingAddFile + ".renamed";
            VSQUERYRENAMEFILERESULTS[] pSummaryResultRen = new VSQUERYRENAMEFILERESULTS[1];
            VSQUERYRENAMEFILERESULTS[] rgResultsRen = new VSQUERYRENAMEFILERESULTS[1];
            result = target.OnQueryRenameFiles(project as IVsProject, 1, new string[] { pendingAddFile }, new string[] { newName }, null, pSummaryResultRen, rgResultsRen);
            Assert.AreEqual<int>(VSConstants.E_NOTIMPL, result);
            project.RenameItem(pendingAddFile, newName);
            result = target.OnAfterRenameFiles(1, 1, new IVsProject[] {project as IVsProject}, new int[] {0}, new string[] { pendingAddFile }, new string[] { newName }, new VSRENAMEFILEFLAGS[] {VSRENAMEFILEFLAGS.VSRENAMEFILEFLAGS_NoFlags});
            Assert.AreEqual<int>(VSConstants.S_OK, result);
            Assert.AreEqual(SourceControlStatus.scsUncontrolled, target.GetFileStatus(pendingAddFile), "Incorrect status returned");
            Assert.AreEqual(SourceControlStatus.scsCheckedIn, target.GetFileStatus(newName), "Incorrect status returned");

            // Mock the UIShell service to answer Cancel to the dialog invocation
            BaseMock mockUIShell = MockUiShellProvider.GetShowMessageBoxCancel();
            serviceProvider.AddService(typeof(IVsUIShell), mockUIShell, true);
            // Try to delete the file from project; the delete should not be allowed
            VSQUERYREMOVEFILERESULTS[] pSummaryResultDel = new VSQUERYREMOVEFILERESULTS[1];
            VSQUERYREMOVEFILERESULTS[] rgResultsDel = new VSQUERYREMOVEFILERESULTS[1];
            result = target.OnQueryRemoveFiles(project as IVsProject, 1, new string[] { newName }, null, pSummaryResultDel, rgResultsDel);
            Assert.AreEqual<int>(VSConstants.S_OK, result);
            Assert.AreEqual<VSQUERYREMOVEFILERESULTS>(VSQUERYREMOVEFILERESULTS.VSQUERYREMOVEFILERESULTS_RemoveNotOK, pSummaryResultDel[0]);
            // Mock the UIShell service to answer Yes to the dialog invocation
            serviceProvider.RemoveService(typeof(IVsUIShell));
            mockUIShell = MockUiShellProvider.GetShowMessageBoxYes();
            serviceProvider.AddService(typeof(IVsUIShell), mockUIShell, true);
            // Try to delete the file from project; the delete should be allowed this time
            result = target.OnQueryRemoveFiles(project as IVsProject, 1, new string[] { newName }, null, pSummaryResultDel, rgResultsDel);
            Assert.AreEqual<int>(VSConstants.S_OK, result);
            Assert.AreEqual<VSQUERYREMOVEFILERESULTS>(VSQUERYREMOVEFILERESULTS.VSQUERYREMOVEFILERESULTS_RemoveOK, pSummaryResultDel[0]);
            // Remove the file from project
            project.RemoveItem(newName);
            result = target.OnAfterRemoveFiles(1, 1, new IVsProject[] { project as IVsProject }, new int[] { 0 }, new string[] { newName }, null);
            Assert.AreEqual<int>(VSConstants.E_NOTIMPL, result);
        }
        public void TestSccMenuCommands()
        {
            int result = 0;
            Guid badGuid = new Guid();
            Guid guidCmdGroup = GuidList.guidSccProviderCmdSet;

            OLECMD[] cmdAddToScc = new OLECMD[1];
            cmdAddToScc[0].cmdID = CommandId.icmdAddToSourceControl;
            OLECMD[] cmdCheckin = new OLECMD[1];
            cmdCheckin[0].cmdID = CommandId.icmdCheckin;
            OLECMD[] cmdCheckout = new OLECMD[1];
            cmdCheckout[0].cmdID = CommandId.icmdCheckout;
            OLECMD[] cmdUseSccOffline = new OLECMD[1];
            cmdUseSccOffline[0].cmdID = CommandId.icmdUseSccOffline;
            OLECMD[] cmdViewToolWindow = new OLECMD[1];
            cmdViewToolWindow[0].cmdID = CommandId.icmdViewToolWindow;
            OLECMD[] cmdToolWindowToolbarCommand = new OLECMD[1];
            cmdToolWindowToolbarCommand[0].cmdID = CommandId.icmdToolWindowToolbarCommand;
            OLECMD[] cmdUnsupported = new OLECMD[1];
            cmdUnsupported[0].cmdID = 0;

            // Initialize the provider, etc
            SccProviderService target = GetSccProviderServiceInstance;

            // Mock a service implementing IVsMonitorSelection
            BaseMock monitorSelection = MockIVsMonitorSelectionFactory.GetMonSel();
            serviceProvider.AddService(typeof(IVsMonitorSelection), monitorSelection, true);

            // Commands that don't belong to our package should not be supported
            result = _sccProvider.QueryStatus(ref badGuid, 1, cmdAddToScc, IntPtr.Zero);
            Assert.AreEqual((int)Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED, result);

            // The command should be invisible when there is no solution
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdAddToScc);

            // Activate the provider and test the result
            target.SetActive();
            Assert.AreEqual(true, target.Active, "Microsoft.Samples.VisualStudio.SourceControlIntegration.SccProvider.SccProviderService.Active was not reported correctly.");

            // The commands should be invisible when there is no solution
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdUseSccOffline);

            // Commands that don't belong to our package should not be supported
            result = _sccProvider.QueryStatus(ref guidCmdGroup, 1, cmdUnsupported, IntPtr.Zero);
            Assert.AreEqual((int)Microsoft.VisualStudio.OLE.Interop.Constants.OLECMDERR_E_NOTSUPPORTED, result);

            // Deactivate the provider and test the result
            target.SetInactive();
            Assert.AreEqual(false, target.Active, "Microsoft.Samples.VisualStudio.SourceControlIntegration.SccProvider.SccProviderService.Active was not reported correctly.");

            // Create a solution
            solution.SolutionFile = Path.GetTempFileName();
            MockIVsProject project = new MockIVsProject(Path.GetTempFileName());
            project.AddItem(Path.GetTempFileName());
            solution.AddProject(project);

            // The commands should be invisible when the provider is not active
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdUseSccOffline);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdViewToolWindow);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_INVISIBLE, cmdToolWindowToolbarCommand);

            // Activate the provider and test the result
            target.SetActive();
            Assert.AreEqual(true, target.Active, "Microsoft.Samples.VisualStudio.SourceControlIntegration.SccProvider.SccProviderService.Active was not reported correctly.");

            // The command should be visible but disabled now, except the toolwindow ones
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdUseSccOffline);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdViewToolWindow);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdToolWindowToolbarCommand);

            // Set selection to solution node
            VSITEMSELECTION selSolutionRoot;
            selSolutionRoot.pHier = _solution as IVsHierarchy;
            selSolutionRoot.itemid = VSConstants.VSITEMID_ROOT;
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selSolutionRoot };

            // The add command should be available, rest should be disabled
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdUseSccOffline);

            // Still solution hierarchy, but other way
            selSolutionRoot.pHier = null;
            selSolutionRoot.itemid = VSConstants.VSITEMID_ROOT;
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selSolutionRoot };

            // The add command should be available, rest should be disabled
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdUseSccOffline);

            // Set selection to project node
            VSITEMSELECTION selProjectRoot;
            selProjectRoot.pHier = project as IVsHierarchy;
            selProjectRoot.itemid = VSConstants.VSITEMID_ROOT;
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selProjectRoot };

            // The add command should be available, rest should be disabled
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdUseSccOffline);

            // Set selection to project item
            VSITEMSELECTION selProjectItem;
            selProjectItem.pHier = project as IVsHierarchy;
            selProjectItem.itemid = 0;
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selProjectItem };

            // The add command should be available, rest should be disabled
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdUseSccOffline);

            // Set selection to project and item node and add project to scc
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selProjectRoot, selProjectItem };
            VerifyCommandExecution(cmdAddToScc);

            // The add command and checkin should be disabled, rest should be available now
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdUseSccOffline);

            // Checkout the project
            VerifyCommandExecution(cmdCheckout);

            // The add command and checkout should be disabled, rest should be available now
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdUseSccOffline);

            // Select the solution
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selSolutionRoot };

            // The checkout and offline should be disabled, rest should be available now
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdUseSccOffline);

            // Checkin the project
            VerifyCommandExecution(cmdCheckin);

            // The add command and checkout should be enabled, rest should be disabled
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdUseSccOffline);

            // Add the solution to scc
            VerifyCommandExecution(cmdAddToScc);

            // The add command and checkin should be disabled, rest should be available now
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdUseSccOffline);

            // Select the solution and project
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selSolutionRoot, selProjectRoot };

            // Take the project and solution offline
            VerifyCommandExecution(cmdUseSccOffline);

            // The offline command should be latched
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED | OLECMDF.OLECMDF_LATCHED, cmdUseSccOffline);

            // Select the solution only
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selSolutionRoot};

            // Take the solution online
            VerifyCommandExecution(cmdUseSccOffline);

            // The offline command should be normal again
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdUseSccOffline);

            // Select the solution and project
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selSolutionRoot, selProjectRoot };

            // The offline command should be disabled for mixed selection
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdUseSccOffline);

            // Add a new item to the project
            project.AddItem(Path.GetTempFileName());

            // Select the new item
            selProjectItem.pHier = project as IVsHierarchy;
            selProjectItem.itemid = 1;
            monitorSelection["Selection"] = new VSITEMSELECTION[] { selProjectItem };

            // The add command and checkout should be disabled, rest should be available now
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED | OLECMDF.OLECMDF_LATCHED, cmdUseSccOffline);

            // Checkin the new file (this should do an add)
            VerifyCommandExecution(cmdCheckin);

            // The add command and checkout should be disabled, rest should be available now
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdAddToScc);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED, cmdCheckin);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED, cmdCheckout);
            VerifyCommandStatus(OLECMDF.OLECMDF_SUPPORTED | OLECMDF.OLECMDF_ENABLED | OLECMDF.OLECMDF_LATCHED, cmdUseSccOffline);
        }
        public void TestFileStatus()
        {
            SccProviderService target = GetSccProviderServiceInstance;
            solution.SolutionFile = Path.GetTempFileName();
            MockIVsProject project = new MockIVsProject(Path.GetTempFileName());
            project.AddItem(Path.GetTempFileName());
            solution.AddProject(project);

            VsStateIcon [] rgsiGlyphs = new VsStateIcon[1];
            VsStateIcon [] rgsiGlyphsFromStatus = new VsStateIcon[1];
            uint[] rgdwSccStatus = new uint[1];
            int result = 0;
            string strTooltip;

            // Check glyphs and statuses for uncontrolled items
            IList<string> files = new string[] { solution.SolutionFile, project.ProjectFile, project.ProjectItems[0] };
            foreach (string file in files)
            {
                Assert.AreEqual(SourceControlStatus.scsUncontrolled, target.GetFileStatus(file), "Incorrect status returned");

                result = target.GetSccGlyph(1, new string[] { file }, rgsiGlyphs, rgdwSccStatus);
                Assert.AreEqual<int>(VSConstants.S_OK, result);
                Assert.AreEqual<VsStateIcon>(VsStateIcon.STATEICON_BLANK, rgsiGlyphs[0]);
                Assert.AreEqual<uint>((uint) __SccStatus.SCC_STATUS_NOTCONTROLLED, rgdwSccStatus[0]);

                result = target.GetSccGlyphFromStatus(rgdwSccStatus[0], rgsiGlyphsFromStatus);
                Assert.AreEqual<int>(VSConstants.S_OK, result);
                Assert.AreEqual<VsStateIcon>(rgsiGlyphs[0], rgsiGlyphsFromStatus[0]);
            }

            // Uncontrolled items should not have tooltips
            target.GetGlyphTipText(project as IVsHierarchy, VSConstants.VSITEMID_ROOT, out strTooltip);
            Assert.IsTrue(strTooltip.Length == 0);

            Hashtable uncontrolled = new Hashtable();
            uncontrolled[project as IVsSccProject2] = true;
            target.AddProjectsToSourceControl(ref uncontrolled, true);

            foreach (string file in files)
            {
                Assert.AreEqual(SourceControlStatus.scsCheckedIn, target.GetFileStatus(file), "Incorrect status returned");

                result = target.GetSccGlyph(1, new string[] { file }, rgsiGlyphs, rgdwSccStatus);
                Assert.AreEqual<int>(VSConstants.S_OK, result);
                Assert.AreEqual<VsStateIcon>(VsStateIcon.STATEICON_CHECKEDIN, rgsiGlyphs[0]);
                Assert.AreEqual<uint>((uint) __SccStatus.SCC_STATUS_CONTROLLED, rgdwSccStatus[0]);

                result = target.GetSccGlyphFromStatus(rgdwSccStatus[0], rgsiGlyphsFromStatus);
                Assert.AreEqual<int>(VSConstants.S_OK, result);
                Assert.AreEqual<VsStateIcon>(rgsiGlyphs[0], rgsiGlyphsFromStatus[0]);
            }

            // Checked in items should have tooltips
            target.GetGlyphTipText(project as IVsHierarchy, VSConstants.VSITEMID_ROOT, out strTooltip);
            Assert.IsTrue(strTooltip.Length > 0);

            foreach (string file in files)
            {
                target.CheckoutFile(file);
                Assert.AreEqual(SourceControlStatus.scsCheckedOut, target.GetFileStatus(file), "Incorrect status returned");

                result = target.GetSccGlyph(1, new string[] { file }, rgsiGlyphs, rgdwSccStatus);
                Assert.AreEqual<int>(VSConstants.S_OK, result);
                Assert.AreEqual<VsStateIcon>(VsStateIcon.STATEICON_CHECKEDOUT, rgsiGlyphs[0]);
                Assert.AreEqual<uint>((uint) __SccStatus.SCC_STATUS_CHECKEDOUT, rgdwSccStatus[0]);

                result = target.GetSccGlyphFromStatus(rgdwSccStatus[0], rgsiGlyphsFromStatus);
                Assert.AreEqual<int>(VSConstants.S_OK, result);
                Assert.AreEqual<VsStateIcon>(rgsiGlyphs[0], rgsiGlyphsFromStatus[0]);
            }

            // Checked out items should have tooltips, too
            target.GetGlyphTipText(project as IVsHierarchy, VSConstants.VSITEMID_ROOT, out strTooltip);
            Assert.IsTrue(strTooltip.Length > 0);

            foreach (string file in files)
            {
                target.CheckinFile(file);
                Assert.AreEqual(SourceControlStatus.scsCheckedIn, target.GetFileStatus(file), "Incorrect status returned");

                result = target.GetSccGlyph(1, new string[] { file }, rgsiGlyphs, rgdwSccStatus);
                Assert.AreEqual<int>(VSConstants.S_OK, result);
                Assert.AreEqual<VsStateIcon>(VsStateIcon.STATEICON_CHECKEDIN, rgsiGlyphs[0]);
                Assert.AreEqual<uint>((uint) __SccStatus.SCC_STATUS_CONTROLLED, rgdwSccStatus[0]);
            }

            // Add a new file to the project (don't worry about TPD events for now)
            string pendingAddFile = Path.GetTempFileName();
            project.AddItem(pendingAddFile);
            Assert.AreEqual(SourceControlStatus.scsUncontrolled, target.GetFileStatus(pendingAddFile), "Incorrect status returned");

            result = target.GetSccGlyph(1, new string[] { pendingAddFile }, rgsiGlyphs, rgdwSccStatus);
            Assert.AreEqual<int>(VSConstants.S_OK, result);
            Assert.AreEqual<VsStateIcon>(VsStateIcon.STATEICON_CHECKEDOUT, rgsiGlyphs[0]);
            Assert.AreEqual<uint>((uint) __SccStatus.SCC_STATUS_CHECKEDOUT, rgdwSccStatus[0]);

            // Pending add items should have tooltips, too
            target.GetGlyphTipText(project as IVsHierarchy, 1, out strTooltip);
            Assert.IsTrue(strTooltip.Length > 0);

            // Checkin the pending add file
            target.AddFileToSourceControl(pendingAddFile);
            Assert.AreEqual(SourceControlStatus.scsCheckedIn, target.GetFileStatus(pendingAddFile), "Incorrect status returned");

            result = target.GetSccGlyph(1, new string[] { pendingAddFile }, rgsiGlyphs, rgdwSccStatus);
            Assert.AreEqual<int>(VSConstants.S_OK, result);
            Assert.AreEqual<VsStateIcon>(VsStateIcon.STATEICON_CHECKEDIN, rgsiGlyphs[0]);
            Assert.AreEqual<uint>((uint) __SccStatus.SCC_STATUS_CONTROLLED, rgdwSccStatus[0]);
        }