diff --git a/.azure-pipelines/azure-pipelines-build.yml b/.azure-pipelines/azure-pipelines-build.yml index 554acc1..3c6bbff 100644 --- a/.azure-pipelines/azure-pipelines-build.yml +++ b/.azure-pipelines/azure-pipelines-build.yml @@ -52,8 +52,11 @@ steps: Write-Host "Version: $version" $version | Out-File "$(Build.ArtifactStagingDirectory)\version.txt" Get-ChildItem -Path "$(Build.SourcesDirectory)\source\AccUnit\bin\$(buildConfiguration)" - Compress-Archive -Path "$(Build.SourcesDirectory)\source\AccUnit\bin\$(buildConfiguration)\AccessCodeLib.*.dll" -DestinationPath "$(Build.ArtifactStagingDirectory)\AccUnit.$($version).bin.zip" - Compress-Archive -Path "$(Build.SourcesDirectory)\source\AccUnit\bin\$(buildConfiguration)\AccessCodeLib.*.tlb" -DestinationPath "$(Build.ArtifactStagingDirectory)\AccUnit.$($version).bin.zip" -Update + Compress-Archive -Path "$(Build.SourcesDirectory)\source\AccUnit\bin\$(buildConfiguration)\AccUnit.dll*" -DestinationPath "$(Build.ArtifactStagingDirectory)\AccUnit.$($version).bin.zip" + Compress-Archive -Path "$(Build.SourcesDirectory)\source\AccUnit\bin\$(buildConfiguration)\AccUnit.tlb" -DestinationPath "$(Build.ArtifactStagingDirectory)\AccUnit.$($version).bin.zip" -Update + Compress-Archive -Path "$(Build.SourcesDirectory)\source\AccUnit\bin\$(buildConfiguration)\AccessCodeLib.*.dll" -DestinationPath "$(Build.ArtifactStagingDirectory)\AccUnit.$($version).bin.zip" -Update + Compress-Archive -Path "$(Build.SourcesDirectory)\vbe-add-In\AccUnit.VbeAddIn\bin\$(buildConfiguration)\AccUnit.VbeAddIn.dll*" -DestinationPath "$(Build.ArtifactStagingDirectory)\AccUnit.$($version).bin.zip" -Update + Compress-Archive -Path "$(Build.SourcesDirectory)\vbe-add-In\AccUnit.VbeAddIn\bin\$(buildConfiguration)\AccessCodeLib.Common.VbeUserControlHost.dll" -DestinationPath "$(Build.ArtifactStagingDirectory)\AccUnit.$($version).bin.zip" -Update displayName: 'Read Version and create zip file' - task: PublishBuildArtifacts@1 diff --git a/access-add-in/AccUnitLoader.accda b/access-add-in/AccUnitLoader.accda index bc1832a..445e9f9 100644 Binary files a/access-add-in/AccUnitLoader.accda and b/access-add-in/AccUnitLoader.accda differ diff --git a/access-add-in/_CopyAccUnitLibFilesFromRelease.cmd b/access-add-in/_CopyAccUnitLibFilesFromRelease.cmd index 097ca5b..eb9cfd5 100644 --- a/access-add-in/_CopyAccUnitLibFilesFromRelease.cmd +++ b/access-add-in/_CopyAccUnitLibFilesFromRelease.cmd @@ -3,7 +3,14 @@ if exist .\lib\ ( ) else ( mkdir .\lib\ ) -copy .\..\source\AccUnit\bin\Release\AccessCodeLib.*.tlb .\lib\ + +:: Framework: +copy .\..\source\AccUnit\bin\Release\AccUnit.dll* .\lib\ +copy .\..\source\AccUnit\bin\Release\AccUnit.tlb .\lib\ copy .\..\source\AccUnit\bin\Release\AccessCodeLib.*.dll .\lib\ +:: VBE Add-in: +copy .\..\vbe-add-In\AccUnit.VbeAddIn\bin\Release\AccUnit.VbeAddIn.dll* .\lib\ +copy .\..\vbe-add-In\AccUnit.VbeAddIn\bin\Release\AccessCodeLib.Common.VbeUserControlHost.dll .\lib\ + timeout 3 \ No newline at end of file diff --git a/access-add-in/source/forms/AccUnitLoaderForm.bas b/access-add-in/source/forms/AccUnitLoaderForm.bas index 5997fc3..4ec128f 100644 --- a/access-add-in/source/forms/AccUnitLoaderForm.bas +++ b/access-add-in/source/forms/AccUnitLoaderForm.bas @@ -16,10 +16,10 @@ Begin Form GridY =10 Width =10604 DatasheetFontHeight =11 - ItemSuffix =128 - Left =3713 + ItemSuffix =154 + Left =6285 Top =3915 - Right =20010 + Right =14978 Bottom =12750 OnUnload ="[Event Procedure]" RecSrcDt = Begin @@ -102,7 +102,7 @@ Begin Form GridlineShade =65.0 End Begin Section - Height =4025 + Height =5142 Name ="Detail" Begin Begin CommandButton @@ -157,6 +157,10 @@ Begin Form ControlTipText ="Select AccUnit directory of the dll files" GroupTable =2 BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =9908 LayoutCachedTop =120 @@ -188,6 +192,10 @@ Begin Form AfterUpdate ="[Event Procedure]" GroupTable =2 BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =2805 LayoutCachedTop =120 @@ -213,6 +221,10 @@ Begin Form Caption ="Location of AccUnit dll files:" GroupTable =2 BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =120 LayoutCachedTop =120 LayoutCachedWidth =2738 @@ -263,6 +275,10 @@ Begin Form OnClick ="[Event Procedure]" GroupTable =2 BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =2805 LayoutCachedTop =1395 @@ -291,7 +307,12 @@ Begin Form Caption ="Remove reference to AccUnit.tlb" OnClick ="[Event Procedure]" GroupTable =2 - BottomPadding =150 + BottomPadding =86 + GridlineStyleBottom =1 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =2805 LayoutCachedTop =1988 @@ -307,6 +328,7 @@ Begin Form GridlineShade =65.0 ThemeFontIndex =1 GroupTable =2 + Overlaps =1 End Begin CommandButton TabStop = NotDefault @@ -321,6 +343,10 @@ Begin Form OnClick ="[Event Procedure]" GroupTable =2 BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =2805 LayoutCachedTop =803 @@ -337,24 +363,6 @@ Begin Form ThemeFontIndex =1 GroupTable =2 End - Begin EmptyCell - Left =120 - Top =803 - Width =2618 - Height =405 - Name ="EmptyCell71" - GroupTable =2 - BottomPadding =150 - LayoutCachedLeft =120 - LayoutCachedTop =803 - LayoutCachedWidth =2738 - LayoutCachedHeight =1208 - RowStart =1 - RowEnd =1 - ColumnEnd =1 - LayoutGroup =1 - GroupTable =2 - End Begin EmptyCell Left =7845 Top =803 @@ -363,6 +371,10 @@ Begin Form Name ="EmptyCell73" GroupTable =2 BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =7845 LayoutCachedTop =803 LayoutCachedWidth =9840 @@ -374,24 +386,6 @@ Begin Form LayoutGroup =1 GroupTable =2 End - Begin EmptyCell - Left =120 - Top =1395 - Width =2618 - Height =405 - Name ="EmptyCell76" - GroupTable =2 - BottomPadding =150 - LayoutCachedLeft =120 - LayoutCachedTop =1395 - LayoutCachedWidth =2738 - LayoutCachedHeight =1800 - RowStart =2 - RowEnd =2 - ColumnEnd =1 - LayoutGroup =1 - GroupTable =2 - End Begin EmptyCell Left =7845 Top =1395 @@ -400,6 +394,10 @@ Begin Form Name ="EmptyCell78" GroupTable =2 BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =7845 LayoutCachedTop =1395 LayoutCachedWidth =10478 @@ -411,24 +409,6 @@ Begin Form LayoutGroup =1 GroupTable =2 End - Begin EmptyCell - Left =120 - Top =1988 - Width =2618 - Height =405 - Name ="EmptyCell81" - GroupTable =2 - BottomPadding =150 - LayoutCachedLeft =120 - LayoutCachedTop =1988 - LayoutCachedWidth =2738 - LayoutCachedHeight =2393 - RowStart =3 - RowEnd =3 - ColumnEnd =1 - LayoutGroup =1 - GroupTable =2 - End Begin EmptyCell Left =7845 Top =1988 @@ -436,7 +416,12 @@ Begin Form Height =405 Name ="EmptyCell83" GroupTable =2 - BottomPadding =150 + BottomPadding =86 + GridlineStyleBottom =1 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =7845 LayoutCachedTop =1988 LayoutCachedWidth =9840 @@ -452,23 +437,27 @@ Begin Form TabStop = NotDefault OverlapFlags =85 Left =120 - Top =3338 + Top =4508 Width =5175 Height =465 - TabIndex =8 + TabIndex =10 Name ="cmdInsertFactoryModule" Caption ="Insert/update AccUnit Factory module in application" OnClick ="[Event Procedure]" GroupTable =2 BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =120 - LayoutCachedTop =3338 + LayoutCachedTop =4508 LayoutCachedWidth =5295 - LayoutCachedHeight =3803 + LayoutCachedHeight =4973 PictureCaptionArrangement =5 - RowStart =5 - RowEnd =5 + RowStart =7 + RowEnd =7 ColumnEnd =2 LayoutGroup =1 GridlineThemeColorIndex =1 @@ -484,6 +473,10 @@ Begin Form Name ="EmptyCell93" GroupTable =2 BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =9908 LayoutCachedTop =803 LayoutCachedWidth =10478 @@ -502,7 +495,11 @@ Begin Form Height =405 Name ="EmptyCell95" GroupTable =2 - BottomPadding =150 + BottomPadding =86 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =9908 LayoutCachedTop =1988 LayoutCachedWidth =10478 @@ -518,24 +515,28 @@ Begin Form TabStop = NotDefault OverlapFlags =85 Left =9908 - Top =3338 + Top =4508 Width =570 Height =465 - TabIndex =9 + TabIndex =11 Name ="cmdOpenMenu" Caption ="..." OnClick ="[Event Procedure]" ControlTipText ="More commands ..." GroupTable =2 BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =9908 - LayoutCachedTop =3338 + LayoutCachedTop =4508 LayoutCachedWidth =10478 - LayoutCachedHeight =3803 + LayoutCachedHeight =4973 PictureCaptionArrangement =5 - RowStart =5 - RowEnd =5 + RowStart =7 + RowEnd =7 ColumnStart =6 ColumnEnd =6 LayoutGroup =1 @@ -548,10 +549,10 @@ Begin Form TabStop = NotDefault OverlapFlags =85 Left =9908 - Top =2580 + Top =3750 Width =570 Height =570 - TabIndex =7 + TabIndex =9 Name ="cmdUserSettings" OnClick ="[Event Procedure]" ObjectPalette = Begin @@ -559,7 +560,12 @@ Begin Form End ControlTipText ="AccUnit Settings" GroupTable =2 + TopPadding =86 BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 ImageData = Begin 0x2800000010000000100000000100200000000000000000000000000000000000 , 0x000000000000000000000000000000000000000072727287727272f3727272f3 , @@ -598,11 +604,11 @@ Begin Form End LayoutCachedLeft =9908 - LayoutCachedTop =2580 + LayoutCachedTop =3750 LayoutCachedWidth =10478 - LayoutCachedHeight =3150 - RowStart =4 - RowEnd =4 + LayoutCachedHeight =4320 + RowStart =6 + RowEnd =6 ColumnStart =6 ColumnEnd =6 LayoutGroup =1 @@ -612,35 +618,44 @@ Begin Form End Begin EmptyCell Left =120 - Top =2580 + Top =3750 Width =562 Height =570 Name ="EmptyCell113" GroupTable =2 + TopPadding =86 BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =120 - LayoutCachedTop =2580 + LayoutCachedTop =3750 LayoutCachedWidth =682 - LayoutCachedHeight =3150 - RowStart =4 - RowEnd =4 + LayoutCachedHeight =4320 + RowStart =6 + RowEnd =6 LayoutGroup =1 GroupTable =2 End Begin EmptyCell Left =7845 - Top =3338 + Top =4508 Width =1995 Height =465 Name ="EmptyCell119" GroupTable =2 BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =7845 - LayoutCachedTop =3338 + LayoutCachedTop =4508 LayoutCachedWidth =9840 - LayoutCachedHeight =3803 - RowStart =5 - RowEnd =5 + LayoutCachedHeight =4973 + RowStart =7 + RowEnd =7 ColumnStart =4 ColumnEnd =5 LayoutGroup =1 @@ -648,18 +663,22 @@ Begin Form End Begin EmptyCell Left =5355 - Top =3338 + Top =4508 Width =2430 Height =465 Name ="EmptyCell121" GroupTable =2 BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =5355 - LayoutCachedTop =3338 + LayoutCachedTop =4508 LayoutCachedWidth =7785 - LayoutCachedHeight =3803 - RowStart =5 - RowEnd =5 + LayoutCachedHeight =4973 + RowStart =7 + RowEnd =7 ColumnStart =3 ColumnEnd =3 LayoutGroup =1 @@ -669,18 +688,23 @@ Begin Form OverlapFlags =85 TextAlign =2 Left =743 - Top =2580 + Top =3750 Width =8887 Height =570 Name ="labInfo" GroupTable =2 + TopPadding =86 BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =743 - LayoutCachedTop =2580 + LayoutCachedTop =3750 LayoutCachedWidth =9630 - LayoutCachedHeight =3150 - RowStart =4 - RowEnd =4 + LayoutCachedHeight =4320 + RowStart =6 + RowEnd =6 ColumnStart =1 ColumnEnd =4 LayoutGroup =1 @@ -692,16 +716,79 @@ Begin Form End Begin EmptyCell Left =9690 - Top =2580 + Top =3750 Width =150 Height =570 Name ="EmptyCell127" GroupTable =2 + TopPadding =86 BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 LayoutCachedLeft =9690 - LayoutCachedTop =2580 + LayoutCachedTop =3750 LayoutCachedWidth =9840 - LayoutCachedHeight =3150 + LayoutCachedHeight =4320 + RowStart =6 + RowEnd =6 + ColumnStart =5 + ColumnEnd =5 + LayoutGroup =1 + GroupTable =2 + End + Begin CommandButton + TabStop = NotDefault + OverlapFlags =85 + Left =2805 + Top =2573 + Width =4980 + Height =405 + TabIndex =7 + Name ="cmdInstallVbeAddIn" + Caption ="Install VBE Add-in" + OnClick ="[Event Procedure]" + GroupTable =2 + TopPadding =86 + BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 + + LayoutCachedLeft =2805 + LayoutCachedTop =2573 + LayoutCachedWidth =7785 + LayoutCachedHeight =2978 + PictureCaptionArrangement =5 + RowStart =4 + RowEnd =4 + ColumnStart =2 + ColumnEnd =3 + LayoutGroup =1 + GridlineThemeColorIndex =1 + GridlineShade =65.0 + ThemeFontIndex =1 + GroupTable =2 + End + Begin EmptyCell + Left =9690 + Top =2573 + Width =150 + Height =405 + Name ="EmptyCell135" + GroupTable =2 + TopPadding =86 + BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 + LayoutCachedLeft =9690 + LayoutCachedTop =2573 + LayoutCachedWidth =9840 + LayoutCachedHeight =2978 RowStart =4 RowEnd =4 ColumnStart =5 @@ -709,6 +796,262 @@ Begin Form LayoutGroup =1 GroupTable =2 End + Begin EmptyCell + Left =9908 + Top =2573 + Width =570 + Height =405 + Name ="EmptyCell136" + GroupTable =2 + TopPadding =86 + BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 + LayoutCachedLeft =9908 + LayoutCachedTop =2573 + LayoutCachedWidth =10478 + LayoutCachedHeight =2978 + RowStart =4 + RowEnd =4 + ColumnStart =6 + ColumnEnd =6 + LayoutGroup =1 + GroupTable =2 + End + Begin EmptyCell + Left =7845 + Top =2573 + Width =1785 + Height =405 + Name ="EmptyCell137" + GroupTable =2 + TopPadding =86 + BottomPadding =150 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 + LayoutCachedLeft =7845 + LayoutCachedTop =2573 + LayoutCachedWidth =9630 + LayoutCachedHeight =2978 + RowStart =4 + RowEnd =4 + ColumnStart =4 + ColumnEnd =4 + LayoutGroup =1 + GroupTable =2 + End + Begin CommandButton + TabStop = NotDefault + OverlapFlags =85 + Left =2805 + Top =3165 + Width =4980 + Height =405 + TabIndex =8 + Name ="cmdLoadVbeAddIn" + Caption ="Load VBE Add-in" + OnClick ="[Event Procedure]" + GroupTable =2 + BottomPadding =86 + GridlineStyleBottom =1 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 + + LayoutCachedLeft =2805 + LayoutCachedTop =3165 + LayoutCachedWidth =7785 + LayoutCachedHeight =3570 + PictureCaptionArrangement =5 + RowStart =5 + RowEnd =5 + ColumnStart =2 + ColumnEnd =3 + LayoutGroup =1 + GridlineThemeColorIndex =1 + GridlineShade =65.0 + ThemeFontIndex =1 + GroupTable =2 + Overlaps =1 + End + Begin EmptyCell + Left =9690 + Top =3165 + Width =150 + Height =405 + Name ="EmptyCell145" + GroupTable =2 + BottomPadding =86 + GridlineStyleBottom =1 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 + LayoutCachedLeft =9690 + LayoutCachedTop =3165 + LayoutCachedWidth =9840 + LayoutCachedHeight =3570 + RowStart =5 + RowEnd =5 + ColumnStart =5 + ColumnEnd =5 + LayoutGroup =1 + GroupTable =2 + End + Begin EmptyCell + Left =9908 + Top =3165 + Width =570 + Height =405 + Name ="EmptyCell146" + GroupTable =2 + BottomPadding =86 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 + LayoutCachedLeft =9908 + LayoutCachedTop =3165 + LayoutCachedWidth =10478 + LayoutCachedHeight =3570 + RowStart =5 + RowEnd =5 + ColumnStart =6 + ColumnEnd =6 + LayoutGroup =1 + GroupTable =2 + End + Begin EmptyCell + Left =7845 + Top =3165 + Width =1785 + Height =405 + Name ="EmptyCell147" + GroupTable =2 + BottomPadding =86 + GridlineStyleBottom =1 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 + LayoutCachedLeft =7845 + LayoutCachedTop =3165 + LayoutCachedWidth =9630 + LayoutCachedHeight =3570 + RowStart =5 + RowEnd =5 + ColumnStart =4 + ColumnEnd =4 + LayoutGroup =1 + GroupTable =2 + End + Begin Label + OverlapFlags =85 + TextAlign =3 + Left =743 + Top =803 + Width =1995 + Height =1590 + Name ="Label148" + Caption ="AccUnit (Framework)" + GroupTable =2 + BottomPadding =86 + GridlineStyleBottom =1 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 + LayoutCachedLeft =743 + LayoutCachedTop =803 + LayoutCachedWidth =2738 + LayoutCachedHeight =2393 + RowStart =1 + RowEnd =3 + ColumnStart =1 + ColumnEnd =1 + LayoutGroup =1 + GridlineThemeColorIndex =1 + GridlineShade =65.0 + GroupTable =2 + End + Begin Label + OverlapFlags =85 + TextAlign =3 + Left =743 + Top =2573 + Width =1995 + Height =997 + Name ="Label149" + Caption ="AccUnit VBE Add-in" + GroupTable =2 + TopPadding =86 + BottomPadding =86 + GridlineStyleBottom =1 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 + LayoutCachedLeft =743 + LayoutCachedTop =2573 + LayoutCachedWidth =2738 + LayoutCachedHeight =3570 + RowStart =4 + RowEnd =5 + ColumnStart =1 + ColumnEnd =1 + LayoutGroup =1 + GridlineThemeColorIndex =1 + GridlineShade =65.0 + GroupTable =2 + End + Begin EmptyCell + Left =120 + Top =2573 + Width =562 + Height =997 + Name ="EmptyCell151" + GroupTable =2 + TopPadding =86 + BottomPadding =86 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 + LayoutCachedLeft =120 + LayoutCachedTop =2573 + LayoutCachedWidth =682 + LayoutCachedHeight =3570 + RowStart =4 + RowEnd =5 + LayoutGroup =1 + GroupTable =2 + End + Begin EmptyCell + Left =120 + Top =803 + Width =562 + Height =1590 + Name ="EmptyCell153" + GroupTable =2 + BottomPadding =86 + GridlineWidthLeft =0 + GridlineWidthTop =0 + GridlineWidthRight =0 + GridlineWidthBottom =0 + LayoutCachedLeft =120 + LayoutCachedTop =803 + LayoutCachedWidth =682 + LayoutCachedHeight =2393 + RowStart =1 + RowEnd =3 + LayoutGroup =1 + GroupTable =2 + End End End End diff --git a/access-add-in/source/forms/AccUnitLoaderForm.cls b/access-add-in/source/forms/AccUnitLoaderForm.cls index f4e3602..d11e4a3 100644 --- a/access-add-in/source/forms/AccUnitLoaderForm.cls +++ b/access-add-in/source/forms/AccUnitLoaderForm.cls @@ -26,6 +26,8 @@ Private Const APPFILE_PROPNAME_APPICON As String = "AppIcon" Private Const ShowSuccessInfoTimerInterval As Long = 4000 +Private RunLoadAfterAddInInstalledTimer As Boolean + Private Sub ShowErrorHandlerInfo(ByVal ProcName As String) Me.labInfo.Caption = "Error " & Err.Number & " (" & Err.Description & ") in procedure " & ProcName End Sub @@ -68,6 +70,172 @@ HandleErr: End Sub +Private Sub cmdInstallVbeAddIn_Click() + +On Error GoTo HandleErr + + If Me.cmdInstallVbeAddIn.Tag <> "Installed" Then + OpenVbeInstallShortcutMenu + Exit Sub + End If + + With New VbeAddInInstaller + .UnRegisterAccUnitVbeAddIn + VBE.Addins.Update + SetInstallVbeAddInCaption False + Me.cmdLoadVbeAddIn.Enabled = False + SetLoadVbeAddInCaption False + + End With + + Me.labInfo.Caption = "AccUnit VBE Add-in has been unregistered" + Me.TimerInterval = ShowSuccessInfoTimerInterval + +ExitHere: + Exit Sub + +HandleErr: + ShowErrorHandlerInfo "cmdInstallVbeAddIn_Click" + Resume ExitHere + +End Sub + +Private Function OpenVbeInstallShortcutMenu() As Long + + Dim mnu As WinApiShortcutMenu + Dim SuccessMessage As String + Dim Installed As Boolean + +On Error GoTo HandleErr + + Set mnu = New WinApiShortcutMenu + + With mnu + Set .MenuControl = Me.cmdInstallVbeAddIn + Set .AccessForm = Me + .ControlSection = acDetail + + .AddMenuItem 1, "Install Add-In (Load on Startup)" + .AddMenuItem 2, "Install Add-In (don't load)" + + End With + + With New VbeAddInInstaller + Select Case mnu.OpenMenu + Case 1 + .RegisterAccUnitVbeAddIn CurrentAccUnitConfiguration.AccUnitDllPath, 3 + Installed = True + RunLoadAfterAddInInstalledTimer = True + Case 2 + .RegisterAccUnitVbeAddIn CurrentAccUnitConfiguration.AccUnitDllPath, 0 + Installed = True + Case Else + ' + End Select + End With + + SetInstallVbeAddInCaption Installed + If Installed Then + SuccessMessage = "AccUnit VBE Add-in installed" + Me.cmdLoadVbeAddIn.Enabled = True + Else + SuccessMessage = "Canceled" + End If + + Me.labInfo.Caption = SuccessMessage + If RunLoadAfterAddInInstalledTimer Then + Me.TimerInterval = 250 + Else + Me.TimerInterval = ShowSuccessInfoTimerInterval + End If + Set mnu = Nothing + +ExitHere: + Exit Function + +HandleErr: + ShowErrorHandlerInfo "OpenVbeInstallShortcutMenu" + Resume ExitHere + +End Function + +Private Sub LoadAddInAfterInstall() + VBE.Addins.Update + With New VbeAddInInstaller + .LoadAccUnitAddIn True + SetLoadVbeAddInCaption .AddInIsLoaded + End With + Me.TimerInterval = ShowSuccessInfoTimerInterval + + Me.labInfo.Caption = "AccUnit VBE Add-in has been unregistered" + Me.TimerInterval = ShowSuccessInfoTimerInterval + +End Sub + +Private Sub cmdLoadVbeAddIn_Click() + + Dim IsLoaded As Boolean + +On Error GoTo HandleErr + + VBE.Addins.Update + + With New VbeAddInInstaller + .LoadAccUnitAddIn Not .AddInIsLoaded + IsLoaded = .AddInIsLoaded + SetLoadVbeAddInCaption IsLoaded + End With + + If IsLoaded Then + Me.labInfo.Caption = "AccUnit VBE Add-in loaded" + Else + Me.labInfo.Caption = "AccUnit VBE Add-in unloaded" + End If + Me.TimerInterval = ShowSuccessInfoTimerInterval + +ExitHere: + Exit Sub + +HandleErr: + ShowErrorHandlerInfo "cmdLoadVbeAddIn_Click" + Resume ExitHere + +End Sub + +Private Sub SetInstallVbeAddInCaption(ByVal IsInstalled As Boolean) + + Dim ButtonCaption As String + Dim ButtonTag As String + + If IsInstalled Then + ButtonCaption = "Uninstall AccUnit VBE Add-in" + ButtonTag = "Installed" + Else + ButtonCaption = "Install AccUnit VBE Add-in" + ButtonTag = vbNullString + End If + + With Me.cmdInstallVbeAddIn + .Caption = ButtonCaption + .Tag = ButtonTag + End With + +End Sub + +Private Sub SetLoadVbeAddInCaption(ByVal IsLoaded As Boolean) + + Dim ButtonCaption As String + + If IsLoaded Then + ButtonCaption = "Unload AccUnit VBE Add-in" + Else + ButtonCaption = "Load AccUnit VBE Add-in" + End If + + Me.cmdLoadVbeAddIn.Caption = ButtonCaption + +End Sub + Private Sub cmdOpenMenu_Click() OpenImportFileShortcutMenu End Sub @@ -182,7 +350,7 @@ Private Sub cmdSetAccUnitTlbReferenz_Click() On Error GoTo HandleErr AddAccUnitTlbReference - Me.labInfo.Caption = "AccUnit.tlb reference inserted" + Me.labInfo.Caption = ACCUNIT_TYPELIB_FILE & " reference inserted" Me.TimerInterval = ShowSuccessInfoTimerInterval ExitHere: @@ -199,7 +367,7 @@ Private Sub cmdRemoveAccUnitTlbReferenz_Click() On Error GoTo HandleErr RemoveAccUnitTlbReference - Me.labInfo.Caption = "AccUnit.tlb reference removed" + Me.labInfo.Caption = ACCUNIT_TYPELIB_FILE & " reference removed" Me.TimerInterval = ShowSuccessInfoTimerInterval ExitHere: @@ -229,6 +397,14 @@ On Error GoTo ErrMissingPath Me.txtAccUnitDllPath.Value = .AccUnitDllPath End With + Dim VbeAddInIsInstalled As Boolean + With New VbeAddInInstaller + VbeAddInIsInstalled = .AddInIsInstalled + SetInstallVbeAddInCaption VbeAddInIsInstalled + Me.cmdLoadVbeAddIn.Enabled = VbeAddInIsInstalled + SetLoadVbeAddInCaption .AddInIsLoaded + End With + SetEnableMode Exit Sub @@ -252,6 +428,13 @@ Private Sub Form_Open(Cancel As Integer) End Sub Private Sub Form_Timer() + + If RunLoadAfterAddInInstalledTimer Then + RunLoadAfterAddInInstalledTimer = False + LoadAddInAfterInstall + Exit Sub + End If + Me.TimerInterval = 0 Me.labInfo.Caption = vbNullString End Sub diff --git a/access-add-in/source/modules/AccUnitLoaderConfigProcedures.bas b/access-add-in/source/modules/AccUnitLoaderConfigProcedures.bas index 9ac518e..5015c6d 100644 --- a/access-add-in/source/modules/AccUnitLoaderConfigProcedures.bas +++ b/access-add-in/source/modules/AccUnitLoaderConfigProcedures.bas @@ -14,7 +14,7 @@ End Property Public Sub AddAccUnitTlbReference() RemoveAccUnitTlbReference - modVbProject.CurrentVbProject.References.AddFromFile CurrentAccUnitConfiguration.AccUnitDllPath & "\AccessCodeLib.AccUnit.tlb" + modVbProject.CurrentVbProject.References.AddFromFile CurrentAccUnitConfiguration.AccUnitDllPath & "\" & ACCUNIT_TYPELIB_FILE End Sub Public Sub RemoveAccUnitTlbReference() @@ -145,7 +145,9 @@ Public Property Get AccUnitFileNames() As Variant() ACCUNIT_TYPELIB_FILE, _ ACCUNIT_DLL_FILE, _ "AccessCodeLib.Common.Tools.dll", _ - "AccessCodeLib.Common.VBIDETools.dll") + "AccessCodeLib.Common.VBIDETools.dll", _ + "AccessCodeLib.AccUnit.VbeAddIn.dll", _ + "AccessCodeLib.Common.VbeUserControlHost.dll") End Property @@ -168,7 +170,7 @@ ExitHere: Exit Sub HandleErr: - If AccUnitFileName = "AccessCodeLib.AccUnit.tlb" Then + If AccUnitFileName = ACCUNIT_TYPELIB_FILE Then Resume Next End If Err.Raise Err.Number, Err.Source, Err.Description, Err.HelpFile, Err.HelpContext diff --git a/access-add-in/source/modules/ApplicationHandler.cls b/access-add-in/source/modules/ApplicationHandler.cls index ceea911..6c664cf 100644 --- a/access-add-in/source/modules/ApplicationHandler.cls +++ b/access-add-in/source/modules/ApplicationHandler.cls @@ -65,10 +65,10 @@ Private Declare PtrSafe Function FindWindowEx Lib "user32.dll" Alias "FindWindow Private Declare PtrSafe Function CreateSolidBrush Lib "gdi32.dll" (ByVal CrColor As Long) As Long Private Declare PtrSafe Function SetClassLong Lib "user32" Alias "SetClassLongA" ( _ - ByVal Hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long + ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Private Declare PtrSafe Function RedrawWindow Lib "user32" ( _ - ByVal Hwnd As Long, LprcUpdate As Any, _ + ByVal hwnd As Long, LprcUpdate As Any, _ ByVal HrgnUpdate As Long, ByVal FuRedraw As Long) As Long Private Declare PtrSafe Function GetSysColor Lib "user32" (ByVal NumIndex As Long) As Long @@ -82,10 +82,10 @@ Private Declare Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" ( _ Private Declare Function CreateSolidBrush Lib "gdi32.dll" (ByVal CrColor As Long) As Long Private Declare Function SetClassLong Lib "user32" Alias "SetClassLongA" ( _ - ByVal Hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long + ByVal hwnd As Long, ByVal nIndex As Long, ByVal dwNewLong As Long) As Long Private Declare Function RedrawWindow Lib "user32" ( _ - ByVal Hwnd As Long, LprcUpdate As Any, _ + ByVal hwnd As Long, LprcUpdate As Any, _ ByVal HrgnUpdate As Long, ByVal FuRedraw As Long) As Long Private Declare Function GetSysColor Lib "user32" (ByVal Index As Long) As Long diff --git a/access-add-in/source/modules/DebugPrintTestResultReporter.cls b/access-add-in/source/modules/DebugPrintTestResultReporter.cls index 36ea3a7..6061c24 100644 --- a/access-add-in/source/modules/DebugPrintTestResultReporter.cls +++ b/access-add-in/source/modules/DebugPrintTestResultReporter.cls @@ -19,6 +19,8 @@ Option Explicit Implements AccUnit.ITestResultReporter +#Const ShowEventDebugLine = False + Private WithEvents m_TestResultCollector As AccUnit.TestResultCollector Attribute m_TestResultCollector.VB_VarHelpID = -1 @@ -31,18 +33,52 @@ Private Property Set ITestResultReporter_TestResultCollector(ByVal TestResultCol End Property Private Sub m_TestResultCollector_NewTestResult(ByVal Result As AccUnit.ITestResult) -' +#If ShowEventDebugLine Then + Debug.Print "m_TestResultCollector_NewTestResult" +#End If +End Sub ' + +Private Sub m_TestResultCollector_TestStarted(ByVal Test As AccUnit.ITest, ByVal IgnoreInfo As AccUnit.IgnoreInfo) +#If ShowEventDebugLine Then + Debug.Print "m_TestResultCollector_TestStarted", Test.FullName +#End If +End Sub + +Private Sub m_TestResultCollector_TestFinished(ByVal Result As AccUnit.ITestResult) +#If ShowEventDebugLine Then + Debug.Print "m_TestResultCollector_TestFinished" +#End If +End Sub + +Private Sub m_TestResultCollector_TestFixtureFinished(ByVal Result As AccUnit.ITestResult) +#If ShowEventDebugLine Then + Debug.Print "m_TestResultCollector_TestFixtureFinished" +#End If +End Sub + +Private Sub m_TestResultCollector_TestFixtureStarted(ByVal TestFixture As AccUnit.ITestFixture) +#If ShowEventDebugLine Then + Debug.Print "m_TestResultCollector_TestFixtureStarted" +#End If End Sub Private Sub m_TestResultCollector_TestSuiteFinished(ByVal Summary As AccUnit.ITestSummary) -' +#If ShowEventDebugLine Then + Debug.Print "m_TestResultCollector_TestSuiteFinished" +#End If +End Sub + +Private Sub m_TestResultCollector_TestSuiteReset(ByVal Summary As AccUnit.ITestSummary) + Debug.Print "m_TestResultCollector_TestSuiteReset" End Sub Private Sub m_TestResultCollector_TestSuiteStarted(ByVal TestSuite As AccUnit.ITestSuite) -' +#If ShowEventDebugLine Then + Debug.Print "m_TestResultCollector_TestSuiteStarted" +#End If End Sub -Private Sub m_TestResultCollector_TestTraceMessage(ByVal Message As String, ByVal CodeCoverageTracker As CodeCoverageTracker) +Private Sub m_TestResultCollector_TestTraceMessage(ByVal Message As String, ByVal CodeCoverageTracker As ICodeCoverageTracker) If Message Like "* [*][*][*]*" Then Message = Replace(Message, vbNewLine, vbTab) ElseIf Message Like "* ~~~*" Then diff --git a/access-add-in/source/modules/FileTools.bas b/access-add-in/source/modules/FileTools.bas index 9d6fa7b..8be8962 100644 --- a/access-add-in/source/modules/FileTools.bas +++ b/access-add-in/source/modules/FileTools.bas @@ -59,7 +59,7 @@ Private Declare PtrSafe Function API_GetTempFilename Lib "kernel32" Alias "GetTe ByVal lpTempFileName As String) As Long Private Declare PtrSafe Function API_ShellExecuteA Lib "shell32.dll" ( _ - ByVal Hwnd As LongPtr, _ + ByVal hwnd As LongPtr, _ ByVal lOperation As String, _ ByVal lpFile As String, _ ByVal lpParameters As String, _ @@ -82,7 +82,7 @@ Private Declare Function API_GetTempFilename Lib "kernel32" Alias "GetTempFileNa ByVal lpTempFileName As String) As Long Private Declare Function API_ShellExecuteA Lib "shell32.dll" ( _ - ByVal Hwnd As Long, _ + ByVal hwnd As Long, _ ByVal lOperation As String, _ ByVal lpFile As String, _ ByVal lpParameters As String, _ diff --git a/access-add-in/source/modules/LogFileTestResultReporter.cls b/access-add-in/source/modules/LogFileTestResultReporter.cls index ab20ee2..e6b11f6 100644 --- a/access-add-in/source/modules/LogFileTestResultReporter.cls +++ b/access-add-in/source/modules/LogFileTestResultReporter.cls @@ -41,6 +41,26 @@ Private Property Set TestResultCollector(ByVal TestResultCollectorToListen As Te Set m_TestResultCollector = TestResultCollectorToListen End Property +Private Sub m_TestResultCollector_TestFinished(ByVal Result As AccUnit.ITestResult) +' +End Sub + +Private Sub m_TestResultCollector_TestFixtureFinished(ByVal Result As AccUnit.ITestResult) +' +End Sub + +Private Sub m_TestResultCollector_TestFixtureStarted(ByVal TestFixture As AccUnit.ITestFixture) +' +End Sub + +Private Sub m_TestResultCollector_TestStarted(ByVal Test As AccUnit.ITest, ByVal IgnoreInfo As AccUnit.IgnoreInfo) +' +End Sub + +Private Sub m_TestResultCollector_TestSuiteReset(ByVal Summary As AccUnit.ITestSummary) +' +End Sub + Private Sub m_TestResultCollector_TestSuiteStarted(ByVal TestSuite As AccUnit.ITestSuite) PrintToFile String(LineSeperatorLen, "#") PrintToFile Format(Now(), "yyyy-mm-dd hh:nn:ss") @@ -88,7 +108,7 @@ Private Sub PrintSummary(ByVal TestSummary As AccUnit.ITestSummary, ByVal PrintT End Sub -Private Sub PrintTestDetailSummary(ByRef TestResults() As AccUnit.ITestResult) +Private Sub PrintTestDetailSummary(ByRef TestResults() As AccUnit.TestResult) Dim i As Long Dim r As Variant 'AccUnit.ITestResult diff --git a/access-add-in/source/modules/MsAccessVcsTestResultReporter.cls b/access-add-in/source/modules/MsAccessVcsTestResultReporter.cls index 263e67a..faa9109 100644 --- a/access-add-in/source/modules/MsAccessVcsTestResultReporter.cls +++ b/access-add-in/source/modules/MsAccessVcsTestResultReporter.cls @@ -42,6 +42,26 @@ Private Property Set TestResultCollector(ByVal TestResultCollectorToListen As Te Set m_TestResultCollector = TestResultCollectorToListen End Property +Private Sub m_TestResultCollector_TestFinished(ByVal Result As AccUnit.ITestResult) +' +End Sub + +Private Sub m_TestResultCollector_TestFixtureFinished(ByVal Result As AccUnit.ITestResult) +' +End Sub + +Private Sub m_TestResultCollector_TestFixtureStarted(ByVal TestFixture As AccUnit.ITestFixture) +' +End Sub + +Private Sub m_TestResultCollector_TestStarted(ByVal Test As AccUnit.ITest, ByVal IgnoreInfo As AccUnit.IgnoreInfo) +' +End Sub + +Private Sub m_TestResultCollector_TestSuiteReset(ByVal Summary As AccUnit.ITestSummary) +' +End Sub + Private Sub m_TestResultCollector_TestSuiteStarted(ByVal TestSuite As AccUnit.ITestSuite) PrintToFile String(LineSeperatorLen, "#") PrintToFile Format(Now(), "yyyy-mm-dd hh:nn:ss") diff --git a/access-add-in/source/modules/SqlTools.cls b/access-add-in/source/modules/SqlTools.cls index de347ff..2e80fdd 100644 --- a/access-add-in/source/modules/SqlTools.cls +++ b/access-add-in/source/modules/SqlTools.cls @@ -702,11 +702,11 @@ End Function Private Property Get DecimalMarker() As String Static DecChar As String - Dim X As String + Dim x As String If Len(DecChar) = 0 Then - X = Trim(CStr(1.2)) - DecChar = Mid(X, 2, 1) + x = Trim(CStr(1.2)) + DecChar = Mid(x, 2, 1) End If DecimalMarker = DecChar diff --git a/access-add-in/source/modules/TestSuite.cls b/access-add-in/source/modules/TestSuite.cls index 707e174..3c7a1d1 100644 --- a/access-add-in/source/modules/TestSuite.cls +++ b/access-add-in/source/modules/TestSuite.cls @@ -44,13 +44,15 @@ Public Property Set CodeCoverageTracker(ByVal NewRef As Object) Set m_CodeCoverageTracker = NewRef End Property -'#################################### -' AccessTestSuite event handler -' Private Sub m_TestSuite_TestSuiteStarted(ByVal TestSuite As AccUnit.ITestSuite) ' End Sub +'#################################### +' AccessTestSuite event handler +' + + Private Sub m_TestSuite_TestTraceMessage(ByVal Message As String, ByVal CodeCoverageTracker As AccUnit.ICodeCoverageTracker) ' End Sub diff --git a/access-add-in/source/modules/VbeAddInInstaller.cls b/access-add-in/source/modules/VbeAddInInstaller.cls new file mode 100644 index 0000000..82b9f4d --- /dev/null +++ b/access-add-in/source/modules/VbeAddInInstaller.cls @@ -0,0 +1,287 @@ +VERSION 1.0 CLASS +BEGIN + MultiUse = -1 'True +END +Attribute VB_Name = "VbeAddInInstaller" +Attribute VB_GlobalNameSpace = False +Attribute VB_Creatable = False +Attribute VB_PredeclaredId = False +Attribute VB_Exposed = False +Option Compare Database +Option Explicit + +Private Declare PtrSafe Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" ( _ + ByVal hwnd As LongPtr, _ + ByVal lpOperation As String, _ + ByVal lpFile As String, _ + ByVal lpParameters As String, _ + ByVal lpDirectory As String, _ + ByVal nShowCmd As Long) As Long + +Private Const SW_HIDE = 0 + +Private Const AddInProgId As String = "AccUnit.VbeAddIn.Connect" +Private Const AddInClassGuid As String = "{F15F18C3-CA43-421E-9585-6A04F51C5786}" + +Private Const VbeUserControlHostProgId As String = "AccLib.VbeUserControlHost" +Private Const VbeUserControlHostClassGuid As String = "{030A1F2F-4E0B-4041-A7F5-C4C0B94BAF07}" + +Public Enum VbeAddInLoadBehavior + LoadBehavior_Disabled = 0 + LoadBehavior_LoadOnStartup = 1 + LoadBehavior_Loaded = 2 +End Enum + +Public Sub RegisterAccUnitVbeAddIn(ByVal DllPath As String, ByVal LoadBehavior As Long) + + Const FullClassName As String = "AccessCodeLib.AccUnit.VbeAddIn.Connect" + Const AssemblyName As String = "AccUnit.VbeAddIn" + Const TargetRuntimeVersion As String = "v4.0.30319" + Const AssemblyFile As String = AssemblyName & ".dll" + Const AddInFriendlyName As String = "AccUnit VBE Add-in" + Const AddInDescription As String = "VBE Add-in for AccUnit Framework" + +#If Win64 Then + Const Bitness As Long = 64 + Const AddInsFolder As String = "Addins64" +#Else + Const Bitness As Long = 32 + Const AddInsFolder As String = "Addins" +#End If + + Dim AssemblyVersion As String + With New ApplicationHandler_AppFile + AssemblyVersion = .GetStoredAppFileVersion("AccUnit.VbeAddIn.dll") + End With + + If Right(DllPath, 1) <> "\" Then + DllPath = DllPath & "\" + End If + +' Add-in COM dll + RegisterNetComDll FullClassName, AddInClassGuid, AddInProgId, _ + AssemblyName, DllPath & AssemblyFile, AssemblyVersion, Bitness, _ + TargetRuntimeVersion + +' Host + RegisterVbeUserControlHost DllPath, Bitness + +' VBE Add-in + RegisterVbeAddIn AddInProgId, LoadBehavior, AddInFriendlyName, AddInDescription + +End Sub + +Private Sub RegisterVbeUserControlHost(ByVal DllPath As String, ByVal Bitness As Long) + + Const FullClassName As String = "AccessCodeLib.Common.VBIDETools.VbeUserControlHost" + Const AssemblyName As String = "AccessCodeLib.Common.VbeUserControlHost" + Const TargetRuntimeVersion As String = "v4.0.30319" + Const AssemblyFile As String = AssemblyName & ".dll" + + Dim AssemblyVersion As String + With New ApplicationHandler_AppFile + AssemblyVersion = .GetStoredAppFileVersion("AccessCodeLib.Common.VbeUserControlHost.dll") + End With + +' COM dll + RegisterNetComDll FullClassName, VbeUserControlHostClassGuid, VbeUserControlHostProgId, _ + AssemblyName, DllPath & AssemblyFile, AssemblyVersion, Bitness, _ + TargetRuntimeVersion + +End Sub + +Private Sub RegisterVbeAddIn(ByVal ProgId As String, _ + ByVal LoadBehavior As Long, ByVal FriendlyName As String, ByVal Description As String) + +#If Win64 Then + Const AddInsFolder As String = "Addins64" +#Else + Const AddInsFolder As String = "Addins" +#End If + + AddRegItem "HKCU\Software\Microsoft\VBA\VBE\6.0\" & AddInsFolder & "\" & ProgId, "LoadBehavior", "REG_DWORD", "0x0000000" & LoadBehavior + AddRegItem "HKCU\Software\Microsoft\VBA\VBE\6.0\" & AddInsFolder & "\" & ProgId, "FriendlyName", "REG_SZ", FriendlyName + AddRegItem "HKCU\Software\Microsoft\VBA\VBE\6.0\" & AddInsFolder & "\" & ProgId, "Description", "REG_SZ", Description + + +'%windir%\system32\REG ADD "HKCU\Software\Microsoft\VBA\VBE\6.0\%AddInsFolder%\%ProgId%" /v "LoadBehavior" /t REG_DWORD /d "0x00000003" /f +'%windir%\system32\REG ADD "HKCU\Software\Microsoft\VBA\VBE\6.0\%AddInsFolder%\%ProgId%" /v "FriendlyName" /t REG_SZ /d "AccUnit VBE Add-in" /f +'%windir%\system32\REG ADD "HKCU\Software\Microsoft\VBA\VBE\6.0\%AddInsFolder%\%ProgId%" /v "Description" /t REG_SZ /d "AccUnit VBE Add-in" /f + +End Sub + +Private Sub RegisterNetComDll(ByVal FullClassName As String, ByVal ClassGuid As String, ByVal ProgId As String, _ + ByVal AssemblyName As String, ByVal AssemblyPath As String, ByVal AssemblyVersion As String, ByVal Bitness As Long, _ + ByVal TargetRuntimeVersion As String) + + AddRegItem "HKCU\Software\Classes\" & ProgId, vbNullString, "REG_SZ", FullClassName + AddRegItem "HKCU\Software\Classes\" & ProgId & "\CLSID", vbNullString, "REG_SZ", ClassGuid + AddRegItem "HKCU\Software\Classes\CLSID\" & ClassGuid, vbNullString, "REG_SZ", FullClassName, Bitness + AddRegItem "HKCU\Software\Classes\CLSID\" & ClassGuid & "\ProgId", vbNullString, "REG_SZ", ProgId, Bitness + AddRegItem "HKCU\Software\Classes\CLSID\" & ClassGuid & "\InprocServer32", vbNullString, "REG_SZ", "mscoree.dll", Bitness + AddRegItem "HKCU\Software\Classes\CLSID\" & ClassGuid & "\InprocServer32", "ThreadingModel", "REG_SZ", "Both", Bitness + AddRegItem "HKCU\Software\Classes\CLSID\" & ClassGuid & "\InprocServer32", "Class", "REG_SZ", FullClassName, Bitness + AddRegItem "HKCU\Software\Classes\CLSID\" & ClassGuid & "\InprocServer32", "Assembly", "REG_SZ", AssemblyName & ", Version=" & AssemblyVersion & ", Culture=neutral, PublicKeyToken=null", Bitness + AddRegItem "HKCU\Software\Classes\CLSID\" & ClassGuid & "\InprocServer32", "RuntimeVersion", "REG_SZ", TargetRuntimeVersion, Bitness + AddRegItem "HKCU\Software\Classes\CLSID\" & ClassGuid & "\InprocServer32", "CodeBase", "REG_SZ", "file:///" & Replace(AssemblyPath, "\", "/"), Bitness + +End Sub + +Private Sub AddRegItem(ByVal RegPath As String, _ + ByVal RegValue As String, ByVal RegDataType As String, ByVal RegData As String, _ + Optional ByVal Bitness As Long = 0) + + Const ParamStringTemplate As String = "ADD ""{RegPath}"" /v ""{RegValue}"" /t {RegDataType} /d ""{RegData}"" /reg:{Bitness} /f" + + Dim ParamString As String + + ParamString = ParamStringTemplate + ParamString = Replace(ParamString, "{RegPath}", RegPath) + + If Len(RegValue) = 0 Then + ParamString = Replace(ParamString, "/v ""{RegValue}""", "/ve") + Else + ParamString = Replace(ParamString, "{RegValue}", RegValue) + End If + + ParamString = Replace(ParamString, "{RegDataType}", RegDataType) + ParamString = Replace(ParamString, "{RegData}", RegData) + + If Bitness = 0 Then + ParamString = Replace(ParamString, "/reg:{Bitness} ", vbNullString) + Else + ParamString = Replace(ParamString, "{Bitness}", Bitness) + End If + + RunRegExe ParamString + +End Sub + +Private Sub RunRegExe(ByVal Params As String) + + Dim RegExeFilePath As String + RegExeFilePath = Environ("windir") & "\System32\REG.exe" + ShellExecute Application.hWndAccessApp, "open", RegExeFilePath, Params, vbNullString, SW_HIDE + +End Sub + +Public Sub UnRegisterAccUnitVbeAddIn() + +#If Win64 Then + Const Bitness As Long = 64 + Const AddInsFolder As String = "Addins64" +#Else + Const Bitness As Long = 32 + Const AddInsFolder As String = "Addins" +#End If + + If Me.AddInIsInstalled Then + Me.LoadAccUnitAddIn False + End If + + UnRegisterVbeAddIn AddInProgId, Bitness + UnRegisterComDll AddInClassGuid, AddInProgId, Bitness + UnRegisterComDll VbeUserControlHostClassGuid, VbeUserControlHostProgId, Bitness + +End Sub + +Private Sub UnRegisterComDll(ByVal ClassGuid As String, ByVal ProgId As String, Bitness As Long) + + DelRegItem "HKCU\Software\Classes\" & ProgId + DelRegItem "HKCU\Software\Classes\CLSID\" & ClassGuid, Bitness + +End Sub + +Private Sub UnRegisterVbeAddIn(ByVal ProgId As String, Bitness As Long) + + Dim AddInsFolder As String + + If Bitness = 64 Then + AddInsFolder = "Addins64" + Else + AddInsFolder = "Addins" + End If + + DelRegItem "HKCU\Software\Microsoft\VBA\VBE\6.0\" & AddInsFolder & "\" & ProgId + +End Sub + +Private Sub DelRegItem(ByVal RegPath As String, _ + Optional ByVal Bitness As Long = 0) + + Const ParamStringTemplate As String = "DELETE ""{RegPath}"" /reg:{Bitness} /f" + + Dim ParamString As String + + ParamString = ParamStringTemplate + ParamString = Replace(ParamString, "{RegPath}", RegPath) + + If Bitness = 0 Then + ParamString = Replace(ParamString, "/reg:{Bitness} ", vbNullString) + Else + ParamString = Replace(ParamString, "{Bitness}", Bitness) + End If + + RunRegExe ParamString + +End Sub + + +Public Property Get AddInIsInstalled() As Boolean + AddInIsInstalled = FindAccUnitAddIn() +End Property + +Public Property Get AddInIsLoaded() As Boolean + + Dim VbeAddIn As VBIDE.AddIn + + If Not FindAccUnitAddIn(VbeAddIn) Then + AddInIsLoaded = False + Exit Property + End If + + AddInIsLoaded = VbeAddIn.Connect + +End Property + +Public Sub LoadAccUnitAddIn(ByVal LoadAddIn As Boolean) + + Dim VbeAddIn As VBIDE.AddIn + + If Not FindAccUnitAddIn(VbeAddIn) Then + Exit Sub + End If + + If LoadAddIn Then + SetFocusToImmediateWindow + End If + + VbeAddIn.Connect = LoadAddIn + +End Sub + +Private Sub SetFocusToImmediateWindow() + Dim VbeWin As VBIDE.Window + For Each VbeWin In Application.VBE.Windows + If VbeWin.Type = VBIDE.vbext_WindowType.vbext_wt_Immediate Then + If Not VbeWin.Visible Then + VbeWin.Visible = True + End If + VbeWin.SetFocus + Exit Sub + End If + Next +End Sub + +Private Function FindAccUnitAddIn(Optional ByRef AddInRef As VBIDE.AddIn) As Boolean + + Dim VbeAddIn As VBIDE.AddIn + + For Each VbeAddIn In VBE.Addins + If VbeAddIn.ProgId = AddInProgId Then + Set AddInRef = VbeAddIn + FindAccUnitAddIn = True + End If + Next + +End Function diff --git a/access-add-in/source/modules/WinApiImageTools.cls b/access-add-in/source/modules/WinApiImageTools.cls index 813645c..d384c88 100644 --- a/access-add-in/source/modules/WinApiImageTools.cls +++ b/access-add-in/source/modules/WinApiImageTools.cls @@ -37,7 +37,7 @@ Private Const LR_LOADFROMFILE As Long = &H10 #If VBA7 Then Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" ( _ - ByVal Hwnd As Long, _ + ByVal hwnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ lParam As Any) As Long @@ -53,7 +53,7 @@ Private Declare PtrSafe Function LoadImage Lib "user32" Alias "LoadImageA" ( _ #Else Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" ( _ - ByVal Hwnd As Long, _ + ByVal hwnd As Long, _ ByVal wMsg As Long, _ ByVal wParam As Long, _ lParam As Any) As Long @@ -90,7 +90,7 @@ On Error Resume Next ' ... Error message would only interfere with this "unimpor ImageHandle = LoadImage(0, IconFilePath, IMAGE_ICON, _ ICONPIXELSIZE, ICONPIXELSIZE, LR_LOADFROMFILE) If ImageHandle <> 0 Then - SendMessage FormRef.Hwnd, WM_MSG_SETICON, WM_PARAM_ICON_SMALL, ByVal ImageHandle + SendMessage FormRef.hwnd, WM_MSG_SETICON, WM_PARAM_ICON_SMALL, ByVal ImageHandle End If End Sub diff --git a/access-add-in/source/modules/WinApiLayoutTools.cls b/access-add-in/source/modules/WinApiLayoutTools.cls index 3647fdb..f93cd34 100644 --- a/access-add-in/source/modules/WinApiLayoutTools.cls +++ b/access-add-in/source/modules/WinApiLayoutTools.cls @@ -47,7 +47,7 @@ Private Declare PtrSafe Function CreateSolidBrush _ Private Declare PtrSafe Function RedrawWindow _ Lib "user32" ( _ - ByVal Hwnd As LongPtr, _ + ByVal hwnd As LongPtr, _ LprcUpdate As Any, _ ByVal HrgnUpdate As Long, _ ByVal FuRedraw As Long _ @@ -56,15 +56,15 @@ Private Declare PtrSafe Function RedrawWindow _ Private Declare PtrSafe Function SetClassLong _ Lib "user32.dll" _ Alias "SetClassLongA" ( _ - ByVal Hwnd As LongPtr, _ + ByVal hwnd As LongPtr, _ ByVal nIndex As Long, _ ByVal dwNewLong As LongPtr _ ) As Long Private Declare PtrSafe Function GetSystemMetrics Lib "user32" (ByVal Index As Long) As Long -Private Declare PtrSafe Function GetDC Lib "user32" (ByVal Hwnd As LongPtr) As LongPtr -Private Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal Hwnd As LongPtr, ByVal DC As LongPtr) As Long +Private Declare PtrSafe Function GetDC Lib "user32" (ByVal hwnd As LongPtr) As LongPtr +Private Declare PtrSafe Function ReleaseDC Lib "user32" (ByVal hwnd As LongPtr, ByVal DC As LongPtr) As Long Private Declare PtrSafe Function GetDeviceCaps Lib "gdi32" (ByVal DC As LongPtr, ByVal Index As Long) As LongPtr #Else @@ -76,7 +76,7 @@ Private Declare Function CreateSolidBrush _ Private Declare Function RedrawWindow _ Lib "user32" ( _ - ByVal Hwnd As Long, _ + ByVal hwnd As Long, _ LprcUpdate As Any, _ ByVal HrgnUpdate As Long, _ ByVal FuRedraw As Long _ @@ -85,15 +85,15 @@ Private Declare Function RedrawWindow _ Private Declare Function SetClassLong _ Lib "user32.dll" _ Alias "SetClassLongA" ( _ - ByVal Hwnd As Long, _ + ByVal hwnd As Long, _ ByVal nIndex As Long, _ ByVal dwNewLong As Long _ ) As Long Private Declare Function GetSystemMetrics Lib "user32" (ByVal Index As Long) As Long -Private Declare Function GetDC Lib "user32" (ByVal Hwnd As Long) As Long -Private Declare Function ReleaseDC Lib "user32" (ByVal Hwnd As Long, ByVal DC As Long) As Long +Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long +Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal DC As Long) As Long Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal DC As Long, ByVal Index As Long) As Long #End If @@ -109,16 +109,16 @@ Private Declare Function GetDeviceCaps Lib "gdi32" (ByVal DC As Long, ByVal Inde ' Color - Color number ' '--------------------------------------------------------------------------------------- -Public Sub SetBackColor(ByVal Hwnd As LongPtr, ByVal Color As Long) +Public Sub SetBackColor(ByVal hwnd As LongPtr, ByVal Color As Long) Dim NewBrush As LongPtr 'Create Brush NewBrush = CreateSolidBrush(Color) 'Assign Brush - SetClassLong Hwnd, GCL_HBRBACKGROUND, NewBrush + SetClassLong hwnd, GCL_HBRBACKGROUND, NewBrush 'Redraw window (entire window incl. background) - RedrawWindow Hwnd, ByVal 0&, ByVal 0&, RDW_INVALIDATE Or RDW_ERASE + RedrawWindow hwnd, ByVal 0&, ByVal 0&, RDW_INVALIDATE Or RDW_ERASE End Sub diff --git a/access-add-in/source/modules/WinApiShellTools.cls b/access-add-in/source/modules/WinApiShellTools.cls index 4efabcd..d9c7b9f 100644 --- a/access-add-in/source/modules/WinApiShellTools.cls +++ b/access-add-in/source/modules/WinApiShellTools.cls @@ -67,14 +67,14 @@ Private Const WAIT_TIMEOUT As Long = &H102& #If VBA7 Then Private Declare PtrSafe Function ShellExecuteA Lib "shell32.dll" ( _ - ByVal Hwnd As Long, _ + ByVal hwnd As LongPtr, _ ByVal lOperation As String, _ ByVal lpFile As String, _ ByVal lpParameters As String, _ ByVal lpDirectory As String, _ ByVal nShowCmd As Long) As Long -Private Declare PtrSafe Function GetDesktopWindow Lib "user32" () As Long +Private Declare PtrSafe Function GetDesktopWindow Lib "user32" () As LongPtr Private Declare PtrSafe Function GetSystemDirectory Lib "kernel32" Alias "GetSystemDirectoryA" ( _ ByVal lpBuffer As String, _ @@ -96,7 +96,7 @@ Private Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal DwMilliseconds As Long) #Else Private Declare Function ShellExecuteA Lib "shell32.dll" ( _ - ByVal Hwnd As Long, _ + ByVal hwnd As Long, _ ByVal lOperation As String, _ ByVal lpFile As String, _ ByVal lpParameters As String, _ diff --git a/access-add-in/source/modules/WinApiShortcutMenu.cls b/access-add-in/source/modules/WinApiShortcutMenu.cls index 6e1963a..007b0d2 100644 --- a/access-add-in/source/modules/WinApiShortcutMenu.cls +++ b/access-add-in/source/modules/WinApiShortcutMenu.cls @@ -39,7 +39,7 @@ Option Compare Text Option Explicit Private Type POINTAPI - X As Long + x As Long Y As Long End Type @@ -55,7 +55,7 @@ End Type Private m_Helper As LongPtr 'Auxiliary window handle Private Type APIMSG - Hwnd As LongPtr + hwnd As LongPtr Message As LongPtr wParam As Long lParam As Long @@ -71,7 +71,7 @@ Private Declare PtrSafe Function CreateWindowEx _ ByVal lpClassname As String, _ ByVal lpWindowName As String, _ ByVal dwStyle As Long, _ - ByVal X As Long, _ + ByVal x As Long, _ ByVal Y As Long, _ ByVal nWidth As Long, _ ByVal nHeight As Long, _ @@ -97,10 +97,10 @@ Private Declare PtrSafe Function TrackPopupMenu _ Lib "user32.dll" ( _ ByVal hMenu As LongPtr, _ ByVal wFlags As Long, _ - ByVal X As Long, _ + ByVal x As Long, _ ByVal Y As Long, _ ByVal nReserved As Long, _ - ByVal Hwnd As LongPtr, _ + ByVal hwnd As LongPtr, _ lprc As Any _ ) As LongPtr 'lprc As RECT @@ -114,7 +114,7 @@ Private Declare PtrSafe Function GetMessage _ Lib "user32.dll" _ Alias "GetMessageA" ( _ ByRef lpMsg As APIMSG, _ - ByVal Hwnd As LongPtr, _ + ByVal hwnd As LongPtr, _ ByVal wMsgFilterMin As Long, _ ByVal wMsgFilterMax As Long _ ) As Long @@ -130,7 +130,7 @@ Private Declare PtrSafe Function TranslateMessage _ Private Declare PtrSafe Function GetWindowRect _ Lib "user32.dll" ( _ - ByVal Hwnd As LongPtr, _ + ByVal hwnd As LongPtr, _ ByRef lpRect As RECT _ ) As LongPtr @@ -146,7 +146,7 @@ Private Declare PtrSafe Function SetMenuDefaultItem _ Private m_Helper As Long 'Auxiliary window handle Private Type APIMSG - Hwnd As Long + hwnd As Long Message As Long wParam As Long lParam As Long @@ -162,7 +162,7 @@ Private Declare Function CreateWindowEx _ ByVal lpClassname As String, _ ByVal lpWindowName As String, _ ByVal dwStyle As Long, _ - ByVal X As Long, _ + ByVal x As Long, _ ByVal Y As Long, _ ByVal nWidth As Long, _ ByVal nHeight As Long, _ @@ -188,10 +188,10 @@ Private Declare Function TrackPopupMenu _ Lib "user32.dll" ( _ ByVal hMenu As Long, _ ByVal wFlags As Long, _ - ByVal X As Long, _ + ByVal x As Long, _ ByVal Y As Long, _ ByVal nReserved As Long, _ - ByVal Hwnd As Long, _ + ByVal hwnd As Long, _ lprc As Any _ ) As Long 'lprc As RECT @@ -205,7 +205,7 @@ Private Declare Function GetMessage _ Lib "user32.dll" _ Alias "GetMessageA" ( _ ByRef lpMsg As APIMSG, _ - ByVal Hwnd As Long, _ + ByVal hwnd As Long, _ ByVal wMsgFilterMin As Long, _ ByVal wMsgFilterMax As Long _ ) As Long @@ -221,7 +221,7 @@ Private Declare Function TranslateMessage _ Private Declare Function GetWindowRect _ Lib "user32.dll" ( _ - ByVal Hwnd As Long, _ + ByVal hwnd As Long, _ ByRef lpRect As RECT _ ) As Long @@ -337,13 +337,13 @@ Public Property Set MenuControl(ByRef MnuCtl As Access.Control) Select Case m_Section Case 0 'Detailbereich - lngSectionHwnd = WindowTools.GetDetailSection(ParentObj.Hwnd) + lngSectionHwnd = WindowTools.GetDetailSection(ParentObj.hwnd) Case 1 'Kopf - lngSectionHwnd = WindowTools.GetHeaderSection(ParentObj.Hwnd) + lngSectionHwnd = WindowTools.GetHeaderSection(ParentObj.hwnd) Case 2 ' Fuß - lngSectionHwnd = WindowTools.GetFooterSection(ParentObj.Hwnd) + lngSectionHwnd = WindowTools.GetFooterSection(ParentObj.hwnd) Case Else - lngSectionHwnd = WindowTools.GetDetailSection(ParentObj.Hwnd) + lngSectionHwnd = WindowTools.GetDetailSection(ParentObj.hwnd) End Select Set ParentObj = Nothing @@ -419,16 +419,16 @@ End Sub ' Long - Number of the selected menu item ' '--------------------------------------------------------------------------------------- -Public Function OpenMenu(Optional ByVal X As Single = 0, Optional ByVal Y As Single = 0) As Long +Public Function OpenMenu(Optional ByVal x As Single = 0, Optional ByVal Y As Single = 0) As Long #If VBA7 Then Dim MenuHwnd As LongPtr Dim TmpHwnd As LongPtr - Dim Hwnd As LongPtr + Dim hwnd As LongPtr #Else Dim MenuHwnd As Long Dim TmpHwnd As Long - Dim Hwnd As Long + Dim hwnd As Long #End If Dim Message As APIMSG @@ -477,12 +477,12 @@ Public Function OpenMenu(Optional ByVal X As Single = 0, Optional ByVal Y As Sin GetWindowRect m_Helper, RcHelper If m_MenuControl Is Nothing Then - GetWindowRect m_AccessForm.Hwnd, AccFormRect - ButtonLeft = LayoutTools.GetPixelFromTwips(X) + AccFormRect.Left + GetWindowRect m_AccessForm.hwnd, AccFormRect + ButtonLeft = LayoutTools.GetPixelFromTwips(x) + AccFormRect.Left ButtonTop = LayoutTools.GetPixelFromTwips(Y) + AccFormRect.Top Else '- Buttom relative to the section window - ButtonLeft = LayoutTools.GetPixelFromTwips(m_MenuControl.Left) + LayoutTools.GetPixelFromTwips(X) + ButtonLeft = LayoutTools.GetPixelFromTwips(m_MenuControl.Left) + LayoutTools.GetPixelFromTwips(x) ButtonTop = LayoutTools.GetPixelFromTwips(m_MenuControl.Top) + LayoutTools.GetPixelFromTwips(Y) End If '- calc with each other @@ -501,20 +501,20 @@ Public Function OpenMenu(Optional ByVal X As Single = 0, Optional ByVal Y As Sin End If TrackPopupMenu MenuHwnd, TPM_BOTTOMALIGN, XPos, YPos, _ - ByVal 0&, ParentObj.Hwnd, ByVal 0& + ByVal 0&, ParentObj.hwnd, ByVal 0& 'Message-Loop (Attention: for normal forms Application.hWndAccessApp, for POPUPS Form.Hwnd) If m_AccessForm.PopUp = True Then - Hwnd = m_AccessForm.Hwnd + hwnd = m_AccessForm.hwnd Else - Hwnd = Application.hWndAccessApp + hwnd = Application.hWndAccessApp End If Dim RepeatGetMessage As Boolean Do ' Security sleep in case there are problems with windows message. (WM_MOUSELEAVE] RepeatGetMessage = False - GetMessage Message, Hwnd, ByVal 0&, ByVal 0& + GetMessage Message, hwnd, ByVal 0&, ByVal 0& TranslateMessage Message DispatchMessage Message diff --git a/access-add-in/source/modules/WinApiWindowTools.cls b/access-add-in/source/modules/WinApiWindowTools.cls index ef1e5cc..a81ca9b 100644 --- a/access-add-in/source/modules/WinApiWindowTools.cls +++ b/access-add-in/source/modules/WinApiWindowTools.cls @@ -35,12 +35,12 @@ Option Compare Text Option Explicit Private Type POINTAPI - X As Long + x As Long Y As Long End Type Private Declare PtrSafe Function ClientToScreen Lib "user32.dll" ( _ - ByVal Hwnd As LongPtr, _ + ByVal hwnd As LongPtr, _ ByRef lpPoint As POINTAPI _ ) As Long @@ -81,10 +81,10 @@ End Function ' LongPtr ' '--------------------------------------------------------------------------------------- -Public Function GetHeaderSection(ByVal Hwnd As LongPtr) As LongPtr +Public Function GetHeaderSection(ByVal hwnd As LongPtr) As LongPtr Dim h As LongPtr 'Determine first "OFormsub" child window of the form (fhwnd) - h = FindWindowEx(Hwnd, 0&, "OformSub", vbNullString) + h = FindWindowEx(hwnd, 0&, "OformSub", vbNullString) GetHeaderSection = h End Function @@ -101,11 +101,11 @@ End Function ' LongPtr ' '--------------------------------------------------------------------------------------- -Public Function GetDetailSection(ByVal Hwnd As LongPtr) As LongPtr +Public Function GetDetailSection(ByVal hwnd As LongPtr) As LongPtr Dim h As LongPtr 'Determine first "OFormsub" child window of the form (fhwnd), starting after the header area. - h = GetHeaderSection(Hwnd) - h = FindWindowEx(Hwnd, h, "OformSub", vbNullString) + h = GetHeaderSection(hwnd) + h = FindWindowEx(hwnd, h, "OformSub", vbNullString) GetDetailSection = h End Function @@ -122,11 +122,11 @@ End Function ' LongPtr ' '--------------------------------------------------------------------------------------- -Public Function GetFooterSection(ByVal Hwnd As Long) As LongPtr +Public Function GetFooterSection(ByVal hwnd As Long) As LongPtr Dim h As LongPtr 'Determine first "OFormsub" child window of the form (fhwnd), starting after the detail area. - h = GetDetailSection(Hwnd) - h = FindWindowEx(Hwnd, h, "OformSub", vbNullString) + h = GetDetailSection(hwnd) + h = FindWindowEx(hwnd, h, "OformSub", vbNullString) GetFooterSection = h End Function @@ -146,7 +146,7 @@ End Function ' LongPtr ' '--------------------------------------------------------------------------------------- -Public Function GetControl(ByRef FormRef As Access.Form, ByVal Hwnd As LongPtr, _ +Public Function GetControl(ByRef FormRef As Access.Form, ByVal hwnd As LongPtr, _ ByVal ClassName As String, ByVal ControlName As String) As LongPtr 'Exitieren mehrere Controls der gleichen Klasse auf einem Formular, z.B. TabControls, besteht das Problem, daß @@ -170,16 +170,16 @@ On Error Resume Next Do 'Erstes (h=0)/nächstes (h<>0) Control auf dem Sektionsfenster ermitteln - h = FindWindowEx(Hwnd, h, ClassName, vbNullString) + h = FindWindowEx(hwnd, h, ClassName, vbNullString) 'Bildschirmkoordinaten dieses Controls ermitteln 'dafür die Punktkoordinaten aus dem letzten Durchlauf zurücksetzen, sonst wird addiert! - pt.X = 0 + pt.x = 0 pt.Y = 0 ClientToScreen h, pt 'Objekt bei den Koordinaten ermitteln - Set obj = FormRef.accHitTest(pt.X, pt.Y) + Set obj = FormRef.accHitTest(pt.x, pt.Y) 'Wenn Objektname = Tabname Ausstieg aus der Schleife If obj.Name = ControlName Then diff --git a/access-add-in/source/modules/_config_Application.bas b/access-add-in/source/modules/_config_Application.bas index ea05b46..9f5eace 100644 --- a/access-add-in/source/modules/_config_Application.bas +++ b/access-add-in/source/modules/_config_Application.bas @@ -18,14 +18,14 @@ Option Compare Text Option Explicit 'Version number -Private Const APPLICATION_VERSION As String = "0.9.700.240403" +Private Const APPLICATION_VERSION As String = "0.9.800.240509" Private Const APPLICATION_NAME As String = "ACLib AccUnit Loader" Private Const APPLICATION_FULLNAME As String = "Access Code Library - AccUnit Loader" Private Const APPLICATION_TITLE As String = APPLICATION_FULLNAME Private Const APPLICATION_ICONFILE As String = "ACLib.ico" -Public Const ACCUNIT_TYPELIB_FILE As String = "AccessCodeLib.AccUnit.tlb" -Public Const ACCUNIT_DLL_FILE As String = "AccessCodeLib.AccUnit.dll" +Public Const ACCUNIT_TYPELIB_FILE As String = "AccUnit.tlb" +Public Const ACCUNIT_DLL_FILE As String = "AccUnit.dll" Private Const APPLICATION_STARTFORMNAME As String = "AccUnitLoaderForm" diff --git a/access-add-in/source/modules/modTypeLibCheck.bas b/access-add-in/source/modules/modTypeLibCheck.bas index 34bd6f2..ac7dda6 100644 --- a/access-add-in/source/modules/modTypeLibCheck.bas +++ b/access-add-in/source/modules/modTypeLibCheck.bas @@ -57,9 +57,9 @@ On Error Resume Next CheckMissingReference VBProjectRef, ReferenceFixed ReferenceFixed = ReferenceFixed Or FileFixed - If Len(ReferenceFixedMessage) > 0 Then - If Left(ReferenceFixedMessage, 2) = vbNewLine Then - ReferenceFixedMessage = Mid(ReferenceFixedMessage, 3) + If VBA.Len(ReferenceFixedMessage) > 0 Then + If VBA.Left$(ReferenceFixedMessage, 2) = VBA.vbNewLine Then + ReferenceFixedMessage = VBA.Mid$(ReferenceFixedMessage, 3) End If End If diff --git a/access-add-in/source/modules/modVbProject.bas b/access-add-in/source/modules/modVbProject.bas index 942c8ee..f94a57a 100644 --- a/access-add-in/source/modules/modVbProject.bas +++ b/access-add-in/source/modules/modVbProject.bas @@ -21,7 +21,7 @@ Option Compare Text Option Explicit Option Private Module -#Const EARLYBINDING = 0 +#Const EARLYBINDING = 1 Private m_CurrentVbProject As Object diff --git a/access-add-in/source/tbldefs/USys_AppFiles.xml b/access-add-in/source/tbldefs/USys_AppFiles.xml index afc18b6..7f07df2 100644 --- a/access-add-in/source/tbldefs/USys_AppFiles.xml +++ b/access-add-in/source/tbldefs/USys_AppFiles.xml @@ -38,7 +38,7 @@ - + @@ -74,6 +74,7 @@ + diff --git a/binaries/VBE-Add-in/Register_HKCU.cmd b/binaries/VBE-Add-in/Register_HKCU.cmd new file mode 100644 index 0000000..309594f --- /dev/null +++ b/binaries/VBE-Add-in/Register_HKCU.cmd @@ -0,0 +1,159 @@ +@ECHO OFF +setlocal enabledelayedexpansion + +:: ################################################################### +:: Config ClassGuit, ProgId, ... +:: ------------------------------------------------------------------- + +SET TargetRuntimeVersion=v4.0.30319 + +:: ------------------------------------------------------------------- +:: VBE Add-in: +:: ----------- + +SET AddInAssemblyName=AccUnit.VbeAddIn +SET AddInAssemblyFile=%AddInAssemblyName%.dll + +SET AddInClassGuid=F15F18C3-CA43-421E-9585-6A04F51C5786 +SET AddInProgId=AccUnit.VbeAddIn.Connect +SET AddInFullClassName=AccessCodeLib.AccUnit.VbeAddIn.Connect +SET AddInProgVersion=0.2 + +:: ------------------------------------------------------------------- +:: VBE ControlHost (VBE window) +:: ---------------------------- + +SET ControlHostAssemblyName=AccessCodeLib.Common.VbeUserControlHost +SET ControlHostAssemblyFile=%ControlHostAssemblyName%.dll + +SET ControlHostClassGuid=030A1F2F-4E0B-4041-A7F5-C4C0B94BAF07 +SET ControlHostProgId=AccLib.VbeUserControlHost +SET ControlHostFullClassName=AccessCodeLib.Common.VBIDETools.VbeUserControlHost +SET ControlHostProgVersion=1.0 + +:: ################################################################### +:: Find Office bitness +:: ------------------- + +set "key64=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\Configuration" +set "key32=HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Office\ClickToRun\Configuration" +set "bitness=" + +rem check bitness from Office: +reg query "%key64%" /v "Platform" >nul 2>&1 +if !errorlevel! equ 0 ( + for /f "tokens=3" %%a in ('reg query "%key64%" /v "Platform"') do set "bitness=%%a" +) + +if not defined bitness ( + reg query "%key32%" /v "Platform" >nul 2>&1 + if !errorlevel! equ 0 ( + for /f "tokens=3" %%a in ('reg query "%key32%" /v "Platform"') do set "bitness=%%a" + ) +) + +if defined bitness ( + set "bitness=!bitness:x86=32!" + set "bitness=!bitness:x=!" +) else ( + set /p bitness="Please insert Office bitness (32 or 64):" +) +echo ------------------------ +echo Office bitness: !bitness! bit +echo ------------------------ + +:: ################################################################### +:: set registry data (bitness) +:: --------------------------- + +if %bitness%==64 ( + SET AddInsFolder=Addins64 +) else ( + SET AddInsFolder=Addins +) + + +:: ################################################################### +:: set registry data VBE Add-in +:: ---------------------------- + +if %bitness%==64 ( + SET ClsIdFolder=CLSID + SET AddInsFolder=Addins64 +) else ( + SET ClsIdFolder=CLSID + SET AddInsFolder=Addins +) + +SET AssemblyDir=%~dp0 +SET AssemblyDir=%AssemblyDir:\=/% + +SET AssemblyName=%AddInAssemblyName% +SET AssemblyFile=%AddInAssemblyFile% + +SET ClassGuid=%AddInClassGuid% +SET ProgId=%AddInProgId% +SET FullClassName=%AddInFullClassName% +SET ProgVersion=%AddInProgVersion% + +echo. +echo. +echo Insert registry data for %ProgId% (%AddInClassGuid%) ... +echo. +%windir%\system32\REG ADD "HKCU\Software\Classes\%ProgId%" /ve /t REG_SZ /d %FullClassName% /f +%windir%\system32\REG ADD "HKCU\Software\Classes\%ProgId%\CLSID" /ve /t REG_SZ /d "{%ClassGuid%}" /f + +%windir%\system32\REG ADD "HKCU\Software\Classes\CLSID\{%ClassGuid%}" /ve /t REG_SZ /d %FullClassName% /reg:%bitness% /f +%windir%\system32\REG ADD "HKCU\Software\Classes\CLSID\{%ClassGuid%}\ProgId" /ve /t REG_SZ /d %ProgId% /reg:%bitness% /f + +%windir%\system32\REG ADD "HKCU\Software\Classes\CLSID\{%ClassGuid%}\InprocServer32" /ve /t REG_SZ /d "mscoree.dll" /reg:%bitness% /f +%windir%\system32\REG ADD "HKCU\Software\Classes\CLSID\{%ClassGuid%}\InprocServer32" /v "ThreadingModel" /t REG_SZ /d "Both" /reg:%bitness% /f +%windir%\system32\REG ADD "HKCU\Software\Classes\CLSID\{%ClassGuid%}\InprocServer32" /v "Class" /t REG_SZ /d %FullClassName% /reg:%bitness% /f +%windir%\system32\REG ADD "HKCU\Software\Classes\CLSID\{%ClassGuid%}\InprocServer32" /v "Assembly" /t ^ + REG_SZ /d "%AssemblyName%, Version=%ProgVersion%, Culture=neutral, PublicKeyToken=null" /reg:%bitness% /f +%windir%\system32\REG ADD "HKCU\Software\Classes\CLSID\{%ClassGuid%}\InprocServer32" /v "RuntimeVersion" /t ^ + REG_SZ /d %TargetRuntimeVersion% /reg:%bitness% /f +%windir%\system32\REG ADD "HKCU\Software\Classes\CLSID\{%ClassGuid%}\InprocServer32" /v "CodeBase" /t ^ + REG_SZ /d "file:///%AssemblyDir%%AssemblyFile%" /reg:%bitness% /f + +%windir%\system32\REG ADD "HKCU\Software\Microsoft\VBA\VBE\6.0\%AddInsFolder%\%ProgId%" /v "LoadBehavior" /t REG_DWORD /d "0x00000003" /f +%windir%\system32\REG ADD "HKCU\Software\Microsoft\VBA\VBE\6.0\%AddInsFolder%\%ProgId%" /v "FriendlyName" /t REG_SZ /d "AccUnit VBE Add-in" /f +%windir%\system32\REG ADD "HKCU\Software\Microsoft\VBA\VBE\6.0\%AddInsFolder%\%ProgId%" /v "Description" /t REG_SZ /d "AccUnit VBE Add-in" /f + + + +:: ################################################################### +:: set registry data VBE Window Host +:: --------------------------------- + +SET AssemblyName=%ControlHostAssemblyName% +SET AssemblyFile=%ControlHostAssemblyFile% + +SET ClassGuid=%ControlHostClassGuid% +SET ProgId=%ControlHostProgId% +SET FullClassName=%ControlHostFullClassName% +SET ProgVersion=%ControlHostProgVersion% + +echo. +echo. +echo Insert registry data for %ProgId% (%AddInClassGuid%) +echo. +%windir%\system32\REG ADD "HKCU\Software\Classes\%ProgId%" /ve /t REG_SZ /d %FullClassName% /f +%windir%\system32\REG ADD "HKCU\Software\Classes\%ProgId%\CLSID" /ve /t REG_SZ /d "{%ClassGuid%}" /reg:%bitness% /f + +%windir%\system32\REG ADD "HKCU\Software\Classes\CLSID\{%ClassGuid%}" /ve /t REG_SZ /d %FullClassName% /reg:%bitness% /f +%windir%\system32\REG ADD "HKCU\Software\Classes\CLSID\{%ClassGuid%}\ProgId" /ve /t REG_SZ /d %ProgId% /reg:%bitness% /f + +%windir%\system32\REG ADD "HKCU\Software\Classes\CLSID\{%ClassGuid%}\InprocServer32" /ve /t REG_SZ /d "mscoree.dll" /reg:%bitness% /f +%windir%\system32\REG ADD "HKCU\Software\Classes\CLSID\{%ClassGuid%}\InprocServer32" /v "ThreadingModel" /t REG_SZ /d "Both" /reg:%bitness% /f +%windir%\system32\REG ADD "HKCU\Software\Classes\CLSID\{%ClassGuid%}\InprocServer32" /v "Class" /t REG_SZ /d %FullClassName% /reg:%bitness% /f +%windir%\system32\REG ADD "HKCU\Software\Classes\CLSID\{%ClassGuid%}\InprocServer32" /v "Assembly" /t ^ + REG_SZ /d "%AssemblyName%, Version=%ProgVersion%, Culture=neutral, PublicKeyToken=null" /reg:%bitness% /f +%windir%\system32\REG ADD "HKCU\Software\Classes\CLSID\{%ClassGuid%}\InprocServer32" /v "RuntimeVersion" /t ^ + REG_SZ /d %TargetRuntimeVersion% /reg:%bitness% /f +%windir%\system32\REG ADD "HKCU\Software\Classes\CLSID\{%ClassGuid%}\InprocServer32" /v "CodeBase" /t ^ + REG_SZ /d "file:///%AssemblyDir%%AssemblyFile%" /reg:%bitness% /f + + +endlocal +timeout 5 diff --git a/binaries/VBE-Add-in/Unregister_HKCU.cmd b/binaries/VBE-Add-in/Unregister_HKCU.cmd new file mode 100644 index 0000000..08d87df --- /dev/null +++ b/binaries/VBE-Add-in/Unregister_HKCU.cmd @@ -0,0 +1,104 @@ +@ECHO OFF +setlocal enabledelayedexpansion + +:: ################################################################### +:: Config ClassGuit, ProgId, ... +:: ------------------------------------------------------------------- +:: +:: ------------------------------------------------------------------- +:: VBE Add-in: +:: ----------- + +SET AddInClassGuid=F15F18C3-CA43-421E-9585-6A04F51C5786 +SET AddInProgId=AccUnit.VbeAddIn.Connect + +:: ------------------------------------------------------------------- +:: VBE ControlHost (VBE window) +:: ---------------------------- + +SET ControlHostClassGuid=030A1F2F-4E0B-4041-A7F5-C4C0B94BAF07 +SET ControlHostProgId=AccLib.VbeUserControlHost + +:: ################################################################### +:: Find Office bitness +:: ------------------- + +set "key64=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\ClickToRun\Configuration" +set "key32=HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Office\ClickToRun\Configuration" +set "bitness=" + +rem Prüfen für 64-Bit Office unter 64-Bit und 32-Bit Windows +reg query "%key64%" /v "Platform" >nul 2>&1 +if !errorlevel! equ 0 ( + for /f "tokens=3" %%a in ('reg query "%key64%" /v "Platform"') do set "bitness=%%a" +) + +rem Prüfen für 32-Bit Office unter 64-Bit Windows +if not defined bitness ( + reg query "%key32%" /v "Platform" >nul 2>&1 + if !errorlevel! equ 0 ( + for /f "tokens=3" %%a in ('reg query "%key32%" /v "Platform"') do set "bitness=%%a" + ) +) + +if defined bitness ( + set "bitness=!bitness:x86=32!" + set "bitness=!bitness:x=!" +) else ( + set /p bitness="Please insert Office bitness (32 or 64):" +) +echo ------------------------ +echo Office bitness: !bitness! bit +echo ------------------------ + +:: ################################################################### +:: set registry data (bitness) +:: --------------------------- + +if %bitness%==64 ( + SET AddInsFolder=Addins64 +) else ( + SET AddInsFolder=Addins +) + + +:: ################################################################### +:: set registry data VBE Add-in +:: ---------------------------- + +if %bitness%==64 ( + SET ClsIdFolder=CLSID + SET AddInsFolder=Addins64 +) else ( + SET ClsIdFolder=CLSID + SET AddInsFolder=Addins +) + +SET ClassGuid=%AddInClassGuid% +SET ProgId=%AddInProgId% + +echo. +echo. +echo Remove registry data for %ProgId% (%AddInClassGuid%) ... +echo. +%windir%\system32\REG DELETE "HKCU\Software\Classes\%ProgId%" /f +%windir%\system32\REG DELETE "HKCU\Software\Classes\CLSID\{%ClassGuid%}" /reg:%bitness% /f +%windir%\system32\REG DELETE "HKCU\Software\Microsoft\VBA\VBE\6.0\%AddInsFolder%\%ProgId%" /f + + +:: ################################################################### +:: set registry data VBE Window Host +:: --------------------------------- + +SET ClassGuid=%ControlHostClassGuid% +SET ProgId=%ControlHostProgId% + +echo. +echo. +echo Remove registry data for %ProgId% (%AddInClassGuid%) ... +echo. +%windir%\system32\REG DELETE "HKCU\Software\Classes\%ProgId%" /f +%windir%\system32\REG DELETE "HKCU\Software\Classes\CLSID\{%ClassGuid%}" /reg:%bitness% /f + +endlocal +timeout 5 \ No newline at end of file diff --git a/source/AccUnit/AccessCodeLib.AccUnit.csproj b/source/AccUnit/AccessCodeLib.AccUnit.csproj index c1958c5..8d94471 100644 --- a/source/AccUnit/AccessCodeLib.AccUnit.csproj +++ b/source/AccUnit/AccessCodeLib.AccUnit.csproj @@ -145,6 +145,7 @@ + @@ -156,10 +157,8 @@ - - + - @@ -169,7 +168,6 @@ - @@ -293,8 +291,6 @@ - copy $(TargetDir)$(TargetFileName) $(TargetDir)$(ProjectName).dll -"$(ProjectDir)..\tools\tlb\tlbExp.exe" $(TargetDir)$(TargetFileName) /out:$(TargetDir)\$(ProjectName).tlb -copy $(TargetDir)$(TargetFileName).config $(TargetDir)$(ProjectName).dll.config + "$(ProjectDir)..\tools\tlb\tlbExp.exe" $(TargetDir)$(TargetFileName) /out:$(TargetDir)\$(TargetName).tlb \ No newline at end of file diff --git a/source/AccUnit/Assertions/Constraints/StringComparerConstraint.cs b/source/AccUnit/Assertions/Constraints/StringComparerConstraint.cs index d94a47a..5f3db94 100644 --- a/source/AccUnit/Assertions/Constraints/StringComparerConstraint.cs +++ b/source/AccUnit/Assertions/Constraints/StringComparerConstraint.cs @@ -23,7 +23,7 @@ public StringComparerConstraint(string compareText, string expected, int expecte protected override IMatchResult Compare(object actual) { - if (actual is null || (_nullIsEqualEmptyString && actual is string s && s == string.Empty)) + if (actual is null || (_nullIsEqualEmptyString && actual is string s && s == string.Empty)) { if (Expected == null || _nullIsEqualEmptyString && Expected == string.Empty) { @@ -41,7 +41,7 @@ protected override IMatchResult Compare(object actual) { return new MatchResult(CompareText, false, "actual is Null and expected is not Null", actual, Expected); } - + // Check type var actualType = ConstraintBuilder.Type2Compare(actual, Strict); var expectedType = typeof(string); diff --git a/source/AccUnit/Configuration/AccUnitLoaderAddInCodeTemplates.cs b/source/AccUnit/Configuration/AccUnitLoaderAddInCodeTemplates.cs index 90e5f3d..23aa974 100644 --- a/source/AccUnit/Configuration/AccUnitLoaderAddInCodeTemplates.cs +++ b/source/AccUnit/Configuration/AccUnitLoaderAddInCodeTemplates.cs @@ -18,7 +18,7 @@ public AccUnitLoaderAddInCodeTemplates(bool useAccUnitTypeLib = false, string ho private void AddAccUnitLoaderFactory(bool useAccUnitTypeLib, string hostAppName) { - var code = hostAppName.Equals("Microsoft Access",System.StringComparison.OrdinalIgnoreCase) ? AccessAccUnitLoaderFactoryCode : ExcelAccUnitLoaderFactoryCode; + var code = hostAppName.Equals("Microsoft Access", System.StringComparison.OrdinalIgnoreCase) ? AccessAccUnitLoaderFactoryCode : ExcelAccUnitLoaderFactoryCode; code = code.Replace("{UseAccUnitTypeLib}", useAccUnitTypeLib ? "1" : "0"); Add(new CodeTemplate(@"AccUnit_Factory", vbext_ComponentType.vbext_ct_StdModule, code)); @@ -42,6 +42,10 @@ Public Enum StringCompareMode StringCompareMode_TextCompare = 1 StringCompareMode_vbNullStringEqualEmptyString = 4 End Enum +Public Enum ResetMode + ResetMode_RemoveTests = 2 + ResetMode_ResetTestSuite = 4 +End Enum #End If Private Const DefaultTestReportOutput As Long = TestReportOutput.DebugPrint @@ -50,11 +54,38 @@ Private m_CodeCoverageTracker As Object Private Function AccUnitLoaderFactory() As Object If m_AccUnitLoaderFactory Is Nothing Then - Set m_AccUnitLoaderFactory = Application.Run(GetAddInPath & ""AccUnitLoader.GetAccUnitFactory"") + Set m_AccUnitLoaderFactory = GetAccUnitLoaderFactory End If Set AccUnitLoaderFactory = m_AccUnitLoaderFactory End Function +Private Function GetAccUnitLoaderFactory() As Object + + Dim AccUnitVbeAddIn As Object + + If TryGetAccUnitVbeAddIn(AccUnitVbeAddIn) Then + Set GetAccUnitLoaderFactory = AccUnitVbeAddIn.Object + Else + Set GetAccUnitLoaderFactory = Application.Run(GetAddInPath & ""AccUnitLoader.GetAccUnitFactory"") + End If + +End Function + +Private Function TryGetAccUnitVbeAddIn(ByRef AccUnitVbeAddIn As Object) As Boolean + + Dim AddIn2check As Object + + For Each AddIn2check In Application.VBE.Addins + If AddIn2check.ProgId = ""AccUnit.VbeAddIn.Connect"" Then + If AddIn2check.Connect Then + Set AccUnitVbeAddIn = Application.VBE.Addins.Item(""AccUnit.VbeAddIn.Connect"") + TryGetAccUnitVbeAddIn = True + End If + End If + Next + +End Function + #If USE_ACCUNIT_TYPELIB Then Private Property Get AccUnitFactory() As AccUnit.AccUnitFactory #Else @@ -89,6 +120,7 @@ Public Property Get TestSuite(Optional ByVal OutputTo As TestReportOutput = Defa Public Property Get TestSuite(Optional ByVal OutputTo As TestReportOutput = DefaultTestReportOutput) As Object #End If Set TestSuite = AccUnitLoaderFactory.TestSuite(OutputTo) + TestSuite.Reset ResetMode_ResetTestSuite + ResetMode_RemoveTests End Property Public Sub RunAllTests() @@ -168,11 +200,38 @@ Private m_CodeCoverageTracker As Object Private Function AccUnitLoaderFactory() As Object If m_AccUnitLoaderFactory Is Nothing Then - Set m_AccUnitLoaderFactory = GetLoaderAddIn.Application.Run(""GetAccUnitFactory"") + Set m_AccUnitLoaderFactory = GetAccUnitLoaderFactory End If Set AccUnitLoaderFactory = m_AccUnitLoaderFactory End Function +Private Function GetAccUnitLoaderFactory() As Object + + Dim AccUnitVbeAddIn As Object + + If TryGetAccUnitVbeAddIn(AccUnitVbeAddIn) Then + Set GetAccUnitLoaderFactory = AccUnitVbeAddIn.Object + Else + Set GetAccUnitLoaderFactory = GetLoaderAddIn.Application.Run(""GetAccUnitFactory"") + End If + +End Function + +Private Function TryGetAccUnitVbeAddIn(ByRef AccUnitVbeAddIn As Object) As Boolean + + Dim AddIn2check As Object + + For Each AddIn2check In Application.VBE.Addins + If AddIn2check.ProgId = ""AccUnit.VbeAddIn.Connect"" Then + If AddIn2check.Connect Then + Set AccUnitVbeAddIn = Application.VBE.Addins.Item(""AccUnit.VbeAddIn.Connect"") + TryGetAccUnitVbeAddIn = True + End If + End If + Next + +End Function + Private Function GetLoaderAddIn() As Excel.AddIn Dim AddIn As AddIn diff --git a/source/AccUnit/Configuration/Configurator.cs b/source/AccUnit/Configuration/Configurator.cs index 601d5c9..f89f56d 100644 --- a/source/AccUnit/Configuration/Configurator.cs +++ b/source/AccUnit/Configuration/Configurator.cs @@ -20,7 +20,7 @@ public interface IConfigurator void ExportTestClasses(string ExportPath = null, [MarshalAs(UnmanagedType.IDispatch)] object VBProject = null, bool ExportTestComponents = true); void ImportTestClasses(string FileNameFilter = null, string ImportPath = null, [MarshalAs(UnmanagedType.IDispatch)] object VBProject = null); - IUserSettings UserSettings { get; } + IUserSettings UserSettings { get; } } [ComVisible(true)] @@ -40,7 +40,7 @@ public Configurator(VBProject vbproject) _vbProject = vbproject; } - public void InsertAccUnitLoaderFactoryModule(bool UseAccUnitTypeLib = false, bool removeIfExists = false, + public void InsertAccUnitLoaderFactoryModule(bool UseAccUnitTypeLib = false, bool removeIfExists = false, object vbProject = null, object HostApplication = null) { if (vbProject != null) @@ -114,7 +114,8 @@ private void RemoveAccUnitTlbReference() { refName = reference.Name; } - catch { + catch + { refName = ""; } @@ -153,7 +154,7 @@ public IUserSettings UserSettings { return Configuration.UserSettings.Current; } - } + } /* public static void CheckAccUnitVBAReferences(VBProject vbProject) diff --git a/source/AccUnit/Configuration/ErrorTrappingObserver.cs b/source/AccUnit/Configuration/ErrorTrappingObserver.cs index 775395a..59977eb 100644 --- a/source/AccUnit/Configuration/ErrorTrappingObserver.cs +++ b/source/AccUnit/Configuration/ErrorTrappingObserver.cs @@ -12,7 +12,7 @@ public interface IErrorTrappingObserver : IDisposable { [ComVisible(true)] void SetErrorTrapping(VbaErrorTrapping ErrorTrapping); - new void Dispose(); + new void Dispose(); } [ComVisible(true)] diff --git a/source/AccUnit/Configuration/TestClassManager.cs b/source/AccUnit/Configuration/TestClassManager.cs index 35845f5..37bb4d1 100644 --- a/source/AccUnit/Configuration/TestClassManager.cs +++ b/source/AccUnit/Configuration/TestClassManager.cs @@ -446,6 +446,15 @@ public TestClassInfo FindFirstMissingTestClassInVBProject(IEnumerable !completeList.Exists(x => x.Name == testClassInfo.Name)); } + public TestClassInfo GetTestClassInfo(string className, bool initMembers) + { + using (new BlockLogger()) + { + var reader = new TestClassReader(ActiveVBProject); + return reader.GetTestClassInfo(className, initMembers); + } + } + public CodeModule InsertTestTemplate(CodeTemplate template, string templateName) { return template.AddToVBProject(ActiveVBProject, templateName); diff --git a/source/AccUnit/Configuration/UserSettings.cs b/source/AccUnit/Configuration/UserSettings.cs index 08c1201..dd1ebcc 100644 --- a/source/AccUnit/Configuration/UserSettings.cs +++ b/source/AccUnit/Configuration/UserSettings.cs @@ -116,7 +116,7 @@ public void Save() // ReSharper restore MemberCanBePrivate.Global #region Tools - + [Category("Import/Export")] [DefaultValue(@"%APPFOLDER%\Tests\%APPNAME%")] [Description("Import and export folder for test classes\n%APPFOLDER% ... Path to current mdb/accdb\n%APPNAME% ... Filename of mdb/accdb")] diff --git a/source/AccUnit/Integration/BaseTest.cs b/source/AccUnit/Integration/BaseTest.cs index 85c939c..fc12875 100644 --- a/source/AccUnit/Integration/BaseTest.cs +++ b/source/AccUnit/Integration/BaseTest.cs @@ -2,16 +2,26 @@ namespace AccessCodeLib.AccUnit.Integration { - internal abstract class BaseTest : ITest + public abstract class BaseTest : ITest { public BaseTest(ITestFixture fixture, ITestClassMemberInfo testClassMemberInfo) { Fixture = fixture; + Parent = fixture; Name = testClassMemberInfo.Name; MethodName = testClassMemberInfo.Name; TestClassMemberInfo = testClassMemberInfo; } + public BaseTest(ITestFixture fixture, object parentTest, ITestClassMemberInfo testClassMemberInfo) + { + Fixture = fixture; + Name = testClassMemberInfo.Name; + MethodName = testClassMemberInfo.Name; + TestClassMemberInfo = testClassMemberInfo; + Parent = parentTest; + } + protected virtual string FormattedFullName() { return $"{Fixture.Name}.{MethodName}"; @@ -19,11 +29,14 @@ protected virtual string FormattedFullName() public ITestFixture Fixture { get; private set; } + public object Parent { get; private set; } + public string MethodName { get; private set; } public string FullName { get { return FormattedFullName(); } } - public string DisplayName { get; set; } + protected string _displayName; + public string DisplayName { get { return _displayName ?? Name; } set { _displayName = value; } } public RunState RunState { get; set; } public string Name { get; private set; } diff --git a/source/AccUnit/~trash/CodeModuleMemberWithMarker.cs b/source/AccUnit/Integration/CodeModuleMemberWithMarker.cs similarity index 82% rename from source/AccUnit/~trash/CodeModuleMemberWithMarker.cs rename to source/AccUnit/Integration/CodeModuleMemberWithMarker.cs index edef51a..e86730a 100644 --- a/source/AccUnit/~trash/CodeModuleMemberWithMarker.cs +++ b/source/AccUnit/Integration/CodeModuleMemberWithMarker.cs @@ -1,8 +1,7 @@ -/* -using AccessCodeLib.Common.VBIDETools; +using AccessCodeLib.Common.VBIDETools; using Microsoft.Vbe.Interop; -namespace AccessCodeLib.AccUnit.Common +namespace AccessCodeLib.AccUnit { public class CodeModuleMemberWithMarker : CodeModuleMember { @@ -13,7 +12,5 @@ public CodeModuleMemberWithMarker(string name, vbext_ProcKind procKind, bool isP } public bool Marked { get; set; } - } } -*/ \ No newline at end of file diff --git a/source/AccUnit/Integration/IgnoreInfo.cs b/source/AccUnit/Integration/IgnoreInfo.cs new file mode 100644 index 0000000..dced358 --- /dev/null +++ b/source/AccUnit/Integration/IgnoreInfo.cs @@ -0,0 +1,12 @@ +using System.Runtime.InteropServices; + +namespace AccessCodeLib.AccUnit +{ + [ComVisible(true)] + [Guid("54485999-BB08-4C3C-99BB-0D6C1D84B69B")] + public class IgnoreInfo + { + public bool Ignore; + public string Comment; + } +} diff --git a/source/AccUnit/Integration/MethodTest.cs b/source/AccUnit/Integration/MethodTest.cs index ce90d8d..195c3b1 100644 --- a/source/AccUnit/Integration/MethodTest.cs +++ b/source/AccUnit/Integration/MethodTest.cs @@ -2,7 +2,7 @@ namespace AccessCodeLib.AccUnit.Integration { - internal class MethodTest : BaseTest + public class MethodTest : BaseTest { public MethodTest(ITestFixture fixture, ITestClassMemberInfo testClassMemberInfo) : base(fixture, testClassMemberInfo) diff --git a/source/AccUnit/Integration/ParamTest.cs b/source/AccUnit/Integration/ParamTest.cs index cb7628f..5717326 100644 --- a/source/AccUnit/Integration/ParamTest.cs +++ b/source/AccUnit/Integration/ParamTest.cs @@ -3,7 +3,7 @@ namespace AccessCodeLib.AccUnit.Integration { - internal class ParamTest : BaseTest, IParamTest + public class ParamTest : BaseTest, IParamTest, IRowTestId { private readonly string _testRowId = string.Empty; @@ -14,11 +14,25 @@ public ParamTest(ITestFixture fixture, ITestClassMemberInfo testClassMemberInfo, Parameters = parameters; } + public ParamTest(ITestFixture fixture, ITest parent, ITestClassMemberInfo testClassMemberInfo, string testRowId, IEnumerable parameters) + : base(fixture, parent, testClassMemberInfo) + { + _testRowId = testRowId; + Parameters = parameters; + } + protected override string FormattedFullName() { return $"{Fixture.Name}.{MethodName}.{_testRowId}"; } public IEnumerable Parameters { get; private set; } + + public string RowId => _testRowId; + } + + public interface IRowTestId + { + string RowId { get; } } } diff --git a/source/AccUnit/Integration/RowTest.cs b/source/AccUnit/Integration/RowTest.cs index 63f5d7c..763bf60 100644 --- a/source/AccUnit/Integration/RowTest.cs +++ b/source/AccUnit/Integration/RowTest.cs @@ -3,7 +3,7 @@ namespace AccessCodeLib.AccUnit.Integration { - internal class RowTest : IRowTest + public class RowTest : IRowTest { public RowTest(ITestFixture fixture, TestClassMemberInfo testClassMemberInfo) { @@ -30,7 +30,7 @@ private void FillRows() row.Name = i.ToString(); } var paramTestClassMemberInfo = new TestClassMemberInfo(TestClassMemberInfo, row.IgnoreInfo, row.Tags); - var paramTest = new ParamTest(Fixture, paramTestClassMemberInfo, row.Name, row.Args); + var paramTest = new ParamTest(Fixture, this, paramTestClassMemberInfo, row.Name, row.Args); paramTests.Add(paramTest); } @@ -44,7 +44,8 @@ private void FillRows() public string FullName { get; private set; } - public string DisplayName { get; set; } + protected string _displayName; + public string DisplayName { get { return _displayName ?? Name; } set { _displayName = value; } } public RunState RunState { get; set; } public string Name { get; private set; } @@ -54,5 +55,7 @@ private void FillRows() public IEnumerable Rows { get; private set; } public IEnumerable ParamTests { get; private set; } + + public object Parent => Fixture; } } diff --git a/source/AccUnit/Integration/TestClassMemberInfo.cs b/source/AccUnit/Integration/TestClassMemberInfo.cs index 79b8d6b..1287fcd 100644 --- a/source/AccUnit/Integration/TestClassMemberInfo.cs +++ b/source/AccUnit/Integration/TestClassMemberInfo.cs @@ -54,6 +54,7 @@ private void ReadProcHeader(string procHeader) } public string Name { get; private set; } + public string FullName { get { return string.Format("{0}.{1}", Parent.Name, Name); } } public TestClassInfo Parent { get @@ -64,7 +65,7 @@ public TestClassInfo Parent } } - private IgnoreInfo _ignoreInfo; + private readonly IgnoreInfo _ignoreInfo = new IgnoreInfo(); public IgnoreInfo IgnoreInfo { get { return _ignoreInfo; } } private readonly List _testRowFilter; @@ -188,11 +189,4 @@ public string DisplayName } } } - - public struct IgnoreInfo - { - public bool Ignore; - public string Comment; - } - } diff --git a/source/AccUnit/Integration/TestClassReader.cs b/source/AccUnit/Integration/TestClassReader.cs index cb15cfe..c20386e 100644 --- a/source/AccUnit/Integration/TestClassReader.cs +++ b/source/AccUnit/Integration/TestClassReader.cs @@ -48,6 +48,15 @@ where IsTestRelatedCodeModule(vbc.CodeModule) } } + public TestClassInfo GetTestClassInfo(string classname, bool initMembers) + { + using (new BlockLogger()) + { + var vbc = VbProject.VBComponents.Item(classname); + return GetTestClassInfo(vbc, initMembers); + } + } + private static TestClassInfo GetTestClassInfo(_VBComponent vbc, bool initMembers) { using (new BlockLogger(vbc.CodeModule.Name)) @@ -98,23 +107,27 @@ public TestClassMemberInfo GetTestClassMemberInfo(string classname, string membe { var reader = new CodeModuleReader(VbProject.VBComponents.Item(classname).CodeModule); var memberInfo = new TestClassMemberInfo(membername, reader.GetProcedureHeader(membername)); - - var rowGenerator = new TestRowGenerator - { - ActiveVBProject = (VBProject)VbProject, - TestName = classname - }; - var testRows = rowGenerator.GetTestRows(membername); - - memberInfo.TestRows.AddRange(testRows); - + FillTestRows(classname, memberInfo, (VBProject)VbProject); return memberInfo; } } + private static void FillTestRows(string className, TestClassMemberInfo memberInfo, VBProject vbProject) + { + var rowGenerator = new TestRowGenerator + { + ActiveVBProject = vbProject, + TestName = className + }; + var testRows = rowGenerator.GetTestRows(memberInfo.Name); + + memberInfo.TestRows.AddRange(testRows); + } + private static TestClassMemberInfo GetTestClassMemberInfo(CodeModuleMember member, CodeModuleReader reader) { - return new TestClassMemberInfo(member.Name, reader.GetProcedureHeader(member.Name, member.ProcKind)); + return new TestClassMemberInfo(member.Name, + reader.GetProcedureHeader(member.Name, member.ProcKind)); } public static bool IsTestClassCodeModul(_CodeModule codeModule) diff --git a/source/AccUnit/Integration/TestFixture.cs b/source/AccUnit/Integration/TestFixture.cs index 6529a0b..c9ff655 100644 --- a/source/AccUnit/Integration/TestFixture.cs +++ b/source/AccUnit/Integration/TestFixture.cs @@ -29,6 +29,14 @@ public TestFixture(string name, object testToAdd) _testClassInstance = testToAdd; } + public object Parent + { + get + { + return null; + } + } + public ITestFixtureMembers Members { get diff --git a/source/AccUnit/Integration/TestResultCollection.cs b/source/AccUnit/Integration/TestResultCollection.cs index 2a09a25..745e66d 100644 --- a/source/AccUnit/Integration/TestResultCollection.cs +++ b/source/AccUnit/Integration/TestResultCollection.cs @@ -91,7 +91,22 @@ public ITestResult Item(int index) public void Reset() { - throw new NotImplementedException(); + Clear(); + + ExecutedCount = 0; + IsErrorCount = 0; + IsFailureCount = 0; + IsIgnoredCount = 0; + IsPassedCount = 0; + + Executed = false; + IsError = false; + IsFailure = false; + IsIgnored = false; + IsPassed = false; + Message = string.Empty; + + ElapsedTime = 0; } public ITestData Test { get; private set; } @@ -125,7 +140,7 @@ public string Result public double ElapsedTime { get; set; } public IEnumerable TestResults { get { return this; } } - public ITestResult[] GetTestResults() { return this.ToArray(); } + public ITestResult[] GetTestResults() { return this.ToArray(); } public int Total { get { return ExecutedCount; } } diff --git a/source/AccUnit/Integration/TestResultCollector.cs b/source/AccUnit/Integration/TestResultCollector.cs index 3e5888a..3a50b74 100644 --- a/source/AccUnit/Integration/TestResultCollector.cs +++ b/source/AccUnit/Integration/TestResultCollector.cs @@ -4,7 +4,7 @@ namespace AccessCodeLib.AccUnit.Integration { public class TestResultCollector : TestResultCollection - , ITestResultCollector, ITestResultSummaryPrinter, ITestResultCollectorEvents + , INotifyingTestResultCollector, ITestResultCollector, ITestResultSummaryPrinter, ITestResultCollectorEvents { public TestResultCollector(ITestSuite testSuite) : base(testSuite) { @@ -21,10 +21,41 @@ private void TryInitTestSuiteListener(ITestSuite testSuite) { if (testSuite != null) { + testSuite.TestSuiteReset += RaiseTestSuiteReset; testSuite.TestSuiteStarted += RaiseTestSuiteStarted; + testSuite.TestFixtureStarted += RaiseTestFixtureStarted; + testSuite.TestStarted += RaiseTestStarted; testSuite.TestTraceMessage += RaiseTestTraceMessage; + testSuite.TestFinished += RaiseTestFinished; + testSuite.TestFixtureFinished += RaiseTestFixtureFinished; testSuite.TestSuiteFinished += RaiseTestSuiteFinished; - } + } + } + + protected virtual void RaiseTestSuiteReset(ResetMode resetmode, ref bool cancel) + { + TestSuiteReset?.Invoke(resetmode, ref cancel); + } + + protected virtual void RaiseTestFixtureFinished(ITestResult result) + { + TestFixtureFinished?.Invoke(result); + } + + protected virtual void RaiseTestFixtureStarted(ITestFixture fixture) + { + TestFixtureStarted?.Invoke(fixture); + } + + protected virtual void RaiseTestFinished(ITestResult result) + { + TestFinished?.Invoke(result); + } + + protected virtual void RaiseTestStarted(ITest test, ref IgnoreInfo ignoreInfo) + { + //ignoreInfo.Ignore = false; + TestStarted?.Invoke(test, ref ignoreInfo); } void ITestResultSummaryPrinter.PrintSummary(ITestSummary TestSummary, bool PrintTestResults) @@ -39,7 +70,7 @@ protected virtual void RaiseTestSuiteStarted(ITestSuite testSuite) protected virtual void RaiseTestTraceMessage(string message, ICodeCoverageTracker CodeCoverageTracker) { - TestTraceMessage?.Invoke(message, CodeCoverageTracker); + TestTraceMessage?.Invoke(message, CodeCoverageTracker); } protected virtual void RaiseNewTestResult(ITestResult testResult) @@ -57,12 +88,17 @@ protected virtual void RaisePrintSummary(ITestSummary TestSummary, bool PrintTes PrintSummary?.Invoke(TestSummary, PrintTestResults); } + public event TestSuiteResetEventHandler TestSuiteReset; public event TestSuiteStartedEventHandler TestSuiteStarted; + public event TestFixtureStartedEventHandler TestFixtureStarted; + public event TestStartedEventHandler TestStarted; public event TestTraceMessageEventHandler TestTraceMessage; + public event FinishedEventHandler TestFinished; public event TestResultEventHandler NewTestResult; + public event FinishedEventHandler TestFixtureFinished; public event TestSuiteFinishedEventHandler TestSuiteFinished; public event PrintSummaryEventHandler PrintSummary; } - + } \ No newline at end of file diff --git a/source/AccUnit/Integration/TestRow.cs b/source/AccUnit/Integration/TestRow.cs index 7e54043..64ff7ff 100644 --- a/source/AccUnit/Integration/TestRow.cs +++ b/source/AccUnit/Integration/TestRow.cs @@ -67,7 +67,7 @@ public ITestRow ClickingMsgBox(params VbMsgBoxResult[] args) return this; } - private IgnoreInfo _ignoreInfo = new IgnoreInfo(); + private readonly IgnoreInfo _ignoreInfo = new IgnoreInfo(); public IgnoreInfo IgnoreInfo { get { return _ignoreInfo; } } public ITestRow Ignore(string comment = "") diff --git a/source/AccUnit/Integration/VBATestBuilder.cs b/source/AccUnit/Integration/VBATestBuilder.cs index e72597f..f00600d 100644 --- a/source/AccUnit/Integration/VBATestBuilder.cs +++ b/source/AccUnit/Integration/VBATestBuilder.cs @@ -2,7 +2,6 @@ using AccessCodeLib.AccUnit.Interfaces; using AccessCodeLib.Common.Tools.Logging; using AccessCodeLib.Common.VBIDETools; -using AccessCodeLib.Common.VBIDETools.Integration; using Microsoft.Vbe.Interop; using System; using System.Collections.Generic; diff --git a/source/AccUnit/Interfaces/ITest.cs b/source/AccUnit/Interfaces/ITest.cs index fdcfc29..0b65bb1 100644 --- a/source/AccUnit/Interfaces/ITest.cs +++ b/source/AccUnit/Interfaces/ITest.cs @@ -4,9 +4,12 @@ namespace AccessCodeLib.AccUnit.Interfaces { [ComVisible(true)] [Guid("96AEE906-564B-4A39-B85C-E47F275CFD51")] - [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface ITest : ITestData { + new string Name { get; } + new string FullName { get; } + ITestFixture Fixture { get; } string MethodName { get; } string DisplayName { get; set; } diff --git a/source/AccUnit/Interfaces/ITestData.cs b/source/AccUnit/Interfaces/ITestData.cs index b2dbfb5..f1fe66a 100644 --- a/source/AccUnit/Interfaces/ITestData.cs +++ b/source/AccUnit/Interfaces/ITestData.cs @@ -4,9 +4,11 @@ namespace AccessCodeLib.AccUnit.Interfaces { [ComVisible(true)] [Guid("D6C5FF83-10A3-4C88-80DF-29068F252B5F")] + [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface ITestData { string Name { get; } string FullName { get; } + object Parent { [return: MarshalAs(UnmanagedType.IDispatch)] get; } } } diff --git a/source/AccUnit/Interfaces/ITestFixture.cs b/source/AccUnit/Interfaces/ITestFixture.cs index 8952d9b..a6cbc69 100644 --- a/source/AccUnit/Interfaces/ITestFixture.cs +++ b/source/AccUnit/Interfaces/ITestFixture.cs @@ -5,7 +5,7 @@ namespace AccessCodeLib.AccUnit.Interfaces { [ComVisible(true)] [Guid("5B540C56-B19B-4A44-BF98-E66BB07C4EB9")] - [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface ITestFixture : ITestData { object Instance { get; } diff --git a/source/AccUnit/Interfaces/ITestResultCollector.cs b/source/AccUnit/Interfaces/ITestResultCollector.cs index f1304b6..9c10bad 100644 --- a/source/AccUnit/Interfaces/ITestResultCollector.cs +++ b/source/AccUnit/Interfaces/ITestResultCollector.cs @@ -10,6 +10,10 @@ public interface ITestResultCollector void Add(ITestResult TestResult); } + public interface INotifyingTestResultCollector : ITestResultCollector, ITestResultCollectorEvents + { + } + [ComVisible(true)] [Guid("95036E79-3476-4031-9656-E3762AEA5220")] public interface ITestResultSummaryPrinter @@ -25,14 +29,19 @@ public interface ITestSummaryTestResultCollector : ITestResultCollector public interface ITestResultCollectorEvents { + event TestSuiteResetEventHandler TestSuiteReset; event TestSuiteStartedEventHandler TestSuiteStarted; + event TestFixtureStartedEventHandler TestFixtureStarted; + event TestStartedEventHandler TestStarted; event TestTraceMessageEventHandler TestTraceMessage; + event FinishedEventHandler TestFinished; event TestResultEventHandler NewTestResult; + event FinishedEventHandler TestFixtureFinished; event TestSuiteFinishedEventHandler TestSuiteFinished; event PrintSummaryEventHandler PrintSummary; } public delegate void TestResultEventHandler(ITestResult Result); public delegate void PrintSummaryEventHandler(ITestSummary TestSummary, bool PrintTestResults); - + } diff --git a/source/AccUnit/Interfaces/ITestSuite.cs b/source/AccUnit/Interfaces/ITestSuite.cs index bde7da0..9182ae3 100644 --- a/source/AccUnit/Interfaces/ITestSuite.cs +++ b/source/AccUnit/Interfaces/ITestSuite.cs @@ -1,6 +1,6 @@ -using System.Collections.Generic; +using AccessCodeLib.AccUnit.CodeCoverage; +using System.Collections.Generic; using System.Runtime.InteropServices; -using AccessCodeLib.AccUnit.CodeCoverage; namespace AccessCodeLib.AccUnit.Interfaces { @@ -61,7 +61,7 @@ public interface ITestSuiteEvents public delegate void FinishedEventHandler(ITestResult result); public delegate void TestSuiteStartedEventHandler(ITestSuite testSuite); public delegate void TestFixtureStartedEventHandler(ITestFixture fixture); - public delegate void TestStartedEventHandler(ITest test, IgnoreInfo ignoreInfo, ITagList tags); + public delegate void TestStartedEventHandler(ITest test, ref IgnoreInfo ignoreInfo); public delegate void MessageEventHandler(string message); public delegate void TestSuiteFinishedEventHandler(ITestSummary summary); public delegate void TestSuiteResetEventHandler(ResetMode resetmode, ref bool cancel); diff --git a/source/AccUnit/Interfaces/IVBATestBuilder.cs b/source/AccUnit/Interfaces/IVBATestBuilder.cs index da9b410..d8dd33f 100644 --- a/source/AccUnit/Interfaces/IVBATestBuilder.cs +++ b/source/AccUnit/Interfaces/IVBATestBuilder.cs @@ -1,6 +1,4 @@ -using AccessCodeLib.AccUnit.Interfaces; -using Microsoft.Vbe.Interop; -using System; +using System; using System.Collections.Generic; namespace AccessCodeLib.AccUnit.Interfaces @@ -11,7 +9,7 @@ public interface IVBATestBuilder : ITestBuilder //object HostApplication { get; } } - public interface ITestBuilder : IDisposable + public interface ITestBuilder : IDisposable { bool TestToolsActivated { get; } object CreateObject(string className); diff --git a/source/AccUnit/Interfaces/IVBATestSuite.cs b/source/AccUnit/Interfaces/IVBATestSuite.cs index 106948b..adfddd1 100644 --- a/source/AccUnit/Interfaces/IVBATestSuite.cs +++ b/source/AccUnit/Interfaces/IVBATestSuite.cs @@ -1,5 +1,4 @@ -using Microsoft.Vbe.Interop; -using System; +using System; namespace AccessCodeLib.AccUnit.Interfaces { diff --git a/source/AccUnit/Interop/AccessTestSuite.cs b/source/AccUnit/Interop/AccessTestSuite.cs index 9198f8a..de8e7e2 100644 --- a/source/AccUnit/Interop/AccessTestSuite.cs +++ b/source/AccUnit/Interop/AccessTestSuite.cs @@ -1,6 +1,5 @@ using AccessCodeLib.AccUnit.Interfaces; using AccessCodeLib.Common.VBIDETools; -using Microsoft.Vbe.Interop; using System; using System.Collections.Generic; using System.Runtime.InteropServices; @@ -15,14 +14,14 @@ public interface IAccessTestSuite : Interfaces.IVBATestSuite new string Name { get; } new ITestSummary Summary { get; } - + new IAccessTestSuite AppendTestResultReporter(ITestResultReporter reporter); new IAccessTestSuite Add([MarshalAs(UnmanagedType.IDispatch)] object testToAdd); new IAccessTestSuite AddByClassName(string className); new IAccessTestSuite AddFromVBProject(); new IAccessTestSuite Run(); new IAccessTestSuite Reset(ResetMode mode = ResetMode.ResetTestData); - + new void Dispose(); #endregion diff --git a/source/AccUnit/Interop/CodeCoverageTracker.cs b/source/AccUnit/Interop/CodeCoverageTracker.cs index 7f2ffcd..2228cbe 100644 --- a/source/AccUnit/Interop/CodeCoverageTracker.cs +++ b/source/AccUnit/Interop/CodeCoverageTracker.cs @@ -6,12 +6,12 @@ namespace AccessCodeLib.AccUnit.Interop { [ComVisible(true)] [Guid("ED31BE77-E17D-42FA-95F9-5280798B22CD")] - public interface ICodeCoverageTracker : IDisposable + public interface ICodeCoverageTracker : IDisposable, CodeCoverage.ICodeCoverageTracker { - ICodeCoverageTracker Add(string CodeModuleName); - void Track(string CodeModulName, string ProcedureName, int LineNo); - string GetReport(string CodeModuleName = "*", string ProcedureName = "*", bool ShowCoverageDetails = false); - void Clear(string CodeModuleName = null); + new ICodeCoverageTracker Add(string CodeModuleName); + new void Track(string CodeModulName, string ProcedureName, int LineNo); + new string GetReport(string CodeModuleName = "*", string ProcedureName = "*", bool ShowCoverageDetails = false); + new void Clear(string CodeModuleName = null); new void Dispose(); } diff --git a/source/AccUnit/Interop/ITestResultCollectorComEvents.cs b/source/AccUnit/Interop/ITestResultCollectorComEvents.cs index d66423b..faa824e 100644 --- a/source/AccUnit/Interop/ITestResultCollectorComEvents.cs +++ b/source/AccUnit/Interop/ITestResultCollectorComEvents.cs @@ -9,9 +9,14 @@ namespace AccessCodeLib.AccUnit.Interop [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)] public interface ITestResultCollectorComEvents : ITestResultCollectorEvents { + new void TestSuiteReset(ITestSummary Summary); new void TestSuiteStarted(ITestSuite TestSuite); + new void TestFixtureStarted(ITestFixture TestFixtureName); + new void TestStarted(ITest Test, IgnoreInfo ignoreInfo); new void TestTraceMessage(string Message, ICodeCoverageTracker CodeCoverageTracker); + new void TestFinished(ITestResult Result); new void NewTestResult(ITestResult Result); + new void TestFixtureFinished(ITestResult Result); new void TestSuiteFinished(ITestSummary Summary); new void PrintSummary(ITestSummary TestSummary, bool PrintTestResults); } diff --git a/source/AccUnit/Interop/ITestSuiteComEvents.cs b/source/AccUnit/Interop/ITestSuiteComEvents.cs index 2039e9f..697cacd 100644 --- a/source/AccUnit/Interop/ITestSuiteComEvents.cs +++ b/source/AccUnit/Interop/ITestSuiteComEvents.cs @@ -1,6 +1,5 @@ using AccessCodeLib.AccUnit.Interfaces; using System; -using System.Collections; using System.Runtime.InteropServices; namespace AccessCodeLib.AccUnit.Interop @@ -12,18 +11,5 @@ public interface ITestSuiteComEvents : ITestSuiteEvents { new void TestTraceMessage(string Message, ICodeCoverageTracker CodeCoverageTracker); new void TestSuiteStarted(ITestSuite TestSuite); - /* - - void TestFixtureStarted(ITestFixture Fixture); - void TestStarted(ITest TestCase); - - void TestFinished(ITestResult Result); - void TestFixtureFinished(ITestResult Result); - */ - new void TestSuiteFinished(ITestSummary Summary); - - - //void TestSuiteReset(ResetMode Mode, bool Cancel); - // void Disposed([MarshalAs(UnmanagedType.IDispatch)] object sender); } } diff --git a/source/AccUnit/Interop/TestResultCollector.cs b/source/AccUnit/Interop/TestResultCollector.cs index 4408132..ee560a9 100644 --- a/source/AccUnit/Interop/TestResultCollector.cs +++ b/source/AccUnit/Interop/TestResultCollector.cs @@ -1,5 +1,4 @@ -using AccessCodeLib.AccUnit.Integration; -using AccessCodeLib.AccUnit.Interfaces; +using AccessCodeLib.AccUnit.Interfaces; using System; using System.Runtime.InteropServices; @@ -19,50 +18,22 @@ public interface ITestCollector : Interfaces.ITestResultCollector [ComSourceInterfaces(typeof(ITestResultCollectorComEvents))] [ProgId("AccUnit.TestResultCollector")] public class TestResultCollector : Integration.TestResultCollector, ITestCollector - , ITestResultCollectorEvents + , INotifyingTestResultCollector, ITestResultCollectorEvents + , ITestResultSummaryPrinter { public TestResultCollector(ITestSuite test) : base(test) { } - public new void Add(ITestResult testResult) - { - base.Add(testResult); - } - - protected override void RaiseTestSuiteStarted(ITestSuite testSuite) - { - TestSuiteStarted?.Invoke(testSuite); - } - protected override void RaiseTestTraceMessage(string message, CodeCoverage.ICodeCoverageTracker CodeCoverageTracker) { TestTraceMessage?.Invoke(message, CodeCoverageTracker as ICodeCoverageTracker); + base.RaiseTestTraceMessage(message, CodeCoverageTracker); } - protected override void RaiseNewTestResult(ITestResult testResult) - { - NewTestResult?.Invoke(testResult); - } - - protected override void RaiseTestSuiteFinished(ITestSummary summary) - { - TestSuiteFinished?.Invoke(summary); - } - - protected override void RaisePrintSummary(ITestSummary TestSummary, bool PrintTestResults) - { - PrintSummary?.Invoke(TestSummary, PrintTestResults); - } - - public new event TestSuiteStartedEventHandler TestSuiteStarted; public new event TestTraceMessageEventHandler TestTraceMessage; - public new event TestResultEventHandler NewTestResult; - public new event TestSuiteFinishedEventHandler TestSuiteFinished; - public new event PrintSummaryEventHandler PrintSummary; } public delegate void TestTraceMessageEventHandler(string Message, ICodeCoverageTracker CodeCoverageTracker); - } diff --git a/source/AccUnit/Interop/VbaFactory/AccUnitFactory.cs b/source/AccUnit/Interop/VbaFactory/AccUnitFactory.cs index 676931c..e11d05a 100644 --- a/source/AccUnit/Interop/VbaFactory/AccUnitFactory.cs +++ b/source/AccUnit/Interop/VbaFactory/AccUnitFactory.cs @@ -20,6 +20,12 @@ public interface IAccUnitFactory IAccessTestSuite AccessTestSuite([MarshalAs(UnmanagedType.IDispatch)] object hostApplication, ITestBuilder testBuilder = null, ITestRunner testRunner = null, ITestSummaryFormatter testSummaryFormatter = null, ITestResultCollector externalTestResultCollector = null); ICodeCoverageTracker CodeCoverageTracker([MarshalAs(UnmanagedType.IDispatch)] object VBProject); IErrorTrappingObserver AccessErrorTrappingObserver([MarshalAs(UnmanagedType.IDispatch)] object HostApplication); + + [ComVisible(false)] + IVBATestSuite VBATestSuite(IOfficeApplicationHelper applicationHelper, ITestBuilder testBuilder = null, ITestRunner testRunner = null, ITestSummaryFormatter testSummaryFormatter = null, ITestResultCollector externalTestResultCollector = null); + [ComVisible(false)] + IAccessTestSuite AccessTestSuite(IAccessApplicationHelper applicationHelper, ITestBuilder testBuilder = null, ITestRunner testRunner = null, ITestSummaryFormatter testSummaryFormatter = null, ITestResultCollector externalTestResultCollector = null); + } [ComVisible(true)] @@ -60,14 +66,23 @@ public IConfigurator Configurator(object vbProject = null) } public IVBATestSuite VBATestSuite( - object hostApplication, - ITestBuilder testBuilder = null, - ITestRunner testRunner = null, + object hostApplication, + ITestBuilder testBuilder = null, + ITestRunner testRunner = null, ITestSummaryFormatter testSummaryFormatter = null, ITestResultCollector externalTestResultCollector = null) { var applicationHelper = GetApplicationHelper(hostApplication); + return VBATestSuite(applicationHelper, testBuilder, testRunner, testSummaryFormatter, externalTestResultCollector); + } + public IVBATestSuite VBATestSuite( + IOfficeApplicationHelper applicationHelper, + ITestBuilder testBuilder = null, + ITestRunner testRunner = null, + ITestSummaryFormatter testSummaryFormatter = null, + ITestResultCollector externalTestResultCollector = null) + { if (testRunner == null) testRunner = new TestRunner(applicationHelper.CurrentVBProject); @@ -92,15 +107,25 @@ private OfficeApplicationHelper GetApplicationHelper(object hostApplication) } public IAccessTestSuite AccessTestSuite( - object hostApplcation, - ITestBuilder testBuilder = null, - ITestRunner testRunner = null, + object hostApplcation, + ITestBuilder testBuilder = null, + ITestRunner testRunner = null, ITestSummaryFormatter testSummaryFormatter = null, ITestResultCollector externalTestResultCollector = null) { var applicationHelper = new AccessApplicationHelper(hostApplcation); + return AccessTestSuite(applicationHelper, testBuilder, testRunner, testSummaryFormatter, externalTestResultCollector); + } - if (testRunner == null) + public IAccessTestSuite AccessTestSuite( + IAccessApplicationHelper applicationHelper, + ITestBuilder testBuilder = null, + ITestRunner testRunner = null, + ITestSummaryFormatter testSummaryFormatter = null, + ITestResultCollector externalTestResultCollector = null) + { + + if (testRunner == null) testRunner = new TestRunner(applicationHelper.CurrentVBProject); if (testBuilder == null) @@ -110,7 +135,7 @@ public IAccessTestSuite AccessTestSuite( testSummaryFormatter = new TestSummaryFormatter(TestSuiteUserSettings.Current.SeparatorMaxLength, TestSuiteUserSettings.Current.SeparatorChar); var testSuite = new AccessTestSuite(applicationHelper, testBuilder, testRunner, testSummaryFormatter); - + if (externalTestResultCollector != null) testSuite.TestResultCollector = externalTestResultCollector; diff --git a/source/AccUnit/Interop/VbaTestSuite.cs b/source/AccUnit/Interop/VbaTestSuite.cs index e74f8b7..38c9aa0 100644 --- a/source/AccUnit/Interop/VbaTestSuite.cs +++ b/source/AccUnit/Interop/VbaTestSuite.cs @@ -1,6 +1,5 @@ using AccessCodeLib.AccUnit.Interfaces; using AccessCodeLib.Common.VBIDETools; -using Microsoft.Vbe.Interop; using System; using System.Collections.Generic; using System.Runtime.InteropServices; @@ -15,14 +14,14 @@ public interface IVBATestSuite : Interfaces.IVBATestSuite new string Name { get; } new ITestSummary Summary { get; } - + new IVBATestSuite AppendTestResultReporter(ITestResultReporter reporter); new IVBATestSuite Add([MarshalAs(UnmanagedType.IDispatch)] object testToAdd); new IVBATestSuite AddByClassName(string className); new IVBATestSuite AddFromVBProject(); new IVBATestSuite Run(); new IVBATestSuite Reset(ResetMode mode = ResetMode.ResetTestData); - + new void Dispose(); #endregion @@ -30,7 +29,7 @@ public interface IVBATestSuite : Interfaces.IVBATestSuite IVBATestSuite SelectTests(object TestNameFilter); IVBATestSuite Filter(object FilterTags); ITestClassGenerator TestClassGenerator { get; } - + } @@ -41,7 +40,7 @@ public interface IVBATestSuite : Interfaces.IVBATestSuite [ProgId("AccUnit.VBATestSuite")] public class VBATestSuite : AccUnit.VBATestSuite, IVBATestSuite, IDisposable { - public VBATestSuite(OfficeApplicationHelper applicationHelper, IVBATestBuilder testBuilder, ITestRunner testRunner, ITestSummaryFormatter testSummaryFormatter) + public VBATestSuite(IOfficeApplicationHelper applicationHelper, IVBATestBuilder testBuilder, ITestRunner testRunner, ITestSummaryFormatter testSummaryFormatter) : base(applicationHelper, testBuilder, testRunner, testSummaryFormatter) { } diff --git a/source/AccUnit/Properties/AssemblyInfo.cs b/source/AccUnit/Properties/AssemblyInfo.cs index cb09ef8..38fe72b 100644 --- a/source/AccUnit/Properties/AssemblyInfo.cs +++ b/source/AccUnit/Properties/AssemblyInfo.cs @@ -5,7 +5,7 @@ // Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern, // die einer Assembly zugeordnet sind. [assembly: AssemblyTitle("AccUnit")] -[assembly: AssemblyDescription("")] +[assembly: AssemblyDescription("AccUnit - VBA Unit Testing Framework")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("access-codelib.net")] [assembly: AssemblyProduct("AccUnit")] @@ -31,5 +31,5 @@ // Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden, // indem Sie "*" wie unten gezeigt eingeben: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.9.7.0")] -[assembly: AssemblyFileVersion("0.9.7.0")] +[assembly: AssemblyVersion("0.9.8.0")] +[assembly: AssemblyFileVersion("0.9.8.0")] diff --git a/source/AccUnit/Properties/Settings.Designer.cs b/source/AccUnit/Properties/Settings.Designer.cs index d9708e5..64eba54 100644 --- a/source/AccUnit/Properties/Settings.Designer.cs +++ b/source/AccUnit/Properties/Settings.Designer.cs @@ -13,7 +13,7 @@ namespace AccessCodeLib.AccUnit.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.7.0.0")] - internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + public sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); diff --git a/source/AccUnit/TestRunner/VbaTestRunner.cs b/source/AccUnit/TestRunner/VbaTestRunner.cs index ca16370..7a6157e 100644 --- a/source/AccUnit/TestRunner/VbaTestRunner.cs +++ b/source/AccUnit/TestRunner/VbaTestRunner.cs @@ -31,9 +31,9 @@ public ITestResult Run(ITestSuite testSuite, ITestResultCollector testResultColl RaiseTestSuiteStarted(testSuite); var results = new TestResultCollection(testSuite); - foreach (var tests in testSuite.TestFixtures) + foreach (var fixture in testSuite.TestFixtures) { - var result = Run(tests, testResultCollector, methodFilter, filterTags); + var result = Run(fixture, testResultCollector, methodFilter, filterTags); results.Add(result); } @@ -42,7 +42,7 @@ public ITestResult Run(ITestSuite testSuite, ITestResultCollector testResultColl return results; } - void RaiseTestSuiteStarted(ITestSuite testSuite) + void RaiseTestSuiteStarted(ITestSuite testSuite/*, IEnumerable tags*/) { TestSuiteStarted?.Invoke(testSuite); } @@ -144,6 +144,20 @@ private ITest CreateTest(ITestFixture testFixture, string testMethodName) public ITestResult Run(IRowTest test, IEnumerable filterTags = null) { var results = new TestResultCollection(test); + var ignoreInfo = new IgnoreInfo(); + RaiseTestStarted(test, ref ignoreInfo); + + if (ignoreInfo.Ignore) + { + var ignoreTestResult = new TestResult(test) + { + IsIgnored = true, + Message = ignoreInfo.Comment + }; + RaiseTestFinished(ignoreTestResult); + return ignoreTestResult; + } + foreach (var paramTest in test.ParamTests) { if (filterTags != null) @@ -157,6 +171,8 @@ public ITestResult Run(IRowTest test, IEnumerable filterTags = nul var result = Run(paramTest); results.Add(result); } + + RaiseTestFinished(results); return results; } @@ -203,8 +219,7 @@ public ITestResult Run(ITest test, IEnumerable filterTags = null) using (var invocationHelper = new InvocationHelper(testFixture.Instance)) { var ignoreInfo = new IgnoreInfo(); - - RaiseTestStarted(test, ignoreInfo, test.TestClassMemberInfo.Tags); + RaiseTestStarted(test, ref ignoreInfo); if (ignoreInfo.Ignore) { testResult.IsIgnored = true; @@ -298,9 +313,9 @@ private static void RunTeardown(ITestFixture testFixture, InvocationHelper invoc } } - void RaiseTestStarted(ITest test, IgnoreInfo ignoreInfo, ITagList tags) + void RaiseTestStarted(ITest test, ref IgnoreInfo ignoreInfo) { - TestStarted?.Invoke(test, ignoreInfo, tags); + TestStarted?.Invoke(test, ref ignoreInfo); } void RaiseTestFinished(ITestResult result) diff --git a/source/AccUnit/TestSuite/AccessTestSuite.cs b/source/AccUnit/TestSuite/AccessTestSuite.cs index 0d09cd5..e8a43d5 100644 --- a/source/AccUnit/TestSuite/AccessTestSuite.cs +++ b/source/AccUnit/TestSuite/AccessTestSuite.cs @@ -18,7 +18,7 @@ public AccessTestSuite(IAccessApplicationHelper applicationHelper, IVBATestBuild } protected new IAccessApplicationHelper ApplicationHelper => (IAccessApplicationHelper)base.ApplicationHelper; - + protected override void OnTestStarted(TestClassMemberInfo testClassMemberInfo) { TransactionManager = null; diff --git a/source/AccUnit/TestSuite/VBATestSuite.cs b/source/AccUnit/TestSuite/VBATestSuite.cs index e2d58d9..e82fca0 100644 --- a/source/AccUnit/TestSuite/VBATestSuite.cs +++ b/source/AccUnit/TestSuite/VBATestSuite.cs @@ -12,9 +12,9 @@ namespace AccessCodeLib.AccUnit { public class VBATestSuite : IVBATestSuite, IDisposable, ITestData { - public VBATestSuite(IOfficeApplicationHelper applicationHelper, - IVBATestBuilder testBuilder, - ITestRunner testRunner, + public VBATestSuite(IOfficeApplicationHelper applicationHelper, + IVBATestBuilder testBuilder, + ITestRunner testRunner, ITestSummaryFormatter testSummaryFormatter) { using (new BlockLogger()) @@ -26,6 +26,8 @@ public VBATestSuite(IOfficeApplicationHelper applicationHelper, } } + public object Parent { get { return null; } } + private readonly List _accUnitTests = new List(); private readonly List _testFixtures = new List(); private IEnumerable _filterTags = null; @@ -50,11 +52,11 @@ public ITestResultCollector TestResultCollector { _testResultCollector = NewTestResultCollector(); } - return _testResultCollector; + return _testResultCollector; } set { - _testResultCollector = value; + _testResultCollector = value; } } @@ -110,14 +112,14 @@ private void OnTestSuiteTestFixtureStarted(ITestFixture fixture) } using (new BlockLogger(fixture.FullName)) { - RaiseTraceMessage(_summaryFormatter.GetTestFixtureStartedText(fixture)); RaiseTestFixtureStarted(fixture); + RaiseTraceMessage(_summaryFormatter.GetTestFixtureStartedText(fixture)); } } public bool Cancel { get; set; } - void OnTestSuiteTestStarted(ITest test, IgnoreInfo ignoreInfo, ITagList tags) + void OnTestSuiteTestStarted(ITest test, ref IgnoreInfo ignoreInfo) { if (Cancel) { @@ -131,11 +133,13 @@ void OnTestSuiteTestStarted(ITest test, IgnoreInfo ignoreInfo, ITagList tags) var ignoreMember = false; if (memberinfo != null) { - ignoreInfo = memberinfo.IgnoreInfo; - ignoreMember = ignoreInfo.Ignore; + var memberIgnoreInfo = memberinfo.IgnoreInfo; + ignoreMember = memberIgnoreInfo.Ignore; if (ignoreMember) { SetRunstateToIgnored(test); + ignoreInfo.Ignore = true; + ignoreInfo.Comment = memberIgnoreInfo.Comment; } } @@ -166,7 +170,7 @@ void OnTestSuiteTestStarted(ITest test, IgnoreInfo ignoreInfo, ITagList tags) //testcase.DisplayName = memberinfo.DisplayName; } - RaiseTestStarted(test, ignoreInfo, memberinfo?.Tags); + RaiseTestStarted(test, ref ignoreInfo); } } @@ -249,8 +253,12 @@ private void OnTestSuiteTestFinished(ITestResult result) if (Cancel) return; using (new BlockLogger(result.Message)) { - RaiseTraceMessage(_summaryFormatter.GetTestCaseFinishedText(result)); - // TODO: Here, a TestConverter comes along, which does not implement ITestCase, so the following condition always evaluates to false! + if (!(result.Test is IRowTest)) + { + RaiseTraceMessage(_summaryFormatter.GetTestCaseFinishedText(result)); + } + + // TODO: Here, a TestConverter comes along, which does not implement ITest, so the following condition always evaluates to false! if (result.Test is ITest test) { var memberinfo = GetMemberInfo(test); @@ -285,7 +293,7 @@ protected virtual void OnTestFinished(ITestResult result) { } #region Event-Invocators - private void RaiseTestSuiteStarted(ITestSuite testSuite) + protected virtual void RaiseTestSuiteStarted(ITestSuite testSuite/*, IEnumerable tags*/) { TestSuiteStarted?.Invoke(testSuite); } @@ -305,9 +313,9 @@ private void RaiseTestFixtureStarted(ITestFixture fixture) TestFixtureStarted?.Invoke(fixture); } - private void RaiseTestStarted(ITest testcase, IgnoreInfo ignoreInfo, ITagList tags) + protected virtual void RaiseTestStarted(ITest test, ref IgnoreInfo ignoreInfo) { - TestStarted?.Invoke(testcase, ignoreInfo, tags); + TestStarted?.Invoke(test, ref ignoreInfo); } private void RaiseTestFinished(ITestResult result) @@ -317,7 +325,7 @@ private void RaiseTestFinished(ITestResult result) protected virtual void RaiseTraceMessage(string text) { - TestTraceMessage?.Invoke(text, CodeCoverageTracker); + TestTraceMessage?.Invoke(text, CodeCoverageTracker); } #endregion @@ -405,8 +413,11 @@ public virtual IVBATestSuite AddByClassName(string className) public virtual IVBATestSuite AddFromVBProject() { + RaiseTraceMessage("AddFromVBProject:reset"); Reset(ResetMode.RemoveTests); + RaiseTraceMessage("AddFromVBProject:AddToTestSuite"); AddToTestSuite(_testBuilder.CreateTestsFromVBProject()); + RaiseTraceMessage("AddFromVBProject:Completed"); return this; } @@ -426,6 +437,15 @@ public ITestSuite Filter(IEnumerable filterTags) public virtual IVBATestSuite Reset(ResetMode mode = ResetMode.ResetTestData) { + /* + None = 0, + ResetTestData = 1, + RemoveTests = 2, + ResetTestSuite = 4, + RefreshFactoryModule = 8, + DeleteFactoryModule = 16 + */ + if (TestSuiteReset != null) { var cancel = false; @@ -434,17 +454,27 @@ public virtual IVBATestSuite Reset(ResetMode mode = ResetMode.ResetTestData) return this; } + //RaiseTraceMessage("Reset: _testSummary"); _testSummary?.Reset(); + //RaiseTraceMessage("Reset: testSummaryCollector"); if (TestResultCollector is ITestSummaryTestResultCollector testSummaryCollector) testSummaryCollector.Summary.Reset(); //ConstantsReader.Clear(); + //RaiseTraceMessage("Reset: _accUnitTests"); _accUnitTests.Clear(); // clear Memberinfo (maybe source code changed) + //RaiseTraceMessage("Reset: _testCaseInfos"); _testCaseInfos.Clear(); + if ((mode & ResetMode.RemoveTests) == ResetMode.RemoveTests) + { + //RaiseTraceMessage("Reset: _testFixtures"); + _testFixtures.Clear(); + } + if ((mode & ResetMode.DeleteFactoryModule) == ResetMode.DeleteFactoryModule) { _testBuilder.DeleteFactoryCodeModule(); @@ -466,6 +496,7 @@ public virtual IVBATestSuite Run() { TestResultCollector = NewTestResultCollector(); } + //RaiseTestSuiteStarted(this, _filterTags); RaiseTestSuiteStarted(this); var testResult = TestRunner.Run(this, TestResultCollector, _methodFilter, _filterTags); _testSummary = testResult as ITestSummary; diff --git a/source/AccUnit/~trash/CompareTypeHelper.cs b/source/AccUnit/~trash/CompareTypeHelper.cs deleted file mode 100644 index a6e1f38..0000000 --- a/source/AccUnit/~trash/CompareTypeHelper.cs +++ /dev/null @@ -1,34 +0,0 @@ -/* -using System; -using System.Collections.Generic; - -namespace AccessCodeLib.AccUnit.Common -{ - internal static class CompareTypeHelper - { - - public static bool IsIntNumeric(Type T) - { - return IntNumericTypes.Contains(Nullable.GetUnderlyingType(T) ?? T); - } - - private static readonly HashSet IntNumericTypes = new HashSet - { - typeof(long), typeof(int), typeof(short), typeof(byte), typeof(sbyte), - typeof(ulong), typeof(uint), typeof(ushort) - }; - - public static bool IsNumeric(Type T) - { - return NumericTypes.Contains(Nullable.GetUnderlyingType(T) ?? T); - } - private static readonly HashSet NumericTypes = new HashSet - { - typeof(int), typeof(double), typeof(decimal), - typeof(long), typeof(short), typeof(sbyte), - typeof(byte), typeof(ulong), typeof(ushort), - typeof(uint), typeof(float) - }; - } -} -*/ \ No newline at end of file diff --git a/source/AccUnit/~trash/StringTools.cs b/source/AccUnit/~trash/StringTools.cs deleted file mode 100644 index 7d720d2..0000000 --- a/source/AccUnit/~trash/StringTools.cs +++ /dev/null @@ -1,23 +0,0 @@ -/* - using System; - -namespace AccessCodeLib.AccUnit.Common -{ - internal static class StringTools - { - public static string GetInnerXml(string checkString, string tagName) - { - return FindSubString(checkString, "<" + tagName + ">", ""); - } - - private static string FindSubString(string source, string startTag, string endTag) - { - var startPos = source.IndexOf(startTag, StringComparison.InvariantCultureIgnoreCase); - if (startPos < 0) return String.Empty; - startPos += startTag.Length; - var endPos = source.IndexOf(endTag, startPos, StringComparison.InvariantCultureIgnoreCase); - return endPos < 0 ? String.Empty : source.Substring(startPos, endPos - startPos).Trim(); - } - } -} -*/ \ No newline at end of file diff --git a/source/Common/Common.VBIDETools/VbaProjectManagement/VbeManager.cs b/source/Common/Common.VBIDETools/VbaProjectManagement/VbeManager.cs index abe80d3..8ef7dbd 100644 --- a/source/Common/Common.VBIDETools/VbaProjectManagement/VbeManager.cs +++ b/source/Common/Common.VBIDETools/VbaProjectManagement/VbeManager.cs @@ -30,7 +30,7 @@ public void WriteOrCreate(Module module) // TODO: Make this more generic/configurable var codeModule = vbComponent.CodeModule; codeModule.DeleteLines(1, codeModule.CountOfLines); - codeModule.AddFromString("Option Compare Database"); + codeModule.AddFromString("Option Compare Text"); codeModule.AddFromString("Option Explicit"); codeModule.AddFromString(""); codeModule.AddFromString(module.GetNewContent()); diff --git a/vbe-add-In/.gitattributes b/vbe-add-In/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/vbe-add-In/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/vbe-add-In/.gitignore b/vbe-add-In/.gitignore new file mode 100644 index 0000000..1cca802 --- /dev/null +++ b/vbe-add-In/.gitignore @@ -0,0 +1,342 @@ +*.accd* + +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- Backup*.rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb +/MsAccessFiles/lib diff --git a/vbe-add-In/AccUnit.VbeAddIn/AccUnitCommandBarAdapter.cs b/vbe-add-In/AccUnit.VbeAddIn/AccUnitCommandBarAdapter.cs new file mode 100644 index 0000000..8573af8 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/AccUnitCommandBarAdapter.cs @@ -0,0 +1,155 @@ +using AccessCodeLib.AccUnit.VbeAddIn.Properties; +using AccessCodeLib.AccUnit.VbeAddIn.Resources; +using AccessCodeLib.Common.Tools.Logging; +using AccessCodeLib.Common.VBIDETools.Commandbar; +using Microsoft.Office.Core; +using Microsoft.Vbe.Interop; +using System; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + class AccUnitCommandBarAdapter : VbeCommandBarAdapter + { + private const string AccUnitCommandBarName = "AccUnit"; + + public AccUnitCommandBarAdapter(VBE vbe) + : base(vbe) + { } + + public CommandBar AccUnitCommandbar { get; private set; } + + public CommandBarPopup AccUnitSubMenu { get; private set; } + + public void Init() + { + using (new BlockLogger()) + { + CreateAccUnitCommandbar(); + SetupAccUnitToolsSubMenu(); + } + } + + private void CreateAccUnitCommandbar() + { + using (new BlockLogger()) + { + AccUnitCommandbar = VBE.CommandBars.Add(AccUnitCommandBarName, Type.Missing, false, true); + LoadSettings(); + } + } + + private void LoadSettings() + { + using (new BlockLogger()) + { + AccUnitCommandbar.Position = (MsoBarPosition)Settings.Default.CommandbarPosition; + AccUnitCommandbar.RowIndex = Settings.Default.CommandbarRowIndex; + AccUnitCommandbar.Left = Settings.Default.CommandbarLeft; + AccUnitCommandbar.Top = Settings.Default.CommandbarTop; + AccUnitCommandbar.Visible = Settings.Default.CommandbarVisible; + } + } + + private void RemoveAccUnitCommandbar() + { + try + { + SaveSettings(AccUnitCommandbar); + AccUnitCommandbar.Delete(); + AccUnitCommandbar = null; + } + catch (Exception ex) + { + UITools.ShowException(ex); + } + } + + private static void SaveSettings(CommandBar accUnitCommandbar) + { + Settings.Default.CommandbarPosition = (int)accUnitCommandbar.Position; + Settings.Default.CommandbarRowIndex = accUnitCommandbar.RowIndex; + Settings.Default.CommandbarLeft = accUnitCommandbar.Left; + Settings.Default.CommandbarTop = accUnitCommandbar.Top; + Settings.Default.CommandbarVisible = accUnitCommandbar.Visible; + Settings.Default.Save(); + } + + private void SetupAccUnitToolsSubMenu() + { + using (new BlockLogger()) + { + var commandBar = GetToolsCommandBarOrMenuBar(); + AccUnitSubMenu = commandBar.AddPopup(); + // PERF: Reading the settings takes long! + using (new BlockLogger("PERF: Reading VbeCommandbars.ToolsAccUnitSubMenuCaption")) + { + AccUnitSubMenu.Caption = VbeCommandbars.ToolsAccUnitSubMenuCaption; + } + AccUnitSubMenu.BeginGroup = true; + } + } + + private CommandBar GetToolsCommandBarOrMenuBar() + { + try + { + return CommandBarTools; + } + catch + { + return MenuBar; + } + } + + private bool _disposed; + + protected override void Dispose(bool disposing) + { + if (_disposed) return; + + try + { + if (disposing) + { + // managed resources: + } + + // unmanaged resources: + if (AccUnitSubMenu != null) + { + try + { + AccUnitSubMenu.Delete(); + } + finally + { + AccUnitSubMenu = null; + } + } + + + if (AccUnitCommandbar != null) + { + try + { + RemoveAccUnitCommandbar(); + } + finally + { + AccUnitCommandbar = null; + } + } + } + catch (Exception ex) + { + Logger.Log(ex.Message); + } + finally + { + base.Dispose(disposing); + } + _disposed = true; + } + + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/AccessCodeLib.AccUnit.VbeAddIn.csproj b/vbe-add-In/AccUnit.VbeAddIn/AccessCodeLib.AccUnit.VbeAddIn.csproj new file mode 100644 index 0000000..a3bb8af --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/AccessCodeLib.AccUnit.VbeAddIn.csproj @@ -0,0 +1,346 @@ + + + + + Debug + AnyCPU + {179AC295-1F12-462D-B1A1-AEA0F204C6CA} + Library + Properties + AccessCodeLib.AccUnit.VbeAddIn + AccUnit.VbeAddIn + v4.8 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + bin\x86\Debug\ + DEBUG;TRACE + full + x86 + 7.3 + prompt + + + bin\x86\Release\ + TRACE + true + pdbonly + x86 + 7.3 + prompt + + + bin\AzureCI\ + TRACE + true + pdbonly + AnyCPU + 7.3 + prompt + + + bin\x86\AzureCI\ + TRACE + true + pdbonly + x86 + 7.3 + prompt + + + + False + ..\lib\VbeUserControlHost\AccessCodeLib.Common.VbeUserControlHost.dll + + + False + True + ..\..\source\lib\vbide\Extensibility.dll + + + ..\packages\ThammimTech.Microsoft.Vbe.Interop.15.0.0\lib\net20\Microsoft.Vbe.Interop.dll + False + + + False + False + ..\..\source\lib\office\Office.dll + + + + + False + + + + + + + + + + + + + + + + + + + + + + Component + + + GenerateTestMethodsFromCodeModuleDialog.xaml + + + + + + + + + + InsertTestMethodDialog.xaml + + + + InsertTestMethodControl.xaml + + + + + + + + + + CheckableTreeView.xaml + + + + + + + TestExplorerView.xaml + + + + + + + + ImportExportWindow.xaml + + + + LoggerBoxControl.xaml + + + UserControl + + + LoggerControl.cs + + + + + + + True + True + Resources.resx + + + True + True + Settings.settings + + + + True + True + Icons.resx + + + True + True + MessageStrings.resx + + + True + True + ToolTips.resx + + + True + True + UserControls.resx + + + True + True + VbeCommandbars.resx + + + + + SelectControl.xaml + + + + + + + TestExplorerTreeView.xaml + + + + + + + + + + + + + + + {1575d69a-c503-4149-b3a9-2ce188b19c15} + AccessCodeLib.AccUnit + True + + + {7af24615-91b3-4775-bc6e-c8986f980b57} + AccessCodeLib.Common.Tools + + + {9fa679c2-82c0-42dc-a34f-f78a9012eeeb} + AccessCodeLib.Common.VBIDETools + + + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + LoggerControl.cs + + + ResXFileCodeGenerator + Resources.Designer.cs + + + ResXFileCodeGenerator + Icons.Designer.cs + + + ResXFileCodeGenerator + MessageStrings.Designer.cs + + + ResXFileCodeGenerator + ToolTips.Designer.cs + + + ResXFileCodeGenerator + UserControls.Designer.cs + Designer + + + ResXFileCodeGenerator + VbeCommandbars.Designer.cs + Designer + + + + + + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + MSBuild:Compile + Designer + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vbe-add-In/AccUnit.VbeAddIn/AddInManager.cs b/vbe-add-In/AccUnit.VbeAddIn/AddInManager.cs new file mode 100644 index 0000000..cd3b485 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/AddInManager.cs @@ -0,0 +1,560 @@ +using AccessCodeLib.AccUnit.Configuration; +using AccessCodeLib.AccUnit.Interfaces; +using AccessCodeLib.AccUnit.VbeAddIn.Properties; +using AccessCodeLib.AccUnit.VbeAddIn.TestExplorer; +using AccessCodeLib.Common.Tools.Logging; +using AccessCodeLib.Common.VBIDETools; +using AccessCodeLib.Common.VBIDETools.Integration; +using Microsoft.Vbe.Interop; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Reflection; +using Timer = System.Windows.Forms.Timer; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + internal class AddInManager : IDisposable + { + private AddIn _addIn; + private Timer _startupTimer; + private OfficeApplicationHelper _officeApplicationHelper; + + private readonly VbeIntegrationManager _vbeIntegrationManager = new VbeIntegrationManager(); + private readonly TestSuiteManager _testSuiteManager = new TestSuiteManager(); + + private readonly AccUnitCommandBarAdapter _commandBarsAdapter; + private readonly TestStarter _testStarter = new TestStarter(); + + private readonly TestExplorerManager _testExplorerManager; + + /* + private readonly TagListManager _tagListManager = new TagListManager(); + + private readonly DialogManager _dialogManager = new DialogManager(); + private readonly TestTemplateGenerator _testTemplateGenerator = new TestTemplateGenerator(); + private AccSpecCommandBarAdapterClient _accSpecCommandBarAdapterClient; + private AccSpecManager _accSpecManager; + + + */ + + //private VbaProgrammingTools _vbaProgrammingTools; + + public AddInManager(AddIn addIn) + { + using (new BlockLogger()) + { + _addIn = addIn; + + /* + _tagListManager.AddIn = addIn; + _testListAndResultManager.AddIn = addIn; + + + if (Settings.Default.VbaProgrammingToolsEnabled) + { + _vbaProgrammingTools = new VbaProgrammingTools(); + } + */ + + InitOfficeApplicationHelper(); + //InitAccSpec(); + + var testExplorer = new TestExplorerView(); + var vbeControl = new VbeUserControl(AddIn, "AccUnit Test Explorer", TestExplorerInfo.PositionGuid, testExplorer, false); + _testExplorerManager = new TestExplorerManager(vbeControl); + + _commandBarsAdapter = new AccUnitCommandBarAdapter(VBE); + } + } + + /* + private void InitAccSpec() + { + VbeManager vbeManager = null; + var currentVbProject = _officeApplicationHelper.CurrentVBProject; + if (currentVbProject != null) + vbeManager = new VbeManager(currentVbProject); + + _accSpecManager = new AccSpecManager(vbeManager); + _accSpecCommandBarAdapterClient = new AccSpecCommandBarAdapterClient(_accSpecManager); + _vbeIntegrationManager.ScanningForTestModules += OnScanningForTestModules; + _testStarter.ScanningForTestModules += OnScanningForTestModules; + } + */ + + public void Init() + { + using (new BlockLogger()) + { + if (!ApplicationSupportsAddIn) + return; + + try + { + InitTestSuiteManager(); + InitVbeWindows(); + InitVbeIntegrationManager(); + + _testExplorerManager.RunTests += OnRunTests; + _testStarter.ShowUIMessage += OnShowUIMessage; + + InitCommandBarsAdapter(); + } + catch (Exception ex) + { + UITools.ShowException(ex); + } + } + } + + private void OnRunTests(object sender, RunTestsEventArgs e) + { + _testStarter.RunTests(e.TestClassList, e.BreakOnAllErrors); + } + + static void OnShowUIMessage(object sender, MessageEventArgs e) + { + UITools.ShowMessage(e.Message, e.Buttons, e.Icon, e.DefaultButton); + e.MessageDisplayed = true; + } + + private bool ApplicationSupportsAddIn => !(_officeApplicationHelper is VbeOnlyApplicatonHelper); + + private void InitCommandBarsAdapter() + { + using (new BlockLogger()) + { + _commandBarsAdapter.Init(); + _commandBarsAdapter.AddClient(_testStarter); + _commandBarsAdapter.AddClient(_vbeIntegrationManager); + _commandBarsAdapter.AddClient(_testExplorerManager); + + /* + _commandBarsAdapter.AddClient(_tagListManager); + _commandBarsAdapter.AddClient(_testTemplateGenerator); + + _commandBarsAdapter.AddClient(_dialogManager); + */ + + /* + if (UserSettings.Current.IsAccSpecEnabled) + { + _commandBarsAdapter.AddClient(_accSpecCommandBarAdapterClient); + } + + if (_vbaProgrammingTools != null) + { + AddVbaProgrammingToolsToCommandBar(); + } + */ + } + } + + /* + private void AddVbaProgrammingToolsToCommandBar() + { + using (new BlockLogger()) + { + _commandBarsAdapter.AddClient(_vbaProgrammingTools); + } + } + */ + + private void InitTestSuiteManager() + { + using (new BlockLogger()) + { + _testSuiteManager.TestResultReporterRequest += TestSuiteManager_TestResultReporterRequest; + _testStarter.TestSuiteManager = _testSuiteManager; + } + } + + private void TestSuiteManager_TestResultReporterRequest(ref IList reporters) + { + var loggerControl = new LoggerControl(); + loggerControl.LogTextBox.AppendText("..."); + var vbeControl = new VbeUserControl(AddIn, "AccUnit Test Result Logger", LoggerControlInfo.PositionGuid, loggerControl); + reporters.Add(new LoggerControlReporter(vbeControl)); + + /* WPF not refeshing during test run (without async test run) ... + var loggerControl = new LoggerBoxControl(); + loggerControl.LoggerTextBox.AppendText("..."); + var vbeControl = new VbeUserControl(AddIn, "AccUnit Test Result Logger", LoggerControlInfo.PositionGuid, loggerControl); + reporters.Add(new LoggerBoxControlReporter(vbeControl)); + */ + + if (!reporters.Contains(_testExplorerManager)) + { + reporters.Add(_testExplorerManager); + } + } + + private void InitVbeIntegrationManager() + { + using (new BlockLogger()) + { + //_tagListManager.VbeIntegrationManager = _vbeIntegrationManager; + _testExplorerManager.VbeIntegrationManager = _vbeIntegrationManager; + _testStarter.VbeIntegrationManager = _vbeIntegrationManager; + + //_testTemplateGenerator.VbeIntegrationManager = _vbeIntegrationManager; + + _vbeIntegrationManager.VBProjectChanged += VbeIntegrationManagerOnVBProjectChanged; + } + } + + void VbeIntegrationManagerOnVBProjectChanged(object sender, VbProjectEventArgs e) + { + /* + var accessTestSuite = _testSuiteManager.TestSuite as AccessTestSuite; + if (accessTestSuite != null) + { + accessTestSuite.HostApplication = _officeApplicationHelper.Application; + } + else + { + var vbaTestSuite = (VBATestSuite)_testSuiteManager.TestSuite; + vbaTestSuite.HostApplication = _officeApplicationHelper.Application; + vbaTestSuite.ActiveVBProject = e.VBProject; + } + */ + TestClassManager.ApplicationHelper = _officeApplicationHelper; + //_accSpecManager.VbeManager = new VbeManager(_officeApplicationHelper.CurrentVBProject); + + } + + void OnScanningForTestModules(object sender, EventArgs e) + { + /* + if (UserSettings.Current.IsAccSpecEnabled) + { + _accSpecManager.TransformFeatures(); + } + */ + } + + private TestClassManager TestClassManager => _vbeIntegrationManager.TestClassManager; + + #region ad Bridge + + private AddInManagerBridge _addInManagerBridge; + + public AddInManagerBridge Bridge + { + get + { + if (_addInManagerBridge == null) + { + CreateAddInManagerBridge(); + } + return _addInManagerBridge; + } + } + + private void CreateAddInManagerBridge() + { + using (new BlockLogger()) + { + _addInManagerBridge = new AddInManagerBridge(); + _addInManagerBridge.TestSuiteRequest += AddInBridgeTestSuiteRequest; + _addInManagerBridge.HostApplicationInitialized += AddInBridgeHostApplicationInitialized; + _addInManagerBridge.ConstraintBuilderRequest += AddInBridgeConstraintBuilderRequest; + _addInManagerBridge.AssertRequest += AddInBridgeAssertRequest; + } + } + + private void AddInBridgeAssertRequest(out Interop.IAssert assert) + { + assert = _testSuiteManager.Assert; + } + + private void AddInBridgeConstraintBuilderRequest(out Interop.IConstraintBuilder constraintBuilder) + { + constraintBuilder = _testSuiteManager.ConstraintBuilder; + } + + void AddInBridgeTestSuiteRequest(out IVBATestSuite suite) + { + suite = _testSuiteManager.TestSuite; + } + + void AddInBridgeHostApplicationInitialized(object application) + { + InitOfficeApplicationHelper(application); + } + + private void InitOfficeApplicationHelper(object hostApplication = null) + { + using (new BlockLogger()) + { + _officeApplicationHelper = HostApplicationTools.GetOfficeApplicationHelper(VBE, ref hostApplication); + _vbeIntegrationManager.OfficeApplicationHelper = _officeApplicationHelper; + _testSuiteManager.OfficeApplicationHelper = _officeApplicationHelper; + + /* + if (_vbaProgrammingTools != null) + { + InitVbaProgrammingTools(_officeApplicationHelper); + } + */ + } + } + + #endregion + /* + private void InitVbaProgrammingTools(OfficeApplicationHelper officeApplicationHelper) + { + using (new BlockLogger()) + { + _vbaProgrammingTools.OfficeApplicationHelper = officeApplicationHelper; + } + } + */ + #region ad VbeWindow + + private void InitVbeWindows() + { + bool testListVisible; + using (new BlockLogger("Getting testListVisible")) + { + // PERF: This takes long, consider retrieving the values later + using (new BlockLogger("PERF: Reading some settings")) + { + bool restoreVbeWindowsStateOnLoad; + using (new BlockLogger("PERF: Reading 1st setting from Settings.Default")) + { + restoreVbeWindowsStateOnLoad = Settings.Default.RestoreVbeWindowsStateOnLoad; + } + var listVisible = Settings.Default.TestListVisible; + testListVisible = restoreVbeWindowsStateOnLoad && listVisible; + } + } + /* + using (new BlockLogger("Settings.Default.TestListVisible = " + testListVisible)) + { + if (!testListVisible) return; + _testListAndResultManager.ShowTestListWindow(true, false); + InitStartUpTimer(1000, true); + } + */ + } + + /* + private void InitStartUpTimer(int interval, bool start) + { + if (_startupTimer == null) + { + _startupTimer = new Timer(); + _startupTimer.Tick += StartupTimerTick; + } + _startupTimer.Interval = interval; + if (start) + _startupTimer.Start(); + } + */ + + private void DisposeStartUpTimer() + { + if (_startupTimer == null) + return; + + using (new BlockLogger()) + { + try + { + _startupTimer.Stop(); + } + catch (Exception ex) + { + Logger.Log(ex); + } + + try + { + _startupTimer.Tick -= StartupTimerTick; + } + catch (Exception ex) + { + Logger.Log(ex); + } + + try + { + _startupTimer.Dispose(); + _startupTimer = null; + Logger.Log("_startupTimer disposed"); + } + catch (Exception ex) + { + Logger.Log(ex); + } + } + } + + void StartupTimerTick(object sender, EventArgs e) + { + _startupTimer.Stop(); + //_testListAndResultManager.AddTestClassListToTestListAndResultWindow(); + DisposeStartUpTimer(); + } + + #endregion + + public static string FriendlyName => $"AccUnit {FileVersion}"; + + public static string FileVersion + { + get + { + var version = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location); + return version.FileVersion; + } + } + + private VBE VBE => AddIn.VBE; + + private AddIn AddIn => _addIn; + + + #region IDisposable Support + + bool _disposed; + + protected virtual void Dispose(bool disposing) + { + using (new BlockLogger()) + { + if (_disposed) return; + + if (disposing) + { + try + { + DisposeManagedResources(); + } + catch (Exception ex) + { + Logger.Log(ex); + } + } + + try + { + DisposeUnManagedResources(); + } + catch (Exception ex) + { + Logger.Log(ex); + } + + GC.Collect(); + GC.WaitForPendingFinalizers(); + GC.Collect(); + + _disposed = true; + } + } + + private void DisposeUnManagedResources() + { + _addIn = null; + } + + private void DisposeManagedResources() + { + using (new BlockLogger()) + { + try + { + DisposeStartUpTimer(); + DisposeVbaProgrammingTools(); + + _testStarter.Dispose(); + + //_testTemplateGenerator.Dispose(); + + _vbeIntegrationManager.Dispose(); + + try + { + _commandBarsAdapter.Dispose(); + } + catch (Exception ex) + { + Logger.Log(ex); + } + + _testSuiteManager.Dispose(); + + DisposeAddInManagerBridge(); + + } + catch (Exception ex) + { + Logger.Log(ex); + } + + try + { + _officeApplicationHelper.Dispose(); + _officeApplicationHelper = null; + } + catch (Exception ex) + { + Logger.Log(ex); + } + } + } + + private void DisposeVbaProgrammingTools() + { + //_vbaProgrammingTools?.Dispose(); + //_vbaProgrammingTools = null; + } + + private void DisposeAddInManagerBridge() + { + using (new BlockLogger()) + { + if (_addInManagerBridge == null) + return; + + try + { + RemoveEventHandler(_addInManagerBridge); + Logger.Log("_addInManagerBridge disposed"); + } + finally + { + _addInManagerBridge = null; + } + } + } + + private void RemoveEventHandler(AddInManagerBridge addInManagerBridge) + { + addInManagerBridge.TestSuiteRequest -= AddInBridgeTestSuiteRequest; + addInManagerBridge.HostApplicationInitialized -= AddInBridgeHostApplicationInitialized; + } + + public void Dispose() + { + using (new BlockLogger()) + { + Dispose(true); + GC.SuppressFinalize(this); + } + } + + ~AddInManager() + { + Logger.Log("~AddInManager"); + Dispose(false); + Logger.Log("~AddInManager completed"); + } + + #endregion + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/AddInManagerBridge.cs b/vbe-add-In/AccUnit.VbeAddIn/AddInManagerBridge.cs new file mode 100644 index 0000000..81a26ce --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/AddInManagerBridge.cs @@ -0,0 +1,76 @@ +using AccessCodeLib.AccUnit.Interop; +using System.Runtime.InteropServices; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + [ComVisible(true)] + [Guid("E69DF056-1CB6-4977-8554-78F7FFF6BA0A")] + [ClassInterface(ClassInterfaceType.None)] + [ProgId("AccUnit.AddInManager")] + public class AddInManagerBridge : IAddInManagerBridge + { + public delegate void TestSuiteRequestEventHandler(out Interfaces.IVBATestSuite testsuite); + public event TestSuiteRequestEventHandler TestSuiteRequest; + + public delegate void ConstraintBuilderRequestEventHandler(out IConstraintBuilder constraintBuilder); + public event ConstraintBuilderRequestEventHandler ConstraintBuilderRequest; + + public delegate void AssertRequestEventHandler(out IAssert assert); + public event AssertRequestEventHandler AssertRequest; + + public delegate void HostApplicationInitializedEventHandler(object hostapplication); + + public event HostApplicationInitializedEventHandler HostApplicationInitialized; + + public object Application + { + set + { + HostApplicationInitialized?.Invoke(value); + } + } + + public Interfaces.IVBATestSuite TestSuite(TestReportOutput OutputTo = TestReportOutput.DebugPrint) + { + Interfaces.IVBATestSuite suite = null; + TestSuiteRequest?.Invoke(out suite); + return suite; + } + + public IConstraintBuilder ConstraintBuilder + { + get + { + IConstraintBuilder constraintBuilder = null; + ConstraintBuilderRequest?.Invoke(out constraintBuilder); + return constraintBuilder; + } + } + + public IAssert Assert + { + get + { + IAssert assert = null; + AssertRequest?.Invoke(out assert); + return assert; + } + } + } + + [ComVisible(true)] + [Guid("0EEEA3E7-68D6-49BA-8536-572E69CCCEF0")] + public interface IAddInManagerBridge + { + object Application { set; } + Interfaces.IVBATestSuite TestSuite(TestReportOutput OutputTo = TestReportOutput.DebugPrint); + IConstraintBuilder ConstraintBuilder { get; } + IAssert Assert { get; } + } + + public enum TestReportOutput + { + DebugPrint = 1, + LogFile = 2 + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/AxHostConverter.cs b/vbe-add-In/AccUnit.VbeAddIn/AxHostConverter.cs new file mode 100644 index 0000000..cf64028 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/AxHostConverter.cs @@ -0,0 +1,34 @@ +using AccessCodeLib.AccUnit.VbeAddIn.Resources; +using AccessCodeLib.Common.Tools.Logging; +using stdole; +using System.Drawing; +using System.Windows.Forms; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + /// @see http://blogs.msdn.com/b/andreww/archive/2007/07/30/converting-between-ipicturedisp-and-system-drawing-image.aspx + public class AxHostConverter : AxHost + { + private AxHostConverter() : base("") { } + + public static IPictureDisp ImageToPictureDisp(Image image) + { + using (new BlockLogger()) + { + return (IPictureDisp)GetIPictureDispFromPicture(image); + } + } + + public static Image PictureDispToImage(IPictureDisp pictureDisp) + { + return GetPictureFromIPicture(pictureDisp); + } + + private static IPictureDisp _runTestPictureDisp; + public static IPictureDisp RunTestPictureDisp + { + get { return _runTestPictureDisp ?? (_runTestPictureDisp = ImageToPictureDisp(Icons.runtest)); } + } + + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/ComRegistration.cs b/vbe-add-In/AccUnit.VbeAddIn/ComRegistration.cs new file mode 100644 index 0000000..0f4c855 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/ComRegistration.cs @@ -0,0 +1,93 @@ +using AccessCodeLib.Common.Tools.Logging; +using Microsoft.Win32; +using System; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + public static class ComRegistration + { + public const string ComProgId = "AccUnit.VbeAddIn.Connect"; + private const string HkcuSubKey = @"Software\Microsoft\VBA\VBE\6.0\Addins\" + ComProgId; + + public static void ComRegisterClass(Type t) + { + using (new BlockLogger()) + { + CreateHkcrSubkey(t); + RegisterVbeAddIn(); + } + } + + public static void ComUnregisterClass(Type t) + { + using (new BlockLogger()) + { + DeleteHkcuSubkey(HkcuSubKey); + DeleteHkcrSubkey(GetHkcrSubKey(t)); + } + } + + private static void CreateHkcrSubkey(Type t) + { + using (new BlockLogger()) + { + var key = Registry.ClassesRoot.CreateSubKey(GetHkcrSubKey(t)); + if (key != null) + { + key.CreateSubKey("Programmable"); + key.SetValue("", ComProgId); + var subkey = key.CreateSubKey(@"InprocServer32\"); + subkey?.SetValue("", Environment.GetFolderPath(Environment.SpecialFolder.System) + @"\mscoree.dll"); + } + key = Registry.ClassesRoot.CreateSubKey(ComProgId); + if (key == null) return; + key.SetValue("", ComProgId); + key.Close(); + } + } + + private static void RegisterVbeAddIn() + { + using (new BlockLogger()) + { + var key = Registry.CurrentUser.CreateSubKey(HkcuSubKey); + if (key == null) return; + key.SetValue("LoadBehavior", 3, RegistryValueKind.DWord); + key.SetValue("CommandLineSafe", 0, RegistryValueKind.DWord); + key.SetValue("FriendlyName", AddInManager.FriendlyName, RegistryValueKind.String); + key.SetValue("Description", "AccUnit VBIDE Add-In for Access/VBA", RegistryValueKind.String); + key.Close(); + } + } + + private static string GetHkcrSubKey(Type t) + { + return "CLSID\\{" + t.GUID.ToString().ToUpper() + "}"; + } + + private static void DeleteHkcuSubkey(string subkey) + { + SafeDeleteRegistrySubkey(Registry.CurrentUser, "HKCU", subkey); + } + + private static void DeleteHkcrSubkey(string subkey) + { + SafeDeleteRegistrySubkey(Registry.ClassesRoot, "HKCR", subkey); + } + + private static void SafeDeleteRegistrySubkey(RegistryKey registryKey, string registryKeyName, string subkey) + { + using (new BlockLogger($"Deleting {registryKeyName} sub key {subkey}")) + { + try + { + registryKey.DeleteSubKeyTree(subkey); + } + catch (Exception exception) + { + Logger.Log(exception); + } + } + } + } +} \ No newline at end of file diff --git a/vbe-add-In/AccUnit.VbeAddIn/CommitMethodNameEventArgs.cs b/vbe-add-In/AccUnit.VbeAddIn/CommitMethodNameEventArgs.cs new file mode 100644 index 0000000..5be096b --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/CommitMethodNameEventArgs.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + public class CommitInsertTestMethodEventArgs : EventArgs + { + public CommitInsertTestMethodEventArgs(string methodUnderTest, string stateUnderTest, string expectedBehaviour) + { + MethodUnderTest = methodUnderTest; + StateUnderTest = stateUnderTest; + ExpectedBehaviour = expectedBehaviour; + } + + public string MethodUnderTest { get; private set; } + public string StateUnderTest { get; private set; } + public string ExpectedBehaviour { get; private set; } + } + + public class CommitInsertTestMethodsEventArgs : EventArgs + { + public CommitInsertTestMethodsEventArgs(string testClass, IEnumerable methodsUnderTest, string stateUnderTest, string expectedBehaviour) + { + TestClass = testClass; + MethodsUnderTest = methodsUnderTest; + StateUnderTest = stateUnderTest; + ExpectedBehaviour = expectedBehaviour; + Cancel = false; + } + + public string TestClass { get; private set; } + public IEnumerable MethodsUnderTest { get; private set; } + public string StateUnderTest { get; private set; } + public string ExpectedBehaviour { get; private set; } + public bool Cancel { get; set; } + } + +} \ No newline at end of file diff --git a/vbe-add-In/AccUnit.VbeAddIn/Connect.cs b/vbe-add-In/AccUnit.VbeAddIn/Connect.cs new file mode 100644 index 0000000..76819bc --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/Connect.cs @@ -0,0 +1,217 @@ +using AccessCodeLib.Common.Tools.Logging; +using System; +using System.Runtime.InteropServices; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + + #region Read me for Add-in installation and setup information. + // When run, the Add-in wizard prepared the registry for the Add-in. + // At a later time, if the Add-in becomes unavailable for reasons such as: + // 1) You moved this project to a computer other than which is was originally created on. + // 2) You chose 'Yes' when presented with a message asking if you wish to remove the Add-in. + // 3) Registry corruption. + // you will need to re-register the Add-in by building the MyAddin1Setup project, + // right click the project in the Solution Explorer, then choose install. + #endregion + + /// + /// The object for implementing an Add-in. + /// + /// + [ComVisible(true)] + [Guid("F15F18C3-CA43-421E-9585-6A04F51C5786")] + [ProgId(ComRegistration.ComProgId)] + public class Connect : Object, Extensibility.IDTExtensibility2, IDisposable + { + #region IDTExtensibility2 implementation + + Microsoft.Vbe.Interop.AddIn _addInInstance; + private AddInManager AddInManager { get; set; } + + /// + /// Implements the OnConnection method of the IDTExtensibility2 interface. + /// Receives notification that the Add-in is being loaded. + /// + /// + /// Root object of the host application. + /// + /// + /// Describes how the Add-in is being loaded. + /// + /// + /// Object representing this Add-in. + /// + /// + /// + public void OnConnection(object application, Extensibility.ext_ConnectMode connectMode, object addInInstance, ref Array custom) + { + using (new BlockLogger()) + { + try + { + _addInInstance = (Microsoft.Vbe.Interop.AddIn)addInInstance; + AddInManager = new AddInManager(_addInInstance); + AddInManager.Init(); + + _addInInstance.Object = AddInManager.Bridge; + } + catch (Exception ex) + { + UITools.ShowException(ex); + } + } + } + + /// + /// Implements the OnDisconnection method of the IDTExtensibility2 interface. + /// Receives notification that the Add-in is being unloaded. + /// + /// + /// Describes how the Add-in is being unloaded. + /// + /// + /// Array of parameters that are host application specific. + /// + /// + public void OnDisconnection(Extensibility.ext_DisconnectMode disconnectMode, ref Array custom) + { + using (new BlockLogger()) + { + try + { + Dispose(); + } + catch (Exception xcp) + { + Logger.Log(xcp); + } + } + } + + /// + /// Implements the OnAddInsUpdate method of the IDTExtensibility2 interface. + /// Receives notification that the collection of Add-ins has changed. + /// + /// + /// Array of parameters that are host application specific. + /// + /// + public void OnAddInsUpdate(ref Array custom) + { + Logger.Log(); + } + + /// + /// Implements the OnStartupComplete method of the IDTExtensibility2 interface. + /// Receives notification that the host application has completed loading. + /// + /// + /// Array of parameters that are host application specific. + /// + /// + public void OnStartupComplete(ref Array custom) + { + Logger.Log(); + } + + /// + /// Implements the OnBeginShutdown method of the IDTExtensibility2 interface. + /// Receives notification that the host application is being unloaded. + /// + /// + /// Array of parameters that are host application specific. + /// + /// + public void OnBeginShutdown(ref Array custom) + { + try + { + using (new BlockLogger()) + { + try + { + _addInInstance.Object = null; + } + catch (Exception ex) + { + Logger.Log(ex); + } + } + } + catch { /* ignore */} + } + + #endregion + + #region COM register/unregister support + [ComRegisterFunction] + public static void RegisterClass(Type t) + { + ComRegistration.ComRegisterClass(t); + } + + [ComUnregisterFunction] + public static void UnregisterClass(Type t) + { + ComRegistration.ComUnregisterClass(t); + } + + #endregion + + #region IDisposable Support + + public delegate void DisposeEventHandler(object sender); + public event DisposeEventHandler Disposed; + + bool _disposed; + + protected virtual void Dispose(bool disposing) + { + using (new BlockLogger()) + { + if (_disposed) + { + Logger.Log("_disposed == true => Exit Dispose()"); + return; + } + + if (disposing) + { + Logger.Log("disposing == true"); + if (AddInManager != null) + { + Logger.Log("Start AddInManager.Dispose ..."); + AddInManager.Dispose(); + AddInManager = null; + } + } + + _addInInstance = null; + + GC.Collect(); + GC.WaitForPendingFinalizers(); + GC.Collect(); + + _disposed = true; + + Disposed?.Invoke(this); + } + } + + public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + ~Connect() + { + Logger.Log("~Connect"); + Dispose(false); + Logger.Log("~Connect completed"); + } + + #endregion + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/GetTestClassInfoEventArgs.cs b/vbe-add-In/AccUnit.VbeAddIn/GetTestClassInfoEventArgs.cs new file mode 100644 index 0000000..471aa72 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/GetTestClassInfoEventArgs.cs @@ -0,0 +1,15 @@ +using System; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + public class GetTestClassInfoEventArgs : EventArgs + { + public GetTestClassInfoEventArgs(string className) + { + ClassName = className; + } + + public string ClassName { get; } + public TestClassInfo TestClassInfo { get; set; } + } +} \ No newline at end of file diff --git a/vbe-add-In/AccUnit.VbeAddIn/InsertTestMethod/CheckableCodeModulTreeViewItem.cs b/vbe-add-In/AccUnit.VbeAddIn/InsertTestMethod/CheckableCodeModulTreeViewItem.cs new file mode 100644 index 0000000..c919e05 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/InsertTestMethod/CheckableCodeModulTreeViewItem.cs @@ -0,0 +1,10 @@ +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + public class CheckableCodeModuleGroupTreeViewItem : CheckableTreeViewItemBase + { + public CheckableCodeModuleGroupTreeViewItem(string fullName, string name, bool isChecked = false) + : base(fullName, name, isChecked) + { + } + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/InsertTestMethod/CheckableCodeModuleMember.cs b/vbe-add-In/AccUnit.VbeAddIn/InsertTestMethod/CheckableCodeModuleMember.cs new file mode 100644 index 0000000..50d7dae --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/InsertTestMethod/CheckableCodeModuleMember.cs @@ -0,0 +1,20 @@ +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + public class CheckableCodeModuleMember : CheckableItem + { + private readonly CodeModuleMemberWithMarker _member; + + public CheckableCodeModuleMember(CodeModuleMemberWithMarker member) + : base(member.Name, member.Name, member.Marked) + { + _member = member; + } + + internal override void SetChecked(bool value) + { + base.SetChecked(value); + _member.Marked = value; + OnPropertyChanged(nameof(IsChecked)); + } + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/InsertTestMethod/CodeModuleInfoTreeViewItem.cs b/vbe-add-In/AccUnit.VbeAddIn/InsertTestMethod/CodeModuleInfoTreeViewItem.cs new file mode 100644 index 0000000..25d18e4 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/InsertTestMethod/CodeModuleInfoTreeViewItem.cs @@ -0,0 +1,10 @@ +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + public class CodeModuleInfoTreeViewItem : CheckableTreeViewItemBase + { + public CodeModuleInfoTreeViewItem(string fullName, string name, bool isChecked = false) + : base(fullName, name, isChecked) + { + } + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/InsertTestMethod/GenerateTestMethodsFromCodeModuleDialog.xaml b/vbe-add-In/AccUnit.VbeAddIn/InsertTestMethod/GenerateTestMethodsFromCodeModuleDialog.xaml new file mode 100644 index 0000000..556744f --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/InsertTestMethod/GenerateTestMethodsFromCodeModuleDialog.xaml @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vbe-add-In/AccUnit.VbeAddIn/SelectLists/SelectControl.xaml.cs b/vbe-add-In/AccUnit.VbeAddIn/SelectLists/SelectControl.xaml.cs new file mode 100644 index 0000000..0d9174d --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/SelectLists/SelectControl.xaml.cs @@ -0,0 +1,12 @@ +using System.Windows.Controls; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + public partial class SelectControl : UserControl + { + public SelectControl() + { + InitializeComponent(); + } + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/SelectLists/SelectControlViewModel.cs b/vbe-add-In/AccUnit.VbeAddIn/SelectLists/SelectControlViewModel.cs new file mode 100644 index 0000000..10fb914 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/SelectLists/SelectControlViewModel.cs @@ -0,0 +1,174 @@ +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.Linq; +using System.Windows.Input; +using System.Windows.Media; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + public class SelectControlViewModel : INotifyPropertyChanged + { + private string _selectAllCheckBoxText = Resources.UserControls.SelectListSelectAllCheckboxCaption; + private string _commitButtonText = Resources.UserControls.SelectListCommitButtonText; + + public delegate void CommitSelectedItemsEventHandler(SelectControlViewModel sender, CheckableItemsEventArgs e); + public event CommitSelectedItemsEventHandler ItemsSelected; + + public delegate void RefreshItemListEventHandler(SelectControlViewModel sender, CheckableItemsEventArgs e); + public event RefreshItemListEventHandler RefreshList; + + public SelectControlViewModel() + { + RefreshCommand = new RelayCommand(Refresh); + CommitCommand = new RelayCommand(Commit); + } + + public SelectControlViewModel( + string title, + string selectAllCheckBoxText, + string commitButtonText, + bool optionalCheckBoxVisibility = false, + string optionalCheckBoxText = null) + : this() + { + _selectAllCheckBoxText = selectAllCheckBoxText; + _commitButtonText = commitButtonText; + _title = title; + OptionalCheckboxVisibility = optionalCheckBoxVisibility; + OptionalCheckBoxText = optionalCheckBoxText; + } + + public event PropertyChangedEventHandler PropertyChanged; + protected virtual void OnPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + private string _title = "Select Items"; + public string Title + { + get { return _title; } + set + { + if (_title != value) + { + _title = value; + OnPropertyChanged(nameof(Title)); + } + } + } + + private bool _selectAll = false; + + public bool SelectAll + { + get { return _selectAll; } + set + { + if (_selectAll != value) + { + _selectAll = value; + if (Items != null) + { + foreach (var item in Items) + { + item.IsChecked = value; + } + } + OnPropertyChanged(nameof(SelectAll)); + } + } + } + + public string SelectAllCheckBoxText + { + get => _selectAllCheckBoxText; + set + { + if (_selectAllCheckBoxText != value) + { + _selectAllCheckBoxText = value; + OnPropertyChanged(nameof(SelectAllCheckBoxText)); + } + } + } + + public string CommitButtonText + { + get => _commitButtonText; + set + { + if (_commitButtonText != value) + { + _commitButtonText = value; + OnPropertyChanged(nameof(CommitButtonText)); + } + } + } + + public ICommand RefreshCommand { get; } + public ICommand CommitCommand { get; } + public ImageSource RefreshCommandImageSource + { + get + { + return UITools.ConvertBitmapToBitmapSource(Resources.Icons.refresh_green); + } + } + + protected virtual void Refresh() + { + RefreshList?.Invoke(this, new CheckableItemsEventArgs(Items)); + } + + protected virtual void Commit() + { + var e = new CheckableItemsEventArgs(SelectedItems); + var close = true; + ItemsSelected?.Invoke(this, e); + if (close) + { + //Close(); + } + } + + public ICollection SelectedItems + { + get => Items.Where(i => i.IsChecked).ToList(); + } + + private ObservableCollection _items = new ObservableCollection(); + public ObservableCollection Items + { + get { return _items; } + set + { + if (_items != value) + { + _items = value; + OnPropertyChanged("Items"); + } + } + } + + + + public string OptionalCheckBoxText { get; private set; } + public bool OptionalCheckboxVisibility { get; private set; } = false; + + private bool _optionalCheckboxChecked = false; + public bool OptionalCheckboxChecked + { + get { return _optionalCheckboxChecked; } + set + { + _optionalCheckboxChecked = value; + OnPropertyChanged(nameof(OptionalCheckboxChecked)); + } + + + } + + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/Settings.cs b/vbe-add-In/AccUnit.VbeAddIn/Settings.cs new file mode 100644 index 0000000..864b955 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/Settings.cs @@ -0,0 +1,33 @@ +namespace AccessCodeLib.AccUnit.VbeAddIn.Properties +{ + + + // Diese Klasse ermöglicht die Behandlung bestimmter Ereignisse der Einstellungsklasse: + // Das SettingChanging-Ereignis wird ausgelöst, bevor der Wert einer Einstellung geändert wird. + // Das PropertyChanged-Ereignis wird ausgelöst, nachdem der Wert einer Einstellung geändert wurde. + // Das SettingsLoaded-Ereignis wird ausgelöst, nachdem die Einstellungswerte geladen wurden. + // Das SettingsSaving-Ereignis wird ausgelöst, bevor die Einstellungswerte gespeichert werden. + internal sealed partial class Settings + { + + public Settings() + { + // // Heben Sie die Auskommentierung der unten angezeigten Zeilen auf, um Ereignishandler zum Speichern und Ändern von Einstellungen hinzuzufügen: + // + // this.SettingChanging += this.SettingChangingEventHandler; + // + // this.SettingsSaving += this.SettingsSavingEventHandler; + // + } + + private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) + { + // Fügen Sie hier Code zum Behandeln des SettingChangingEvent-Ereignisses hinzu. + } + + private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) + { + // Fügen Sie hier Code zum Behandeln des SettingsSaving-Ereignisses hinzu. + } + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestClassListEventArgs.cs b/vbe-add-In/AccUnit.VbeAddIn/TestClassListEventArgs.cs new file mode 100644 index 0000000..94e2e14 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestClassListEventArgs.cs @@ -0,0 +1,19 @@ +using System; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + public class TestClassListEventArgs : EventArgs + { + protected readonly TestClassList _testClassList; + + public TestClassListEventArgs(TestClassList testclasslist) + { + _testClassList = testclasslist; + } + + public TestClassList TestClassList + { + get { return _testClassList; } + } + } +} \ No newline at end of file diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestComponentsEventArgs.cs b/vbe-add-In/AccUnit.VbeAddIn/TestComponentsEventArgs.cs new file mode 100644 index 0000000..ed985b9 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestComponentsEventArgs.cs @@ -0,0 +1,20 @@ +using AccessCodeLib.Common.VBIDETools; +using System; +using System.Collections.Generic; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + public class TestComponentsEventArgs : EventArgs + { + public TestComponentsEventArgs() + { + } + + public TestComponentsEventArgs(IEnumerable components) + { + Components = components; + } + + public IEnumerable Components { get; set; } + } +} \ No newline at end of file diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestClassInfoTestItem.cs b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestClassInfoTestItem.cs new file mode 100644 index 0000000..2712032 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestClassInfoTestItem.cs @@ -0,0 +1,18 @@ +namespace AccessCodeLib.AccUnit.VbeAddIn.TestExplorer +{ + public class TestClassInfoTestItem : TestItem + { + public TestClassInfoTestItem(TestClassInfo testClassInfo, bool isChecked = false) + : base(testClassInfo.Name, testClassInfo.Name, isChecked) + { + TestClassInfo = testClassInfo; + } + + protected override void SetChildren() + { + Children = new TestClassMemberInfoTestItems(); + } + + public TestClassInfo TestClassInfo { get; set; } + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestClassInfoTestItems.cs b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestClassInfoTestItems.cs new file mode 100644 index 0000000..b733c0d --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestClassInfoTestItems.cs @@ -0,0 +1,29 @@ +namespace AccessCodeLib.AccUnit.VbeAddIn.TestExplorer +{ + public class TestClassInfoTestItems : CheckableItems + { + protected override void PerformActionOnAddedItem(TestItem item) + { + var testClassInfoTestItem = (TestClassInfoTestItem)item; + var testClassInfo = testClassInfoTestItem.TestClassInfo; + + if (testClassInfo.Members == null) + return; + + foreach (var member in testClassInfo.Members) + { + var testClassMemberInfoTestItem = new TestClassMemberInfoTestItem(member, true); + item.Children.Add(testClassMemberInfoTestItem); + } + } + } + + public class TestClassMemberInfoTestItems : CheckableItems + { + } + + public class TestRowTestItems : CheckableItems + { + } + +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestClassMemberInfoTestItem.cs b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestClassMemberInfoTestItem.cs new file mode 100644 index 0000000..d990e74 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestClassMemberInfoTestItem.cs @@ -0,0 +1,18 @@ +namespace AccessCodeLib.AccUnit.VbeAddIn.TestExplorer +{ + public class TestClassMemberInfoTestItem : TestItem + { + public TestClassMemberInfoTestItem(TestClassMemberInfo testClassMemberInfo, bool isChecked = false) + : base(testClassMemberInfo.FullName, testClassMemberInfo.Name, isChecked) + { + TestClassMemberInfo = testClassMemberInfo; + } + + protected override void SetChildren() + { + Children = new TestRowTestItems(); + } + + public TestClassMemberInfo TestClassMemberInfo { get; set; } + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerManager.cs b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerManager.cs new file mode 100644 index 0000000..352c994 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerManager.cs @@ -0,0 +1,147 @@ +using AccessCodeLib.AccUnit.Interfaces; +using AccessCodeLib.Common.Tools.Logging; +using AccessCodeLib.Common.VBIDETools; +using AccessCodeLib.Common.VBIDETools.Commandbar; +using Microsoft.Office.Core; +using System; + +namespace AccessCodeLib.AccUnit.VbeAddIn.TestExplorer +{ + internal class TestExplorerManager : ITestResultReporter, ICommandBarsAdapterClient + { + private readonly VbeUserControl _vbeUserControl; + private readonly TestExplorerViewModel _viewModel; + private INotifyingTestResultCollector _testResultCollector; + + public event EventHandler RunTests; + //public event EventHandler CancelTestRun; + + public TestExplorerManager(VbeUserControl vbeUserControl) + { + _vbeUserControl = vbeUserControl; + _viewModel = new TestExplorerViewModel(); + _vbeUserControl.Control.DataContext = _viewModel; + + InitViewModel(); + } + + private void InitViewModel() + { + _viewModel.RefreshList += (sender, e) => + { + FillTestsFromVbProject(); + }; + + _viewModel.RunTests += (sender, e) => + { + RunTests?.Invoke(sender, e); + }; + /* + _viewModel.CancelTestRun += (sender, e) => + { + CancelTestRun?.Invoke(sender, e); + }; + */ + _viewModel.GetTestClassInfo += (sender, e) => + { + e.TestClassInfo = VbeIntegrationManager.TestClassManager.GetTestClassInfo(e.ClassName, true); + }; + } + + public VbeIntegrationManager VbeIntegrationManager { get; set; } + + public ITestResultCollector TestResultCollector + { + get { return _viewModel.TestResultCollector; } + set + { + _viewModel.TestResultCollector = value; + _testResultCollector = value as INotifyingTestResultCollector; + _testResultCollector.TestSuiteStarted += TestResultCollector_TestSuiteStarted; + } + } + + private void TestResultCollector_TestSuiteStarted(ITestSuite testSuite) + { + _vbeUserControl.Visible = true; + } + + #region ICommandBarsAdapterClient support + + public void SubscribeToCommandBarAdapter(VbeCommandBarAdapter commandBarAdapter) + { + using (new BlockLogger()) + { + var accUnitCommandBarAdapter = commandBarAdapter as AccUnitCommandBarAdapter; + if (accUnitCommandBarAdapter != null) + { + AddTestListCommandBarButton(commandBarAdapter, accUnitCommandBarAdapter.AccUnitCommandbar); + } + + // TODO: Why shouldn't there be any view commandbar? + var viewCommandBar = GetViewCommandBarOrNull(commandBarAdapter); + if (viewCommandBar != null) + { + const int projectExplorerControlID = 2557; + var projectExplorerControlIndex = VbeCommandBarAdapter.GetButtonIndex(viewCommandBar, projectExplorerControlID); + AddTestListCommandBarButton(commandBarAdapter, viewCommandBar, projectExplorerControlIndex); + } + else + { + if (accUnitCommandBarAdapter != null) + { + var accUnitSubMenu = accUnitCommandBarAdapter.AccUnitSubMenu.CommandBar; + AddTestListCommandBarButton(commandBarAdapter, accUnitSubMenu); + } + } + } + } + + private static CommandBar GetViewCommandBarOrNull(VbeCommandBarAdapter commandBarAdapter) + { + try + { + return commandBarAdapter.CommandBarView; + } + catch + { + return null; + } + } + + private void AddTestListCommandBarButton(VbeCommandBarAdapter commandBarAdapter, CommandBar commandBar, int? index = null) + { + var buttonData = new CommandbarButtonData + { + Caption = Resources.VbeCommandbars.ViewTestExplorerCommandbarButtonCaption, + Description = Resources.VbeCommandbars.SelectTestsCommandBarButtonDescription, + FaceId = 2529, + BeginGroup = true, + Index = index + }; + var button = commandBarAdapter.AddCommandBarButton(commandBar, buttonData, AccUnitCommandBarItemsShowTestListWindow); + button.Style = MsoButtonStyle.msoButtonAutomatic; + } + + void AccUnitCommandBarItemsShowTestListWindow(CommandBarButton ctrl, ref bool cancelDefault) + { + _vbeUserControl.Visible = true; + if (_viewModel.TestItems.Count == 0) + { + FillTestsFromVbProject(); + } + } + + private void FillTestsFromVbProject() + { + _viewModel.TestItems.Clear(); + var testItems = VbeIntegrationManager.TestClassManager.GetTestClassListFromVBProject(true); + foreach (var testItem in testItems) + { + _viewModel.TestItems.Add(new TestClassInfoTestItem(testItem, true)); + } + } + + #endregion + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerTreeView.xaml b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerTreeView.xaml new file mode 100644 index 0000000..286d7aa --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerTreeView.xaml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerTreeView.xaml.cs b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerTreeView.xaml.cs new file mode 100644 index 0000000..43ebebb --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerTreeView.xaml.cs @@ -0,0 +1,13 @@ +using System.Windows.Controls; + +namespace AccessCodeLib.AccUnit.VbeAddIn.TestExplorer +{ + public partial class TestExplorerTreeView : UserControl + { + public TestExplorerTreeView() + { + InitializeComponent(); + //DataContext = new TestExplorerViewModel(); + } + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerView.xaml b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerView.xaml new file mode 100644 index 0000000..adae4f4 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerView.xaml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerView.xaml.cs b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerView.xaml.cs new file mode 100644 index 0000000..c2d41e1 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerView.xaml.cs @@ -0,0 +1,15 @@ +using System.Windows.Controls; + +namespace AccessCodeLib.AccUnit.VbeAddIn.TestExplorer +{ + /// + /// Interaktionslogik für TestExplorer.xaml + /// + public partial class TestExplorerView : UserControl + { + public TestExplorerView() + { + InitializeComponent(); + } + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerViewModel.cs b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerViewModel.cs new file mode 100644 index 0000000..872c69a --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestExplorerViewModel.cs @@ -0,0 +1,352 @@ +using AccessCodeLib.AccUnit.Integration; +using AccessCodeLib.AccUnit.Interfaces; +using System; +using System.Collections.Specialized; +using System.ComponentModel; +using System.Linq; +using System.Windows.Input; +using System.Windows.Media; + +namespace AccessCodeLib.AccUnit.VbeAddIn.TestExplorer +{ + public class TestExplorerViewModel : ITestResultReporter, INotifyPropertyChanged + { + private string _selectAllCheckBoxText = Resources.UserControls.SelectListSelectAllCheckboxCaption; + private string _commitButtonText = Resources.UserControls.SelectListCommitButtonText; + + public delegate void RefreshTestItemListEventHandler(TestExplorerViewModel sender, CheckableTestItemsEventArgs e); + public event RefreshTestItemListEventHandler RefreshList; + + public event EventHandler RunTests; + //public event EventHandler CancelTestRun; + public event EventHandler GetTestClassInfo; + + public TestExplorerViewModel() + { + _selectAllCheckBoxText = Resources.UserControls.SelectListSelectAllCheckboxCaption; + _commitButtonText = Resources.UserControls.TestExplorerCommitButtonText; + + TestItems = new TestClassInfoTestItems(); + RefreshCommand = new RelayCommand(Refresh); + CommitCommand = new RelayCommand(Commit); + } + + private CheckableItems _testItems; + public CheckableItems TestItems + { + get => _testItems; + set + { + _testItems = value; + TestItems.CollectionChanged += OnChildrenCollectionChanged; + OnPropertyChanged(nameof(TestItems)); + } + } + + private void OnChildrenCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + if (e.Action == NotifyCollectionChangedAction.Add) + { + foreach (var item in e.NewItems) + { + if (item is TestItem testItem) + { + testItem.PropertyChanged += OnChildPropertyChanged; + } + } + } + } + + private void OnChildPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (e.PropertyName == nameof(TestItem.IsChecked)) + { + if (sender is TestItem testItem) + { + if (!testItem.IsChecked) + { + if (SelectAll == true) + { + _selectAll = false; + OnPropertyChanged(nameof(SelectAll)); + } + } + else if (SelectAll == false) + { + foreach (var item in TestItems) + { + if (!item.IsChecked) + return; + } + _selectAll = true; + OnPropertyChanged(nameof(SelectAll)); + } + } + } + } + + public event PropertyChangedEventHandler PropertyChanged; + protected void OnPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } + + #region ITestResultReporter + private INotifyingTestResultCollector _testResultCollector; + + public ITestResultCollector TestResultCollector + { + get { return _testResultCollector; } + set + { + _testResultCollector = value as INotifyingTestResultCollector; + InitEventHandler(); + } + } + + private void InitEventHandler() + { + _testResultCollector.TestSuiteStarted += TestResultCollector_TestSuiteStarted; + _testResultCollector.TestSuiteFinished += TestResultCollector_TestSuiteFinished; + _testResultCollector.TestSuiteReset += TestResultCollector_TestSuiteReset; + _testResultCollector.TestFixtureStarted += TestResultCollector_TestFixtureStarted; + _testResultCollector.TestFixtureFinished += TestResultCollector_TestFixtureFinished; + _testResultCollector.TestStarted += TestResultCollector_TestStarted; + _testResultCollector.TestFinished += TestResultCollector_TestFinished; + } + + private void TestResultCollector_TestSuiteStarted(ITestSuite testSuite) + { + // remove all items that are not in the current test suite + foreach (var item in TestItems.ToList()) + { + if (!testSuite.TestFixtures.Any(tf => tf.FullName == item.FullName)) + { + TestItems.Remove(item); + } + } + } + + private void TestResultCollector_TestSuiteFinished(ITestSummary summary) + { + //LogStringToTextBox(summary.ToString()); + //LogStringToTextBox("TS finished."); + } + + private void TestResultCollector_TestFixtureStarted(ITestFixture fixture) + { + + var testItem = FindTestItem(fixture); + if (testItem != null) + { + return; + } + AddTestClassInfoTestItem(fixture.Name); + } + + private void AddTestClassInfoTestItem(string className) + { + var testClassInfoEventArgs = new GetTestClassInfoEventArgs(className); + GetTestClassInfo?.Invoke(this, testClassInfoEventArgs); + if (testClassInfoEventArgs.TestClassInfo == null) + { + throw new Exception("Test class info not found for test fixture " + className); + } + TestItems.Add(new TestClassInfoTestItem(testClassInfoEventArgs.TestClassInfo, true)); + } + + private void TestResultCollector_TestFixtureFinished(ITestResult result) + { + + var testItem = FindTestItem(result.Test); + if (testItem == null) + { + return; + } + testItem.Result = result.Result.ToString(); + testItem.IsExpanded = result.IsFailure || result.IsError; + testItem.TestResult = result; + OnPropertyChanged(nameof(testItem.IsExpanded)); + } + + private void TestResultCollector_TestStarted(ITest test, ref IgnoreInfo ignoreInfo) + { + var testItem = FindTestItem(test); + if (testItem != null) + { + if (!testItem.IsChecked) + { + ignoreInfo.Ignore = true; + ignoreInfo.Comment = "Test is not selected"; + return; + } + + var parent = FindParentTestItem(test); + if (parent != null) + { + parent.IsExpanded = true; + } + return; + } + + var parentItem = FindParentTestItem(test); + if (parentItem == null) + { + AddTestClassInfoTestItem(test.Name); + } + else + { + TestItem child; + if (test.Parent is IRowTest) + child = new TestItem(test.FullName, ((IRowTestId)test).RowId, parentItem.IsChecked); + else + child = new TestItem(test.FullName, test.Name, parentItem.IsChecked); + child.IsChecked = true; + parentItem.Children.Add(child); + parentItem.IsExpanded = true; + } + } + + private void TestResultCollector_TestFinished(ITestResult result) + { + var testItem = FindTestItem(result.Test); + if (testItem == null) + { + return; + } + + //testItem.Result = result.Result + result.Message ?? string.Empty; + testItem.IsExpanded = result.IsFailure || result.IsError; + testItem.TestResult = result; + if (result.Success) + { + testItem.IsChecked = false; + OnPropertyChanged(nameof(testItem.IsChecked)); + } + OnPropertyChanged(nameof(testItem.IsExpanded)); + } + + private void TestResultCollector_TestSuiteReset(ResetMode resetmode, ref bool cancel) + { + if ((resetmode & ResetMode.ResetTestSuite) == ResetMode.ResetTestSuite) + { + TestItems.Clear(); + } + } + #endregion + + private TestItem FindParentTestItem(ITest test) + { + var parent = test.Parent as ITestData; + if (test.Parent == null) + { + return null; + } + + if (test.Parent is ITestFixture testFixture) + { + return TestItems.FirstOrDefault(ti => ti.FullName == testFixture.FullName); + } + + if (test.Parent is IRowTest rowTest) + { + var rowTestFixtureItem = FindParentTestItem(rowTest); + return rowTestFixtureItem.Children.FirstOrDefault(ti => ti.FullName == rowTest.FullName); + } + + var parentTest = test.Parent as ITest; + var fixtureItem = FindParentTestItem(parentTest); + return fixtureItem.Children.FirstOrDefault(ti => ti.FullName == parentTest.FullName); + } + + private TestItem FindTestItem(ITestData testData) + { + TestItem parentItem = null; + if (testData is ITest test) + { + parentItem = FindParentTestItem(test); + } + if (parentItem == null) + { + return TestItems.FirstOrDefault(ti => ti.FullName == testData.FullName); + } + return parentItem.Children.FirstOrDefault(ti => ti.FullName == testData.FullName); + } + + private bool _selectAll = true; + public bool SelectAll + { + get { return _selectAll; } + set + { + if (_selectAll != value) + { + _selectAll = value; + if (TestItems != null) + { + foreach (var item in TestItems) + { + item.SetChecked(value); + } + } + OnPropertyChanged(nameof(SelectAll)); + } + } + } + + public string SelectAllCheckBoxText + { + get => _selectAllCheckBoxText; + set + { + if (_selectAllCheckBoxText != value) + { + _selectAllCheckBoxText = value; + OnPropertyChanged(nameof(SelectAllCheckBoxText)); + } + } + } + + public string CommitButtonText + { + get => _commitButtonText; + set + { + if (_commitButtonText != value) + { + _commitButtonText = value; + OnPropertyChanged(nameof(CommitButtonText)); + } + } + } + + public ICommand RefreshCommand { get; } + public ICommand CommitCommand { get; } + public ImageSource RefreshCommandImageSource + { + get + { + return UITools.ConvertBitmapToBitmapSource(Resources.Icons.refresh_green); + } + } + + protected void Refresh() + { + RefreshList?.Invoke(this, new CheckableTestItemsEventArgs(TestItems)); + } + + protected virtual void Commit() + { + TestClassList list = new TestClassList(); + list.AddRange(TestItems.Where(ti => ti.IsChecked).Select(ti => ((TestClassInfoTestItem)ti).TestClassInfo)); + RunTests?.Invoke(this, new RunTestsEventArgs(list)); + } + + } + + public static class TestExplorerInfo + { + public const string ProgID = @"AccUnit.VbeAddIn.TestExplorer"; + public const string PositionGuid = @"DB052D8D-8418-4322-ADD9-5DCB8157C8D4"; + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestItem.cs b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestItem.cs new file mode 100644 index 0000000..4b5e118 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestItem.cs @@ -0,0 +1,90 @@ +using AccessCodeLib.AccUnit.Interfaces; +using System.Windows.Media; + +namespace AccessCodeLib.AccUnit.VbeAddIn.TestExplorer +{ + public class TestItem : CheckableTreeViewItemBase + { + public TestItem(string fullName, string name, bool isChecked = false) + : base(fullName, name, isChecked) + { + } + + private ITestResult _testResult; + public ITestResult TestResult + { + get + { + return _testResult; + } + set + { + _testResult = value; + OnPropertyChanged(nameof(TestResult)); + ImageSource = CalculatedImageSource; + + Result = _testResult == null ? null : (Children.Count == 0 ? _testResult.Message : _testResult.Result); + OnPropertyChanged(nameof(Result)); + + if (_testResult != null && _testResult.IsIgnored && _testResult.Success) + { + if (_testResult is ITestSummary summary) + { + if (summary.Passed != 0) + { + return; + } + } + SetChildsToIgnored(); + } + } + } + + private void SetChildsToIgnored() + { + foreach (var item in Children) + { + item.ImageSource = UITools.ConvertBitmapToBitmapSource(Properties.Resources.noaction_gray); + } + } + + public string Result { get; set; } + + private ImageSource CalculatedImageSource + { + get + { + if (TestResult == null) + return null; + + if (TestResult.IsFailure || TestResult.IsError) + return UITools.ConvertBitmapToBitmapSource(Properties.Resources.result_failed_16x16); + + if (TestResult.Success) + { + if (TestResult is ITestSummary summary) + { + if (summary.Passed == 0) + return UITools.ConvertBitmapToBitmapSource(Properties.Resources.noaction_gray); + } + else + { + if (TestResult.IsIgnored) + return UITools.ConvertBitmapToBitmapSource(Properties.Resources.noaction_gray); + } + + return UITools.ConvertBitmapToBitmapSource(Properties.Resources.result_success_16x16); + } + + if (TestResult.IsPassed) + return UITools.ConvertBitmapToBitmapSource(Properties.Resources.result_success_16x16); + + + if (TestResult.Executed == false) + return UITools.ConvertBitmapToBitmapSource(Properties.Resources.noaction_gray); + + return null; + } + } + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestListAndResultManager.cs b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestListAndResultManager.cs new file mode 100644 index 0000000..4a36963 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestExplorer/TestListAndResultManager.cs @@ -0,0 +1,349 @@ +/* +using System; +using AccessCodeLib.AccUnit.Common; +using AccessCodeLib.AccUnit.Common.Interfaces; +using AccessCodeLib.Common.Tools.Logging; +using AccessCodeLib.Common.VBIDETools.Commandbar; +using Microsoft.Office.Core; +using Microsoft.Vbe.Interop; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + class TestListAndResultManager : IDisposable, ICommandBarsAdapterClient + { + private TestSuiteManager _testSuiteManager; + //private TestListAndResultView _testListAndResultView; + //private VbideUserControl _testListAndResultVbideControl; + //private TagListManager _tagListManager; + + public TestSuiteManager TestSuiteManager + { + get { return _testSuiteManager; } + set + { + _testSuiteManager = value; + _testSuiteManager.TestSuiteStarted += TestSuiteManagerTestSuiteStarted; + _testSuiteManager.TestStarted += TestSuiteManagerTestStarted; + _testSuiteManager.TestFinished += TestSuiteManagerTestFinished; + _testSuiteManager.TestCountChanged += TestSuiteManagerTestCountChanged; + } + } + + public event EventHandler RunTests; + public event EventHandler CancelTestRun; + + public Microsoft.Vbe.Interop.AddIn AddIn { get; set; } + public VbeIntegrationManager VbeIntegrationManager { get; set; } + public TestClassManager TestClassManager { get { return VbeIntegrationManager.TestClassManager; } } + + void TestSuiteManagerTestSuiteStarted(ITestSuite testSuite) + { + TestListAndResultWindow.Visible = true; + } + + void TestSuiteManagerTestStarted(ITest test, bool disableTestCaseSelection, bool newTestRun, IgnoreInfo ignoreInfo, TagList tags) + { + TestListAndResultWindow.Control.Add(test, disableTestCaseSelection, newTestRun, ignoreInfo, tags); + } + + void TestSuiteManagerTestFinished(ITestResult result, bool isSummary = false, TestClassMemberInfo memberinfo = null) + { + using (new BlockLogger()) + { + Logger.Log($"Result:{result.Message}"); + TestListAndResultWindow.Control.Add(result, isSummary, memberinfo); + } + + } + + void TestSuiteManagerTestCountChanged(int number) + { + TestCount += number; + } + + public TagListManager TagListManager + { + get { return _tagListManager; } + set + { + _tagListManager = value; + _tagListManager.TagsSelected += TagsSelected; + } + } + + public VbideUserControl TestListAndResultWindow + { + get + { + if (_testListAndResultVbideControl == null) + { + _testListAndResultVbideControl = new VbideUserControl(AddIn, Resources.UserControls.TestResultUserControlInfoCaption, TestListAndResultViewUserControlInfo.PositionGuid); + _testListAndResultView = _testListAndResultVbideControl.Control; + _testListAndResultView.RunBreakOnErrorMenuItemEnabled = (TestSuiteManager.TestSuite is AccessTestSuite); + + _testListAndResultView.RunTests += TestListAndResultViewRunTests; + _testListAndResultView.ShowSourceCodeInvoked += TestListAndResultViewShowSourceCodeInvoked; + _testListAndResultView.ShowTestResultDetailInvoked += TestListAndResultViewShowTestResultDetailInvoked; + _testListAndResultView.RefreshTestList += TestListAndResultViewRefreshTestList; + _testListAndResultView.Cancel += TestListAndResultViewCancel; + } + return _testListAndResultVbideControl; + } + } + + void TestListAndResultViewCancel(object sender, EventArgs e) + { + if (CancelTestRun != null) + CancelTestRun(sender, e); + } + + void TestListAndResultViewRunTests(object sender, RunTestsEventArgs e) + { + if (RunTests != null) + RunTests(sender, e); + } + + public void AddTestClassListToTestListAndResultWindow() + { + try + { + _testListAndResultView.Add(TestClassManager.GetTestClassListFromVBProject(TagListManager.GetFilterTagList())); + } + catch (Exception ex) + { + Logger.Log(ex); + } + } + + public int TestCount + { + get { return _testListAndResultView.TestCount; } + set { _testListAndResultView.TestCount = value; } + } + + void TestListAndResultViewShowSourceCodeInvoked(object sender, TestNodeEventArgs e) + { + ShowSourceCode(e.ClassName, e.MemberName); + } + + void TestListAndResultViewRefreshTestList(ref TestClassList list) + { + list = TestClassManager.GetTestClassListFromVBProject(TagListManager.GetFilterTagList()); + } + + static void TestListAndResultViewShowTestResultDetailInvoked(object sender, TestNodeInfoEventArgs e) + { + var testInfo = new TestInfoForm {TestInfo = e.TestNodeInfo}; + testInfo.ShowDialog(); + } + + private void ShowSourceCode(string classname, string membername) + { + var codePane = ActivateCodePane(classname, membername); + EnsureTextCursorIsVisible(codePane); + } + + private CodePane ActivateCodePane(string classname, string membername = null) + { + var modul = TestClassManager.ActiveVBProject.VBComponents.Item(classname).CodeModule; + var pane = modul.CodePane; + pane.Show(); + pane.Window.SetFocus(); + var procLine = 1; + if (!string.IsNullOrEmpty(membername)) + { + // TODO: Determine upfront if the member does not exist and throw appropriate exception (including name of the missing member) + procLine = modul.ProcBodyLine[membername, vbext_ProcKind.vbext_pk_Proc]; + } + pane.SetSelection(procLine, 1, procLine, 1); + return pane; + } + + // VBE bugfix: invisible text cursor in CodePane + private static void EnsureTextCursorIsVisible(_CodePane codePane) + { + var window = codePane.Window; + window.Visible = false; + window.Visible = true; + window.SetFocus(); + } + + void TagsSelected(TagList tags) + { + TestListAndResultWindow.Visible = true; + _testListAndResultView.Add(TestClassManager.GetTestClassListFromVBProject(tags)); + } + + public void ShowTestListWindow(bool visible, bool loadTestListIfEmpty = true) + { + using (new BlockLogger()) + { + try + { + using (new BlockLogger("Try block, visible = " + visible)) + { + TestListAndResultWindow.Visible = visible; + if (visible) + { + if (loadTestListIfEmpty && TestListAndResultWindow.Control.TestCount == 0) + { + AddTestClassListToTestListAndResultWindow(); + } + TestListAndResultWindow.Control.Repaint(); // issue #71 + } + } + } + catch (Exception xcp) + { + if (VbeIntegrationManager != null && VbeIntegrationManager.HostApplication == null) + { + VbeIntegrationManager.ShowMissingApplicationInfo(); + return; + } + UITools.ShowException(xcp); + } + } + } + + #region ICommandBarsAdapterClient support + + public void SubscribeToCommandBarAdapter(VbeCommandBarAdapter commandBarAdapter) + { + using (new BlockLogger()) + { + var accUnitCommandBarAdapter = commandBarAdapter as AccUnitCommandBarAdapter; + if (accUnitCommandBarAdapter != null) + { + AddTestListCommandBarButton(commandBarAdapter, accUnitCommandBarAdapter.AccUnitCommandbar); + } + + // TODO: Why shouldn't there be any view commandbar? + var viewCommandBar = GetViewCommandBarOrNull(commandBarAdapter); + if (viewCommandBar != null) + { + const int projectExplorerControlID = 2557; + var projectExplorerControlIndex = VbeCommandBarAdapter.GetButtonIndex(viewCommandBar, projectExplorerControlID); + AddTestListCommandBarButton(commandBarAdapter, viewCommandBar, projectExplorerControlIndex); + } + else + { + if (accUnitCommandBarAdapter != null) + { + var accUnitSubMenu = accUnitCommandBarAdapter.AccUnitSubMenu.CommandBar; + AddTestListCommandBarButton(commandBarAdapter, accUnitSubMenu); + } + } + } + } + + private static CommandBar GetViewCommandBarOrNull(VbeCommandBarAdapter commandBarAdapter) + { + try + { + return commandBarAdapter.CommandBarView; + } + catch + { + return null; + } + } + + private void AddTestListCommandBarButton(VbeCommandBarAdapter commandBarAdapter, CommandBar commandBar, int? index = null) + { + var buttonData = new CommandbarButtonData + { + Caption = Resources.VbeCommandbars.ViewTestListCommandbarButtonCaption, + Description = Resources.VbeCommandbars.SelectTestsCommandBarButtonDescription, + FaceId = 2529, + BeginGroup = true, + Index = index + }; + var button = commandBarAdapter.AddCommandBarButton(commandBar, buttonData, AccUnitCommandBarItemsShowTestListWindow); + button.Style = MsoButtonStyle.msoButtonAutomatic; + } + + void AccUnitCommandBarItemsShowTestListWindow(CommandBarButton ctrl, ref bool cancelDefault) + { + ShowTestListWindow(true); + } + + #endregion + + #region IDisposable Support + + bool _disposed; + + protected virtual void Dispose(bool disposing) + { + if (_disposed) return; + + if (disposing) + { + DisposeTestListAndResultVbideControl(); + _testSuiteManager = null; + _tagListManager = null; + } + + _disposed = true; + } + + public void Dispose() + { + using (new BlockLogger()) + { + Dispose(true); + GC.SuppressFinalize(this); + } + } + + ~TestListAndResultManager() + { + Dispose(false); + } + + private void DisposeTestListAndResultVbideControl() + { + if (_testListAndResultVbideControl == null) + return; + + try + { + Settings.Default.TestListVisible = _testListAndResultVbideControl.Visible; + if (_testListAndResultVbideControl.Visible) + _testListAndResultVbideControl.Visible = false; + } + catch (Exception ex) + { + Logger.Log(ex); + } + + if (_testListAndResultView != null) + try + { + _testListAndResultView.Dispose(); + } + catch (Exception ex) + { + Logger.Log(ex); + } + finally + { + _testListAndResultView = null; + Logger.Log("_testListAndResultView disposed"); + } + + try + { + _testListAndResultVbideControl.Dispose(); + _testListAndResultVbideControl = null; + } + catch (Exception ex) + { + Logger.Log(ex); + } + } + + #endregion + } +} +*/ \ No newline at end of file diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestImportExport/ImportExportManager.cs b/vbe-add-In/AccUnit.VbeAddIn/TestImportExport/ImportExportManager.cs new file mode 100644 index 0000000..9d20771 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestImportExport/ImportExportManager.cs @@ -0,0 +1,260 @@ +using AccessCodeLib.AccUnit.Configuration; +using AccessCodeLib.AccUnit.VbeAddIn.Resources; +using AccessCodeLib.Common.Tools.Logging; +using AccessCodeLib.Common.VBIDETools; +using AccessCodeLib.Common.VBIDETools.Commandbar; +using Microsoft.Office.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + class ImportExportManager : IDisposable, ICommandBarsAdapterClient + { + public event EventHandler TestClassesImported; + + public TestClassManager TestClassManager { get; set; } + + void ShowImportDialog() + { + try + { + var dataContext = new SelectControlViewModel( + UserControls.TestClassSelectionFormCaptionImport, + UserControls.SelectListSelectAllCheckboxCaption, + UserControls.TestClassSelectionFormCommitTestImport, + true, "Overwrite existing codemodule"); + + foreach (var item in TestClassManager.GetTestModulesFromDirectory()) + { + dataContext.Items.Add(new CheckableCodeModuleInfo(item)); + } + + var form = new ImportExportWindow(dataContext); + dataContext.OptionalCheckboxChecked = true; + dataContext.RefreshList += (sender, e) => + { + e.Items.Clear(); + foreach (var item in TestClassManager.GetTestModulesFromDirectory()) + { + e.Items.Add(new CheckableCodeModuleInfo(item)); + } + }; + dataContext.ItemsSelected += (sender, e) => + { + var sb = new StringBuilder(); + bool errRaised = false; + + try + { + IEnumerable codeModulesToImport = e.Items.Select(x => ((CheckableCodeModuleInfo)x).CodeModule); + if (codeModulesToImport.Count() == 0) + { + throw new Exception("No test modules selected for import."); + } + TestClassManager.ImportTestComponents(codeModulesToImport, dataContext.OptionalCheckboxChecked); + } + catch (Exception ex) + { + errRaised = true; + UITools.ShowException(ex); + } + TestClassesImported?.Invoke(this, null); + + if (!errRaised) + { + UITools.ShowMessage(MessageStrings.TestImportedCommitMessage); + form.Close(); + } + }; + + SetDialogPosition(form); + form.ShowDialog(); + + dataContext.RefreshList -= (sender, e) => { }; + dataContext.ItemsSelected -= (sender, e) => { }; + } + catch (Exception ex) + { + UITools.ShowException(ex); + } + } + + void ShowExportDialog() + { + try + { + var dataContext = new SelectControlViewModel( + UserControls.TestClassSelectionFormCaptionExport, + UserControls.SelectListSelectAllCheckboxCaption, + UserControls.TestClassSelectionFormCommitTestExport, + true, UserControls.TestClassSelectionFormOptionalCheckBoxTextExport); + var list = TestClassManager.GetTestModulesFromVBProject(); + + foreach (var item in list) + { + dataContext.Items.Add(new CheckableItem(item.Name)); + } + + var form = new ImportExportWindow(dataContext); + dataContext.RefreshList += (sender, e) => + { + e.Items.Clear(); + foreach (var item in TestClassManager.GetTestModulesFromVBProject()) + { + e.Items.Add(new CheckableItem(item.Name)); + } + }; + dataContext.ItemsSelected += (sender, e) => + { + var sb = new StringBuilder(); + bool errRaised = false; + foreach (var item in e.Items) + { + try + { + if (item.IsChecked) + { + TestClassManager.ExportTestClass(item.Name); + item.IsChecked = false; + sb.AppendLine(" - " + item.Name); + } + } + catch (Exception ex) + { + errRaised = true; + UITools.ShowException(ex); + } + } + + var msg = string.Format(MessageStrings.TestExportedCommitMessage, sb.ToString()); + UITools.ShowMessage(msg); + + if (!errRaised) + { + form.Close(); + } + }; + dataContext.PropertyChanged += (sender, e) => + { + if (e.PropertyName == nameof(dataContext.OptionalCheckboxChecked)) + { + dataContext.CommitButtonText = dataContext.OptionalCheckboxChecked + ? UserControls.TestClassSelectionFormCommitTestExportAndRemove + : UserControls.TestClassSelectionFormCommitTestExport; + } + }; + + SetDialogPosition(form); + form.ShowDialog(); + + dataContext.RefreshList -= (sender, e) => { }; + dataContext.ItemsSelected -= (sender, e) => { }; + dataContext.PropertyChanged -= (sender, e) => { }; + } + catch (Exception ex) + { + UITools.ShowException(ex); + } + } + + private void SetDialogPosition(System.Windows.Window dialog) + { + var scaleFactor = UITools.GetScalingFactor(); + var width = dialog.Width; + var height = dialog.Height; + + var mainWindow = TestClassManager.ActiveVBProject.VBE.MainWindow; + + dialog.Top = (mainWindow.Top + mainWindow.Height / 2) / scaleFactor - height / 2; + dialog.Left = (mainWindow.Left + mainWindow.Width / 2) / scaleFactor - width / 2; + } + + #region ICommandBarsAdapterClient support + + public void SubscribeToCommandBarAdapter(VbeCommandBarAdapter commandBarAdapter) + { + using (new BlockLogger()) + { + if (!(commandBarAdapter is AccUnitCommandBarAdapter accUnitCommandBarAdapter)) return; + + var menu = accUnitCommandBarAdapter.AccUnitSubMenu; + var buttonData = new CommandbarButtonData + { + Caption = VbeCommandbars.ToolsImportTestsCommandButtonCaption, + Description = string.Empty, + FaceId = 524, + BeginGroup = true + }; + commandBarAdapter.AddCommandBarButton(menu, buttonData, AccUnitMenuItemsImportTests); + + buttonData = new CommandbarButtonData + { + Caption = VbeCommandbars.ToolsExportTestsCommandButtonCaption, + Description = string.Empty, + FaceId = 525, + BeginGroup = false + }; + commandBarAdapter.AddCommandBarButton(menu, buttonData, AccUnitMenuItemsExportTests); + } + } + + void AccUnitMenuItemsImportTests(CommandBarButton ctrl, ref bool cancelDefault) + { + ShowImportDialog(); + } + + void AccUnitMenuItemsExportTests(CommandBarButton ctrl, ref bool cancelDefault) + { + ShowExportDialog(); + } + + #endregion + + + #region IDisposable Support + + bool _disposed; + + protected virtual void Dispose(bool disposing) + { + if (_disposed) return; + + if (disposing) + { + DisposeManagedResources(); + } + + //DisposeUnmanagedResources(); + _disposed = true; + } + + //private void DisposeUnmanagedResources() + //{ + // // + //} + + private void DisposeManagedResources() + { + TestClassManager = null; + } + + public void Dispose() + { + using (new BlockLogger()) + { + Dispose(true); + GC.SuppressFinalize(this); + } + } + + ~ImportExportManager() + { + Dispose(false); + } + + #endregion + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestImportExport/ImportExportWindow.xaml b/vbe-add-In/AccUnit.VbeAddIn/TestImportExport/ImportExportWindow.xaml new file mode 100644 index 0000000..c391cfb --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestImportExport/ImportExportWindow.xaml @@ -0,0 +1,9 @@ + + + + + diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestImportExport/ImportExportWindow.xaml.cs b/vbe-add-In/AccUnit.VbeAddIn/TestImportExport/ImportExportWindow.xaml.cs new file mode 100644 index 0000000..38d5681 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestImportExport/ImportExportWindow.xaml.cs @@ -0,0 +1,16 @@ +using System.Windows; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + /// + /// Interaktionslogik für ImportExportWindow.xaml + /// + public partial class ImportExportWindow : Window + { + public ImportExportWindow(SelectControlViewModel dataContext) + { + DataContext = dataContext; + InitializeComponent(); + } + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestResultReporter.cs b/vbe-add-In/AccUnit.VbeAddIn/TestResultReporter.cs new file mode 100644 index 0000000..ca4da41 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestResultReporter.cs @@ -0,0 +1,84 @@ +using AccessCodeLib.AccUnit.CodeCoverage; +using AccessCodeLib.AccUnit.Interfaces; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + public class TestResultReporter : ITestResultReporter + { + public event TestSuiteStartedEventHandler TestSuiteStarted; + public event TestSuiteFinishedEventHandler TestSuiteFinished; + public event TestSuiteResetEventHandler TestSuiteReset; + public event TestFixtureStartedEventHandler TestFixtureStarted; + public event FinishedEventHandler TestFixtureFinished; + public event TestStartedEventHandler TestStarted; + public event FinishedEventHandler TestFinished; + public event TestTraceMessageEventHandler TestTraceMessage; + + private INotifyingTestResultCollector _testResultCollector; + + public ITestResultCollector TestResultCollector + { + get { return _testResultCollector; } + set + { + _testResultCollector = value as INotifyingTestResultCollector; + InitEventHandler(); + } + } + + private void InitEventHandler() + { + _testResultCollector.TestSuiteStarted += TestResultCollector_TestSuiteStarted; + _testResultCollector.TestSuiteFinished += TestResultCollector_TestSuiteFinished; + _testResultCollector.TestSuiteReset += TestResultCollector_TestSuiteReset; + + _testResultCollector.TestFixtureStarted += TestResultCollector_TestFixtureStarted; + _testResultCollector.TestFixtureFinished += TestResultCollector_TestFixtureFinished; + + _testResultCollector.TestStarted += TestResultCollector_TestStarted; + _testResultCollector.TestFinished += TestResultCollector_TestFinished; + _testResultCollector.TestTraceMessage += TestResultCollector_TestTraceMessage; + + } + + private void TestResultCollector_TestSuiteStarted(ITestSuite testSuite) + { + TestSuiteStarted?.Invoke(testSuite); + } + + private void TestResultCollector_TestSuiteFinished(ITestSummary summary) + { + TestSuiteFinished?.Invoke(summary); + } + + private void TestResultCollector_TestSuiteReset(ResetMode resetmode, ref bool cancel) + { + TestSuiteReset?.Invoke(resetmode, ref cancel); + } + + private void TestResultCollector_TestFixtureStarted(ITestFixture fixture) + { + TestFixtureStarted?.Invoke(fixture); + } + + private void TestResultCollector_TestFixtureFinished(ITestResult result) + { + TestFixtureFinished?.Invoke(result); + } + + private void TestResultCollector_TestStarted(ITest test, ref IgnoreInfo ignoreInfo) + { + TestStarted?.Invoke(test, ref ignoreInfo); + } + + private void TestResultCollector_TestFinished(ITestResult result) + { + TestFinished?.Invoke(result); + } + + private void TestResultCollector_TestTraceMessage(string message, ICodeCoverageTracker CodeCoverageTracker) + { + TestTraceMessage?.Invoke(message, CodeCoverageTracker); + } + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestStarter.cs b/vbe-add-In/AccUnit.VbeAddIn/TestStarter.cs new file mode 100644 index 0000000..1d531cd --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestStarter.cs @@ -0,0 +1,546 @@ +using AccessCodeLib.AccUnit.Configuration; +using AccessCodeLib.AccUnit.Interfaces; +using AccessCodeLib.Common.Tools.Logging; +using AccessCodeLib.Common.VBIDETools; +using AccessCodeLib.Common.VBIDETools.Commandbar; +using Microsoft.Office.Core; +using Microsoft.Vbe.Interop; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Windows.Forms; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + class TestStarter : IDisposable, ICommandBarsAdapterClient + { + bool _referencesChecked; + private bool _breakOnAllErrorsForNextRun; + private CommandBarEvents _accUnitSubMenuEvents; + private int _accUnitSubMenuRunCurrentTestIndex; + private CommandBarButton _codeWindowRunCurrentTestButton; + private CommandBarButton _projectWindowRunCurrentTestButton; + + public VbeIntegrationManager VbeIntegrationManager { get; set; } + + void OnVbeMainWindowRButtonDown(object sender, EventArgs e) + { + try + { + var enabled = SelectedCodeModuleIsTestClass; + _codeWindowRunCurrentTestButton.Enabled = enabled; + _projectWindowRunCurrentTestButton.Enabled = enabled; + } + catch (Exception ex) + { + Logger.Log(ex); + } + } + + private TestClassManager TestClassManager { get { return VbeIntegrationManager.TestClassManager; } } + //private object HostApplication { get { return VbeIntegrationManager.HostApplication; } } + private VBE VBE { get { return VbeIntegrationManager.OfficeApplicationHelper.VBE; } } + + public TestSuiteManager TestSuiteManager { get; set; } + private IVBATestSuite TestSuite { get { return TestSuiteManager.TestSuite; } } + + public event EventHandler ShowUIMessage; + public event EventHandler ScanningForTestModules; + + private void RunCurrentTests(ResetMode resetmode = ResetMode.RemoveTests | ResetMode.ResetTestSuite) + { + try + { + TestClassInfo testclass = VbeIntegrationManager.GetTestClassInfoFromSelectedComponent(); + if (testclass != null) + { + var list = new TestClassList { testclass }; + RunTests(list, resetmode); + } + } + catch (Exception xcp) + { + UITools.ShowException(xcp); + } + } + + public void RunAllTests(ResetMode resetmode = ResetMode.RemoveTests) + { + try + { + RunTests(null, resetmode); + } + catch (Exception ex) + { + if (ShowMessage(ex)) + return; + + throw; + } + } + + public void RunTests(ICollection testClassList, bool BreakOnAllErrors = false) + { + try + { + if (testClassList.Count > 0) + { + _breakOnAllErrorsForNextRun = BreakOnAllErrors; + var missingTestClass = TestClassManager.FindFirstMissingTestClassInVBProject(testClassList); + if (missingTestClass != null) + { + UITools.ShowMessage(string.Format(Resources.MessageStrings.MissingTestClassInVBProject, missingTestClass.Name)); + return; + } + RunTests(testClassList, ResetMode.RemoveTests); + } + } + catch (Exception ex) + { + if (ShowMessage(ex)) + return; + + throw; + } + } + + private bool ShowMessage(Exception ex) + { + return ShowMessage(ex.Message, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + private bool ShowMessage(string message, MessageBoxButtons buttons = MessageBoxButtons.OK, + MessageBoxIcon icon = MessageBoxIcon.Information, + MessageBoxDefaultButton defaultButton = MessageBoxDefaultButton.Button1) + { + if (ShowUIMessage != null) + { + var e = new MessageEventArgs(message, buttons, icon, defaultButton); + ShowUIMessage(this, e); + if (e.MessageDisplayed) + return true; + } + return false; + } + + private void RunTests(IEnumerable list, ResetMode resetmode) + { + var testSuite = TestSuite.Reset(resetmode) as IVBATestSuite; + CheckReferences(); + + if (testSuite is AccessTestSuite accessSuite) + { + // TODO ScanningForTestModules: This triggers the ScanningForTestModules event, checkout if necessary + if (!CheckAccessApplicationIsCompiledAndRefreshFactoryModule(accessSuite)) + return; + + if (_breakOnAllErrorsForNextRun) + { + accessSuite.ErrorTrapping = VbaErrorTrapping.BreakOnAllErrors; + _breakOnAllErrorsForNextRun = false; + } + } + + // TODO ScanningForTestModules: This triggers the ScanningForTestModules event, checkout if necessary + AddTests(testSuite, list, resetmode); + + testSuite.Run(); + //Task.Run(() => testSuite.Run()); + } + + private bool CheckAccessApplicationIsCompiledAndRefreshFactoryModule(AccessTestSuite accessSuite) + { + if (accessSuite.CheckAccessApplicationIsCompiled()) return true; + + // safety: refresh factory procedures (if class renamed) + var saveModules = false; + try + { + saveModules = accessSuite.ActiveVBProject.Saved; + } + catch { } + + try // issue #37 + { + RaiseScanningForTestModules(); + accessSuite.Reset(ResetMode.RefreshFactoryModule); + } + catch + { + //accessSuite.HostApplication = HostApplication; + accessSuite.Reset(ResetMode.RefreshFactoryModule); + } + finally + { + if (saveModules) + TryExecuteSaveMenuItem(); + } + + try // issue #68 (try to compile) + { + if (VbeIntegrationManager.OfficeApplicationHelper is AccessApplicationHelper access) + { + access.RunCommand(AccessApplicationHelper.AcCommand.AcCmdCompileAndSaveAllModules); + if (access.IsCompiled) + return true; + } + } + catch (Exception ex) + { + Logger.Log(ex); + } + + return DialogResult.Cancel != UITools.ShowMessage(Resources.MessageStrings.Application_not_saved_in_compiled_state, + MessageBoxButtons.OKCancel, MessageBoxIcon.Information, MessageBoxDefaultButton.Button2 + ); + } + + private void TryExecuteSaveMenuItem() + { + using (new BlockLogger()) + { + try + { + new VbeCommandBarAdapter(VBE).MenuBar.FindControl(MsoControlType.msoControlButton, 3, Type.Missing, Type.Missing, true).Execute(); + } + catch (Exception ex) + { + Logger.Log(ex); + } + } + } + + /* + private void AddTestsAndTryToRepairComException(IVBATestSuite testSuite, IEnumerable list, ResetMode resetmode) + { + try + { + AddTests(testSuite, list, resetmode); + } + catch (COMException comEx) // issue #37 + { + Logger.Log(comEx); + RepairTestSuiteCOMException(); + AddTests(testSuite, list, resetmode); + } + catch (Exception ex) + { + Logger.Log(ex); + if (HostApplication == null) + { + throw new MissingHostException(); + } + throw; + } + } + + private void RepairTestSuiteCOMException() + { + if (TestSuite is AccessTestSuite) + { + var accessSuite = (AccessTestSuite)TestSuite; + accessSuite.HostApplication = HostApplication; + } + else + { + var vbaTestSuite = (VBATestSuite)TestSuite; + vbaTestSuite.HostApplication = HostApplication; + vbaTestSuite.ActiveVBProject = VbeIntegrationManager.OfficeApplicationHelper.CurrentVBProject; + } + } + */ + + private void AddTests(IVBATestSuite testSuite, IEnumerable list, ResetMode resetmode) + { + + if (list != null) + { + testSuite.AddTestClasses(list); + } + else if (resetmode == ResetMode.RemoveTests) + { + // TODO ScanningForTestModules: Call into TestClassManager.GetTestClassListFromVBProject() or alike - see comment block at the end of that method + RaiseScanningForTestModules(); + testSuite.AddFromVBProject(); + } + + // like this (but maintain condition logic as done above, the following condition is not sufficient!) + //if (list == null) + //{ + // var testClassManager = new TestClassManager(); + // list = testClassManager.GetTestClassListFromVBProject(true); + //} + //testSuite.AddTestClasses(list); + } + + private void RaiseScanningForTestModules() + { + ScanningForTestModules?.Invoke(this, EventArgs.Empty); + } + + public void SubscribeToCommandBarAdapter(VbeCommandBarAdapter commandBarAdapter) + { + using (new BlockLogger()) + { + AddRunButtonsToProjectExplorerContextMenu(commandBarAdapter); + AddRunButtonsToCodeWindowContextMenu(commandBarAdapter); + + if (commandBarAdapter is AccUnitCommandBarAdapter accUnitCommandbarAdapter) + { + AddRunButtonsToAccUnitSubMenu(accUnitCommandbarAdapter); + AddRunButtonsToAccUnitCommandBar(accUnitCommandbarAdapter); + } + + VbeIntegrationManager.VbeAdapter.MainWindowRButtonDown += OnVbeMainWindowRButtonDown; + + RegisterHotKeys(); + } + } + + private void AddRunButtonsToAccUnitSubMenu(AccUnitCommandBarAdapter commandBarAdapter) + { + var commandBar = commandBarAdapter.AccUnitSubMenu.CommandBar; + CreateCommandBarItems(commandBarAdapter, commandBar, null, false); + _accUnitSubMenuRunCurrentTestIndex = 1; + _accUnitSubMenuEvents = + commandBarAdapter.VBE.Events.CommandBarEvents[commandBarAdapter.AccUnitSubMenu]; + _accUnitSubMenuEvents.Click += OnAccUnitSubMenuEventsClick; + } + + private void AddRunButtonsToProjectExplorerContextMenu(VbeCommandBarAdapter commandBarAdapter) + { + const int printControlID = 4; + var commandBar = commandBarAdapter.CommandBarProjectWindow; + var printControlIndex = VbeCommandBarAdapter.GetButtonIndex(commandBar, printControlID); + _projectWindowRunCurrentTestButton = CreateCommandBarItems(commandBarAdapter, commandBar, printControlIndex, false); + } + + private void AddRunButtonsToCodeWindowContextMenu(VbeCommandBarAdapter commandBarAdapter) + { + const int objectBrowserControlID = 473; + var commandBar = commandBarAdapter.CommandBarCodeWindow; + var objectBrowserControlIndex = VbeCommandBarAdapter.GetButtonIndex(commandBar, objectBrowserControlID); + _codeWindowRunCurrentTestButton = CreateCommandBarItems(commandBarAdapter, commandBar, objectBrowserControlIndex, false); + } + + private void AddRunButtonsToAccUnitCommandBar(AccUnitCommandBarAdapter commandBarAdapter) + { + var commandBar = commandBarAdapter.AccUnitCommandbar; + CreateCommandBarItems(commandBarAdapter, commandBar, null, true); + } + + void OnAccUnitSubMenuEventsClick(object commandBarControl, ref bool handled, ref bool cancelDefault) + { + if (!(commandBarControl is CommandBarPopup mnu)) + return; + + mnu.Controls[_accUnitSubMenuRunCurrentTestIndex].Enabled = ActiveCodeModuleIsTestClass; + } + + private bool ActiveCodeModuleIsTestClass + { + get + { + try + { + var cm = VBE.ActiveCodePane.CodeModule; + return TestClassReader.IsTestClassCodeModul(cm); + } + catch (Exception ex) + { + Logger.Log(ex); + return false; + } + } + } + + private bool SelectedCodeModuleIsTestClass + { + get + { + try + { + var component = VBE.SelectedVBComponent; + return component != null && TestClassReader.IsTestClassCodeModul(component.CodeModule); + } + catch (Exception ex) + { + Logger.Log(ex); + return false; + } + } + } + + private CommandBarButton CreateCommandBarItems(VbeCommandBarAdapter commandBarAdapter, + CommandBar commandBar, + int? positionBefore, + bool usePicture) + { + var runCurrentTestButton = AddRunCurrentTestsCommandBarButton(commandBarAdapter, commandBar, positionBefore, usePicture); + AddRunAllTestsCommandBarButton(commandBarAdapter, commandBar, runCurrentTestButton.Index + 1, usePicture); + + return runCurrentTestButton; + } + + private CommandBarButton AddRunCurrentTestsCommandBarButton(VbeCommandBarAdapter commandBarAdapter, + CommandBar commandBar, + int? positionBefore, + bool usePicture) + { + var buttonData = new CommandbarButtonData + { + Caption = Resources.VbeCommandbars.RunCurrentTestCommandBarButtonCaption, + Description = Resources.VbeCommandbars.RunCurrentTestCommandBarButtonDescription, + FaceId = 2997, + Index = positionBefore, + BeginGroup = true + }; + var button = commandBarAdapter.AddCommandBarButton(commandBar, buttonData, RunCurrentTestsEventHandler); + button.ShortcutText = "Ctrl+Shift+T"; + if (usePicture) + { + ApplyMaskedPicture(button, Resources.Icons.runtest, Resources.Icons.runtest_mask); + } + return button; + } + + private CommandBarButton AddRunAllTestsCommandBarButton(VbeCommandBarAdapter commandBarAdapter, + CommandBar commandBar, + int? positionBefore, + bool usePicture) + { + var buttonData = new CommandbarButtonData + { + Caption = Resources.VbeCommandbars.RunAllTestsCommandBarButtonCaption, + Description = Resources.VbeCommandbars.RunAllTestsCommandBarButtonDescription, + FaceId = 620, + Index = positionBefore + }; + var button = commandBarAdapter.AddCommandBarButton(commandBar, buttonData, RunAllTestsEventHandler); + button.ShortcutText = "Ctrl+Shift+A"; + if (usePicture) + { + ApplyMaskedPicture(button, Resources.Icons.runtests, Resources.Icons.runtests_mask); + } + return button; + } + + private void ApplyMaskedPicture(CommandBarButton button, Bitmap image, Bitmap mask) + { + try + { + using (new BlockLogger()) + { + button.Style = MsoButtonStyle.msoButtonAutomatic; + // PERF: The first conversions takes long + using (new BlockLogger("PERF: 1st call to ImageToPictureDisp takes long")) + { + button.Picture = AxHostConverter.ImageToPictureDisp(image); + } + button.Mask = AxHostConverter.ImageToPictureDisp(mask); + } + } + catch (AccessViolationException e) + { + Logger.Log(e); + } + } + + private void RegisterHotKeys() + { + var hotkeys = VbeIntegrationManager.VbeAdapter.HotKeys; + var hotKey = hotkeys.RegisterHotKey(HotKey.ModKeys.Control | HotKey.ModKeys.Shift, (uint)Keys.T); + hotKey.Pressed += RunCurrentTestsHotKeyPressed; + + hotKey = hotkeys.RegisterHotKey(HotKey.ModKeys.Control | HotKey.ModKeys.Shift, (uint)Keys.A); + hotKey.Pressed += RunAllTestsHotKeyPressed; + } + + private void RunCurrentTestsHotKeyPressed(object sender, HotKeyEventArgs e) + { + RunCurrentTests(); + } + + private void RunAllTestsHotKeyPressed(object sender, HotKeyEventArgs e) + { + RunAllTests(); + } + + private void RunCurrentTestsEventHandler(CommandBarButton ctrl, ref bool cancelDefault) + { + RunCurrentTests(); + } + + private void RunAllTestsEventHandler(CommandBarButton ctrl, ref bool cancelDefault) + { + RunAllTests(); + } + + private void CheckReferences(bool constrainedCheck = false) + { + + if (!constrainedCheck && _referencesChecked) + return; + /* + using (var configurator = new Configurator()) + { + configurator.AccUnitReference.EnsureReferenceExistsInVbProject(VBE.ActiveVBProject); + } + */ + _referencesChecked = true; + } + + #region IDisposable Support + + bool _disposed; + + protected virtual void Dispose(bool disposing) + { + if (_disposed) return; + + if (disposing) + { + _codeWindowRunCurrentTestButton = null; + _projectWindowRunCurrentTestButton = null; + + _accUnitSubMenuEvents = null; + + if (VbeIntegrationManager != null) + { + try + { + VbeIntegrationManager.VbeAdapter.MainWindowRButtonDown -= OnVbeMainWindowRButtonDown; + } + catch (Exception ex) + { + Logger.Log(ex); + } + finally + { + VbeIntegrationManager = null; + } + } + + TestSuiteManager = null; + } + + _disposed = true; + } + + public void Dispose() + { + using (new BlockLogger()) + { + Dispose(true); + GC.SuppressFinalize(this); + } + } + + ~TestStarter() + { + Dispose(false); + } + + #endregion + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/TestSuiteManager.cs b/vbe-add-In/AccUnit.VbeAddIn/TestSuiteManager.cs new file mode 100644 index 0000000..84fcbbf --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/TestSuiteManager.cs @@ -0,0 +1,186 @@ +using AccessCodeLib.AccUnit.Interfaces; +using AccessCodeLib.AccUnit.Interop; +using AccessCodeLib.Common.Tools.Logging; +using AccessCodeLib.Common.VBIDETools; +using Microsoft.Vbe.Interop; +using System; +using System.Collections.Generic; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + class TestSuiteManager : IDisposable + { + public delegate void TestSuiteInitializedEventHandler(ITestSuite suite); + public event TestSuiteInitializedEventHandler TestSuiteInitialized; + + public delegate void TestResultReporterRequestEventHandler(ref IList reporters); + public event TestResultReporterRequestEventHandler TestResultReporterRequest; + + /* + public delegate void TestCountChangedEventHandler(int number); + public event TestCountChangedEventHandler TestCountChanged; + */ + + private Interfaces.IVBATestSuite _vbaTestSuite; + + private OfficeApplicationHelper _officeApplicationHelper; + public OfficeApplicationHelper OfficeApplicationHelper + { + get { return _officeApplicationHelper; } + set + { + _officeApplicationHelper = value; + } + } + + public Interfaces.IVBATestSuite TestSuite + { + get + { + if (_vbaTestSuite == null) + { + InitTestSuite(); + } + return _vbaTestSuite; + } + } + + public VBProject ActiveVBProject + { + get + { + return ((VBATestSuite)TestSuite).ActiveVBProject; + } + } + + private void InitTestSuite() + { + using (new BlockLogger()) + { + try + { + _vbaTestSuite = CreateVbaTestSuite(OfficeApplicationHelper); + } + catch (Exception ex) + { + UITools.ShowException(ex); + } + finally + { + TestSuiteInitialized?.Invoke(_vbaTestSuite); + } + } + } + + private Interfaces.IVBATestSuite CreateVbaTestSuite(OfficeApplicationHelper applicationHelper) + { + using (new BlockLogger()) + { + Interfaces.IVBATestSuite vbaTestSuite; + var accUnitFactory = new Interop.AccUnitFactory(); + if (applicationHelper is AccessApplicationHelper) + { + Logger.Log("Access application"); + vbaTestSuite = accUnitFactory.AccessTestSuite(applicationHelper); + } + else + { + vbaTestSuite = accUnitFactory.VBATestSuite(applicationHelper); + } + + IList reporters = new List(); + TestResultReporterRequest?.Invoke(ref reporters); + foreach (ITestResultReporter reporter in reporters) + { + vbaTestSuite.AppendTestResultReporter(reporter); + } + + return vbaTestSuite; + } + } + + public IAssert Assert + { + get + { + var accUnitFactory = new Interop.AccUnitFactory(); + return accUnitFactory.Assert; + } + } + + public IConstraintBuilder ConstraintBuilder + { + get + { + var accUnitFactory = new Interop.AccUnitFactory(); + return accUnitFactory.ConstraintBuilder; + } + } + + #region IDisposable Support + + bool _disposed; + + protected virtual void Dispose(bool disposing) + { + if (_disposed) return; + + if (disposing) + { + DisposeManagedResources(); + } + + DisposeUnmanagedResources(); + _disposed = true; + } + + private void DisposeUnmanagedResources() + { + OfficeApplicationHelper = null; + } + + private void DisposeManagedResources() + { + DisposeVbaTestSuite(); + } + + private void DisposeVbaTestSuite() + { + if (_vbaTestSuite == null) + return; + + using (new BlockLogger()) + { + try + { + _vbaTestSuite.Dispose(); + Logger.Log("_vbaTestSuite disposed"); + } + catch (Exception exception) + { + Logger.Log(exception); + } + finally + { + _vbaTestSuite = null; + } + } + } + + public void Dispose() + { + using (new BlockLogger()) + { + Dispose(true); + GC.SuppressFinalize(this); + } + } + + ~TestSuiteManager() + { + Dispose(false); + } + #endregion + + } +} diff --git a/source/AccUnit/~trash/UITools.cs b/vbe-add-In/AccUnit.VbeAddIn/UITools.cs similarity index 75% rename from source/AccUnit/~trash/UITools.cs rename to vbe-add-In/AccUnit.VbeAddIn/UITools.cs index ae4cf2e..0bd5140 100644 --- a/source/AccUnit/~trash/UITools.cs +++ b/vbe-add-In/AccUnit.VbeAddIn/UITools.cs @@ -1,13 +1,15 @@ -/* +using AccessCodeLib.AccUnit.VbeAddIn.Resources; using AccessCodeLib.Common.Tools.Logging; using System; using System.Drawing; using System.Text; using System.Windows.Forms; +using System.Windows.Interop; +using System.Windows.Media.Imaging; -namespace AccessCodeLib.AccUnit.Common +namespace AccessCodeLib.AccUnit.VbeAddIn { - public static class UITools + internal static class UITools { public static void ShowException(Exception exception) { @@ -70,7 +72,7 @@ public static DialogResult InputBox(string title, string promptText, ref string buttonCancel.SetBounds(309, 72, 75, 23); label.AutoSize = true; - textBox.Anchor |= AnchorStyles.Right; + textBox.Anchor = textBox.Anchor | AnchorStyles.Right; buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; @@ -93,6 +95,36 @@ public static Icon ConvertBitmapToIcon(Bitmap bmp) { return Icon.FromHandle(bmp.GetHicon()); } + + public static BitmapSource ConvertBitmapToBitmapSource(Bitmap bitmap) + { + var hBitmap = bitmap.GetHbitmap(); + BitmapSource bitmapSource; + + try + { + bitmapSource = Imaging.CreateBitmapSourceFromHBitmap( + hBitmap, + IntPtr.Zero, + System.Windows.Int32Rect.Empty, + BitmapSizeOptions.FromEmptyOptions()); + } + finally + { + DeleteObject(hBitmap); + } + + return bitmapSource; + } + + [System.Runtime.InteropServices.DllImport("gdi32.dll")] + private static extern bool DeleteObject(IntPtr hObject); + + public static float GetScalingFactor() + { + Graphics g = Graphics.FromHwnd(IntPtr.Zero); + float dpiX = g.DpiX; + return dpiX / 96; // 96 DPI = 100% + } } -} -*/ \ No newline at end of file +} \ No newline at end of file diff --git a/vbe-add-In/AccUnit.VbeAddIn/VbProjectEventArgs.cs b/vbe-add-In/AccUnit.VbeAddIn/VbProjectEventArgs.cs new file mode 100644 index 0000000..c7d1931 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/VbProjectEventArgs.cs @@ -0,0 +1,20 @@ +using Microsoft.Vbe.Interop; +using System; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + class VbProjectEventArgs : EventArgs + { + private readonly VBProject _vbProject; + + public VbProjectEventArgs(VBProject vbProject) + { + _vbProject = vbProject; + } + + public VBProject VBProject + { + get { return _vbProject; } + } + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/VbeCodePaneTools.cs b/vbe-add-In/AccUnit.VbeAddIn/VbeCodePaneTools.cs new file mode 100644 index 0000000..ac13206 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/VbeCodePaneTools.cs @@ -0,0 +1,51 @@ +using Microsoft.Vbe.Interop; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + public static class VbeCodePaneTools + { + public static string GetCodeModuleMemberNameFromCodePane(_CodePane codepane) + { + return GetCodeModuleMemberNameFromCodePane(codepane, out _); + } + + public static string GetCodeModuleMemberNameFromCodePane(_CodePane codepane, out vbext_ProcKind procKind) + { + var startLine = GetStartLineFromCodePaneSelection(codepane); + var codemodule = codepane.CodeModule; + return codemodule.get_ProcOfLine(startLine, out procKind); + } + + public static int GetStartLineFromCodePaneSelection(_CodePane codepane) + { + codepane.GetSelection(out int startLine, out _, out _, out _); + return startLine; + } + + public static void InsertText(_CodePane codepane, string text, int startLine) + { + var codemodule = codepane.CodeModule; + codemodule.InsertLines(startLine, text); + } + + public static string GetSelectedText(_CodePane codepane) + { + codepane.GetSelection(out int startLine, out int startColumn, out int endLine, out int endColumn); + + var text = codepane.CodeModule.Lines[startLine, endLine - startLine + 1]; + + if (startLine != endLine) + { + var lastLine = codepane.CodeModule.Lines[endLine, 1]; + if (lastLine.Length > endColumn) + text = text.Substring(1, text.Length - (lastLine.Length - endColumn)); + } + + if (startColumn > 1) + text = text.Substring(startColumn); + + return text; + } + + } +} \ No newline at end of file diff --git a/vbe-add-In/AccUnit.VbeAddIn/VbeIntegrationManager.cs b/vbe-add-In/AccUnit.VbeAddIn/VbeIntegrationManager.cs new file mode 100644 index 0000000..53d436e --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/VbeIntegrationManager.cs @@ -0,0 +1,508 @@ +using AccessCodeLib.AccUnit.Configuration; +using AccessCodeLib.AccUnit.Tools; +using AccessCodeLib.Common.Tools.Logging; +using AccessCodeLib.Common.VBIDETools; +using AccessCodeLib.Common.VBIDETools.Commandbar; +using AccessCodeLib.Common.VBIDETools.Templates; +using Microsoft.Office.Core; +using Microsoft.Vbe.Interop; +using System; +using System.Drawing; +using System.Linq; +using System.Windows.Forms; + +namespace AccessCodeLib.AccUnit.VbeAddIn +{ + class VbeIntegrationManager : IDisposable, ICommandBarsAdapterClient + { + private readonly VbeAdapter _vbeAdapter = new VbeAdapter(); + private readonly ImportExportManager _importExportManager = new ImportExportManager(); + private TestClassManager _testClassManager; + + public VbeIntegrationManager() + { + _importExportManager.TestClassesImported += ImportExportManagerTestClassesImported; + } + + public event EventHandler VBProjectChanged; + public event EventHandler ScanningForTestModules; + + public OfficeApplicationHelper OfficeApplicationHelper + { + get { return _vbeAdapter.OfficeApplicationHelper; } + set + { + _vbeAdapter.OfficeApplicationHelper = value; + _importExportManager.TestClassManager = TestClassManager; + } + } + + public VbeAdapter VbeAdapter + { + get { return _vbeAdapter; } + } + + void ImportExportManagerTestClassesImported(object sender, EventArgs e) + { + if (!(OfficeApplicationHelper is AccessApplicationHelper)) return; + ((AccessApplicationHelper)OfficeApplicationHelper).RunCommand(AccessApplicationHelper.AcCommand.AcCmdCompileAndSaveAllModules); + } + + private VBProject ActiveVBProject + { + get { return _vbeAdapter.ActiveVBProject; } + } + + public TestClassManager TestClassManager + { + get + { + if (_testClassManager == null) + InitTestClassManager(); + + return _testClassManager; + } + } + + private void InitTestClassManager() + { + _testClassManager = new TestClassManager(OfficeApplicationHelper); + _importExportManager.TestClassManager = _testClassManager; + _testClassManager.RepairActiveVBProjectCOMException += TestClassManagerOnRepairActiveVbProjectComException; + _testClassManager.ScanningForTestModules += TestClassManagerOnScanningForTestModules; + } + + void TestClassManagerOnScanningForTestModules(object sender, EventArgs e) + { + RaiseScanningForTestModules(); + } + + public object HostApplication + { + get { return OfficeApplicationHelper.Application; } + } + + private void SetTestEnvironment() + { + var configurator = new Configurator(ActiveVBProject); + configurator.InsertAccUnitLoaderFactoryModule(AccUnitTypeLibIsReferenced, true); + } + + private bool AccUnitTypeLibIsReferenced + { + get + { + foreach (Reference reference in ActiveVBProject.References) + { + if (reference.IsBroken) continue; + if (reference.Name == "AccUnit") + return true; + } + return false; + } + } + + private void RemoveTestEnvironment() + { + if (MessageBox.Show(Resources.UserControls.RemoveEnvironmentMessageBoxText, + Resources.UserControls.RemoveEnvironmentMessageBoxCaption, + MessageBoxButtons.YesNo, + MessageBoxIcon.Exclamation) != DialogResult.Yes) return; + + TestClassManager.RemoveTestComponents(true, true); + } + + private void CreateTestMethodInActiveCodePane() + { + var insertTestMethodDataContext = new InsertTestMethodViewModel(); + var dialog = new InsertTestMethodDialog(insertTestMethodDataContext); + + insertTestMethodDataContext.InsertTestMethod += (sender, e) => + { + InsertTestMethodDialogCommitMethodName(sender, e); + dialog.Close(); + }; + insertTestMethodDataContext.Canceled += (sender, e) => dialog.Close(); + + SetDialogPosition(dialog); + dialog.ShowDialog(); + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE0060:Remove unused parameter", Justification = "default interface, but not used")] + private void InsertTestMethodDialogCommitMethodName(InsertTestMethodViewModel sender, TestNamePartsEventArgs e) + { + var methodUnderTest = e.Items.FirstOrDefault(i => i.Name == InsertTestMethodViewModel.TestNamePart_MethodName)?.Value; + var stateUnderTest = e.Items.FirstOrDefault(i => i.Name == InsertTestMethodViewModel.TestNamePart_State)?.Value; + var expectedBehaviour = e.Items.FirstOrDefault(i => i.Name == InsertTestMethodViewModel.TestNamePart_Expected)?.Value; + CreateTestMethodInActiveCodePane(methodUnderTest, stateUnderTest, expectedBehaviour); + } + + private void CreateTestMethodInActiveCodePane(string methodUnderTest, string stateUnderTest, string expectedBehaviour) + { + using (new BlockLogger()) + { + if (string.IsNullOrEmpty(methodUnderTest)) + methodUnderTest = "MethodUnderTest"; + var memberInfo = new CodeModuleMember(methodUnderTest, vbext_ProcKind.vbext_pk_Proc, true); + var methodText = TestCodeGenerator.GenerateProcedureCode(memberInfo, stateUnderTest, expectedBehaviour); + + var activeCodePane = _vbeAdapter.ActiveCodePane; + var startLine = VbeCodePaneTools.GetStartLineFromCodePaneSelection(activeCodePane); + + //Todo: check if startLine is inside a method + + VbeCodePaneTools.InsertText(activeCodePane, methodText, startLine); + } + } + + public TestClassInfo GetTestClassInfoFromSelectedComponent() + { + var selectedComponent = _vbeAdapter.VBE.SelectedVBComponent; + if (selectedComponent == null) + return null; // no active test + + if (selectedComponent.Type != vbext_ComponentType.vbext_ct_ClassModule) + return null; + + if (!TestClassReader.IsTestClassCodeModul(selectedComponent.CodeModule)) + return null; + + var className = selectedComponent.Name; + var memberInfo = GetTestClassMemberInfoFromCodePane(selectedComponent.CodeModule.CodePane); + + TestClassInfo testclass; + if (memberInfo != null) + { + var members = new TestClassMemberList { memberInfo }; + testclass = new TestClassInfo(className, members); + } + else + { + testclass = new TestClassInfo(className); + } + return testclass; + } + + private static TestClassMemberInfo GetTestClassMemberInfoFromCodePane(_CodePane codepane) + { + var procName = VbeCodePaneTools.GetCodeModuleMemberNameFromCodePane(codepane, out vbext_ProcKind procKind); + + if (procKind == vbext_ProcKind.vbext_pk_Proc && procName != null) + { + return new TestClassMemberInfo(procName); + } + return null; + } + + private void InsertTestMethodDialogCommitMethodName(object sender, CommitInsertTestMethodEventArgs e) + { + CreateTestMethodInActiveCodePane(e.MethodUnderTest, e.StateUnderTest, e.ExpectedBehaviour); + } + + private void TestClassManagerOnRepairActiveVbProjectComException(object sender, EventArgs e) + { + try + { + RepairTestSuiteCOMException(); + } + catch (Exception ex) + { + Logger.Log(ex); + } + } + + private void RaiseScanningForTestModules() + { + ScanningForTestModules?.Invoke(this, EventArgs.Empty); + } + + private void RepairTestSuiteCOMException() + { + VBProjectChanged?.Invoke(this, new VbProjectEventArgs(OfficeApplicationHelper.CurrentVBProject)); + + TestClassManager.ApplicationHelper = OfficeApplicationHelper; + } + + public void ShowMissingApplicationInfo() + { + if (HostApplication == null) + { + UITools.ShowMessage(Resources.MessageStrings.MissingHostApplicationReference); + } + } + + #region ICommandBarsAdapterClient support + + public void SubscribeToCommandBarAdapter(VbeCommandBarAdapter commandBarAdapter) + { + using (new BlockLogger()) + { + _importExportManager.SubscribeToCommandBarAdapter(commandBarAdapter); + CreateShortcutMenuItems(commandBarAdapter); + } + } + + private void CreateShortcutMenuItems(VbeCommandBarAdapter commandBarAdapter) + { + if (commandBarAdapter is AccUnitCommandBarAdapter accUnitCommandBarAdapter) + { + var menu = accUnitCommandBarAdapter.AccUnitSubMenu; + CreateAccUnitToolsSubMenuItems(commandBarAdapter, menu); + } + + var commandBar = commandBarAdapter.CommandBarCodeWindow; + const int objectBrowserControlID = 473; + CreateAccUnitShortcutMenuItems(commandBarAdapter, commandBar, objectBrowserControlID); + + commandBar = commandBarAdapter.CommandBarProjectWindow; + const int printControlID = 4; + CreateAccUnitShortcutMenuItems(commandBarAdapter, commandBar, printControlID); + + } + + private void CreateAccUnitToolsSubMenuItems(VbeCommandBarAdapter commandBarAdapter, CommandBarPopup menu) + { + CreateAccUnitToolsSetTestEnvironmentSubMenuItem(commandBarAdapter, menu); + CreateAccUnitToolsRemoveTestEnvironmentSubMenuItem(commandBarAdapter, menu); + } + + private void CreateAccUnitToolsSetTestEnvironmentSubMenuItem(VbeCommandBarAdapter commandBarAdapter, CommandBarPopup menu) + { + var buttonData = new CommandbarButtonData + { + Caption = Resources.VbeCommandbars.ToolsSetTestEnvironmentCommandButtonCaption, + Description = string.Empty, + FaceId = 589, + BeginGroup = true + }; + commandBarAdapter.AddCommandBarButton(menu, buttonData, AccUnitMenuItemsSetTestEnvironment); + } + + private void CreateAccUnitToolsRemoveTestEnvironmentSubMenuItem(VbeCommandBarAdapter commandBarAdapter, CommandBarPopup menu) + { + var buttonData = new CommandbarButtonData + { + Caption = Resources.VbeCommandbars.ToolsRemoveTestEnvironmentCommandButtonCaption, + Description = string.Empty, + FaceId = 478, + BeginGroup = false + }; + commandBarAdapter.AddCommandBarButton(menu, buttonData, AccUnitMenuItemsRemoveTestEnvironment); + } + + private void CreateAccUnitShortcutMenuItems(VbeCommandBarAdapter accUnitMenuItems, CommandBar commandBar, int controlID) + { + var objectBrowserControlIndex = VbeCommandBarAdapter.GetButtonIndex(commandBar, controlID); + var buttonData = new CommandbarButtonData + { + Caption = Resources.VbeCommandbars.InsertTestMethodCommandbarButtonCaption, + Description = string.Empty, + FaceId = 559, + BeginGroup = true, + Index = objectBrowserControlIndex + }; + accUnitMenuItems.AddCommandBarButton(commandBar, buttonData, AccUnitMenuItemsInsertTestMethod); + } + + void AccUnitMenuItemsSetTestEnvironment(CommandBarButton ctrl, ref bool cancelDefault) + { + SetTestEnvironment(); + } + + void AccUnitMenuItemsRemoveTestEnvironment(CommandBarButton ctrl, ref bool cancelDefault) + { + RemoveTestEnvironment(); + } + + void AccUnitMenuItemsInsertTestMethod(CommandBarButton ctrl, ref bool cancelDefault) + { + if (SelectedVbComponentIsTestClass) + CreateTestMethodInActiveCodePane(); + else + CreateTestMethodFromSelectedVbComponent(); + } + + private bool SelectedVbComponentIsTestClass + { + get + { + return TestClassReader.IsTestClassCodeModul(_vbeAdapter.VBE.SelectedVBComponent.CodeModule); + } + } + + public object VBETools { get; private set; } + + private void CreateTestMethodFromSelectedVbComponent() + { + var generateTestMethodsFromCodeModuleDataContext = new GenerateTestMethodsFromCodeModuleViewModel(GetCodeModuleInfoWithMarkerFromSelectedVbComponent()); + var dialog = new GenerateTestMethodsFromCodeModuleDialog(generateTestMethodsFromCodeModuleDataContext); + + generateTestMethodsFromCodeModuleDataContext.InsertTestMethods += (sender, e) => + { + var newCodeModule = InsertTestMethodsDialogCommitMethodName(sender, e); + dialog.Close(); + if (newCodeModule != null) + { + newCodeModule.CodePane.Show(); + newCodeModule.CodePane.Window.SetFocus(); + } + }; + generateTestMethodsFromCodeModuleDataContext.Canceled += (sender, e) => dialog.Close(); + + SetDialogPosition(dialog); + dialog.ShowDialog(); + } + + private void SetDialogPosition(System.Windows.Window dialog) + { + var scaleFactor = UITools.GetScalingFactor(); + var width = dialog.MinWidth; + var height = dialog.MaxHeight; + + dialog.Top = (_vbeAdapter.VBE.MainWindow.Top + _vbeAdapter.VBE.MainWindow.Height / 2) / scaleFactor - height / 2; + dialog.Left = (_vbeAdapter.VBE.MainWindow.Left + _vbeAdapter.VBE.MainWindow.Width / 2) / scaleFactor - width / 2; + } + + private CodeModule InsertTestMethodsDialogCommitMethodName(object sender, CommitInsertTestMethodsEventArgs e) + { + var testClassGenerator = new TestClassGenerator(ActiveVBProject); + try + { + using (new BlockLogger($"{e.TestClass}.{e.MethodsUnderTest}_{e.StateUnderTest}_{e.ExpectedBehaviour}")) + { + return testClassGenerator.InsertTestMethods(e.TestClass, e.MethodsUnderTest, e.StateUnderTest, e.ExpectedBehaviour); + } + } + catch (Exception ex) + { + Logger.Log(ex); + e.Cancel = true; + return null; + } + } + + private CodeModuleInfo GetCodeModuleInfoWithMarkerFromSelectedVbComponent() + { + var vbc = _vbeAdapter.VBE.SelectedVBComponent; + var reader = new CodeModuleReader(vbc.CodeModule); + var codemoduleInfo = reader.CodeModuleInfo; + + var codePane = _vbeAdapter.ActiveCodePane; + var activeMemberName = (codePane == null || codePane.CodeModule != vbc.CodeModule) ? null : VbeCodePaneTools.GetCodeModuleMemberNameFromCodePane(codePane); + + var markAll = (activeMemberName == null); + var publicMembers = codemoduleInfo.Members.FindAll(m => m.IsPublic); + + var newMembers = new CodeModuleMemberList(); + newMembers.AddRange(publicMembers.Select(newMember => new CodeModuleMemberWithMarker(newMember.Name, newMember.ProcKind, newMember.IsPublic, newMember.DeclarationString, markAll)).Cast()); + if (!markAll) + { + var markedMember = (CodeModuleMemberWithMarker)newMembers.Find(m => m.Name == activeMemberName); + if (markedMember != null) markedMember.Marked = true; + var info = activeMemberName; + if (markedMember != null) info += string.Format(": {0}", markedMember.Marked); + Logger.Log(info); + } + + codemoduleInfo.Members = newMembers; + return codemoduleInfo; + } + + public void InsertTestTemplate(string templatekey) + { + var templates = UserSettings.Current.TestTemplates; + var template = templates[templatekey]; + var name = FindFreeClassName(template.Name); + do + { + if (DialogResult.OK != UITools.InputBox(Resources.UserControls.InsertTestTemplateInputboxTitle, + Resources.UserControls.InsertTestTemplateInputboxPromptText, + ref name)) + return; + + } while (!InsertTestTemplate(template, name)); + } + + private string FindFreeClassName(string defaultName) + { + var codeModuleContainer = new CodeModuleContainer(ActiveVBProject); + var newClassName = defaultName; + var i = 0; + while (codeModuleContainer.Exists(newClassName)) + { + newClassName = string.Format("{0}{1}", defaultName, ++i); + } + return newClassName; + } + + private bool InsertTestTemplate(CodeTemplate template, string className) + { + try + { + TestClassManager.InsertTestTemplate(template, className); + return true; + } + catch (ArgumentException ex) + { + UITools.ShowMessage(ex.Message); + return false; + } + catch (Exception ex) + { + UITools.ShowException(ex); + return false; + } + } + + #endregion + + #region IDisposable Support + + bool _disposed; + + protected virtual void Dispose(bool disposing) + { + if (_disposed) return; + + if (disposing) + { + DisposeManagedResources(); + } + + //DisposeUnmanagedResources(); + _disposed = true; + } + + //private void DisposeUnmanagedResources() + //{ + //} + + private void DisposeManagedResources() + { + if (_testClassManager != null) + { + _testClassManager.Dispose(); + _testClassManager = null; + } + + _importExportManager.Dispose(); + _vbeAdapter.Dispose(); + } + + public void Dispose() + { + using (new BlockLogger()) + { + Dispose(true); + GC.SuppressFinalize(this); + } + } + + ~VbeIntegrationManager() + { + Dispose(false); + } + + #endregion + } +} diff --git a/vbe-add-In/AccUnit.VbeAddIn/app.config b/vbe-add-In/AccUnit.VbeAddIn/app.config new file mode 100644 index 0000000..100bee2 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/app.config @@ -0,0 +1,36 @@ + + + + +
+ + + + + + 1 + + + 0 + + + 0 + + + -1 + + + True + + + False + + + True + + + %ModuleUnderTest%Tests + + + + \ No newline at end of file diff --git a/vbe-add-In/AccUnit.VbeAddIn/packages.config b/vbe-add-In/AccUnit.VbeAddIn/packages.config new file mode 100644 index 0000000..df82ff8 --- /dev/null +++ b/vbe-add-In/AccUnit.VbeAddIn/packages.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/vbe-add-In/AccessCodeLib.AccUnit.VbeAddIn.sln b/vbe-add-In/AccessCodeLib.AccUnit.VbeAddIn.sln new file mode 100644 index 0000000..c257fd3 --- /dev/null +++ b/vbe-add-In/AccessCodeLib.AccUnit.VbeAddIn.sln @@ -0,0 +1,130 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34723.18 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AccessCodeLib.AccUnit.VbeAddIn", "AccUnit.VbeAddIn\AccessCodeLib.AccUnit.VbeAddIn.csproj", "{179AC295-1F12-462D-B1A1-AEA0F204C6CA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AccessCodeLib.Common.Tools", "..\source\Common\Common.Tools\AccessCodeLib.Common.Tools.csproj", "{7AF24615-91B3-4775-BC6E-C8986F980B57}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AccessCodeLib.Common.VBIDETools", "..\source\Common\Common.VBIDETools\AccessCodeLib.Common.VBIDETools.csproj", "{9FA679C2-82C0-42DC-A34F-F78A9012EEEB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AccessCodeLib.AccUnit", "..\source\AccUnit\AccessCodeLib.AccUnit.csproj", "{1575D69A-C503-4149-B3A9-2CE188B19C15}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{21839B1B-5233-411F-8993-9631D5A5BA34}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WpfUserControlsTests", "Tests\WpfUserControlsTests\WpfUserControlsTests.csproj", "{C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + AzureCI|Any CPU = AzureCI|Any CPU + AzureCI|x64 = AzureCI|x64 + AzureCI|x86 = AzureCI|x86 + Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.AzureCI|Any CPU.ActiveCfg = AzureCI|Any CPU + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.AzureCI|Any CPU.Build.0 = AzureCI|Any CPU + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.AzureCI|x64.ActiveCfg = Release|Any CPU + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.AzureCI|x64.Build.0 = Release|Any CPU + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.AzureCI|x86.ActiveCfg = Release|Any CPU + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.AzureCI|x86.Build.0 = Release|Any CPU + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.Debug|x64.ActiveCfg = Debug|Any CPU + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.Debug|x64.Build.0 = Debug|Any CPU + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.Debug|x86.ActiveCfg = Debug|x86 + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.Debug|x86.Build.0 = Debug|x86 + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.Release|Any CPU.Build.0 = Release|Any CPU + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.Release|x64.ActiveCfg = Release|Any CPU + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.Release|x64.Build.0 = Release|Any CPU + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.Release|x86.ActiveCfg = Release|Any CPU + {179AC295-1F12-462D-B1A1-AEA0F204C6CA}.Release|x86.Build.0 = Release|Any CPU + {7AF24615-91B3-4775-BC6E-C8986F980B57}.AzureCI|Any CPU.ActiveCfg = AzureCI|Any CPU + {7AF24615-91B3-4775-BC6E-C8986F980B57}.AzureCI|Any CPU.Build.0 = AzureCI|Any CPU + {7AF24615-91B3-4775-BC6E-C8986F980B57}.AzureCI|x64.ActiveCfg = AzureCI|x64 + {7AF24615-91B3-4775-BC6E-C8986F980B57}.AzureCI|x64.Build.0 = AzureCI|x64 + {7AF24615-91B3-4775-BC6E-C8986F980B57}.AzureCI|x86.ActiveCfg = AzureCI|x86 + {7AF24615-91B3-4775-BC6E-C8986F980B57}.AzureCI|x86.Build.0 = AzureCI|x86 + {7AF24615-91B3-4775-BC6E-C8986F980B57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7AF24615-91B3-4775-BC6E-C8986F980B57}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7AF24615-91B3-4775-BC6E-C8986F980B57}.Debug|x64.ActiveCfg = Debug|x64 + {7AF24615-91B3-4775-BC6E-C8986F980B57}.Debug|x64.Build.0 = Debug|x64 + {7AF24615-91B3-4775-BC6E-C8986F980B57}.Debug|x86.ActiveCfg = Debug|x86 + {7AF24615-91B3-4775-BC6E-C8986F980B57}.Debug|x86.Build.0 = Debug|x86 + {7AF24615-91B3-4775-BC6E-C8986F980B57}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7AF24615-91B3-4775-BC6E-C8986F980B57}.Release|Any CPU.Build.0 = Release|Any CPU + {7AF24615-91B3-4775-BC6E-C8986F980B57}.Release|x64.ActiveCfg = Release|x64 + {7AF24615-91B3-4775-BC6E-C8986F980B57}.Release|x64.Build.0 = Release|x64 + {7AF24615-91B3-4775-BC6E-C8986F980B57}.Release|x86.ActiveCfg = Release|x86 + {7AF24615-91B3-4775-BC6E-C8986F980B57}.Release|x86.Build.0 = Release|x86 + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.AzureCI|Any CPU.ActiveCfg = AzureCI|Any CPU + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.AzureCI|Any CPU.Build.0 = AzureCI|Any CPU + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.AzureCI|x64.ActiveCfg = AzureCI|x64 + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.AzureCI|x64.Build.0 = AzureCI|x64 + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.AzureCI|x86.ActiveCfg = AzureCI|x86 + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.AzureCI|x86.Build.0 = AzureCI|x86 + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.Debug|x64.ActiveCfg = Debug|x64 + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.Debug|x64.Build.0 = Debug|x64 + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.Debug|x86.ActiveCfg = Debug|x86 + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.Debug|x86.Build.0 = Debug|x86 + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.Release|Any CPU.Build.0 = Release|Any CPU + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.Release|x64.ActiveCfg = Release|x64 + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.Release|x64.Build.0 = Release|x64 + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.Release|x86.ActiveCfg = Release|x86 + {9FA679C2-82C0-42DC-A34F-F78A9012EEEB}.Release|x86.Build.0 = Release|x86 + {1575D69A-C503-4149-B3A9-2CE188B19C15}.AzureCI|Any CPU.ActiveCfg = AzureCI|Any CPU + {1575D69A-C503-4149-B3A9-2CE188B19C15}.AzureCI|Any CPU.Build.0 = AzureCI|Any CPU + {1575D69A-C503-4149-B3A9-2CE188B19C15}.AzureCI|x64.ActiveCfg = AzureCI|x64 + {1575D69A-C503-4149-B3A9-2CE188B19C15}.AzureCI|x64.Build.0 = AzureCI|x64 + {1575D69A-C503-4149-B3A9-2CE188B19C15}.AzureCI|x86.ActiveCfg = AzureCI|x86 + {1575D69A-C503-4149-B3A9-2CE188B19C15}.AzureCI|x86.Build.0 = AzureCI|x86 + {1575D69A-C503-4149-B3A9-2CE188B19C15}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1575D69A-C503-4149-B3A9-2CE188B19C15}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1575D69A-C503-4149-B3A9-2CE188B19C15}.Debug|x64.ActiveCfg = Debug|x64 + {1575D69A-C503-4149-B3A9-2CE188B19C15}.Debug|x64.Build.0 = Debug|x64 + {1575D69A-C503-4149-B3A9-2CE188B19C15}.Debug|x86.ActiveCfg = Debug|x86 + {1575D69A-C503-4149-B3A9-2CE188B19C15}.Debug|x86.Build.0 = Debug|x86 + {1575D69A-C503-4149-B3A9-2CE188B19C15}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1575D69A-C503-4149-B3A9-2CE188B19C15}.Release|Any CPU.Build.0 = Release|Any CPU + {1575D69A-C503-4149-B3A9-2CE188B19C15}.Release|x64.ActiveCfg = Release|x64 + {1575D69A-C503-4149-B3A9-2CE188B19C15}.Release|x64.Build.0 = Release|x64 + {1575D69A-C503-4149-B3A9-2CE188B19C15}.Release|x86.ActiveCfg = Release|x86 + {1575D69A-C503-4149-B3A9-2CE188B19C15}.Release|x86.Build.0 = Release|x86 + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.AzureCI|Any CPU.ActiveCfg = Debug|Any CPU + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.AzureCI|x64.ActiveCfg = Debug|Any CPU + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.AzureCI|x64.Build.0 = Debug|Any CPU + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.AzureCI|x86.ActiveCfg = Debug|Any CPU + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.AzureCI|x86.Build.0 = Debug|Any CPU + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.Debug|x64.ActiveCfg = Debug|Any CPU + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.Debug|x64.Build.0 = Debug|Any CPU + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.Debug|x86.ActiveCfg = Debug|Any CPU + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.Debug|x86.Build.0 = Debug|Any CPU + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.Release|Any CPU.Build.0 = Release|Any CPU + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.Release|x64.ActiveCfg = Release|Any CPU + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.Release|x64.Build.0 = Release|Any CPU + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.Release|x86.ActiveCfg = Release|Any CPU + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {C63CF654-F59C-4F98-9DB1-3DE62BF99ECF} = {21839B1B-5233-411F-8993-9631D5A5BA34} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {7937BEBA-24F9-4A3C-987E-8801C4C58F6C} + EndGlobalSection +EndGlobal diff --git a/vbe-add-In/Tests/WpfUserControlsTests/UnitTest1.cs b/vbe-add-In/Tests/WpfUserControlsTests/UnitTest1.cs new file mode 100644 index 0000000..50f9e74 --- /dev/null +++ b/vbe-add-In/Tests/WpfUserControlsTests/UnitTest1.cs @@ -0,0 +1,16 @@ +namespace WpfUserControlsTests +{ + public class Tests + { + [SetUp] + public void Setup() + { + } + + [Test] + public void Test1() + { + Assert.Pass(); + } + } +} \ No newline at end of file diff --git a/vbe-add-In/Tests/WpfUserControlsTests/WpfUserControlsTests.csproj b/vbe-add-In/Tests/WpfUserControlsTests/WpfUserControlsTests.csproj new file mode 100644 index 0000000..8b5797e --- /dev/null +++ b/vbe-add-In/Tests/WpfUserControlsTests/WpfUserControlsTests.csproj @@ -0,0 +1,24 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + + + + + + + + diff --git a/vbe-add-In/lib/VbeUserControlHost/AccessCodeLib.Common.VbeUserControlHost.dll b/vbe-add-In/lib/VbeUserControlHost/AccessCodeLib.Common.VbeUserControlHost.dll new file mode 100644 index 0000000..50a8b80 Binary files /dev/null and b/vbe-add-In/lib/VbeUserControlHost/AccessCodeLib.Common.VbeUserControlHost.dll differ