Skip to content

Commit 3a66620

Browse files
committed
Merge pull request #24 from eiriktsarpalis/master
Add fsc unit tests
2 parents de56d84 + eb0d73c commit 3a66620

File tree

5 files changed

+158
-21
lines changed

5 files changed

+158
-21
lines changed

samples/EditorService/EditorService.fsproj

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
</PropertyGroup>
3939
<ItemGroup>
4040
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
41-
<Private>True</Private>
41+
<Private>False</Private>
4242
</Reference>
4343
<Reference Include="mscorlib" />
4444
<Reference Include="System" />
@@ -59,12 +59,12 @@
5959
<PropertyGroup>
6060
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
6161
</PropertyGroup>
62-
<PropertyGroup>
63-
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
64-
</PropertyGroup>
65-
<PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0' OR '$(VisualStudioVersion)' == '11.0'">
66-
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
67-
</PropertyGroup>
62+
<PropertyGroup>
63+
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
64+
</PropertyGroup>
65+
<PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0' OR '$(VisualStudioVersion)' == '11.0'">
66+
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
67+
</PropertyGroup>
6868
<Import Project="$(FSharpTargetsPath)" Condition="Exists('$(FSharpTargetsPath)')" />
6969
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
7070
Other similar extension points exist, see Microsoft.Common.targets.

samples/Tokenizer/Tokenizer.fsproj

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
</PropertyGroup>
3939
<ItemGroup>
4040
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
41-
<Private>True</Private>
41+
<Private>False</Private>
4242
</Reference>
4343
<Reference Include="mscorlib" />
4444
<Reference Include="System" />
@@ -59,12 +59,12 @@
5959
<PropertyGroup>
6060
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
6161
</PropertyGroup>
62-
<PropertyGroup>
63-
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
64-
</PropertyGroup>
65-
<PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0' OR '$(VisualStudioVersion)' == '11.0'">
66-
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
67-
</PropertyGroup>
62+
<PropertyGroup>
63+
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
64+
</PropertyGroup>
65+
<PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0' OR '$(VisualStudioVersion)' == '11.0'">
66+
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
67+
</PropertyGroup>
6868
<Import Project="$(FSharpTargetsPath)" Condition="Exists('$(FSharpTargetsPath)')" />
6969
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
7070
Other similar extension points exist, see Microsoft.Common.targets.

samples/UntypedTree/UntypedTree.fsproj

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
</PropertyGroup>
3939
<ItemGroup>
4040
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
41-
<Private>True</Private>
41+
<Private>False</Private>
4242
</Reference>
4343
<Reference Include="mscorlib" />
4444
<Reference Include="System" />
@@ -59,12 +59,12 @@
5959
<PropertyGroup>
6060
<MinimumVisualStudioVersion Condition="'$(MinimumVisualStudioVersion)' == ''">11</MinimumVisualStudioVersion>
6161
</PropertyGroup>
62-
<PropertyGroup>
63-
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
64-
</PropertyGroup>
65-
<PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0' OR '$(VisualStudioVersion)' == '11.0'">
66-
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
67-
</PropertyGroup>
62+
<PropertyGroup>
63+
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\FSharp\Microsoft.FSharp.Targets</FSharpTargetsPath>
64+
</PropertyGroup>
65+
<PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0' OR '$(VisualStudioVersion)' == '11.0'">
66+
<FSharpTargetsPath>$(MSBuildExtensionsPath32)\..\Microsoft SDKs\F#\3.0\Framework\v4.0\Microsoft.FSharp.Targets</FSharpTargetsPath>
67+
</PropertyGroup>
6868
<Import Project="$(FSharpTargetsPath)" Condition="Exists('$(FSharpTargetsPath)')" />
6969
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
7070
Other similar extension points exist, see Microsoft.Common.targets.

tests/service/FSharp.Compiler.Service.Tests.fsproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
<Compile Include="Common.fs" />
4949
<Compile Include="EditorTests.fs" />
5050
<Compile Include="FsiTests.fs" />
51+
<Compile Include="FscTests.fs" />
5152
<Compile Include="TokenizerTests.fs" />
5253
<Compile Include="FileSystemTests.fs" />
5354
<Compile Include="ProjectAnalysisTests.fs" />
@@ -64,6 +65,7 @@
6465
<Reference Include="FSharp.Core, Version=$(TargetFSharpCoreVersion), Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
6566
<Private>False</Private>
6667
</Reference>
68+
<Reference Include="Microsoft.Build.Utilities.v4.0" />
6769
<Reference Include="mscorlib" />
6870
<Reference Include="nunit.framework">
6971
<HintPath>..\..\packages\NUnit.2.6.3\lib\nunit.framework.dll</HintPath>

tests/service/FscTests.fs

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
module FSharp.Compiler.Service.Tests.FscTests
2+
3+
open System
4+
open System.Diagnostics
5+
open System.IO
6+
7+
open Microsoft.Build.Utilities
8+
open Microsoft.FSharp.Compiler
9+
10+
open NUnit.Framework
11+
12+
exception VerificationException of (*assembly:*)string * (*errorCode:*)int * (*output:*)string
13+
with
14+
override e.Message = sprintf "Verification of '%s' failed with code %d." e.Data0 e.Data1
15+
16+
exception CompilationError of (*assembly:*)string * (*errorCode:*)int * (*info:*)ErrorInfo []
17+
with
18+
override e.Message = sprintf "Compilation of '%s' failed with code %d (%A)" e.Data0 e.Data1 e.Data2
19+
20+
type PEVerifier () =
21+
22+
static let expectedExitCode = 0
23+
24+
let runsOnMono = try System.Type.GetType("Mono.Runtime") <> null with _ -> false
25+
let verifierPath, switches =
26+
if runsOnMono then
27+
"pedump", "--verify all"
28+
else
29+
let path = ToolLocationHelper.GetPathToDotNetFrameworkSdkFile("peverify.exe", TargetDotNetFrameworkVersion.VersionLatest)
30+
path, "/UNIQUE /IL /NOLOGO"
31+
32+
static let execute (fileName : string, arguments : string) =
33+
let psi = new ProcessStartInfo(fileName, arguments)
34+
psi.UseShellExecute <- false
35+
psi.ErrorDialog <- false
36+
psi.CreateNoWindow <- true
37+
psi.RedirectStandardOutput <- true
38+
psi.RedirectStandardError <- true
39+
40+
use proc = Process.Start(psi)
41+
let stdOut = proc.StandardOutput.ReadToEnd()
42+
let stdErr = proc.StandardError.ReadToEnd()
43+
while not proc.HasExited do ()
44+
proc.ExitCode, stdOut, stdErr
45+
46+
member __.Verify(assemblyPath : string) =
47+
let id,stdOut,stdErr = execute(verifierPath, sprintf "%s \"%s\"" switches assemblyPath)
48+
if id = expectedExitCode && String.IsNullOrWhiteSpace stdErr then ()
49+
else
50+
raise <| VerificationException(assemblyPath, id, stdOut + "\n" + stdErr)
51+
52+
53+
type DebugMode =
54+
| Off
55+
| PdbOnly
56+
| Full
57+
58+
let compileAndVerify isDll debugMode (assemblyName : string) (code : string) (dependencies : string list) =
59+
let scs = new Microsoft.FSharp.Compiler.SimpleSourceCodeServices.SimpleSourceCodeServices()
60+
let verifier = new PEVerifier ()
61+
let tmp = Path.GetTempPath()
62+
let sourceFile = Path.Combine(tmp, assemblyName + ".fs")
63+
let outFile = Path.Combine(tmp, assemblyName + if isDll then ".dll" else ".exe")
64+
let pdbFile = Path.Combine(tmp, assemblyName + ".pdb")
65+
do File.WriteAllText(sourceFile, code)
66+
let args =
67+
[|
68+
// fsc parser skips the first argument by default;
69+
// perhaps this shouldn't happen in library code.
70+
yield "fsc.exe"
71+
72+
if isDll then yield "--target:library"
73+
74+
match debugMode with
75+
| Off -> () // might need to include some switches here
76+
| PdbOnly ->
77+
yield "--debug:pdbonly"
78+
yield sprintf "--pdb:%s" pdbFile
79+
| Full ->
80+
yield "--debug:full"
81+
yield sprintf "--pdb:%s" pdbFile
82+
83+
for d in dependencies do
84+
yield sprintf "-r:%s" d
85+
86+
yield sprintf "--out:%s" outFile
87+
88+
yield sourceFile
89+
|]
90+
91+
let errorInfo, id = scs.Compile args
92+
if id <> 0 then raise <| CompilationError(assemblyName, id, errorInfo)
93+
verifier.Verify outFile
94+
outFile
95+
96+
97+
[<Test>]
98+
let ``1. PEVerifier sanity check`` () =
99+
let verifier = new PEVerifier()
100+
101+
let fscorlib = typeof<int option>.Assembly
102+
verifier.Verify fscorlib.Location
103+
104+
let nonAssembly = Path.Combine(Directory.GetCurrentDirectory(), typeof<PEVerifier>.Assembly.GetName().Name + ".pdb")
105+
Assert.Throws<VerificationException>(fun () -> verifier.Verify nonAssembly |> ignore) |> ignore
106+
107+
108+
[<Test>]
109+
let ``2. Simple FSC library test`` () =
110+
let code = """
111+
module Foo
112+
113+
let f x = (x,x)
114+
115+
type Foo = class end
116+
117+
exception E of int * string
118+
"""
119+
120+
compileAndVerify true PdbOnly "Foo" code [] |> ignore
121+
122+
[<Test>]
123+
let ``3. Simple FSC executable test`` () =
124+
let code = """
125+
module Bar
126+
127+
[<EntryPoint>]
128+
let main _ = printfn "Hello, World!" ; 42
129+
130+
"""
131+
let outFile = compileAndVerify false PdbOnly "Bar" code []
132+
133+
use proc = Process.Start(outFile, "")
134+
while not proc.HasExited do ()
135+
Assert.AreEqual(proc.ExitCode, 42)

0 commit comments

Comments
 (0)