Skip to content

Commit 7a3fbdb

Browse files
committed
add tests
1 parent 10d1bc5 commit 7a3fbdb

File tree

21 files changed

+780
-18
lines changed

21 files changed

+780
-18
lines changed

ReSharper.FSharp/src/FSharp.Common/src/Checker/FcsCheckerService.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,8 @@ type FcsCheckerService(lifetime: Lifetime, logger: ILogger, onSolutionCloseNotif
146146
|> Seq.iter x.InvalidateFcsProject
147147

148148
member x.InvalidateFcsProjects(solution: ISolution, isApplicable: IProject -> bool) =
149-
use lock = ReadLockCookie.Create()
150149
if checker.IsValueCreated then
150+
use lock = ReadLockCookie.Create()
151151
solution.GetAllProjects()
152152
|> Seq.filter isApplicable
153153
|> Seq.iter x.InvalidateFcsProject

ReSharper.FSharp/src/FSharp.Common/src/Shim/TypeProviders/ExtensionTypingProviderShim.fs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ open JetBrains.ProjectModel
1111
open JetBrains.ProjectModel.Tasks
1212
open JetBrains.Rd.Tasks
1313
open JetBrains.ReSharper.Feature.Services.Daemon
14+
open JetBrains.ReSharper.Plugins.FSharp
1415
open JetBrains.ReSharper.Plugins.FSharp.Checker
1516
open JetBrains.ReSharper.Plugins.FSharp.Settings
1617
open JetBrains.ReSharper.Plugins.FSharp.TypeProviders.Protocol
@@ -23,12 +24,12 @@ type IProxyExtensionTypingProvider =
2324

2425
abstract RuntimeVersion: unit -> string
2526
abstract DumpTypeProvidersProcess: unit -> string
27+
abstract TerminateConnection: unit -> unit
2628

2729
[<SolutionComponent>]
2830
type ExtensionTypingProviderShim(solution: ISolution, toolset: ISolutionToolset,
2931
experimentalFeatures: FSharpExperimentalFeaturesProvider,
3032
checkerService: FcsCheckerService, daemon: IDaemon, psiFiles: IPsiFiles,
31-
scheduler: ISolutionLoadTasksScheduler,
3233
typeProvidersLoadersFactory: TypeProvidersExternalProcessFactory) as this =
3334
let lifetime = solution.GetLifetime()
3435
let defaultShim = ExtensionTypingProvider
@@ -137,5 +138,4 @@ type ExtensionTypingProviderShim(solution: ISolution, toolset: ISolutionToolset,
137138

138139
$"{inProcessDump}\n\n{outOfProcessDump}"
139140

140-
interface IDisposable with
141-
member this.Dispose() = terminateConnection ()
141+
member this.TerminateConnection() = terminateConnection()

ReSharper.FSharp/src/FSharp.Common/src/Shim/TypeProviders/TypeProvidersManager.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
open System
44
open System.Collections.Concurrent
5+
open System.Collections.Generic
56
open System.Threading
67
open FSharp.Compiler.ExtensionTyping
78
open FSharp.Core.CompilerServices

ReSharper.FSharp/src/FSharp.TypeProviders.Host/src/TypeProvidersLoader.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@ public class TypeProvidersLoader : ITypeProvidersLoader
2626
private readonly ILogger myLogger;
2727
private readonly Dictionary<string, string> myShadowCopyMapping = new Dictionary<string, string>();
2828

29-
public TypeProvidersLoader(ILogger logger)
30-
{
31-
myLogger = logger;
32-
}
29+
public TypeProvidersLoader(ILogger logger) => myLogger = logger;
3330

3431
private readonly FSharpFunc<TypeProviderError, Unit> myLogError =
3532
FSharpFunc<TypeProviderError, Unit>.FromConverter(e =>
@@ -56,7 +53,8 @@ public IEnumerable<ITypeProvider> InstantiateTypeProvidersOfAssembly(
5653
var systemRuntimeAssemblyVersion = Version.Parse(parameters.SystemRuntimeAssemblyVersion);
5754
var compilerToolsPath = ListModule.OfSeq(parameters.CompilerToolsPath);
5855

59-
// todo: comment
56+
// We assume that to check the type provider, its developer will reference the type provider design-time assembly in the project.
57+
// In this case, RunTimeAssemblyFileName will be the same as DesignTimeAssemblyNameString.
6058
var designTimeAssembly = parameters.ShadowCopyDesignTimeAssembly
6159
? GetAssemblyShadowCopy(parameters.RunTimeAssemblyFileName)
6260
: parameters.DesignTimeAssemblyNameString;

ReSharper.FSharp/test/src/FSharp.Tests.Host/FSharpTestHost.fs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ type FSharpTestHost(solution: ISolution, sourceCache: FSharpSourceCache, itemsCo
5959
CultureInfo.CurrentUICulture <- newCulture
6060
currentCulture.Name
6161

62+
let killTypeProvidersProcess _ =
63+
solution.GetComponent<IProxyExtensionTypingProvider>().TerminateConnection()
64+
JetBrains.Core.Unit.Instance
65+
6266
do
6367
let fsTestHost = solution.RdFSharpModel().FsharpTestHost
6468

@@ -69,3 +73,4 @@ type FSharpTestHost(solution: ISolution, sourceCache: FSharpSourceCache, itemsCo
6973
fsTestHost.TypeProvidersRuntimeVersion.Set(typeProvidersRuntimeVersion)
7074
fsTestHost.DumpTypeProvidersProcess.Set(dumpTypeProvidersProcess)
7175
fsTestHost.GetCultureInfoAndSetNew.Set(getCultureInfoAndSetNew)
76+
fsTestHost.KillTypeProvidersProcess.Set(killTypeProvidersProcess)

rider-fsharp/protocol/src/kotlin/model/RdFSharpModel.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ object RdFSharpModel : Ext(SolutionModel.Solution) {
5151
call("dumpSingleProjectLocalReferences", void, immutableList(string))
5252
call("typeProvidersRuntimeVersion", void, string.nullable)
5353
call("dumpTypeProvidersProcess", void, string)
54+
call("killTypeProvidersProcess", void, void)
5455
}
5556

5657
private val RdFSharpTypeProvidersHost = aggregatedef("RdFSharpTypeProvidersHost") {

rider-fsharp/src/main/resources/META-INF/plugin.xml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,7 @@
105105
<action id="SendFsiRefs" class="com.jetbrains.rider.plugins.fsharp.services.fsi.SendProjectReferencesToFsiAction" icon="/icons/fsharpConsole.png">
106106
<add-to-group group-id="SolutionExplorerPopupMenu.Repl"/>
107107
</action>
108-
<action id="Rider.Plugins.FSharp.RestartTypeProviders" class="com.jetbrains.rider.plugins.fsharp.services.typeProviders.RestartTypeProvidersAction" icon="/icons/Fsharp.svg">
109-
<add-to-group group-id="ToolsMenu" anchor="after" relative-to-action="Rider.Plugins.FSharp.FsiGroup"/>
110-
</action>
108+
<action id="Rider.Plugins.FSharp.RestartTypeProviders" class="com.jetbrains.rider.plugins.fsharp.services.typeProviders.RestartTypeProvidersAction" icon="/icons/Fsharp.svg"/>
111109
</actions>
112110

113111
<project-components>

rider-fsharp/src/test/kotlin/Extensions.kt

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,19 @@ fun com.intellij.openapi.editor.Editor.dumpTypeProviders(stream: PrintStream) {
1717
}
1818
}
1919

20-
fun withSetting(project: Project, setting: String, function: () -> Unit) {
21-
TestHost.getInstance(project.protocolHost).setSetting(setting, "true")
20+
fun withSettings(project: Project, settings: List<String>, function: () -> Unit) {
21+
settings.forEach { TestHost.getInstance(project.protocolHost).setSetting(it, "true") }
2222
try {
2323
function()
2424
} finally {
25-
TestHost.getInstance(project.protocolHost).setSetting(setting, "false")
25+
settings.forEach { TestHost.getInstance(project.protocolHost).setSetting(it, "false") }
2626
}
2727
}
2828

29-
fun BaseTestWithSolution.withTypeProviders(function: () -> Unit) {
30-
withSetting(project, "FSharp/FSharpOptions/FSharpExperimentalFeatures/OutOfProcessTypeProviders/@EntryValue") {
29+
fun BaseTestWithSolution.withTypeProviders(shadowCopyMode: Boolean = false, function: () -> Unit) {
30+
val settings = mutableListOf("FSharp/FSharpOptions/FSharpExperimentalFeatures/OutOfProcessTypeProviders/@EntryValue")
31+
if (shadowCopyMode) settings.add("FSharp/FSharpOptions/FSharpExperimentalFeatures/HostTypeProvidersFromTempFolder/@EntryValue")
32+
withSettings(project, settings) {
3133
try {
3234
function()
3335
} finally {
@@ -40,7 +42,7 @@ fun BaseTestWithSolution.withTypeProviders(function: () -> Unit) {
4042
}
4143

4244
fun withEditorConfig(project: Project, function: () -> Unit) {
43-
withSetting(project, "CodeStyle/EditorConfig/EnableEditorConfigSupport", function)
45+
withSettings(project, listOf("CodeStyle/EditorConfig/EnableEditorConfigSupport"), function)
4446
}
4547

4648
fun withCultureInfo(project: Project, culture: String, function: () -> Unit) {
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package typeProviders
2+
3+
import com.intellij.execution.configurations.GeneralCommandLine
4+
import com.jetbrains.rd.platform.util.lifetime
5+
import com.jetbrains.rdclient.testFramework.waitForDaemon
6+
import com.jetbrains.rdclient.util.idea.waitAndPump
7+
import com.jetbrains.rider.NetCoreRuntime
8+
import com.jetbrains.rider.daemon.util.hasErrors
9+
import com.jetbrains.rider.plugins.fsharp.rdFSharpModel
10+
import com.jetbrains.rider.projectView.solution
11+
import com.jetbrains.rider.projectView.solutionDirectoryPath
12+
import com.jetbrains.rider.test.annotations.TestEnvironment
13+
import com.jetbrains.rider.test.asserts.*
14+
import com.jetbrains.rider.test.base.BaseTestWithSolution
15+
import com.jetbrains.rider.test.enums.CoreVersion
16+
import com.jetbrains.rider.test.enums.ToolsetVersion
17+
import com.jetbrains.rider.test.scriptingApi.*
18+
import org.testng.annotations.Test
19+
import withTypeProviders
20+
import java.time.Duration
21+
22+
@Test
23+
@TestEnvironment(toolset = ToolsetVersion.TOOLSET_16, coreVersion = CoreVersion.DOT_NET_CORE_3_1)
24+
class TypeProvidersActionsTest : BaseTestWithSolution() {
25+
override fun getSolutionDirectoryName() = "TypeProviderLibrary"
26+
override val restoreNuGetPackages = true
27+
private val sourceFile = "TypeProviderLibrary/Caches.fs"
28+
private val rdFcsHost get() = project.solution.rdFSharpModel.fsharpTestHost
29+
private val restartTypeProvidersAction = "Rider.Plugins.FSharp.RestartTypeProviders"
30+
31+
private fun waitForTypeProviders() {
32+
waitAndPump(project.lifetime, { rdFcsHost.typeProvidersRuntimeVersion.sync(Unit) != null }, Duration.ofSeconds(60000))
33+
}
34+
35+
@Test
36+
fun restartTypeProviders() {
37+
withTypeProviders {
38+
withOpenedEditor(project, sourceFile) {
39+
waitForDaemon()
40+
rdFcsHost.typeProvidersRuntimeVersion.sync(Unit).shouldNotBeNull()
41+
markupAdapter.hasErrors.shouldBeFalse()
42+
43+
rdFcsHost.killTypeProvidersProcess.sync(Unit)
44+
rdFcsHost.typeProvidersRuntimeVersion.sync(Unit).shouldBeNull()
45+
46+
callAction(restartTypeProvidersAction)
47+
waitForTypeProviders()
48+
waitForDaemon()
49+
markupAdapter.hasErrors.shouldBeFalse()
50+
}
51+
}
52+
}
53+
54+
@Test
55+
@TestEnvironment(solution = "LemonadeProvider")
56+
fun rebuildTypeProvider() {
57+
val lemonadeProviderProject = "${project.solutionDirectoryPath}/LemonadeProvider.DesignTime/LemonadeProvider.DesignTime.fsproj"
58+
val sourceFileToCheck = "LemonadeProviderConsumer/Library.fs"
59+
60+
withTypeProviders(true) {
61+
62+
GeneralCommandLine()
63+
.withWorkDirectory(project.solutionDirectoryPath.toString())
64+
.withExePath(NetCoreRuntime.cliPath.value)
65+
.withParameters("tool", "restore")
66+
.createProcess()
67+
.waitFor()
68+
.shouldBe(0)
69+
70+
buildSelectedProjectsWithReSharperBuild(listOf(lemonadeProviderProject), ignoreReferencesResolve = true)
71+
72+
withOpenedEditor(project, sourceFileToCheck) {
73+
waitForDaemon()
74+
rdFcsHost.typeProvidersRuntimeVersion.sync(Unit).shouldNotBeNull()
75+
markupAdapter.hasErrors.shouldBeFalse()
76+
}
77+
78+
withOpenedEditor(project, "LemonadeProvider.DesignTime/LemonadeProvider.DesignTime.fs") {
79+
//change "Drink" -> "Drink1"
80+
typeFromOffset("1", 496)
81+
}
82+
83+
buildSelectedProjectsWithReSharperBuild(project, listOf(lemonadeProviderProject))
84+
85+
withOpenedEditor(project, sourceFileToCheck) {
86+
callAction(restartTypeProvidersAction)
87+
waitForTypeProviders()
88+
waitForDaemon()
89+
markupAdapter.hasErrors.shouldBeTrue()
90+
91+
//change "Drink" -> "Drink1"
92+
typeFromOffset("1", 86)
93+
waitForDaemon()
94+
markupAdapter.hasErrors.shouldBeFalse()
95+
}
96+
}
97+
}
98+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"version": 1,
3+
"isRoot": true,
4+
"tools": {
5+
"paket": {
6+
"version": "5.241.5",
7+
"commands": [
8+
"paket"
9+
]
10+
}
11+
}
12+
}

0 commit comments

Comments
 (0)