diff --git a/.devcontainer.json b/.devcontainer.json
deleted file mode 100644
index 2ca757d7..00000000
--- a/.devcontainer.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- // Install ESLint and Peacock extensions
- "extensions": [
- "ms-vscode.csharp"
- ]
-}
\ No newline at end of file
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 00000000..b8062b19
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,9 @@
+# Please see the documentation for all configuration options:
+# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
+
+version: 2
+updates:
+- package-ecosystem: nuget
+ directory: /src/
+ schedule:
+ interval: weekly
\ No newline at end of file
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 00000000..73230659
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,96 @@
+name: build
+on:
+ push:
+ branches: [ '*' ]
+ pull_request:
+ types: [opened, synchronize, reopened]
+
+env:
+ DOTNET_NOLOGO: true
+ CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
+
+defaults:
+ run:
+ shell: bash
+
+jobs:
+ build:
+ name: ${{ matrix.os }}
+ runs-on: ${{ matrix.os }}
+ strategy:
+ matrix:
+ os: [ubuntu-latest, windows-latest, macOS-latest]
+ steps:
+ - name: 🤘 checkout
+ uses: actions/checkout@v2
+ - name: ⚙ dotnet 5.0 rc2
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 5.0.100-rc.2.20479.15
+ - name: 🙏 build
+ run: dotnet msbuild -r -m:1 -bl:build.binlog -p:versionsuffix="$GITHUB_REF.$GITHUB_RUN_NUMBER"
+ - name: 🧪 test win
+ run: dotnet test --no-build --collect:"XPlat Code Coverage"
+ if: matrix.os == 'windows-latest'
+ - name: 🧪 test !win
+ run: dotnet test --no-build -f net5.0 --collect:"XPlat Code Coverage"
+ if: matrix.os != 'windows-latest'
+ - name: 🔍 coverage
+ if: 'false'
+ run: bash <(curl -s https://codecov.io/bash)
+ - name: 🔼 logs
+ if: ${{ always() }}
+ uses: actions/upload-artifact@v2
+ with:
+ name: ${{ matrix.os }}
+ path: |
+ *.binlog
+ **/coverage.cobertura.xml
+ - name: 🔼 packages
+ uses: actions/upload-artifact@v2
+ with:
+ name: bin
+ path: bin/*.nupkg
+
+ acceptance:
+ name: acceptance-${{ matrix.os }}
+ runs-on: ${{ matrix.os }}
+ needs: build
+ strategy:
+ matrix:
+ os: [ubuntu-latest, windows-latest, macOS-latest]
+ steps:
+ - name: 🤘 checkout
+ uses: actions/checkout@v2
+ - name: 🔽 packages
+ uses: actions/download-artifact@v2
+ with:
+ name: bin
+ path: bin
+ - name: ⚙ dotnet 5.0 rc2
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 5.0.100-rc.2.20479.15
+ - name: 🧪 test
+ run: dotnet test -m:1 -p:versionsuffix="$GITHUB_REF.$GITHUB_RUN_NUMBER"
+ working-directory: src/Acceptance
+
+ push:
+ name: push nuget.ci
+ runs-on: ubuntu-latest
+ needs: [build, acceptance]
+ steps:
+ - name: 🔽 packages
+ uses: actions/download-artifact@v2
+ with:
+ name: bin
+ path: bin
+ - name: ⚙ dotnet 2.1.x
+ uses: actions/setup-dotnet@v1
+ if: matrix.os == 'ubuntu-latest'
+ with:
+ dotnet-version: 2.1.x
+ - name: 🚀 sleet
+ run: |
+ dotnet tool install -g --version 3.2.0 sleet
+ sleet push bin --config none -f --verbose -p "SLEET_FEED_CONTAINER=nuget" -p "SLEET_FEED_CONNECTIONSTRING=${{ secrets.SLEET_CONNECTION }}" -p "SLEET_FEED_TYPE=azure"
\ No newline at end of file
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 00000000..48f78e19
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,31 @@
+name: release
+on:
+ release:
+ types: [created]
+
+env:
+ DOTNET_NOLOGO: true
+ Configuration: Release
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - name: 🤘 checkout
+ uses: actions/checkout@v2
+ - name: ⚙ dotnet 5.0 rc2
+ uses: actions/setup-dotnet@v1
+ with:
+ dotnet-version: 5.0.100-rc.2.20479.15
+ - name: 🙏 build
+ run: dotnet msbuild -r -m:1 -bl:build.binlog -p:version=${GITHUB_REF#refs/*/v}
+ - name: 🧪 test net5.0
+ run: dotnet test --no-build -f net5.0
+ - name: 🔼 logs
+ if: ${{ always() }}
+ uses: actions/upload-artifact@v2
+ with:
+ name: ${{ matrix.os }}
+ path: '*.binlog'
+ - name: 🚀 nuget
+ run: dotnet nuget push ./bin/**/*.nupkg -s https://api.nuget.org/v3/index.json -k ${{secrets.NUGET_API_KEY}} --skip-duplicate
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 74671e66..06c3a592 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,6 +14,4 @@ obj
*.log
*.binlog
*.rsp
-/src/Usage
-/src/Backup
-/src/TestResults
+TestResults
diff --git a/Moq.sln b/Moq.sln
new file mode 100644
index 00000000..a5b1359f
--- /dev/null
+++ b/Moq.sln
@@ -0,0 +1,100 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.28417.167
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Moq", "src\Moq\Moq.csproj", "{65F3AB28-9A74-405E-83B2-420D5AD5A459}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2093478C-CEA6-4034-BCDE-EDC7A5DD4532}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ src\Directory.Build.props = src\Directory.Build.props
+ Directory.Build.rsp = Directory.Build.rsp
+ src\Directory.Build.targets = src\Directory.Build.targets
+ src\Directory.Packages.props = src\Directory.Packages.props
+ README.md = README.md
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Moq.Sdk", "src\Moq.Sdk\Moq.Sdk.csproj", "{80DE507E-3AF9-4360-9E56-66523B01FB51}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Moq.Sdk.Tests", "src\Moq.Sdk.Tests\Moq.Sdk.Tests.csproj", "{EB66BC5E-4072-4F26-9772-979D8561883F}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Moq.Tests", "src\Moq.Tests\Moq.Tests.csproj", "{9A09225F-E0BC-4890-BED4-D9F6F5DAC146}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Moq.DynamicProxy", "src\Moq.DynamicProxy\Moq.DynamicProxy.csproj", "{BA43EF2F-6CA8-49A5-A4E7-C2FF71928F05}"
+EndProject
+Project("{13B669BE-BB05-4DDF-9536-439F39A36129}") = "Moq.Package", "src\Moq.Package\Moq.Package.msbuildproj", "{D486033C-1CCF-47BB-BDA6-28EA08018CDE}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Moq.StaticProxy", "src\Moq.StaticProxy\Moq.StaticProxy.csproj", "{0580AEDE-7661-4311-9A40-EAD4CD485742}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Moq.CodeAnalysis", "src\Moq.CodeAnalysis\Moq.CodeAnalysis.csproj", "{1D05F2B9-B67D-4EFE-B4FF-D7F6907C2701}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Moq.StaticProxy.UnitTests", "src\Moq.StaticProxy.UnitTests\Moq.StaticProxy.UnitTests.csproj", "{36A3DD24-4B67-4A9E-83F8-C4794336460F}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{73262D37-1503-4F10-B7B2-E945523828E4}"
+ ProjectSection(SolutionItems) = preProject
+ azure-pipelines.yml = azure-pipelines.yml
+ .github\workflows\build.yml = .github\workflows\build.yml
+ .github\dependabot.yml = .github\dependabot.yml
+ .github\workflows\release.yml = .github\workflows\release.yml
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Moq.CodeAnalysis.UnitTests", "src\Moq.CodeAnalysis.UnitTests\Moq.CodeAnalysis.UnitTests.csproj", "{7EFC63B5-6978-40C9-8FEF-4FEEB4019B4C}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {65F3AB28-9A74-405E-83B2-420D5AD5A459}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {65F3AB28-9A74-405E-83B2-420D5AD5A459}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {65F3AB28-9A74-405E-83B2-420D5AD5A459}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {65F3AB28-9A74-405E-83B2-420D5AD5A459}.Release|Any CPU.Build.0 = Release|Any CPU
+ {80DE507E-3AF9-4360-9E56-66523B01FB51}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {80DE507E-3AF9-4360-9E56-66523B01FB51}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {80DE507E-3AF9-4360-9E56-66523B01FB51}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {80DE507E-3AF9-4360-9E56-66523B01FB51}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EB66BC5E-4072-4F26-9772-979D8561883F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EB66BC5E-4072-4F26-9772-979D8561883F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EB66BC5E-4072-4F26-9772-979D8561883F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EB66BC5E-4072-4F26-9772-979D8561883F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9A09225F-E0BC-4890-BED4-D9F6F5DAC146}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9A09225F-E0BC-4890-BED4-D9F6F5DAC146}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9A09225F-E0BC-4890-BED4-D9F6F5DAC146}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9A09225F-E0BC-4890-BED4-D9F6F5DAC146}.Release|Any CPU.Build.0 = Release|Any CPU
+ {BA43EF2F-6CA8-49A5-A4E7-C2FF71928F05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {BA43EF2F-6CA8-49A5-A4E7-C2FF71928F05}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {BA43EF2F-6CA8-49A5-A4E7-C2FF71928F05}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {BA43EF2F-6CA8-49A5-A4E7-C2FF71928F05}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D486033C-1CCF-47BB-BDA6-28EA08018CDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D486033C-1CCF-47BB-BDA6-28EA08018CDE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D486033C-1CCF-47BB-BDA6-28EA08018CDE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D486033C-1CCF-47BB-BDA6-28EA08018CDE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0580AEDE-7661-4311-9A40-EAD4CD485742}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {0580AEDE-7661-4311-9A40-EAD4CD485742}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {0580AEDE-7661-4311-9A40-EAD4CD485742}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {0580AEDE-7661-4311-9A40-EAD4CD485742}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1D05F2B9-B67D-4EFE-B4FF-D7F6907C2701}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {1D05F2B9-B67D-4EFE-B4FF-D7F6907C2701}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {1D05F2B9-B67D-4EFE-B4FF-D7F6907C2701}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {1D05F2B9-B67D-4EFE-B4FF-D7F6907C2701}.Release|Any CPU.Build.0 = Release|Any CPU
+ {36A3DD24-4B67-4A9E-83F8-C4794336460F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {36A3DD24-4B67-4A9E-83F8-C4794336460F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {36A3DD24-4B67-4A9E-83F8-C4794336460F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {36A3DD24-4B67-4A9E-83F8-C4794336460F}.Release|Any CPU.Build.0 = Release|Any CPU
+ {7EFC63B5-6978-40C9-8FEF-4FEEB4019B4C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {7EFC63B5-6978-40C9-8FEF-4FEEB4019B4C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {7EFC63B5-6978-40C9-8FEF-4FEEB4019B4C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {7EFC63B5-6978-40C9-8FEF-4FEEB4019B4C}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {73262D37-1503-4F10-B7B2-E945523828E4} = {2093478C-CEA6-4034-BCDE-EDC7A5DD4532}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {DA4CFD03-827D-482B-9304-83456D2A8115}
+ EndGlobalSection
+EndGlobal
diff --git a/NuGet.Config b/NuGet.Config
deleted file mode 100644
index 1436d285..00000000
--- a/NuGet.Config
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/README.md b/README.md
index 03162b19..c336a856 100644
--- a/README.md
+++ b/README.md
@@ -2,57 +2,55 @@
The most popular and friendly mocking framework for .NET
-[](http://www.corebuild.io)
-[](https://dev.azure.com/kzu/oss/_build/latest?definitionId=20&branchName=master)
-[](https://dev.azure.com/kzu/oss/_build/latest?definitionId=20&branchName=master&view=results)
+[](https://pkg.kzu.io/index.json)
+[](https://github.com/moq/moq/actions?query=branch%3Amain+workflow%3Abuild+)
[](https://github.com/moq/moq/blob/master/LICENSE)
-[](https://gitter.im/moq/moq?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
-[](http://twitter.com/intent/user?screen_name=moqthis)
+[](https://discord.gg/AfGsdRa)
+[](https://github.com/moq/moq)
-This repository supports [corebuild](http://www.corebuild.io) for configure/build/test from `msbuild`.
> **IMPORTANT**: this repository is for the *upcoming* version of Moq. Issues and source for the current stable Moq v4.x are at https://github.com/moq/moq4
-CI package feed: http://kzu.nuget.cloud/index.json (CDN) or https://kzu.blob.core.windows.net/nuget/index.json (blob).
+CI package feed: https://pkg.kzu.io/index.json
## Building the repository
```
-msbuild /t:configure
-msbuild
+dotnet msbuild
```
-The default target is `Help`, which will render the documentation for the build itself and what targets are available.
-Since this is a [corebuild](http://www.corebuild.io) standard repository, you can run:
+Running tests:
```
-msbuild /t:configure
-msbuild /t:build
-msbuild /t:test
+dotnet test
```
## Testing built packages locally
-Release builds will produce packages. In Debug builds, you will need to right-click and `Pack` the relevant project,
-such as `Moq.Package` (which will also pack its dependencies like `Stunts.Package`). These packages will be dropped
-in the `out` folder in the repository root directory. To test these packages you can just add a package source
+You can either build from command line or explicitly Pack (from the context menu) the *Moq.Package* project.
+
+Packages are generated in the `bin` folder in the repository root. To test these packages you can just add a package source
pointing to it. You can also just place a `NuGet.Config` like the following anywhere above the directory with the
test solution(s):
```xml
-
+
```
-Every time the packages are produced, the local nuget cache is cleared, so that a subsequent restore in VS will
-automatically cause the updated version to be unpacked again. If versions change between package builds, you can
-just reference them with a wildcard so the latest will automatically be chosen, such as:
+You can also do use project properties (or a *Directory.Build.props* to affect an entire folder hierarchy) with:
```xml
-
-
-
+
+
+ https://api.nuget.org/v3/index.json;$(RestoreSources)
+ [cloned repo dir]\bin;$(RestoreSources)
+
+
```
+
+Every time the packages are produced, the local nuget cache is cleared, so that a subsequent restore in VS will
+automatically cause the updated version to be unpacked again. The locally built version will always have the version [42.42.42](https://en.wikipedia.org/wiki/42_(number)#The_Hitchhiker's_Guide_to_the_Galaxy).
\ No newline at end of file
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
deleted file mode 100644
index b5ace6f6..00000000
--- a/azure-pipelines.yml
+++ /dev/null
@@ -1,129 +0,0 @@
-trigger:
- batch: false
- branches:
- include:
- - master
- - features/*
- - releases/*
- - dev/*
- paths:
- exclude:
- - docs
-pr:
- - master
- - features/*
- - releases/*
-
-variables:
-- group: Sleet
-- name: Configuration
- value: Release
-
-stages:
-
-- stage: Build
- jobs:
- - job: Build
- pool:
- vmImage: 'windows-2019'
- steps:
- - checkout: self
- clean: true
-
- - task: MSBuild@1
- displayName: Restore Script
- inputs:
- solution: build.proj
- configuration: $(Configuration)
- msbuildArguments: -t:restore
-
- - task: MSBuild@1
- displayName: Restore Solution
- inputs:
- solution: src/Moq.sln
- configuration: $(Configuration)
- msbuildArguments: -t:restore -bl:$(Build.ArtifactStagingDirectory)/logs/restore.binlog
-
- - task: MSBuild@1
- displayName: Set Version
- inputs:
- solution: src/Moq/Moq.Package/Moq.Package.msbuildproj
- msbuildArguments: -t:Version -bl:$(Build.ArtifactStagingDirectory)/logs/setversion.binlog
-
- - task: MSBuild@1
- displayName: Build
- inputs:
- solution: src/Moq.sln
- configuration: $(Configuration)
- msbuildArguments: -p:PackOnBuild=true -p:PackageOutputPath=$(Build.ArtifactStagingDirectory)/pkg -bl:$(Build.ArtifactStagingDirectory)/logs/build.binlog
-
- - task: VSTest@2
- displayName: Test
- inputs:
- testAssemblyVer2: src/*/*/bin/*/*.Tests.dll
- runInParallel: true
- codeCoverageEnabled: true
- publishRunAttachments: true
- diagnosticsEnabled: false
- rerunFailedTests: true
-
- - task: PublishBuildArtifacts@1
- displayName: Upload Packages
- condition: always()
- inputs:
- PathtoPublish: $(Build.ArtifactStagingDirectory)/pkg
- ArtifactName: packages
- ArtifactType: Container
-
- - task: PublishBuildArtifacts@1
- displayName: Upload Logs
- condition: always()
- inputs:
- PathtoPublish: $(Build.ArtifactStagingDirectory)/logs
- ArtifactName: logs
- ArtifactType: Container
-
-- stage: Deploy
- variables:
- - name: SleetVersion
- value: 2.3.33
- jobs:
- - deployment: Deploy
- pool:
- vmImage: 'windows-2019'
- environment: sleet
- strategy:
- runOnce:
- deploy:
- steps:
- - pwsh: |
- $anyinstalled = (dotnet tool list -g | select-string sleet) -ne $null
- Write-Host "##vso[task.setvariable variable=Sleet.AnyInstalled;]$anyinstalled"
-
- $sameinstalled = (dotnet tool list -g | select-string sleet | select-string $(SleetVersion)) -ne $null
- Write-Host "##vso[task.setvariable variable=Sleet.SameInstalled;]$sameinstalled"
- displayName: 'Check Sleet installed version'
-
- - task: DotNetCoreCLI@2
- displayName: 'Uninstall Sleet if necessary'
- continueOnError: true
- condition: and(eq(variables['Sleet.AnyInstalled'], 'True'), eq(variables['Sleet.SameInstalled'], 'False'))
- inputs:
- command: custom
- custom: tool
- arguments: 'uninstall -g Sleet'
-
- - task: DotNetCoreCLI@2
- displayName: 'Install Sleet if necessary'
- condition: eq(variables['Sleet.SameInstalled'], 'False')
- inputs:
- command: custom
- custom: tool
- arguments: 'install --global Sleet --version $(SleetVersion)'
-
- - task: DownloadPipelineArtifact@2
- inputs:
- artifactName: packages
-
- - script: 'sleet push --config none $(Pipeline.Workspace)/packages -f --verbose -p "SLEET_FEED_CONNECTIONSTRING=$(SLEET_FEED_CONNECTIONSTRING)"'
- displayName: 'Push packages via Sleet'
\ No newline at end of file
diff --git a/build.proj b/build.proj
deleted file mode 100644
index bd9c6a76..00000000
--- a/build.proj
+++ /dev/null
@@ -1,89 +0,0 @@
-
-
-
-
-
- Debug
- net472
-
-
-
- $(RestoreOutputPath)\
- Configuration=$(Configuration)
- $(MSBuildProjectDirectory)\out
- src\GitInfo.txt
- $(MSBuildProjectDirectory)\src\Packages.props
-
-
-
-
-
-
-
-
-
- $(AdditionalProperties)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/Acceptance/Acceptance.sln b/src/Acceptance/Acceptance.sln
new file mode 100644
index 00000000..94bb1eb5
--- /dev/null
+++ b/src/Acceptance/Acceptance.sln
@@ -0,0 +1,43 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30615.102
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B62AC629-EB97-4ACA-9130-A318C5B0EE41}"
+ ProjectSection(SolutionItems) = preProject
+ Directory.Build.props = Directory.Build.props
+ Directory.Build.targets = Directory.Build.targets
+ EndProjectSection
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Static", "Static\Static.csproj", "{11D3F1D8-C5DA-4FF6-9F28-F170BC69748B}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dynamic", "Dynamic\Dynamic.csproj", "{ACF75738-6433-4FE3-9E7E-6506D34BEF03}"
+EndProject
+Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "Dynamic.Basic", "Dynamic.Basic\Dynamic.Basic.vbproj", "{8CB8DB45-925F-4A9F-94A4-70F416E719B6}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {11D3F1D8-C5DA-4FF6-9F28-F170BC69748B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {11D3F1D8-C5DA-4FF6-9F28-F170BC69748B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {11D3F1D8-C5DA-4FF6-9F28-F170BC69748B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {11D3F1D8-C5DA-4FF6-9F28-F170BC69748B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {ACF75738-6433-4FE3-9E7E-6506D34BEF03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {ACF75738-6433-4FE3-9E7E-6506D34BEF03}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {ACF75738-6433-4FE3-9E7E-6506D34BEF03}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {ACF75738-6433-4FE3-9E7E-6506D34BEF03}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8CB8DB45-925F-4A9F-94A4-70F416E719B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8CB8DB45-925F-4A9F-94A4-70F416E719B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8CB8DB45-925F-4A9F-94A4-70F416E719B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8CB8DB45-925F-4A9F-94A4-70F416E719B6}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {4D227C00-ECBA-4191-99F8-5622198D7352}
+ EndGlobalSection
+EndGlobal
diff --git a/src/Acceptance/Directory.Build.props b/src/Acceptance/Directory.Build.props
new file mode 100644
index 00000000..fe957239
--- /dev/null
+++ b/src/Acceptance/Directory.Build.props
@@ -0,0 +1,21 @@
+
+
+ false
+
+
+
+
+ $(MSBuildThisFileDirectory)../../bin;
+ https://pkg.kzu.io/index.json;
+ https://api.nuget.org/v3/index.json
+
+
+ $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)../../../nugetizer/bin'));
+ $(RestoreSources)
+
+
+ $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)../../../stunts/bin'));
+ $(RestoreSources)
+
+
+
\ No newline at end of file
diff --git a/src/Acceptance/Directory.Build.targets b/src/Acceptance/Directory.Build.targets
new file mode 100644
index 00000000..1342991b
--- /dev/null
+++ b/src/Acceptance/Directory.Build.targets
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Acceptance/Dynamic.Basic/Dynamic.Basic.vbproj b/src/Acceptance/Dynamic.Basic/Dynamic.Basic.vbproj
new file mode 100644
index 00000000..b10fd2b4
--- /dev/null
+++ b/src/Acceptance/Dynamic.Basic/Dynamic.Basic.vbproj
@@ -0,0 +1,16 @@
+
+
+
+ net472;net5.0
+ Latest
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Samples/Moq.VisualBasic/IParser.vb b/src/Acceptance/Dynamic.Basic/IParser.vb
similarity index 63%
rename from src/Samples/Moq.VisualBasic/IParser.vb
rename to src/Acceptance/Dynamic.Basic/IParser.vb
index 02e0a6a5..1bc28d4c 100644
--- a/src/Samples/Moq.VisualBasic/IParser.vb
+++ b/src/Acceptance/Dynamic.Basic/IParser.vb
@@ -5,5 +5,5 @@ Public Interface IEnvironment
End Interface
Public Interface IParser
- Function TryParse(ByVal input As String, ByRef result As DateTimeOffset) As Boolean
+ Function TryParse(input As String, ByRef result As DateTimeOffset) As Boolean
End Interface
\ No newline at end of file
diff --git a/src/Acceptance/Dynamic.Basic/Model.vb b/src/Acceptance/Dynamic.Basic/Model.vb
new file mode 100644
index 00000000..0eaddc20
--- /dev/null
+++ b/src/Acceptance/Dynamic.Basic/Model.vb
@@ -0,0 +1,33 @@
+Option Strict On
+Imports System.Runtime.InteropServices
+
+Namespace Model
+
+ Public Interface ICalculator
+ Event TurnedOn As EventHandler
+ ReadOnly Property IsOn As Boolean
+ Property Mode As CalculatorMode
+ Function Add(x As Integer, y As Integer) As Integer
+ Function Add(x As Integer, y As Integer, z As Integer) As Integer
+ Function TryAdd(ByRef x As Integer, ByRef y As Integer, ByRef z As Integer) As Boolean
+ Sub TurnOn()
+ Default Property Item(name As String) As Integer?
+ Sub Store(name As String, value As Integer)
+ Function Recall(name As String) As Integer?
+ Sub Clear(name As String)
+ ReadOnly Property Memory As ICalculatorMemory
+ End Interface
+
+ Public Enum CalculatorMode
+ Standard
+ Scientific
+ End Enum
+
+ Public Interface ICalculatorMemory
+ Sub Add(value As Integer)
+ Sub Subtract(value As Integer)
+ Sub Clear()
+ Function Recall() As Integer
+ End Interface
+
+End Namespace
diff --git a/src/Acceptance/Dynamic.Basic/Tests.vb b/src/Acceptance/Dynamic.Basic/Tests.vb
new file mode 100644
index 00000000..bc016bbd
--- /dev/null
+++ b/src/Acceptance/Dynamic.Basic/Tests.vb
@@ -0,0 +1,44 @@
+Option Strict On
+Option Infer On
+Imports Moq
+Imports Xunit
+Imports System.Runtime.InteropServices
+Imports Dynamic.Basic.Model
+
+Public Class Tests
+
+ Public Sub StubProperties()
+ Dim calc = Mock.[Of](Of ICalculator)()
+ calc.Mode = CalculatorMode.Scientific
+ Assert.Equal(CalculatorMode.Scientific, calc.Mode)
+ calc.Mode = CalculatorMode.Standard
+ Assert.Equal(CalculatorMode.Standard, calc.Mode)
+ End Sub
+
+
+ Public Sub Recusive()
+ Dim calc = Mock.[Of](Of ICalculator)()
+ calc.Memory.Recall().Returns(5)
+ Assert.Equal(5, calc.Memory.Recall())
+ End Sub
+
+
+ Public Sub RecusiveSetupScope()
+ Dim calc = Mock.[Of](Of ICalculator)()
+
+ Using calc.Setup()
+ calc.Memory.Recall().Returns(5)
+ End Using
+
+ Assert.Equal(5, calc.Memory.Recall())
+ End Sub
+
+
+ Public Sub RecusiveSetup()
+ Dim calc = Mock.[Of](Of ICalculator, IDisposable)()
+ calc.Setup(Function(m) m.Memory.Recall()).Returns(5)
+ Assert.Equal(5, calc.Memory.Recall())
+ Assert.IsAssignableFrom(Of IDisposable)(calc)
+ End Sub
+
+End Class
diff --git a/src/Acceptance/Dynamic/Dynamic.csproj b/src/Acceptance/Dynamic/Dynamic.csproj
new file mode 100644
index 00000000..133e0be3
--- /dev/null
+++ b/src/Acceptance/Dynamic/Dynamic.csproj
@@ -0,0 +1,22 @@
+
+
+
+ net472;net5.0
+
+ 8.0
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Acceptance/Static/Static.csproj b/src/Acceptance/Static/Static.csproj
new file mode 100644
index 00000000..10c1922d
--- /dev/null
+++ b/src/Acceptance/Static/Static.csproj
@@ -0,0 +1,16 @@
+
+
+
+ net472;net5.0
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Acceptance/Static/Tests.cs b/src/Acceptance/Static/Tests.cs
new file mode 100644
index 00000000..a2ed6941
--- /dev/null
+++ b/src/Acceptance/Static/Tests.cs
@@ -0,0 +1,107 @@
+using System;
+using Moq;
+using Sample;
+using Xunit;
+
+public class Tests
+{
+ [Fact]
+ public void StubProperties()
+ {
+ var calc = Mock.Of();
+
+ calc.Mode = CalculatorMode.Scientific;
+
+ Assert.Equal(CalculatorMode.Scientific, calc.Mode);
+
+ calc.Mode = CalculatorMode.Standard;
+
+ Assert.Equal(CalculatorMode.Standard, calc.Mode);
+ }
+
+ [Fact(Skip = "Fluent recursive without setups not supported yet.")]
+ public void Recusive()
+ {
+ var calc = Mock.Of();
+
+ calc.Memory.Recall().Returns(5);
+
+ Assert.Equal(5, calc.Memory.Recall());
+ }
+
+ [Fact]
+ public void RecusiveSetupScope()
+ {
+ var calc = Mock.Of();
+
+ using (calc.Setup())
+ {
+ calc.Memory.Recall().Returns(5);
+ }
+
+ Assert.Equal(5, calc.Memory.Recall());
+ }
+
+ [Fact]
+ public void RecusiveSetupBase()
+ {
+ var calc = Mock.Of();
+ calc.Setup(m => m.Memory.Recall()).Returns(5);
+
+ Assert.Equal(5, calc.Memory.Recall());
+ Assert.IsAssignableFrom(calc);
+ }
+
+ [Fact]
+ public void RecusiveSetup()
+ {
+ var calc = Mock.Of();
+ calc.Setup(m => m.Memory.Recall()).Returns(5);
+
+ Assert.Equal(5, calc.Memory.Recall());
+ Assert.IsAssignableFrom(calc);
+ }
+
+ [Fact]
+ public void DelegateOut()
+ {
+ var mock = Mock.Of();
+
+ mock.Setup(mock.TryParse)
+ .Returns((string input, out DateTimeOffset date) => DateTimeOffset.TryParse(input, out date));
+
+ var expected = DateTimeOffset.Now;
+ var value = expected.ToString("O");
+
+ Assert.True(mock.TryParse(value, out var actual));
+ Assert.Equal(expected, actual);
+ }
+
+ [Fact]
+ public void RecursiveDelegateOut()
+ {
+ var mock = Mock.Of();
+
+ var expected = DateTimeOffset.Now;
+ var value = expected.ToString("O");
+
+ mock.Setup(() => mock.Parser.TryParse)
+ .Returns((string input, out DateTimeOffset date) => DateTimeOffset.TryParse(value, out date));
+
+ Assert.True(mock.Parser.TryParse(value, out var actual));
+ Assert.Equal(expected, actual);
+ }
+
+ delegate bool TryParse(string input, out DateTimeOffset date);
+
+}
+
+public interface IEnvironment
+{
+ IParser Parser { get; }
+}
+
+public interface IParser
+{
+ bool TryParse(string input, out DateTimeOffset date);
+}
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index d62e7c5d..0e08f270 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -1,3 +1,83 @@
-
-
+
+
+
+ kzu
+ Copyright (C) Daniel Cazzulino $([System.DateTime]::Now.Year). All rights reserved.
+ false
+ MIT
+
+
+ 42.42.42
+ $(VersionSuffix.Replace('refs/heads/', ''))
+ $(VersionSuffix.TrimEnd('.0123456789'))
+ $(VersionSuffix.Replace('refs/pull/', 'pr'))
+ $(VersionSuffix.Replace('/merge', ''))
+ $(VersionSuffix.Replace('/', '-'))
+
+ true
+ true
+
+ $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\bin'))
+
+ false
+ embedded
+ true
+ enable
+
+ $(DefaultItemExcludes);*.binlog;*.zip;*.rsp;*.items
+
+
+ true
+
+ https://pkg.kzu.io/index.json;https://api.nuget.org/v3/index.json;$(RestoreSources)
+ $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\nugetizer\bin'));$(RestoreSources)
+ $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\..\stunts\bin'));$(RestoreSources)
+
+ $(MSBuildThisFileDirectory)Moq.snk
+ 002400000480000094000000060200000024000052534131000400000100010051155fd0ee280be78d81cc979423f1129ec5dd28edce9cd94fd679890639cad54c121ebdb606f8659659cd313d3b3db7fa41e2271158dd602bb0039a142717117fa1f63d93a2d288a1c2f920ec05c4858d344a45d48ebd31c1368ab783596b382b611d8c92f9c1b3d338296aa21b12f3bc9f34de87756100c172c52a24bad2db
+ 00352124762f2aa5
+ true
+
+
+ true
+ true
+ true
+ true
+
+
+ true
+
+
+
+ Preview
+ true
+
+
+
+ false
+ true
+
+
+
+ $(CI)
+ $(CI)
+
+
+
+
+
+
+
+
+
+
+
+
+
+ GetTargetPath
+
+
+
\ No newline at end of file
diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets
index 8de2d61a..07afca9f 100644
--- a/src/Directory.Build.targets
+++ b/src/Directory.Build.targets
@@ -1,3 +1,75 @@
-
-
+
+
+
+
+ 1.0.0
+ $(VersionPrefix)-$(VersionSuffix)
+ $(VersionPrefix)
+
+
+
+ $(DefineConstants);$(TargetFramework.ToUpperInvariant().TrimEnd('0').TrimEnd('.'))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(SourceRevisionId.Substring(0, 9))
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(Description)
+
+ Built from $(RepositoryUrl)/tree/$(SourceRevisionId.Substring(0, 9))
+
+
+
+
+ $(Description)
+
+
+
+
+
+
+ $(NuGetCache)\$(PackageId.ToLowerInvariant())\$(VersionPrefix)
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
new file mode 100644
index 00000000..565bf0d8
--- /dev/null
+++ b/src/Directory.Packages.props
@@ -0,0 +1,70 @@
+
+
+
+ 42.42.42-main.170
+ 42.42.42
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/GitInfo.txt b/src/GitInfo.txt
deleted file mode 100644
index 3f2e310e..00000000
--- a/src/GitInfo.txt
+++ /dev/null
@@ -1 +0,0 @@
-5.0.0-alpha
\ No newline at end of file
diff --git a/src/Moq.CodeAnalysis.UnitTests/Moq.CodeAnalysis.UnitTests.csproj b/src/Moq.CodeAnalysis.UnitTests/Moq.CodeAnalysis.UnitTests.csproj
new file mode 100644
index 00000000..8187ef27
--- /dev/null
+++ b/src/Moq.CodeAnalysis.UnitTests/Moq.CodeAnalysis.UnitTests.csproj
@@ -0,0 +1,19 @@
+
+
+
+ net472;net5.0
+ annotations
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Moq/Moq.CodeAnalysis/MockNamingConvention.cs b/src/Moq.CodeAnalysis/MockNamingConvention.cs
similarity index 96%
rename from src/Moq/Moq.CodeAnalysis/MockNamingConvention.cs
rename to src/Moq.CodeAnalysis/MockNamingConvention.cs
index d248dddf..686e5b0f 100644
--- a/src/Moq/Moq.CodeAnalysis/MockNamingConvention.cs
+++ b/src/Moq.CodeAnalysis/MockNamingConvention.cs
@@ -1,5 +1,5 @@
using Moq.Sdk;
-using Stunts;
+using Stunts.CodeAnalysis;
namespace Moq
{
diff --git a/src/Moq/Moq.CodeAnalysis/MockUnsupportedNestedTypeAnalyzer.cs b/src/Moq.CodeAnalysis/MockNestedTypeAnalyzer.cs
similarity index 76%
rename from src/Moq/Moq.CodeAnalysis/MockUnsupportedNestedTypeAnalyzer.cs
rename to src/Moq.CodeAnalysis/MockNestedTypeAnalyzer.cs
index 7dea629f..1a460949 100644
--- a/src/Moq/Moq.CodeAnalysis/MockUnsupportedNestedTypeAnalyzer.cs
+++ b/src/Moq.CodeAnalysis/MockNestedTypeAnalyzer.cs
@@ -11,12 +11,12 @@ namespace Stunts
///
// TODO: F#
[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
- public class MockUnsupportedNestedTypeAnalyzer : UnsupportedNestedTypeAnalyzer
+ public class MockUnsupportedNestedTypeAnalyzer : NestedTypeAnalyzer
{
///
/// Instantiates the analyzer with the default and
/// for method invocations annotated with .
///
- public MockUnsupportedNestedTypeAnalyzer() : base(new MockNamingConvention(), typeof(MockGeneratorAttribute)) { }
+ public MockUnsupportedNestedTypeAnalyzer() : base(typeof(MockGeneratorAttribute)) { }
}
}
diff --git a/src/Moq/Moq.CodeAnalysis/MockValidateTypesAnalyzer.cs b/src/Moq.CodeAnalysis/MockValidateTypesAnalyzer.cs
similarity index 100%
rename from src/Moq/Moq.CodeAnalysis/MockValidateTypesAnalyzer.cs
rename to src/Moq.CodeAnalysis/MockValidateTypesAnalyzer.cs
diff --git a/src/Moq.CodeAnalysis/Moq.CodeAnalysis.csproj b/src/Moq.CodeAnalysis/Moq.CodeAnalysis.csproj
new file mode 100644
index 00000000..0468d0f8
--- /dev/null
+++ b/src/Moq.CodeAnalysis/Moq.CodeAnalysis.csproj
@@ -0,0 +1,50 @@
+
+
+
+
+ netstandard2.0
+ analyzers\dotnet
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+
+
+ Resources.Designer.cs
+
+
+
+
\ No newline at end of file
diff --git a/src/Moq/Moq.CodeAnalysis/RecursiveMockAnalyzer.cs b/src/Moq.CodeAnalysis/RecursiveMockAnalyzer.cs
similarity index 100%
rename from src/Moq/Moq.CodeAnalysis/RecursiveMockAnalyzer.cs
rename to src/Moq.CodeAnalysis/RecursiveMockAnalyzer.cs
diff --git a/src/Moq/Moq.CodeAnalysis/Properties/Resources.Designer.cs b/src/Moq.CodeAnalysis/Resources.Designer.cs
similarity index 96%
rename from src/Moq/Moq.CodeAnalysis/Properties/Resources.Designer.cs
rename to src/Moq.CodeAnalysis/Resources.Designer.cs
index 5c06bfaa..c15d69e6 100644
--- a/src/Moq/Moq.CodeAnalysis/Properties/Resources.Designer.cs
+++ b/src/Moq.CodeAnalysis/Resources.Designer.cs
@@ -8,7 +8,7 @@
//
//------------------------------------------------------------------------------
-namespace Moq.Properties {
+namespace Moq.CodeAnalysis {
using System;
@@ -19,7 +19,7 @@ namespace Moq.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
- [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
@@ -39,7 +39,7 @@ internal Resources() {
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
- global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Moq.Properties.Resources", typeof(Resources).Assembly);
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Moq.CodeAnalysis.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
diff --git a/src/Moq/Moq.CodeAnalysis/Properties/Resources.resx b/src/Moq.CodeAnalysis/Resources.resx
similarity index 100%
rename from src/Moq/Moq.CodeAnalysis/Properties/Resources.resx
rename to src/Moq.CodeAnalysis/Resources.resx
diff --git a/src/Moq/Moq.CodeFix/AssemblyInfo.cs b/src/Moq.CodeFix/AssemblyInfo.cs
similarity index 100%
rename from src/Moq/Moq.CodeFix/AssemblyInfo.cs
rename to src/Moq.CodeFix/AssemblyInfo.cs
diff --git a/src/Moq/Moq.CodeFix/CustomDelegateCodeFix.cs b/src/Moq.CodeFix/CustomDelegateCodeFix.cs
similarity index 100%
rename from src/Moq/Moq.CodeFix/CustomDelegateCodeFix.cs
rename to src/Moq.CodeFix/CustomDelegateCodeFix.cs
diff --git a/src/Moq/Moq.CodeFix/CustomMockCodeFixProvider.cs b/src/Moq.CodeFix/CustomMockCodeFixProvider.cs
similarity index 100%
rename from src/Moq/Moq.CodeFix/CustomMockCodeFixProvider.cs
rename to src/Moq.CodeFix/CustomMockCodeFixProvider.cs
diff --git a/src/Moq/Moq.CodeAnalysis/GlobalSuppressions.cs b/src/Moq.CodeFix/GlobalSuppressions.cs
similarity index 100%
rename from src/Moq/Moq.CodeAnalysis/GlobalSuppressions.cs
rename to src/Moq.CodeFix/GlobalSuppressions.cs
diff --git a/src/Moq/Moq.CodeFix/MockCodeFixProvider.cs b/src/Moq.CodeFix/MockCodeFixProvider.cs
similarity index 100%
rename from src/Moq/Moq.CodeFix/MockCodeFixProvider.cs
rename to src/Moq.CodeFix/MockCodeFixProvider.cs
diff --git a/src/Moq/Moq.CodeFix/Moq.CodeFix.csproj b/src/Moq.CodeFix/Moq.CodeFix.csproj
similarity index 100%
rename from src/Moq/Moq.CodeFix/Moq.CodeFix.csproj
rename to src/Moq.CodeFix/Moq.CodeFix.csproj
diff --git a/src/Moq/Moq.CodeFix/Properties/Resources.Designer.cs b/src/Moq.CodeFix/Properties/Resources.Designer.cs
similarity index 100%
rename from src/Moq/Moq.CodeFix/Properties/Resources.Designer.cs
rename to src/Moq.CodeFix/Properties/Resources.Designer.cs
diff --git a/src/Moq/Moq.CodeFix/Properties/Resources.resx b/src/Moq.CodeFix/Properties/Resources.resx
similarity index 100%
rename from src/Moq/Moq.CodeFix/Properties/Resources.resx
rename to src/Moq.CodeFix/Properties/Resources.resx
diff --git a/src/Moq/Moq.CodeAnalysis/Properties/launchSettings.json b/src/Moq.CodeFix/Properties/launchSettings.json
similarity index 100%
rename from src/Moq/Moq.CodeAnalysis/Properties/launchSettings.json
rename to src/Moq.CodeFix/Properties/launchSettings.json
diff --git a/src/Moq/Moq.CodeAnalysis/ResourceString.cs b/src/Moq.CodeFix/ResourceString.cs
similarity index 100%
rename from src/Moq/Moq.CodeAnalysis/ResourceString.cs
rename to src/Moq.CodeFix/ResourceString.cs
diff --git a/src/Moq/Moq.DynamicProxy/DynamicMockFactory.cs b/src/Moq.DynamicProxy/DynamicMockFactory.cs
similarity index 73%
rename from src/Moq/Moq.DynamicProxy/DynamicMockFactory.cs
rename to src/Moq.DynamicProxy/DynamicMockFactory.cs
index 16b4b69b..9c598c15 100644
--- a/src/Moq/Moq.DynamicProxy/DynamicMockFactory.cs
+++ b/src/Moq.DynamicProxy/DynamicMockFactory.cs
@@ -1,11 +1,9 @@
using System;
-using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Threading;
using Castle.DynamicProxy;
using Stunts;
-using Stunts.Sdk;
namespace Moq.Sdk
{
@@ -21,7 +19,7 @@ public object CreateMock(Assembly mocksAssembly, Type baseType, Type[] implement
///
/// Creates the mock proxy.
///
- protected override object CreateProxy(Type baseType, Type[] implementedInterfaces, ProxyGenerationOptions options, object[] constructorArguments, bool notImplemented)
+ protected override object CreateProxy(Type baseType, Type[] implementedInterfaces, object[] constructorArguments, ProxyGenerationOptions options, Func getDefaultInterceptor)
{
if (!implementedInterfaces.Contains(typeof(IMocked)))
{
@@ -31,32 +29,28 @@ protected override object CreateProxy(Type baseType, Type[] implementedInterface
implementedInterfaces = fixedInterfaces;
}
- var mocked = (IMocked)Generator.CreateClassProxy(baseType, implementedInterfaces, options, constructorArguments, new DynamicMockInterceptor(notImplemented));
+ var mocked = (IMocked)Generator.CreateClassProxy(baseType, implementedInterfaces, options, constructorArguments,
+ new IInterceptor[] { new MockInterceptor(), getDefaultInterceptor() });
// Save for cloning purposes. We opened a generated proxy from DP to figure out the ctor signature it creates.
// The lazy-calculated value allows us to provide a new interceptor for every retrieval.
// Add first-class support in statebag for this pattern of either Func for values, or
// Lazy, since both could be quite useful for expensive state that may be needed lazily.
- mocked.Mock.State.Set(".ctor", () => new object[] { new IInterceptor[] { new DynamicMockInterceptor(notImplemented) } }.Concat(constructorArguments).ToArray());
+ mocked.Mock.State.Set(".ctor", () => new object[] { new IInterceptor[] { new MockInterceptor(), getDefaultInterceptor() } }.Concat(constructorArguments).ToArray());
return mocked;
}
- class DynamicMockInterceptor : DynamicStuntInterceptor
+ private class MockInterceptor : IInterceptor
{
- IMock mock;
+ private IMock? mock;
- public DynamicMockInterceptor(bool notImplemented) : base(notImplemented) { }
-
- public override void Intercept(IInvocation invocation)
+ public void Intercept(IInvocation invocation)
{
if (invocation.Method.DeclaringType == typeof(IMocked))
- {
invocation.ReturnValue = LazyInitializer.EnsureInitialized(ref mock, () => new DefaultMock((IStunt)invocation.Proxy));
- return;
- }
-
- base.Intercept(invocation);
+ else
+ invocation.Proceed();
}
}
}
diff --git a/src/Moq.DynamicProxy/Mock.DynamicFactory.cs b/src/Moq.DynamicProxy/Mock.DynamicFactory.cs
new file mode 100644
index 00000000..fb9a59d5
--- /dev/null
+++ b/src/Moq.DynamicProxy/Mock.DynamicFactory.cs
@@ -0,0 +1,17 @@
+namespace Moq
+{
+ internal partial class Mock
+ {
+ static Mock()
+ {
+ Sdk.MockFactory.Default = new Sdk.DynamicMockFactory();
+ OnInitialized();
+ }
+
+ ///
+ /// Invoked after the default
+ /// is initialized.
+ ///
+ static partial void OnInitialized();
+ }
+}
\ No newline at end of file
diff --git a/src/Moq.DynamicProxy/Mock.DynamicFactory.vb b/src/Moq.DynamicProxy/Mock.DynamicFactory.vb
new file mode 100644
index 00000000..9d316ad9
--- /dev/null
+++ b/src/Moq.DynamicProxy/Mock.DynamicFactory.vb
@@ -0,0 +1,16 @@
+Namespace Global.Moq
+ Partial Friend Class Mock
+ Shared Sub New()
+ Sdk.MockFactory.[Default] = New Sdk.DynamicMockFactory
+ OnInitialized()
+ End Sub
+
+ '''
+ ''' Invoked after the default
+ ''' is initialized.
+ '''
+ Partial Private Shared Sub OnInitialized()
+
+ End Sub
+ End Class
+End Namespace
\ No newline at end of file
diff --git a/src/Moq.DynamicProxy/Moq.DynamicProxy.csproj b/src/Moq.DynamicProxy/Moq.DynamicProxy.csproj
new file mode 100644
index 00000000..798f367d
--- /dev/null
+++ b/src/Moq.DynamicProxy/Moq.DynamicProxy.csproj
@@ -0,0 +1,37 @@
+
+
+
+ netstandard2.0
+ true
+
+
+ Provides run-time mock generation using Castle DynamicProxy, for projects that
+ cannot use the compile-time mock generation provided built-in by Moq, which
+ requires C# 9.0.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Moq.DynamicProxy/Moq.DynamicProxy.targets b/src/Moq.DynamicProxy/Moq.DynamicProxy.targets
new file mode 100644
index 00000000..a64c35ee
--- /dev/null
+++ b/src/Moq.DynamicProxy/Moq.DynamicProxy.targets
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Moq/Moq/contentFiles/cs/netstandard2.0/Mocks/Mock.Overloads.cs b/src/Moq.Package/Mock.Overloads.cs
similarity index 87%
rename from src/Moq/Moq/contentFiles/cs/netstandard2.0/Mocks/Mock.Overloads.cs
rename to src/Moq.Package/Mock.Overloads.cs
index 0e13ba51..21f6a5a3 100644
--- a/src/Moq/Moq/contentFiles/cs/netstandard2.0/Mocks/Mock.Overloads.cs
+++ b/src/Moq.Package/Mock.Overloads.cs
@@ -1,4 +1,3 @@
-using System.CodeDom.Compiler;
using System.Runtime.CompilerServices;
namespace Moq
@@ -6,53 +5,44 @@ namespace Moq
///
/// Instantiates stunts for the specified types.
///
- partial class Mock
+ internal partial class Mock
{
///
/// Creates a mock that inherits or implements the type .
///
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(params object[] constructorArgs) where T : class => Create(MockBehavior.Loose, constructorArgs);
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(params object[] constructorArgs) where T : class => Create(MockBehavior.Loose, constructorArgs, typeof(T1));
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(params object[] constructorArgs) where T : class => Create(MockBehavior.Loose, constructorArgs, typeof(T1), typeof(T2));
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(params object[] constructorArgs) where T : class => Create(MockBehavior.Loose, constructorArgs, typeof(T1), typeof(T2), typeof(T3));
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(params object[] constructorArgs) where T : class => Create(MockBehavior.Loose, constructorArgs, typeof(T1), typeof(T2), typeof(T3), typeof(T4));
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(params object[] constructorArgs) where T : class => Create(MockBehavior.Loose, constructorArgs, typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5));
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(params object[] constructorArgs) where T : class => Create(MockBehavior.Loose, constructorArgs, typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6));
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(params object[] constructorArgs) where T : class => Create(MockBehavior.Loose, constructorArgs, typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7));
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(params object[] constructorArgs) where T : class => Create(MockBehavior.Loose, constructorArgs, typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8));
@@ -60,47 +50,38 @@ partial class Mock
/// Creates a mock that inherits or implements the type .
///
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(MockBehavior behavior, params object[] constructorArgs) where T : class => Create(behavior, constructorArgs);
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(MockBehavior behavior, params object[] constructorArgs) where T : class => Create(behavior, constructorArgs, typeof(T1));
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(MockBehavior behavior, params object[] constructorArgs) where T : class => Create(behavior, constructorArgs, typeof(T1), typeof(T2));
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(MockBehavior behavior, params object[] constructorArgs) where T : class => Create(behavior, constructorArgs, typeof(T1), typeof(T2), typeof(T3));
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(MockBehavior behavior, params object[] constructorArgs) where T : class => Create(behavior, constructorArgs, typeof(T1), typeof(T2), typeof(T3), typeof(T4));
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(MockBehavior behavior, params object[] constructorArgs) where T : class => Create(behavior, constructorArgs, typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5));
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(MockBehavior behavior, params object[] constructorArgs) where T : class => Create(behavior, constructorArgs, typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6));
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(MockBehavior behavior, params object[] constructorArgs) where T : class => Create(behavior, constructorArgs, typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7));
[MockGenerator]
- [GeneratedCode("Moq", "5.0")]
[CompilerGenerated]
public static T Of(MockBehavior behavior, params object[] constructorArgs) where T : class => Create(behavior, constructorArgs, typeof(T1), typeof(T2), typeof(T3), typeof(T4), typeof(T5), typeof(T6), typeof(T7), typeof(T8));
}
diff --git a/src/Moq/Moq/contentFiles/vb/netstandard2.0/Mocks/Mock.Overloads.vb b/src/Moq.Package/Mock.Overloads.vb
similarity index 87%
rename from src/Moq/Moq/contentFiles/vb/netstandard2.0/Mocks/Mock.Overloads.vb
rename to src/Moq.Package/Mock.Overloads.vb
index ffaff399..80a79ee7 100644
--- a/src/Moq/Moq/contentFiles/vb/netstandard2.0/Mocks/Mock.Overloads.vb
+++ b/src/Moq.Package/Mock.Overloads.vb
@@ -1,134 +1,112 @@
-Imports System.CodeDom.Compiler
-Imports System.Reflection
-Imports System.Runtime.CompilerServices
-Imports Moq.Sdk
-Imports Stunts
+Imports System.Runtime.CompilerServices
Namespace Global.Moq
Partial Friend Class Mock
-
Public Shared Function [Of](Of T As Class)(ParamArray constructorArgs As Object()) As T
Return Create(Of T)(MockBehavior.Loose, constructorArgs)
End Function
-
Public Shared Function [Of](Of T As Class, T1)(ParamArray constructorArgs As Object()) As T
Return Create(Of T)(MockBehavior.Loose, constructorArgs, GetType(T1))
End Function
-
Public Shared Function [Of](Of T As Class, T1, T2)(ParamArray constructorArgs As Object()) As T
Return Create(Of T)(MockBehavior.Loose, constructorArgs, GetType(T1), GetType(T2))
End Function
-
Public Shared Function [Of](Of T As Class, T1, T2, T3)(ParamArray constructorArgs As Object()) As T
Return Create(Of T)(MockBehavior.Loose, constructorArgs, GetType(T1), GetType(T2), GetType(T3))
End Function
-
Public Shared Function [Of](Of T As Class, T1, T2, T3, T4)(ParamArray constructorArgs As Object()) As T
Return Create(Of T)(MockBehavior.Loose, constructorArgs, GetType(T1), GetType(T2), GetType(T3), GetType(T4))
End Function
-
Public Shared Function [Of](Of T As Class, T1, T2, T3, T4, T5)(ParamArray constructorArgs As Object()) As T
Return Create(Of T)(MockBehavior.Loose, constructorArgs, GetType(T1), GetType(T2), GetType(T3), GetType(T4), GetType(T5))
End Function
-
Public Shared Function [Of](Of T As Class, T1, T2, T3, T4, T5, T6)(ParamArray constructorArgs As Object()) As T
Return Create(Of T)(MockBehavior.Loose, constructorArgs, GetType(T1), GetType(T2), GetType(T3), GetType(T4), GetType(T5), GetType(T6))
End Function
-
Public Shared Function [Of](Of T As Class, T1, T2, T3, T4, T5, T6, T7)(ParamArray constructorArgs As Object()) As T
Return Create(Of T)(MockBehavior.Loose, constructorArgs, GetType(T1), GetType(T2), GetType(T3), GetType(T4), GetType(T5), GetType(T6), GetType(T7))
End Function
-
Public Shared Function [Of](Of T As Class, T1, T2, T3, T4, T5, T6, T7, T8)(ParamArray constructorArgs As Object()) As T
Return Create(Of T)(MockBehavior.Loose, constructorArgs, GetType(T1), GetType(T2), GetType(T3), GetType(T4), GetType(T5), GetType(T6), GetType(T7), GetType(T8))
End Function
-
Public Shared Function [Of](Of T As Class)(ByVal behavior As MockBehavior, ParamArray constructorArgs As Object()) As T
Return Create(Of T)(behavior, constructorArgs)
End Function
-
Public Shared Function [Of](Of T As Class, T1)(ByVal behavior As MockBehavior, ParamArray constructorArgs As Object()) As T
Return Create(Of T)(behavior, constructorArgs, GetType(T1))
End Function
-
Public Shared Function [Of](Of T As Class, T1, T2)(ByVal behavior As MockBehavior, ParamArray constructorArgs As Object()) As T
Return Create(Of T)(behavior, constructorArgs, GetType(T1), GetType(T2))
End Function
-
Public Shared Function [Of](Of T As Class, T1, T2, T3)(ByVal behavior As MockBehavior, ParamArray constructorArgs As Object()) As T
Return Create(Of T)(behavior, constructorArgs, GetType(T1), GetType(T2), GetType(T3))
End Function
-
Public Shared Function [Of](Of T As Class, T1, T2, T3, T4)(ByVal behavior As MockBehavior, ParamArray constructorArgs As Object()) As T
Return Create(Of T)(behavior, constructorArgs, GetType(T1), GetType(T2), GetType(T3), GetType(T4))
End Function
-
Public Shared Function [Of](Of T As Class, T1, T2, T3, T4, T5)(ByVal behavior As MockBehavior, ParamArray constructorArgs As Object()) As T
Return Create(Of T)(MockBehavior.Loose, constructorArgs, GetType(T1), GetType(T2), GetType(T3), GetType(T4), GetType(T5))
End Function
-
Public Shared Function [Of](Of T As Class, T1, T2, T3, T4, T5, T6)(ByVal behavior As MockBehavior, ParamArray constructorArgs As Object()) As T
Return Create(Of T)(behavior, constructorArgs, GetType(T1), GetType(T2), GetType(T3), GetType(T4), GetType(T5), GetType(T6))
End Function
-
Public Shared Function [Of](Of T As Class, T1, T2, T3, T4, T5, T6, T7)(ByVal behavior As MockBehavior, ParamArray constructorArgs As Object()) As T
Return Create(Of T)(behavior, constructorArgs, GetType(T1), GetType(T2), GetType(T3), GetType(T4), GetType(T5), GetType(T6), GetType(T7))
End Function
-
Public Shared Function [Of](Of T As Class, T1, T2, T3, T4, T5, T6, T7, T8)(ByVal behavior As MockBehavior, ParamArray constructorArgs As Object()) As T
Return Create(Of T)(behavior, constructorArgs, GetType(T1), GetType(T2), GetType(T3), GetType(T4), GetType(T5), GetType(T6), GetType(T7), GetType(T8))
diff --git a/src/Moq.Package/Mock.StaticFactory.cs b/src/Moq.Package/Mock.StaticFactory.cs
new file mode 100644
index 00000000..5e54bc24
--- /dev/null
+++ b/src/Moq.Package/Mock.StaticFactory.cs
@@ -0,0 +1,17 @@
+namespace Moq
+{
+ internal partial class Mock
+ {
+ static Mock()
+ {
+ Sdk.MockFactory.Default = new Sdk.StaticMockFactory();
+ OnInitialized();
+ }
+
+ ///
+ /// Invoked after the default
+ /// is initialized.
+ ///
+ static partial void OnInitialized();
+ }
+}
\ No newline at end of file
diff --git a/src/Moq.Package/Mock.StaticFactory.vb b/src/Moq.Package/Mock.StaticFactory.vb
new file mode 100644
index 00000000..0c4d52fb
--- /dev/null
+++ b/src/Moq.Package/Mock.StaticFactory.vb
@@ -0,0 +1,16 @@
+Namespace Global.Moq
+ Partial Friend Class Mock
+ Shared Sub New()
+ MockFactory.[Default] = New Sdk.StaticMockFactory
+ OnInitialized()
+ End Sub
+
+ '''
+ ''' Invoked after the default
+ ''' is initialized.
+ '''
+ Partial Private Shared Sub OnInitialized()
+
+ End Sub
+ End Class
+End Namespace
\ No newline at end of file
diff --git a/src/Moq/Moq/contentFiles/cs/netstandard2.0/Mocks/Mock.cs b/src/Moq.Package/Mock.cs
similarity index 79%
rename from src/Moq/Moq/contentFiles/cs/netstandard2.0/Mocks/Mock.cs
rename to src/Moq.Package/Mock.cs
index a1374bdf..12e2cd15 100644
--- a/src/Moq/Moq/contentFiles/cs/netstandard2.0/Mocks/Mock.cs
+++ b/src/Moq.Package/Mock.cs
@@ -1,5 +1,5 @@
using System;
-using System.CodeDom.Compiler;
+using System.Diagnostics.CodeAnalysis;
using System.Reflection;
using System.Runtime.CompilerServices;
using Moq.Sdk;
@@ -9,12 +9,10 @@ namespace Moq
///
/// Instantiates mocks for the specified types.
///
- [GeneratedCode("Moq", "5.0")]
+ [ExcludeFromCodeCoverage]
[CompilerGenerated]
- partial class Mock
+ internal partial class Mock
{
- static Mock() => MockFactory.Default = new Sdk.DynamicMockFactory();
-
///
/// Gets the configuration and introspection for the given mocked instance.
///
@@ -26,7 +24,7 @@ partial class Mock
///
private static T Create(MockBehavior behavior, object[] constructorArgs, params Type[] interfaces) where T : class
{
- var mocked = (IMocked)MockFactory.Default.CreateMock(typeof(Mock).GetTypeInfo().Assembly, typeof(T), interfaces, constructorArgs);
+ var mocked = (IMocked)MockFactory.Default.CreateMock(typeof(Mock).Assembly, typeof(T), interfaces, constructorArgs);
mocked.Initialize(behavior);
diff --git a/src/Moq/Moq/contentFiles/vb/netstandard2.0/Mocks/Mock.vb b/src/Moq.Package/Mock.vb
similarity index 66%
rename from src/Moq/Moq/contentFiles/vb/netstandard2.0/Mocks/Mock.vb
rename to src/Moq.Package/Mock.vb
index dcd8f656..9ea01358 100644
--- a/src/Moq/Moq/contentFiles/vb/netstandard2.0/Mocks/Mock.vb
+++ b/src/Moq.Package/Mock.vb
@@ -1,22 +1,19 @@
Option Strict On
Imports System
-Imports System.CodeDom.Compiler
+Imports System.Diagnostics.CodeAnalysis
Imports System.Reflection
Imports System.Runtime.CompilerServices
Imports Moq.Sdk
Namespace Global.Moq
-
+
Partial Friend Class Mock
- Private Shared Sub New()
- MockFactory.[Default] = New Sdk.DynamicMockFactory()
- End Sub
Private Shared Function Create(Of T As Class)(ByVal behavior As MockBehavior, ByVal constructorArgs As Object(), ParamArray interfaces As Type()) As T
- Dim mocked = DirectCast(MockFactory.[Default].CreateMock(GetType(Mock).GetTypeInfo().Assembly, GetType(T), interfaces, constructorArgs), IMocked)
+ Dim mocked = DirectCast(MockFactory.[Default].CreateMock(GetType(Mock).Assembly, GetType(T), interfaces, constructorArgs), IMocked)
mocked.Initialize(behavior)
diff --git a/src/Moq.Package/Moq.Package.msbuildproj b/src/Moq.Package/Moq.Package.msbuildproj
new file mode 100644
index 00000000..d83ce139
--- /dev/null
+++ b/src/Moq.Package/Moq.Package.msbuildproj
@@ -0,0 +1,29 @@
+
+
+ netstandard2.0
+ .NETStandard,Version=v2.0
+ Moq
+ Moq
+ The most popular and friendly mocking framework for .NET
+ moq mocking mock
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Moq.Package/Moq.props b/src/Moq.Package/Moq.props
new file mode 100644
index 00000000..072af853
--- /dev/null
+++ b/src/Moq.Package/Moq.props
@@ -0,0 +1,10 @@
+
+
+
+ true
+
+ 002400000480000094000000060200000024000052534131000400000100010051155fd0ee280be78d81cc979423f1129ec5dd28edce9cd94fd679890639cad54c121ebdb606f8659659cd313d3b3db7fa41e2271158dd602bb0039a142717117fa1f63d93a2d288a1c2f920ec05c4858d344a45d48ebd31c1368ab783596b382b611d8c92f9c1b3d338296aa21b12f3bc9f34de87756100c172c52a24bad2db
+ 00352124762f2aa5
+
+
+
\ No newline at end of file
diff --git a/src/Moq.Package/Moq.targets b/src/Moq.Package/Moq.targets
new file mode 100644
index 00000000..c3b05273
--- /dev/null
+++ b/src/Moq.Package/Moq.targets
@@ -0,0 +1,36 @@
+
+
+
+ $(MSBuildThisFileDirectory)..\..\tools\netstandard2.0
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Moq/Moq.Sdk.Tests/AnyMatcherTests.cs b/src/Moq.Sdk.Tests/AnyMatcherTests.cs
similarity index 94%
rename from src/Moq/Moq.Sdk.Tests/AnyMatcherTests.cs
rename to src/Moq.Sdk.Tests/AnyMatcherTests.cs
index d9015794..88a08f1b 100644
--- a/src/Moq/Moq.Sdk.Tests/AnyMatcherTests.cs
+++ b/src/Moq.Sdk.Tests/AnyMatcherTests.cs
@@ -1,8 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
using Xunit;
namespace Moq.Sdk.Tests
@@ -110,9 +106,8 @@ public void MatchesDerivedType()
Assert.True(x.Matches(new Derived()));
}
+ private class Base { }
-
- class Base { }
- class Derived : Base { }
+ private class Derived : Base { }
}
}
diff --git a/src/Moq/Moq.Sdk.Tests/CallContextTests.cs b/src/Moq.Sdk.Tests/CallContextTests.cs
similarity index 100%
rename from src/Moq/Moq.Sdk.Tests/CallContextTests.cs
rename to src/Moq.Sdk.Tests/CallContextTests.cs
diff --git a/src/Moq/Moq.Sdk.Tests/ConditionalMatcherTests.cs b/src/Moq.Sdk.Tests/ConditionalMatcherTests.cs
similarity index 96%
rename from src/Moq/Moq.Sdk.Tests/ConditionalMatcherTests.cs
rename to src/Moq.Sdk.Tests/ConditionalMatcherTests.cs
index 38c1a562..a9761e30 100644
--- a/src/Moq/Moq.Sdk.Tests/ConditionalMatcherTests.cs
+++ b/src/Moq.Sdk.Tests/ConditionalMatcherTests.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using Xunit;
namespace Moq.Sdk.Tests
@@ -57,7 +56,8 @@ public void EqualsByConditionFunctionAndName()
Assert.False(matcher.Equals(new ConditionalMatcher(_ => true, "foo")));
}
- class Base { }
- class Derived : Base { }
+ private class Base { }
+
+ private class Derived : Base { }
}
}
diff --git a/src/Moq/Moq.Sdk.Tests/DefaultMockTests.cs b/src/Moq.Sdk.Tests/DefaultMockTests.cs
similarity index 90%
rename from src/Moq/Moq.Sdk.Tests/DefaultMockTests.cs
rename to src/Moq.Sdk.Tests/DefaultMockTests.cs
index 42bfbe56..271e7151 100644
--- a/src/Moq/Moq.Sdk.Tests/DefaultMockTests.cs
+++ b/src/Moq.Sdk.Tests/DefaultMockTests.cs
@@ -1,5 +1,5 @@
using System;
-using System.Collections.ObjectModel;
+using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using Stunts;
@@ -60,7 +60,7 @@ public void TrackMockBehaviors()
var behavior = new MockBehaviorPipeline(setup);
stunt.AddBehavior(behavior);
- stunt.AddBehavior(new DelegateStuntBehavior((m, n) => n().Invoke(m, n)));
+ stunt.AddBehavior((m, n) => n().Invoke(m, n));
Assert.Equal(initialBehaviors + 2, stunt.Behaviors.Count);
Assert.Single(stunt.Mock.Setups);
@@ -102,12 +102,12 @@ public void TracksTargetObject()
public void InitializesState()
=> Assert.NotNull(new FakeStunt().Mock.State);
- class FakeStunt : IStunt, IMocked
+ private class FakeStunt : IStunt, IMocked
{
- BehaviorPipeline pipeline = new BehaviorPipeline();
- DefaultMock mock;
+ private readonly BehaviorPipeline pipeline = new BehaviorPipeline();
+ private DefaultMock mock;
- public ObservableCollection Behaviors => pipeline.Behaviors;
+ public IList Behaviors => pipeline.Behaviors;
public IMock Mock => LazyInitializer.EnsureInitialized(ref mock, () => new DefaultMock(this));
diff --git a/src/Moq/Moq.Sdk.Tests/EqualityTests.cs b/src/Moq.Sdk.Tests/EqualityTests.cs
similarity index 96%
rename from src/Moq/Moq.Sdk.Tests/EqualityTests.cs
rename to src/Moq.Sdk.Tests/EqualityTests.cs
index b7d6dca1..cde53526 100644
--- a/src/Moq/Moq.Sdk.Tests/EqualityTests.cs
+++ b/src/Moq.Sdk.Tests/EqualityTests.cs
@@ -1,10 +1,5 @@
using System;
-using System.Collections;
using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
using Stunts;
using Xunit;
@@ -131,6 +126,6 @@ public void Matchers()
Assert.False(hash.Add(value2));
}
- void AMethod(bool b, string s, PlatformID p) { }
+ private void AMethod(bool b, string s, PlatformID p) { }
}
}
diff --git a/src/Moq/Moq.Sdk.Tests/EventBehaviorTests.cs b/src/Moq.Sdk.Tests/EventBehaviorTests.cs
similarity index 90%
rename from src/Moq/Moq.Sdk.Tests/EventBehaviorTests.cs
rename to src/Moq.Sdk.Tests/EventBehaviorTests.cs
index fb6f3ac4..8ab38ddb 100644
--- a/src/Moq/Moq.Sdk.Tests/EventBehaviorTests.cs
+++ b/src/Moq.Sdk.Tests/EventBehaviorTests.cs
@@ -1,8 +1,6 @@
using System;
-using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Reflection;
-using System.Threading;
using Stunts;
using Xunit;
@@ -35,7 +33,7 @@ public void AddsHandler()
{
var mock = new EventfulMock();
mock.Behaviors.Add(new EventBehavior());
- mock.Behaviors.Add(new DelegateStuntBehavior((m, n) => m.CreateValueReturn(null)));
+ mock.AddBehavior((m, n) => m.CreateValueReturn(null));
EventHandler handler = (_, __) => { };
mock.Empty += handler;
@@ -49,7 +47,7 @@ public void RemovesHandler()
{
var mock = new EventfulMock();
mock.Behaviors.Add(new EventBehavior());
- mock.Behaviors.Add(new DelegateStuntBehavior((m, n) => m.CreateValueReturn(null)));
+ mock.AddBehavior((m, n) => m.CreateValueReturn(null));
EventHandler handler = (_, __) => { };
mock.Empty += handler;
@@ -69,7 +67,7 @@ public void RaisesEventHandlerIfRaiserInContextOnAdd()
{
var mock = new EventfulMock();
mock.Behaviors.Add(new EventBehavior());
- mock.Behaviors.Add(new DelegateStuntBehavior((m, n) => m.CreateValueReturn(null)));
+ mock.AddBehavior((m, n) => m.CreateValueReturn(null));
var called = false;
EventHandler handler = (_, __) => called = true;
@@ -86,7 +84,7 @@ public void RaisesEventArgsIfRaiserInContextOnAdd()
{
var mock = new EventfulMock();
mock.Behaviors.Add(new EventBehavior());
- mock.Behaviors.Add(new DelegateStuntBehavior((m, n) => m.CreateValueReturn(null)));
+ mock.AddBehavior((m, n) => m.CreateValueReturn(null));
var expected = new Args();
var actual = default(Args);
@@ -104,7 +102,7 @@ public void RaisesPropertyChangedIfRaiserInContextOnAdd()
{
var mock = new EventfulMock();
mock.Behaviors.Add(new EventBehavior());
- mock.Behaviors.Add(new DelegateStuntBehavior((m, n) => m.CreateValueReturn(null)));
+ mock.AddBehavior((m, n) => m.CreateValueReturn(null));
var expected = new PropertyChangedEventArgs("Foo");
var actual = default(PropertyChangedEventArgs);
@@ -122,7 +120,7 @@ public void RaisesActionIfRaiserInContextOnAdd()
{
var mock = new EventfulMock();
mock.Behaviors.Add(new EventBehavior());
- mock.Behaviors.Add(new DelegateStuntBehavior((m, n) => m.CreateValueReturn(null)));
+ mock.AddBehavior((m, n) => m.CreateValueReturn(null));
var expected = 5;
var actual = 0;
@@ -140,7 +138,7 @@ public void RaisesCustomDelegateIfRaiserInContextOnAdd()
{
var mock = new EventfulMock();
mock.Behaviors.Add(new EventBehavior());
- mock.Behaviors.Add(new DelegateStuntBehavior((m, n) => m.CreateValueReturn(null)));
+ mock.AddBehavior((m, n) => m.CreateValueReturn(null));
var (id, name) = (5, "foo");
var (id2, name2) = (0, "");
diff --git a/src/Moq/Moq.Sdk.Tests/Fakes.cs b/src/Moq.Sdk.Tests/Fakes.cs
similarity index 93%
rename from src/Moq/Moq.Sdk.Tests/Fakes.cs
rename to src/Moq.Sdk.Tests/Fakes.cs
index 26e74c38..5537462c 100644
--- a/src/Moq/Moq.Sdk.Tests/Fakes.cs
+++ b/src/Moq.Sdk.Tests/Fakes.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using System.Reflection;
using Stunts;
@@ -9,13 +8,13 @@ namespace Moq.Sdk.Tests
{
public class FakeMock : IStunt, IMocked
{
- DefaultMock mock;
+ private readonly DefaultMock mock;
protected BehaviorPipeline Pipeline = new BehaviorPipeline();
public FakeMock() => mock = new DefaultMock(this);
- public ObservableCollection Behaviors => Pipeline.Behaviors;
+ public IList Behaviors => Pipeline.Behaviors;
public IMock Mock => mock;
}
diff --git a/src/Moq/Moq.Sdk.Tests/GlobalSuppressions.cs b/src/Moq.Sdk.Tests/GlobalSuppressions.cs
similarity index 100%
rename from src/Moq/Moq.Sdk.Tests/GlobalSuppressions.cs
rename to src/Moq.Sdk.Tests/GlobalSuppressions.cs
diff --git a/src/Moq/Moq.Sdk.Tests/MockBehaviorPipelineTests.cs b/src/Moq.Sdk.Tests/MockBehaviorPipelineTests.cs
similarity index 100%
rename from src/Moq/Moq.Sdk.Tests/MockBehaviorPipelineTests.cs
rename to src/Moq.Sdk.Tests/MockBehaviorPipelineTests.cs
diff --git a/src/Moq/Moq.Sdk.Tests/MockBehaviorTests.cs b/src/Moq.Sdk.Tests/MockBehaviorTests.cs
similarity index 100%
rename from src/Moq/Moq.Sdk.Tests/MockBehaviorTests.cs
rename to src/Moq.Sdk.Tests/MockBehaviorTests.cs
diff --git a/src/Moq/Moq.Sdk.Tests/MockExtensionsTests.cs b/src/Moq.Sdk.Tests/MockExtensionsTests.cs
similarity index 97%
rename from src/Moq/Moq.Sdk.Tests/MockExtensionsTests.cs
rename to src/Moq.Sdk.Tests/MockExtensionsTests.cs
index d6611fde..d6ee65b8 100644
--- a/src/Moq/Moq.Sdk.Tests/MockExtensionsTests.cs
+++ b/src/Moq.Sdk.Tests/MockExtensionsTests.cs
@@ -42,8 +42,8 @@ public void CanAssertInvocations()
Assert.Equal(0, target.Add(2, 3));
Assert.Single(target.AsMock().InvocationsFor(c => c.Add(2, 3)));
}
-
- class FakeCalls : FakeMock
+
+ private class FakeCalls : FakeMock
{
public void TurnOn() => Pipeline.Execute(new MethodInvocation(this, MethodBase.GetCurrentMethod()));
diff --git a/src/Moq/Moq.Sdk.Tests/MockNamingTests.cs b/src/Moq.Sdk.Tests/MockNamingTests.cs
similarity index 100%
rename from src/Moq/Moq.Sdk.Tests/MockNamingTests.cs
rename to src/Moq.Sdk.Tests/MockNamingTests.cs
diff --git a/src/Moq/Moq.Sdk.Tests/MockTrackingBehaviorTests.cs b/src/Moq.Sdk.Tests/MockTrackingBehaviorTests.cs
similarity index 93%
rename from src/Moq/Moq.Sdk.Tests/MockTrackingBehaviorTests.cs
rename to src/Moq.Sdk.Tests/MockTrackingBehaviorTests.cs
index 5dc0372e..98b533e8 100644
--- a/src/Moq/Moq.Sdk.Tests/MockTrackingBehaviorTests.cs
+++ b/src/Moq.Sdk.Tests/MockTrackingBehaviorTests.cs
@@ -1,6 +1,4 @@
-using System.Collections.ObjectModel;
-using System.Reflection;
-using System.Threading;
+using System.Reflection;
using Stunts;
using Xunit;
@@ -49,8 +47,7 @@ public void SkipInvocationRecordingIfSetupScopeActive()
Assert.Empty(target.Mock.Invocations);
}
-
- class TrackingMock : FakeMock
+ private class TrackingMock : FakeMock
{
public void Do() => Pipeline.Execute(new MethodInvocation(this, MethodBase.GetCurrentMethod()));
}
diff --git a/src/Moq/Moq.Sdk.Tests/Mocked.cs b/src/Moq.Sdk.Tests/Mocked.cs
similarity index 60%
rename from src/Moq/Moq.Sdk.Tests/Mocked.cs
rename to src/Moq.Sdk.Tests/Mocked.cs
index 4c85adc6..c31fdf7f 100644
--- a/src/Moq/Moq.Sdk.Tests/Mocked.cs
+++ b/src/Moq.Sdk.Tests/Mocked.cs
@@ -7,11 +7,11 @@ namespace Moq.Sdk.Tests
{
public class Mocked : IMocked, IStunt
{
- IMock mock;
- ObservableCollection behaviors = new ObservableCollection();
+ private IMock mock;
+ private readonly IList behaviors = new ObservableCollection();
public IMock Mock => LazyInitializer.EnsureInitialized(ref mock, () => new DefaultMock(this));
- public ObservableCollection Behaviors => behaviors;
+ public IList Behaviors => behaviors;
}
}
diff --git a/src/Moq.Sdk.Tests/Moq.Sdk.Tests.csproj b/src/Moq.Sdk.Tests/Moq.Sdk.Tests.csproj
new file mode 100644
index 00000000..9ad3d51b
--- /dev/null
+++ b/src/Moq.Sdk.Tests/Moq.Sdk.Tests.csproj
@@ -0,0 +1,25 @@
+
+
+
+ net472;net5.0
+ annotations
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Moq/Moq.Sdk.Tests/NotMatcherTests.cs b/src/Moq.Sdk.Tests/NotMatcherTests.cs
similarity index 96%
rename from src/Moq/Moq.Sdk.Tests/NotMatcherTests.cs
rename to src/Moq.Sdk.Tests/NotMatcherTests.cs
index a12fbcbc..137fd76a 100644
--- a/src/Moq/Moq.Sdk.Tests/NotMatcherTests.cs
+++ b/src/Moq.Sdk.Tests/NotMatcherTests.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using Xunit;
namespace Moq.Sdk.Tests
@@ -49,7 +48,7 @@ public void MatcherEquals()
Assert.Equal(expected.GetHashCode(), actual.GetHashCode());
}
- class Value
+ private class Value
{
public Value(Guid id) => Id = id;
diff --git a/src/Moq/Moq.Sdk.Tests/PropertyBehaviorTests.cs b/src/Moq.Sdk.Tests/PropertyBehaviorTests.cs
similarity index 95%
rename from src/Moq/Moq.Sdk.Tests/PropertyBehaviorTests.cs
rename to src/Moq.Sdk.Tests/PropertyBehaviorTests.cs
index f5727300..71c7f0c2 100644
--- a/src/Moq/Moq.Sdk.Tests/PropertyBehaviorTests.cs
+++ b/src/Moq.Sdk.Tests/PropertyBehaviorTests.cs
@@ -1,9 +1,5 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
using Stunts;
using Xunit;
diff --git a/src/Moq/Moq.Sdk.Tests/SetupScopeTests.cs b/src/Moq.Sdk.Tests/SetupScopeTests.cs
similarity index 69%
rename from src/Moq/Moq.Sdk.Tests/SetupScopeTests.cs
rename to src/Moq.Sdk.Tests/SetupScopeTests.cs
index 8c8717b5..6c564196 100644
--- a/src/Moq/Moq.Sdk.Tests/SetupScopeTests.cs
+++ b/src/Moq.Sdk.Tests/SetupScopeTests.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Xunit;
+using Xunit;
namespace Moq.Sdk.Tests
{
diff --git a/src/Moq/Moq.Sdk.Tests/StrictMockBehaviorTests.cs b/src/Moq.Sdk.Tests/StrictMockBehaviorTests.cs
similarity index 100%
rename from src/Moq/Moq.Sdk.Tests/StrictMockBehaviorTests.cs
rename to src/Moq.Sdk.Tests/StrictMockBehaviorTests.cs
diff --git a/src/Moq/Moq.Sdk.Tests/TimesFixture.cs b/src/Moq.Sdk.Tests/TimesFixture.cs
similarity index 100%
rename from src/Moq/Moq.Sdk.Tests/TimesFixture.cs
rename to src/Moq.Sdk.Tests/TimesFixture.cs
diff --git a/src/Moq/Moq.Sdk/AnyMatcher.cs b/src/Moq.Sdk/AnyMatcher.cs
similarity index 86%
rename from src/Moq/Moq.Sdk/AnyMatcher.cs
rename to src/Moq.Sdk/AnyMatcher.cs
index f5f8a004..2f184625 100644
--- a/src/Moq/Moq.Sdk/AnyMatcher.cs
+++ b/src/Moq.Sdk/AnyMatcher.cs
@@ -12,9 +12,9 @@ namespace Moq.Sdk
///
public class AnyMatcher : IArgumentMatcher, IEquatable
{
- TypeInfo info;
- bool isValueType;
- bool isNullable;
+ private readonly TypeInfo info;
+ private readonly bool isValueType;
+ private readonly bool isNullable;
///
/// Initializes the matcher with the given .
@@ -38,7 +38,7 @@ public AnyMatcher(Type argumentType)
///
/// Evaluates whether the given value matches this instance.
///
- public bool Matches(object value)
+ public bool Matches(object? value)
{
// Non-nullable value types never match against a null value.
if (isValueType && !isNullable && value == null)
@@ -61,10 +61,10 @@ public bool Matches(object value)
#region Equality
///
- public bool Equals(AnyMatcher other) => other != null && info.Equals(other.info);
+ public bool Equals(AnyMatcher other) => info.Equals(other.info);
///
- public override bool Equals(object other) => Equals(other as AnyMatcher);
+ public override bool Equals(object other) => other is AnyMatcher matcher && Equals(matcher);
///
public override int GetHashCode() => info.GetHashCode();
diff --git a/src/Moq/Moq.Sdk/AnyMatcher`1.cs b/src/Moq.Sdk/AnyMatcher`1.cs
similarity index 87%
rename from src/Moq/Moq.Sdk/AnyMatcher`1.cs
rename to src/Moq.Sdk/AnyMatcher`1.cs
index d0f93f88..302f93ef 100644
--- a/src/Moq/Moq.Sdk/AnyMatcher`1.cs
+++ b/src/Moq.Sdk/AnyMatcher`1.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections;
using System.Diagnostics;
using System.Reflection;
using TypeNameFormatter;
@@ -15,8 +14,8 @@ namespace Moq.Sdk
public class AnyMatcher : IArgumentMatcher, IEquatable>
{
// Disable warning since we only use this member from this class
- static bool IsValueType = typeof(T).GetTypeInfo().IsValueType;
- static bool IsNullable = typeof(T).GetTypeInfo().IsGenericType &&
+ private static readonly bool IsValueType = typeof(T).IsValueType;
+ private static readonly bool IsNullable = typeof(T).IsGenericType &&
typeof(T).GetGenericTypeDefinition() == typeof(Nullable<>);
///
@@ -24,7 +23,7 @@ public class AnyMatcher : IArgumentMatcher, IEquatable>
///
public static IArgumentMatcher Default { get; } = new AnyMatcher();
- AnyMatcher() { }
+ private AnyMatcher() { }
///
/// Gets the type of the argument this matcher supports.
@@ -34,14 +33,14 @@ public class AnyMatcher : IArgumentMatcher, IEquatable>
///
/// Evaluates whether the given value matches this instance.
///
- public bool Matches(object value)
+ public bool Matches(object? value)
{
// Non-nullable value types never match against a null value.
if (IsValueType && !IsNullable && value == null)
return false;
return value == null ||
- typeof(T).GetTypeInfo().IsAssignableFrom(value.GetType().GetTypeInfo());
+ typeof(T).IsAssignableFrom(value.GetType());
}
///
@@ -72,7 +71,7 @@ public bool Matches(object value)
///
/// if is not null and
/// it's an with the same .
- public override bool Equals(object other) => Equals(other as AnyMatcher);
+ public override bool Equals(object other) => other is AnyMatcher matcher && Equals(matcher);
///
public override int GetHashCode() => typeof(T).GetHashCode();
diff --git a/src/Moq/Moq.Sdk/CallContext.cs b/src/Moq.Sdk/CallContext.cs
similarity index 68%
rename from src/Moq/Moq.Sdk/CallContext.cs
rename to src/Moq.Sdk/CallContext.cs
index 0175ed29..f0e99cd3 100644
--- a/src/Moq/Moq.Sdk/CallContext.cs
+++ b/src/Moq.Sdk/CallContext.cs
@@ -10,36 +10,36 @@ namespace Moq.Sdk
///
public static class CallContext
{
- static readonly string defaultName = typeof(T).FullName;
- static ConcurrentDictionary> state = new ConcurrentDictionary>();
+ private static readonly string defaultName = typeof(T).FullName;
+ private static readonly ConcurrentDictionary> state = new();
///
/// Stores a given object.
///
/// The object to store in the call context.
- public static void SetData(T data) => SetData(defaultName, data);
+ public static void SetData(T? data) => SetData(defaultName, data);
///
/// Stores a given object and associates it with the specified name.
///
/// The name with which to associate the new item in the call context.
/// The object to store in the call context.
- public static void SetData(string name, T data) =>
- state.GetOrAdd(name, _ => new AsyncLocal()).Value = data;
+ public static void SetData(string name, T? data)
+ => state.GetOrAdd(name, _ => new AsyncLocal()).Value = data;
///
/// Retrieves an object from the .
///
/// The object in the call context associated with the specified name, or a default value for if none is found.
- public static T GetData() => GetData(defaultName);
+ public static T? GetData() => GetData(defaultName);
///
/// Retrieves an object with the specified name from the .
///
/// The name of the item in the call context.
/// The object in the call context associated with the specified name, or a default value for if none is found.
- public static T GetData(string name) =>
- state.TryGetValue(name, out var data) ? data.Value : default;
+ public static T? GetData(string name)
+ => state.TryGetValue(name, out var data) ? data.Value : default;
///
/// Retrieves an object from the , and
@@ -47,7 +47,7 @@ public static T GetData(string name) =>
///
/// A function that will set the initial value of the given parameter, if it doesn't have a value already in the context.
/// The object in the call context associated with the specified name, or the initial value returned from .
- public static T GetData(Func setInitialValue) => GetData(defaultName, setInitialValue);
+ public static T? GetData(Func setInitialValue) => GetData(defaultName, setInitialValue);
///
/// Retrieves an object with the specified name from the , and
@@ -56,10 +56,10 @@ public static T GetData(string name) =>
/// The name of the item in the call context.
/// A function that will set the initial value of the given parameter, if it doesn't have a value already in the context.
/// The object in the call context associated with the specified name, or the initial value returned from .
- public static T GetData(string name, Func setInitialValue)
+ public static T? GetData(string name, Func setInitialValue)
{
- var local = state.GetOrAdd(name, _ => new AsyncLocal { Value = setInitialValue() });
- if (object.Equals(local.Value, default(T)))
+ var local = state.GetOrAdd(name, _ => new AsyncLocal { Value = setInitialValue() });
+ if (Equals(local.Value, default(T)))
local.Value = setInitialValue();
return local.Value;
@@ -72,22 +72,30 @@ public static T GetData(string name, Func setInitialValue)
///
public static class CallContext
{
- static ConcurrentDictionary> state = new ConcurrentDictionary>();
+ private static readonly ConcurrentDictionary> state = new();
///
/// Stores a given object and associates it with the specified name.
///
/// The name with which to associate the new item in the call context.
/// The object to store in the call context.
- public static void SetData(string name, object data) =>
- state.GetOrAdd(name, _ => new AsyncLocal
public bool Equals(ConditionalMatcher other)
- => other != null && ReferenceEquals(condition, other.condition) && name.Equals(other.name);
+ => ReferenceEquals(condition, other.condition) && name.Equals(other.name);
///
/// Checks whether has the same condition and friendly name.
///
- public override bool Equals(object other) => Equals(other as ConditionalMatcher);
+ public override bool Equals(object other) => other is ConditionalMatcher matcher && Equals(matcher);
///
- public override int GetHashCode() => new HashCode().Add(condition).Add(name).ToHashCode();
+ public override int GetHashCode() => HashCode.Combine(condition, name);
#endregion
}
diff --git a/src/Moq/Moq.Sdk/DefaultMock.cs b/src/Moq.Sdk/DefaultMock.cs
similarity index 70%
rename from src/Moq/Moq.Sdk/DefaultMock.cs
rename to src/Moq.Sdk/DefaultMock.cs
index 397f6b6d..e9199fc3 100644
--- a/src/Moq/Moq.Sdk/DefaultMock.cs
+++ b/src/Moq.Sdk/DefaultMock.cs
@@ -1,11 +1,9 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
-using Moq.Sdk.Properties;
using Stunts;
namespace Moq.Sdk
@@ -29,18 +27,20 @@ public class DefaultMock : IMock
public DefaultMock(IStunt stunt)
{
this.stunt = stunt ?? throw new ArgumentNullException(nameof(stunt));
+ var behaviors = stunt.Behaviors;
- if (!stunt.Behaviors.OfType().Any())
- stunt.Behaviors.Insert(0, new MockContextBehavior());
+ if (!behaviors.OfType().Any())
+ behaviors.Insert(0, new MockContextBehavior());
- if (!stunt.Behaviors.OfType().Any())
- stunt.Behaviors.Insert(1, new MockRecordingBehavior());
+ if (!behaviors.OfType().Any())
+ behaviors.Insert(1, new MockRecordingBehavior());
- stunt.Behaviors.CollectionChanged += OnBehaviorsChanged;
+ if (behaviors is INotifyCollectionChanged notify)
+ notify.CollectionChanged += OnBehaviorsChanged;
}
///
- public ObservableCollection Behaviors => stunt.Behaviors;
+ public IList Behaviors => stunt.Behaviors;
///
public ICollection Invocations { get; } = new List();
@@ -59,48 +59,57 @@ public DefaultMock(IStunt stunt)
public IMockBehaviorPipeline GetPipeline(IMockSetup setup)
=> setupBehaviorMap.GetOrAdd(setup, x =>
{
+ var behaviors = stunt.Behaviors;
var behavior = new MockBehaviorPipeline(x);
+
// The tracking behavior must appear before the mock behaviors.
- var context = Behaviors.OfType().FirstOrDefault();
+ var context = behaviors.OfType().FirstOrDefault();
// If there is a recording behavior, it must be before mock behaviors too.
- var recording = Behaviors.OfType().FirstOrDefault();
+ var recording = behaviors.OfType().FirstOrDefault();
- var index = context == null ? 0 : Behaviors.IndexOf(context);
+ var index = context == null ? 0 : behaviors.IndexOf(context);
if (recording != null)
- index = Math.Max(index, Behaviors.IndexOf(recording));
+ index = Math.Max(index, behaviors.IndexOf(recording));
// NOTE: latest setup wins, since it goes to the top of the list.
- Behaviors.Insert(++index, behavior);
+ behaviors.Insert(++index, behavior);
return behavior;
});
- void OnBehaviorsChanged(object sender, NotifyCollectionChangedEventArgs e)
+ private void OnBehaviorsChanged(object sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
+ var behaviors = stunt.Behaviors;
+ // TODO: optimize these two checks
// Can't have more than one of MockContextBehavior, since that causes problems.
- if (Behaviors.OfType().Skip(1).Any())
- throw new InvalidOperationException(Resources.DuplicateContextBehavior);
+ if (behaviors.OfType().Skip(1).Any())
+ throw new InvalidOperationException(ThisAssembly.Strings.DuplicateContextBehavior);
// Can't have more than one of MockRecordingBehavior, since that causes problems.
- if (Behaviors.OfType().Skip(1).Any())
- throw new InvalidOperationException(Resources.DuplicateRecordingBehavior);
+ if (behaviors.OfType().Skip(1).Any())
+ throw new InvalidOperationException(ThisAssembly.Strings.DuplicateRecordingBehavior);
foreach (var behavior in e.NewItems.OfType())
setupBehaviorMap.TryAdd(behavior.Setup, behavior);
break;
+
case NotifyCollectionChangedAction.Remove:
foreach (var behavior in e.OldItems.OfType())
setupBehaviorMap.TryRemove(behavior.Setup, out _);
break;
+
case NotifyCollectionChangedAction.Replace:
- foreach (var behavior in e.NewItems.OfType())
- setupBehaviorMap.TryAdd(behavior.Setup, behavior);
foreach (var behavior in e.OldItems.OfType())
setupBehaviorMap.TryRemove(behavior.Setup, out _);
+ foreach (var behavior in e.NewItems.OfType())
+ setupBehaviorMap.TryAdd(behavior.Setup, behavior);
break;
+
case NotifyCollectionChangedAction.Reset:
setupBehaviorMap.Clear();
+ foreach (var behavior in stunt.Behaviors.OfType())
+ setupBehaviorMap.TryAdd(behavior.Setup, behavior);
break;
}
}
diff --git a/src/Moq/Moq.Sdk/DelegateMockBehavior.cs b/src/Moq.Sdk/DelegateMockBehavior.cs
similarity index 94%
rename from src/Moq/Moq.Sdk/DelegateMockBehavior.cs
rename to src/Moq.Sdk/DelegateMockBehavior.cs
index a92afaaa..78c800e9 100644
--- a/src/Moq/Moq.Sdk/DelegateMockBehavior.cs
+++ b/src/Moq.Sdk/DelegateMockBehavior.cs
@@ -12,8 +12,8 @@ namespace Moq.Sdk
[DebuggerDisplay("{DisplayName}")]
public class DelegateMockBehavior : IMockBehavior
{
- readonly Lazy displayName;
- readonly ExecuteMockDelegate behavior;
+ private readonly Lazy displayName;
+ private readonly ExecuteMockDelegate behavior;
///
/// Creates an instance of the invokable behavior with the given
diff --git a/src/Moq/Moq.Sdk/EventBehavior.cs b/src/Moq.Sdk/EventBehavior.cs
similarity index 94%
rename from src/Moq/Moq.Sdk/EventBehavior.cs
rename to src/Moq.Sdk/EventBehavior.cs
index 8927cb8c..4ba4698c 100644
--- a/src/Moq/Moq.Sdk/EventBehavior.cs
+++ b/src/Moq.Sdk/EventBehavior.cs
@@ -30,8 +30,7 @@ public IMethodReturn Execute(IMethodInvocation invocation, GetNextBehavior next)
if (info != null)
{
- EventRaiser raiser = null;
- if ((raiser = CallContext.GetData()) != null)
+ if (CallContext.GetData() is EventRaiser raiser)
{
try
{
@@ -77,7 +76,7 @@ public IMethodReturn Execute(IMethodInvocation invocation, GetNextBehavior next)
return next()(invocation, next);
}
- static void CombineDelegate(EventInfo info, Delegate handler, IMock mock)
+ private static void CombineDelegate(EventInfo info, Delegate handler, IMock mock)
{
var state = mock.State.GetOrAdd(info.Name, () => handler);
if (state != handler)
@@ -101,7 +100,7 @@ static void CombineDelegate(EventInfo info, Delegate handler, IMock mock)
}
}
- static void RemoveDelegate(EventInfo info, Delegate handler, IMock mock)
+ private static void RemoveDelegate(EventInfo info, Delegate handler, IMock mock)
{
if (mock.State.TryGetValue(info.Name, out var state))
{
diff --git a/src/Moq/Moq.Sdk/EventRaiser.cs b/src/Moq.Sdk/EventRaiser.cs
similarity index 91%
rename from src/Moq/Moq.Sdk/EventRaiser.cs
rename to src/Moq.Sdk/EventRaiser.cs
index 877967e5..bc7ecb7e 100644
--- a/src/Moq/Moq.Sdk/EventRaiser.cs
+++ b/src/Moq.Sdk/EventRaiser.cs
@@ -14,7 +14,7 @@ public abstract class EventRaiser
public static EventRaiser Empty { get; } = new EmptyEventRaiser();
}
- class EmptyEventRaiser : EventRaiser { }
+ internal class EmptyEventRaiser : EventRaiser { }
///
/// Context state that signals an event must be
@@ -28,12 +28,12 @@ public class EventArgsEventRaiser : EventRaiser
/// Creates an instance of the
/// with the given event arguments.
///
- public EventArgsEventRaiser(object args) => EventArgs = args;
+ public EventArgsEventRaiser(object? args) => EventArgs = args;
///
/// The event arguments for the raised event.
///
- public object EventArgs { get; }
+ public object? EventArgs { get; }
}
///
diff --git a/src/Moq/Moq.Sdk/GlobalSuppressions.cs b/src/Moq.Sdk/GlobalSuppressions.cs
similarity index 100%
rename from src/Moq/Moq.Sdk/GlobalSuppressions.cs
rename to src/Moq.Sdk/GlobalSuppressions.cs
diff --git a/src/Moq/Moq.Sdk/IArgumentMatcher.cs b/src/Moq.Sdk/IArgumentMatcher.cs
similarity index 87%
rename from src/Moq/Moq.Sdk/IArgumentMatcher.cs
rename to src/Moq.Sdk/IArgumentMatcher.cs
index 79c3d9ae..039af635 100644
--- a/src/Moq/Moq.Sdk/IArgumentMatcher.cs
+++ b/src/Moq.Sdk/IArgumentMatcher.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections;
namespace Moq.Sdk
{
@@ -16,6 +15,6 @@ public interface IArgumentMatcher
///
/// Evaluates whether the given value matches this instance.
///
- bool Matches(object value);
+ bool Matches(object? value);
}
}
diff --git a/src/Moq/Moq.Sdk/IMock.cs b/src/Moq.Sdk/IMock.cs
similarity index 100%
rename from src/Moq/Moq.Sdk/IMock.cs
rename to src/Moq.Sdk/IMock.cs
diff --git a/src/Moq/Moq.Sdk/IMockBehavior.cs b/src/Moq.Sdk/IMockBehavior.cs
similarity index 100%
rename from src/Moq/Moq.Sdk/IMockBehavior.cs
rename to src/Moq.Sdk/IMockBehavior.cs
diff --git a/src/Moq/Moq.Sdk/IMockBehaviorPipeline.cs b/src/Moq.Sdk/IMockBehaviorPipeline.cs
similarity index 100%
rename from src/Moq/Moq.Sdk/IMockBehaviorPipeline.cs
rename to src/Moq.Sdk/IMockBehaviorPipeline.cs
diff --git a/src/Moq/Moq.Sdk/IMockFactory.cs b/src/Moq.Sdk/IMockFactory.cs
similarity index 100%
rename from src/Moq/Moq.Sdk/IMockFactory.cs
rename to src/Moq.Sdk/IMockFactory.cs
diff --git a/src/Moq/Moq.Sdk/IMockSetup.cs b/src/Moq.Sdk/IMockSetup.cs
similarity index 100%
rename from src/Moq/Moq.Sdk/IMockSetup.cs
rename to src/Moq.Sdk/IMockSetup.cs
diff --git a/src/Moq/Moq.Sdk/IMock`1.cs b/src/Moq.Sdk/IMock`1.cs
similarity index 100%
rename from src/Moq/Moq.Sdk/IMock`1.cs
rename to src/Moq.Sdk/IMock`1.cs
diff --git a/src/Moq/Moq.Sdk/IMocked.cs b/src/Moq.Sdk/IMocked.cs
similarity index 61%
rename from src/Moq/Moq.Sdk/IMocked.cs
rename to src/Moq.Sdk/IMocked.cs
index f0aa8104..2720aafc 100644
--- a/src/Moq/Moq.Sdk/IMocked.cs
+++ b/src/Moq.Sdk/IMocked.cs
@@ -1,5 +1,4 @@
-using System.CodeDom.Compiler;
-using System.Diagnostics;
+using System.Diagnostics;
using System.Runtime.CompilerServices;
namespace Moq.Sdk
@@ -9,16 +8,13 @@ namespace Moq.Sdk
/// the interface for introspecting
/// a mock instance.
///
- // These attributes prevent registering the "Implement through behavior pipeline" codefix.
- // See CustomMockCodeFixProvider and its base class CustomStuntCodeFixProvider.
- [GeneratedCode("Moq", ThisAssembly.Metadata.Version)]
[CompilerGenerated]
public interface IMocked
{
///
/// The introspection information for the current mock.
///
- [DebuggerDisplay("Invocations = {Mock.Invocations.Count}", Name = nameof(IMocked) + "." + nameof(IMocked.Mock))]
+ [DebuggerDisplay("Invocations = {Mock.Invocations.Count}", Name = nameof(IMocked) + "." + nameof(Mock))]
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
IMock Mock { get; }
}
diff --git a/src/Moq/Moq.Sdk/MockBehaviorPipeline.cs b/src/Moq.Sdk/MockBehaviorPipeline.cs
similarity index 97%
rename from src/Moq/Moq.Sdk/MockBehaviorPipeline.cs
rename to src/Moq.Sdk/MockBehaviorPipeline.cs
index fa0a890d..cf562d21 100644
--- a/src/Moq/Moq.Sdk/MockBehaviorPipeline.cs
+++ b/src/Moq.Sdk/MockBehaviorPipeline.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
-using Moq.Sdk.Properties;
using Stunts;
namespace Moq.Sdk
@@ -38,7 +37,7 @@ public class MockBehaviorPipeline : IMockBehaviorPipeline
///
public IMethodReturn Execute(IMethodInvocation invocation, GetNextBehavior next)
{
- var mock = (invocation.Target as IMocked)?.Mock ?? throw new ArgumentException(Resources.TargetNotMock);
+ var mock = (invocation.Target as IMocked)?.Mock ?? throw new ArgumentException(ThisAssembly.Strings.TargetNotMock);
// NOTE: the mock behavior is like a sub-pipeline within the overall stunt
// behavior pipeline, where all the behaviors added automatically apply
diff --git a/src/Moq/Moq.Sdk/MockContext.cs b/src/Moq.Sdk/MockContext.cs
similarity index 91%
rename from src/Moq/Moq.Sdk/MockContext.cs
rename to src/Moq.Sdk/MockContext.cs
index adfb71ea..2870053d 100644
--- a/src/Moq/Moq.Sdk/MockContext.cs
+++ b/src/Moq.Sdk/MockContext.cs
@@ -12,7 +12,7 @@ public static class MockContext
/// The most recent invocation performed on the mock, tracked
/// by the .
///
- public static IMethodInvocation CurrentInvocation
+ public static IMethodInvocation? CurrentInvocation
{
get => CallContext.GetData();
set => CallContext.SetData(value);
@@ -28,7 +28,7 @@ public static IMethodInvocation CurrentInvocation
/// This property is also tracked and populated by the
/// .
///
- public static IMockSetup CurrentSetup
+ public static IMockSetup? CurrentSetup
{
get => CallContext.GetData();
set => CallContext.SetData(value);
diff --git a/src/Moq/Moq.Sdk/MockContextBehavior.cs b/src/Moq.Sdk/MockContextBehavior.cs
similarity index 100%
rename from src/Moq/Moq.Sdk/MockContextBehavior.cs
rename to src/Moq.Sdk/MockContextBehavior.cs
diff --git a/src/Moq/Moq.Sdk/MockDecorator.cs b/src/Moq.Sdk/MockDecorator.cs
similarity index 90%
rename from src/Moq/Moq.Sdk/MockDecorator.cs
rename to src/Moq.Sdk/MockDecorator.cs
index dd329998..277e1ec6 100644
--- a/src/Moq/Moq.Sdk/MockDecorator.cs
+++ b/src/Moq.Sdk/MockDecorator.cs
@@ -1,5 +1,4 @@
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using Stunts;
namespace Moq.Sdk
@@ -9,7 +8,7 @@ namespace Moq.Sdk
///
public abstract class MockDecorator : IMock
{
- readonly IMock mock;
+ private readonly IMock mock;
///
/// Initializes the decorator with the given underlying
@@ -44,7 +43,7 @@ public virtual StateBag State
///
/// See .
///
- public virtual ObservableCollection Behaviors => mock.Behaviors;
+ public virtual IList Behaviors => mock.Behaviors;
///
/// See .
diff --git a/src/Moq/Moq.Sdk/MockDecorator`1.cs b/src/Moq.Sdk/MockDecorator`1.cs
similarity index 93%
rename from src/Moq/Moq.Sdk/MockDecorator`1.cs
rename to src/Moq.Sdk/MockDecorator`1.cs
index 664e8853..35edcd0b 100644
--- a/src/Moq/Moq.Sdk/MockDecorator`1.cs
+++ b/src/Moq.Sdk/MockDecorator`1.cs
@@ -5,7 +5,7 @@
///
public abstract class MockDecorator : MockDecorator, IMock where T : class
{
- readonly IMock mock;
+ private readonly IMock mock;
///
/// Initializes the decorator with the given underlying
diff --git a/src/Moq/Moq.Sdk/MockException.cs b/src/Moq.Sdk/MockException.cs
similarity index 92%
rename from src/Moq/Moq.Sdk/MockException.cs
rename to src/Moq.Sdk/MockException.cs
index 36b29e6b..36007644 100644
--- a/src/Moq/Moq.Sdk/MockException.cs
+++ b/src/Moq.Sdk/MockException.cs
@@ -1,6 +1,4 @@
using System;
-using System.Linq;
-using System.Reflection;
namespace Moq.Sdk
{
diff --git a/src/Moq/Moq.Sdk/MockExtensions.cs b/src/Moq.Sdk/MockExtensions.cs
similarity index 73%
rename from src/Moq/Moq.Sdk/MockExtensions.cs
rename to src/Moq.Sdk/MockExtensions.cs
index baf27854..79183377 100644
--- a/src/Moq/Moq.Sdk/MockExtensions.cs
+++ b/src/Moq.Sdk/MockExtensions.cs
@@ -1,10 +1,9 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using System.ComponentModel;
+using System.Data;
using System.Diagnostics;
using System.Linq;
-using Moq.Sdk.Properties;
using Stunts;
namespace Moq.Sdk
@@ -21,7 +20,7 @@ public static class MockExtensions
public static IMock AsMock(this T instance) where T : class
=> (instance is MulticastDelegate @delegate ?
@delegate.Target as IMocked :
- instance as IMocked)?.Mock.As(instance) ?? throw new ArgumentException(Strings.TargetNotMock, nameof(instance));
+ instance as IMocked)?.Mock.As(instance) ?? throw new ArgumentException(ThisAssembly.Strings.TargetNotMock, nameof(instance));
///
/// Clones a mock by creating a new instance of the
@@ -32,22 +31,29 @@ public static IMock Clone(this IMock mock) where T : class
if (!mock.State.TryGetValue(".ctor", out var ctor))
throw new ArgumentException("No constructor state found for cloning.");
- // TODO: THIS DOESN'T WORK WITH DYNAMIC PROXIES, SINCE WE'RE MISSING THE INTERCEPTORS
- // This is what it looks like in a DP: public BaseWithCtorProxy(IInterceptor[] interceptorArray, string value) : base(value)
- // So we need to persist the interceptors as part of the ctor array, maybe?
var clone = ((IMocked)Activator.CreateInstance(mock.Object.GetType(), ctor)).Mock;
clone.State = mock.State.Clone();
- clone.Behaviors.Clear();
- foreach (var behavior in mock.Behaviors)
+ var behaviors = clone.Behaviors;
+ (behaviors as ISupportInitialize)?.BeginInit();
+ try
{
- clone.Behaviors.Add(behavior);
+ behaviors.Clear();
+ foreach (var behavior in mock.Behaviors)
+ {
+ behaviors.Add(behavior);
+ }
+ }
+ finally
+ {
+ (behaviors as ISupportInitialize)?.EndInit();
}
- clone.Invocations.Clear();
+ var invocations = clone.Invocations;
+ invocations.Clear();
foreach (var invocation in mock.Invocations)
{
- clone.Invocations.Add(invocation);
+ invocations.Add(invocation);
}
return ((T)clone.Object).AsMock();
@@ -62,7 +68,7 @@ public static IEnumerable InvocationsFor(this IMock moc
using (new SetupScope())
{
action(mock.Object);
- var setup = MockContext.CurrentSetup;
+ var setup = MockContext.CurrentSetup ?? CallContext.ThrowUnexpectedNull();
return mock.Invocations.Where(x => setup.AppliesTo(x));
}
}
@@ -76,16 +82,16 @@ public static IEnumerable InvocationsFor(this IMo
using (new SetupScope())
{
function(mock.Object);
- var setup = MockContext.CurrentSetup;
+ var setup = MockContext.CurrentSetup ?? CallContext.ThrowUnexpectedNull();
return mock.Invocations.Where(x => setup.AppliesTo(x));
}
}
- static IMock As(this IMock mock, T target) where T : class => mock == null ? null : new Mock(mock, target);
+ private static IMock? As(this IMock? mock, T target) where T : class => mock == null ? null : new Mock(mock, target);
- class Mock : IMock where T : class
+ private class Mock : IMock where T : class
{
- IMock mock;
+ private readonly IMock mock;
public Mock(IMock mock, T target)
{
@@ -108,7 +114,7 @@ public StateBag State
public IEnumerable Setups => mock.Setups;
- public ObservableCollection Behaviors => mock.Behaviors;
+ public IList Behaviors => mock.Behaviors;
public IMockBehaviorPipeline GetPipeline(IMockSetup setup) => mock.GetPipeline(setup);
}
diff --git a/src/Moq.Sdk/MockFactory.cs b/src/Moq.Sdk/MockFactory.cs
new file mode 100644
index 00000000..ad72b539
--- /dev/null
+++ b/src/Moq.Sdk/MockFactory.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Reflection;
+
+namespace Moq.Sdk
+{
+ ///
+ /// Allows accessing the default used
+ /// to create mocks.
+ ///
+ public class MockFactory : IMockFactory
+ {
+ private static readonly IMockFactory nullFactory = new MockFactory();
+
+ ///
+ /// Gets or sets the default to use
+ /// to create mocks. Defaults to the factory.
+ ///
+ public static IMockFactory Default { get; set; } = nullFactory;
+
+ ///
+ /// A factory that throws .
+ ///
+ public static IMockFactory NotImplemented { get; } = nullFactory;
+
+ private MockFactory() { }
+
+ ///
+ /// Throws since this is the default
+ /// factory.
+ ///
+ public object CreateMock(Assembly mocksAssembly, Type baseType, Type[] implementedInterfaces, object[] constructorArguments)
+ => throw new NotImplementedException(ThisAssembly.Strings.MockFactoryNotImplemented);
+ }
+}
\ No newline at end of file
diff --git a/src/Moq/Moq.Sdk/MockFactoryExtensions.cs b/src/Moq.Sdk/MockFactoryExtensions.cs
similarity index 100%
rename from src/Moq/Moq.Sdk/MockFactoryExtensions.cs
rename to src/Moq.Sdk/MockFactoryExtensions.cs
diff --git a/src/Moq/Moq.Sdk/MockGeneratorAttribute.cs b/src/Moq.Sdk/MockGeneratorAttribute.cs
similarity index 100%
rename from src/Moq/Moq.Sdk/MockGeneratorAttribute.cs
rename to src/Moq.Sdk/MockGeneratorAttribute.cs
diff --git a/src/Moq/Moq.Sdk/MockNaming.cs b/src/Moq.Sdk/MockNaming.cs
similarity index 100%
rename from src/Moq/Moq.Sdk/MockNaming.cs
rename to src/Moq.Sdk/MockNaming.cs
diff --git a/src/Moq/Moq.Sdk/MockRecordingBehavior.cs b/src/Moq.Sdk/MockRecordingBehavior.cs
similarity index 94%
rename from src/Moq/Moq.Sdk/MockRecordingBehavior.cs
rename to src/Moq.Sdk/MockRecordingBehavior.cs
index d4cc5852..e8b3150a 100644
--- a/src/Moq/Moq.Sdk/MockRecordingBehavior.cs
+++ b/src/Moq.Sdk/MockRecordingBehavior.cs
@@ -1,6 +1,4 @@
-using System;
-using Stunts;
-using System.Diagnostics;
+using Stunts;
namespace Moq.Sdk
{
diff --git a/src/Moq/Moq.Sdk/MockSetup.Static.cs b/src/Moq.Sdk/MockSetup.Static.cs
similarity index 83%
rename from src/Moq/Moq.Sdk/MockSetup.Static.cs
rename to src/Moq.Sdk/MockSetup.Static.cs
index 0308d69f..862d9e07 100644
--- a/src/Moq/Moq.Sdk/MockSetup.Static.cs
+++ b/src/Moq.Sdk/MockSetup.Static.cs
@@ -1,4 +1,5 @@
-using System.Collections.Generic;
+using System;
+using System.Collections.Generic;
using System.Linq;
using Stunts;
@@ -19,9 +20,9 @@ public partial class MockSetup
public static T Push(IArgumentMatcher matcher)
{
CallContext>.GetData(() => new Queue())
- .Enqueue(matcher);
+ ?.Enqueue(matcher);
- return default;
+ return default!;
}
///
@@ -32,7 +33,9 @@ public static T Push(IArgumentMatcher matcher)
/// An that can be used to filter invocations in a behavior pipeline.
internal static IMockSetup Freeze(IMethodInvocation invocation)
{
- var currentMatchers = CallContext>.GetData(() => new Queue());
+ var currentMatchers = CallContext>.GetData(() => new Queue())
+ ?? throw new InvalidOperationException(ThisAssembly.Strings.UnexpectedNullContextState(typeof(Queue).FullName));
+
var finalMatchers = new List();
var parameters = invocation.MethodBase.GetParameters();
var defaultValue = (invocation.Target as IMocked)?.
@@ -47,9 +50,9 @@ internal static IMockSetup Freeze(IMethodInvocation invocation)
// This is a bit fuzzy since we compare the actual argument value against the
// default value for the parameter type, or the type of the matcher in the
// queue of argument matchers to see if applies instead.
- if (object.Equals(argument, defaultValue.GetDefault(parameter.ParameterType)) &&
+ if (Equals(argument, defaultValue.GetDefault(parameter.ParameterType)) &&
currentMatchers.Count != 0 &&
- parameter.ParameterType.GetValueTypeInfo().IsAssignableFrom(currentMatchers.Peek().ArgumentType.GetValueTypeInfo()))
+ parameter.ParameterType.IsAssignableFrom(currentMatchers.Peek().ArgumentType))
{
finalMatchers.Add(currentMatchers.Dequeue());
}
diff --git a/src/Moq/Moq.Sdk/MockSetup.cs b/src/Moq.Sdk/MockSetup.cs
similarity index 92%
rename from src/Moq/Moq.Sdk/MockSetup.cs
rename to src/Moq.Sdk/MockSetup.cs
index 034baf17..8901ccf1 100644
--- a/src/Moq/Moq.Sdk/MockSetup.cs
+++ b/src/Moq.Sdk/MockSetup.cs
@@ -1,6 +1,4 @@
using System;
-using System.Collections;
-using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
@@ -16,9 +14,9 @@ namespace Moq.Sdk
public partial class MockSetup : IMockSetup, IEquatable
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
- readonly IMethodInvocation invocation;
+ private readonly IMethodInvocation invocation;
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
- readonly IArgumentMatcher[] matchers;
+ private readonly IArgumentMatcher[] matchers;
///
/// Initializes the class with the and
@@ -135,7 +133,7 @@ public override string ToString()
#region Equality
///
- public bool Equals(IMockSetup other)
+ public bool Equals(IMockSetup? other)
=> other != null && Invocation.Equals(other.Invocation) && Matchers.SequenceEqual(other.Matchers);
///
@@ -147,8 +145,16 @@ public override bool Equals(object obj)
=> Equals(obj as IMockSetup);
///
- public override int GetHashCode()
- => new HashCode().Add(Invocation).AddRange(Matchers).ToHashCode();
+ public override int GetHashCode()
+ {
+ var hash = new HashCode();
+ hash.Add(Invocation);
+ foreach (var matcher in Matchers)
+ {
+ hash.Add(matcher);
+ }
+ return hash.ToHashCode();
+ }
#endregion
}
diff --git a/src/Moq.Sdk/Moq.Sdk.csproj b/src/Moq.Sdk/Moq.Sdk.csproj
new file mode 100644
index 00000000..6b7920a8
--- /dev/null
+++ b/src/Moq.Sdk/Moq.Sdk.csproj
@@ -0,0 +1,21 @@
+
+
+
+ netstandard2.0
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/Moq/Moq.Sdk/NotMatcher.cs b/src/Moq.Sdk/NotMatcher.cs
similarity index 71%
rename from src/Moq/Moq.Sdk/NotMatcher.cs
rename to src/Moq.Sdk/NotMatcher.cs
index a5730acf..b4b1ae71 100644
--- a/src/Moq/Moq.Sdk/NotMatcher.cs
+++ b/src/Moq.Sdk/NotMatcher.cs
@@ -1,6 +1,5 @@
using System;
using System.Diagnostics;
-using Stunts;
namespace Moq.Sdk
{
@@ -12,12 +11,12 @@ namespace Moq.Sdk
public class NotMatcher : IArgumentMatcher, IEquatable>
{
[DebuggerBrowsable(DebuggerBrowsableState.Never)]
- readonly T value;
+ private readonly T? value;
///
/// Initalizes the matcher with the value to check for.
///
- public NotMatcher(T value) => this.value = value;
+ public NotMatcher(T? value) => this.value = value;
///
/// Gets the type of the argument this matcher supports.
@@ -28,7 +27,7 @@ public class NotMatcher : IArgumentMatcher, IEquatable>
/// Evaluates whether the given value matches this instance, which is always
/// the case unless the initial value equals the .
///
- public bool Matches(object value) => !(Object.Equals(this.value, value));
+ public bool Matches(object? value) => !(Equals(this.value, value));
///
/// Gets a friendly representation of the object.
@@ -39,20 +38,18 @@ public class NotMatcher : IArgumentMatcher, IEquatable>
/// No actual behavior depends on these strings.
///
[DebuggerNonUserCode]
- public override string ToString() => "!" + (value is string ? "\"" + value + "\"" : value.ToString());
+ public override string ToString() => "!" + (value is string ? "\"" + value + "\"" : (value == null ? "null" : value.ToString()));
#region Equality
///
- public bool Equals(NotMatcher other) => other == null ? false :
- ArgumentType == other.ArgumentType && object.Equals(value, other.value);
+ public bool Equals(NotMatcher other) => other != null && ArgumentType == other.ArgumentType && Equals(value, other.value);
///
- public override bool Equals(object obj) => Equals(obj as NotMatcher);
+ public override bool Equals(object obj) => obj is NotMatcher matcher && Equals(matcher);
///
- public override int GetHashCode()
- => new HashCode().Add(ArgumentType).Add(value == null ? 0 : value.GetHashCode()).ToHashCode();
+ public override int GetHashCode() => HashCode.Combine(ArgumentType, value == null ? 0 : value.GetHashCode());
#endregion
}
diff --git a/src/Moq/Moq.Sdk/PropertyBehavior.cs b/src/Moq.Sdk/PropertyBehavior.cs
similarity index 96%
rename from src/Moq/Moq.Sdk/PropertyBehavior.cs
rename to src/Moq.Sdk/PropertyBehavior.cs
index b2e91595..871766c1 100644
--- a/src/Moq/Moq.Sdk/PropertyBehavior.cs
+++ b/src/Moq.Sdk/PropertyBehavior.cs
@@ -1,5 +1,4 @@
using System;
-using Moq.Sdk.Properties;
using Stunts;
namespace Moq.Sdk
@@ -34,7 +33,7 @@ public IMethodReturn Execute(IMethodInvocation invocation, GetNextBehavior next)
{
if (invocation == null) throw new ArgumentNullException(nameof(invocation));
- var state = (invocation.Target as IMocked ?? throw new ArgumentException(Strings.TargetNotMock, nameof(invocation)))
+ var state = (invocation.Target as IMocked ?? throw new ArgumentException(ThisAssembly.Strings.TargetNotMock, nameof(invocation)))
.Mock.State;
if (invocation.MethodBase.Name.StartsWith("get_", StringComparison.Ordinal) &&
diff --git a/src/Moq/Moq.Sdk/Properties/Resources.resx b/src/Moq.Sdk/Resources.resx
similarity index 94%
rename from src/Moq/Moq.Sdk/Properties/Resources.resx
rename to src/Moq.Sdk/Resources.resx
index 1b5c69cd..67ee010b 100644
--- a/src/Moq/Moq.Sdk/Properties/Resources.resx
+++ b/src/Moq.Sdk/Resources.resx
@@ -118,7 +118,7 @@
System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
- Could not locate event for attach or detach method {0}.
+ Could not locate event for attach or detach method '{0}'.No setup is currently being performed on the mock.
@@ -132,4 +132,10 @@
The mock already contains a recording behavior.
+
+ Default factory does not implement mock creation.
+
+
+ Did not expect the call context to have a null value for key '{0}'.
+
\ No newline at end of file
diff --git a/src/Moq/Moq.Sdk/SetupScope.cs b/src/Moq.Sdk/SetupScope.cs
similarity index 93%
rename from src/Moq/Moq.Sdk/SetupScope.cs
rename to src/Moq.Sdk/SetupScope.cs
index 504c3661..44a2d750 100644
--- a/src/Moq/Moq.Sdk/SetupScope.cs
+++ b/src/Moq.Sdk/SetupScope.cs
@@ -18,7 +18,7 @@ namespace Moq
///
public class SetupScope : IDisposable
{
- static AsyncLocal setup = new AsyncLocal();
+ private static readonly AsyncLocal setup = new AsyncLocal();
///
/// Initializes the setup scope.
diff --git a/src/Moq/Moq.Sdk/StackTraceExtensions.cs b/src/Moq.Sdk/StackTraceExtensions.cs
similarity index 100%
rename from src/Moq/Moq.Sdk/StackTraceExtensions.cs
rename to src/Moq.Sdk/StackTraceExtensions.cs
diff --git a/src/Moq/Moq.Sdk/StateBag.cs b/src/Moq.Sdk/StateBag.cs
similarity index 91%
rename from src/Moq/Moq.Sdk/StateBag.cs
rename to src/Moq.Sdk/StateBag.cs
index 4b9d347f..fbe8afb9 100644
--- a/src/Moq/Moq.Sdk/StateBag.cs
+++ b/src/Moq.Sdk/StateBag.cs
@@ -11,17 +11,14 @@ namespace Moq.Sdk
public class StateBag
{
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
- ConcurrentDictionary state;
+ private readonly ConcurrentDictionary state;
///
/// Creates a new instance of the state bag.
///
- public StateBag()
- : this(new ConcurrentDictionary())
- {
- }
+ public StateBag() : this(new()) { }
- private StateBag(ConcurrentDictionary initialState) => state = new ConcurrentDictionary(initialState);
+ private StateBag(ConcurrentDictionary initialState) => state = new(initialState);
///
/// Creates a copy of the state bag.
@@ -49,20 +46,20 @@ public StateBag()
/// specified function, if a value with the given type does not already exist.
///
public T GetOrAdd(Func valueFactory)
- => (T)state.GetOrAdd(typeof(T), _ => valueFactory());
+ => (T)state.GetOrAdd(typeof(T), _ => valueFactory()!);
///
/// Adds the state of the given type and
/// by using the specified function, if a value with the given type does not already exist.
///
public T GetOrAdd(object key, Func valueFactory)
- => (T)state.GetOrAdd(Key(key), _ => valueFactory());
+ => (T)state.GetOrAdd(Key(key), _ => valueFactory()!);
///
/// Sets the state of the given type ,
/// regardless of whether there is an existing value assigned.
///
- public void Set(T value)
+ public void Set(T? value)
{
if (value == null)
state.TryRemove(typeof(T), out _);
@@ -74,7 +71,7 @@ public void Set(T value)
/// Sets the state of the given type ,
/// regardless of whether there is an existing value assigned.
///
- public void Set(Func value)
+ public void Set(Func? value)
{
if (value == null)
state.TryRemove(typeof(T), out _);
@@ -86,7 +83,7 @@ public void Set(Func value)
/// Sets the state of the given type and ,
/// regardless of whether there is an existing value assigned.
///
- public void Set(object key, T value)
+ public void Set(object key, T? value)
{
if (value == null)
state.TryRemove(Key(key), out _);
@@ -98,7 +95,7 @@ public void Set(object key, T value)
/// Sets the state of the given type and ,
/// regardless of whether there is an existing value assigned.
///
- public void Set(object key, Func value)
+ public void Set(object key, Func? value)
{
if (value == null)
state.TryRemove(Key(key), out _);
@@ -112,7 +109,7 @@ public void Set(object key, Func value)
/// The type of value to add.
/// The value of the element to add.
///
- public bool TryAdd(T value) => state.TryAdd(typeof(T), value);
+ public bool TryAdd(T value) => state.TryAdd(typeof(T), value!);
///
/// Attempts to add the specified value to the mock state with the given
@@ -122,7 +119,7 @@ public void Set(object key, Func value)
/// The key of the element to add.
/// The value of the element to add.
///
- public bool TryAdd(object key, T value) => state.TryAdd(Key(key), value);
+ public bool TryAdd(object key, T value) => state.TryAdd(Key(key), value!);
///
/// Attempts to get the value of the given from the mock state.
@@ -131,7 +128,7 @@ public void Set(object key, Func value)
/// When this method returns, contains the object from the mock state
/// that has the specified , or the default value of the type if
/// the operation failed.
- public bool TryGetValue(out T value)
+ public bool TryGetValue(out T? value)
{
var result = state.TryGetValue(typeof(T), out var _value);
value = default;
@@ -150,7 +147,7 @@ public bool TryGetValue(out T value)
/// When this method returns, contains the object from the mock state
/// that has the specified , or the default value of the type if
/// the operation failed.
- public bool TryGetValue(object key, out T value)
+ public bool TryGetValue(object key, out T? value)
{
var result = state.TryGetValue(Key(key), out var _value);
value = default;
@@ -173,7 +170,7 @@ public bool TryGetValue(object key, out T value)
/// When this method returns, contains the object removed from the
/// mock state, or the default value of the type if key does not exist.
/// if the object was removed successfully; otherwise, .
- public bool TryRemove(out T value)
+ public bool TryRemove(out T? value)
{
var result = state.TryRemove(typeof(T), out var _value);
value = default;
@@ -192,7 +189,7 @@ public bool TryRemove(out T value)
/// When this method returns, contains the object removed from the
/// mock state, or the default value of the type if key does not exist.
/// if the object was removed successfully; otherwise, .
- public bool TryRemove(object key, out T value)
+ public bool TryRemove(object key, out T? value)
{
var result = state.TryRemove(Key(key), out var _value);
value = default;
@@ -214,7 +211,7 @@ public bool TryRemove(object key, out T value)
/// if the value with the given was equal
/// to and was replaced with ; otherwise,
/// .
- public bool TryUpdate(T newValue, T comparisonValue) => state.TryUpdate(typeof(T), newValue, comparisonValue);
+ public bool TryUpdate(T newValue, T comparisonValue) => state.TryUpdate(typeof(T), newValue!, comparisonValue!);
///
/// Compares the existing value for of the specified with a specified value,
@@ -229,11 +226,11 @@ public bool TryRemove(object key, out T value)
/// if the value with the given was equal
/// to and was replaced with ; otherwise,
/// .
- public bool TryUpdate(object key, T newValue, T comparisonValue) => state.TryUpdate(Key(key), newValue, comparisonValue);
+ public bool TryUpdate(object key, T newValue, T comparisonValue) => state.TryUpdate(Key(key), newValue!, comparisonValue!);
///
/// Gets the key to use depending on the received .
///
- object Key(object key) => typeof(T) == typeof(object) ? key : (Key: key, Type: typeof(T));
+ private object Key(object key) => typeof(T) == typeof(object) ? key : (Key: key, Type: typeof(T));
}
}
\ No newline at end of file
diff --git a/src/Moq.Sdk/StaticMockFactory.cs b/src/Moq.Sdk/StaticMockFactory.cs
new file mode 100644
index 00000000..30814c93
--- /dev/null
+++ b/src/Moq.Sdk/StaticMockFactory.cs
@@ -0,0 +1,32 @@
+using System;
+using System.ComponentModel;
+using System.Reflection;
+
+namespace Moq.Sdk
+{
+ ///
+ /// Provides a that creates mocks from types
+ /// generated at compile-time that are included in the received mock
+ /// assembly in .
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public class StaticMockFactory : IMockFactory
+ {
+ ///
+ /// Uses the method to
+ /// determine the expected full type name of a compile-time generated mocks
+ /// and tries to locate it from .
+ ///
+ /// The assembly containing the compile-time generated mocks.
+ /// Base type of the mock.
+ /// Additional interfaces the mock implements.
+ /// Optional additional constructor arguments for the mock.
+ public object CreateMock(Assembly mocksAssembly, Type baseType, Type[] implementedInterfaces, object[] constructorArguments)
+ {
+ var name = MockNaming.GetFullName(baseType, implementedInterfaces);
+ var type = mocksAssembly.GetType(name, true, false);
+
+ return Activator.CreateInstance(type, constructorArguments);
+ }
+ }
+}
diff --git a/src/Moq/Moq.Sdk/StrictMockBehavior.cs b/src/Moq.Sdk/StrictMockBehavior.cs
similarity index 95%
rename from src/Moq/Moq.Sdk/StrictMockBehavior.cs
rename to src/Moq.Sdk/StrictMockBehavior.cs
index 25641033..016edc1a 100644
--- a/src/Moq/Moq.Sdk/StrictMockBehavior.cs
+++ b/src/Moq.Sdk/StrictMockBehavior.cs
@@ -1,5 +1,4 @@
-using System;
-using Stunts;
+using Stunts;
namespace Moq.Sdk
{
diff --git a/src/Moq/Moq.Sdk/StrictMockException.cs b/src/Moq.Sdk/StrictMockException.cs
similarity index 100%
rename from src/Moq/Moq.Sdk/StrictMockException.cs
rename to src/Moq.Sdk/StrictMockException.cs
diff --git a/src/Moq/Moq.Sdk/Times.cs b/src/Moq.Sdk/Times.cs
similarity index 98%
rename from src/Moq/Moq.Sdk/Times.cs
rename to src/Moq.Sdk/Times.cs
index 8b61ce77..4b49c6bd 100644
--- a/src/Moq/Moq.Sdk/Times.cs
+++ b/src/Moq.Sdk/Times.cs
@@ -1,6 +1,5 @@
using System;
using System.ComponentModel;
-using Stunts;
namespace Moq.Sdk
{
@@ -9,7 +8,7 @@ namespace Moq.Sdk
///
public readonly struct Times : IEquatable
{
- readonly Lazy hashCode;
+ private readonly Lazy hashCode;
///
/// Initializes the constraint with the given and
@@ -20,7 +19,7 @@ public Times(int from, int to)
{
From = from;
To = to;
- hashCode = new Lazy(() => new HashCode().AddRange(from, to).ToHashCode());
+ hashCode = new Lazy(() => HashCode.Combine(from, to));
}
///
diff --git a/src/Moq/Moq.Sdk/TypeExtensions.cs b/src/Moq.Sdk/TypeExtensions.cs
similarity index 93%
rename from src/Moq/Moq.Sdk/TypeExtensions.cs
rename to src/Moq.Sdk/TypeExtensions.cs
index 2dce7d7c..64b099e8 100644
--- a/src/Moq/Moq.Sdk/TypeExtensions.cs
+++ b/src/Moq.Sdk/TypeExtensions.cs
@@ -3,7 +3,7 @@
namespace Moq.Sdk
{
- static class TypeExtensions
+ internal static class TypeExtensions
{
///
/// Gets the for the underlying value that
diff --git a/src/Moq/Moq.Sdk/ValueMatcher.cs b/src/Moq.Sdk/ValueMatcher.cs
similarity index 77%
rename from src/Moq/Moq.Sdk/ValueMatcher.cs
rename to src/Moq.Sdk/ValueMatcher.cs
index f2bb26e1..e2927bef 100644
--- a/src/Moq/Moq.Sdk/ValueMatcher.cs
+++ b/src/Moq.Sdk/ValueMatcher.cs
@@ -8,14 +8,14 @@ namespace Moq.Sdk
///
public class ValueMatcher : IArgumentMatcher, IEquatable
{
- readonly Tuple value;
+ private readonly Tuple value;
///