@@ -10,11 +10,12 @@ open System.Threading.Tasks
1010open System.Threading
1111open System.Runtime .InteropServices
1212open System.Reflection
13+ open System.Text .RegularExpressions
1314
1415open Newtonsoft.Json .Linq
1516open Ionide.LanguageServerProtocol .Types
1617open Ionide.LanguageServerProtocol .Server
17- open System. Text . RegularExpressions
18+ open NUnit. Framework
1819
1920let indexJToken ( name : string ) ( jobj : option < JToken >) : option < JToken > =
2021 jobj |> Option.bind ( fun p -> p[ name] |> Option.ofObj)
@@ -602,7 +603,8 @@ let rec deleteDirectory (path: string) =
602603 Directory.Delete( path)
603604
604605
605- type FileController ( client : MailboxProcessor < ClientEvent >, projectDir : string , filename : string , sharedFixture : bool ) =
606+ type FileController
607+ ( client: MailboxProcessor< ClientEvent>, projectDir: string, filename: string, fixtureIsReadOnly: bool) =
606608 let mutable fileContents : option < string > = None
607609
608610 member __.FileName = filename
@@ -640,8 +642,8 @@ type FileController(client: MailboxProcessor<ClientEvent>, projectDir: string, f
640642 client.Post( SendServerRpcNotification( " textDocument/didOpen" , serialize didOpenParams))
641643
642644 member this.DidChange ( text : string ) =
643- if sharedFixture then
644- failwith " cannot invoke FileController.DidChange, this is a shared fixture!"
645+ if fixtureIsReadOnly then
646+ failwith " cannot invoke FileController.DidChange, this is a read-only fixture!"
645647
646648 let didChangeParams : DidChangeTextDocumentParams =
647649 { TextDocument = { Uri = this.Uri; Version = 2 }
@@ -668,13 +670,19 @@ type FileController(client: MailboxProcessor<ClientEvent>, projectDir: string, f
668670 tes |> Array.rev |> Array.fold applyTextEdit fileContents.Value
669671
670672
671- type ClientController ( client : MailboxProcessor < ClientEvent >, testDataDir : DirectoryInfo , sharedFixture : bool ) =
673+ type ClientController ( client : MailboxProcessor < ClientEvent >, fixtureName : string , fixtureIsReadOnly : bool ) =
672674 let mutable projectDir : string option = None
673675 let mutable solutionLoaded : bool = false
674676
675677 let logMessage m msg =
676678 client.Post( EmitLogMessage( DateTime.Now, ( sprintf " ClientActorController.%s " m), msg))
677679
680+ let testAssemblyLocationDir =
681+ Path.GetDirectoryName( Assembly.GetExecutingAssembly() .Location)
682+
683+ let sourceTestDataDir =
684+ DirectoryInfo( Path.Combine( testAssemblyLocationDir, " .." , " .." , " .." , " Fixtures" , fixtureName))
685+
678686 interface IDisposable with
679687 member __.Dispose () =
680688 if solutionLoaded then
@@ -697,16 +705,23 @@ type ClientController(client: MailboxProcessor<ClientEvent>, testDataDir: Direct
697705 deleteDirectory projectDir
698706 | _ -> ()
699707
708+ member __.FixtureName = fixtureName
709+ member __.FixtureIsReadOnly = fixtureIsReadOnly
700710 member __.ProjectDir : string = projectDir.Value
701711
702- member this.StartAndWaitForSolutionLoad () =
712+ member this.StartAndWaitForSolutionLoad ( clientProfile : ClientProfile ) =
713+ if not sourceTestDataDir.Exists then
714+ failwithf " ClientController.Prepare(): no such test data dir \" %s \" " sourceTestDataDir.FullName
715+
716+ client.Post( SetupWithProfile clientProfile)
717+
703718 if solutionLoaded then
704719 failwith " Solution has already been loaded for this ClientController!"
705720
706721 solutionLoaded <- true
707722
708723 let log = logMessage " StartInitializeAndWaitForSolutionLoad"
709- projectDir <- Some( prepareTempTestDirFrom testDataDir )
724+ projectDir <- Some( prepareTempTestDirFrom sourceTestDataDir )
710725
711726 log " sending ServerStartRequest"
712727 let state = client.PostAndReply( fun rc -> ServerStartRequest( projectDir.Value, rc))
@@ -857,57 +872,37 @@ type ClientController(client: MailboxProcessor<ClientEvent>, testDataDir: Direct
857872 failwithf " request to method \" %s \" has failed with error: %s " method ( string errorJToken)
858873
859874 member __.Open ( filename : string ) : FileController =
860- let file = new FileController( client, projectDir.Value, filename, sharedFixture )
875+ let file = new FileController( client, projectDir.Value, filename, fixtureIsReadOnly )
861876 file.Open()
862877 file
863878
864879
865- let setupServerClient ( clientProfile : ClientProfile ) ( testDataDirName : string ) ( sharedFixture : bool ) =
880+ let private activateClient ( clientProfile : ClientProfile ) ( fixtureName : string ) ( readOnlyFixture : bool ) =
866881 let initialState =
867882 { defaultClientState with
868883 LoggingEnabled = clientProfile.LoggingEnabled }
869884
870885 let clientActor = MailboxProcessor.Start( clientEventLoop initialState)
871- clientActor.Post( SetupWithProfile clientProfile)
872886
873- let testAssemblyLocationDir =
874- Path.GetDirectoryName( Assembly.GetExecutingAssembly() .Location)
887+ let client = new ClientController( clientActor, fixtureName, readOnlyFixture)
888+ client.StartAndWaitForSolutionLoad( clientProfile)
889+ client
875890
876- let actualTestDataDir =
877- DirectoryInfo( Path.Combine( testAssemblyLocationDir, " .." , " .." , " .." , testDataDirName))
878891
879- if not actualTestDataDir.Exists then
880- failwithf " setupServerClient: no such test data dir \" %s \" " actualTestDataDir.FullName
892+ let activeClientsSemaphore =
893+ new SemaphoreSlim ( Environment.ProcessorCount , Environment.ProcessorCount )
881894
882- new ClientController( clientActor, actualTestDataDir, sharedFixture)
895+
896+ let activateFixture fixtureName =
897+ activeClientsSemaphore.Wait()
898+
899+ try
900+ activateClient defaultClientProfile fixtureName false
901+ finally
902+ activeClientsSemaphore.Release() |> ignore
883903
884904
885905module TextEdit =
886906 let normalizeNewText ( s : TextEdit ) =
887907 { s with
888908 NewText = s.NewText.ReplaceLineEndings( " \n " ) }
889-
890- module Fixtures =
891- let private sharedFixtures = ConcurrentDictionary< string, Lazy< ClientController>>()
892-
893- let numCpus = Environment.ProcessorCount
894- let private setupSemaphore = new SemaphoreSlim( numCpus, numCpus)
895-
896- let private loadFixture sharedFixture fixtureName =
897- setupSemaphore.Wait()
898-
899- try
900- let projectDir = " Fixtures/" + fixtureName
901- let client = setupServerClient defaultClientProfile projectDir sharedFixture
902- client.StartAndWaitForSolutionLoad()
903- client
904- finally
905- setupSemaphore.Release() |> ignore
906-
907- let load fixtureName = loadFixture false fixtureName
908-
909- let getShared fixtureName : ClientController =
910- let lazyClient =
911- sharedFixtures.GetOrAdd( fixtureName, fun fixtureName -> lazy ( loadFixture true fixtureName))
912-
913- lazyClient.Force()
0 commit comments