Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a unit test that checks that the returned FSharpProjectOptions graph doesn't contain duplicates #159

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
90 changes: 83 additions & 7 deletions test/Ionide.ProjInfo.Tests/Tests.fs
Expand Up @@ -824,18 +824,12 @@ let testFCSmapManyProj toolsPath workspaceLoader (workspaceFactory: ToolsPath ->
| Some opts -> yield! allFCSProjects opts
| None -> () ]


let rec allP2P (po: FSharpProjectOptions) =
[ for reference in po.ReferencedProjects do
let opts = internalGetProjectOptions reference |> Option.get
yield reference.OutputFile, opts
yield! allP2P opts ]

let expectP2PKeyIsTargetPath (pos: Map<string, ProjectOptions>) fcsPo =
baronfel marked this conversation as resolved.
Show resolved Hide resolved
for (tar, fcsPO) in allP2P fcsPo do
let dpoPo = pos |> Map.find fcsPo.ProjectFileName
Expect.equal tar dpoPo.TargetPath (sprintf "p2p key is TargetPath, fsc projet options was '%A'" fcsPO)

let testDir = inDir fs "load_sample_fsc"
copyDirFromAssets fs ``sample3 Netsdk projs``.ProjDir testDir

Expand Down Expand Up @@ -866,14 +860,95 @@ let testFCSmapManyProj toolsPath workspaceLoader (workspaceFactory: ToolsPath ->
Expect.equal hasFSharpProjectRef true "Should have project reference to F# reference"
)

let countDistinctObjectsByReference<'a> (items : 'a seq) =
let set = HashSet(items |> Seq.map (fun i -> i :> obj), ReferenceEqualityComparer.Instance)
set.Count

let testFCSmapManyProjCheckCaching =
testCase |> withLog "When creating FCS options, caches them" (fun _ _ ->

let sdkInfo = ProjectLoader.getSdkInfo []

let template : ProjectOptions =
{ ProjectId = None
ProjectFileName = "Template"
TargetFramework = "TF"
SourceFiles = []
OtherOptions = []
ReferencedProjects = []
PackageReferences = []
LoadTime = DateTime.MinValue
TargetPath = "TP"
ProjectOutputType = ProjectOutputType.Library
ProjectSdkInfo = sdkInfo
Items = []
CustomProperties = [] }

let makeReference (options : ProjectOptions) =
{ RelativePath = options.ProjectFileName
ProjectFileName = options.ProjectFileName
TargetFramework = options.TargetFramework }

let makeProject (name : string) (referencedProjects : ProjectOptions list) =
{ template with
ProjectFileName = name
ReferencedProjects = referencedProjects |> List.map makeReference }

let projectsInLayers =
let layerCount = 4
let layerSize = 2
let layers =
[1..layerCount]
|> List.map (fun layer ->
[1..layerSize]
|> List.map (fun item -> makeProject $"layer{layer}_{item}.fsproj" [])
)
let first = layers[0]
let rest =
layers
|> List.pairwise
|> List.map (fun (previous, next) ->
next
|> List.map (fun p ->
{ p with
ReferencedProjects = previous |> List.map makeReference }
)
)
let layers = first :: rest

layers |> List.concat

let fcsOptions = FCS.mapManyOptions projectsInLayers

let rec findProjectOptionsTransitively (project : FSharpProjectOptions) =
project.ReferencedProjects
|> Array.toList
|> List.collect (fun reference ->
reference
|> internalGetProjectOptions
|> Option.map findProjectOptionsTransitively
|> Option.defaultValue []
)
|> List.append [project]

let findDistinctProjectOptionsTransitively (projects : FSharpProjectOptions seq) =
projects
|> Seq.collect findProjectOptionsTransitively
|> countDistinctObjectsByReference

let distinctOptionsCount = findDistinctProjectOptionsTransitively fcsOptions

Expect.equal distinctOptionsCount projectsInLayers.Length "Mapping should reuse instances of FSharpProjectOptions and only create one per project"
)

let testSample2WithBinLog toolsPath workspaceLoader (workspaceFactory: ToolsPath -> IWorkspaceLoader) =
testCase |> withLog (sprintf "can load sample2 with bin log - %s" workspaceLoader) (fun logger fs ->
let testDir = inDir fs "load_sample2_bin_log"
copyDirFromAssets fs ``sample2 NetSdk library``.ProjDir testDir

let projPath = testDir / (``sample2 NetSdk library``.ProjectFile)
let projDir = Path.GetDirectoryName projPath

dotnet fs [ "restore"; projPath ] |> checkExitCodeZero

let loader = workspaceFactory toolsPath
Expand Down Expand Up @@ -1289,6 +1364,7 @@ let tests toolsPath =
//FCS multi-project tests
testFCSmapManyProj toolsPath "WorkspaceLoader" WorkspaceLoader.Create
testFCSmapManyProj toolsPath "WorkspaceLoaderViaProjectGraph" WorkspaceLoaderViaProjectGraph.Create
testFCSmapManyProjCheckCaching
//ProjectSystem tests
testProjectSystem toolsPath "WorkspaceLoader" WorkspaceLoader.Create
testProjectSystem toolsPath "WorkspaceLoaderViaProjectGraph" WorkspaceLoaderViaProjectGraph.Create
Expand Down