diff --git a/packages.config b/packages.config
index b54a7653b29..1c13c60c937 100644
--- a/packages.config
+++ b/packages.config
@@ -3,4 +3,6 @@
+
+
\ No newline at end of file
diff --git a/src/fsharp.sln b/src/fsharp.sln
index 0e9eb059b59..2d535cee41d 100644
--- a/src/fsharp.sln
+++ b/src/fsharp.sln
@@ -32,6 +32,9 @@ EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsiAnyCPU", "fsharp\fsiAnyCpu\FsiAnyCPU.fsproj", "{8B3E283D-B5FE-4055-9D80-7E3A32F3967B}"
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Compiler.Unittests", "fsharp\FSharp.Compiler.Unittests\FSharp.Compiler.Unittests.fsproj", "{A8D9641A-9170-4CF4-8FE0-6DB8C134E1B5}"
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{E49B77EA-64DE-451A-A5E6-A6632FC1F03C}"
+EndProject
+Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharp.Tests", "..\tests\fsharp\FSharp.Tests.fsproj", "{C163E892-5BF7-4B59-AA99-B0E8079C67C4}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -81,8 +84,16 @@ Global
{A8D9641A-9170-4CF4-8FE0-6DB8C134E1B5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A8D9641A-9170-4CF4-8FE0-6DB8C134E1B5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A8D9641A-9170-4CF4-8FE0-6DB8C134E1B5}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C163E892-5BF7-4B59-AA99-B0E8079C67C4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C163E892-5BF7-4B59-AA99-B0E8079C67C4}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C163E892-5BF7-4B59-AA99-B0E8079C67C4}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C163E892-5BF7-4B59-AA99-B0E8079C67C4}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {88E2D422-6852-46E3-A740-83E391DC7973} = {E49B77EA-64DE-451A-A5E6-A6632FC1F03C}
+ {C163E892-5BF7-4B59-AA99-B0E8079C67C4} = {E49B77EA-64DE-451A-A5E6-A6632FC1F03C}
+ EndGlobalSection
EndGlobal
diff --git a/src/update.fs b/src/update.fs
new file mode 100644
index 00000000000..9ba090f5bc9
--- /dev/null
+++ b/src/update.fs
@@ -0,0 +1,186 @@
+
+module UpdateCmd
+
+open System.IO
+open NUnit.Framework
+open Microsoft.Win32
+
+open PlatformHelpers
+open FSharpTestSuiteTypes
+
+type Configuration =
+ | DEBUG
+ | RELEASE
+ override this.ToString() =
+ match this with
+ | DEBUG -> "Debug"
+ | RELEASE -> "Release"
+
+type updateCmdArgs =
+ { Configuration : Configuration
+ Ngen : bool }
+
+let private regQuery = WindowsPlatform.regQuery
+
+let private checkResult result =
+ match result with
+ | CmdResult.ErrorLevel err -> let x = err, (sprintf "ERRORLEVEL %d" err) in Failure (RunError.ProcessExecError x)
+ | CmdResult.Success -> Success ()
+
+let updateCmd envVars args = processor {
+ // @echo off
+ // setlocal
+ ignore "useless"
+
+ // if /i "%1" == "debug" goto :ok
+ // if /i "%1" == "release" goto :ok
+ ignore "already validated input"
+
+ // echo GACs built binaries, adds required strong name verification skipping, and optionally NGens built binaries
+ // echo Usage:
+ // echo update.cmd debug [-ngen]
+ // echo update.cmd release [-ngen]
+ // exit /b 1
+ ignore "useless help"
+
+ //:ok
+ let env k () = match envVars |> Map.tryFind k with None -> Failure (sprintf "environment variable '%s' not found" k) | Some x -> Success x
+ let ``~dp0`` = __SOURCE_DIRECTORY__
+ let exec exe args =
+ log "%s %s" exe args
+ use toLog = redirectToLog ()
+ Process.exec { RedirectError = Some toLog.Post; RedirectOutput = Some toLog.Post; RedirectInput = None } ``~dp0`` envVars exe args
+
+ // set BINDIR=%~dp0..\%1\net40\bin
+ let! binDir = env "FSCBINPATH"
+
+ // if /i "%PROCESSOR_ARCHITECTURE%"=="x86" set X86_PROGRAMFILES=%ProgramFiles%
+ // if /I "%PROCESSOR_ARCHITECTURE%"=="AMD64" set X86_PROGRAMFILES=%ProgramFiles(x86)%
+ let processorArchitecture = WindowsPlatform.processorArchitecture envVars
+ let x86_ProgramFiles = WindowsPlatform.x86ProgramFilesDirectory envVars processorArchitecture
+
+ let! windir = env "windir"
+
+ let REGEXE32BIT path value =
+ let hklm32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32)
+ match hklm32 |> regQuery path value with
+ | Some (:? string as d) -> Some d
+ | Some _ | None -> None
+
+ let allWINSDKNETFXTOOLS = seq {
+ // FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\NETFXSDK\4.6\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B
+ yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\NETFXSDK\4.6\WinSDK-NetFx40Tools" "InstallationFolder"
+ // if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v8.1A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B
+ yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\Windows\v8.1A\WinSDK-NetFx40Tools" "InstallationFolder"
+ // if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v8.0A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B
+ yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\Windows\v8.0A\WinSDK-NetFx40Tools" "InstallationFolder"
+ // if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B
+ yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx40Tools" "InstallationFolder"
+ // if "%WINSDKNETFXTOOLS%"=="" FOR /F "tokens=2* delims= " %%A IN ('%REGEXE32BIT% QUERY "HKLM\Software\Microsoft\Microsoft SDKs\Windows\v7.0A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET WINSDKNETFXTOOLS=%%B
+ yield REGEXE32BIT @"Software\Microsoft\Microsoft SDKs\Windows\v7.0A\WinSDK-NetFx40Tools" "InstallationFolder"
+ }
+
+ let WINSDKNETFXTOOLS = match allWINSDKNETFXTOOLS |> Seq.tryPick id with Some sdk -> sdk | None -> ""
+
+ // set GACUTIL="%WINSDKNETFXTOOLS%gacutil.exe"
+ let GACUTIL = WINSDKNETFXTOOLS/"gacutil.exe"
+ // set SN32="%WINSDKNETFXTOOLS%sn.exe"
+ let SN32 = WINSDKNETFXTOOLS/"sn.exe"
+ // set SN64="%WINSDKNETFXTOOLS%x64\sn.exe"
+ let SN64 = WINSDKNETFXTOOLS/"x64"/"sn.exe"
+ // set NGEN32=%windir%\Microsoft.NET\Framework\v4.0.30319\ngen.exe
+ let NGEN32 = windir/"Microsoft.NET"/"Framework"/"v4.0.30319"/"ngen.exe"
+ // set NGEN64=%windir%\Microsoft.NET\Framework64\v4.0.30319\ngen.exe
+ let NGEN64 = windir/"Microsoft.NET"/"Framework64"/"v4.0.30319"/"ngen.exe"
+
+ let checkResult = function CmdResult.ErrorLevel err -> Failure (sprintf "ERRORLEVEL %d" err) | CmdResult.Success -> Success ()
+
+ let gacutil flags = Commands.gacutil exec GACUTIL flags >> checkResult
+ let ngen32 = Commands.ngen exec NGEN32 >> checkResult
+ let ngen64 = Commands.ngen exec NGEN64 >> checkResult
+ let sn32 = exec SN32 >> checkResult
+ let sn64 = exec SN32 >> checkResult
+
+ // rem Disable strong-name validation for F# binaries built from open source that are signed with the microsoft key
+ // %SN32% -Vr FSharp.Core,b03f5f7f11d50a3a
+ // %SN32% -Vr FSharp.Build,b03f5f7f11d50a3a
+ // %SN32% -Vr FSharp.Compiler.Interactive.Settings,b03f5f7f11d50a3a
+ // %SN32% -Vr FSharp.Compiler.Hosted,b03f5f7f11d50a3a
+ // %SN32% -Vr FSharp.Compiler,b03f5f7f11d50a3a
+ // %SN32% -Vr FSharp.Compiler.Server.Shared,b03f5f7f11d50a3a
+ // %SN32% -Vr FSharp.Editor,b03f5f7f11d50a3a
+ // %SN32% -Vr FSharp.LanguageService,b03f5f7f11d50a3a
+ // %SN32% -Vr FSharp.LanguageService.Base,b03f5f7f11d50a3a
+ // %SN32% -Vr FSharp.LanguageService.Compiler,b03f5f7f11d50a3a
+ // %SN32% -Vr FSharp.ProjectSystem.Base,b03f5f7f11d50a3a
+ // %SN32% -Vr FSharp.ProjectSystem.FSharp,b03f5f7f11d50a3a
+ // %SN32% -Vr FSharp.ProjectSystem.PropertyPages,b03f5f7f11d50a3a
+ // %SN32% -Vr FSharp.VS.FSI,b03f5f7f11d50a3a
+ // %SN32% -Vr Unittests,b03f5f7f11d50a3a
+ // %SN32% -Vr Salsa,b03f5f7f11d50a3a
+
+ let strongName (snExe: string -> Result<_,_>) = processor {
+ let all =
+ [ "FSharp.Core";
+ "FSharp.Build";
+ "FSharp.Compiler.Interactive.Settings";"FSharp.Compiler.Hosted";
+ "FSharp.Compiler";"FSharp.Compiler.Server.Shared";
+ "FSharp.Editor";
+ "FSharp.LanguageService";"FSharp.LanguageService.Base";"FSharp.LanguageService.Compiler";
+ "FSharp.ProjectSystem.Base";"FSharp.ProjectSystem.FSharp";"FSharp.ProjectSystem.PropertyPages";
+ "FSharp.VS.FSI";
+ "Unittests";
+ "Salsa" ]
+ for a in all do
+ do! snExe (sprintf " -Vr %s,b03f5f7f11d50a3a" a)
+ }
+
+ do! strongName sn32
+
+ //if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
+ do! if processorArchitecture = AMD64 then
+ // %SN64% -Vr FSharp.Core,b03f5f7f11d50a3a
+ // %SN64% -Vr FSharp.Build,b03f5f7f11d50a3a
+ // %SN64% -Vr FSharp.Compiler.Interactive.Settings,b03f5f7f11d50a3a
+ // %SN64% -Vr FSharp.Compiler.Hosted,b03f5f7f11d50a3a
+ // %SN64% -Vr FSharp.Compiler,b03f5f7f11d50a3a
+ // %SN64% -Vr FSharp.Compiler.Server.Shared,b03f5f7f11d50a3a
+ // %SN64% -Vr FSharp.Editor,b03f5f7f11d50a3a
+ // %SN64% -Vr FSharp.LanguageService,b03f5f7f11d50a3a
+ // %SN64% -Vr FSharp.LanguageService.Base,b03f5f7f11d50a3a
+ // %SN64% -Vr FSharp.LanguageService.Compiler,b03f5f7f11d50a3a
+ // %SN64% -Vr FSharp.ProjectSystem.Base,b03f5f7f11d50a3a
+ // %SN64% -Vr FSharp.ProjectSystem.FSharp,b03f5f7f11d50a3a
+ // %SN64% -Vr FSharp.ProjectSystem.PropertyPages,b03f5f7f11d50a3a
+ // %SN64% -Vr FSharp.VS.FSI,b03f5f7f11d50a3a
+ // %SN64% -Vr Unittests,b03f5f7f11d50a3a
+ // %SN64% -Vr Salsa,b03f5f7f11d50a3a
+ strongName sn64
+ else
+ (fun () -> Success ())
+ //)
+
+ // rem Only GACing FSharp.Core for now
+ // %GACUTIL% /if %BINDIR%\FSharp.Core.dll
+ do! gacutil "/if" (binDir/"FSharp.Core.dll")
+
+ // rem NGen fsc, fsi, fsiAnyCpu, and FSharp.Build.dll
+ // if /i not "%2"=="-ngen" goto :donengen
+
+ if args.Ngen then
+ // "%NGEN32%" install "%BINDIR%\fsc.exe" /queue:1
+ // "%NGEN32%" install "%BINDIR%\fsi.exe" /queue:1
+ // "%NGEN32%" install "%BINDIR%\FSharp.Build.dll" /queue:1
+ // "%NGEN32%" executeQueuedItems 1
+ do! ngen32 [binDir/"fsc.exe"; binDir/"fsi.exe"; binDir/"FSharp.Build.dll"]
+
+ // if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
+ if processorArchitecture = AMD64 then
+ // "%NGEN64%" install "%BINDIR%\fsiAnyCpu.exe" /queue:1
+ // "%NGEN64%" install "%BINDIR%\FSharp.Build.dll" /queue:1
+ // "%NGEN64%" executeQueuedItems 1
+ do! ngen64 [binDir/"fsiAnyCpu.exe"; binDir/"FSharp.Build.dll"]
+ // )
+ //:donengen
+
+ }
diff --git a/tests/RunTests.cmd b/tests/RunTests.cmd
index f098c3abc7f..d2ffda1675a 100644
--- a/tests/RunTests.cmd
+++ b/tests/RunTests.cmd
@@ -20,21 +20,35 @@ if not exist "%~dp0%..\packages\NUnit.Runners.2.6.4\tools\" (
rem "ttags" indicates what test areas will be run, based on the tags in the test.lst files
set TTAGS_ARG=
+SET TTAGS=
set _tmp=%3
-if not '%_tmp%' == '' set TTAGS_ARG=-ttags:%_tmp:"=%
+if not '%_tmp%' == '' (
+ set TTAGS_ARG=-ttags:%_tmp:"=%
+ set TTAGS=%_tmp:"=%
+)
rem "nottags" indicates which test areas/test cases will NOT be run, based on the tags in the test.lst and env.lst files
set NO_TTAGS_ARG=-nottags:ReqPP,NOOPEN
+set NO_TTAGS=ReqPP,NOOPEN
set _tmp=%4
-if not '%_tmp%' == '' set NO_TTAGS_ARG=-nottags:ReqPP,NOOPEN,%_tmp:"=%
+if not '%_tmp%' == '' (
+ set NO_TTAGS_ARG=-nottags:ReqPP,NOOPEN,%_tmp:"=%
+ set NO_TTAGS=ReqPP,NOOPEN,%_tmp:"=%
+)
-if /I "%APPVEYOR_CI%" == "1" (set NO_TTAGS_ARG=%NO_TTAGS_ARG%,NO_CI)
+if /I "%APPVEYOR_CI%" == "1" (
+ set NO_TTAGS_ARG=%NO_TTAGS_ARG%,NO_CI
+ set NO_TTAGS=%NO_TTAGS%,NO_CI
+)
set PARALLEL_ARG=-procs:%NUMBER_OF_PROCESSORS%
rem This can be set to 1 to reduce the number of permutations used and avoid some of the extra-time-consuming tests
-set REDUCED_RUNTIME=1
-if "%REDUCED_RUNTIME%" == "1" set NO_TTAGS_ARG=%NO_TTAGS_ARG%,Expensive
+set REDUCED_RUNTIME=0
+if "%REDUCED_RUNTIME%" == "1" (
+ set NO_TTAGS_ARG=%NO_TTAGS_ARG%,Expensive
+ set NO_TTAGS=%NO_TTAGS%,Expensive
+)
rem Set this to 1 in order to use an external compiler host process
rem This only has an effect when running the FSHARPQA tests, but can
@@ -89,6 +103,10 @@ exit /b 1
:FSHARP
+if not '%FSHARP_TEST_SUITE_USE_NUNIT_RUNNER%' == '' (
+ goto :FSHARP_NUNIT
+)
+
set RESULTFILE=FSharp_Results.log
set FAILFILE=FSharp_Failures.log
set FAILENV=FSharp_Failures
@@ -107,6 +125,32 @@ echo perl %~dp0\fsharpqa\testenv\bin\runall.pl -resultsroot %RESULTSDIR% -result
goto :EOF
+:FSHARP_NUNIT
+
+set FSHARP_TEST_SUITE_CONFIGURATION=%FLAVOR%
+
+set XMLFILE=%RESULTSDIR%\FSharpNunit_Xml.xml
+set OUTPUTFILE=%RESULTSDIR%\FSharpNunit_Output.log
+set ERRORFILE=%RESULTSDIR%\FSharpNunit_Error.log
+
+setlocal EnableDelayedExpansion
+
+set TTAGS_NUNIT_ARG=
+if not '!TTAGS!' == '' (set TTAGS_NUNIT_ARG=--include="!TTAGS!")
+
+set NO_TTAGS_NUNIT_ARG=
+if not '!NO_TTAGS!' == '' (set NO_TTAGS_NUNIT_ARG=--exclude="!NO_TTAGS!")
+
+SET NUNIT3_CONSOLE=%~dp0%..\packages\NUnit.Console.3.0.0-beta-3\tools\nunit-console.exe
+
+echo "%NUNIT3_CONSOLE%" "%FSCBINPATH%\..\..\net40\bin\FSharp.Tests.FSharp.dll" --framework:V4.0 !TTAGS_NUNIT_ARG! !NO_TTAGS_NUNIT_ARG! --work="%RESULTSDIR%" --output="%OUTPUTFILE%" --err="%ERRORFILE%" --result="%XMLFILE%"
+
+"%NUNIT3_CONSOLE%" "%FSCBINPATH%\..\..\net40\bin\FSharp.Tests.FSharp.dll" --framework:V4.0 !TTAGS_NUNIT_ARG! !NO_TTAGS_NUNIT_ARG! --work="%RESULTSDIR%" --output="%OUTPUTFILE%" --err="%ERRORFILE%" --result="%XMLFILE%"
+
+
+goto :EOF
+
+
:FSHARPQA
set OSARCH=%PROCESSOR_ARCHITECTURE%
diff --git a/tests/config.fs b/tests/config.fs
new file mode 100644
index 00000000000..b606e677652
--- /dev/null
+++ b/tests/config.fs
@@ -0,0 +1,586 @@
+module TestConfig
+
+open System
+open System.IO
+open System.Collections.Generic
+open Microsoft.Win32
+
+open PlatformHelpers
+open FSharpTestSuiteTypes
+
+let private fileExists = Commands.fileExists __SOURCE_DIRECTORY__ >> Option.isSome
+let private directoryExists = Commands.directoryExists __SOURCE_DIRECTORY__ >> Option.isSome
+
+let private regQuery = WindowsPlatform.regQuery
+
+type private FSLibPaths =
+ { FSCOREDLLPATH : string
+ FSCOREDLL20PATH : string
+ FSCOREDLLPORTABLEPATH : string
+ FSCOREDLLNETCOREPATH : string
+ FSCOREDLLNETCORE78PATH : string
+ FSCOREDLLNETCORE259PATH : string
+ FSDATATPPATH : string
+ FSCOREDLLVPREVPATH : string }
+
+
+let private checkResult result =
+ match result with
+ | CmdResult.ErrorLevel err -> let x = err, (sprintf "ERRORLEVEL %d" err) in Failure (RunError.ProcessExecError x)
+ | CmdResult.Success -> Success ()
+
+// REM ===
+// REM === Find paths to shipped F# libraries referenced by clients
+// REM ===
+let private GetFSLibPaths env osArch fscBinPath =
+ // REM == Find out OS architecture, no matter what cmd prompt
+ // SET OSARCH=%PROCESSOR_ARCHITECTURE%
+ // IF NOT "%PROCESSOR_ARCHITEW6432%"=="" SET OSARCH=%PROCESSOR_ARCHITEW6432%
+ ignore (osArch, "param")
+
+ // REM == Find out path to native 'Program Files 32bit', no matter what
+ // REM == architecture we are running on and no matter what command
+ // REM == prompt we came from.
+ // IF /I "%OSARCH%"=="x86" set X86_PROGRAMFILES=%ProgramFiles%
+ // IF /I "%OSARCH%"=="IA64" set X86_PROGRAMFILES=%ProgramFiles(x86)%
+ // IF /I "%OSARCH%"=="AMD64" set X86_PROGRAMFILES=%ProgramFiles(x86)%
+ let X86_PROGRAMFILES = WindowsPlatform.x86ProgramFilesDirectory env osArch
+
+ // REM == Default VS install locations
+ // set FSCOREDLLPATH=%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.4.0.0
+ let mutable FSCOREDLLPATH = X86_PROGRAMFILES/"Reference Assemblies"/"Microsoft"/"FSharp"/".NETFramework"/"v4.0"/"4.4.0.0"
+ // set FSCOREDLL20PATH=%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETFramework\v2.0\2.3.0.0
+ let mutable FSCOREDLL20PATH = X86_PROGRAMFILES/"Reference Assemblies"/"Microsoft"/"FSharp"/".NETFramework"/"v2.0"/"2.3.0.0"
+ // set FSCOREDLLPORTABLEPATH=%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETPortable\3.47.4.0
+ let mutable FSCOREDLLPORTABLEPATH = X86_PROGRAMFILES/"Reference Assemblies"/"Microsoft"/"FSharp"/".NETPortable"/"3.47.4.0"
+ // set FSCOREDLLNETCOREPATH=%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETCore\3.7.4.0
+ let mutable FSCOREDLLNETCOREPATH = X86_PROGRAMFILES/"Reference Assemblies"/"Microsoft"/"FSharp"/".NETCore"/"3.7.4.0"
+ // set FSCOREDLLNETCORE78PATH=%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETCore\3.78.4.0
+ let mutable FSCOREDLLNETCORE78PATH = X86_PROGRAMFILES/"Reference Assemblies"/"Microsoft"/"FSharp"/".NETCore"/"3.78.4.0"
+ // set FSCOREDLLNETCORE259PATH=%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETCore\3.259.4.0
+ let mutable FSCOREDLLNETCORE259PATH = X86_PROGRAMFILES/"Reference Assemblies"/"Microsoft"/"FSharp"/".NETCore"/"3.259.4.0"
+ // set FSDATATPPATH=%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.0.0\Type Providers
+ let mutable FSDATATPPATH = X86_PROGRAMFILES/"Reference Assemblies"/"Microsoft"/"FSharp"/".NETFramework"/"v4.0"/"4.3.0.0"/"Type Providers"
+ // set FSCOREDLLVPREVPATH=%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.1.0
+ let mutable FSCOREDLLVPREVPATH = X86_PROGRAMFILES/"Reference Assemblies"/"Microsoft"/"FSharp"/".NETFramework"/"v4.0"/"4.3.1.0"
+
+ // REM == Check if using open build instead
+
+ // IF EXIST "%FSCBinPath%\FSharp.Core.dll" set FSCOREDLLPATH=%FSCBinPath%
+ match fscBinPath with
+ | Some d when fileExists (d/"FSharp.Core.dll") -> FSCOREDLLPATH <- d
+ | Some _ | None -> ()
+
+ // IF EXIST "%FSCBinPath%\..\..\net20\bin\FSharp.Core.dll" set FSCOREDLL20PATH=%FSCBinPath%\..\..\net20\bin
+ match fscBinPath |> Option.map (fun d -> d/".."/".."/"net20"/"bin") with
+ | Some d when fileExists (d/"FSharp.Core.dll") -> FSCOREDLL20PATH <- d
+ | Some _ | None -> ()
+
+ // IF EXIST "%FSCBinPath%\..\..\portable47\bin\FSharp.Core.dll" set FSCOREDLLPORTABLEPATH=%FSCBinPath%\..\..\portable47\bin
+ match fscBinPath |> Option.map (fun d -> d/".."/".."/"portable47"/"bin") with
+ | Some d when fileExists (d/"FSharp.Core.dll") -> FSCOREDLLPORTABLEPATH <- d
+ | Some _ | None -> ()
+
+ // IF EXIST "%FSCBinPath%\..\..\portable7\bin\FSharp.Core.dll" set FSCOREDLLNETCOREPATH=%FSCBinPath%\..\..\portable7\bin
+ match fscBinPath |> Option.map (fun d -> d/".."/".."/"portable7"/"bin") with
+ | Some d when fileExists (d/"FSharp.Core.dll") -> FSCOREDLLNETCOREPATH <- d
+ | Some _ | None -> ()
+
+ // IF EXIST "%FSCBinPath%\..\..\portable78\bin\FSharp.Core.dll" set FSCOREDLLNETCORE78PATH=%FSCBinPath%\..\..\portable78\bin
+ match fscBinPath |> Option.map (fun d -> d/".."/".."/"portable78"/"bin") with
+ | Some d when fileExists (d/"FSharp.Core.dll") -> FSCOREDLLNETCORE78PATH <- d
+ | Some _ | None -> ()
+
+ // IF EXIST "%FSCBinPath%\..\..\portable259\bin\FSharp.Core.dll" set FSCOREDLLNETCORE259PATH=%FSCBinPath%\..\..\portable259\bin
+ match fscBinPath |> Option.map (fun d -> d/".."/".."/"portable259"/"bin") with
+ | Some d when fileExists (d/"FSharp.Core.dll") -> FSCOREDLLNETCORE259PATH <- d
+ | Some _ | None -> ()
+
+ // IF EXIST "%FSCBinPath%\FSharp.Data.TypeProviders.dll" set FSDATATPPATH=%FSCBinPath%
+ match fscBinPath with
+ | Some d when fileExists (d/"FSharp.Data.TypeProviders.dll") -> FSDATATPPATH <- d
+ | Some _ | None -> ()
+
+ // set FSCOREDLLPATH=%FSCOREDLLPATH%\FSharp.Core.dll
+ FSCOREDLLPATH <- FSCOREDLLPATH/"FSharp.Core.dll"
+ // set FSCOREDLL20PATH=%FSCOREDLL20PATH%\FSharp.Core.dll
+ FSCOREDLL20PATH <- FSCOREDLL20PATH/"FSharp.Core.dll"
+ // set FSCOREDLLPORTABLEPATH=%FSCOREDLLPORTABLEPATH%\FSharp.Core.dll
+ FSCOREDLLPORTABLEPATH <- FSCOREDLLPORTABLEPATH/"FSharp.Core.dll"
+ // set FSCOREDLLNETCOREPATH=%FSCOREDLLNETCOREPATH%\FSharp.Core.dll
+ FSCOREDLLNETCOREPATH <- FSCOREDLLNETCOREPATH/"FSharp.Core.dll"
+ // set FSCOREDLLNETCORE78PATH=%FSCOREDLLNETCORE78PATH%\FSharp.Core.dll
+ FSCOREDLLNETCORE78PATH <- FSCOREDLLNETCORE78PATH/"FSharp.Core.dll"
+ // set FSCOREDLLNETCORE259PATH=%FSCOREDLLNETCORE259PATH%\FSharp.Core.dll
+ FSCOREDLLNETCORE259PATH <- FSCOREDLLNETCORE259PATH/"FSharp.Core.dll"
+ // set FSDATATPPATH=%FSDATATPPATH%\FSharp.Data.TypeProviders.dll
+ FSDATATPPATH <- FSDATATPPATH/"FSharp.Data.TypeProviders.dll"
+ // set FSCOREDLLVPREVPATH=%FSCOREDLLVPREVPATH%\FSharp.Core.dll
+ FSCOREDLLVPREVPATH <- FSCOREDLLVPREVPATH/"FSharp.Core.dll"
+
+ X86_PROGRAMFILES, {
+ FSCOREDLLPATH = FSCOREDLLPATH;
+ FSCOREDLL20PATH = FSCOREDLL20PATH;
+ FSCOREDLLPORTABLEPATH = FSCOREDLLPORTABLEPATH;
+ FSCOREDLLNETCOREPATH = FSCOREDLLNETCOREPATH;
+ FSCOREDLLNETCORE78PATH = FSCOREDLLNETCORE78PATH;
+ FSCOREDLLNETCORE259PATH = FSCOREDLLNETCORE259PATH;
+ FSDATATPPATH = FSDATATPPATH;
+ FSCOREDLLVPREVPATH = FSCOREDLLVPREVPATH }
+
+// REM ===
+// REM === Find path to FSC/FSI looking up the registry
+// REM === Will set the FSCBinPath env variable.
+// REM === This if for Dev11+/NDP4.5
+// REM === Works on both XP and Vista and hopefully everything else
+// REM === Works on 32bit and 64 bit, no matter what cmd prompt it is invoked from
+// REM ===
+let private SetFSCBinPath45 () =
+ // FOR /F "tokens=1-2*" %%a IN ('reg query "%REG_SOFTWARE%\Microsoft\FSharp\4.0\Runtime\v4.0" /ve') DO set FSCBinPath=%%c
+ // FOR /F "tokens=1-3*" %%a IN ('reg query "%REG_SOFTWARE%\Microsoft\FSharp\4.0\Runtime\v4.0" /ve') DO set FSCBinPath=%%d
+ // IF EXIST "%FSCBinPath%" goto :EOF
+ let hklm32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32)
+ match hklm32 |> regQuery @"SOFTWARE\Microsoft\FSharp\4.0\Runtime\v4.0" "" with
+ | Some (:? string as d) when directoryExists d -> Some d
+ | Some _ | None -> None
+
+let private attendedLog envVars x86_ProgramFiles corDir corDir40 =
+ let getMsbuildPath =
+ // rem first see if we have got msbuild installed
+ let mutable MSBuildToolsPath = envVars |> Map.tryFind "MSBuildToolsPath"
+
+ // if exist "%X86_PROGRAMFILES%\MSBuild\14.0\Bin\MSBuild.exe" SET MSBuildToolsPath=%X86_PROGRAMFILES%\MSBuild\14.0\Bin\
+ if x86_ProgramFiles/"MSBuild"/"14.0"/"Bin"/"MSBuild.exe" |> fileExists
+ then MSBuildToolsPath <- Some (x86_ProgramFiles/"MSBuild"/"14.0"/"Bin" |> Commands.pathAddBackslash)
+ // if not "%MSBuildToolsPath%" == "" goto done_MsBuildToolsPath
+ match MSBuildToolsPath with
+ | Some x -> Some x
+ | None ->
+ let mutable MSBuildToolsPath = None
+ // IF NOT "%CORDIR%"=="" IF EXIST "%CORDIR%\msbuild.exe" SET MSBuildToolsPath=%CORDIR%
+ if not (corDir = "") then
+ if corDir/"msbuild.exe" |> fileExists
+ then MSBuildToolsPath <- Some corDir
+ // IF "%CORDIR40%"=="" IF NOT "%CORDIR%"=="" IF EXIST "%CORDIR%\..\V3.5\msbuild.exe" SET MSBuildToolsPath="%CORDIR%\..\V3.5\"
+ if (corDir40 |> Option.isNone) then
+ if (not (corDir = "")) then
+ if corDir/".."/"V3.5"/"msbuild.exe" |> fileExists
+ then MSBuildToolsPath <- Some (corDir/".."/"V3.5")
+
+ // IF NOT "%CORDIR%"=="" FOR /f %%j IN ("%MSBuildToolsPath%") do SET MSBuildToolsPath=%%~fj
+ if (not (corDir = ""))
+ then MSBuildToolsPath <- (MSBuildToolsPath |> Option.map Path.GetFullPath)
+ MSBuildToolsPath
+ // :done_MsBuildToolsPath
+
+ // exit /b 0
+ getMsbuildPath, (WindowsPlatform.visualStudioVersion ())
+
+
+let config envVars =
+ // set _SCRIPT_DRIVE=%~d0
+ ignore "unused"
+ // set _SCRIPT_PATH=%~p0
+ ignore "unused"
+ // set SCRIPT_ROOT=%_SCRIPT_DRIVE%%_SCRIPT_PATH%
+ let SCRIPT_ROOT = __SOURCE_DIRECTORY__ |> Path.GetFullPath
+
+ let env key = envVars |> Map.tryFind key
+ let envOrDefault key def = env key |> Option.fold (fun s t -> t) def
+ let envOrFail key = env key |> function Some x -> x | None -> failwithf "environment variable '%s' required " key
+ let where = Commands.where envVars
+
+ let PROCESSOR_ARCHITECTURE = WindowsPlatform.processorArchitecture envVars
+ // set REG_SOFTWARE=HKLM\SOFTWARE
+ // IF /I "%PROCESSOR_ARCHITECTURE%"=="AMD64" (set REG_SOFTWARE=%REG_SOFTWARE%\Wow6432Node)
+ ignore "unused, using .net bcl to query RegistryView.Registry32"
+
+ // if not defined FSHARP_HOME set FSHARP_HOME=%SCRIPT_ROOT%..\..
+ // for /f %%i in ("%FSHARP_HOME%") do set FSHARP_HOME=%%~fi
+ let FSHARP_HOME =
+ envOrDefault "FSHARP_HOME" (SCRIPT_ROOT/".."/"..")
+ |> Path.GetFullPath
+
+ // REM Do we know where fsc.exe is?
+ // IF DEFINED FSCBinPath goto :FSCBinPathFound
+ // FOR /F "delims=" %%i IN ('where fsc.exe') DO SET FSCBinPath=%%~dpi
+ // :FSCBinPathFound
+ let mutable FSCBinPath =
+ match env "FSCBINPATH" with
+ | Some p -> Some p
+ | None -> where "fsc.exe" |> Option.map Path.GetDirectoryName
+
+ // SET CLIFLAVOUR=cli\4.5
+ let CLIFLAVOUR = @"cli\4.5"
+
+ // if not exist "%FSCBinPath%\fsc.exe" call :SetFSCBinPath45
+ if not (FSCBinPath |> Option.map (fun dir -> dir/"fsc.exe") |> Option.exists fileExists)
+ then FSCBinPath <- SetFSCBinPath45 ()
+
+ // if not exist "%FSCBinPath%\fsc.exe" echo %FSCBinPath%\fsc.exe still not found. Assume that user has added it to path somewhere
+ ignore "smoke test check fsc.exe"
+
+ // REM add %FSCBinPath% to path only if not already there. Otherwise, the path keeps growing.
+ // echo %path%; | find /i "%FSCBinPath%;" > NUL
+ // if ERRORLEVEL 1 set PATH=%PATH%;%FSCBinPath%
+ //REVIEW add it? or better use only env var?
+
+ // if "%FSDIFF%"=="" set FSDIFF=%SCRIPT_ROOT%fsharpqa\testenv\bin\diff.exe
+ let FSDIFF = envOrDefault "FSDIFF" (SCRIPT_ROOT/"fsharpqa"/"testenv"/"bin"/"diff.exe")
+ // if not exist "%FSDIFF%" echo FSDIFF not found at expected path of %fsdiff% && exit /b 1
+ ignore "check exists diff.exe"
+
+ // rem check if we're already configured, if not use the configuration from the last line of the config file
+ // if "%fsc%"=="" (
+ // set csc_flags=/nologo
+ // set fsiroot=fsi
+ // )
+ let mutable FSC = env "fsc"
+ let csc_flags =
+ match FSC with None -> "/nologo" | Some _ -> (envOrDefault "csc_flags" "/nologo")
+ let mutable fsiroot =
+ match FSC with None -> Some "fsi" | Some _ -> (env "fsiroot")
+
+ // if not defined ALINK set ALINK=al.exe
+ let mutable ALINK = (envOrDefault "ALINK" "al.exe")
+ // if not defined CSC set CSC=csc.exe %csc_flags%
+ let CSC = envOrDefault "CSC" "csc.exe"
+
+ // REM SDK Dependencires.
+ // if not defined ILDASM set ILDASM=ildasm.exe
+ let mutable ILDASM = envOrDefault "ILDASM" "ildasm.exe"
+ // if not defined GACUTIL set GACUTIL=gacutil.exe
+ let mutable GACUTIL = envOrDefault "GACUTIL" "gacutil.exe"
+ // if not defined PEVERIFY set PEVERIFY=peverify.exe
+ let mutable PEVERIFY = envOrDefault "PEVERIFY" "peverify.exe"
+ // if not defined RESGEN set RESGEN=resgen.exe
+ let mutable RESGEN = envOrDefault "RESGEN" "resgen.exe"
+
+ // if "%fsiroot%" == "" ( set fsiroot=fsi)
+ if fsiroot |> Option.isNone
+ then fsiroot <- Some "fsi"
+
+ // REM == Test strategy: if we are on a 32bit OS => use fsi.exe
+ // REM == if we are on a 64bit OS => use fsiAnyCPU.exe
+ // REM == This way we get coverage of both binaries without having to
+ // REM == double the test matrix. Note that our nightly automation
+ // REM == always cover x86 and x64... so we won't miss much. There
+ // REM == is an implicit assumption that the CLR will do it's job
+ // REM == to make an FSIAnyCPU.exe behave as FSI.exe on a 32bit OS.
+ // REM == On 64 bit machines ensure that we run the 64 bit versions of tests too.
+
+ // SET OSARCH=%PROCESSOR_ARCHITECTURE%
+ // IF NOT "%PROCESSOR_ARCHITEW6432%"=="" SET OSARCH=%PROCESSOR_ARCHITEW6432%
+ let OSARCH = WindowsPlatform.osArch envVars
+
+ // IF "%fsiroot%"=="fsi" IF NOT "%OSARCH%"=="x86" (
+ // SET fsiroot=fsiAnyCPU
+ // set FSC_BASIC_64=FSC_BASIC_64
+ // )
+ let mutable FSC_BASIC_64 = env "FSC_BASIC_64"
+ match fsiroot, OSARCH with
+ | Some "fsi", X86 -> ()
+ | Some "fsi", arc ->
+ fsiroot <- Some "fsiAnyCPU"
+ FSC_BASIC_64 <- Some "FSC_BASIC_64"
+ | _ -> ()
+
+
+ // REM ---------------------------------------------------------------
+ // REM If we set a "--cli-version" flag anywhere in the flags then assume its v1.x
+ // REM and generate a config file, so we end up running the test on the right version
+ // REM of the CLR. Also modify the CORSDK used.
+ // REM
+ // REM Use CLR 1.1 at a minimum since 1.0 is not installed on most of my machines
+ // REM otherwise assume v2.0
+ // REM TODO: we need to update this to be v2.0 or v3.5 and nothing else.
+
+ // set fsc_flags=%fsc_flags%
+ let mutable fsc_flags = env "fsc_flags"
+
+ // set CLR_SUPPORTS_GENERICS=true
+ let CLR_SUPPORTS_GENERICS = true
+ // set ILDASM=%ILDASM%
+ ignore "env var not needed, ildasm is invoked with Commands.ildasm"
+ // set GACUTIL=%GACUTIL%
+ ignore "env var not needed, gacutil is invoked with Commads.gacutil"
+ // set CLR_SUPPORTS_WINFORMS=true
+ let CLR_SUPPORTS_WINFORMS = true
+ // set CLR_SUPPORTS_SYSTEM_WEB=true
+ let CLR_SUPPORTS_SYSTEM_WEB = true
+
+ // REM ==
+ // REM == F# v1.0 targets NetFx3.5 (i.e. NDP2.0)
+ // REM == It is ok to hardcode the location, since this is not going to
+ // REM == change ever. Well, if/when we target a different runtime we'll have
+ // REM == to come and update this, but for now we MUST make sure we use the 2.0 stuff.
+ // REM ==
+ // REM == If we run on a 64bit machine (from a 64bit command prompt!), we use the 64bit
+ // REM == CLR, but tweaking 'Framework' to 'Framework64'.
+ // REM ==
+ // set CORDIR=%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\
+ let SystemRoot = envOrFail "SystemRoot"
+ let mutable CORDIR = SystemRoot/"Microsoft.NET"/"Framework"/"v2.0.50727" |> Commands.pathAddBackslash
+ // set CORDIR40=
+ // FOR /D %%i IN (%windir%\Microsoft.NET\Framework\v4.0.?????) do set CORDIR40=%%i
+ let windir = envOrFail "windir"
+ let CORDIR40 =
+ match Directory.EnumerateDirectories (windir/"Microsoft.NET"/"Framework", "v4.0.?????") |> List.ofSeq |> List.rev with
+ | x :: _ -> Some x
+ | [] -> None
+ // IF NOT "%CORDIR40%"=="" set CORDIR=%CORDIR40%
+ match CORDIR40 with
+ | None -> ()
+ | Some d -> CORDIR <- d
+
+ // REM == Use the same runtime as our architecture
+ // REM == ASSUMPTION: This could be a good or bad thing.
+ // IF /I NOT "%PROCESSOR_ARCHITECTURE%"=="x86" set CORDIR=%CORDIR:Framework=Framework64%
+ match PROCESSOR_ARCHITECTURE with
+ | X86 -> ()
+ | _ -> CORDIR <- CORDIR.Replace("Framework", "Framework64")
+
+
+
+ let regQueryREG_SOFTWARE path value =
+ let hklm32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32)
+ match hklm32 |> regQuery path value with
+ | Some (:? string as d) -> Some d
+ | Some _ | None -> None
+
+ let allSDK = seq {
+ // FOR /F "tokens=2* delims= " %%A IN ('reg QUERY "%REG_SOFTWARE%\Microsoft\Microsoft SDKs\NETFXSDK\4.6\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET CORSDK=%%B
+ yield regQueryREG_SOFTWARE @"Software\Microsoft\Microsoft SDKs\NETFXSDK\4.6\WinSDK-NetFx40Tools" "InstallationFolder";
+ // if "%CORSDK%"=="" FOR /F "tokens=2* delims= " %%A IN ('reg QUERY "%REG_SOFTWARE%\Microsoft\Microsoft SDKs\Windows\v8.1A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET CORSDK=%%B
+ yield regQueryREG_SOFTWARE @"Software\Microsoft\Microsoft SDKs\Windows\v8.1A\WinSDK-NetFx40Tools" "InstallationFolder";
+ // if "%CORSDK%"=="" FOR /F "tokens=2* delims= " %%A IN ('reg QUERY "%REG_SOFTWARE%\Microsoft\Microsoft SDKs\Windows\v8.0A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET CORSDK=%%B
+ yield regQueryREG_SOFTWARE @"Software\Microsoft\Microsoft SDKs\Windows\v8.0A\WinSDK-NetFx40Tools" "InstallationFolder";
+ // if "%CORSDK%"=="" FOR /F "tokens=2* delims= " %%A IN ('reg QUERY "%REG_SOFTWARE%\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET CORSDK=%%B
+ yield regQueryREG_SOFTWARE @"Software\Microsoft\Microsoft SDKs\Windows\v7.1\WinSDK-NetFx40Tools" "InstallationFolder";
+ // if "%CORSDK%"=="" FOR /F "tokens=2* delims= " %%A IN ('reg QUERY "%REG_SOFTWARE%\Microsoft\Microsoft SDKs\Windows\v7.0A\WinSDK-NetFx40Tools" /v InstallationFolder') DO SET CORSDK=%%B
+ yield regQueryREG_SOFTWARE @"Software\Microsoft\Microsoft SDKs\Windows\v7.0A\WinSDK-NetFx40Tools" "InstallationFolder";
+ }
+
+ let mutable CORSDK = allSDK |> Seq.tryPick id
+
+ // REM == Fix up CORSDK for 64bit platforms...
+ // IF /I "%PROCESSOR_ARCHITECTURE%"=="AMD64" SET CORSDK=%CORSDK%\x64
+ // IF /I "%PROCESSOR_ARCHITECTURE%"=="IA64" SET CORSDK=%CORSDK%\IA64
+ match PROCESSOR_ARCHITECTURE with
+ | AMD64 -> CORSDK <- CORSDK |> Option.map (fun dir -> dir/"x64")
+ | IA64 -> CORSDK <- CORSDK |> Option.map (fun dir -> dir/"IA64")
+ | _ -> ()
+
+ // REM add powerpack to flags only if not already there. Otherwise, the variable can keep growing.
+ // echo %fsc_flags% | find /i "powerpack"
+ // if ERRORLEVEL 1 set fsc_flags=%fsc_flags% -r:System.Core.dll --nowarn:20
+ if fsc_flags |> Option.exists (fun flags -> flags.ToLower().Contains("powerpack")) then ()
+ else fsc_flags <- Some (sprintf "%s -r:System.Core.dll --nowarn:20" (fsc_flags |> Option.fold (fun s t -> t) ""))
+
+ // if not defined fsi_flags set fsi_flags=%fsc_flags:--define:COMPILED=% --define:INTERACTIVE --maxerrors:1 --abortonerror
+ let mutable fsi_flags = env "fsi_flags"
+ if fsi_flags |> Option.isNone then (
+ let fsc_flags_no_compiled = fsc_flags |> Option.fold (fun s flags -> flags.Replace("--define:COMPILED", "")) ""
+ fsi_flags <- Some (sprintf "%s --define:INTERACTIVE --maxerrors:1 --abortonerror" fsc_flags_no_compiled)
+ )
+
+ // echo %fsc_flags%; | find "--define:COMPILED" > NUL || (
+ // set fsc_flags=%fsc_flags% --define:COMPILED
+ // )
+ if not (fsc_flags |> Option.exists (fun flags -> flags.Contains("--define:COMPILED")))
+ then fsc_flags <- Some (sprintf "%s --define:COMPILED" (fsc_flags |> Option.fold (fun s t -> t) ""))
+
+ // if NOT "%fsc_flags:generate-config-file=X%"=="%fsc_flags%" (
+ // if NOT "%fsc_flags:clr-root=X%"=="%fsc_flags%" (
+ // set fsc_flags=%fsc_flags% --clr-root:%CORDIR%
+ // )
+ // )
+ // --clr-root non e' un flag valido di fsc
+ // if not <| (fsc_flags |> Option.exists (fun flags -> flags.Contains("generate-config-file"))) then
+ // if not <| (fsc_flags |> Option.exists (fun flags -> flags.Contains("clr-root"))) then
+ // fsc_flags <- Some (sprintf "%s --clr-root:%s" (fsc_flags |> Option.fold (fun s t -> t) "") (!CORDIR))
+
+ // if "%CORDIR%"=="unknown" set CORDIR=
+ if CORDIR = "unknown" then CORDIR <- ""
+
+ // REM use short names in the path so you don't have to deal with the space in things like "Program Files"
+ // for /f "delims=" %%I in ("%CORSDK%") do set CORSDK=%%~dfsI%
+ CORSDK <- CORSDK |> Option.map Commands.convertToShortPath
+
+ // for /f "delims=" %%I in ("%CORDIR%") do set CORDIR=%%~dfsI%
+ CORDIR <- Commands.convertToShortPath CORDIR
+
+
+ // set NGEN=
+ let mutable NGEN = None
+
+ // REM ==
+ // REM == Set path to C# compiler. If we are NOT on NetFx4.0, try we prefer C# 3.5 to C# 2.0
+ // REM == This is because we have tests that reference System.Core.dll from C# code!
+ // REM == (e.g. fsharp\core\fsfromcs)
+ // REM ==
+ // IF NOT "%CORDIR%"=="" IF EXIST "%CORDIR%\csc.exe" SET CSC="%CORDIR%\csc.exe" %csc_flags%
+ let mutable CSC = None
+ if not (CORDIR = "") then
+ if CORDIR/"csc.exe" |> fileExists
+ then CSC <- Some (CORDIR/"csc.exe")
+
+ // IF "%CORDIR40%"=="" IF NOT "%CORDIR%"=="" IF EXIST "%CORDIR%\..\V3.5\csc.exe" SET CSC="%CORDIR%\..\v3.5\csc.exe" %csc_flags%
+ if CORDIR40 |> Option.isNone then
+ if not (CORDIR = "") then
+ if CORDIR/".."/"V3.5"/"csc.exe" |> fileExists
+ then CSC <- Some (CORDIR/".."/"V3.5"/"csc.exe")
+
+ // IF NOT "%CORDIR%"=="" IF EXIST "%CORDIR%\ngen.exe" SET NGEN=%CORDIR%\ngen.exe
+ if not (CORDIR = "") then
+ if CORDIR/"ngen.exe" |> fileExists
+ then NGEN <- Some (CORDIR/"ngen.exe")
+
+ // IF NOT "%CORDIR%"=="" IF EXIST "%CORDIR%\al.exe" SET ALINK=%CORDIR%\al.exe
+ if not (CORDIR = "") then
+ if CORDIR/"al.exe" |> fileExists
+ then ALINK <- CORDIR/"al.exe"
+
+ // REM ==
+ // REM == The logic here is: pick the latest msbuild
+ // REM == If we are testing against NDP4.0, then don't try msbuild 3.5
+ // REM ==
+
+ // IF NOT "%CORSDK%"=="" IF EXIST "%CORSDK%\ildasm.exe" SET ILDASM=%CORSDK%\ildasm.exe
+ match CORSDK |> Option.map (fun d -> d/"ildasm.exe") with
+ | Some p when fileExists p -> ILDASM <- p
+ | Some _ | None -> ()
+
+ // IF NOT "%CORSDK%"=="" IF EXIST "%CORSDK%\gacutil.exe" SET GACUTIL=%CORSDK%\gacutil.exe
+ match CORSDK |> Option.map (fun d -> d/"gacutil.exe") with
+ | Some p when fileExists p -> GACUTIL <- p
+ | Some _ | None -> ()
+
+ // IF NOT "%CORSDK%"=="" IF EXIST "%CORSDK%\peverify.exe" SET PEVERIFY=%CORSDK%\peverify.exe
+ match CORSDK |> Option.map (fun d -> d/"peverify.exe") with
+ | Some p when fileExists p -> PEVERIFY <- p
+ | Some _ | None -> ()
+
+ // IF NOT "%CORSDK%"=="" IF EXIST "%CORSDK%\resgen.exe" SET RESGEN=%CORSDK%\resgen.exe
+ // IF NOT "%CORSDK%"=="" IF NOT EXIST "%RESGEN%" IF EXIST "%CORSDK%\..\resgen.exe" SET RESGEN=%CORSDK%\..\resgen.exe
+ match CORSDK with
+ | Some sdk ->
+ if sdk/"resgen.exe" |> fileExists
+ then RESGEN <- sdk/"resgen.exe"
+ elif sdk/".."/"resgen.exe" |> fileExists
+ then RESGEN <- sdk/".."/"resgen.exe"
+ | None -> ()
+
+ // IF NOT "%CORSDK%"=="" IF EXIST "%CORSDK%\al.exe" SET ALINK=%CORSDK%\al.exe
+ match CORSDK |> Option.map (fun d -> d/"al.exe") with
+ | Some p when fileExists p -> ALINK <- p
+ | Some _ | None -> ()
+
+ // IF NOT DEFINED FSC SET FSC=fsc.exe
+ let mutable FSC = envOrDefault "FSC" "fsc.exe"
+ // IF NOT DEFINED FSI SET FSI=%fsiroot%.exe
+ let mutable FSI = envOrDefault "FSI" (fsiroot |> Option.fold (+) ".exe")
+
+ // IF DEFINED FSCBinPath IF EXIST "%FSCBinPath%\fsc.exe" SET FSC=%FSCBinPath%\fsc.exe
+ match FSCBinPath |> Option.map (fun d -> d/"fsc.exe") with
+ | Some fscExe when fileExists fscExe -> FSC <- fscExe
+ | Some _ | None -> ()
+
+ // IF DEFINED FSCBinPath IF EXIST "%FSCBinPath%\%fsiroot%.exe" SET FSI=%FSCBinPath%\%fsiroot%.exe
+ match FSCBinPath, fsiroot with
+ | Some dir, Some fsiExe when fileExists (dir/(fsiExe+".exe")) -> FSI <- dir/(fsiExe+".exe")
+ | _ -> ()
+
+ // REM == Located F# library DLLs in either open or Visual Studio contexts
+ // call :GetFSLibPaths
+ let X86_PROGRAMFILES, libs = GetFSLibPaths envVars OSARCH FSCBinPath
+
+ // REM == Set standard flags for invoking powershell scripts
+ // IF NOT DEFINED PSH_FLAGS SET PSH_FLAGS=-nologo -noprofile -executionpolicy bypass
+ let PSH_FLAGS = envOrDefault "PSH_FLAGS" "-nologo -noprofile -executionpolicy bypass"
+ ignore "unused, cross platform requirement and powershell is not used in tests"
+
+ //add to environment variables, only if needed (an example is ILDASM, cfg.ILDASM should be used instead inside tests)
+ let environment =
+ envVars
+ |> Map.add "CLR_SUPPORTS_GENERICS" (sprintf "%A" CLR_SUPPORTS_GENERICS)
+ |> Map.add "CLR_SUPPORTS_WINFORMS" (sprintf "%A" CLR_SUPPORTS_WINFORMS)
+ |> Map.add "CLR_SUPPORTS_SYSTEM_WEB" (sprintf "%A" CLR_SUPPORTS_SYSTEM_WEB)
+
+ let orBlank = Option.fold (fun _ x -> x) ""
+
+ let cfg = {
+ EnvironmentVariables = environment;
+ ALINK = ALINK;
+ CORDIR = CORDIR |> Commands.pathAddBackslash;
+ CORSDK = CORSDK |> orBlank |> Commands.pathAddBackslash;
+ FSCBinPath = FSCBinPath |> orBlank |> Commands.pathAddBackslash;
+ FSCOREDLL20PATH = libs.FSCOREDLL20PATH;
+ FSCOREDLLPATH = libs.FSCOREDLLPATH;
+ FSCOREDLLPORTABLEPATH = libs.FSCOREDLLPORTABLEPATH;
+ FSCOREDLLNETCOREPATH = libs.FSCOREDLLNETCOREPATH;
+ FSCOREDLLNETCORE78PATH = libs.FSCOREDLLNETCORE78PATH;
+ FSCOREDLLNETCORE259PATH = libs.FSCOREDLLNETCORE259PATH;
+ FSDATATPPATH = libs.FSDATATPPATH;
+ FSCOREDLLVPREVPATH = libs.FSCOREDLLVPREVPATH;
+ FSDIFF = FSDIFF;
+ GACUTIL = GACUTIL;
+ ILDASM = ILDASM;
+ INSTALL_SKU = None;
+ MSBUILDTOOLSPATH = None;
+ MSBUILD = None;
+ NGEN = NGEN |> orBlank;
+ PEVERIFY = PEVERIFY;
+ RESGEN = RESGEN;
+ CSC = CSC |> orBlank;
+ FSC = FSC;
+ FSI = FSI;
+ csc_flags = csc_flags;
+ fsc_flags = fsc_flags |> orBlank;
+ fsi_flags = fsi_flags |> orBlank;
+ }
+
+ // if DEFINED _UNATTENDEDLOG exit /b 0
+ match env "_UNATTENDEDLOG" with
+ | Some _ -> cfg
+ | None ->
+ let msbuildToolsPath, installSku = attendedLog envVars X86_PROGRAMFILES CORDIR CORDIR40
+ { cfg with
+ MSBUILDTOOLSPATH = msbuildToolsPath |> Option.map (Commands.pathAddBackslash);
+ MSBUILD = msbuildToolsPath |> Option.map (fun d -> d/"msbuild.exe");
+ INSTALL_SKU = installSku }
+
+
+
+let logConfig (cfg: TestConfig) =
+ log "---------------------------------------------------------------"
+ log "Executables"
+ log ""
+ log "ALINK =%s" cfg.ALINK
+ log "CORDIR =%s" cfg.CORDIR
+ log "CORSDK =%s" cfg.CORSDK
+ log "CSC =%s" cfg.CSC
+ log "csc_flags =%s" cfg.csc_flags
+ log "FSC =%s" cfg.FSC
+ log "fsc_flags =%s" cfg.fsc_flags
+ log "FSCBINPATH =%s" cfg.FSCBinPath
+ log "FSCOREDLL20PATH =%s" cfg.FSCOREDLL20PATH
+ log "FSCOREDLLPATH =%s" cfg.FSCOREDLLPATH
+ log "FSCOREDLLPORTABLEPATH =%s" cfg.FSCOREDLLPORTABLEPATH
+ log "FSCOREDLLNETCOREPATH=%s" cfg.FSCOREDLLNETCOREPATH
+ log "FSCOREDLLNETCORE78PATH=%s" cfg.FSCOREDLLNETCORE78PATH
+ log "FSCOREDLLNETCORE259PATH=%s" cfg.FSCOREDLLNETCORE259PATH
+ log "FSCOREDLLVPREVPATH=%s" cfg.FSCOREDLLVPREVPATH
+ log "FSDATATPPATH =%s" cfg.FSDATATPPATH
+ log "FSDIFF =%s" cfg.FSDIFF
+ log "FSI =%s" cfg.FSI
+ log "fsi_flags =%s" cfg.fsi_flags
+ log "GACUTIL =%s" cfg.GACUTIL
+ log "ILDASM =%s" cfg.ILDASM
+ log "INSTALL_SKU =%A" cfg.INSTALL_SKU
+ log "MSBUILDTOOLSPATH =%A" cfg.MSBUILDTOOLSPATH
+ log "MSBUILD =%A" cfg.MSBUILD
+ log "NGEN =%s" cfg.NGEN
+ log "PEVERIFY =%s" cfg.PEVERIFY
+ log "RESGEN =%s" cfg.RESGEN
+ log "---------------------------------------------------------------"
diff --git a/tests/fsharp/Commands.fs b/tests/fsharp/Commands.fs
new file mode 100644
index 00000000000..6cd77821bd0
--- /dev/null
+++ b/tests/fsharp/Commands.fs
@@ -0,0 +1,160 @@
+[]
+module Commands
+
+open System
+open System.IO
+
+open PlatformHelpers
+
+let getfullpath workDir path =
+ let rooted =
+ if Path.IsPathRooted(path) then path
+ else Path.Combine(workDir, path)
+ rooted |> Path.GetFullPath
+
+let fileExists workDir path =
+ if path |> getfullpath workDir |> File.Exists then Some path else None
+
+let directoryExists workDir path =
+ if path |> getfullpath workDir |> Directory.Exists then Some path else None
+
+/// copy /y %source1% tmptest2.ml
+let copy_y workDir source to' =
+ log "copy /y %s %s" source to'
+ File.Copy( source |> getfullpath workDir, to' |> getfullpath workDir, true)
+ CmdResult.Success
+
+/// mkdir orig
+let mkdir_p workDir dir =
+ log "mkdir %s" dir
+ Directory.CreateDirectory ( Path.Combine(workDir, dir) ) |> ignore
+
+/// del test.txt
+let rm dir path =
+ log "rm %s" path
+ let p = path |> getfullpath dir
+ if File.Exists(p) then File.Delete(p)
+
+let pathAddBackslash (p: FilePath) =
+ if String.IsNullOrWhiteSpace (p)
+ then p
+ else
+ p.TrimEnd ([| Path.DirectorySeparatorChar; Path.AltDirectorySeparatorChar |])
+ + Path.DirectorySeparatorChar.ToString()
+
+// echo. > build.ok
+let ``echo._tofile`` workDir text p =
+ log "echo.%s> %s" text p
+ let to' = p |> getfullpath workDir in File.WriteAllText(to', text + Environment.NewLine)
+
+/// echo // empty file > tmptest2.mli
+let echo_tofile workDir text p =
+ log "echo %s> %s" text p
+ let to' = p |> getfullpath workDir in File.WriteAllText(to', text + Environment.NewLine)
+
+/// echo // empty file >> tmptest2.mli
+let echo_append_tofile workDir text p =
+ log "echo %s> %s" text p
+ let to' = p |> getfullpath workDir in File.AppendAllText(to', text + Environment.NewLine)
+
+/// type %source1% >> tmptest3.ml
+let type_append_tofile workDir source p =
+ log "type %s >> %s" source p
+ let from = source |> getfullpath workDir
+ let to' = p |> getfullpath workDir
+ let contents = File.ReadAllText(from)
+ File.AppendAllText(to', contents)
+
+// %GACUTIL% /if %BINDIR%\FSharp.Core.dll
+let gacutil exec exeName flags assembly =
+ exec exeName (sprintf """%s "%s" """ flags assembly)
+
+// "%NGEN32%" install "%BINDIR%\fsc.exe" /queue:1
+// "%NGEN32%" install "%BINDIR%\fsi.exe" /queue:1
+// "%NGEN32%" install "%BINDIR%\FSharp.Build.dll" /queue:1
+// "%NGEN32%" executeQueuedItems 1
+let ngen exec (ngenExe: FilePath) assemblies =
+ let queue = assemblies |> List.map (fun a -> (sprintf "install \"%s\" /queue:1" a))
+
+ List.concat [ queue; ["executeQueuedItems 1"] ]
+ |> Seq.ofList
+ |> Seq.map (fun args -> exec ngenExe args)
+ |> Seq.takeWhile (function ErrorLevel _ -> false | Ok -> true)
+ |> Seq.last
+
+let fsc exec (fscExe: FilePath) flags srcFiles =
+ // "%FSC%" %fsc_flags% --define:COMPILING_WITH_EMPTY_SIGNATURE -o:tmptest2.exe tmptest2.mli tmptest2.ml
+ exec fscExe (sprintf "%s %s" flags (srcFiles |> Seq.ofList |> String.concat " "))
+
+let csc exec cscExe flags srcFiles =
+ exec cscExe (sprintf "%s %s" flags (srcFiles |> Seq.ofList |> String.concat " "))
+
+let fsi exec fsiExe flags sources =
+ exec fsiExe (sprintf "%s %s" flags (sources |> Seq.ofList |> String.concat " "))
+
+// "%MSBUILDTOOLSPATH%\msbuild.exe" PCL.fsproj
+let msbuild exec msbuildExe flags srcFiles =
+ exec msbuildExe (sprintf "%s %s" flags (srcFiles |> Seq.ofList |> String.concat " "))
+
+// "%RESGEN%" /compile Resources.resx
+let resgen exec resgenExe flags sources =
+ exec resgenExe (sprintf "%s %s" flags (sources |> Seq.ofList |> String.concat " "))
+
+let internal quotepath (p: FilePath) =
+ let quote = '"'.ToString()
+ if p.Contains(" ")
+ then (sprintf "%s%s%s" quote p quote)
+ else p
+
+let ildasm exec ildasmExe flags assembly =
+ exec ildasmExe (sprintf "%s %s" flags (quotepath assembly))
+
+let peverify exec peverifyExe path =
+ exec peverifyExe path
+
+let createTempDir () =
+ let path = Path.GetTempFileName ()
+ File.Delete path
+ Directory.CreateDirectory path |> ignore
+ path
+
+let convertToShortPath path =
+ log "convert to short path %s" path
+ let result = ref None
+ let lastLine = function null -> () | l -> result := Some l
+
+ let cmdArgs = { RedirectOutput = Some lastLine; RedirectError = None; RedirectInput = None }
+
+ let args = sprintf """/c for /f "delims=" %%I in ("%s") do echo %%~dfsI""" path
+
+ match Process.exec cmdArgs (Path.GetTempPath()) Map.empty "cmd.exe" args with
+ | ErrorLevel _ -> path
+ | Ok -> match !result with None -> path | Some p -> p
+
+let where envVars cmd =
+ log "where %s" cmd
+ let result = ref None
+ let lastLine = function null -> () | l -> result := Some l
+
+ let cmdArgs = { RedirectOutput = Some lastLine; RedirectError = None; RedirectInput = None; }
+
+ match Process.exec cmdArgs (Path.GetTempPath()) envVars "cmd.exe" (sprintf "/c where %s" cmd) with
+ | ErrorLevel _ -> None
+ | CmdResult.Success -> !result
+
+let fsdiff exec fsdiffExe ignoreWhiteSpaceChanges file1 file2 =
+ // %FSDIFF% %testname%.err %testname%.bsl
+ exec fsdiffExe (sprintf "%s%s %s" (if ignoreWhiteSpaceChanges then "-dew " else "") file1 file2)
+
+let ``for /f`` path =
+ // FOR /F processing of a text file consists of reading the file, one line of text at a time and then breaking the line up into individual
+ // items of data called 'tokens'. The DO command is then executed with the parameter(s) set to the token(s) found.
+ // By default, /F breaks up the line at each blank space " ", and any blank lines are skipped, this default parsing behavior can be changed
+ // by applying one or more of the "options" parameters. The option(s) must be contained within "a pair of quotes"
+ let splitLines lines =
+ lines
+ |> Array.filter (fun l -> not <| String.IsNullOrWhiteSpace(l))
+ |> Array.collect (fun l -> l.Split([| ' ' |], StringSplitOptions.RemoveEmptyEntries))
+ |> List.ofArray
+
+ File.ReadAllLines (path) |> splitLines
diff --git a/tests/fsharp/FSharp.Tests.fsproj b/tests/fsharp/FSharp.Tests.fsproj
new file mode 100644
index 00000000000..ddc781d051c
--- /dev/null
+++ b/tests/fsharp/FSharp.Tests.fsproj
@@ -0,0 +1,1108 @@
+
+
+
+ ..\..\src
+ {C163E892-5BF7-4B59-AA99-B0E8079C67C4}
+
+
+
+ Debug
+ AnyCPU
+ 2.0
+ true
+ true
+ Library
+ FSharp.Tests.FSharp
+ SystematicUnitTests
+
+ false
+ false
+
+
+ $(DefineConstants);EXTENSIONTYPING
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 3
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 3
+
+
+
+
+ {DED3BBD7-53F4-428A-8C9F-27968E768605}
+ FSharp.Core
+
+
+
+ ..\..\packages\NUnit.3.0.0-beta-3\lib\net45\nunit.framework.dll
+ True
+
+
+
+
+
+
+
+
+
+ windowsPlatform.fs
+
+
+ config.fs
+
+
+ update.fs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/fsharp/FSharpTestSuiteTypes.fs b/tests/fsharp/FSharpTestSuiteTypes.fs
new file mode 100644
index 00000000000..6596a928daf
--- /dev/null
+++ b/tests/fsharp/FSharpTestSuiteTypes.fs
@@ -0,0 +1,69 @@
+module FSharpTestSuiteTypes
+
+open PlatformHelpers
+
+type RunError =
+ | GenericError of string
+ | ProcessExecError of (int * string)
+ | Skipped of string
+
+type Permutation =
+ | FSI_FILE
+ | FSI_STDIN
+ | FSI_STDIN_OPT
+ | FSI_STDIN_GUI
+ | FSC_BASIC
+ | FSC_BASIC_64
+ | FSC_HW
+ | FSC_O3
+ | GENERATED_SIGNATURE
+ | EMPTY_SIGNATURE
+ | EMPTY_SIGNATURE_OPT
+ | FSC_OPT_MINUS_DEBUG
+ | FSC_OPT_PLUS_DEBUG
+ | FRENCH
+ | SPANISH
+ | AS_DLL
+ | WRAPPER_NAMESPACE
+ | WRAPPER_NAMESPACE_OPT
+ override this.ToString() = (sprintf "%A" this)
+
+type TestConfig =
+ { EnvironmentVariables : Map
+ ALINK : string
+ CORDIR : string
+ CORSDK : string
+ CSC : string
+ csc_flags : string
+ FSC : string
+ fsc_flags : string
+ FSCBinPath : string
+ FSCOREDLL20PATH : string
+ FSCOREDLLPATH : string
+ FSCOREDLLPORTABLEPATH : string
+ FSCOREDLLNETCOREPATH : string
+ FSCOREDLLNETCORE78PATH : string
+ FSCOREDLLNETCORE259PATH : string
+ FSDATATPPATH : string
+ FSCOREDLLVPREVPATH : string
+ FSDIFF : string
+ FSI : string
+ fsi_flags : string
+ GACUTIL : string
+ ILDASM : string
+ INSTALL_SKU : INSTALL_SKU option
+ MSBUILDTOOLSPATH : string option
+ NGEN : string
+ PEVERIFY : string
+ RESGEN : string
+ MSBUILD : string option }
+
+and INSTALL_SKU =
+ | Clean
+ | DesktopExpress
+ | WebExpress
+ | Ultimate
+
+type TestRunContext =
+ { Directory: string;
+ Config: TestConfig }
diff --git a/tests/fsharp/PickPermutations.ps1 b/tests/fsharp/PickPermutations.ps1
index b31532a0864..1e35c113969 100644
--- a/tests/fsharp/PickPermutations.ps1
+++ b/tests/fsharp/PickPermutations.ps1
@@ -26,6 +26,6 @@ $specialCaseCriteria = @{
# seed for random selection is based on build # and test area
# this ensures re-runs are predictable, but different test areas get different random choices
$seed = (dir $fscPath).VersionInfo.FileBuildPart -bxor $testPath.GetHashCode()
-$permutations = ($allPermutations -split '\s+') |?{ $specialCaseCriteria[$_] -ne $false } | Get-Random -SetSeed $seed
+$permutations = ($allPermutations -split '\s+') |?{ $specialCaseCriteria[$_] -ne $false } #| Get-Random -SetSeed $seed
$permutations -join ' '
\ No newline at end of file
diff --git a/tests/fsharp/PlatformHelpers.fs b/tests/fsharp/PlatformHelpers.fs
new file mode 100644
index 00000000000..d85a5792f5d
--- /dev/null
+++ b/tests/fsharp/PlatformHelpers.fs
@@ -0,0 +1,204 @@
+module PlatformHelpers
+
+type ProcessorArchitecture =
+ | X86
+ | IA64
+ | AMD64
+ | Unknown of string
+ override this.ToString() =
+ match this with
+ | X86 -> "x86"
+ | IA64 -> "IA64"
+ | AMD64 -> "AMD64"
+ | Unknown arc -> arc
+
+open System.IO
+
+type FilePath = string
+
+type CmdResult =
+ | Success
+ | ErrorLevel of int
+
+type CmdArguments =
+ { RedirectOutput : (string -> unit) option
+ RedirectError : (string -> unit) option
+ RedirectInput : (StreamWriter -> unit) option }
+
+module Process =
+
+ open System.Diagnostics
+
+ let processExePath baseDir exe =
+ if Path.IsPathRooted(exe) then exe
+ else
+ match Path.GetDirectoryName(exe) with
+ | "" -> exe
+ | _ -> Path.Combine(baseDir,exe) |> Path.GetFullPath
+
+ let exec cmdArgs (workDir: FilePath) envs (path: FilePath) arguments =
+
+ let exePath = path |> processExePath workDir
+ let processInfo = new ProcessStartInfo(exePath, arguments)
+ processInfo.CreateNoWindow <- true
+ processInfo.UseShellExecute <- false
+ processInfo.WorkingDirectory <- workDir
+
+ envs
+ |> Map.iter (fun k v -> processInfo.EnvironmentVariables.[k] <- v)
+
+ let p = new Process()
+ p.EnableRaisingEvents <- true
+ p.StartInfo <- processInfo
+
+ cmdArgs.RedirectOutput
+ |> Option.map (fun f -> (fun (ea: DataReceivedEventArgs) -> ea.Data |> f))
+ |> Option.iter (fun newOut ->
+ processInfo.RedirectStandardOutput <- true
+ p.OutputDataReceived.Add newOut
+ )
+
+ cmdArgs.RedirectError
+ |> Option.map (fun f -> (fun (ea: DataReceivedEventArgs) -> ea.Data |> f))
+ |> Option.iter (fun newErr ->
+ processInfo.RedirectStandardError <- true
+ p.ErrorDataReceived.Add newErr
+ )
+
+ cmdArgs.RedirectInput
+ |> Option.iter (fun _ -> p.StartInfo.RedirectStandardInput <- true)
+
+ let exitedAsync (proc: Process) =
+ let tcs = new System.Threading.Tasks.TaskCompletionSource();
+ p.Exited.Add (fun s ->
+ tcs.TrySetResult(proc.ExitCode) |> ignore
+ proc.Dispose())
+ tcs.Task
+
+ p.Start() |> ignore
+
+ cmdArgs.RedirectOutput |> Option.iter (fun _ -> p.BeginOutputReadLine())
+ cmdArgs.RedirectError |> Option.iter (fun _ -> p.BeginErrorReadLine())
+
+ cmdArgs.RedirectInput
+ |> Option.map (fun input -> async {
+ let inputWriter = p.StandardInput
+ do! inputWriter.FlushAsync () |> Async.AwaitIAsyncResult |> Async.Ignore
+ input inputWriter
+ do! inputWriter.FlushAsync () |> Async.AwaitIAsyncResult |> Async.Ignore
+ inputWriter.Close ()
+ })
+ |> Option.iter Async.Start
+
+ let exitCode = p |> exitedAsync |> Async.AwaitTask |> Async.RunSynchronously
+
+ match exitCode with
+ | 0 -> Success
+ | err -> ErrorLevel err
+
+
+
+type Result<'S,'F> =
+ | Success of 'S
+ | Failure of 'F
+
+type Attempt<'S,'F> = (unit -> Result<'S,'F>)
+
+open System.Diagnostics
+
+[]
+let internal succeed x = (fun () -> Success x)
+
+[]
+let internal failed err = (fun () -> Failure err)
+
+[]
+let runAttempt (a: Attempt<_,_>) = a ()
+
+[]
+let delay f = (fun () -> f() |> runAttempt)
+
+[]
+let either successTrack failTrack (input : Attempt<_, _>) : Attempt<_, _> =
+ match runAttempt input with
+ | Success s -> successTrack s
+ | Failure f -> failTrack f
+
+[]
+let bind successTrack = either successTrack failed
+
+[]
+let fail failTrack result = either succeed failTrack result
+
+[]
+type Attempt =
+ static member Run x = runAttempt x
+
+[]
+type AttemptBuilder() =
+ member this.Bind(m : Attempt<_, _>, success) = bind success m
+ member this.Bind(m : Result<_, _>, success) = bind success (fun () -> m)
+ member this.Bind(m : Result<_, _> option, success) =
+ match m with
+ | None -> this.Combine(this.Zero(), success)
+ | Some x -> this.Bind(x, success)
+ member this.Return(x) : Attempt<_, _> = succeed x
+ member this.ReturnFrom(x : Attempt<_, _>) = x
+ member this.Combine(v, f) : Attempt<_, _> = bind f v
+ member this.Yield(x) = Success x
+ member this.YieldFrom(x) = x
+ member this.Delay(f) : Attempt<_, _> = delay f
+ member this.Zero() : Attempt<_, _> = succeed ()
+ member this.While(guard, body: Attempt<_, _>) =
+ if not (guard())
+ then this.Zero()
+ else this.Bind(body, fun () ->
+ this.While(guard, body))
+
+ member this.TryWith(body, handler) =
+ try this.ReturnFrom(body())
+ with e -> handler e
+
+ member this.TryFinally(body, compensation) =
+ try this.ReturnFrom(body())
+ finally compensation()
+
+ member this.Using(disposable:#System.IDisposable, body) =
+ let body' = fun () -> body disposable
+ this.TryFinally(body', fun () ->
+ match disposable with
+ | null -> ()
+ | disp -> disp.Dispose())
+
+ member this.For(sequence:seq<'a>, body: 'a -> Attempt<_,_>) =
+ this.Using(sequence.GetEnumerator(),fun enum ->
+ this.While(enum.MoveNext,
+ this.Delay(fun () -> body enum.Current)))
+
+let processor = new AttemptBuilder()
+
+
+let log format = Printf.ksprintf (printfn "%s") format
+
+type OutPipe (mailbox: MailboxProcessor<_>) =
+ member x.Post msg = mailbox.Post(msg)
+ interface System.IDisposable with
+ member x.Dispose () =
+ async {
+ while mailbox.CurrentQueueLength > 0 do
+ let timeout = System.TimeSpan.FromMilliseconds(50.0)
+ do! Async.Sleep (timeout.TotalMilliseconds |> int)
+ } |> Async.RunSynchronously
+
+let redirectTo (writer: TextWriter) =
+ let mailbox = MailboxProcessor.Start(fun inbox ->
+ let rec loop () = async {
+ let! (msg : string) = inbox.Receive ()
+ do! writer.WriteLineAsync(msg) |> (Async.AwaitIAsyncResult >> Async.Ignore)
+ return! loop () }
+ loop ())
+ new OutPipe (mailbox)
+
+let redirectToLog () = redirectTo System.Console.Out
+
+let inline (/) a (b: string) = System.IO.Path.Combine(a,b)
diff --git a/tests/fsharp/Properties/AssemblyInfo.cs b/tests/fsharp/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000000..11e3bfec935
--- /dev/null
+++ b/tests/fsharp/Properties/AssemblyInfo.cs
@@ -0,0 +1,33 @@
+// Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("145B8577-B5E8-46A0-9FDF-2FB99C4D3573")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/tests/fsharp/core/.gitignore b/tests/fsharp/core/.gitignore
index e395d5b7827..34c12b24af2 100644
--- a/tests/fsharp/core/.gitignore
+++ b/tests/fsharp/core/.gitignore
@@ -51,3 +51,8 @@ topinit/both69514-noopt.pdb
verify/xmlverify.exe
verify/xmlverify.pdb
+
+fsi-reload/load1.exe
+fsi-reload/load2.exe
+
+quotesInMultipleModules/module2-staticlink.exe
diff --git a/tests/fsharp/core/tests_core.fs b/tests/fsharp/core/tests_core.fs
new file mode 100644
index 00000000000..b3b600546a0
--- /dev/null
+++ b/tests/fsharp/core/tests_core.fs
@@ -0,0 +1,2683 @@
+module ``FSharp-Tests-Core``
+
+open System
+open System.IO
+open NUnit.Framework
+
+open NUnitConf
+open PlatformHelpers
+open FSharpTestSuiteTypes
+
+let testContext = FSharpTestSuite.testContext
+
+let requireVSUltimate cfg = processor {
+ do! match cfg.INSTALL_SKU with
+ | Some (Ultimate) -> Success
+ | x ->
+ // IF /I "%INSTALL_SKU%" NEQ "ULTIMATE" (
+ // echo Test not supported except on Ultimate
+ NUnitConf.skip (sprintf "Test not supported except on Ultimate, was %A" x)
+ // exit /b 0
+ // )
+ }
+
+module Access =
+ []
+ let access p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+module Apporder =
+ []
+ let apporder p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+module Array =
+ []
+ let array p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+module Attributes =
+ []
+ let attributes p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+module Comprehensions =
+ []
+ let comprehensions p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+module Control =
+ []
+ let control p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+ []
+ let ``control --tailcalls`` p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun {cfg with fsi_flags = " --tailcalls" } dir p
+ })
+
+module ControlChamenos =
+ []
+ let controlChamenos p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun { cfg with fsi_flags = " --tailcalls" } dir p
+ })
+
+module ControlMailbox =
+ []
+ let controlMailbox p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+ []
+ let ``controlMailbox --tailcalls`` p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun { cfg with fsi_flags = " --tailcalls" } dir p
+ })
+
+module ControlWpf =
+ []
+ let controlWpf p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+module Csext =
+ []
+ let csext p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+module Events =
+
+ let build cfg dir = processor {
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None} p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let csc = Printf.ksprintf (Commands.csc exec cfg.CSC)
+
+ // "%FSC%" %fsc_flags% -a -o:test.dll -g test.fs
+ do! fsc "%s -a -o:test.dll -g" cfg.fsc_flags ["test.fs"]
+
+ // "%PEVERIFY%" test.dll
+ do! peverify "test.dll"
+
+ // %CSC% /r:"%FSCOREDLLPATH%" /reference:test.dll /debug+ testcs.cs
+ do! csc """/r:"%s" /reference:test.dll /debug+""" cfg.FSCOREDLLPATH ["testcs.cs"]
+
+ // "%PEVERIFY%" testcs.exe
+ do! peverify "testcs.exe"
+ }
+
+ let run cfg dir = processor {
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None} p >> checkResult
+ let fsi = Printf.ksprintf (Commands.fsi exec cfg.FSI)
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ use testOkFile = fileguard "test.ok"
+
+ // %CLIX% "%FSI%" test.fs && (
+ do! fsi "" ["test.fs"]
+
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo :FSI failed;
+ // goto Error
+ // set ERRORMSG=%ERRORMSG% FSI failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+
+ // %CLIX% .\testcs.exe
+ do! exec ("."/"testcs.exe") ""
+ }
+
+ []
+ let events () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+ })
+
+
+module ``FSI-Shadowcopy`` =
+
+ []
+ // "%FSI%" %fsi_flags% < test1.fsx
+ []
+ // "%FSI%" %fsi_flags% --shadowcopyreferences- < test1.fsx
+ []
+ let ``shadowcopy disabled`` (flags: string) = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let ``exec <`` l p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = Some(RedirectInput(l)) } p >> checkResult
+ let ``fsi <`` = Printf.ksprintf (fun flags l -> Commands.fsi (``exec <`` l) cfg.FSI flags [])
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ // if exist test1.ok (del /f /q test1.ok)
+ use testOkFile = fileguard "test1.ok"
+
+ do! ``fsi <`` "%s %s" cfg.fsi_flags flags "test1.fsx"
+
+ // if NOT EXIST test1.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+ })
+
+ []
+ // "%FSI%" %fsi_flags% /shadowcopyreferences+ < test2.fsx
+ []
+ // "%FSI%" %fsi_flags% --shadowcopyreferences < test2.fsx
+ []
+ let ``shadowcopy enabled`` (flags: string) = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let ``exec <`` l p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = Some(RedirectInput(l)) } p >> checkResult
+ let ``fsi <`` = Printf.ksprintf (fun flags l -> Commands.fsi (``exec <`` l) cfg.FSI flags [])
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ // if exist test2.ok (del /f /q test2.ok)
+ use testOkFile = fileguard "test2.ok"
+
+ // "%FSI%" %fsi_flags% /shadowcopyreferences+ < test2.fsx
+ do! ``fsi <`` "%s %s" cfg.fsi_flags flags "test2.fsx"
+
+ // if NOT EXIST test2.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+ })
+
+
+
+module Forwarders =
+
+ []
+ let forwarders () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let csc = Printf.ksprintf (Commands.csc exec cfg.CSC)
+ let copy_y f = Commands.copy_y dir f >> checkResult
+ let mkdir = Commands.mkdir_p dir
+
+ // mkdir orig
+ mkdir "orig"
+ // mkdir split
+ mkdir "split"
+
+ // %CSC% /nologo /target:library /out:orig\a.dll /define:PART1;PART2 a.cs
+ do! csc """/nologo /target:library /out:orig\a.dll /define:PART1;PART2""" ["a.cs"]
+
+ // %CSC% /nologo /target:library /out:orig\b.dll /r:orig\a.dll b.cs
+ do! csc """/nologo /target:library /out:orig\b.dll /r:orig\a.dll""" ["b.cs"]
+
+ // "%FSC%" -a -o:orig\c.dll -r:orig\b.dll -r:orig\a.dll c.fs
+ do! fsc """-a -o:orig\c.dll -r:orig\b.dll -r:orig\a.dll""" ["c.fs"]
+
+ // %CSC% /nologo /target:library /out:split\a-part1.dll /define:PART1;SPLIT a.cs
+ do! csc """/nologo /target:library /out:split\a-part1.dll /define:PART1;SPLIT""" ["a.cs"]
+
+ // %CSC% /nologo /target:library /r:split\a-part1.dll /out:split\a.dll /define:PART2;SPLIT a.cs
+ do! csc """/nologo /target:library /r:split\a-part1.dll /out:split\a.dll /define:PART2;SPLIT""" ["a.cs"]
+
+ // copy /y orig\b.dll split\b.dll
+ do! copy_y ("orig"/"b.dll") ("split"/"b.dll")
+ // copy /y orig\c.dll split\c.dll
+ do! copy_y ("orig"/"c.dll") ("split"/"c.dll")
+
+ // "%FSC%" -o:orig\test.exe -r:orig\b.dll -r:orig\a.dll test.fs
+ do! fsc """-o:orig\test.exe -r:orig\b.dll -r:orig\a.dll""" ["test.fs"]
+
+ // "%FSC%" -o:split\test.exe -r:split\b.dll -r:split\a-part1.dll -r:split\a.dll test.fs
+ do! fsc """-o:split\test.exe -r:split\b.dll -r:split\a-part1.dll -r:split\a.dll""" ["test.fs"]
+
+ // "%FSC%" -o:split\test-against-c.exe -r:split\c.dll -r:split\a-part1.dll -r:split\a.dll test.fs
+ do! fsc """-o:split\test-against-c.exe -r:split\c.dll -r:split\a-part1.dll -r:split\a.dll""" ["test.fs"]
+
+ // pushd split
+ // "%PEVERIFY%" a-part1.dll
+ do! peverify ("split"/"a-part1.dll")
+
+ // REM "%PEVERIFY%" a.dll
+ // REM @if ERRORLEVEL 1 goto Error
+
+ // "%PEVERIFY%" b.dll
+ do! peverify ("split"/"b.dll")
+
+ // "%PEVERIFY%" c.dll
+ do! peverify ("split"/"c.dll")
+
+ // "%PEVERIFY%" test.exe
+ do! peverify ("split"/"test.exe")
+
+ // "%PEVERIFY%" test-against-c.exe
+ do! peverify ("split"/"test-against-c.exe")
+
+ // popd
+
+ })
+
+module FsFromCs =
+
+ let build cfg dir = processor {
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let csc = Printf.ksprintf (Commands.csc exec cfg.CSC)
+ let fsc_flags = cfg.fsc_flags
+
+ // "%FSC%" %fsc_flags% -a --doc:lib.xml -o:lib.dll -g lib.ml
+ do! fsc "%s -a --doc:lib.xml -o:lib.dll -g" fsc_flags ["lib.ml"]
+
+ // "%PEVERIFY%" lib.dll
+ do! peverify "lib.dll"
+
+ // %CSC% /nologo /r:"%FSCOREDLLPATH%" /r:System.Core.dll /r:lib.dll /out:test.exe test.cs
+ do! csc """/nologo /r:"%s" /r:System.Core.dll /r:lib.dll /out:test.exe""" cfg.FSCOREDLLPATH ["test.cs"]
+
+ // "%FSC%" %fsc_flags% -a --doc:lib--optimize.xml -o:lib--optimize.dll -g lib.ml
+ do! fsc """%s -a --doc:lib--optimize.xml -o:lib--optimize.dll -g""" fsc_flags ["lib.ml"]
+
+ // "%PEVERIFY%" lib--optimize.dll
+ do! peverify "lib--optimize.dll"
+
+ // %CSC%
+ do! csc """/nologo /r:"%s" /r:System.Core.dll /r:lib--optimize.dll /out:test--optimize.exe""" cfg.FSCOREDLLPATH ["test.cs"]
+
+ }
+
+ let run cfg dir = processor {
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+
+ // %CLIX% .\test.exe
+ do! exec ("."/"test.exe") ""
+
+ // %CLIX% .\test--optimize.exe
+ do! exec ("."/"test--optimize.exe") ""
+
+ }
+
+ []
+ let fsfromcs () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+module FsFromFsViaCs =
+
+ let build cfg dir = processor {
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let csc = Printf.ksprintf (Commands.csc exec cfg.CSC)
+ let fsc_flags = cfg.fsc_flags
+
+ // "%FSC%" %fsc_flags% -a -o:lib.dll -g lib.ml
+ do! fsc "%s -a -o:lib.dll -g" fsc_flags ["lib.ml"]
+
+ // "%PEVERIFY%" lib.dll
+ do! peverify "lib.dll"
+
+ // %CSC% /nologo /target:library /r:"%FSCOREDLLPATH%" /r:lib.dll /out:lib2.dll lib2.cs
+ do! csc """/nologo /target:library /r:"%s" /r:lib.dll /out:lib2.dll""" cfg.FSCOREDLLPATH ["lib2.cs"]
+
+ // "%FSC%" %fsc_flags% -r:lib.dll -r:lib2.dll -o:test.exe -g test.fsx
+ do! fsc "%s -r:lib.dll -r:lib2.dll -o:test.exe -g" fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test.exe
+ do! peverify "test.exe"
+
+ }
+
+ let run cfg dir = processor {
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+
+ // %CLIX% .\test.exe
+ do! exec ("."/"test.exe") ""
+
+ }
+
+ []
+ let fsfromfsviacs () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+module ``FSI-reload`` =
+
+ []
+ let ``fsi-reload`` () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let ``exec <`` l p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = Some(RedirectInput(l)) } p >> checkResult
+ let ``fsi <`` = Printf.ksprintf (fun flags l -> Commands.fsi (``exec <`` l) cfg.FSI flags [])
+ let fsi = Printf.ksprintf (Commands.fsi exec cfg.FSI)
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+
+ /////// build.bat ///////
+
+ // REM NOTE that this test does not do anything.
+ // REM PEVERIFY not needed
+
+ /////// run.bat ////////
+
+ do! processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+ // "%FSI%" %fsi_flags% --maxerrors:1 < test1.ml
+ do! ``fsi <`` "%s --maxerrors:1" cfg.fsi_flags "test1.ml"
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ do! processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+ // "%FSI%" %fsi_flags% --maxerrors:1 load1.fsx
+ do! fsi "%s --maxerrors:1" cfg.fsi_flags ["load1.fsx"]
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ do! processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+ // "%FSI%" %fsi_flags% --maxerrors:1 load2.fsx
+ do! fsi "%s --maxerrors:1" cfg.fsi_flags ["load2.fsx"]
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ // REM Check we can also compile, for sanity's sake
+ // "%FSC%" load1.fsx
+ do! fsc "" ["load1.fsx"]
+
+ // REM Check we can also compile, for sanity's sake
+ // "%FSC%" load2.fsx
+ do! fsc "" ["load2.fsx"]
+
+ })
+
+
+module fsiAndModifiers =
+
+ let build cfg dir = processor {
+ let ``exec <`` l p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = Some(RedirectInput(l)) } p >> checkResult
+ let ``fsi <`` = Printf.ksprintf (fun flags l -> Commands.fsi (``exec <`` l) cfg.FSI flags [])
+ let del = Commands.rm dir
+ let exist = Commands.fileExists dir >> Option.isSome
+
+ // if exist TestLibrary.dll (del /f /q TestLibrary.dll)
+ do if exist "TestLibrary.dll" then del "TestLibrary.dll"
+
+ // "%FSI%" %fsi_flags% --maxerrors:1 < prepare.fsx
+ do! ``fsi <`` "%s --maxerrors:1" cfg.fsi_flags "prepare.fsx"
+
+ }
+
+ let run cfg dir = processor {
+ let ``exec <`` l p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = Some(RedirectInput(l)) } p >> checkResult
+ let ``fsi <`` = Printf.ksprintf (fun flags l -> Commands.fsi (``exec <`` l) cfg.FSI flags [])
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+
+ // "%FSI%" %fsi_flags% --maxerrors:1 < test.fsx
+ do! ``fsi <`` "%s --maxerrors:1" cfg.fsi_flags "test.fsx"
+
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+
+ }
+
+ []
+ let fsiAndModifiers () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+module GenericMeasures =
+
+ []
+ let genericmeasures p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+module Hiding =
+
+ []
+ let hiding () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let fsc_flags = cfg.fsc_flags
+
+ // "%FSC%" %fsc_flags% -a --optimize -o:lib.dll lib.mli lib.ml libv.ml
+ do! fsc "%s -a --optimize -o:lib.dll" fsc_flags ["lib.mli";"lib.ml";"libv.ml"]
+
+ // "%PEVERIFY%" lib.dll
+ do! peverify "lib.dll"
+
+ // "%FSC%" %fsc_flags% -a --optimize -r:lib.dll -o:lib2.dll lib2.mli lib2.ml lib3.ml
+ do! fsc "%s -a --optimize -r:lib.dll -o:lib2.dll" fsc_flags ["lib2.mli";"lib2.ml";"lib3.ml"]
+
+ // "%PEVERIFY%" lib2.dll
+ do! peverify "lib2.dll"
+
+ // "%FSC%" %fsc_flags% --optimize -r:lib.dll -r:lib2.dll -o:client.exe client.ml
+ do! fsc "%s --optimize -r:lib.dll -r:lib2.dll -o:client.exe" fsc_flags ["client.ml"]
+
+ // "%PEVERIFY%" client.exe
+ do! peverify "client.exe"
+
+ })
+
+
+module Innerpoly =
+
+ []
+ let innerpoly p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+module ``test int32`` =
+
+ []
+ let int32 p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+module QueriesCustomQueryOps =
+
+ let build cfg dir = processor {
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let csc = Printf.ksprintf (Commands.csc exec cfg.CSC)
+ let fsc_flags = cfg.fsc_flags
+
+ // "%FSC%" %fsc_flags% -o:test.exe -g test.fsx
+ do! fsc """%s -o:test.exe -g""" fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test.exe
+ do! peverify "test.exe"
+
+ // "%FSC%" %fsc_flags% --optimize -o:test--optimize.exe -g test.fsx
+ do! fsc """%s --optimize -o:test--optimize.exe -g""" fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test--optimize.exe
+ do! peverify "test--optimize.exe"
+
+ // call ..\..\single-neg-test.bat negativetest
+ do! SingleNegTest.singleNegTest cfg dir "negativetest"
+
+ }
+
+ let run cfg dir = processor {
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsi = Printf.ksprintf (Commands.fsi exec cfg.FSI)
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ // echo TestC
+ log "TestC"
+ do! processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+
+ // "%FSI%" %fsi_flags% test.fsx
+ do! fsi "%s" cfg.fsi_flags ["test.fsx"]
+
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ // echo TestD
+ log "TestD"
+ do! processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+
+ // %CLIX% test.exe
+ do! exec ("."/"test.exe") ""
+
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ do! processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+
+ // %CLIX% test--optimize.exe
+ do! exec ("."/"test--optimize.exe") ""
+
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ }
+
+ []
+ let queriesCustomQueryOps () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+[]
+module Printing =
+
+ // "%FSI%" %fsc_flags_errors_ok% --nologo --use:preludePrintSize200.fsx z.raw.output.test.200.txt 2>&1
+ // findstr /v "%CD%" z.raw.output.test.200.txt | findstr /v -C:"--help' for options" > z.output.test.200.txt
+ // if NOT EXIST z.output.test.200.bsl COPY z.output.test.200.txt z.output.test.200.bsl
+ // %PRDIFF% z.output.test.200.txt z.output.test.200.bsl > z.output.test.200.diff
+ []
+ [] //not enough
+ []
+ []
+ []
+ []
+ []
+ let printing flag diffFile expectedFile = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let copy from' = Commands.copy_y dir from' >> checkResult
+ let fileExists = Commands.fileExists dir >> Option.isSome
+ let getfullpath = Commands.getfullpath dir
+
+ let ``fsi b 2>&1`` =
+ // "%FSI%" %fsc_flags_errors_ok% --nologo z.raw.output.test.default.txt 2>&1
+ let ``exec b 2>&1`` inFile outFile p =
+ Command.exec dir cfg.EnvironmentVariables { Output = OutputAndError(Overwrite(outFile)); Input = Some(RedirectInput(inFile)); } p
+ >> checkResult
+ Printf.ksprintf (fun flags in' out -> Commands.fsi (``exec b 2>&1`` in' out) cfg.FSI flags [])
+
+ let fsdiff a b =
+ let ``exec >`` f p = Command.exec dir cfg.EnvironmentVariables { Output = Output(Overwrite(f)); Input = None} p >> checkResult
+ let diffFile = Path.ChangeExtension(a, ".diff")
+ Commands.fsdiff (``exec >`` diffFile) cfg.FSDIFF false a b
+
+ let fsc_flags_errors_ok = ""
+
+ // echo == Plain
+ // "%FSI%" %fsc_flags_errors_ok% --nologo z.raw.output.test.default.txt 2>&1
+ // echo == PrintSize 1000
+ // "%FSI%" %fsc_flags_errors_ok% --nologo --use:preludePrintSize1000.fsx z.raw.output.test.1000.txt 2>&1
+ // echo == PrintSize 200
+ // "%FSI%" %fsc_flags_errors_ok% --nologo --use:preludePrintSize200.fsx z.raw.output.test.200.txt 2>&1
+ // echo == ShowDeclarationValues off
+ // "%FSI%" %fsc_flags_errors_ok% --nologo --use:preludeShowDeclarationValuesFalse.fsx z.raw.output.test.off.txt 2>&1
+ // echo == Quiet
+ // "%FSI%" %fsc_flags_errors_ok% --nologo --quiet z.raw.output.test.quiet.txt 2>&1
+ let rawFile = Path.GetTempFileName()
+ do! ``fsi b 2>&1`` "%s --nologo %s" fsc_flags_errors_ok flag "test.fsx" rawFile
+
+ // REM REVIEW: want to normalise CWD paths, not suppress them.
+ let ``findstr /v`` text = Seq.filter (fun (s: string) -> not <| s.Contains(text))
+ let removeCDandHelp from' to' =
+ File.ReadLines from' |> (``findstr /v`` dir) |> (``findstr /v`` "--help' for options") |> (fun lines -> File.WriteAllLines(getfullpath to', lines))
+
+ // findstr /v "%CD%" z.raw.output.test.default.txt | findstr /v -C:"--help' for options" > z.output.test.default.txt
+ // findstr /v "%CD%" z.raw.output.test.1000.txt | findstr /v -C:"--help' for options" > z.output.test.1000.txt
+ // findstr /v "%CD%" z.raw.output.test.200.txt | findstr /v -C:"--help' for options" > z.output.test.200.txt
+ // findstr /v "%CD%" z.raw.output.test.off.txt | findstr /v -C:"--help' for options" > z.output.test.off.txt
+ // findstr /v "%CD%" z.raw.output.test.quiet.txt | findstr /v -C:"--help' for options" > z.output.test.quiet.txt
+ removeCDandHelp rawFile diffFile
+
+ let withDefault default' to' =
+ if not (fileExists to') then Some (copy default' to') else None
+ // if NOT EXIST z.output.test.default.bsl COPY z.output.test.default.txt z.output.test.default.bsl
+ // if NOT EXIST z.output.test.off.bsl COPY z.output.test.off.txt z.output.test.off.bsl
+ // if NOT EXIST z.output.test.1000.bsl COPY z.output.test.1000.txt z.output.test.1000.bsl
+ // if NOT EXIST z.output.test.200.bsl COPY z.output.test.200.txt z.output.test.200.bsl
+ // if NOT EXIST z.output.test.quiet.bsl COPY z.output.test.quiet.txt z.output.test.quiet.bsl
+ do! expectedFile |> withDefault diffFile
+
+ // %PRDIFF% z.output.test.default.txt z.output.test.default.bsl > z.output.test.default.diff
+ // %PRDIFF% z.output.test.off.txt z.output.test.off.bsl > z.output.test.off.diff
+ // %PRDIFF% z.output.test.1000.txt z.output.test.1000.bsl > z.output.test.1000.diff
+ // %PRDIFF% z.output.test.200.txt z.output.test.200.bsl > z.output.test.200.diff
+ // %PRDIFF% z.output.test.quiet.txt z.output.test.quiet.bsl > z.output.test.quiet.diff
+ do! fsdiff diffFile expectedFile
+
+ // echo ======== Differences From ========
+ // TYPE z.output.test.default.diff
+ // TYPE z.output.test.off.diff
+ // TYPE z.output.test.1000.diff
+ // TYPE z.output.test.200.diff
+ // TYPE z.output.test.quiet.diff
+ // echo ========= Differences To =========
+ //
+ // TYPE z.output.test.default.diff > zz.alldiffs
+ // TYPE z.output.test.off.diff >> zz.alldiffs
+ // TYPE z.output.test.1000.diff >> zz.alldiffs
+ // TYPE z.output.test.200.diff >> zz.alldiffs
+ // TYPE z.output.test.quiet.diff >> zz.alldiffs
+ //
+ // for /f %%c IN (zz.alldiffs) do (
+ // echo NOTE -------------------------------------
+ // echo NOTE ---------- THERE ARE DIFFs ----------
+ // echo NOTE -------------------------------------
+ // echo .
+ // echo To update baselines: "sd edit *bsl", "del *bsl", "build.bat" regenerates bsl, "sd diff ...", check what changed.
+ // goto Error
+ // )
+ ignore "printed to log"
+
+
+ })
+
+module Quotes =
+
+ let build cfg dir = processor {
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let fsc_flags = cfg.fsc_flags
+ let csc = Printf.ksprintf (Commands.csc exec cfg.CSC)
+
+ //missing csc
+ do! csc """/nologo /target:library /out:cslib.dll""" ["cslib.cs"]
+
+ // "%FSC%" %fsc_flags% -o:test.exe -r cslib.dll -g test.fsx
+ do! fsc "%s -o:test.exe -r cslib.dll -g" fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test.exe
+ do! peverify "test.exe"
+
+ // "%FSC%" %fsc_flags% -o:test-with-debug-data.exe --quotations-debug+ -r cslib.dll -g test.fsx
+ do! fsc "%s -o:test-with-debug-data.exe --quotations-debug+ -r cslib.dll -g" fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test-with-debug-data.exe
+ do! peverify "test-with-debug-data.exe"
+
+ // "%FSC%" %fsc_flags% --optimize -o:test--optimize.exe -r cslib.dll -g test.fsx
+ do! fsc "%s --optimize -o:test--optimize.exe -r cslib.dll -g" fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test--optimize.exe
+ do! peverify "test--optimize.exe"
+
+ }
+
+ let run cfg dir = processor {
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsi = Printf.ksprintf (Commands.fsi exec cfg.FSI)
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ do! processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+
+ // "%FSI%" %fsi_flags% -r cslib.dll test.fsx
+ do! fsi "%s -r cslib.dll" cfg.fsi_flags ["test.fsx"]
+
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ do! processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+
+ // %CLIX% test.exe
+ do! exec ("."/"test.exe") ""
+
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ do! processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+
+ // %CLIX% test-with-debug-data.exe
+ do! exec ("."/"test-with-debug-data.exe") ""
+
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ do! processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+
+ // %CLIX% test--optimize.exe
+ do! exec ("."/"test--optimize.exe") ""
+
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ }
+
+ []
+ let quotes () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+module Namespaces =
+
+ []
+ let attributes p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+module Parsing =
+
+ []
+ let parsing () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let fsc_flags = cfg.fsc_flags
+
+ // "%FSC%" %fsc_flags% -a -o:crlf.dll -g crlf.ml
+ do! fsc "%s -a -o:crlf.dll -g" fsc_flags ["crlf.ml"]
+
+ // "%FSC%" %fsc_flags% -o:toplet.exe -g toplet.ml
+ do! fsc "%s -o:toplet.exe -g" fsc_flags ["toplet.ml"]
+
+ // "%PEVERIFY%" toplet.exe
+ do! peverify "toplet.exe"
+
+ })
+
+module Unicode =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let fsc_flags = cfg.fsc_flags
+
+ // REM just checking the files actually parse/compile for now....
+
+ // "%FSC%" %fsc_flags% -a -o:kanji-unicode-utf8-nosig-codepage-65001.dll -g kanji-unicode-utf8-nosig-codepage-65001.fs
+ do! fsc "%s -a -o:kanji-unicode-utf8-nosig-codepage-65001.dll -g" fsc_flags ["kanji-unicode-utf8-nosig-codepage-65001.fs"]
+
+ // "%FSC%" %fsc_flags% -a -o:kanji-unicode-utf8-nosig-codepage-65001.dll -g kanji-unicode-utf8-nosig-codepage-65001.fs
+ do! fsc "%s -a -o:kanji-unicode-utf8-nosig-codepage-65001.dll -g" fsc_flags ["kanji-unicode-utf8-nosig-codepage-65001.fs"]
+
+ let codepage = processor {
+ // "%FSC%" %fsc_flags% -a -o:kanji-unicode-utf16.dll -g kanji-unicode-utf16.fs
+ do! fsc "%s -a -o:kanji-unicode-utf16.dll -g" fsc_flags ["kanji-unicode-utf16.fs"]
+
+ // "%FSC%" %fsc_flags% -a --codepage:65000 -o:kanji-unicode-utf7-codepage-65000.dll -g kanji-unicode-utf7-codepage-65000.fs
+ do! fsc "%s -a --codepage:65000 -o:kanji-unicode-utf7-codepage-65000.dll -g" fsc_flags ["kanji-unicode-utf7-codepage-65000.fs"]
+ }
+
+ // REM check non-utf8 and --codepage flag for bootstrapped fsc.exe
+ // if NOT "%FSC:fscp=X%" == "%FSC%" (
+ do! if not <| cfg.FSC.Contains("fscp") then codepage else Success
+
+ // "%FSC%" %fsc_flags% -a -o:kanji-unicode-utf8-withsig-codepage-65001.dll -g kanji-unicode-utf8-withsig-codepage-65001.fs
+ do! fsc "%s -a -o:kanji-unicode-utf8-withsig-codepage-65001.dll -g" fsc_flags ["kanji-unicode-utf8-withsig-codepage-65001.fs"]
+ }
+
+ let run cfg dir = processor {
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsi = Printf.ksprintf (Commands.fsi exec cfg.FSI)
+ let fsi_flags = cfg.fsi_flags
+
+ // if exist test.ok (del /f /q test.ok)
+ ignore "unused"
+ // "%FSI%" %fsi_flags% --utf8output kanji-unicode-utf8-nosig-codepage-65001.fs
+ do! fsi "%s --utf8output" fsi_flags ["kanji-unicode-utf8-nosig-codepage-65001.fs"]
+
+ // if exist test.ok (del /f /q test.ok)
+ ignore "unused"
+ // "%FSI%" %fsi_flags% --utf8output --codepage:65001 kanji-unicode-utf8-withsig-codepage-65001.fs
+ do! fsi "%s --utf8output --codepage:65001" fsi_flags ["kanji-unicode-utf8-withsig-codepage-65001.fs"]
+
+ // if exist test.ok (del /f /q test.ok)
+ ignore "unused"
+ // "%FSI%" %fsi_flags% --utf8output kanji-unicode-utf8-withsig-codepage-65001.fs
+ do! fsi "%s --utf8output" fsi_flags ["kanji-unicode-utf8-withsig-codepage-65001.fs"]
+
+ // if exist test.ok (del /f /q test.ok)
+ ignore "unused"
+ // "%FSI%" %fsi_flags% --utf8output --codepage:65000 kanji-unicode-utf7-codepage-65000.fs
+ do! fsi "%s --utf8output --codepage:65000" fsi_flags ["kanji-unicode-utf7-codepage-65000.fs"]
+
+ // if exist test.ok (del /f /q test.ok)
+ ignore "unused"
+ // "%FSI%" %fsi_flags% --utf8output kanji-unicode-utf16.fs
+ do! fsi "%s --utf8output" fsi_flags ["kanji-unicode-utf16.fs"]
+ }
+
+
+ []
+ let unicode () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+ do! run cfg dir
+ })
+
+ []
+ let unicode2 p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ // call %~d0%~p0..\..\single-test-build.bat
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ // call %~d0%~p0..\..\single-test-run.bat
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+module InternalsVisible =
+
+ []
+ let internalsvisible () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let csc = Printf.ksprintf (Commands.csc exec cfg.CSC)
+ let fsc_flags = cfg.fsc_flags
+
+ // REM Test internals visible
+
+ // echo == Compiling F# Library
+ log "== Compiling F# Library"
+ // "%FSC%" %fsc_flags% --version:1.2.3 --keyfile:key.snk -a --optimize -o:library.dll library.fsi library.fs
+ do! fsc "%s --version:1.2.3 --keyfile:key.snk -a --optimize -o:library.dll" fsc_flags ["library.fsi"; "library.fs"]
+
+ // echo == Verifying F# Library
+ log "== Verifying F# Library"
+
+ // "%PEVERIFY%" library.dll
+ do! peverify "library.dll"
+
+ // echo == Compiling C# Library
+ log "== Compiling C# Library"
+ // %CSC% /target:library /keyfile:key.snk /out:librarycs.dll librarycs.cs
+ do! csc "/target:library /keyfile:key.snk /out:librarycs.dll" ["librarycs.cs"]
+
+ // echo == Verifying C# Library
+ log "== Verifying C# Library"
+ // "%PEVERIFY%" librarycs.dll
+ do! peverify "librarycs.dll"
+
+ // echo == Compiling F# main referencing C# and F# libraries
+ log "== Compiling F# main referencing C# and F# libraries"
+ // "%FSC%" %fsc_flags% --version:1.2.3 --keyfile:key.snk --optimize -r:library.dll -r:librarycs.dll -o:main.exe main.fs
+ do! fsc "%s --version:1.2.3 --keyfile:key.snk --optimize -r:library.dll -r:librarycs.dll -o:main.exe" fsc_flags ["main.fs"]
+
+ // echo == Verifying F# main
+ log "== Verifying F# main"
+ // "%PEVERIFY%" main.exe
+ do! peverify "main.exe"
+
+ // echo == Run F# main. Quick test!
+ log "== Run F# main. Quick test!"
+ // main.exe
+ do! exec ("."/"main.exe") ""
+ })
+
+
+module Interop =
+
+ let build cfg dir = processor {
+ let envVars =
+ cfg.EnvironmentVariables
+ |> Map.add "FSCOREDLLPATH" cfg.FSCOREDLLPATH
+ |> Map.add "FSCOREDLLNETCORE78PATH" cfg.FSCOREDLLNETCORE78PATH
+
+ let exec p = Command.exec dir envVars { Output = Inherit; Input = None; } p >> checkResult
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let msbuild = Printf.ksprintf (Commands.msbuild exec (cfg.MSBUILD.Value))
+
+ // rd /S /Q obj
+ // del /f /q *.pdb *.xml *.config *.dll *.exe
+
+ // "%MSBUILDTOOLSPATH%\msbuild.exe" PCL.fsproj
+ do! msbuild "" ["PCL.fsproj"]
+
+ // "%MSBUILDTOOLSPATH%\msbuild.exe" User.fsproj
+ do! msbuild "" ["User.fsproj"]
+
+ // %PEVERIFY% User.exe
+ do! peverify "User.exe"
+
+ }
+
+ let run cfg dir = processor {
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+
+ do! exec ("."/"User.exe") ""
+ }
+
+ []
+ let interop () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+module ``test lazy`` =
+
+ []
+ let ``lazy`` p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+module letrec =
+
+ []
+ let letrec p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+module LibTest =
+
+ []
+ let libtest p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+module Lift =
+
+ []
+ let lift p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+[]
+module ``Load-Script`` =
+
+ let ``script > a 2>&1`` cfg dir to' = processor {
+
+ let toPath = to' |> Commands.getfullpath dir
+
+ let alwaysSuccess _ = Success ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = OutputAndError(Append(toPath)); Input = None; } p >> alwaysSuccess
+ let ``exec <`` l p = Command.exec dir cfg.EnvironmentVariables { Output = OutputAndError(Append(toPath)); Input = Some(RedirectInput(l)) } p >> alwaysSuccess
+
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let type_append_tofile from = Commands.type_append_tofile dir from toPath
+ let echo text = Commands.echo_append_tofile dir text toPath
+ let fsi = Printf.ksprintf (Commands.fsi exec cfg.FSI)
+ let ``fsi <`` = Printf.ksprintf (fun flags l -> Commands.fsi (``exec <`` l) cfg.FSI flags [])
+ let fileExists = Commands.fileExists dir >> Option.isSome
+ let del = Commands.rm dir
+ let getfullpath = Commands.getfullpath dir
+
+ File.WriteAllText(toPath, "")
+
+ // del 3.exe 2>nul 1>nul
+ do if fileExists "3.exe" then getfullpath "3.exe" |> File.Delete
+ // type 1.fsx 2.fsx 3.fsx
+ ["1.fsx"; "2.fsx"; "3.fsx"] |> List.iter type_append_tofile
+ // echo Test 1=================================================
+ echo "Test 1================================================="
+ // "%FSC%" 3.fsx --nologo
+ do! fsc "--nologo" ["3.fsx"]
+ // 3.exe
+ do! exec ("."/"3.exe") ""
+ // del 3.exe
+ del "3.exe"
+ // echo Test 2=================================================
+ echo "Test 2================================================="
+ // "%FSI%" 3.fsx
+ do! fsi "" ["3.fsx"]
+ // echo Test 3=================================================
+ echo "Test 3================================================="
+ // "%FSI%" --nologo < pipescr
+ do! ``fsi <`` "--nologo" "pipescr"
+ // echo.
+ echo ""
+ // echo Test 4=================================================
+ echo "Test 4================================================="
+ // "%FSI%" usesfsi.fsx
+ do! fsi "" ["usesfsi.fsx"]
+ // echo Test 5=================================================
+ echo "Test 5================================================="
+ // "%FSC%" usesfsi.fsx --nologo
+ do! fsc "--nologo" ["usesfsi.fsx"]
+ // echo Test 6=================================================
+ echo "Test 6================================================="
+ // "%FSC%" usesfsi.fsx --nologo -r FSharp.Compiler.Interactive.Settings
+ do! fsc "--nologo -r FSharp.Compiler.Interactive.Settings" ["usesfsi.fsx"]
+ // echo Test 7=================================================
+ echo "Test 7================================================="
+ // "%FSI%" 1.fsx 2.fsx 3.fsx
+ do! fsi "" ["1.fsx";"2.fsx";"3.fsx"]
+ // echo Test 8=================================================
+ echo "Test 8================================================="
+ // "%FSI%" 3.fsx 2.fsx 1.fsx
+ do! fsi "" ["3.fsx";"2.fsx";"1.fsx"]
+ // echo Test 9=================================================
+ echo "Test 9================================================="
+ // "%FSI%" multiple-load-1.fsx
+ do! fsi "" ["multiple-load-1.fsx"]
+ // echo Test 10=================================================
+ echo "Test 10================================================="
+ // "%FSI%" multiple-load-2.fsx
+ do! fsi "" ["multiple-load-2.fsx"]
+ // echo Test 11=================================================
+ echo "Test 11================================================="
+ // "%FSC%" FlagCheck.fs --nologo
+ do! fsc "--nologo" ["FlagCheck.fs"]
+ // FlagCheck.exe
+ do! exec ("."/"FlagCheck.exe") ""
+ // del FlagCheck.exe
+ del "FlagCheck.exe"
+ // echo Test 12=================================================
+ echo "Test 12================================================="
+ // "%FSC%" FlagCheck.fsx --nologo
+ do! fsc "--nologo" ["FlagCheck.fsx"]
+ // FlagCheck.exe
+ do! exec ("."/"FlagCheck.exe") ""
+ // del FlagCheck.exe
+ del "FlagCheck.exe"
+ // echo Test 13=================================================
+ echo "Test 13================================================="
+ // "%FSI%" load-FlagCheckFs.fsx
+ do! fsi "" ["load-FlagCheckFs.fsx"]
+ // echo Test 14=================================================
+ echo "Test 14================================================="
+ // "%FSI%" FlagCheck.fsx
+ do! fsi "" ["FlagCheck.fsx"]
+ // echo Test 15=================================================
+ echo "Test 15================================================="
+ // "%FSI%" ProjectDriver.fsx
+ do! fsi "" ["ProjectDriver.fsx"]
+ // echo Test 16=================================================
+ echo "Test 16================================================="
+ // "%FSC%" ProjectDriver.fsx --nologo
+ do! fsc "--nologo" ["ProjectDriver.fsx"]
+ // ProjectDriver.exe
+ do! exec ("."/"ProjectDriver.exe") ""
+ // del ProjectDriver.exe
+ del "ProjectDriver.exe"
+ // echo Done ==================================================
+ echo "Done =================================================="
+ }
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let ``script > out.txt 2>&1`` () = ``script > a 2>&1`` cfg dir "out.txt"
+ let getfullpath = Commands.getfullpath dir
+
+ let fsdiff a b = processor {
+ let out = new ResizeArray()
+ let redirectOutputToFile path args =
+ log "%s %s" path args
+ let toLog = redirectToLog ()
+ Process.exec { RedirectOutput = Some (function null -> () | s -> out.Add(s)); RedirectError = Some toLog.Post; RedirectInput = None; } dir cfg.EnvironmentVariables path args
+ do! (Commands.fsdiff redirectOutputToFile cfg.FSDIFF true a b) |> (fun _ -> Success ())
+ return out.ToArray() |> List.ofArray
+ }
+
+
+ // script > out.txt 2>&1
+ do! ``script > out.txt 2>&1`` ()
+
+ // if NOT EXIST out.bsl COPY out.txt
+ ignore "useless, first run, same as use an empty file"
+
+ let normalizePaths f =
+ let text = File.ReadAllText(f)
+ let dummyPath = @"D:\staging\staging\src\tests\fsharp\core\load-script"
+ let contents = System.Text.RegularExpressions.Regex.Replace(text, System.Text.RegularExpressions.Regex.Escape(dir), dummyPath)
+ File.WriteAllText(f, contents)
+
+ normalizePaths (getfullpath "out.txt")
+
+ // %FSDIFF% out.txt out.bsl > out.diff
+ let! diffs = fsdiff (getfullpath "out.txt") (getfullpath "out.bsl")
+
+ // %FSDIFF% z.output.fsi.help.txt z.output.fsi.help.bsl > z.output.fsi.help.diff
+
+ // echo ======== Differences From ========
+ // TYPE out.diff
+ // echo ========= Differences To =========
+
+ // for /f %%c IN (out.diff do (
+ // echo .
+ // echo To update baselines: "sd edit *bsl", "del *bsl", "build.bat" regenerates bsl, "sd diff ...", check what changed.
+ // goto Error
+ // )
+ do! match diffs with
+ | [] -> Success
+ | l ->
+ // echo NOTE -------------------------------------
+ // echo NOTE ---------- THERE ARE DIFFs ----------
+ // echo NOTE -------------------------------------
+ log "NOTE -------------------------------------"
+ log "NOTE ---------- THERE ARE DIFFs ----------"
+ log "NOTE -------------------------------------"
+ NUnitConf.genericError (sprintf "'%s' and '%s' differ; %A" (getfullpath "out.txt") (getfullpath "out.bsl") diffs)
+ }
+
+ []
+ let ``load-script`` () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ })
+
+
+module LongNames =
+
+ []
+ let longnames p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+module ``test map`` =
+
+ []
+ let map p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+module Math =
+ //TODO math/lalgebra does not have build.bat/run.bat and #r "FSharp.Math.Providers.dll"
+
+ module Numbers =
+
+ []
+ let numbers p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+ module numbersVS2008 =
+
+ []
+ let numbersVS2008 p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+
+module Measures =
+
+ []
+ let measures p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+module Members =
+
+ //TODO members/console does not have build.bat/run.bat
+
+ (* REVIEW This test fail for FSI_STDIN*
+ Output:
+
+ // D:\github\fsharp\tests\fsharp\..\..\Debug\net40\bin\fsiAnyCPU.exe -r:System.Core.dll --nowarn:20 --define:INTERACTIVE --maxerrors:1 --abortonerror
+ //
+ // ERRORLEVEL 1
+
+ Fail only for with redirected input:
+ - FAIL: `fsiAnyCPU.exe ..args.. ` character (input ready) after stdin(5,1): error.
+ Redirect is too fast and fsi discard input when starting?
+ *)
+ []
+ module Basics =
+
+ []
+ let Basics p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+ module Ctree =
+
+ []
+ let ctree p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+ module Factors =
+
+ []
+ let factors p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+ module Incremental =
+
+ []
+ let incremental p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+ module Ops =
+
+ []
+ let ops p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+module Nested =
+
+ []
+ let nested p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+module NetCore =
+
+ module Netcore259 =
+
+ let build cfg dir = processor {
+ // IF /I "%INSTALL_SKU%" NEQ "ULTIMATE" (
+ // echo Test not supported except on Ultimate
+ // exit /b 0
+ // )
+ do! requireVSUltimate cfg
+
+ let envVars =
+ cfg.EnvironmentVariables
+ |> Map.add "FSCOREDLLNETCORE259PATH" cfg.FSCOREDLLNETCORE259PATH
+
+ let exec p = Command.exec dir envVars { Output = Inherit; Input = None; } p >> checkResult
+ let msbuild = Printf.ksprintf (Commands.msbuild exec (cfg.MSBUILD.Value))
+
+ // "%MSBUILDTOOLSPATH%\msbuild.exe" ..\netcore.sln /p:Configuration=Debug /p:TestProfile=Profile259 /t:Rebuild
+ do! msbuild "/p:Configuration=Debug /p:TestProfile=Profile259 /t:Rebuild" [".."/"netcore.sln"]
+
+ }
+
+ let run cfg dir = processor {
+ let getfullpath = Commands.getfullpath dir
+
+ // IF /I "%INSTALL_SKU%" NEQ "ULTIMATE" (
+ // echo Test not supported except on Ultimate
+ // exit /b 0
+ // )
+ do! requireVSUltimate cfg
+
+ // set CONTROL_FAILURES_LOG=%~dp0..\ConsoleApplication1\bin\Debug\Profile259\control_failures.log
+ let setLog = Map.add "CONTROL_FAILURES_LOG" (getfullpath ".."/"ConsoleApplication1"/"bin"/"Debug"/"Profile259"/"control_failures.log")
+
+ let exec p = Command.exec dir (cfg.EnvironmentVariables |> setLog) { Output = Inherit; Input = None; } p >> checkResult
+
+ // ..\ConsoleApplication1\bin\Debug\Profile259\PortableTestEntry.exe
+ do! exec (".."/"ConsoleApplication1"/"bin"/"Debug"/"Profile259"/"PortableTestEntry.exe") ""
+
+ }
+
+ []
+ let netcore259 () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+ module Netcore7 =
+
+ let build cfg dir = processor {
+ // IF /I "%INSTALL_SKU%" NEQ "ULTIMATE" (
+ // echo Test not supported except on Ultimate
+ // exit /b 0
+ // )
+ do! requireVSUltimate cfg
+
+ let envVars =
+ cfg.EnvironmentVariables
+ |> Map.add "FSCOREDLLNETCOREPATH" cfg.FSCOREDLLNETCOREPATH
+
+ let exec p = Command.exec dir envVars { Output = Inherit; Input = None; } p >> checkResult
+ let msbuild = Printf.ksprintf (Commands.msbuild exec (cfg.MSBUILD.Value))
+
+ // "%MSBUILDTOOLSPATH%\msbuild.exe" ..\netcore.sln /p:Configuration=Debug /p:TestProfile=Profile7 /t:Rebuild
+ do! msbuild "/p:Configuration=Debug /p:TestProfile=Profile7 /t:Rebuild" [".."/"netcore.sln"]
+ }
+
+ let run cfg dir = processor {
+ let getfullpath = Commands.getfullpath dir
+
+ // IF /I "%INSTALL_SKU%" NEQ "ULTIMATE" (
+ // echo Test not supported except on Ultimate
+ // exit /b 0
+ // )
+ do! requireVSUltimate cfg
+
+ // set CONTROL_FAILURES_LOG=%~dp0..\ConsoleApplication1\bin\Debug\profile7\control_failures.log
+ let setLog = Map.add "CONTROL_FAILURES_LOG" (getfullpath ".."/"ConsoleApplication1"/"bin"/"Debug"/"profile7"/"control_failures.log")
+
+ let exec p = Command.exec dir (cfg.EnvironmentVariables |> setLog) { Output = Inherit; Input = None; } p >> checkResult
+
+ // ..\ConsoleApplication1\bin\Debug\profile7\PortableTestEntry.exe
+ do! exec (".."/"ConsoleApplication1"/"bin"/"Debug"/"profile7"/"PortableTestEntry.exe") ""
+ }
+
+ []
+ let netcore7 () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+ module Netcore78 =
+
+ let build cfg dir = processor {
+ // IF /I "%INSTALL_SKU%" NEQ "ULTIMATE" (
+ // echo Test not supported except on Ultimate
+ // exit /b 0
+ // )
+ do! requireVSUltimate cfg
+
+ let envVars =
+ cfg.EnvironmentVariables
+ |> Map.add "FSCOREDLLNETCORE78PATH" cfg.FSCOREDLLNETCORE78PATH
+
+ let exec p = Command.exec dir envVars { Output = Inherit; Input = None; } p >> checkResult
+ let msbuild = Printf.ksprintf (Commands.msbuild exec (cfg.MSBUILD.Value))
+
+ // "%MSBUILDTOOLSPATH%\msbuild.exe" ..\netcore.sln /p:Configuration=Debug /p:TestProfile=Profile78 /t:Rebuild
+ do! msbuild "/p:Configuration=Debug /p:TestProfile=Profile78 /t:Rebuild" [".."/"netcore.sln"]
+ }
+
+ let run cfg dir = processor {
+ let getfullpath = Commands.getfullpath dir
+
+ // IF /I "%INSTALL_SKU%" NEQ "ULTIMATE" (
+ // echo Test not supported except on Ultimate
+ // exit /b 0
+ // )
+ do! requireVSUltimate cfg
+
+ // set CONTROL_FAILURES_LOG=%~dp0..\ConsoleApplication1\bin\Debug\profile78\control_failures.log
+ let setLog = Map.add "CONTROL_FAILURES_LOG" (getfullpath ".."/"ConsoleApplication1"/"bin"/"Debug"/"profile78"/"control_failures.log")
+
+ let exec p = Command.exec dir (cfg.EnvironmentVariables |> setLog) { Output = Inherit; Input = None; } p >> checkResult
+
+
+ // ..\ConsoleApplication1\bin\Debug\profile78\PortableTestEntry.exe
+ do! exec (".."/"ConsoleApplication1"/"bin"/"Debug"/"profile78"/"PortableTestEntry.exe") ""
+ }
+
+ []
+ let netcore78 () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+module Patterns =
+
+ []
+ let patterns p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+
+[]
+module Pinvoke =
+
+ []
+ let pinvoke () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let peverify = Printf.ksprintf (Commands.peverify exec cfg.PEVERIFY)
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+
+ let ILX_CONFIG = ""
+
+ // "%FSC%" %fsc_flags% -o:test%ILX_CONFIG%.exe -g test.fsx
+ do! fsc "%s -o:test%s.exe -g" cfg.fsc_flags ILX_CONFIG ["test.fsx"]
+
+ // REM The IL is unverifiable code
+ // "%PEVERIFY%" /MD test%ILX_CONFIG%.exe
+ do! peverify "/MD test%s.exe" ILX_CONFIG
+
+ return! NUnitConf.genericError (sprintf "env var 'ILX_CONFIG' not found, using '%s' as default the test pass" ILX_CONFIG)
+
+ })
+
+
+
+module Portable =
+
+ let build cfg dir = processor {
+ let envVars =
+ cfg.EnvironmentVariables
+ |> Map.add "FSCOREDLLPORTABLEPATH" cfg.FSCOREDLLPORTABLEPATH
+
+ let exec p = Command.exec dir envVars { Output = Inherit; Input = None; } p >> checkResult
+ let msbuild = Printf.ksprintf (Commands.msbuild exec (cfg.MSBUILD.Value))
+
+ do! requireVSUltimate cfg
+
+ // "%MSBUILDTOOLSPATH%\msbuild.exe" portablelibrary1.sln /p:Configuration=Debug
+ do! msbuild "/p:Configuration=Debug" ["portablelibrary1.sln"]
+
+ }
+
+ let run cfg dir = processor {
+ let getfullpath = Commands.getfullpath dir
+
+ // IF /I "%INSTALL_SKU%" NEQ "ULTIMATE" (
+ // echo Test not supported except on Ultimate
+ // exit /b 0
+ // )
+ do! requireVSUltimate cfg
+
+ // set CONTROL_FAILURES_LOG=%~dp0\control_failures.log
+ let setLog = Map.add "CONTROL_FAILURES_LOG" (getfullpath "control_failures.log")
+
+ let exec p = Command.exec dir (cfg.EnvironmentVariables |> setLog) { Output = Inherit; Input = None; } p >> checkResult
+
+ // .\ConsoleApplication1\bin\Debug\PortableTestEntry.exe
+ do! exec ("."/"ConsoleApplication1"/"bin"/"Debug"/"PortableTestEntry.exe") ""
+
+ }
+
+ []
+ let portable () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+module ``test printf`` =
+ let permutations = [ FSharpSuiteTestCaseData("core/printf", FSC_BASIC) ]
+
+ []
+ let printf p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+module QueriesLeafExpressionConvert =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let fsc_flags = cfg.fsc_flags
+
+ // "%FSC%" %fsc_flags% -o:test.exe -g test.fsx
+ do! fsc "%s -o:test.exe -g" fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test.exe
+ do! peverify "test.exe"
+
+ // "%FSC%" %fsc_flags% --optimize -o:test--optimize.exe -g test.fsx
+ do! fsc "%s --optimize -o:test--optimize.exe -g" fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test--optimize.exe
+ do! peverify "test--optimize.exe"
+
+ }
+
+ let run cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsi = Printf.ksprintf (Commands.fsi exec cfg.FSI)
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ // REM fsi.exe testing
+ // echo TestC
+ log "TestC"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+ // "%FSI%" %fsi_flags% test.fsx
+ do! fsi "%s" cfg.fsi_flags ["test.fsx"]
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+
+ // REM fsc.exe testing
+
+ // echo TestD
+ log "TestD"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile2 = fileguard "test.ok"
+ // %CLIX% test.exe
+ do! exec ("."/"test.exe") ""
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile2 |> NUnitConf.checkGuardExists
+
+
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile3 = fileguard "test.ok"
+ // %CLIX% test--optimize.exe
+ do! exec ("."/"test--optimize.exe") ""
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile3 |> NUnitConf.checkGuardExists
+
+ }
+
+ []
+ let queriesLeafExpressionConvert () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+module QueriesNullableOperators =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let fsc_flags = cfg.fsc_flags
+
+ // "%FSC%" %fsc_flags% -o:test.exe -g test.fsx
+ do! fsc "%s -o:test.exe -g" fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test.exe
+ do! peverify "test.exe"
+
+ // "%FSC%" %fsc_flags% --optimize -o:test--optimize.exe -g test.fsx
+ do! fsc "%s --optimize -o:test--optimize.exe -g" fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test--optimize.exe
+ do! peverify "test--optimize.exe"
+
+ }
+
+ let run cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsi = Printf.ksprintf (Commands.fsi exec cfg.FSI)
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ // REM fsi.exe testing
+ // echo TestC
+ log "TestC"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+ // "%FSI%" %fsi_flags% test.fsx
+ do! fsi "%s" cfg.fsi_flags ["test.fsx"]
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+
+ // REM fsc.exe testing
+ // echo TestD
+ log "TestD"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile2 = fileguard "test.ok"
+ // %CLIX% test.exe
+ do! exec ("."/"test.exe") ""
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile2 |> NUnitConf.checkGuardExists
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile3 = fileguard "test.ok"
+ // %CLIX% test--optimize.exe
+ do! exec ("."/"test--optimize.exe") ""
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile3 |> NUnitConf.checkGuardExists
+
+ }
+
+ []
+ let queriesNullableOperators () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+
+module QueriesOverIEnumerable =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+
+ // "%FSC%" %fsc_flags% -o:test.exe -g test.fsx
+ do! fsc "%s -o:test.exe -g" cfg.fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test.exe
+ do! peverify "test.exe"
+
+ // "%FSC%" %fsc_flags% --optimize -o:test--optimize.exe -g test.fsx
+ do! fsc "%s --optimize -o:test--optimize.exe -g" cfg.fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test--optimize.exe
+ do! peverify "test--optimize.exe"
+
+ }
+
+ let run cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsi = Printf.ksprintf (Commands.fsi exec cfg.FSI)
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ // REM fsi.exe testing
+ //echo TestC
+ log "TestC"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+ // "%FSI%" %fsi_flags% test.fsx
+ do! fsi "%s" cfg.fsi_flags ["test.fsx"]
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+
+
+ // REM fsc.exe testing
+ // echo TestD
+ log "TestD"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile2 = fileguard "test.ok"
+ // %CLIX% test.exe
+ do! exec ("."/"test.exe") ""
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile2 |> NUnitConf.checkGuardExists
+
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile3 = fileguard "test.ok"
+ // %CLIX% test--optimize.exe
+ do! exec ("."/"test--optimize.exe") ""
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile3 |> NUnitConf.checkGuardExists
+
+ }
+
+ []
+ let queriesOverIEnumerable () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+
+module QueriesOverIQueryable =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+
+ // "%FSC%" %fsc_flags% -o:test.exe -g test.fsx
+ do! fsc "%s -o:test.exe -g" cfg.fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test.exe
+ do! peverify "test.exe"
+
+ // "%FSC%" %fsc_flags% --optimize -o:test--optimize.exe -g test.fsx
+ do! fsc "%s --optimize -o:test--optimize.exe -g" cfg.fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test--optimize.exe
+ do! peverify "test--optimize.exe"
+
+ }
+
+ let run cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsi = Printf.ksprintf (Commands.fsi exec cfg.FSI)
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ // REM fsi.exe testing
+ // echo TestC
+ log "TestC"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+ // "%FSI%" %fsi_flags% test.fsx
+ do! fsi "%s" cfg.fsi_flags ["test.fsx"]
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+
+ // REM fsc.exe testing
+ // echo TestD
+ log "TestD"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile2 = fileguard "test.ok"
+ // %CLIX% test.exe
+ do! exec ("."/"test.exe") ""
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile2 |> NUnitConf.checkGuardExists
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile3 = fileguard "test.ok"
+ // %CLIX% test--optimize.exe
+ do! exec ("."/"test--optimize.exe") ""
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile3 |> NUnitConf.checkGuardExists
+
+
+ }
+
+ []
+ let queriesOverIQueryable () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+
+module QueriesOverOData =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+
+ // "%FSC%" %fsc_flags% -o:test.exe -g test.fsx
+ do! fsc "%s -o:test.exe -g" cfg.fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test.exe
+ do! peverify "test.exe"
+
+ // "%FSC%" %fsc_flags% --optimize -o:test--optimize.exe -g test.fsx
+ do! fsc "%s --optimize -o:test--optimize.exe -g" cfg.fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test--optimize.exe
+ do! peverify "test--optimize.exe"
+
+ }
+
+ let run cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsi = Printf.ksprintf (Commands.fsi exec cfg.FSI)
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ // REM fsi.exe testing
+ // echo TestC
+ log "TestC"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+ // "%FSI%" %fsi_flags% test.fsx
+ do! fsi "%s" cfg.fsi_flags ["test.fsx"]
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+
+ // REM fsc.exe testing
+ // echo TestD
+ log "TestD"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile2 = fileguard "test.ok"
+ // %CLIX% test.exe
+ do! exec ("."/"test.exe") ""
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile2 |> NUnitConf.checkGuardExists
+
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile3 = fileguard "test.ok"
+ // %CLIX% test--optimize.exe
+ do! exec ("."/"test--optimize.exe") ""
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile3 |> NUnitConf.checkGuardExists
+
+ }
+
+ []
+ let queriesOverOData () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+
+module QuotesDebugInfo =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+
+ // "%FSC%" %fsc_flags% --quotations-debug+ --optimize -o:test.exe -g test.fsx
+ do! fsc "%s --quotations-debug+ --optimize -o:test.exe -g" cfg.fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test.exe
+ do! peverify "test.exe"
+
+ // "%FSC%" %fsc_flags% --quotations-debug+ --optimize -o:test--optimize.exe -g test.fsx
+ do! fsc "%s --quotations-debug+ --optimize -o:test--optimize.exe -g" cfg.fsc_flags ["test.fsx"]
+
+ // "%PEVERIFY%" test--optimize.exe
+ do! peverify "test--optimize.exe"
+
+ }
+
+ let run cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsi = Printf.ksprintf (Commands.fsi exec cfg.FSI)
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ // REM fsi.exe testing
+ // echo TestC
+ log "TestC"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+ // "%FSI%" %fsi_flags% --quotations-debug+ test.fsx
+ do! fsi "%s --quotations-debug+" cfg.fsi_flags ["test.fsx"]
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+
+ // REM fsc.exe testing
+ // echo TestD
+ log "TestD"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile2 = fileguard "test.ok"
+ // %CLIX% test.exe
+ do! exec ("."/"test.exe") ""
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile2 |> NUnitConf.checkGuardExists
+
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile3 = fileguard "test.ok"
+ // %CLIX% test--optimize.exe
+ do! exec ("."/"test--optimize.exe") ""
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile3 |> NUnitConf.checkGuardExists
+
+ }
+
+ []
+ let quotesDebugInfo () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+
+module QuotesInMultipleModules =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+
+ // "%FSC%" %fsc_flags% -o:module1.dll --target:library module1.fsx
+ do! fsc "%s -o:module1.dll --target:library" cfg.fsc_flags ["module1.fsx"]
+
+ // "%PEVERIFY%" module1.dll
+ do! peverify "module1.dll"
+
+ // "%FSC%" %fsc_flags% -o:module2.exe -r:module1.dll module2.fsx
+ do! fsc "%s -o:module2.exe -r:module1.dll" cfg.fsc_flags ["module2.fsx"]
+
+ // "%PEVERIFY%" module2.exe
+ do! peverify "module2.exe"
+
+ // "%FSC%" %fsc_flags% --staticlink:module1 -o:module2-staticlink.exe -r:module1.dll module2.fsx
+ do! fsc "%s --staticlink:module1 -o:module2-staticlink.exe -r:module1.dll" cfg.fsc_flags ["module2.fsx"]
+
+ // "%PEVERIFY%" module2-staticlink.exe
+ do! peverify "module2-staticlink.exe"
+
+ // "%FSC%" %fsc_flags% -o:module1-opt.dll --target:library --optimize module1.fsx
+ do! fsc "%s -o:module1-opt.dll --target:library --optimize" cfg.fsc_flags ["module1.fsx"]
+
+ // "%PEVERIFY%" module1-opt.dll
+ do! peverify "module1-opt.dll"
+
+ // "%FSC%" %fsc_flags% -o:module2-opt.exe -r:module1-opt.dll --optimize module2.fsx
+ do! fsc "%s -o:module2-opt.exe -r:module1-opt.dll --optimize" cfg.fsc_flags ["module2.fsx"]
+
+ // "%PEVERIFY%" module2-opt.exe
+ do! peverify "module2-opt.exe"
+
+ }
+
+ let run cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsi = Printf.ksprintf (Commands.fsi exec cfg.FSI)
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ // REM fsi.exe testing
+ // echo TestC
+ log "TestC"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+ // "%FSI%" %fsi_flags% -r module1.dll module2.fsx
+ do! fsi "%s -r module1.dll" cfg.fsi_flags ["module2.fsx"]
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+
+ // REM fsc.exe testing
+ // echo TestD
+ log "TestD"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+ // %CLIX% module2.exe
+ do! exec ("."/"module2.exe") ""
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+ // %CLIX% module2-opt.exe
+ do! exec ("."/"module2-opt.exe") ""
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+ // %CLIX% module2-staticlink.exe
+ do! exec ("."/"module2-staticlink.exe") ""
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+
+ }
+
+ []
+ let quotesInMultipleModules () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+
+
+module Reflect =
+
+ []
+ let reflect p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+module ``test resources`` =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let resgen = Printf.ksprintf (Commands.resgen exec cfg.RESGEN)
+
+ // REM Note that you have a VS SDK dependence here.
+ // "%RESGEN%" /compile Resources.resx
+ do! resgen "/compile" ["Resources.resx"]
+
+ // "%FSC%" %fsc_flags% --resource:Resources.resources -o:test-embed.exe -g test.fs
+ do! fsc "%s --resource:Resources.resources -o:test-embed.exe -g" cfg.fsc_flags ["test.fs"]
+
+ // "%PEVERIFY%" test-embed.exe
+ do! peverify "test-embed.exe"
+
+ // "%FSC%" %fsc_flags% --linkresource:Resources.resources -o:test-link.exe -g test.fs
+ do! fsc "%s --linkresource:Resources.resources -o:test-link.exe -g" cfg.fsc_flags ["test.fs"]
+
+ // "%PEVERIFY%" test-link.exe
+ do! peverify "test-link.exe"
+
+ // "%FSC%" %fsc_flags% --resource:Resources.resources,ResourceName.resources -o:test-embed-named.exe -g test.fs
+ do! fsc "%s --resource:Resources.resources,ResourceName.resources -o:test-embed-named.exe -g" cfg.fsc_flags ["test.fs"]
+
+ // "%PEVERIFY%" test-embed-named.exe
+ do! peverify "test-embed-named.exe"
+
+ // "%FSC%" %fsc_flags% --linkresource:Resources.resources,ResourceName.resources -o:test-link-named.exe -g test.fs
+ do! fsc "%s --linkresource:Resources.resources,ResourceName.resources -o:test-link-named.exe -g" cfg.fsc_flags ["test.fs"]
+
+ // "%PEVERIFY%" test-link-named.exe
+ do! peverify "test-link-named.exe"
+
+ }
+
+ let run cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+
+ // %CLIX% .\test-embed.exe
+ do! exec ("."/"test-embed.exe") ""
+
+ // %CLIX% .\test-link.exe
+ do! exec ("."/"test-link.exe") ""
+
+ // %CLIX% .\test-link-named.exe ResourceName
+ do! exec ("."/"test-link-named.exe") "ResourceName"
+
+ // %CLIX% .\test-embed-named.exe ResourceName
+ do! exec ("."/"test-embed-named.exe") "ResourceName"
+
+ }
+
+ []
+ let resources () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+module ``test seq`` =
+
+ []
+ let seq p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+
+module Subtype =
+
+ []
+ let subtype p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+
+module Syntax =
+
+ []
+ let syntax p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+
+module Tlr =
+
+ []
+ let tlr p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+
+module Topinit =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let csc = Printf.ksprintf (Commands.csc exec cfg.CSC)
+ let fsc_flags = cfg.fsc_flags
+
+
+ // "%FSC%" %fsc_flags% --optimize -o both69514.exe -g lib69514.fs app69514.fs
+ do! fsc "%s --optimize -o both69514.exe -g" fsc_flags ["lib69514.fs"; "app69514.fs"]
+
+ // "%PEVERIFY%" both69514.exe
+ do! peverify "both69514.exe"
+
+ // "%FSC%" %fsc_flags% --optimize- -o both69514-noopt.exe -g lib69514.fs app69514.fs
+ do! fsc "%s --optimize- -o both69514-noopt.exe -g" fsc_flags ["lib69514.fs"; "app69514.fs"]
+
+ // "%PEVERIFY%" both69514-noopt.exe
+ do! peverify "both69514-noopt.exe"
+
+
+ // "%FSC%" %fsc_flags% --optimize -a -g lib69514.fs
+ do! fsc "%s --optimize -a -g" fsc_flags ["lib69514.fs"]
+
+ // "%PEVERIFY%" lib69514.dll
+ do! peverify "lib69514.dll"
+
+ // "%FSC%" %fsc_flags% --optimize -r:lib69514.dll -g app69514.fs
+ do! fsc "%s --optimize -r:lib69514.dll -g" fsc_flags ["app69514.fs"]
+
+ // "%PEVERIFY%" app69514.exe
+ do! peverify "app69514.exe"
+
+ // "%FSC%" %fsc_flags% --optimize- -o:lib69514-noopt.dll -a -g lib69514.fs
+ do! fsc "%s --optimize- -o:lib69514-noopt.dll -a -g" fsc_flags ["lib69514.fs"]
+
+ // "%PEVERIFY%" lib69514-noopt.dll
+ do! peverify "lib69514-noopt.dll"
+
+ // "%FSC%" %fsc_flags% --optimize- -r:lib69514-noopt.dll -o:app69514-noopt.exe -g app69514.fs
+ do! fsc "%s --optimize- -r:lib69514-noopt.dll -o:app69514-noopt.exe -g" fsc_flags ["app69514.fs"]
+
+ // "%PEVERIFY%" app69514-noopt.exe
+ do! peverify "app69514-noopt.exe"
+
+
+ // "%FSC%" %fsc_flags% --optimize- -o:lib69514-noopt-withsig.dll -a -g lib69514.fsi lib69514.fs
+ do! fsc "%s --optimize- -o:lib69514-noopt-withsig.dll -a -g" fsc_flags ["lib69514.fsi"; "lib69514.fs"]
+
+ // "%PEVERIFY%" lib69514-noopt-withsig.dll
+ do! peverify "lib69514-noopt-withsig.dll"
+
+ // "%FSC%" %fsc_flags% --optimize- -r:lib69514-noopt-withsig.dll -o:app69514-noopt-withsig.exe -g app69514.fs
+ do! fsc "%s --optimize- -r:lib69514-noopt-withsig.dll -o:app69514-noopt-withsig.exe -g" fsc_flags ["app69514.fs"]
+
+ // "%PEVERIFY%" app69514-noopt-withsig.exe
+ do! peverify "app69514-noopt-withsig.exe"
+
+ // "%FSC%" %fsc_flags% -o:lib69514-withsig.dll -a -g lib69514.fsi lib69514.fs
+ do! fsc "%s -o:lib69514-withsig.dll -a -g" fsc_flags ["lib69514.fsi"; "lib69514.fs"]
+
+ // "%PEVERIFY%" lib69514-withsig.dll
+ do! peverify "lib69514-withsig.dll"
+
+ // "%FSC%" %fsc_flags% -r:lib69514-withsig.dll -o:app69514-withsig.exe -g app69514.fs
+ do! fsc "%s -r:lib69514-withsig.dll -o:app69514-withsig.exe -g" fsc_flags ["app69514.fs"]
+
+ // "%PEVERIFY%" app69514-withsig.exe
+ do! peverify "app69514-withsig.exe"
+
+
+ // "%FSC%" %fsc_flags% -o:lib.dll -a -g lib.ml
+ do! fsc "%s -o:lib.dll -a -g" fsc_flags ["lib.ml"]
+
+ // "%PEVERIFY%" lib.dll
+ do! peverify "lib.dll"
+
+ // %CSC% /nologo /r:"%FSCOREDLLPATH%" /r:lib.dll /out:test.exe test.cs
+ do! csc """/nologo /r:"%s" /r:lib.dll /out:test.exe """ cfg.FSCOREDLLPATH ["test.cs"]
+
+ // "%FSC%" %fsc_flags% --optimize -o:lib--optimize.dll -a -g lib.ml
+ do! fsc "%s --optimize -o:lib--optimize.dll -a -g" fsc_flags ["lib.ml"]
+
+ // "%PEVERIFY%" lib--optimize.dll
+ do! peverify "lib--optimize.dll"
+
+ // %CSC% /nologo /r:"%FSCOREDLLPATH%" /r:lib--optimize.dll /out:test--optimize.exe test.cs
+ do! csc """/nologo /r:"%s" /r:lib--optimize.dll /out:test--optimize.exe""" cfg.FSCOREDLLPATH ["test.cs"]
+
+ // set dicases= flag_deterministic_init1.fs lib_deterministic_init1.fs flag_deterministic_init2.fs lib_deterministic_init2.fs flag_deterministic_init3.fs lib_deterministic_init3.fs flag_deterministic_init4.fs lib_deterministic_init4.fs flag_deterministic_init5.fs lib_deterministic_init5.fs flag_deterministic_init6.fs lib_deterministic_init6.fs flag_deterministic_init7.fs lib_deterministic_init7.fs flag_deterministic_init8.fs lib_deterministic_init8.fs flag_deterministic_init9.fs lib_deterministic_init9.fs flag_deterministic_init10.fs lib_deterministic_init10.fs flag_deterministic_init11.fs lib_deterministic_init11.fs flag_deterministic_init12.fs lib_deterministic_init12.fs flag_deterministic_init13.fs lib_deterministic_init13.fs flag_deterministic_init14.fs lib_deterministic_init14.fs flag_deterministic_init15.fs lib_deterministic_init15.fs flag_deterministic_init16.fs lib_deterministic_init16.fs flag_deterministic_init17.fs lib_deterministic_init17.fs flag_deterministic_init18.fs lib_deterministic_init18.fs flag_deterministic_init19.fs lib_deterministic_init19.fs flag_deterministic_init20.fs lib_deterministic_init20.fs flag_deterministic_init21.fs lib_deterministic_init21.fs flag_deterministic_init22.fs lib_deterministic_init22.fs flag_deterministic_init23.fs lib_deterministic_init23.fs flag_deterministic_init24.fs lib_deterministic_init24.fs flag_deterministic_init25.fs lib_deterministic_init25.fs flag_deterministic_init26.fs lib_deterministic_init26.fs flag_deterministic_init27.fs lib_deterministic_init27.fs flag_deterministic_init28.fs lib_deterministic_init28.fs flag_deterministic_init29.fs lib_deterministic_init29.fs flag_deterministic_init30.fs lib_deterministic_init30.fs flag_deterministic_init31.fs lib_deterministic_init31.fs flag_deterministic_init32.fs lib_deterministic_init32.fs flag_deterministic_init33.fs lib_deterministic_init33.fs flag_deterministic_init34.fs lib_deterministic_init34.fs flag_deterministic_init35.fs lib_deterministic_init35.fs flag_deterministic_init36.fs lib_deterministic_init36.fs flag_deterministic_init37.fs lib_deterministic_init37.fs flag_deterministic_init38.fs lib_deterministic_init38.fs flag_deterministic_init39.fs lib_deterministic_init39.fs flag_deterministic_init40.fs lib_deterministic_init40.fs flag_deterministic_init41.fs lib_deterministic_init41.fs flag_deterministic_init42.fs lib_deterministic_init42.fs flag_deterministic_init43.fs lib_deterministic_init43.fs flag_deterministic_init44.fs lib_deterministic_init44.fs flag_deterministic_init45.fs lib_deterministic_init45.fs flag_deterministic_init46.fs lib_deterministic_init46.fs flag_deterministic_init47.fs lib_deterministic_init47.fs flag_deterministic_init48.fs lib_deterministic_init48.fs flag_deterministic_init49.fs lib_deterministic_init49.fs flag_deterministic_init50.fs lib_deterministic_init50.fs flag_deterministic_init51.fs lib_deterministic_init51.fs flag_deterministic_init52.fs lib_deterministic_init52.fs flag_deterministic_init53.fs lib_deterministic_init53.fs flag_deterministic_init54.fs lib_deterministic_init54.fs flag_deterministic_init55.fs lib_deterministic_init55.fs flag_deterministic_init56.fs lib_deterministic_init56.fs flag_deterministic_init57.fs lib_deterministic_init57.fs flag_deterministic_init58.fs lib_deterministic_init58.fs flag_deterministic_init59.fs lib_deterministic_init59.fs flag_deterministic_init60.fs lib_deterministic_init60.fs flag_deterministic_init61.fs lib_deterministic_init61.fs flag_deterministic_init62.fs lib_deterministic_init62.fs flag_deterministic_init63.fs lib_deterministic_init63.fs flag_deterministic_init64.fs lib_deterministic_init64.fs flag_deterministic_init65.fs lib_deterministic_init65.fs flag_deterministic_init66.fs lib_deterministic_init66.fs flag_deterministic_init67.fs lib_deterministic_init67.fs flag_deterministic_init68.fs lib_deterministic_init68.fs flag_deterministic_init69.fs lib_deterministic_init69.fs flag_deterministic_init70.fs lib_deterministic_init70.fs flag_deterministic_init71.fs lib_deterministic_init71.fs flag_deterministic_init72.fs lib_deterministic_init72.fs flag_deterministic_init73.fs lib_deterministic_init73.fs flag_deterministic_init74.fs lib_deterministic_init74.fs flag_deterministic_init75.fs lib_deterministic_init75.fs flag_deterministic_init76.fs lib_deterministic_init76.fs flag_deterministic_init77.fs lib_deterministic_init77.fs flag_deterministic_init78.fs lib_deterministic_init78.fs flag_deterministic_init79.fs lib_deterministic_init79.fs flag_deterministic_init80.fs lib_deterministic_init80.fs flag_deterministic_init81.fs lib_deterministic_init81.fs flag_deterministic_init82.fs lib_deterministic_init82.fs flag_deterministic_init83.fs lib_deterministic_init83.fs flag_deterministic_init84.fs lib_deterministic_init84.fs flag_deterministic_init85.fs lib_deterministic_init85.fs
+ let dicases = ["flag_deterministic_init1.fs"; "lib_deterministic_init1.fs"; "flag_deterministic_init2.fs"; "lib_deterministic_init2.fs"; "flag_deterministic_init3.fs"; "lib_deterministic_init3.fs"; "flag_deterministic_init4.fs"; "lib_deterministic_init4.fs"; "flag_deterministic_init5.fs"; "lib_deterministic_init5.fs"; "flag_deterministic_init6.fs"; "lib_deterministic_init6.fs"; "flag_deterministic_init7.fs"; "lib_deterministic_init7.fs"; "flag_deterministic_init8.fs"; "lib_deterministic_init8.fs"; "flag_deterministic_init9.fs"; "lib_deterministic_init9.fs"; "flag_deterministic_init10.fs"; "lib_deterministic_init10.fs"; "flag_deterministic_init11.fs"; "lib_deterministic_init11.fs"; "flag_deterministic_init12.fs"; "lib_deterministic_init12.fs"; "flag_deterministic_init13.fs"; "lib_deterministic_init13.fs"; "flag_deterministic_init14.fs"; "lib_deterministic_init14.fs"; "flag_deterministic_init15.fs"; "lib_deterministic_init15.fs"; "flag_deterministic_init16.fs"; "lib_deterministic_init16.fs"; "flag_deterministic_init17.fs"; "lib_deterministic_init17.fs"; "flag_deterministic_init18.fs"; "lib_deterministic_init18.fs"; "flag_deterministic_init19.fs"; "lib_deterministic_init19.fs"; "flag_deterministic_init20.fs"; "lib_deterministic_init20.fs"; "flag_deterministic_init21.fs"; "lib_deterministic_init21.fs"; "flag_deterministic_init22.fs"; "lib_deterministic_init22.fs"; "flag_deterministic_init23.fs"; "lib_deterministic_init23.fs"; "flag_deterministic_init24.fs"; "lib_deterministic_init24.fs"; "flag_deterministic_init25.fs"; "lib_deterministic_init25.fs"; "flag_deterministic_init26.fs"; "lib_deterministic_init26.fs"; "flag_deterministic_init27.fs"; "lib_deterministic_init27.fs"; "flag_deterministic_init28.fs"; "lib_deterministic_init28.fs"; "flag_deterministic_init29.fs"; "lib_deterministic_init29.fs"; "flag_deterministic_init30.fs"; "lib_deterministic_init30.fs"; "flag_deterministic_init31.fs"; "lib_deterministic_init31.fs"; "flag_deterministic_init32.fs"; "lib_deterministic_init32.fs"; "flag_deterministic_init33.fs"; "lib_deterministic_init33.fs"; "flag_deterministic_init34.fs"; "lib_deterministic_init34.fs"; "flag_deterministic_init35.fs"; "lib_deterministic_init35.fs"; "flag_deterministic_init36.fs"; "lib_deterministic_init36.fs"; "flag_deterministic_init37.fs"; "lib_deterministic_init37.fs"; "flag_deterministic_init38.fs"; "lib_deterministic_init38.fs"; "flag_deterministic_init39.fs"; "lib_deterministic_init39.fs"; "flag_deterministic_init40.fs"; "lib_deterministic_init40.fs"; "flag_deterministic_init41.fs"; "lib_deterministic_init41.fs"; "flag_deterministic_init42.fs"; "lib_deterministic_init42.fs"; "flag_deterministic_init43.fs"; "lib_deterministic_init43.fs"; "flag_deterministic_init44.fs"; "lib_deterministic_init44.fs"; "flag_deterministic_init45.fs"; "lib_deterministic_init45.fs"; "flag_deterministic_init46.fs"; "lib_deterministic_init46.fs"; "flag_deterministic_init47.fs"; "lib_deterministic_init47.fs"; "flag_deterministic_init48.fs"; "lib_deterministic_init48.fs"; "flag_deterministic_init49.fs"; "lib_deterministic_init49.fs"; "flag_deterministic_init50.fs"; "lib_deterministic_init50.fs"; "flag_deterministic_init51.fs"; "lib_deterministic_init51.fs"; "flag_deterministic_init52.fs"; "lib_deterministic_init52.fs"; "flag_deterministic_init53.fs"; "lib_deterministic_init53.fs"; "flag_deterministic_init54.fs"; "lib_deterministic_init54.fs"; "flag_deterministic_init55.fs"; "lib_deterministic_init55.fs"; "flag_deterministic_init56.fs"; "lib_deterministic_init56.fs"; "flag_deterministic_init57.fs"; "lib_deterministic_init57.fs"; "flag_deterministic_init58.fs"; "lib_deterministic_init58.fs"; "flag_deterministic_init59.fs"; "lib_deterministic_init59.fs"; "flag_deterministic_init60.fs"; "lib_deterministic_init60.fs"; "flag_deterministic_init61.fs"; "lib_deterministic_init61.fs"; "flag_deterministic_init62.fs"; "lib_deterministic_init62.fs"; "flag_deterministic_init63.fs"; "lib_deterministic_init63.fs"; "flag_deterministic_init64.fs"; "lib_deterministic_init64.fs"; "flag_deterministic_init65.fs"; "lib_deterministic_init65.fs"; "flag_deterministic_init66.fs"; "lib_deterministic_init66.fs"; "flag_deterministic_init67.fs"; "lib_deterministic_init67.fs"; "flag_deterministic_init68.fs"; "lib_deterministic_init68.fs"; "flag_deterministic_init69.fs"; "lib_deterministic_init69.fs"; "flag_deterministic_init70.fs"; "lib_deterministic_init70.fs"; "flag_deterministic_init71.fs"; "lib_deterministic_init71.fs"; "flag_deterministic_init72.fs"; "lib_deterministic_init72.fs"; "flag_deterministic_init73.fs"; "lib_deterministic_init73.fs"; "flag_deterministic_init74.fs"; "lib_deterministic_init74.fs"; "flag_deterministic_init75.fs"; "lib_deterministic_init75.fs"; "flag_deterministic_init76.fs"; "lib_deterministic_init76.fs"; "flag_deterministic_init77.fs"; "lib_deterministic_init77.fs"; "flag_deterministic_init78.fs"; "lib_deterministic_init78.fs"; "flag_deterministic_init79.fs"; "lib_deterministic_init79.fs"; "flag_deterministic_init80.fs"; "lib_deterministic_init80.fs"; "flag_deterministic_init81.fs"; "lib_deterministic_init81.fs"; "flag_deterministic_init82.fs"; "lib_deterministic_init82.fs"; "flag_deterministic_init83.fs"; "lib_deterministic_init83.fs"; "flag_deterministic_init84.fs"; "lib_deterministic_init84.fs"; "flag_deterministic_init85.fs"; "lib_deterministic_init85.fs"]
+
+ // "%FSC%" %fsc_flags% --optimize- -o test_deterministic_init.exe %dicases% test_deterministic_init.fs
+ do! fsc "%s --optimize- -o test_deterministic_init.exe" fsc_flags (dicases @ ["test_deterministic_init.fs"])
+
+ // "%PEVERIFY%" test_deterministic_init.exe
+ do! peverify "test_deterministic_init.exe"
+
+ // "%FSC%" %fsc_flags% --optimize -o test_deterministic_init--optimize.exe %dicases% test_deterministic_init.fs
+ do! fsc "%s --optimize -o test_deterministic_init--optimize.exe" fsc_flags (dicases @ ["test_deterministic_init.fs"])
+
+ // "%PEVERIFY%" test_deterministic_init--optimize.exe
+ do! peverify "test_deterministic_init--optimize.exe"
+
+
+ // "%FSC%" %fsc_flags% --optimize- -a -o test_deterministic_init_lib.dll %dicases%
+ do! fsc "%s --optimize- -a -o test_deterministic_init_lib.dll" fsc_flags dicases
+
+ // "%PEVERIFY%" test_deterministic_init_lib.dll
+ do! peverify "test_deterministic_init_lib.dll"
+
+ // "%FSC%" %fsc_flags% --optimize- -r test_deterministic_init_lib.dll -o test_deterministic_init_exe.exe test_deterministic_init.fs
+ do! fsc "%s --optimize- -r test_deterministic_init_lib.dll -o test_deterministic_init_exe.exe" fsc_flags ["test_deterministic_init.fs"]
+
+ // "%PEVERIFY%" test_deterministic_init_exe.exe
+ do! peverify "test_deterministic_init_exe.exe"
+
+ // "%FSC%" %fsc_flags% --optimize -a -o test_deterministic_init_lib--optimize.dll %dicases%
+ do! fsc "%s --optimize -a -o test_deterministic_init_lib--optimize.dll" fsc_flags dicases
+
+ // "%PEVERIFY%" test_deterministic_init_lib--optimize.dll
+ do! peverify "test_deterministic_init_lib--optimize.dll"
+
+ // "%FSC%" %fsc_flags% --optimize -r test_deterministic_init_lib--optimize.dll -o test_deterministic_init_exe--optimize.exe test_deterministic_init.fs
+ do! fsc "%s --optimize -r test_deterministic_init_lib--optimize.dll -o test_deterministic_init_exe--optimize.exe" fsc_flags ["test_deterministic_init.fs"]
+
+ // "%PEVERIFY%" test_deterministic_init_exe--optimize.exe
+ do! peverify "test_deterministic_init_exe--optimize.exe"
+
+
+ // set static_init_cases= test0.fs test1.fs test2.fs test3.fs test4.fs test5.fs test6.fs
+ let static_init_cases = [ "test0.fs"; "test1.fs"; "test2.fs"; "test3.fs"; "test4.fs"; "test5.fs"; "test6.fs" ]
+
+ // "%FSC%" %fsc_flags% --optimize- -o test_static_init.exe %static_init_cases% static-main.fs
+ do! fsc "%s --optimize- -o test_static_init.exe" fsc_flags (static_init_cases @ ["static-main.fs"])
+
+ // "%PEVERIFY%" test_static_init.exe
+ do! peverify "test_static_init.exe"
+
+ // "%FSC%" %fsc_flags% --optimize -o test_static_init--optimize.exe %static_init_cases% static-main.fs
+ do! fsc "%s --optimize -o test_static_init--optimize.exe" fsc_flags (static_init_cases @ [ "static-main.fs" ])
+
+ // "%PEVERIFY%" test_static_init--optimize.exe
+ do! peverify "test_static_init--optimize.exe"
+
+
+ // "%FSC%" %fsc_flags% --optimize- -a -o test_static_init_lib.dll %static_init_cases%
+ do! fsc "%s --optimize- -a -o test_static_init_lib.dll" fsc_flags static_init_cases
+
+ // "%PEVERIFY%" test_static_init_lib.dll
+ do! peverify "test_static_init_lib.dll"
+
+ // "%FSC%" %fsc_flags% --optimize- -r test_static_init_lib.dll -o test_static_init_exe.exe static-main.fs
+ do! fsc "%s --optimize- -r test_static_init_lib.dll -o test_static_init_exe.exe" fsc_flags ["static-main.fs"]
+
+ // "%PEVERIFY%" test_static_init_exe.exe
+ do! peverify "test_static_init_exe.exe"
+
+ // "%FSC%" %fsc_flags% --optimize -a -o test_static_init_lib--optimize.dll %static_init_cases%
+ do! fsc "%s --optimize -a -o test_static_init_lib--optimize.dll" fsc_flags static_init_cases
+
+ // "%PEVERIFY%" test_static_init_lib--optimize.dll
+ do! peverify "test_static_init_lib--optimize.dll"
+
+ // "%FSC%" %fsc_flags% --optimize -r test_static_init_lib--optimize.dll -o test_static_init_exe--optimize.exe static-main.fs
+ do! fsc "%s --optimize -r test_static_init_lib--optimize.dll -o test_static_init_exe--optimize.exe" fsc_flags ["static-main.fs"]
+
+ // "%PEVERIFY%" test_static_init_exe--optimize.exe
+ do! peverify "test_static_init_exe--optimize.exe"
+
+ }
+
+ let run cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+
+ // %CLIX% .\test.exe
+ do! exec ("."/"test.exe") ""
+
+ // %CLIX% .\test--optimize.exe
+ do! exec ("."/"test--optimize.exe") ""
+
+ // %CLIX% .\test_deterministic_init.exe
+ do! exec ("."/"test_deterministic_init.exe") ""
+
+ // %CLIX% .\test_deterministic_init--optimize.exe
+ do! exec ("."/"test_deterministic_init--optimize.exe") ""
+
+ // %CLIX% .\test_deterministic_init_exe.exe
+ do! exec ("."/"test_deterministic_init_exe.exe") ""
+
+ // %CLIX% .\test_deterministic_init_exe--optimize.exe
+ do! exec ("."/"test_deterministic_init_exe--optimize.exe") ""
+
+
+ // %CLIX% .\test_static_init.exe
+ do! exec ("."/"test_static_init.exe") ""
+
+ // %CLIX% .\test_static_init--optimize.exe
+ do! exec ("."/"test_static_init--optimize.exe") ""
+
+ // %CLIX% .\test_static_init_exe.exe
+ do! exec ("."/"test_static_init_exe.exe") ""
+
+ // %CLIX% .\test_static_init_exe--optimize.exe
+ do! exec ("."/"test_static_init_exe--optimize.exe") ""
+
+
+ }
+
+ []
+ let topinit () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+module UnitsOfMeasure =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+
+ // "%FSC%" %fsc_flags% --optimize- -o:test.exe -g test.fs
+ do! fsc "%s --optimize- -o:test.exe -g" cfg.fsc_flags ["test.fs"]
+
+ // "%PEVERIFY%" test.exe
+ do! peverify "test.exe"
+
+ }
+
+ let run cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+
+ // %CLIX% .\test.exe
+ do! exec ("."/"test.exe") ""
+
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ []
+ let unitsOfMeasure () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+
+module Verify =
+
+ []
+ let verify () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let peverify' = Printf.ksprintf (Commands.peverify exec cfg.PEVERIFY)
+ let getfullpath = Commands.getfullpath dir
+
+ // "%PEVERIFY%" "%FSCOREDLLPATH%"
+ do! peverify cfg.FSCOREDLLPATH
+
+ // "%PEVERIFY%" "%FSCOREDLL20PATH%"
+ do! peverify cfg.FSCOREDLL20PATH
+
+ // "%PEVERIFY%" "%FSCOREDLLPORTABLEPATH%"
+ do! peverify cfg.FSCOREDLLPORTABLEPATH
+
+ // "%PEVERIFY%" "%FSCOREDLLNETCOREPATH%"
+ do! peverify cfg.FSCOREDLLNETCOREPATH
+
+ // "%PEVERIFY%" "%FSCOREDLLNETCORE78PATH%"
+ do! peverify cfg.FSCOREDLLNETCORE78PATH
+
+ // "%PEVERIFY%" "%FSCOREDLLNETCORE259PATH%"
+ do! peverify cfg.FSCOREDLLNETCORE259PATH
+
+ // "%PEVERIFY%" "%FSCBinPath%\FSharp.Build.dll"
+ do! peverify (cfg.FSCBinPath/"FSharp.Build.dll")
+
+ // REM Use /MD because this contains some P/Invoke code
+ // "%PEVERIFY%" /MD "%FSCBinPath%\FSharp.Compiler.dll"
+ do! peverify' """/MD "%s" """ (cfg.FSCBinPath/"FSharp.Compiler.dll")
+
+ // "%PEVERIFY%" "%FSCBinPath%\fsi.exe"
+ do! peverify (cfg.FSCBinPath/"fsi.exe")
+
+ // "%PEVERIFY%" "%FSCBinPath%\FSharp.Compiler.Interactive.Settings.dll"
+ do! peverify (cfg.FSCBinPath/"FSharp.Compiler.Interactive.Settings.dll")
+
+ // "%FSC%" %fsc_flags% -o:xmlverify.exe -g xmlverify.fs
+ do! fsc "%s -o:xmlverify.exe -g" cfg.fsc_flags ["xmlverify.fs"]
+
+ // "%PEVERIFY%" xmlverify.exe
+ do! peverify "xmlverify.exe"
+
+ // REM == Calc correct path to FSharp.Core.dll no matter what arch we are on
+ // call :SetFSCoreXMLPath "%FSCOREDLLPATH%"
+ // :SetFSCoreXMLPath
+ // set FSHARPCOREXML=%~dpn1.xml
+ let FSharpCoreXml = Path.ChangeExtension(cfg.FSCOREDLLPATH, ".xml") |> getfullpath
+
+ // %CLIX% xmlverify.exe "%FSHARPCOREXML%"
+ do! exec ("."/"xmlverify.exe") FSharpCoreXml
+
+ })
diff --git a/tests/fsharp/nunitConf.fs b/tests/fsharp/nunitConf.fs
new file mode 100644
index 00000000000..a225502b2e7
--- /dev/null
+++ b/tests/fsharp/nunitConf.fs
@@ -0,0 +1,379 @@
+module NUnitConf
+
+open System
+open System.IO
+open NUnit.Framework
+
+open UpdateCmd
+open TestConfig
+open PlatformHelpers
+open FSharpTestSuiteTypes
+
+let checkTestResult result =
+ match result with
+ | Success () -> ()
+ | Failure (GenericError msg) -> Assert.Fail (msg)
+ | Failure (ProcessExecError (err, msg)) -> Assert.Fail (sprintf "ERRORLEVEL %i %s" err msg)
+ | Failure (Skipped msg) -> Assert.Ignore(sprintf "skipped. Reason: %s" msg)
+
+let checkResult result =
+ match result with
+ | CmdResult.ErrorLevel err -> let x = err, (sprintf "ERRORLEVEL %d" err) in Failure (RunError.ProcessExecError x)
+ | CmdResult.Success -> Success ()
+
+let skip msg () = Failure (Skipped msg)
+let genericError msg () = Failure (GenericError msg)
+let errorLevel exitCode msg () = Failure (ProcessExecError (exitCode,msg))
+
+let envVars () =
+ System.Environment.GetEnvironmentVariables ()
+ |> Seq.cast
+ |> Seq.map (fun d -> d.Key :?> string, d.Value :?> string)
+ |> Map.ofSeq
+
+let defaultConfigurationName =
+#if !DEBUG
+ DEBUG
+#else
+ RELEASE
+#endif
+
+let parseConfigurationName (name: string) =
+ match name.ToUpper() with
+ | "RELEASE" -> RELEASE
+ | "DEBUG" -> DEBUG
+ | s -> failwithf "invalid env var FSHARP_TEST_SUITE_CONFIGURATION '%s'" s
+
+
+let initializeSuite () =
+
+ let configurationName = defaultConfigurationName
+
+ let doNgen = true;
+
+ let FSCBinPath = __SOURCE_DIRECTORY__/".."/".."/(sprintf "%O" configurationName)/"net40"/"bin"
+
+ let mapWithDefaults defaults m =
+ Seq.concat [ (Map.toSeq defaults) ; (Map.toSeq m) ] |> Map.ofSeq
+
+ let env =
+ envVars ()
+ |> mapWithDefaults ( [ "FSCBINPATH", FSCBinPath ] |> Map.ofList )
+
+ let configurationName =
+ match env |> Map.tryFind "FSHARP_TEST_SUITE_CONFIGURATION" |> Option.map parseConfigurationName with
+ | Some confName -> confName
+ | None -> configurationName
+
+ processor {
+ do! updateCmd env { Configuration = configurationName; Ngen = doNgen; }
+ |> Attempt.Run
+ |> function Success () -> Success () | Failure msg -> genericError msg ()
+
+ let cfg =
+ let c = config env
+ let usedEnvVars =
+ c.EnvironmentVariables
+ |> Map.add "FSC" c.FSC
+ { c with EnvironmentVariables = usedEnvVars }
+
+ logConfig cfg
+
+ let directoryExists = Commands.directoryExists (Path.GetTempPath()) >> Option.isSome
+
+ let checkfscBinPath () = processor {
+
+ let fscBinPath = cfg.EnvironmentVariables |> Map.tryFind "FSCBINPATH"
+ return!
+ match fscBinPath with
+ | Some dir when directoryExists dir -> Success
+ | None -> genericError "environment variable 'FSCBinPath' is required to be a valid directory, is not set"
+ | Some dir -> genericError (sprintf "environment variable 'FSCBinPath' is required to be a valid directory, but is '%s'" dir)
+ }
+
+ let smokeTest () = processor {
+ let tempFile ext =
+ let p = Path.ChangeExtension( Path.GetTempFileName(), ext)
+ File.AppendAllText (p, """printfn "ciao"; exit 0""")
+ p
+
+ let tempDir = Commands.createTempDir ()
+ let exec exe args =
+ log "%s %s" exe args
+ use toLog = redirectToLog ()
+ Process.exec { RedirectError = Some toLog.Post; RedirectOutput = Some toLog.Post; RedirectInput = None } tempDir cfg.EnvironmentVariables exe args
+
+ do! Commands.fsc exec cfg.FSC "" [ tempFile ".fs" ] |> checkResult
+
+ do! Commands.fsi exec cfg.FSI "" [ tempFile ".fsx" ] |> checkResult
+
+ }
+
+ do! checkfscBinPath ()
+
+ do! smokeTest ()
+
+ return cfg
+ }
+
+
+let suiteHelpers = lazy (
+ initializeSuite ()
+ |> Attempt.Run
+ |> function Success x -> x | Failure err -> failwith (sprintf "Error %A" err)
+)
+
+[]
+type public InitializeSuiteAttribute () =
+ inherit TestActionAttribute()
+
+ override x.BeforeTest details =
+ if details.IsSuite
+ then suiteHelpers.Force() |> ignore
+
+ override x.AfterTest details =
+ ()
+
+ override x.Targets with get() = ActionTargets.Test ||| ActionTargets.Suite
+
+
+[]
+()
+
+module FSharpTestSuite =
+
+ let getTagsOfFile path =
+ match File.ReadLines(path) |> Seq.take 5 |> Seq.tryFind (fun s -> s.StartsWith("// #")) with
+ | None -> []
+ | Some line ->
+ line.TrimStart('/').Split([| '#' |], StringSplitOptions.RemoveEmptyEntries)
+ |> Seq.map (fun s -> s.Trim())
+ |> Seq.filter (fun s -> s.Length > 0)
+ |> Seq.distinct
+ |> Seq.toList
+
+ let getTestFileMetadata dir =
+ Directory.EnumerateFiles(dir, "*.fs*")
+ |> Seq.toList
+ |> List.collect getTagsOfFile
+
+ let parseTestLst path =
+ let dir = Path.GetDirectoryName(path)
+ let commentLine (t: string) = t.StartsWith("#")
+ let lines =
+ File.ReadAllLines(path)
+ |> Array.filter (not << commentLine)
+ |> Array.filter (not << String.IsNullOrWhiteSpace)
+ let parse (t: string) =
+ let a = t.Split([| '\t'; '\t' |], StringSplitOptions.RemoveEmptyEntries)
+ let testDir = Commands.getfullpath dir a.[1]
+ [| for x in a.[0].Split(',') do yield (x, testDir) |]
+
+ lines |> Array.collect parse |> List.ofArray
+
+ let ``test.lst`` = lazy (
+ parseTestLst ( __SOURCE_DIRECTORY__/".."/"test.lst" )
+ )
+
+ let getTestLstTags db dir =
+ let normalizePath path =
+ Uri(path).LocalPath
+ |> (fun s -> s.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar))
+ |> (fun s -> s.ToUpperInvariant())
+
+ let sameDir a = (normalizePath dir) = (normalizePath a)
+ let normalizedPath = normalizePath dir
+ db
+ |> List.choose (fun (tag, d) -> if sameDir d then Some tag else None)
+
+ let fsharpSuiteDirectory = __SOURCE_DIRECTORY__
+
+ let setProps dir (props: NUnit.Framework.Interfaces.IPropertyBag) =
+ let testDir = dir |> Commands.getfullpath fsharpSuiteDirectory
+
+ if not (Directory.Exists(testDir)) then failwithf "test directory '%s' does not exists" testDir
+
+ let categories = [ dir ] @ (testDir |> getTestFileMetadata) @ (testDir |> getTestLstTags ``test.lst``.Value)
+ categories |> List.iter (fun (c: string) -> props.Add(NUnit.Framework.Internal.PropertyNames.Category, c))
+
+ props.Set("DIRECTORY", testDir)
+
+ let testContext () =
+ let test = NUnit.Framework.TestContext.CurrentContext.Test
+ { Directory = test.Properties.Get("DIRECTORY") :?> string;
+ Config = suiteHelpers.Value }
+
+// parametrized test cases does not inherits properties of test ( see https://github.com/nunit/nunit/issues/548 )
+// and properties is where the custom context data is saved
+
+type FSharpSuiteTestAttribute(dir: string) =
+ inherit NUnitAttribute()
+ interface NUnit.Framework.Interfaces.IApplyToTest with
+ member x.ApplyToTest(test: NUnit.Framework.Internal.Test) =
+ try
+ test.Properties |> FSharpTestSuite.setProps dir
+ with ex ->
+ test.RunState <- NUnit.Framework.Interfaces.RunState.NotRunnable
+ test.Properties.Set(NUnit.Framework.Internal.PropertyNames.SkipReason, NUnit.Framework.Internal.ExceptionHelper.BuildMessage(ex))
+ test.Properties.Set(NUnit.Framework.Internal.PropertyNames.ProviderStackTrace, NUnit.Framework.Internal.ExceptionHelper.BuildStackTrace(ex))
+
+type FSharpSuiteTestCaseData =
+ inherit TestCaseData
+
+ new (dir: string, [] arguments: Object array) as this =
+ { inherit TestCaseData(arguments) }
+ then
+ this.Properties |> FSharpTestSuite.setProps dir
+ arguments
+ |> Array.choose (fun a -> match a with :? Permutation as p -> Some p | _ -> None)
+ |> Array.iter (fun p -> this.SetCategory(sprintf "%A" p) |> ignore)
+
+[]
+type FSharpSuiteTestCaseAttribute =
+ inherit TestCaseAttribute
+
+ new (dir: string, [] arguments: Object array) as this =
+ { inherit TestCaseAttribute(arguments) }
+ then
+ this.Properties |> FSharpTestSuite.setProps dir
+
+
+type FSharpSuitePermutationsAttribute(dir: string) =
+ inherit NUnitAttribute()
+
+ let _builder = NUnit.Framework.Internal.Builders.NUnitTestCaseBuilder()
+ interface NUnit.Framework.Interfaces.ITestBuilder with
+ member x.BuildFrom(methodInfo, suite) =
+ let allPermutations =
+ [ FSI_FILE; FSI_STDIN; FSI_STDIN_OPT; FSI_STDIN_GUI;
+ FSC_BASIC; FSC_HW; FSC_O3;
+ GENERATED_SIGNATURE; EMPTY_SIGNATURE; EMPTY_SIGNATURE_OPT;
+ FSC_OPT_MINUS_DEBUG; FSC_OPT_PLUS_DEBUG;
+ FRENCH; SPANISH;
+ AS_DLL;
+ WRAPPER_NAMESPACE; WRAPPER_NAMESPACE_OPT
+ ]
+ |> List.map (fun p -> (new FSharpSuiteTestCaseData (dir, p)))
+
+ allPermutations
+ |> List.map (fun tc -> _builder.BuildTestMethod(methodInfo, suite, tc))
+ |> Seq.ofList
+
+module FileGuard =
+ let private remove path = if File.Exists(path) then Commands.rm (Path.GetTempPath()) path
+
+ []
+ type T (path: string) =
+ member x.Path = path
+ interface IDisposable with
+ member x.Dispose () = remove path
+
+ let create path =
+ if not (Path.IsPathRooted(path)) then failwithf "path '%s' must be absolute" path
+ remove path
+ new T(path)
+
+ let exists (guard: T) = guard.Path |> File.Exists
+
+
+let checkGuardExists guard = processor {
+ if not <| (guard |> FileGuard.exists)
+ then return! genericError (sprintf "exit code 0 but %s file doesn't exists" (guard.Path |> Path.GetFileName))
+ }
+
+
+let check (f: Attempt<_,_>) =
+ f |> Attempt.Run |> checkTestResult
+
+
+type RedirectInfo =
+ { Output : RedirectTo
+ Input : RedirectFrom option }
+
+and RedirectTo =
+ | Inherit
+ | Output of RedirectToType
+ | OutputAndError of RedirectToType
+ | Error of RedirectToType
+
+and RedirectToType =
+ | Overwrite of FilePath
+ | Append of FilePath
+
+and RedirectFrom =
+ | RedirectInput of FilePath
+
+
+module Command =
+
+ let logExec dir path args redirect =
+ let inF =
+ function
+ | None -> ""
+ | Some(RedirectInput l) -> sprintf " <%s" l
+ let redirectType = function Overwrite x -> sprintf ">%s" x | Append x -> sprintf ">>%s" x
+ let outF =
+ function
+ | Inherit -> ""
+ | Output r-> sprintf " 1%s" (redirectType r)
+ | OutputAndError r -> sprintf " 1%s 2>&1" (redirectType r)
+ | Error r -> sprintf " 2%s" (redirectType r)
+ sprintf "%s%s%s%s" path (match args with "" -> "" | x -> " " + x) (inF redirect.Input) (outF redirect.Output)
+
+ let exec dir envVars redirect path args =
+ let { Output = o; Input = i} = redirect
+
+ let inputWriter sources (writer: StreamWriter) =
+ let pipeFile name = async {
+ let path = Commands.getfullpath dir name
+ use reader = File.OpenRead (path)
+ use ms = new MemoryStream()
+ do! reader.CopyToAsync (ms) |> (Async.AwaitIAsyncResult >> Async.Ignore)
+ ms.Position <- 0L
+ try
+ do! ms.CopyToAsync(writer.BaseStream) |> (Async.AwaitIAsyncResult >> Async.Ignore)
+ do! writer.FlushAsync() |> (Async.AwaitIAsyncResult >> Async.Ignore)
+ with
+ | :? System.IO.IOException as ex -> //input closed is ok if process is closed
+ ()
+ }
+ sources |> pipeFile |> Async.RunSynchronously
+
+ let inF fCont cmdArgs =
+ match i with
+ | None -> fCont cmdArgs
+ | Some(RedirectInput l) -> fCont { cmdArgs with RedirectInput = Some (inputWriter l) }
+
+ let openWrite rt =
+ let fullpath = Commands.getfullpath dir
+ match rt with
+ | Append p -> new StreamWriter (p |> fullpath, true)
+ | Overwrite p -> new StreamWriter (p |> fullpath, false)
+
+ let outF fCont cmdArgs =
+ match o with
+ | RedirectTo.Inherit ->
+ use toLog = redirectToLog ()
+ fCont { cmdArgs with RedirectOutput = Some (toLog.Post); RedirectError = Some (toLog.Post) }
+ | Output r ->
+ use writer = openWrite r
+ use outFile = redirectTo writer
+ use toLog = redirectToLog ()
+ fCont { cmdArgs with RedirectOutput = Some (outFile.Post); RedirectError = Some (toLog.Post) }
+ | OutputAndError r ->
+ use writer = openWrite r
+ use outFile = redirectTo writer
+ fCont { cmdArgs with RedirectOutput = Some (outFile.Post); RedirectError = Some (outFile.Post) }
+ | Error r ->
+ use writer = openWrite r
+ use outFile = redirectTo writer
+ use toLog = redirectToLog ()
+ fCont { cmdArgs with RedirectOutput = Some (toLog.Post); RedirectError = Some (outFile.Post) }
+
+ let exec cmdArgs =
+ log "%s" (logExec dir path args redirect)
+ Process.exec cmdArgs dir envVars path args
+
+ { RedirectOutput = None; RedirectError = None; RedirectInput = None }
+ |> (outF (inF exec))
+
diff --git a/tests/fsharp/optimize/tests_optimize.fs b/tests/fsharp/optimize/tests_optimize.fs
new file mode 100644
index 00000000000..f1ed301e1b7
--- /dev/null
+++ b/tests/fsharp/optimize/tests_optimize.fs
@@ -0,0 +1,276 @@
+module ``FSharp-Tests-Optimize``
+
+open System
+open System.IO
+open NUnit.Framework
+
+open NUnitConf
+open PlatformHelpers
+open FSharpTestSuiteTypes
+
+let testContext = FSharpTestSuite.testContext
+
+module Analyses =
+
+ let ``fsc >a 2>&1`` cfg dir =
+ let ``exec >a 2>&1`` outFile p =
+ Command.exec dir cfg.EnvironmentVariables { Output = OutputAndError(Overwrite(outFile)); Input = None; } p
+ >> checkResult
+ Printf.ksprintf (fun flags sources out -> Commands.fsc (``exec >a 2>&1`` out) cfg.FSC flags sources)
+
+ let fsdiff cfg dir a b = processor {
+ let out = new ResizeArray()
+ let redirectOutputToFile path args =
+ log "%s %s" path args
+ let toLog = redirectToLog ()
+ Process.exec { RedirectOutput = Some (function null -> () | s -> out.Add(s)); RedirectError = Some toLog.Post; RedirectInput = None; } dir cfg.EnvironmentVariables path args
+ do! (Commands.fsdiff redirectOutputToFile cfg.FSDIFF true a b) |> (fun _ -> Success ())
+ return out.ToArray() |> List.ofArray
+ }
+
+ []
+ let functionSizes () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let getfullpath = Commands.getfullpath dir
+ let ``fsc >a 2>&1`` = ``fsc >a 2>&1`` cfg dir
+ let fsdiff = fsdiff cfg dir
+
+ let outFile = "sizes.FunctionSizes.output.test.txt"
+ let expectedFile = "sizes.FunctionSizes.output.test.bsl"
+
+ // echo == FunctionSizes
+ log "== FunctionSizes"
+ // "%FSC%" %fsc_flags% --nologo -O --test:FunctionSizes sizes.fs >sizes.FunctionSizes.output.test.txt 2>&1
+ do! ``fsc >a 2>&1`` "%s --nologo -O --test:FunctionSizes" cfg.fsc_flags ["sizes.fs"] outFile
+ // if NOT EXIST sizes.FunctionSizes.output.test.bsl COPY sizes.FunctionSizes.output.test.txt sizes.FunctionSizes.output.test.bsl
+ ignore "used only the first time when no expected output file exists, useless"
+ // %FSDIFF% sizes.FunctionSizes.output.test.txt sizes.FunctionSizes.output.test.bsl > sizes.FunctionSizes.output.test.diff
+ let! diff = fsdiff outFile expectedFile
+
+ do! match diff with
+ | [] -> Success
+ | l ->
+ NUnitConf.genericError (sprintf "'%s' and '%s' differ; %A" (getfullpath outFile) (getfullpath expectedFile) diff)
+ })
+
+ []
+ let totalSizes () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let ``fsc >a 2>&1`` = ``fsc >a 2>&1`` cfg dir
+ let fsdiff = fsdiff cfg dir
+ let getfullpath = Commands.getfullpath dir
+
+ let outFile = "sizes.TotalSizes.output.test.txt"
+ let expectedFile = "sizes.TotalSizes.output.test.bsl"
+
+ // echo == TotalSizes
+ log "== TotalSizes"
+ // "%FSC%" %fsc_flags% --nologo -O --test:TotalSizes sizes.fs >sizes.TotalSizes.output.test.txt 2>&1
+ do! ``fsc >a 2>&1`` "%s --nologo -O --test:TotalSizes" cfg.fsc_flags ["sizes.fs"] outFile
+ // if NOT EXIST sizes.TotalSizes.output.test.bsl COPY sizes.TotalSizes.output.test.txt sizes.TotalSizes.output.test.bsl
+ ignore "used only the first time when no expected output file exists, useless"
+ // %FSDIFF% sizes.TotalSizes.output.test.txt sizes.TotalSizes.output.test.bsl > sizes.TotalSizes.output.test.diff
+ let! diff = fsdiff outFile expectedFile
+
+ do! match diff with
+ | [] -> Success
+ | l ->
+ NUnitConf.genericError (sprintf "'%s' and '%s' differ; %A" (getfullpath outFile) (getfullpath expectedFile) diff)
+ })
+
+ []
+ let hasEffect () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let ``fsc >a 2>&1`` = ``fsc >a 2>&1`` cfg dir
+ let fsdiff = fsdiff cfg dir
+ let getfullpath = Commands.getfullpath dir
+
+ let outFile = "effects.HasEffect.output.test.txt"
+ let expectedFile = "effects.HasEffect.output.test.bsl"
+
+ // echo == HasEffect
+ log "== HasEffect"
+ // "%FSC%" %fsc_flags% --nologo -O --test:HasEffect effects.fs >effects.HasEffect.output.test.txt 2>&1
+ do! ``fsc >a 2>&1`` "%s --nologo -O --test:HasEffect" cfg.fsc_flags ["effects.fs"] outFile
+ // if NOT EXIST effects.HasEffect.output.test.bsl COPY effects.HasEffect.output.test.txt effects.HasEffect.output.test.bsl
+ ignore "used only the first time when no expected output file exists, useless"
+ // %FSDIFF% effects.HasEffect.output.test.txt effects.HasEffect.output.test.bsl > effects.HasEffect.output.test.diff
+ let! diff = fsdiff outFile expectedFile
+
+ do! match diff with
+ | [] -> Success
+ | l ->
+ NUnitConf.genericError (sprintf "'%s' and '%s' differ; %A" (getfullpath outFile) (getfullpath expectedFile) diff)
+ })
+
+ []
+ let noNeedToTailcall () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let ``fsc >a 2>&1`` = ``fsc >a 2>&1`` cfg dir
+ let fsdiff = fsdiff cfg dir
+ let getfullpath = Commands.getfullpath dir
+
+ let outFile = "tailcalls.NoNeedToTailcall.output.test.txt"
+ let expectedFile = "tailcalls.NoNeedToTailcall.output.test.bsl"
+
+ // echo == NoNeedToTailcall
+ log "== NoNeedToTailcall"
+ // "%FSC%" %fsc_flags% --nologo -O --test:NoNeedToTailcall tailcalls.fs >tailcalls.NoNeedToTailcall.output.test.txt 2>&1
+ do! ``fsc >a 2>&1`` "%s --nologo -O --test:NoNeedToTailcall" cfg.fsc_flags ["tailcalls.fs"] outFile
+ // if NOT EXIST tailcalls.NoNeedToTailcall.output.test.bsl COPY tailcalls.NoNeedToTailcall.output.test.txt tailcalls.NoNeedToTailcall.output.test.bsl
+ ignore "used only the first time when no expected output file exists, useless"
+ // %FSDIFF% tailcalls.NoNeedToTailcall.output.test.txt tailcalls.NoNeedToTailcall.output.test.bsl > tailcalls.NoNeedToTailcall.output.test.diff
+ let! diff = fsdiff outFile expectedFile
+
+ do! match diff with
+ | [] -> Success
+ | l ->
+ NUnitConf.genericError (sprintf "'%s' and '%s' differ; %A" (getfullpath outFile) (getfullpath expectedFile) diff)
+ })
+
+
+
+
+module Inline =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+
+ // "%FSC%" %fsc_flags% -g --optimize- --target:library -o:lib.dll lib.fs
+ do! fsc "%s -g --optimize- --target:library -o:lib.dll" cfg.fsc_flags ["lib.fs"]
+
+ // "%FSC%" %fsc_flags% --optimize --target:library -o:lib--optimize.dll -g lib.fs
+ do! fsc "%s --optimize --target:library -o:lib--optimize.dll -g" cfg.fsc_flags ["lib.fs"]
+
+ // "%FSC%" %fsc_flags% -g --optimize- -o:test.exe test.fs -r:lib.dll
+ do! fsc "%s -g --optimize- -o:test.exe -r:lib.dll" cfg.fsc_flags ["test.fs "]
+
+ // "%FSC%" %fsc_flags% --optimize -o:test--optimize.exe -g test.fs -r:lib--optimize.dll
+ do! fsc "%s --optimize -o:test--optimize.exe -g -r:lib--optimize.dll" cfg.fsc_flags ["test.fs "]
+
+ }
+
+ let run cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let ildasm = Printf.ksprintf (Commands.ildasm exec cfg.ILDASM)
+ let getfullpath = Commands.getfullpath dir
+
+ // if not exist "%ILDASM%" (
+ // @echo '%ILDASM%' not found.
+ // goto Error
+ // )
+ ignore "already checked at suite startup"
+
+ // "%ILDASM%" /nobar /out=test.il test.exe
+ do! ildasm "/nobar /out=test.il" "test.exe"
+
+ // "%ILDASM%" /nobar /out=test--optimize.il test--optimize.exe
+ do! ildasm "/nobar /out=test--optimize.il" "test--optimize.exe"
+
+ // type test--optimize.il | find /C ".locals init" > count--optimize
+ let ``test--optimize.il`` =
+ File.ReadLines (getfullpath "test--optimize.il")
+ |> Seq.filter (fun line -> line.Contains(".locals init"))
+ |> List.ofSeq
+
+ // for /f %%c IN (count--optimize) do (if NOT "%%c"=="0" (
+ do! match ``test--optimize.il`` with
+ | [] -> Success
+ | lines ->
+ // echo Error: optimizations not removed. Relevant lines from IL file follow:
+ // type test--optimize.il | find ".locals init"
+ // goto SetError)
+ NUnitConf.genericError (sprintf "Error: optimizations not removed. Relevant lines from IL file follow: %A" lines)
+ // )
+
+ // type test.il | find /C ".locals init" > count
+ // for /f %%c IN (count) do (
+ // set NUMELIM=%%c
+ // )
+ let numElim =
+ File.ReadLines (getfullpath "test.il")
+ |> Seq.filter (fun line -> line.Contains(".locals init"))
+ |> Seq.length
+
+ log "Ran ok - optimizations removed %d textual occurrences of optimizable identifiers from target IL" numElim
+
+ }
+
+ []
+ let ``inline`` () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+module Stats =
+
+ []
+ let stats () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let ildasm = Commands.ildasm exec cfg.ILDASM
+ let getfullpath = Commands.getfullpath dir
+
+ // if not exist "%ILDASM%" (goto Error)
+ ignore "already checked at suite startup"
+
+ // where sd.exe 2> NUL
+ // if not ERRORLEVEL 1 ( sd edit stats.txt ) else (attrib -r stats.txt )
+ ignore "dont know"
+
+ // "%ILDASM%" /nobar /out=FSharp.Core.il "%FSCOREDLLPATH%"
+ do! ildasm "/nobar /out=FSharp.Core.il" cfg.FSCOREDLLPATH
+
+ let ``FSharp.Core.il`` = File.ReadLines(getfullpath "FSharp.Core.il") |> Seq.toList
+
+ let contains text (s: string) = if s.Contains(text) then 1 else 0
+
+ // echo Counting TypeFuncs...
+ // type FSharp.Core.il | find /C "extends Microsoft.FSharp.TypeFunc" > count-Microsoft.FSharp-TypeFunc
+ let typeFunc = ``FSharp.Core.il`` |> List.sumBy (contains "extends Microsoft.FSharp.TypeFunc")
+ // echo Counting classes...
+ // type FSharp.Core.il | find /C ".class" > count-Microsoft.FSharp-.class
+ let classes = ``FSharp.Core.il`` |> List.sumBy (contains ".class")
+ // echo Counting methods...
+ // type FSharp.Core.il | find /C ".method" > count-Microsoft.FSharp-.method
+ let methods = ``FSharp.Core.il`` |> List.sumBy (contains ".method")
+ // echo Counting fields...
+ // type FSharp.Core.il | find /C ".field" > count-Microsoft.FSharp-.field
+ let fields = ``FSharp.Core.il`` |> List.sumBy (contains ".field")
+
+ // for /f %%c IN (count-Microsoft.FSharp-TypeFunc) do (
+ // for /f %%d IN (count-Microsoft.FSharp-.class) do (
+ // for /f %%e IN (count-Microsoft.FSharp-.method) do (
+ // for /f %%f IN (count-Microsoft.FSharp-.field) do (
+ // echo %date%, %time%, Microsoft.FSharp-TypeFunc, %%c, Microsoft.FSharp-classes, %%d, Microsoft.FSharp-methods, %%e, , Microsoft.FSharp-fields, %%f, >> stats.txt
+ let date = DateTime.Today.ToString("dd/MM/yyyy") // 23/11/2006
+ let time = DateTime.Now.ToString("HH:mm:ss.ff") // 16:03:23.40
+ let m = sprintf "%s, %s, Microsoft.FSharp-TypeFunc, %d, Microsoft.FSharp-classes, %d, Microsoft.FSharp-methods, %d, , Microsoft.FSharp-fields, %d, " date time typeFunc classes methods fields
+
+ log "now:"
+ log "%s" m
+ log "old (from 'stats.txt'):"
+ log "%s" (File.ReadAllLines(getfullpath "stats.txt") |> Seq.where (String.IsNullOrWhiteSpace >> not) |> Seq.last)
+
+ //REVIEW test add a line to a versioned file 'stats.txt', but is not maintained anymore?
+ ignore (fun () -> File.AppendAllLines(getfullpath "stats.txt", [ m ]) )
+
+
+ // )
+ // )
+ // )
+ // )
+
+ })
diff --git a/tests/fsharp/packages.config b/tests/fsharp/packages.config
new file mode 100644
index 00000000000..0c9dd291aa3
--- /dev/null
+++ b/tests/fsharp/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/tests/fsharp/perf/tests_perf.fs b/tests/fsharp/perf/tests_perf.fs
new file mode 100644
index 00000000000..1c57b24bb93
--- /dev/null
+++ b/tests/fsharp/perf/tests_perf.fs
@@ -0,0 +1,35 @@
+module ``FSharp-Tests-Perf``
+
+open System
+open System.IO
+open NUnit.Framework
+
+open FSharpTestSuiteTypes
+open NUnitConf
+open PlatformHelpers
+
+let testContext = FSharpTestSuite.testContext
+
+
+module Graph =
+
+ []
+ let graph p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+module Nbody =
+
+ []
+ let nbody p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
diff --git a/tests/fsharp/regression/tests_regression.fs b/tests/fsharp/regression/tests_regression.fs
new file mode 100644
index 00000000000..ec737a90e91
--- /dev/null
+++ b/tests/fsharp/regression/tests_regression.fs
@@ -0,0 +1,235 @@
+module ``FSharp-Tests-Regression``
+
+open System
+open System.IO
+open NUnit.Framework
+
+open FSharpTestSuiteTypes
+open NUnitConf
+open PlatformHelpers
+
+let testContext = FSharpTestSuite.testContext
+
+
+module ``26`` =
+
+ []
+ let ``26`` p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+module ``321`` =
+
+ []
+ let ``321`` p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+module ``655`` =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+
+ // "%FSC%" %fsc_flags% -a -o:pack.dll xlibC.ml
+ do! fsc "%s -a -o:pack.dll" cfg.fsc_flags ["xlibC.ml"]
+
+ // "%PEVERIFY%" pack.dll
+ do! peverify "pack.dll"
+
+ // "%FSC%" %fsc_flags% -o:test.exe -r:pack.dll main.fs
+ do! fsc "%s -o:test.exe -r:pack.dll" cfg.fsc_flags ["main.fs"]
+
+ // "%PEVERIFY%" test.exe
+ do! peverify "test.exe"
+
+ }
+
+ let run cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+
+ // %CLIX% test.exe
+ do! exec ("."/"test.exe") ""
+
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ []
+ let ``655`` () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+[]
+module ``656`` =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Printf.ksprintf (Commands.peverify exec cfg.PEVERIFY)
+
+ //REVIEW ILX_CONFIG?
+ let ILX_CONFIG = ""
+
+ // "%FSC%" %fsc_flags% -o:pack%ILX_CONFIG%.exe misc.fs mathhelper.fs filehelper.fs formshelper.fs plot.fs traj.fs playerrecord.fs trackedplayers.fs form.fs
+ do! fsc "%s -o:pack%s.exe" cfg.fsc_flags ILX_CONFIG ["misc.fs mathhelper.fs filehelper.fs formshelper.fs plot.fs traj.fs playerrecord.fs trackedplayers.fs form.fs"]
+
+ // "%PEVERIFY%" pack%ILX_CONFIG%.exe
+ do! peverify "pack%s.exe" ILX_CONFIG
+ }
+
+ let run cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ //REVIEW ILX_CONFIG?
+ let ILX_CONFIG = ""
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+
+ // %CLIX% pack%ILX_CONFIG%.exe
+ do! exec ("."/(sprintf "pack%s.exe" ILX_CONFIG)) ""
+
+ // if NOT EXIST test.ok goto SetError
+ do! testOkFile |> NUnitConf.checkGuardExists
+
+ return! NUnitConf.genericError "env var 'ILX_CONFIG' not found, using '' as default the test pass"
+ }
+
+ []
+ let ``656`` () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+
+module ``83`` =
+
+ []
+ let ``83`` p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ // if "%CLR_SUPPORTS_WINFORMS%"=="false" ( goto Skip)
+ do! match cfg.EnvironmentVariables |> Map.tryFind "CLR_SUPPORTS_WINFORMS" |> Option.map (fun s -> s.ToLower()) with
+ | Some "false" -> NUnitConf.skip "env var CLR_SUPPORTS_WINFORMS is false"
+ | Some _ | None -> Success
+
+ // call %~d0%~p0..\..\single-test-build.bat
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ // if "%CLR_SUPPORTS_WINFORMS%"=="false" ( goto Skip )
+ ignore "already skipped if CLR_SUPPORTS_WINFORMS == false"
+
+ // if "%COMPLUS_Version%"=="v1.0.3705" ( goto Skip )
+ do! match cfg.EnvironmentVariables |> Map.tryFind "COMPLUS_Version" |> Option.map (fun s -> s.ToLower()) with
+ | Some "v1.0.3705" -> NUnitConf.skip "env var COMPLUS_Version is v1.0.3705"
+ | Some _ | None -> Success
+
+ // call %~d0%~p0..\..\single-test-run.bat
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+
+module ``84`` =
+
+ []
+ let ``84`` p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+module ``85`` =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+
+ // if "%CLR_SUPPORTS_GENERICS%"=="false" ( goto Skip)
+ do! match cfg.EnvironmentVariables |> Map.tryFind "CLR_SUPPORTS_GENERICS" |> Option.map (fun s -> s.ToLower()) with
+ | Some "false" -> NUnitConf.skip "env var CLR_SUPPORTS_GENERICS is false"
+ | Some _ | None -> Success
+
+ // if "%CLR_SUPPORTS_SYSTEM_WEB%"=="false" ( goto Skip)
+ do! match cfg.EnvironmentVariables |> Map.tryFind "CLR_SUPPORTS_SYSTEM_WEB" |> Option.map (fun s -> s.ToLower()) with
+ | Some "false" -> NUnitConf.skip "env var CLR_SUPPORTS_SYSTEM_WEB is false"
+ | Some _ | None -> Success
+
+ // "%FSC%" %fsc_flags% -r:Category.dll -a -o:petshop.dll Category.ml
+ do! fsc "%s -r:Category.dll -a -o:petshop.dll" cfg.fsc_flags ["Category.ml"]
+
+ // "%PEVERIFY%" petshop.dll
+ do! peverify "petshop.dll"
+
+ }
+
+ []
+ let ``85`` () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ // REM build.bat produces only dll's. Nothing to run
+
+ })
+
+
+module ``86`` =
+
+ []
+ let ``86`` p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+module ``Tuple-bug-1`` =
+
+ []
+ let ``tuple-bug-1`` p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
diff --git a/tests/fsharp/single-neg-test.fs b/tests/fsharp/single-neg-test.fs
new file mode 100644
index 00000000000..b994fe87053
--- /dev/null
+++ b/tests/fsharp/single-neg-test.fs
@@ -0,0 +1,219 @@
+module SingleNegTest
+
+open System
+open System.IO
+open NUnit.Framework
+
+open PlatformHelpers
+open NUnitConf
+open FSharpTestSuiteTypes
+
+let private singleNegTest' (cfg: TestConfig) workDir testname = processor {
+
+ // call %~d0%~p0..\config.bat
+ ignore "from arguments"
+
+ // if errorlevel 1 (
+ // set ERRORMSG=%ERRORMSG% config.bat failed;
+ // goto :ERROR
+ // )
+ ignore "already checked"
+
+ let exec p = Command.exec workDir cfg.EnvironmentVariables { Output = Inherit; Input = None } p >> checkResult
+ let fsdiff a = Commands.fsdiff exec cfg.FSDIFF true a
+ let envOrFail key =
+ cfg.EnvironmentVariables
+ |> Map.tryFind key
+ |> function Some x -> (fun () -> Success x) | None -> NUnitConf.genericError (sprintf "environment variable '%s' required " key)
+ let fullpath = Commands.getfullpath workDir
+ let fileExists = fullpath >> Commands.fileExists workDir >> Option.isSome
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let fsc_flags = cfg.fsc_flags
+
+ // if not exist "%FSC%" (
+ // set ERRORMSG=Could not find FSC at path "%FSC%"
+ // goto :ERROR
+ // )
+ ignore "already checked"
+
+ // set testname=%1
+ ignore "from arguments"
+
+ // REM == Set baseline (fsc vs vs, in case the vs baseline exists)
+ let BSLFILE =
+ // IF EXIST %testname%.vsbsl (set BSLFILE=%testname%.vsbsl)
+ // IF NOT EXIST %testname%.vsbsl (set BSLFILE=%testname%.bsl)
+ if (sprintf "%s.vsbsl" testname) |> fileExists
+ then sprintf "%s.vsbsl" testname
+ else sprintf "%s.bsl" testname
+
+ // %FSDIFF% %~f0 %~f0
+ // @if ERRORLEVEL 1 (
+ // set ERRORMSG=%ERRORMSG% FSDIFF likely not found;
+ // goto Error
+ // )
+
+ //REVIEW move to suite smoke tests like fsc/fsi?
+ do! fsdiff BSLFILE BSLFILE
+
+ // set sources=
+ // if exist "%testname%.mli" (set sources=%sources% %testname%.mli)
+ // if exist "%testname%.fsi" (set sources=%sources% %testname%.fsi)
+ // if exist "%testname%.ml" (set sources=%sources% %testname%.ml)
+ // if exist "%testname%.fs" (set sources=%sources% %testname%.fs)
+ // if exist "%testname%.fsx" (set sources=%sources% %testname%.fsx)
+ // if exist "%testname%a.mli" (set sources=%sources% %testname%a.mli)
+ // if exist "%testname%a.fsi" (set sources=%sources% %testname%a.fsi)
+ // if exist "%testname%a.ml" (set sources=%sources% %testname%a.ml)
+ // if exist "%testname%a.fs" (set sources=%sources% %testname%a.fs)
+ // if exist "%testname%b.mli" (set sources=%sources% %testname%b.mli)
+ // if exist "%testname%b.fsi" (set sources=%sources% %testname%b.fsi)
+ // if exist "%testname%b.ml" (set sources=%sources% %testname%b.ml)
+ // if exist "%testname%b.fs" (set sources=%sources% %testname%b.fs)
+ let sources = [
+ let src =
+ [ testname + ".mli"; testname + ".fsi"; testname + ".ml"; testname + ".fs"; testname + ".fsx";
+ testname + "a.mli"; testname + "a.fsi"; testname + "a.ml"; testname + "a.fs";
+ testname + "b.mli"; testname + "b.fsi"; testname + "b.ml"; testname + "b.fs" ]
+
+ yield! src |> List.filter fileExists
+
+ // if exist "helloWorldProvider.dll" (set sources=%sources% -r:helloWorldProvider.dll)
+ if fileExists "helloWorldProvider.dll"
+ then yield "-r:helloWorldProvider.dll"
+
+ // if exist "%testname%-pre.fs" (
+ // set sources=%sources% -r:%testname%-pre.dll
+ // )
+ if fileExists (testname + "-pre.fs")
+ then yield (sprintf "-r:%s-pre.dll" testname)
+
+ ]
+
+ // REM check negative tests for bootstrapped fsc.exe due to line-ending differences
+ // if "%FSC:fscp=X%" == "%FSC%" (
+ do! if cfg.FSC.Contains("fscp")
+ then NUnitConf.skip "bootstrapped fsc.exe due to line-ending differences"
+ else Success
+
+ // if exist "%testname%-pre.fs" (
+ do! if fileExists (testname + "-pre.fs")
+ // "%FSC%" %fsc_flags% -a -o:%testname%-pre.dll "%testname%-pre.fs"
+ then fsc "%s -a -o:%s-pre.dll" fsc_flags testname [testname + "-pre.fs"]
+ else Success ()
+ // @if ERRORLEVEL 1 (
+ // set ERRORMSG=%ERRORMSG% FSC failed for precursor library code for %sources%;
+ // goto SetError
+ // )
+ // )
+
+ // echo Negative typechecker testing: %testname%
+ log "Negative typechecker testing: %s" testname
+
+ let fsc' =
+ // "%FSC%" %fsc_flags% --vserrors --warnaserror --nologo --maxerrors:10000 -a -o:%testname%.dll %sources% 2> %testname%.err
+ // @if NOT ERRORLEVEL 1 (
+ // set ERRORMSG=%ERRORMSG% FSC passed unexpectedly for %sources%;
+ // goto SetError
+ // )
+ let ``exec 2>`` errPath = Command.exec workDir cfg.EnvironmentVariables { Output = Error(Overwrite(errPath)); Input = None }
+ let checkErrorLevel1 = function
+ | CmdResult.ErrorLevel 1 -> Success
+ | CmdResult.Success | CmdResult.ErrorLevel _ -> NUnitConf.genericError (sprintf "FSC passed unexpectedly for %A" sources)
+
+ Printf.ksprintf (fun flags sources errPath -> Commands.fsc (``exec 2>`` errPath) cfg.FSC flags sources |> checkErrorLevel1)
+
+ let fsdiff a b = processor {
+ let out = new ResizeArray()
+ let redirectOutputToFile path args =
+ log "%s %s" path args
+ let toLog = redirectToLog ()
+ Process.exec { RedirectOutput = Some (function null -> () | s -> out.Add(s)); RedirectError = Some toLog.Post; RedirectInput = None; } workDir cfg.EnvironmentVariables path args
+ do! (Commands.fsdiff redirectOutputToFile cfg.FSDIFF true a b) |> checkResult
+ return out.ToArray() |> List.ofArray
+ }
+
+ // "%FSC%" %fsc_flags% --vserrors --warnaserror --nologo --maxerrors:10000 -a -o:%testname%.dll %sources% 2> %testname%.err
+ do! fsc' """%s --vserrors --warnaserror --nologo --maxerrors:10000 -a -o:%s.dll""" fsc_flags testname sources (sprintf "%s.err" testname)
+
+ // %FSDIFF% %testname%.err %testname%.bsl > %testname%.diff
+ let! testnameDiff = fsdiff (sprintf "%s.err" testname) (sprintf "%s.bsl" testname)
+
+ // for /f %%c IN (%testname%.diff) do (
+ do! match testnameDiff with
+ | [] -> Success
+ | l ->
+ // echo ***** %testname%.err %testname%.bsl differed: a bug or baseline may neeed updating
+ log "***** %s.err %s.bsl differed: a bug or baseline may neeed updating" testname testname
+ // set ERRORMSG=%ERRORMSG% %testname%.err %testname%.bsl differ;
+ NUnitConf.genericError (sprintf "%s.err %s.bsl differ; %A" testname testname l)
+
+ // echo Good, output %testname%.err matched %testname%.bsl
+ log "Good, output %s.err matched %s.bsl" testname testname
+
+ // "%FSC%" %fsc_flags% --test:ContinueAfterParseFailure --vserrors --warnaserror --nologo --maxerrors:10000 -a -o:%testname%.dll %sources% 2> %testname%.vserr
+ do! fsc' "%s --test:ContinueAfterParseFailure --vserrors --warnaserror --nologo --maxerrors:10000 -a -o:%s.dll" fsc_flags testname sources (sprintf "%s.vserr" testname)
+ // @if NOT ERRORLEVEL 1 (
+ // set ERRORMSG=%ERRORMSG% FSC passed unexpectedly for %sources%;
+ // goto SetError
+ // )
+
+ // %FSDIFF% %testname%.vserr %BSLFILE% > %testname%.vsdiff
+ let! testnameDiff = fsdiff (sprintf "%s.vserr" testname) BSLFILE
+
+ // for /f %%c IN (%testname%.vsdiff) do (
+ do! match testnameDiff with
+ | [] -> Success
+ | l ->
+ // echo ***** %testname%.vserr %BSLFILE% differed: a bug or baseline may neeed updating
+ log "***** %s.vserr %s differed: a bug or baseline may neeed updating" testname BSLFILE
+ // set ERRORMSG=%ERRORMSG% %testname%.vserr %BSLFILE% differ;
+ NUnitConf.genericError (sprintf "%s.vserr %s differ; %A" testname BSLFILE l)
+
+ // echo Good, output %testname%.vserr matched %BSLFILE%
+ log "Good, output %s.vserr matched %s" testname BSLFILE
+ // )
+ }
+
+let singleNegTest =
+
+ // :Ok
+ let doneOK x =
+ // echo Ran fsharp %~f0 ok.
+ log "Ran fsharp %%~f0 ok"
+ // endlocal
+ // exit /b 0
+ // goto :EOF
+ Success x
+
+ // :Skip
+ let doneSkipped workDir msg x =
+ // echo Skipped %~f0
+ log "Skipped neg run '%s' reason: %s" workDir msg
+ // endlocal
+ // exit /b 0
+ // goto :EOF
+ Success x
+
+ // :Error
+ let doneError err msg =
+ // echo %ERRORMSG%
+ log "%s" msg
+ // exit /b %ERRORLEVEL%
+ // goto :EOF
+ Failure (err)
+
+ // :SETERROR
+ // set NonexistentErrorLevel 2> nul
+ // goto Error
+ // goto :EOF
+
+ let flow cfg workDir testname () =
+ singleNegTest' cfg workDir testname
+ |> Attempt.Run
+ |> function
+ | Success () -> doneOK ()
+ | Failure (Skipped msg) -> doneSkipped workDir msg ()
+ | Failure (GenericError msg) -> doneError (GenericError msg) msg
+ | Failure (ProcessExecError (err,msg)) -> doneError (ProcessExecError(err,msg)) msg
+ flow
diff --git a/tests/fsharp/single-test-build.fs b/tests/fsharp/single-test-build.fs
new file mode 100644
index 00000000000..e2ff68e1d51
--- /dev/null
+++ b/tests/fsharp/single-test-build.fs
@@ -0,0 +1,404 @@
+module SingleTestBuild
+
+open System
+open System.IO
+open System.Diagnostics
+open NUnit.Framework
+
+open PlatformHelpers
+open NUnitConf
+open FSharpTestSuiteTypes
+
+
+let singleTestBuild cfg testDir =
+
+ let fileExists = Commands.fileExists testDir >> Option.isSome
+ let del = Commands.rm testDir
+
+ //if EXIST build.ok DEL /f /q build.ok
+ let buildOkPath = testDir / "build.ok"
+ do if fileExists "build.ok" then del "build.ok"
+
+ //call %~d0%~p0..\config.bat
+ ignore "param"
+
+ //if NOT "%FSC:NOTAVAIL=X%" == "%FSC%" (
+ // goto Skip
+ //)
+ ignore "already checked fsc/fsi exists"
+
+ //set source1=
+ //if exist test.ml (set source1=test.ml)
+ //if exist test.fs (set source1=test.fs)
+ let source1 =
+ ["test.ml"; "test.fs"]
+ |> List.rev
+ |> List.tryFind fileExists
+
+ //set sources=
+ //if exist testlib.fsi (set sources=%sources% testlib.fsi)
+ //if exist testlib.fs (set sources=%sources% testlib.fs)
+ //if exist test.mli (set sources=%sources% test.mli)
+ //if exist test.ml (set sources=%sources% test.ml)
+ //if exist test.fsi (set sources=%sources% test.fsi)
+ //if exist test.fs (set sources=%sources% test.fs)
+ //if exist test2.mli (set sources=%sources% test2.mli)
+ //if exist test2.ml (set sources=%sources% test2.ml)
+ //if exist test2.fsi (set sources=%sources% test2.fsi)
+ //if exist test2.fs (set sources=%sources% test2.fs)
+ //if exist test.fsx (set sources=%sources% test.fsx)
+ //if exist test2.fsx (set sources=%sources% test2.fsx)
+ let sources =
+ ["testlib.fsi";"testlib.fs";"test.mli";"test.ml";"test.fsi";"test.fs";"test2.mli";"test2.ml";"test2.fsi";"test2.fs";"test.fsx";"test2.fsx"]
+ |> List.filter fileExists
+
+ //set sourceshw=
+ //if exist test-hw.mli (set sourceshw=%sourceshw% test-hw.mli)
+ //if exist test-hw.ml (set sourceshw=%sourceshw% test-hw.ml)
+ //if exist test-hw.fsx (set sourceshw=%sourceshw% test-hw.fsx)
+ //if exist test2-hw.mli (set sourceshw=%sourceshw% test2-hw.mli)
+ //if exist test2-hw.ml (set sourceshw=%sourceshw% test2-hw.ml)
+ //if exist test2-hw.fsx (set sourceshw=%sourceshw% test2-hw.fsx)
+ let sourceshw =
+ ["test-hw.mli";"test-hw.ml";"test-hw.fsx";"test2-hw.mli";"test2-hw.ml";"test2-hw.fsx"]
+ |> List.filter fileExists
+
+ //rem to run the 64 bit version of the code set FSC_BASIC_64=FSC_BASIC_64
+ //set PERMUTATIONS_LIST=FSI_FILE FSI_STDIN FSI_STDIN_OPT FSI_STDIN_GUI FSC_BASIC %FSC_BASIC_64% FSC_HW FSC_O3 GENERATED_SIGNATURE EMPTY_SIGNATURE EMPTY_SIGNATURE_OPT FSC_OPT_MINUS_DEBUG FSC_OPT_PLUS_DEBUG FRENCH SPANISH AS_DLL WRAPPER_NAMESPACE WRAPPER_NAMESPACE_OPT
+
+ //if "%REDUCED_RUNTIME%"=="1" (
+ // echo REDUCED_RUNTIME set
+ //
+ // if not defined PERMUTATIONS (
+ // powershell.exe %PSH_FLAGS% -command "&{& '%~d0%~p0\PickPermutations.ps1' '%cd%' '%FSC%' '%PERMUTATIONS_LIST%'}" > _perm.txt
+ // if errorlevel 1 (
+ // set ERRORMSG=%ERRORMSG% PickPermutations.ps1 failed;
+ // goto :ERROR
+ // )
+ // set /p PERMUTATIONS=<_perm.txt
+ // )
+ //
+ // powershell.exe %PSH_FLAGS% -command "&{& '%~d0%~p0\DecidePEVerify.ps1' '%cd%' '%FSC%'}"
+ // if errorlevel 1 (
+ // set ERRORMSG=%ERRORMSG% DecidePEVerify.ps1 failed;
+ // goto :ERROR
+ // )
+ //)
+
+ //if not defined PERMUTATIONS (
+ // echo "PERMUTATIONS not defined. Building everything."
+ // set PERMUTATIONS=%PERMUTATIONS_LIST%
+ //)
+
+ //for %%A in (%PERMUTATIONS%) do (
+ // call :%%A
+ // IF ERRORLEVEL 1 EXIT /B 1
+ //)
+ ignore "permutations useless because build type is an input"
+
+ let exec p = Command.exec testDir cfg.EnvironmentVariables { Output = Inherit; Input = None } p >> checkResult
+
+ let echo_tofile = Commands.echo_tofile testDir
+ let copy_y f = Commands.copy_y testDir f >> checkResult
+ let type_append_tofile = Commands.type_append_tofile testDir
+ let fsc = Printf.ksprintf (fun flags -> Commands.fsc exec cfg.FSC flags)
+ let fsc_flags = cfg.fsc_flags
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let ``echo._tofile`` = Commands.``echo._tofile`` testDir
+
+ //:Ok
+ let doneOk x =
+ //echo Built fsharp %~f0 ok.
+ log "Built fsharp %s ok." testDir
+ //echo. > build.ok
+ ``echo._tofile`` " " "build.ok"
+ //endlocal
+ //exit /b 0
+ Success x
+
+ //:Skip
+ let doneSkipped msg x =
+ //echo Skipped %~f0
+ log "Skipped build '%s' reason: %s" testDir msg
+ //endlocal
+ ``echo._tofile`` " " "build.ok"
+ //exit /b 0
+ Success x
+
+ //:Error
+ let doneError err msg =
+ //echo Test Script Failed (perhaps test did not emit test.ok signal file?)
+ log "%s" msg
+ //endlocal
+ //exit /b %ERRORLEVEL%
+ Failure (err)
+
+ let genericErrorMessage = "Test Script Failed (perhaps test did not emit test.ok signal file?)"
+
+ //:SETERROR
+ //set NonexistentErrorLevel 2> nul
+ //goto Error
+
+ let skipIfExists file = processor {
+ if fileExists file
+ then return! NUnitConf.skip (sprintf "file '%s' found" file)
+ }
+
+ let skipIfNotExists file = processor {
+ if not (fileExists file)
+ then return! NUnitConf.skip (sprintf "file '%s' not found" file)
+ }
+
+ ///
+ /// if NOT EXIST dont.run.peverify (
+ /// "%PEVERIFY%" test.exe
+ /// @if ERRORLEVEL 1 goto Error
+ /// )
+ ///
+ let doPeverify cmd = processor {
+ do! skipIfExists "dont.run.peverify"
+
+ do! peverify cmd
+ }
+
+ let doNOOP () = processor {
+ //@echo No build action to take for this permutation
+ log "No build action to take for this permutation"
+ }
+
+ let doBasic () = processor {
+ // FSC %fsc_flags% --define:BASIC_TEST -o:test.exe -g %sources%
+ //if ERRORLEVEL 1 goto Error
+ do! fsc "%s --define:BASIC_TEST -o:test.exe -g" fsc_flags sources
+
+ //if NOT EXIST dont.run.peverify (
+ // "%PEVERIFY%" test.exe
+ // @if ERRORLEVEL 1 goto Error
+ //)
+ do! doPeverify "test.exe"
+ }
+
+ let doBasic64 () = processor {
+ // "%FSC%" %fsc_flags% --define:BASIC_TEST --platform:x64 -o:testX64.exe -g %sources%
+ do! fsc "%s --define:BASIC_TEST --platform:x64 -o:testX64.exe -g" fsc_flags sources
+
+ // if NOT EXIST dont.run.peverify (
+ // "%PEVERIFY%" testX64.exe
+ // )
+ do! doPeverify "testX64.exe"
+ }
+
+ let doFscHW () = processor {
+ // if exist test-hw.* (
+ if Directory.EnumerateFiles(testDir, "test-hw.*") |> Seq.exists fileExists then
+ // "%FSC%" %fsc_flags% -o:test-hw.exe -g %sourceshw%
+ do! fsc "%s -o:test-hw.exe -g" fsc_flags sourceshw
+
+ // if NOT EXIST dont.run.peverify (
+ // "%PEVERIFY%" test-hw.exe
+ // )
+ do! doPeverify "test-hw.exe"
+ //)
+ else
+ do! NUnitConf.skip (sprintf "file '%s' not found" "test-hw.*")
+ }
+
+ let doFscO3 () = processor {
+ //"%FSC%" %fsc_flags% --optimize --define:PERF -o:test--optimize.exe -g %sources%
+ do! fsc "%s --optimize --define:PERF -o:test--optimize.exe -g" fsc_flags sources
+ //if NOT EXIST dont.run.peverify (
+ // "%PEVERIFY%" test--optimize.exe
+ //)
+ do! doPeverify "test--optimize.exe"
+ }
+
+ let doGeneratedSignature () = processor {
+ //if NOT EXIST dont.use.generated.signature (
+ do! skipIfExists "dont.use.generated.signature"
+
+ // if exist test.ml (
+ do! skipIfNotExists "test.ml"
+
+ // echo Generating interface file...
+ log "Generating interface file..."
+ // copy /y %source1% tmptest.ml
+ do! source1 |> Option.map (fun from -> copy_y from "tmptest.ml")
+ // REM NOTE: use --generate-interface-file since results may be in Unicode
+ // "%FSC%" %fsc_flags% --sig:tmptest.mli tmptest.ml
+ do! fsc "%s --sig:tmptest.mli" fsc_flags ["tmptest.ml"]
+
+ // echo Compiling against generated interface file...
+ log "Compiling against generated interface file..."
+ // "%FSC%" %fsc_flags% -o:tmptest1.exe tmptest.mli tmptest.ml
+ do! fsc "%s -o:tmptest1.exe" fsc_flags ["tmptest.mli";"tmptest.ml"]
+
+ // if NOT EXIST dont.run.peverify (
+ // "%PEVERIFY%" tmptest1.exe
+ // )
+ do! doPeverify "tmptest1.exe"
+ }
+
+ let doEmptySignature () = processor {
+ //if NOT EXIST dont.use.empty.signature (
+ do! skipIfExists "dont.use.empty.signature"
+
+ // if exist test.ml (
+ do! skipIfNotExists "test.ml"
+
+ // echo Compiling against empty interface file...
+ log "Compiling against empty interface file..."
+ // echo // empty file > tmptest2.mli
+ echo_tofile "// empty file " "tmptest2.mli"
+ // copy /y %source1% tmptest2.ml
+ do! source1 |> Option.map (fun from -> copy_y from "tmptest2.ml")
+ // "%FSC%" %fsc_flags% --define:COMPILING_WITH_EMPTY_SIGNATURE -o:tmptest2.exe tmptest2.mli tmptest2.ml
+ do! fsc "%s --define:COMPILING_WITH_EMPTY_SIGNATURE -o:tmptest2.exe" fsc_flags ["tmptest2.mli";"tmptest2.ml"]
+
+ // if NOT EXIST dont.run.peverify (
+ // "%PEVERIFY%" tmptest2.exe
+ // )
+ do! doPeverify "tmptest2.exe"
+ }
+
+
+ let doEmptySignatureOpt () = processor {
+ //if NOT EXIST dont.use.empty.signature (
+ do! skipIfExists "dont.use.empty.signature"
+
+ // if exist test.ml (
+ do! skipIfNotExists "test.ml"
+
+ // echo Compiling against empty interface file...
+ log "Compiling against empty interface file..."
+ // echo // empty file > tmptest2.mli
+ echo_tofile "// empty file " "tmptest2.mli"
+ // copy /y %source1% tmptest2.ml
+ do! source1 |> Option.map (fun from -> copy_y from "tmptest2.ml")
+ // "%FSC%" %fsc_flags% --define:COMPILING_WITH_EMPTY_SIGNATURE --optimize -o:tmptest2--optimize.exe tmptest2.mli tmptest2.ml
+ do! fsc "%s --define:COMPILING_WITH_EMPTY_SIGNATURE --optimize -o:tmptest2--optimize.exe" fsc_flags ["tmptest2.mli";"tmptest2.ml"]
+
+ // if NOT EXIST dont.run.peverify (
+ // "%PEVERIFY%" tmptest2--optimize.exe
+ // )
+ do! doPeverify "tmptest2--optimize.exe"
+ }
+
+ let doOptFscMinusDebug () = processor {
+ // "%FSC%" %fsc_flags% --optimize- --debug -o:test--optminus--debug.exe -g %sources%
+ do! fsc "%s --optimize- --debug -o:test--optminus--debug.exe -g" fsc_flags sources
+
+ // if NOT EXIST dont.run.peverify (
+ // "%PEVERIFY%" test--optminus--debug.exe
+ // )
+ do! doPeverify "test--optminus--debug.exe"
+ }
+
+ let doOptFscPlusDebug () = processor {
+ // "%FSC%" %fsc_flags% --optimize+ --debug -o:test--optplus--debug.exe -g %sources%
+ do! fsc "%s --optimize+ --debug -o:test--optplus--debug.exe -g" fsc_flags sources
+
+ // if NOT EXIST dont.run.peverify (
+ // "%PEVERIFY%" test--optplus--debug.exe
+ // )
+ do! doPeverify "test--optplus--debug.exe"
+ }
+
+ let doAsDLL () = processor {
+ //REM Compile as a DLL to exercise pickling of interface data, then recompile the original source file referencing this DLL
+ //REM THe second compilation will not utilize the information from the first in any meaningful way, but the
+ //REM compiler will unpickle the interface and optimization data, so we test unpickling as well.
+
+ //if NOT EXIST dont.compile.test.as.dll (
+ do! skipIfExists "dont.compile.test.as.dll"
+
+ // "%FSC%" %fsc_flags% --optimize -a -o:test--optimize-lib.dll -g %sources%
+ do! fsc "%s --optimize -a -o:test--optimize-lib.dll -g" fsc_flags sources
+
+ // "%FSC%" %fsc_flags% --optimize -r:test--optimize-lib.dll -o:test--optimize-client-of-lib.exe -g %sources%
+ do! fsc "%s --optimize -r:test--optimize-lib.dll -o:test--optimize-client-of-lib.exe -g" fsc_flags sources
+
+ // if NOT EXIST dont.run.peverify (
+ // "%PEVERIFY%" test--optimize-lib.dll
+ // )
+ do! doPeverify "test--optimize-lib.dll"
+
+ // if NOT EXIST dont.run.peverify (
+ // "%PEVERIFY%" test--optimize-client-of-lib.exe
+ // )
+ do! doPeverify "test--optimize-client-of-lib.exe"
+ }
+
+ let doWrapperNamespace () = processor {
+ // if NOT EXIST dont.use.wrapper.namespace (
+ do! skipIfExists "dont.use.wrapper.namespace"
+
+ // if exist test.ml (
+ do! skipIfNotExists "test.ml"
+
+ // echo Compiling when wrapped in a namespace declaration...
+ log "Compiling when wrapped in a namespace declaration..."
+ // echo module TestNamespace.TestModule > tmptest3.ml
+ echo_tofile "module TestNamespace.TestModule " "tmptest3.ml"
+ // type %source1% >> tmptest3.ml
+ source1 |> Option.iter (fun from -> type_append_tofile from "tmptest3.ml")
+ // "%FSC%" %fsc_flags% -o:tmptest3.exe tmptest3.ml
+ do! fsc "%s -o:tmptest3.exe" fsc_flags ["tmptest3.ml"]
+
+ // if NOT EXIST dont.run.peverify (
+ // "%PEVERIFY%" tmptest3.exe
+ // )
+ do! doPeverify "tmptest3.exe"
+ }
+
+ let doWrapperNamespaceOpt () = processor {
+ //if NOT EXIST dont.use.wrapper.namespace (
+ do! skipIfExists "dont.use.wrapper.namespace"
+
+ // if exist test.ml (
+ do! skipIfNotExists "test.ml"
+
+ // echo Compiling when wrapped in a namespace declaration...
+ log "Compiling when wrapped in a namespace declaration..."
+ // echo module TestNamespace.TestModule > tmptest3.ml
+ echo_tofile "module TestNamespace.TestModule " "tmptest3.ml"
+ // type %source1% >> tmptest3.ml
+ source1 |> Option.iter (fun from -> type_append_tofile from "tmptest3.ml")
+ // "%FSC%" %fsc_flags% --optimize -o:tmptest3--optimize.exe tmptest3.ml
+ do! fsc "%s --optimize -o:tmptest3--optimize.exe" fsc_flags ["tmptest3.ml"]
+
+ // if NOT EXIST dont.run.peverify (
+ // "%PEVERIFY%" tmptest3--optimize.exe
+ // )
+ do! doPeverify "tmptest3--optimize.exe"
+ }
+
+ let build = function
+ | FSI_FILE -> doNOOP
+ | FSI_STDIN -> doNOOP
+ | FSI_STDIN_OPT -> doNOOP
+ | FSI_STDIN_GUI -> doNOOP
+ | FRENCH -> doBasic
+ | SPANISH -> doBasic
+ | FSC_BASIC -> doBasic
+ | FSC_BASIC_64 -> doBasic64
+ | FSC_HW -> doFscHW
+ | FSC_O3 -> doFscO3
+ | GENERATED_SIGNATURE -> doGeneratedSignature
+ | EMPTY_SIGNATURE -> doEmptySignature
+ | EMPTY_SIGNATURE_OPT -> doEmptySignatureOpt
+ | FSC_OPT_MINUS_DEBUG -> doOptFscMinusDebug
+ | FSC_OPT_PLUS_DEBUG -> doOptFscPlusDebug
+ | AS_DLL -> doAsDLL
+ | WRAPPER_NAMESPACE -> doWrapperNamespace
+ | WRAPPER_NAMESPACE_OPT -> doWrapperNamespaceOpt
+
+ let flow p () =
+ build p ()
+ |> Attempt.Run
+ |> function
+ | Success () -> doneOk ()
+ | Failure (Skipped msg) -> doneSkipped msg ()
+ | Failure (GenericError msg) -> doneError (GenericError msg) msg
+ | Failure (ProcessExecError (err,msg)) -> doneError (ProcessExecError(err,msg)) msg
+
+ flow
diff --git a/tests/fsharp/single-test-run.fs b/tests/fsharp/single-test-run.fs
new file mode 100644
index 00000000000..4ef0801f425
--- /dev/null
+++ b/tests/fsharp/single-test-run.fs
@@ -0,0 +1,527 @@
+module SingleTestRun
+
+open System
+open System.IO
+open NUnit.Framework
+
+open PlatformHelpers
+open NUnitConf
+open FSharpTestSuiteTypes
+
+let private singleTestRun' cfg testDir =
+
+ let getfullpath = Commands.getfullpath testDir
+ let fileExists = Commands.fileExists testDir >> Option.isSome
+
+ // set sources=
+ // if exist testlib.fsi (set sources=%sources% testlib.fsi)
+ // if exist testlib.fs (set sources=%sources% testlib.fs)
+ // if exist test.mli (set sources=%sources% test.mli)
+ // if exist test.ml (set sources=%sources% test.ml)
+ // if exist test.fsi (set sources=%sources% test.fsi)
+ // if exist test.fs (set sources=%sources% test.fs)
+ // if exist test2.mli (set sources=%sources% test2.mli)
+ // if exist test2.ml (set sources=%sources% test2.ml)
+ // if exist test2.fsi (set sources=%sources% test2.fsi)
+ // if exist test2.fs (set sources=%sources% test2.fs)
+ // if exist test.fsx (set sources=%sources% test.fsx)
+ // if exist test2.fsx (set sources=%sources% test2.fsx)
+ let sources =
+ ["testlib.fsi";"testlib.fs";"test.mli";"test.ml";"test.fsi";"test.fs";"test2.mli";"test2.ml";"test2.fsi";"test2.fs";"test.fsx";"test2.fsx"]
+ |> List.filter fileExists
+
+ // set sourceshw=
+ // if exist test-hw.mli (set sourceshw=%sourceshw% test-hw.mli)
+ // if exist test-hw.ml (set sourceshw=%sourceshw% test-hw.ml)
+ // if exist test2-hw.mli (set sourceshw=%sourceshw% test2-hw.mli)
+ // if exist test2-hw.ml (set sourceshw=%sourceshw% test2-hw.ml)
+ // if exist test-hw.fsi (set sourceshw=%sourceshw% test-hw.fsi)
+ // if exist test-hw.fs (set sourceshw=%sourceshw% test-hw.fs)
+ // if exist test2-hw.fsi (set sourceshw=%sourceshw% test2-hw.fsi)
+ // if exist test2-hw.fs (set sourceshw=%sourceshw% test2-hw.fs)
+ // if exist test-hw.fsx (set sourceshw=%sourceshw% test-hw.fsx)
+ // if exist test2-hw.fsx (set sourceshw=%sourceshw% test2-hw.fsx)
+ let sourceshw =
+ ["test-hw.mli";"test-hw.ml";"test2-hw.mli";"test2-hw.ml";"test-hw.fsi";"test-hw.fs";"test2-hw.fsi";"test2-hw.fs";"test-hw.fsx";"test2-hw.fsx"]
+ |> List.filter fileExists
+
+ // :START
+
+ // set PERMUTATIONS_LIST=FSI_FILE FSI_STDIN FSI_STDIN_OPT FSI_STDIN_GUI FSC_BASIC %FSC_BASIC_64% FSC_HW FSC_O3 GENERATED_SIGNATURE EMPTY_SIGNATURE EMPTY_SIGNATURE_OPT FSC_OPT_MINUS_DEBUG FSC_OPT_PLUS_DEBUG FRENCH SPANISH AS_DLL WRAPPER_NAMESPACE WRAPPER_NAMESPACE_OPT
+ //
+ // if "%REDUCED_RUNTIME%"=="1" (
+ // echo REDUCED_RUNTIME set
+ //
+ // if not defined PERMUTATIONS (
+ // powershell.exe %PSH_FLAGS% -command "&{& '%~d0%~p0\PickPermutations.ps1' '%cd%' '%FSC%' '%PERMUTATIONS_LIST%'}" > _perm.txt
+ // if errorlevel 1 (
+ // set ERRORMSG=%ERRORMSG% PickPermutations.ps1 failed;
+ // goto :ERROR
+ // )
+ // set /p PERMUTATIONS=<_perm.txt
+ // )
+ // )
+ ignore "test is parametrized"
+
+ // if not defined PERMUTATIONS (
+ // echo "PERMUTATIONS not defined. Running everything."
+ // set PERMUTATIONS=%PERMUTATIONS_LIST%
+ // )
+ ignore "test is parametrized"
+
+ // for %%A in (%PERMUTATIONS%) do (
+ // call :%%A
+ // IF ERRORLEVEL 1 EXIT /B 1
+ // )
+ ignore "test is parametrized"
+
+ // if "%ERRORMSG%"=="" goto Ok
+
+ // set NonexistentErrorLevel 2> nul
+ // goto :ERROR
+
+ // :END
+
+ // :EXIT_PATHS
+
+ // REM =========================================
+ // REM THE TESTS
+ // REM =========================================
+
+ let exec p = Command.exec testDir cfg.EnvironmentVariables { Output = Inherit; Input = None } p >> checkResult
+
+ let fsi = Printf.ksprintf (fun flags l -> Commands.fsi exec cfg.FSI flags l)
+ let ``exec <`` l p = Command.exec testDir cfg.EnvironmentVariables { Output = Inherit; Input = Some(RedirectInput(l)) } p >> checkResult
+ let ``fsi <`` = Printf.ksprintf (fun flags l -> Commands.fsi (``exec <`` l) cfg.FSI flags [])
+
+ let fsi_flags = cfg.fsi_flags
+
+ let createTestOkFile () = NUnitConf.FileGuard.create (getfullpath "test.ok")
+
+ let skipIfExists file = processor {
+ if fileExists file
+ then return! NUnitConf.skip (sprintf "file '%s' found" file)
+ }
+
+ let skipIfNotExists file = processor {
+ if not (fileExists file)
+ then return! NUnitConf.skip (sprintf "file '%s' not found" file)
+ }
+
+
+ // :FSI_STDIN
+ // @echo do :FSI_STDIN
+ let runFSI_STDIN () = processor {
+ // if NOT EXIST dont.pipe.to.stdin (
+ do! skipIfExists "dont.pipe.to.stdin"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% "%FSI%" %fsi_flags% < %sources% && (
+ do! ``fsi <`` "%s" fsi_flags (sources |> List.rev |> List.head) //use last file, because `cmd < a.txt b.txt` redirect b.txt only
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo FSI_STDIN failed;
+ // set ERRORMSG=%ERRORMSG% FSI_STDIN failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ // )
+ }
+
+ // :FSI_STDIN_OPT
+ // @echo do :FSI_STDIN_OPT
+ let runFSI_STDIN_OPT () = processor {
+ // if NOT EXIST dont.pipe.to.stdin (
+ do! skipIfExists "dont.pipe.to.stdin"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% "%FSI%" %fsi_flags% --optimize < %sources% && (
+ do! ``fsi <`` "%s --optimize" fsi_flags (sources |> List.rev |> List.head) //use last file, because `cmd < a.txt b.txt` redirect b.txt only
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo FSI_STDIN_OPT failed
+ // set ERRORMSG=%ERRORMSG% FSI_STDIN_OPT failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ // )
+ }
+
+ // :FSI_STDIN_GUI
+ // @echo do :FSI_STDIN_GUI
+ let runFSI_STDIN_GUI () = processor {
+ // if NOT EXIST dont.pipe.to.stdin (
+ do! skipIfExists "dont.pipe.to.stdin"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% "%FSI%" %fsi_flags% --gui < %sources% && (
+ do! ``fsi <`` "%s --gui" fsi_flags (sources |> List.rev |> List.head) //use last file, because `cmd < a.txt b.txt` redirect b.txt only
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo FSI_STDIN_GUI failed;
+ // set ERRORMSG=%ERRORMSG% FSI_STDIN_GUI failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ // )
+ }
+
+ // :FSI_FILE
+ // @echo do :FSI_FILE
+ let runFSI_FILE () = processor {
+ // if NOT EXIST dont.run.as.script (
+ do! skipIfExists "dont.run.as.script"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% "%FSI%" %fsi_flags% %sources% && (
+ do! fsi "%s" fsi_flags sources
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo FSI_FILE failed
+ // set ERRORMSG=%ERRORMSG% FSI_FILE failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ // )
+ }
+
+ // :FSC_BASIC
+ // @echo do :FSC_BASIC
+ let runFSC_BASIC () = processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% .\test.exe && (
+ do! exec ("."/"test.exe") ""
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo :FSC_BASIC failed
+ // set ERRORMSG=%ERRORMSG% FSC_BASIC failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ // :FSC_BASIC_64
+ // @echo do :FSC_BASIC_64
+ let runFSC_BASIC_64 () = processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% .\testX64.exe && (
+ do! exec ("."/"testX64.exe") ""
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo :FSC_BASIC_64 failed
+ // set ERRORMSG=%ERRORMSG% FSC_BASIC_64 failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ // :FSC_HW
+ // @echo do :FSC_HW
+ let runFSC_HW () = processor {
+ // if exist test-hw.* (
+ if Directory.EnumerateFiles(testDir, "test-hw.*") |> Seq.exists fileExists then
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% .\test-hw.exe && (
+ do! exec ("."/"test-hw.exe") ""
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo :FSC_HW failed
+ // set ERRORMSG=%ERRORMSG% FSC_HW failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ //)
+ else
+ do! NUnitConf.skip (sprintf "file '%s' not found" "test-hw.*")
+ }
+
+ // :FSC_O3
+ // @echo do :FSC_O3
+ let runFSC_O3 () = processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% .\test--optimize.exe && (
+ do! exec ("."/"test--optimize.exe") ""
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo :FSC_O3 failed
+ // set ERRORMSG=%ERRORMSG% FSC_03 failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ // :FSC_OPT_MINUS_DEBUG
+ // @echo do :FSC_OPT_MINUS_DEBUG
+ let runFSC_OPT_MINUS_DEBUG () = processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% .\test--optminus--debug.exe && (
+ do! exec ("."/"test--optminus--debug.exe") ""
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo :FSC_OPT_MINUS_DEBUG failed
+ // set ERRORMSG=%ERRORMSG% FSC_OPT_MINUS_DEBUG failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ // :FSC_OPT_PLUS_DEBUG
+ // @echo do :FSC_OPT_PLUS_DEBUG
+ let runFSC_OPT_PLUS_DEBUG () = processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% .\test--optplus--debug.exe && (
+ do! exec ("."/"test--optplus--debug.exe") ""
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo :FSC_OPT_PLUS_DEBUG failed
+ // set ERRORMSG=%ERRORMSG% FSC_OPT_PLUS_DEBUG failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ // :GENERATED_SIGNATURE
+ // @echo do :GENERATED_SIGNATURE
+ let runGENERATED_SIGNATURE () = processor {
+ // if NOT EXIST dont.use.generated.signature (
+ do! skipIfExists "dont.use.generated.signature"
+
+ // if exist test.ml (
+ do! skipIfNotExists "test.ml"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% tmptest1.exe && (
+ do! exec ("."/"tmptest1.exe") ""
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo :GENERATED_SIGNATURE failed
+ // set ERRORMSG=%ERRORMSG% FSC_GENERATED_SIGNATURE failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ // )
+ //)
+ }
+
+ // :EMPTY_SIGNATURE
+ // @echo do :EMPTY_SIGNATURE
+ let runEMPTY_SIGNATURE () = processor {
+ // if NOT EXIST dont.use.empty.signature (
+ do! skipIfExists "dont.use.empty.signature"
+
+ // if exist test.ml (
+ do! skipIfNotExists "test.ml"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% tmptest2.exe && (
+ do! exec ("."/"tmptest2.exe") ""
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo :EMPTY_SIGNATURE failed
+ // set ERRORMSG=%ERRORMSG% FSC_EMPTY_SIGNATURE failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ // )
+ //)
+ }
+
+ // :EMPTY_SIGNATURE_OPT
+ // @echo do :EMPTY_SIGNATURE_OPT
+ let runEMPTY_SIGNATURE_OPT () = processor {
+ // if NOT EXIST dont.use.empty.signature (
+ do! skipIfExists "dont.use.empty.signature"
+
+ // if exist test.ml (
+ do! skipIfNotExists "test.ml"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% tmptest2--optimize.exe && (
+ do! exec ("."/"tmptest2--optimize.exe") ""
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo :EMPTY_SIGNATURE_OPT --optimize failed
+ // set ERRORMSG=%ERRORMSG% EMPTY_SIGNATURE_OPT --optimize failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ // )
+ //)
+ }
+
+ // :FRENCH
+ // @echo do :FRENCH
+ let runFRENCH () = processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% .\test.exe fr-FR && (
+ do! exec ("."/"test.exe") "fr-FR"
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo :FRENCH failed
+ // set ERRORMSG=%ERRORMSG% FRENCH failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ // :SPANISH
+ // @echo do :SPANISH
+ let runSPANISH () = processor {
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% .\test.exe es-ES && (
+ do! exec ("."/"test.exe") "es-ES"
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo :SPANISH failed
+ // set ERRORMSG=%ERRORMSG% SPANISH failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ }
+
+ // :AS_DLL
+ // @echo do :AS_DLL
+ let runAS_DLL () = processor {
+ //if NOT EXIST dont.compile.test.as.dll (
+ do! skipIfExists "dont.compile.test.as.dll"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% .\test--optimize-client-of-lib.exe && (
+ do! exec ("."/"test--optimize-client-of-lib.exe") ""
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo :AS_DLL failed
+ // set ERRORMSG=%ERRORMSG% AS_DLL failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ //)
+ }
+
+ // :WRAPPER_NAMESPACE
+ // @echo do :WRAPPER_NAMESPACE
+ let runWRAPPER_NAMESPACE () = processor {
+ // if NOT EXIST dont.use.wrapper.namespace (
+ do! skipIfExists "dont.use.wrapper.namespace"
+
+ // if exist test.ml (
+ do! skipIfNotExists "test.ml"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% .\tmptest3.exe && (
+ do! exec ("."/"tmptest3.exe") ""
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo :WRAPPER_NAMESPACE failed
+ // set ERRORMSG=%ERRORMSG% WRAPPER_NAMESPACE failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ // )
+ //)
+ }
+
+ // :WRAPPER_NAMESPACE_OPT
+ // @echo do :WRAPPER_NAMESPACE_OPT
+ let runWRAPPER_NAMESPACE_OPT () = processor {
+ // if NOT EXIST dont.use.wrapper.namespace (
+ do! skipIfExists "dont.use.wrapper.namespace"
+
+ // if exist test.ml (
+ do! skipIfNotExists "test.ml"
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = createTestOkFile ()
+ // %CLIX% .\tmptest3--optimize.exe && (
+ do! exec ("."/"tmptest3--optimize.exe") ""
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo :WRAPPER_NAMESPACE_OPT failed
+ // set ERRORMSG=%ERRORMSG% WRAPPER_NAMESPACE_OPT failed;
+ // )
+ do! testOkFile |> NUnitConf.checkGuardExists
+ // )
+ // )
+ }
+
+ let run = function
+ | FSI_FILE -> runFSI_FILE
+ | FSI_STDIN -> runFSI_STDIN
+ | FSI_STDIN_OPT -> runFSI_STDIN_OPT
+ | FSI_STDIN_GUI -> runFSI_STDIN_GUI
+ | FRENCH -> runFRENCH
+ | SPANISH -> runSPANISH
+ | FSC_BASIC -> runFSC_BASIC
+ | FSC_BASIC_64 -> runFSC_BASIC_64
+ | FSC_HW -> runFSC_HW
+ | FSC_O3 -> runFSC_O3
+ | GENERATED_SIGNATURE -> runGENERATED_SIGNATURE
+ | EMPTY_SIGNATURE -> runEMPTY_SIGNATURE
+ | EMPTY_SIGNATURE_OPT -> runEMPTY_SIGNATURE_OPT
+ | FSC_OPT_MINUS_DEBUG -> runFSC_OPT_MINUS_DEBUG
+ | FSC_OPT_PLUS_DEBUG -> runFSC_OPT_PLUS_DEBUG
+ | AS_DLL -> runAS_DLL
+ | WRAPPER_NAMESPACE -> runWRAPPER_NAMESPACE
+ | WRAPPER_NAMESPACE_OPT -> runWRAPPER_NAMESPACE_OPT
+
+ run
+
+let singleTestRun config testDir =
+ let fileExists = Commands.fileExists testDir >> Option.isSome
+
+ //@if "%_echo%"=="" echo off
+ //setlocal
+ ignore "unused"
+
+ //set ERRORMSG=
+ ignore "unused"
+
+ //:Ok
+ let doneOK x =
+ //echo Ran fsharp %~f0 ok.
+ log "Ran fsharp %s ok." testDir
+ //exit /b 0
+ Success x
+
+ //:Skip
+ let doneSkipped msg =
+ //echo Skipped %~f0
+ log "Skipped run '%s' reason: %s" testDir msg
+ //exit /b 0
+ Failure (Skipped msg)
+
+ //:Error
+ let doneError err msg =
+ //echo %ERRORMSG%
+ log "%s" msg
+ //exit /b %ERRORLEVEL%
+ Failure (err)
+
+ let skipIfNotExists file = processor {
+ if not (fileExists file)
+ then return! NUnitConf.skip (sprintf "file '%s' not found" file)
+ }
+
+ let tests config p = processor {
+ //dir build.ok > NUL ) || (
+ // @echo 'build.ok' not found.
+ // set ERRORMSG=%ERRORMSG% Skipped because 'build.ok' not found.
+ // goto :ERROR
+ //)
+ do! skipIfNotExists "build.ok"
+
+ // call %~d0%~p0..\config.bat
+ let cfg = config
+ // if errorlevel 1 (
+ // set ERRORMSG=%ERRORMSG% config.bat failed;
+ // goto :ERROR
+ // )
+
+ // if not exist "%FSC%" (
+ // set ERRORMSG=%ERRORMSG% fsc.exe not found at the location "%FSC%"
+ // goto :ERROR
+ // )
+ ignore "already checked at test suite startup"
+
+ // if not exist "%FSI%" (
+ // set ERRORMSG=%ERRORMSG% fsi.exe not found at the location "%FSI%"
+ // goto :ERROR
+ // )
+ ignore "already checked at test suite startup"
+
+ do! singleTestRun' cfg testDir p ()
+ }
+
+ let flow p () =
+ tests config p
+ |> Attempt.Run
+ |> function
+ | Success () -> doneOK ()
+ | Failure (Skipped msg) -> doneSkipped msg
+ | Failure (GenericError msg) -> doneError (GenericError msg) msg
+ | Failure (ProcessExecError (err,msg)) -> doneError (ProcessExecError(err,msg)) msg
+
+
+ flow
diff --git a/tests/fsharp/tools/tests_tools.fs b/tests/fsharp/tools/tests_tools.fs
new file mode 100644
index 00000000000..8d6f183c9c0
--- /dev/null
+++ b/tests/fsharp/tools/tests_tools.fs
@@ -0,0 +1,62 @@
+module ``FSharp-Tests-Tools``
+
+open System
+open System.IO
+open NUnit.Framework
+
+open FSharpTestSuiteTypes
+open NUnitConf
+open PlatformHelpers
+
+let testContext = FSharpTestSuite.testContext
+
+
+module Bundle =
+
+ []
+ let bundle () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+
+ // "%FSC%" %fsc_flags% --progress --standalone -o:test-one-fsharp-module.exe -g test-one-fsharp-module.fs
+ do! fsc "%s --progress --standalone -o:test-one-fsharp-module.exe -g" cfg.fsc_flags ["test-one-fsharp-module.fs"]
+
+ // "%PEVERIFY%" test-one-fsharp-module.exe
+ do! peverify "test-one-fsharp-module.exe"
+
+ // "%FSC%" %fsc_flags% -a -o:test_two_fsharp_modules_module_1.dll -g test_two_fsharp_modules_module_1.fs
+ do! fsc "%s -a -o:test_two_fsharp_modules_module_1.dll -g" cfg.fsc_flags ["test_two_fsharp_modules_module_1.fs"]
+
+ // "%PEVERIFY%" test_two_fsharp_modules_module_1.dll
+ do! peverify "test_two_fsharp_modules_module_1.dll"
+
+
+ // "%FSC%" %fsc_flags% --standalone -r:test_two_fsharp_modules_module_1.dll -o:test_two_fsharp_modules_module_2.exe -g test_two_fsharp_modules_module_2.fs
+ do! fsc "%s --standalone -r:test_two_fsharp_modules_module_1.dll -o:test_two_fsharp_modules_module_2.exe -g" cfg.fsc_flags ["test_two_fsharp_modules_module_2.fs"]
+
+ // "%PEVERIFY%" test_two_fsharp_modules_module_2.exe
+ do! peverify "test_two_fsharp_modules_module_2.exe"
+
+ // "%FSC%" %fsc_flags% -a --standalone -r:test_two_fsharp_modules_module_1.dll -o:test_two_fsharp_modules_module_2_as_dll.dll -g test_two_fsharp_modules_module_2.fs
+ do! fsc "%s -a --standalone -r:test_two_fsharp_modules_module_1.dll -o:test_two_fsharp_modules_module_2_as_dll.dll -g" cfg.fsc_flags ["test_two_fsharp_modules_module_2.fs"]
+
+ // "%PEVERIFY%" test_two_fsharp_modules_module_2_as_dll.dll
+ do! peverify "test_two_fsharp_modules_module_2_as_dll.dll"
+
+ })
+
+
+
+module Eval =
+
+ []
+ let eval p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
diff --git a/tests/fsharp/typeProviders/build-typeprovider-test.fs b/tests/fsharp/typeProviders/build-typeprovider-test.fs
new file mode 100644
index 00000000000..dc38e806cc4
--- /dev/null
+++ b/tests/fsharp/typeProviders/build-typeprovider-test.fs
@@ -0,0 +1,43 @@
+module BuildTypeProviderTest
+
+open System
+open System.IO
+open NUnit.Framework
+
+open FSharpTestSuiteTypes
+open PlatformHelpers
+open NUnitConf
+
+let build (cfg: TestConfig) (dir: string) p = processor {
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let del = Commands.rm dir
+
+ // if EXIST provided.dll del provided.dll
+ del "provided.dll"
+
+ // "%FSC%" --out:provided.dll -a ..\helloWorld\provided.fs
+ do! fsc "--out:provided.dll -a" [".."/"helloWorld"/"provided.fs"]
+
+ // if EXIST providedJ.dll del providedJ.dll
+ del "providedJ.dll"
+
+ // "%FSC%" --out:providedJ.dll -a ..\helloWorld\providedJ.fs
+ do! fsc "--out:providedJ.dll -a" [".."/"helloWorld"/"providedJ.fs"]
+
+ // if EXIST providedK.dll del providedK.dll
+ del "providedK.dll"
+
+ // "%FSC%" --out:providedK.dll -a ..\helloWorld\providedK.fs
+ do! fsc "--out:providedK.dll -a" [".."/"helloWorld"/"providedK.fs"]
+
+ // if EXIST provider.dll del provider.dll
+ del "provider.dll"
+
+ // "%FSC%" --out:provider.dll -a provider.fsx
+ do! fsc "--out:provider.dll -a" ["provider.fsx"]
+
+ // call %~d0%~p0..\single-test-build.bat
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ }
diff --git a/tests/fsharp/typeProviders/builtin/copyFSharpDataTypeProviderDLL.fs b/tests/fsharp/typeProviders/builtin/copyFSharpDataTypeProviderDLL.fs
new file mode 100644
index 00000000000..960fc915a5a
--- /dev/null
+++ b/tests/fsharp/typeProviders/builtin/copyFSharpDataTypeProviderDLL.fs
@@ -0,0 +1,71 @@
+module CopyFSharpDataTypeProviderDLL
+
+open System
+open System.IO
+open NUnit.Framework
+
+open FSharpTestSuiteTypes
+open PlatformHelpers
+open NUnitConf
+
+let copy (cfg: TestConfig) (dir: string) = processor {
+ let fileExists = Commands.fileExists dir >> Option.isSome
+ let getfullpath = Commands.getfullpath dir
+
+ let copy_y a = Commands.copy_y dir a >> checkResult
+
+ // REM == Find out OS architecture, no matter what cmd prompt
+ // SET OSARCH=%PROCESSOR_ARCHITECTURE%
+ // IF NOT "%PROCESSOR_ARCHITEW6432%"=="" SET OSARCH=%PROCESSOR_ARCHITEW6432%
+ let osArch = WindowsPlatform.osArch cfg.EnvironmentVariables
+
+ // REM == Find out path to native 'Program Files 32bit', no matter what
+ // REM == architecture we are running on and no matter what command
+ // REM == prompt we came from.
+ // IF /I "%OSARCH%"=="x86" set X86_PROGRAMFILES=%ProgramFiles%
+ // IF /I "%OSARCH%"=="AMD64" set X86_PROGRAMFILES=%ProgramFiles(x86)%
+ let x86ProgramFiles = WindowsPlatform.x86ProgramFilesDirectory cfg.EnvironmentVariables osArch
+
+ // REM == Set path to FSharp.Data.TypeProviders.dll
+ // REM == This binary is frozen at 4.3.0.0 version
+ // set FSDATATYPEPROVIDERSPATH=%X86_PROGRAMFILES%\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\4.3.0.0\Type Providers\FSharp.Data.TypeProviders.dll
+ // IF EXIST "%FSCBinPath%\FSharp.Data.TypeProviders.dll" set FSDATATYPEPROVIDERSPATH=%FSCBinPath%\FSharp.Data.TypeProviders.dll
+ let FSDATATYPEPROVIDERSPATH =
+ if fileExists (cfg.FSCBinPath/"FSharp.Data.TypeProviders.dll")
+ then cfg.FSCBinPath/"FSharp.Data.TypeProviders.dll"
+ else x86ProgramFiles/"Reference Assemblies"/"Microsoft"/"FSharp"/".NETFramework"/"v4.0"/"4.3.0.0"/"Type Providers"/"FSharp.Data.TypeProviders.dll"
+
+
+ // REM == Copy the FSharp.Data.TypeProvider.dll
+ // REM == Note: we need this because we are doing white box testing
+ // IF EXIST "%FSDATATYPEPROVIDERSPATH%" copy /y "%FSDATATYPEPROVIDERSPATH%" .
+ do! if fileExists FSDATATYPEPROVIDERSPATH
+ then copy_y FSDATATYPEPROVIDERSPATH ("."/"FSharp.Data.TypeProviders.dll")
+ else Success ()
+
+ // REM == Copy in config files with needed binding redirects
+ let xcopy_ry a b =
+ let removeReadonly p =
+ let attr = File.GetAttributes(p)
+ File.SetAttributes(p, attr &&& (~~~ FileAttributes.ReadOnly))
+
+ if fileExists b then removeReadonly (getfullpath b)
+ copy_y a b
+
+ let ``test.exe.config`` = __SOURCE_DIRECTORY__/"test.exe.config"
+ // xcopy /RY "%~dp0test.exe.config" "%cd%\test.exe.config*"
+ do! xcopy_ry ``test.exe.config`` "test.exe.config"
+ // xcopy /RY "%~dp0test.exe.config" "%cd%\testX64.exe.config*"
+ do! xcopy_ry ``test.exe.config`` "testX64.exe.config"
+ // xcopy /RY "%~dp0test.exe.config" "%cd%\test--optimize.exe.config*"
+ do! xcopy_ry ``test.exe.config`` "test--optimize.exe.config"
+ // xcopy /RY "%~dp0test.exe.config" "%cd%\test--optimize-lib.dll.config*"
+ do! xcopy_ry ``test.exe.config`` "test--optimize-lib.dll.config"
+ // xcopy /RY "%~dp0test.exe.config" "%cd%\test--optimize-client-of-lib.exe.config*"
+ do! xcopy_ry ``test.exe.config`` "test--optimize-client-of-lib.exe.config"
+ // xcopy /RY "%~dp0test.exe.config" "%cd%\test--optminus--debug.exe.config*"
+ do! xcopy_ry ``test.exe.config`` "test--optminus--debug.exe.config"
+ // xcopy /RY "%~dp0test.exe.config" "%cd%\test--optplus--debug.exe.config*"
+ do! xcopy_ry ``test.exe.config`` "test--optplus--debug.exe.config"
+
+ }
diff --git a/tests/fsharp/typeProviders/tests_typeProviders.fs b/tests/fsharp/typeProviders/tests_typeProviders.fs
new file mode 100644
index 00000000000..f467ad5cfed
--- /dev/null
+++ b/tests/fsharp/typeProviders/tests_typeProviders.fs
@@ -0,0 +1,680 @@
+module ``FSharp-Tests-TypeProviders``
+
+open System
+open System.IO
+open NUnit.Framework
+
+open FSharpTestSuiteTypes
+open NUnitConf
+open PlatformHelpers
+
+let testContext = FSharpTestSuite.testContext
+
+let requireVSUltimate cfg = processor {
+ do! match cfg.INSTALL_SKU with
+ | Some (Ultimate) -> Success
+ | x ->
+ // IF /I "%INSTALL_SKU%" NEQ "ULTIMATE" (
+ // echo Test not supported except on Ultimate
+ NUnitConf.skip (sprintf "Test not supported except on Ultimate, was %A" x)
+ // exit /b 0
+ // )
+ }
+
+module Builtin =
+
+ module EdmxFile =
+
+ []
+ let EdmxFile p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ //call %~d0%~p0..\copyFSharpDataTypeProviderDLL.cmd
+ do! CopyFSharpDataTypeProviderDLL.copy cfg dir
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+ module ODataService =
+
+ []
+ let oDataService p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ //call %~d0%~p0..\copyFSharpDataTypeProviderDLL.cmd
+ do! CopyFSharpDataTypeProviderDLL.copy cfg dir
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+ module SqlDataConnection =
+
+ []
+ let sqlDataConnection p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fileExists = Commands.fileExists dir >> Option.isSome
+
+ //call %~d0%~p0..\copyFSharpDataTypeProviderDLL.cmd
+ do! CopyFSharpDataTypeProviderDLL.copy cfg dir
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ // IF /I "%INSTALL_SKU%" NEQ "ULTIMATE" (
+ // echo Test not supported except on Ultimate
+ // exit /b 0
+ // )
+ do! requireVSUltimate cfg
+
+ // IF EXIST test.exe (
+ // echo Running test.exe to warm up SQL
+ // test.exe > nul 2> nul
+ // )
+ do! if fileExists "test.exe"
+ then
+ // echo Running test.exe to warm up SQL
+ // test.exe > nul 2> nul
+ exec ("."/"test.exe") ""
+ else Success ()
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+ module WsdlService =
+
+ []
+ let wsdlService p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ //call %~d0%~p0..\copyFSharpDataTypeProviderDLL.cmd
+ do! CopyFSharpDataTypeProviderDLL.copy cfg dir
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+
+[]
+module DiamondAssembly =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let del = Commands.rm dir
+
+ // if EXIST provider.dll del provider.dll
+ del "provider.dll"
+
+ // "%FSC%" --out:provided.dll -a ..\helloWorld\provided.fs
+ do! fsc "%s" "--out:provided.dll -a" [".."/"helloWorld"/"provided.fs"]
+
+ // "%FSC%" --out:provider.dll -a ..\helloWorld\provider.fsx
+ do! fsc "%s" "--out:provider.dll -a" [".."/"helloWorld"/"provider.fsx"]
+
+ // "%FSC%" %fsc_flags% --debug+ -r:provider.dll --optimize- -o:test1.dll -a test1.fsx
+ do! fsc "%s --debug+ -r:provider.dll --optimize- -o:test1.dll -a" cfg.fsc_flags ["test1.fsx"]
+
+ // "%FSC%" %fsc_flags% --debug+ -r:provider.dll --optimize- -o:test2a.dll -a -r:test1.dll test2a.fsx
+ do! fsc "%s --debug+ -r:provider.dll --optimize- -o:test2a.dll -a -r:test1.dll" cfg.fsc_flags ["test2a.fsx"]
+
+ // "%FSC%" %fsc_flags% --debug+ -r:provider.dll --optimize- -o:test2b.dll -a -r:test1.dll test2b.fsx
+ do! fsc "%s --debug+ -r:provider.dll --optimize- -o:test2b.dll -a -r:test1.dll" cfg.fsc_flags ["test2b.fsx"]
+
+ // "%FSC%" %fsc_flags% --debug+ -r:provider.dll --optimize- -o:test3.exe -r:test1.dll -r:test2a.dll -r:test2b.dll test3.fsx
+ do! fsc "%s --debug+ -r:provider.dll --optimize- -o:test3.exe -r:test1.dll -r:test2a.dll -r:test2b.dll" cfg.fsc_flags ["test3.fsx"]
+
+ }
+
+ let run cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let fsi = Printf.ksprintf (Commands.fsi exec cfg.FSI)
+ let fileguard = (Commands.getfullpath dir) >> FileGuard.create
+
+ // "%PEVERIFY%" test1.dll
+ do! peverify "test1.dll"
+
+ // "%PEVERIFY%" test2a.dll
+ do! peverify "test2a.dll"
+
+ // "%PEVERIFY%" test2b.dll
+ do! peverify "test2b.dll"
+
+ // "%PEVERIFY%" test3.exe
+ do! peverify "test3.exe"
+
+ // test3.exe
+ do! exec ("."/"test3.exe") ""
+
+
+
+ // if exist test.ok (del /f /q test.ok)
+ use testOkFile = fileguard "test.ok"
+
+ // %CLIX% "%FSI%" %fsi_flags% test1.fsx test2a.fsx test2b.fsx test3.fsx && (
+ do! fsi "%s" cfg.fsi_flags ["test1.fsx"; "test2a.fsx"; "test2b.fsx"; "test3.fsx"]
+
+ // dir test.ok > NUL 2>&1 ) || (
+ // @echo :FSI load failed
+ // set ERRORMSG=%ERRORMSG% FSI load failed;
+ do! testOkFile |> NUnitConf.checkGuardExists
+ // )
+
+ }
+
+ []
+ let diamondAssembly () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+
+module GlobalNamespace =
+
+ []
+ let globalNamespace () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let csc = Printf.ksprintf (Commands.csc exec cfg.CSC)
+
+ // %CSC% /out:globalNamespaceTP.dll /debug+ /target:library /r:"%FSCOREDLLPATH%" globalNamespaceTP.cs
+ do! csc """/out:globalNamespaceTP.dll /debug+ /target:library /r:"%s" """ cfg.FSCOREDLLPATH ["globalNamespaceTP.cs"]
+
+ // "%FSC%" %fsc_flags% /debug+ /r:globalNamespaceTP.dll /optimize- test.fsx
+ do! fsc "%s /debug+ /r:globalNamespaceTP.dll /optimize-" cfg.fsc_flags ["test.fsx"]
+
+ })
+
+
+module HelloWorld =
+
+ let build cfg dir p = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let del = Commands.rm dir
+ let execIn workDir p = Command.exec workDir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc' execIn = Printf.ksprintf (Commands.fsc execIn cfg.FSC)
+ let mkdir = Commands.mkdir_p dir
+ let getfullpath = Commands.getfullpath dir
+
+ //if EXIST provided.dll del provided.dll
+ del "provided.dll"
+
+ //if EXIST provided1.dll del provided1.dll
+ del "provided1.dll"
+
+ //"%FSC%" --out:provided1.dll -g -a ..\helloWorld\provided.fs
+ do! fsc "%s" "--out:provided1.dll -g -a" [".."/"helloWorld"/"provided.fs"]
+
+ //if EXIST provided2.dll del provided2.dll
+ del "provided2.dll"
+
+ //"%FSC%" --out:provided2.dll -g -a ..\helloWorld\provided.fs
+ do! fsc "%s" "--out:provided2.dll -g -a" [".."/"helloWorld"/"provided.fs"]
+
+ //if EXIST provided3.dll del provided3.dll
+ del "provided3.dll"
+
+ //"%FSC%" --out:provided3.dll -g -a ..\helloWorld\provided.fs
+ do! fsc "%s" "--out:provided3.dll -g -a" [".."/"helloWorld"/"provided.fs"]
+
+ //if EXIST provided4.dll del provided4.dll
+ del "provided4.dll"
+
+ //"%FSC%" --out:provided4.dll -g -a ..\helloWorld\provided.fs
+ do! fsc "%s" "--out:provided4.dll -g -a" [".."/"helloWorld"/"provided.fs"]
+
+ //if EXIST providedJ.dll del providedJ.dll
+ del "providedJ.dll"
+
+ //"%FSC%" --out:providedJ.dll -g -a ..\helloWorld\providedJ.fs
+ do! fsc "%s" "--out:providedJ.dll -g -a" [".."/"helloWorld"/"providedJ.fs"]
+
+ //if EXIST providedK.dll del providedK.dll
+ del "providedK.dll"
+
+ //"%FSC%" --out:providedK.dll -g -a ..\helloWorld\providedK.fs
+ do! fsc "%s" "--out:providedK.dll -g -a" [".."/"helloWorld"/"providedK.fs"]
+
+ //"%FSC%" --out:providedNullAssemblyName.dll -g -a ..\helloWorld\providedNullAssemblyName.fsx
+ do! fsc "%s" "--out:providedNullAssemblyName.dll -g -a" [".."/"helloWorld"/"providedNullAssemblyName.fsx"]
+
+ //call %~d0%~p0\..\build-typeprovider-test.bat
+ do! BuildTypeProviderTest.build cfg dir p
+
+ //if EXIST provider_with_binary_compat_changes.dll del provider_with_binary_compat_changes.dll
+ del "provider_with_binary_compat_changes.dll"
+
+ //mkdir bincompat1
+ mkdir "bincompat1"
+
+ //pushd bincompat1
+ log "pushd bincompat1"
+ let bincompat1 = getfullpath "bincompat1"
+
+ //xcopy /y ..\*.dll .
+ Directory.EnumerateFiles(bincompat1/"..", "*.dll")
+ |> Seq.iter (fun from -> Commands.copy_y bincompat1 from ("."/Path.GetFileName(from)) |> ignore)
+
+ //"%FSC%" -g -a -o:test_lib.dll -r:provider.dll ..\test.fsx
+ do! fsc' (execIn bincompat1) "%s" "-g -a -o:test_lib.dll -r:provider.dll" [".."/"test.fsx"]
+
+ //"%FSC%" -r:test_lib.dll -r:provider.dll ..\testlib_client.fsx
+ do! fsc' (execIn bincompat1) "%s" "-r:test_lib.dll -r:provider.dll" [".."/"testlib_client.fsx"]
+
+ //popd
+ log "popd"
+
+ //mkdir bincompat2
+ mkdir "bincompat2"
+
+ //pushd bincompat2
+ log "pushd bincompat2"
+ let bincompat2 = getfullpath "bincompat2"
+
+ //xcopy /y ..\bincompat1\*.dll .
+ Directory.EnumerateFiles(bincompat2/".."/"bincompat1", "*.dll")
+ |> Seq.iter (fun from -> Commands.copy_y bincompat2 from ("."/Path.GetFileName(from)) |> ignore)
+
+
+ //REM overwrite provider.dll
+ //"%FSC%" --define:ADD_AN_OPTIONAL_STATIC_PARAMETER --define:USE_IMPLICIT_ITypeProvider2 --out:provider.dll -g -a ..\provider.fsx
+ do! fsc' (execIn bincompat2) "%s" "--define:ADD_AN_OPTIONAL_STATIC_PARAMETER --define:USE_IMPLICIT_ITypeProvider2 --out:provider.dll -g -a" [".."/"provider.fsx"]
+
+ // "%FSC%" -g -a -o:test_lib_recompiled.dll -r:provider.dll ..\test.fsx
+ do! fsc' (execIn bincompat2) "-g -a -o:test_lib_recompiled.dll -r:provider.dll" [".."/"test.fsx"]
+
+ //REM This is the important part of the binary compatibility part of the test: the new provider is being used, but
+ //REM with a binary that was generated w.r.t. the old provider. The new provider can still resolve the references
+ //REM generated by the old provider which are stored in the F# metadata for test_lib.dll
+ //"%FSC%" --define:ADD_AN_OPTIONAL_STATIC_PARAMETER -r:test_lib.dll -r:provider.dll ..\testlib_client.fsx
+ do! fsc' (execIn bincompat2) "%s" "--define:ADD_AN_OPTIONAL_STATIC_PARAMETER -r:test_lib.dll -r:provider.dll" [".."/"testlib_client.fsx"]
+
+ //"%PEVERIFY%" provider.dll
+ do! peverify (bincompat2/"provider.dll")
+
+ //"%PEVERIFY%" test_lib.dll
+ do! peverify (bincompat2/"test_lib.dll")
+
+ // "%PEVERIFY%" test_lib_recompiled.dll
+ do! peverify (bincompat2/"test_lib_recompiled.dll")
+
+ //"%PEVERIFY%" testlib_client.exe
+ do! peverify (bincompat2/"testlib_client.exe")
+
+ }
+
+ []
+ let helloWorld p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+
+ })
+
+
+
+module HelloWorldCSharp =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let csc = Printf.ksprintf (Commands.csc exec cfg.CSC)
+ let del = Commands.rm dir
+ let gacutil = Commands.gacutil exec cfg.GACUTIL
+
+ // if EXIST magic.dll del magic.dll
+ del "magic.dll"
+
+ // "%FSC%" --out:magic.dll -a magic.fs --keyfile:magic.snk
+ do! fsc "%s" "--out:magic.dll -a --keyfile:magic.snk" ["magic.fs "]
+
+ // REM == If we are running this test on a lab machine, we may not be running from an elev cmd prompt
+ // REM == In that case, ADMIN_PIPE is set to the tool to invoke the command elevated.
+ // IF DEFINED ADMIN_PIPE %ADMIN_PIPE% %GACUTIL% /if magic.dll
+
+ //REVIEW check ADMIN_PIPE and elevated gac
+ ignore "useless ADMIN_PIPE, test are run as administrator"
+
+ // if EXIST provider.dll del provider.dll
+ del "provider.dll"
+
+ // %CSC% /out:provider.dll /target:library "/r:%FSCOREDLLPATH%" /r:magic.dll provider.cs
+ do! csc """/out:provider.dll /target:library "/r:%s" /r:magic.dll""" cfg.FSCOREDLLPATH ["provider.cs"]
+
+ // "%GACUTIL%" /if magic.dll
+ do! gacutil "/if" "magic.dll"
+
+ // "%FSC%" %fsc_flags% /debug+ /r:provider.dll /optimize- test.fsx
+ do! fsc "%s /debug+ /r:provider.dll /optimize-" cfg.fsc_flags ["test.fsx"]
+
+ }
+
+ let run cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+
+ // "%PEVERIFY%" magic.dll
+ do! peverify "magic.dll"
+
+ // "%PEVERIFY%" provider.dll
+ do! peverify "provider.dll"
+
+ // "%PEVERIFY%" test.exe
+ do! peverify "test.exe"
+
+ // test.exe
+ do! exec ("."/"test.exe") ""
+
+ }
+
+ []
+ let helloWorldCSharp () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
+
+
+
+[]
+module NegTests =
+
+ let testData =
+ // set TESTS_SIMPLE=neg2h neg4 neg1 neg1_a neg2 neg2c neg2e neg2g neg6
+ let testsSimple =
+ ["neg2h"; "neg4"; "neg1"; "neg1_a"; "neg2"; "neg2c"; "neg2e"; "neg2g"; "neg6"]
+ // REM neg7 - excluded
+ // set TESTS_SIMPLE=%TESTS_SIMPLE% InvalidInvokerExpression providerAttributeErrorConsume ProviderAttribute_EmptyConsume
+ @ ["InvalidInvokerExpression"; "providerAttributeErrorConsume"; "ProviderAttribute_EmptyConsume"]
+
+ // set TESTS_WITH_DEFINE=%TESTS_WITH_DEFINE% EVIL_PROVIDER_GetNestedNamespaces_Exception
+ // set TESTS_WITH_DEFINE=%TESTS_WITH_DEFINE% EVIL_PROVIDER_NamespaceName_Exception
+ // set TESTS_WITH_DEFINE=%TESTS_WITH_DEFINE% EVIL_PROVIDER_NamespaceName_Empty
+ // set TESTS_WITH_DEFINE=%TESTS_WITH_DEFINE% EVIL_PROVIDER_GetTypes_Exception
+ // set TESTS_WITH_DEFINE=%TESTS_WITH_DEFINE% EVIL_PROVIDER_ResolveTypeName_Exception
+ // set TESTS_WITH_DEFINE=%TESTS_WITH_DEFINE% EVIL_PROVIDER_GetNamespaces_Exception
+ // set TESTS_WITH_DEFINE=%TESTS_WITH_DEFINE% EVIL_PROVIDER_GetStaticParameters_Exception
+ // set TESTS_WITH_DEFINE=%TESTS_WITH_DEFINE% EVIL_PROVIDER_GetInvokerExpression_Exception
+ // set TESTS_WITH_DEFINE=%TESTS_WITH_DEFINE% EVIL_PROVIDER_GetTypes_Null
+ // set TESTS_WITH_DEFINE=%TESTS_WITH_DEFINE% EVIL_PROVIDER_ResolveTypeName_Null
+ // set TESTS_WITH_DEFINE=%TESTS_WITH_DEFINE% EVIL_PROVIDER_GetNamespaces_Null
+ // set TESTS_WITH_DEFINE=%TESTS_WITH_DEFINE% EVIL_PROVIDER_GetStaticParameters_Null
+ // set TESTS_WITH_DEFINE=%TESTS_WITH_DEFINE% EVIL_PROVIDER_GetInvokerExpression_Null
+ // set TESTS_WITH_DEFINE=%TESTS_WITH_DEFINE% EVIL_PROVIDER_DoesNotHaveConstructor
+ // set TESTS_WITH_DEFINE=%TESTS_WITH_DEFINE% EVIL_PROVIDER_ConstructorThrows
+ // set TESTS_WITH_DEFINE=%TESTS_WITH_DEFINE% EVIL_PROVIDER_ReturnsTypeWithIncorrectNameFromApplyStaticArguments
+ let testsWithDefine = [
+ "EVIL_PROVIDER_GetNestedNamespaces_Exception";
+ "EVIL_PROVIDER_NamespaceName_Exception";
+ "EVIL_PROVIDER_NamespaceName_Empty";
+ "EVIL_PROVIDER_GetTypes_Exception";
+ "EVIL_PROVIDER_ResolveTypeName_Exception";
+ "EVIL_PROVIDER_GetNamespaces_Exception";
+ "EVIL_PROVIDER_GetStaticParameters_Exception";
+ "EVIL_PROVIDER_GetInvokerExpression_Exception";
+ "EVIL_PROVIDER_GetTypes_Null";
+ "EVIL_PROVIDER_ResolveTypeName_Null";
+ "EVIL_PROVIDER_GetNamespaces_Null";
+ "EVIL_PROVIDER_GetStaticParameters_Null";
+ "EVIL_PROVIDER_GetInvokerExpression_Null";
+ "EVIL_PROVIDER_DoesNotHaveConstructor";
+ "EVIL_PROVIDER_ConstructorThrows";
+ "EVIL_PROVIDER_ReturnsTypeWithIncorrectNameFromApplyStaticArguments" ]
+
+ (testsSimple @ testsWithDefine)
+ |> List.map (fun t -> FSharpSuiteTestCaseData("typeProviders/negTests", t))
+
+ []
+ let negTests name = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Commands.fsc exec cfg.FSC
+ let del = Commands.rm dir
+ let fileExists = Commands.fileExists dir >> Option.isSome
+ let getfullpath = Commands.getfullpath dir
+
+ // if EXIST provided.dll del provided.dll
+ del "provided.dll"
+
+ // "%FSC%" --out:provided.dll -a ..\helloWorld\provided.fs
+ do! fsc "--out:provided.dll -a" [".."/"helloWorld"/"provided.fs"]
+
+ // if EXIST providedJ.dll del providedJ.dll
+ del "providedJ.dll"
+
+ // "%FSC%" --out:providedJ.dll -a ..\helloWorld\providedJ.fs
+ do! fsc "--out:providedJ.dll -a" [".."/"helloWorld"/"providedJ.fs"]
+
+ // if EXIST providedK.dll del providedK.dll
+ del "providedK.dll"
+
+ // "%FSC%" --out:providedK.dll -a ..\helloWorld\providedK.fs
+ do! fsc "--out:providedK.dll -a" [".."/"helloWorld"/"providedK.fs"]
+
+ // if EXIST provider.dll del provider.dll
+ del "provider.dll"
+
+ // "%FSC%" --out:provider.dll -a provider.fsx
+ do! fsc "--out:provider.dll -a" ["provider.fsx"]
+
+ // "%FSC%" --out:provider_providerAttributeErrorConsume.dll -a providerAttributeError.fsx
+ do! fsc "--out:provider_providerAttributeErrorConsume.dll -a" ["providerAttributeError.fsx"]
+
+ // "%FSC%" --out:provider_ProviderAttribute_EmptyConsume.dll -a providerAttribute_Empty.fsx
+ do! fsc "--out:provider_ProviderAttribute_EmptyConsume.dll -a" ["providerAttribute_Empty.fsx"]
+
+ // if EXIST helloWorldProvider.dll del helloWorldProvider.dll
+ del "helloWorldProvider.dll"
+
+ // "%FSC%" --out:helloWorldProvider.dll -a ..\helloWorld\provider.fsx
+ do! fsc "--out:helloWorldProvider.dll -a" [".."/"helloWorld"/"provider.fsx"]
+
+ // if EXIST MostBasicProvider.dll del MostBasicProvider.dll
+ del "MostBasicProvider.dll"
+
+ // "%FSC%" --out:MostBasicProvider.dll -a MostBasicProvider.fsx
+ do! fsc "--out:MostBasicProvider.dll -a" ["MostBasicProvider.fsx"]
+
+ //REVIEW use testfixture setup to run this code ---^ only once?
+
+ // if "%1"=="" goto :RunAllTests
+ // if "%1"=="--withDefine" goto :RunSpecificWithDefine
+ // call :RunTest %1
+ // goto :ReportResults
+ ignore "is a parametrized test, like --withDefine"
+
+ // :Preprocess
+ let preprocess bslppName pref = processor {
+
+ let tempFile = Path.GetTempFileName()
+
+ let ``exec <`` l p = Command.exec dir cfg.EnvironmentVariables { Output = Output(Overwrite(tempFile)); Input = Some(RedirectInput(l)) } p >> checkResult
+ let ``| exec >`` out p = Command.exec dir cfg.EnvironmentVariables { Output = Output(Overwrite(out)); Input = Some(RedirectInput(tempFile)) } p >> checkResult
+
+ let ``fsi <`` = Printf.ksprintf (fun flags l -> Commands.fsi (``exec <`` l) cfg.FSI flags [])
+ let ``| fsi >`` = Printf.ksprintf (fun flags sources out -> Commands.fsi (``| exec >`` out) cfg.FSI flags sources)
+
+ // "%FSI%" --exec sed.fsx "" "%~d0%~p0provider_%1.dll" < %~1.%~2bslpp
+ do! ``fsi <`` """--exec sed.fsx "" "%s" """ (getfullpath (sprintf "provider_%s.dll" name)) (sprintf "%s.%sbslpp" bslppName pref)
+
+ // | fsi --exec sed.fsx "" "file:///%CD%\\" > %~1.%~2bsl
+ do! ``| fsi >`` """--exec sed.fsx "" "%O" """ (Uri(dir |> Commands.pathAddBackslash)) [] (sprintf "%s.%sbsl" bslppName pref)
+ }
+
+ // :RunTestWithDefine
+ let runTestWithDefine = processor {
+ // "%FSC%" --define:%1 --out:provider_%1.dll -a provider.fsx
+ do! fsc (sprintf "--define:%s --out:provider_%s.dll -a" name name) ["provider.fsx"]
+
+ // :RunTest
+ // if EXIST %1.bslpp call :Preprocess "%1" ""
+ do! if fileExists (sprintf "%s.bslpp" name)
+ then preprocess name ""
+ else Success
+
+ // if EXIST %1.vsbslpp call :Preprocess "%1" "vs"
+ do! if fileExists (sprintf "%s.vsbslpp" name)
+ then preprocess name "vs"
+ else Success
+
+ // :DoRunTest
+ // call ..\..\single-neg-test.bat %1
+ do! SingleNegTest.singleNegTest cfg dir name
+
+ }
+
+ // :RunSpecificWithDefine
+ // call :RunTestWithDefine %2
+ do! runTestWithDefine
+ // goto :ReportResults
+ ignore "useless, checked already"
+
+ // :RunAllTests
+ // for %%T in (%TESTS_SIMPLE%) do call :RunTest %%T
+ // for %%T in (%TESTS_WITH_DEFINE%) do call :RunTestWithDefine %%T
+ ignore "is a parametrized test"
+
+
+ })
+
+
+module SplitAssembly =
+
+ []
+ let splitAssembly p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+
+ // "%FSC%" --out:provider.dll -a provider.fs
+ do! fsc "--out:provider.dll -a" ["provider.fs"]
+
+ // "%FSC%" --out:providerDesigner.dll -a providerDesigner.fsx
+ do! fsc "--out:providerDesigner.dll -a" ["providerDesigner.fsx"]
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+
+module WedgeAssembly =
+
+ let build cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let del = Commands.rm dir
+
+ // if EXIST provider.dll del provider.dll
+ del "provider.dll"
+
+ // if EXIST provided.dll del provided.dll
+ del "provided.dll"
+
+ // "%FSC%" --out:provided.dll -a ..\helloWorld\provided.fs
+ do! fsc "%s" "--out:provided.dll -a" [".."/"helloWorld"/"provided.fs"]
+
+ // if EXIST providedJ.dll del providedJ.dll
+ del "providedJ.dll"
+
+ // "%FSC%" --out:providedJ.dll -a ..\helloWorld\providedJ.fs
+ do! fsc "%s" "--out:providedJ.dll -a" [".."/"helloWorld"/"providedJ.fs"]
+
+ // if EXIST providedK.dll del providedK.dll
+ del "providedK.dll"
+
+ // "%FSC%" --out:providedK.dll -a ..\helloWorld\providedK.fs
+ do! fsc "%s" "--out:providedK.dll -a" [".."/"helloWorld"/"providedK.fs"]
+
+ // "%FSC%" --out:provider.dll -a ..\helloWorld\provider.fsx
+ do! fsc "%s" "--out:provider.dll -a" [".."/"helloWorld"/"provider.fsx"]
+
+ // "%FSC%" %fsc_flags% --debug+ -r:provider.dll --optimize- -o:test2a.dll -a test2a.fs
+ do! fsc "%s --debug+ -r:provider.dll --optimize- -o:test2a.dll -a" cfg.fsc_flags ["test2a.fs"]
+
+ // "%FSC%" %fsc_flags% --debug+ -r:provider.dll --optimize- -o:test2b.dll -a test2b.fs
+ do! fsc "%s --debug+ -r:provider.dll --optimize- -o:test2b.dll -a" cfg.fsc_flags ["test2b.fs"]
+
+ // "%FSC%" %fsc_flags% --debug+ -r:provider.dll --optimize- -o:test3.exe test3.fsx
+ do! fsc "%s --debug+ -r:provider.dll --optimize- -o:test3.exe" cfg.fsc_flags ["test3.fsx"]
+
+ // "%FSC%" %fsc_flags% --debug+ -r:provider.dll --optimize- -o:test2a-with-sig.dll -a test2a.fsi test2a.fs
+ do! fsc "%s --debug+ -r:provider.dll --optimize- -o:test2a-with-sig.dll -a" cfg.fsc_flags ["test2a.fsi"; "test2a.fs"]
+
+ // "%FSC%" %fsc_flags% --debug+ -r:provider.dll --optimize- -o:test2b-with-sig.dll -a test2b.fsi test2b.fs
+ do! fsc "%s --debug+ -r:provider.dll --optimize- -o:test2b-with-sig.dll -a" cfg.fsc_flags ["test2b.fsi"; "test2b.fs"]
+
+ // "%FSC%" %fsc_flags% --debug+ -r:provider.dll --optimize- -o:test3-with-sig.exe --define:SIGS test3.fsx
+ do! fsc "%s --debug+ -r:provider.dll --optimize- -o:test3-with-sig.exe --define:SIGS" cfg.fsc_flags ["test3.fsx"]
+
+ // "%FSC%" %fsc_flags% --debug+ -r:provider.dll --optimize- -o:test2a-with-sig-restricted.dll -a test2a-restricted.fsi test2a.fs
+ do! fsc "%s --debug+ -r:provider.dll --optimize- -o:test2a-with-sig-restricted.dll -a" cfg.fsc_flags ["test2a-restricted.fsi"; "test2a.fs"]
+
+ // "%FSC%" %fsc_flags% --debug+ -r:provider.dll --optimize- -o:test2b-with-sig-restricted.dll -a test2b-restricted.fsi test2b.fs
+ do! fsc "%s --debug+ -r:provider.dll --optimize- -o:test2b-with-sig-restricted.dll -a"cfg.fsc_flags ["test2b-restricted.fsi"; "test2b.fs"]
+
+ // "%FSC%" %fsc_flags% --debug+ -r:provider.dll --optimize- -o:test3-with-sig-restricted.exe --define:SIGS_RESTRICTED test3.fsx
+ do! fsc "%s --debug+ -r:provider.dll --optimize- -o:test3-with-sig-restricted.exe --define:SIGS_RESTRICTED" cfg.fsc_flags ["test3.fsx"]
+
+ }
+
+ let run cfg dir = processor {
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+
+ // "%PEVERIFY%" test2a.dll
+ do! peverify "test2a.dll"
+
+ // "%PEVERIFY%" test2b.dll
+ do! peverify "test2b.dll"
+
+ // "%PEVERIFY%" test3.exe
+ do! peverify "test3.exe"
+
+ // test3.exe
+ do! exec ("."/"test3.exe") ""
+
+ }
+
+ []
+ let wedgeAssembly () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! build cfg dir
+
+ do! run cfg dir
+
+ })
diff --git a/tests/fsharp/typecheck/tests_typecheck.fs b/tests/fsharp/typecheck/tests_typecheck.fs
new file mode 100644
index 00000000000..d8e715b8054
--- /dev/null
+++ b/tests/fsharp/typecheck/tests_typecheck.fs
@@ -0,0 +1,311 @@
+module ``FSharp-Tests-Typecheck``
+
+open System
+open System.IO
+open NUnit.Framework
+
+open FSharpTestSuiteTypes
+open NUnitConf
+open PlatformHelpers
+
+let testContext = FSharpTestSuite.testContext
+
+
+module ``Full-rank-arrays`` =
+
+ []
+ let ``full-rank-arrays`` p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let csc = Printf.ksprintf (Commands.csc exec cfg.CSC)
+
+ // %CSC% /target:library /out:HighRankArrayTests.dll .\Class1.cs
+ do! csc "/target:library /out:HighRankArrayTests.dll" ["Class1.cs"]
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+module Misc =
+
+ []
+ let misc p = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ do! SingleTestBuild.singleTestBuild cfg dir p
+
+ do! SingleTestRun.singleTestRun cfg dir p
+ })
+
+
+module Sigs =
+
+ []
+ let sigs () = check (processor {
+ let { Directory = dir; Config = cfg } = testContext ()
+
+ let exec p = Command.exec dir cfg.EnvironmentVariables { Output = Inherit; Input = None; } p >> checkResult
+ let fsc = Printf.ksprintf (Commands.fsc exec cfg.FSC)
+ let peverify = Commands.peverify exec cfg.PEVERIFY
+ let fsc_flags = cfg.fsc_flags
+
+ let singleNegTest = SingleNegTest.singleNegTest cfg dir
+
+
+ // call ..\..\single-neg-test.bat neg91
+ do! singleNegTest "neg91"
+
+ // "%FSC%" %fsc_flags% --target:exe -o:pos20.exe pos20.fs
+ do! fsc "%s --target:exe -o:pos20.exe" fsc_flags ["pos20.fs"]
+ // "%PEVERIFY%" pos20.exe
+ do! peverify "pos20.exe"
+ // pos20.exe
+ do! exec ("."/"pos20.exe") ""
+
+ // "%FSC%" %fsc_flags% --target:exe -o:pos19.exe pos19.fs
+ do! fsc "%s --target:exe -o:pos19.exe" fsc_flags ["pos19.fs"]
+ // "%PEVERIFY%" pos19.exe
+ do! peverify "pos19.exe"
+ // pos19.exe
+ do! exec ("."/"pos19.exe") ""
+
+ // "%FSC%" %fsc_flags% --target:exe -o:pos18.exe pos18.fs
+ do! fsc "%s --target:exe -o:pos18.exe" fsc_flags ["pos18.fs"]
+ // "%PEVERIFY%" pos18.exe
+ do! peverify "pos18.exe"
+ // pos18.exe
+ do! exec ("."/"pos18.exe") ""
+
+ // "%FSC%" %fsc_flags% --target:exe -o:pos16.exe pos16.fs
+ do! fsc "%s --target:exe -o:pos16.exe" fsc_flags ["pos16.fs"]
+ // "%PEVERIFY%" pos16.exe
+ do! peverify "pos16.exe"
+ // pos16.exe
+ do! exec ("."/"pos16.exe") ""
+
+ // "%FSC%" %fsc_flags% --target:exe -o:pos17.exe pos17.fs
+ do! fsc "%s --target:exe -o:pos17.exe" fsc_flags ["pos17.fs"]
+ // "%PEVERIFY%" pos17.exe
+ do! peverify "pos17.exe"
+ // pos17.exe
+ do! exec ("."/"pos17.exe") ""
+
+ // "%FSC%" %fsc_flags% --target:exe -o:pos15.exe pos15.fs
+ do! fsc "%s --target:exe -o:pos15.exe" fsc_flags ["pos15.fs"]
+ // "%PEVERIFY%" pos15.exe
+ do! peverify "pos15.exe"
+ // pos15.exe
+ do! exec ("."/"pos15.exe") ""
+
+ // "%FSC%" %fsc_flags% --target:exe -o:pos14.exe pos14.fs
+ do! fsc "%s --target:exe -o:pos14.exe" fsc_flags ["pos14.fs"]
+ // "%PEVERIFY%" pos14.exe
+ do! peverify "pos14.exe"
+ // pos14.exe
+ do! exec ("."/"pos14.exe") ""
+
+ // "%FSC%" %fsc_flags% --target:exe -o:pos13.exe pos13.fs
+ do! fsc "%s --target:exe -o:pos13.exe" fsc_flags ["pos13.fs"]
+ // "%PEVERIFY%" pos13.exe
+ do! peverify "pos13.exe"
+ // pos13.exe
+ do! exec ("."/"pos13.exe") ""
+
+ // "%FSC%" %fsc_flags% -a -o:pos12.dll pos12.fs
+ do! fsc "%s -a -o:pos12.dll" fsc_flags ["pos12.fs"]
+
+ // "%FSC%" %fsc_flags% -a -o:pos11.dll pos11.fs
+ do! fsc "%s -a -o:pos11.dll" fsc_flags ["pos11.fs"]
+
+ // "%FSC%" %fsc_flags% -a -o:pos10.dll pos10.fs
+ do! fsc "%s -a -o:pos10.dll" fsc_flags ["pos10.fs"]
+
+ // "%PEVERIFY%" pos10.dll
+ do! peverify "pos10.dll"
+
+ // call ..\..\single-neg-test.bat neg90
+ // call ..\..\single-neg-test.bat neg89
+ // call ..\..\single-neg-test.bat neg88
+ do! processor.For (["neg90"; "neg89"; "neg88"], singleNegTest)
+
+ // "%FSC%" %fsc_flags% -a -o:pos09.dll pos09.fs
+ do! fsc "%s -a -o:pos09.dll" fsc_flags ["pos09.fs"]
+
+ // "%PEVERIFY%" pos09.dll
+ do! peverify "pos09.dll"
+
+ // call ..\..\single-neg-test.bat neg87
+ // call ..\..\single-neg-test.bat neg86
+ // call ..\..\single-neg-test.bat neg85
+ // call ..\..\single-neg-test.bat neg84
+ // call ..\..\single-neg-test.bat neg83
+ // call ..\..\single-neg-test.bat neg82
+ // call ..\..\single-neg-test.bat neg81
+ // call ..\..\single-neg-test.bat neg80
+ // call ..\..\single-neg-test.bat neg79
+ // call ..\..\single-neg-test.bat neg78
+ // call ..\..\single-neg-test.bat neg77
+ // call ..\..\single-neg-test.bat neg76
+ // call ..\..\single-neg-test.bat neg75
+ // call ..\..\single-neg-test.bat neg74
+ // call ..\..\single-neg-test.bat neg73
+ // call ..\..\single-neg-test.bat neg72
+ // call ..\..\single-neg-test.bat neg71
+ // call ..\..\single-neg-test.bat neg70
+ // call ..\..\single-neg-test.bat neg69
+ // call ..\..\single-neg-test.bat neg68
+ // call ..\..\single-neg-test.bat neg67
+ // call ..\..\single-neg-test.bat neg66
+ // call ..\..\single-neg-test.bat neg65
+ // call ..\..\single-neg-test.bat neg64
+ // call ..\..\single-neg-test.bat neg61
+ // call ..\..\single-neg-test.bat neg63
+ // call ..\..\single-neg-test.bat neg62
+ // call ..\..\single-neg-test.bat neg20
+ // call ..\..\single-neg-test.bat neg24
+ // call ..\..\single-neg-test.bat neg32
+ // call ..\..\single-neg-test.bat neg37
+ // call ..\..\single-neg-test.bat neg37_a
+ // call ..\..\single-neg-test.bat neg60
+ // call ..\..\single-neg-test.bat neg59
+ // call ..\..\single-neg-test.bat neg58
+ // call ..\..\single-neg-test.bat neg57
+ // call ..\..\single-neg-test.bat neg56
+ // call ..\..\single-neg-test.bat neg56_a
+ // call ..\..\single-neg-test.bat neg56_b
+ // call ..\..\single-neg-test.bat neg55
+ // call ..\..\single-neg-test.bat neg54
+ // call ..\..\single-neg-test.bat neg53
+ // call ..\..\single-neg-test.bat neg52
+ // call ..\..\single-neg-test.bat neg51
+ // call ..\..\single-neg-test.bat neg50
+ // call ..\..\single-neg-test.bat neg49
+ // call ..\..\single-neg-test.bat neg48
+ // call ..\..\single-neg-test.bat neg47
+ // call ..\..\single-neg-test.bat neg46
+ // call ..\..\single-neg-test.bat neg10
+ // call ..\..\single-neg-test.bat neg10_a
+ // call ..\..\single-neg-test.bat neg45
+ // call ..\..\single-neg-test.bat neg44
+ // call ..\..\single-neg-test.bat neg43
+ // call ..\..\single-neg-test.bat neg38
+ // call ..\..\single-neg-test.bat neg39
+ // call ..\..\single-neg-test.bat neg40
+ // call ..\..\single-neg-test.bat neg41
+ // call ..\..\single-neg-test.bat neg42
+ do! processor.For (["neg87"; "neg86"; "neg85"; "neg84"; "neg83"; "neg82"; "neg81"; "neg80"; "neg79"; "neg78"; "neg77"; "neg76"; "neg75"; "neg74"; "neg73"; "neg72"; "neg71"; "neg70"; "neg69"; "neg68"; "neg67"; "neg66"; "neg65"; "neg64"; "neg61"; "neg63"; "neg62"; "neg20"; "neg24"; "neg32"; "neg37"; "neg37_a"; "neg60"; "neg59"; "neg58"; "neg57"; "neg56"; "neg56_a"; "neg56_b"; "neg55"; "neg54"; "neg53"; "neg52"; "neg51"; "neg50"; "neg49"; "neg48"; "neg47"; "neg46"; "neg10"; "neg10_a"; "neg45"; "neg44"; "neg43"; "neg38"; "neg39"; "neg40"; "neg41"; "neg42"], singleNegTest)
+
+ // "%FSC%" %fsc_flags% -a -o:pos07.dll pos07.fs
+ do! fsc "%s -a -o:pos07.dll" fsc_flags ["pos07.fs"]
+
+ // "%PEVERIFY%" pos07.dll
+ do! peverify "pos07.dll"
+
+
+ // "%FSC%" %fsc_flags% -a -o:pos08.dll pos08.fs
+ do! fsc "%s -a -o:pos08.dll" fsc_flags ["pos08.fs"]
+
+ // "%PEVERIFY%" pos08.dll
+ do! peverify "pos08.dll"
+
+ // "%FSC%" %fsc_flags% -a -o:pos06.dll pos06.fs
+ do! fsc "%s -a -o:pos06.dll" fsc_flags ["pos06.fs"]
+
+ // "%PEVERIFY%" pos06.dll
+ do! peverify "pos06.dll"
+
+
+ // "%FSC%" %fsc_flags% -a -o:pos03.dll pos03.fs
+ do! fsc "%s -a -o:pos03.dll" fsc_flags ["pos03.fs"]
+
+ // "%PEVERIFY%" pos03.dll
+ do! peverify "pos03.dll"
+
+ // "%FSC%" %fsc_flags% -a -o:pos03a.dll pos03a.fsi pos03a.fs
+ do! fsc "%s -a -o:pos03a.dll" fsc_flags ["pos03a.fsi"; "pos03a.fs"]
+
+ // "%PEVERIFY%" pos03a.dll
+ do! peverify "pos03a.dll"
+
+
+ // call ..\..\single-neg-test.bat neg34
+ // call ..\..\single-neg-test.bat neg33
+ // call ..\..\single-neg-test.bat neg30
+ // call ..\..\single-neg-test.bat neg31
+ // call ..\..\single-neg-test.bat neg29
+ // call ..\..\single-neg-test.bat neg28
+ // call ..\..\single-neg-test.bat neg07
+ // call ..\..\single-neg-test.bat neg_byref_20
+ // call ..\..\single-neg-test.bat neg_byref_1
+ // call ..\..\single-neg-test.bat neg_byref_2
+ // call ..\..\single-neg-test.bat neg_byref_3
+ // call ..\..\single-neg-test.bat neg_byref_4
+ // call ..\..\single-neg-test.bat neg_byref_5
+ // call ..\..\single-neg-test.bat neg_byref_6
+ // call ..\..\single-neg-test.bat neg_byref_7
+ // call ..\..\single-neg-test.bat neg_byref_8
+ // call ..\..\single-neg-test.bat neg_byref_10
+ // call ..\..\single-neg-test.bat neg_byref_11
+ // call ..\..\single-neg-test.bat neg_byref_12
+ // call ..\..\single-neg-test.bat neg_byref_13
+ // call ..\..\single-neg-test.bat neg_byref_14
+ // call ..\..\single-neg-test.bat neg_byref_15
+ // call ..\..\single-neg-test.bat neg_byref_16
+ // call ..\..\single-neg-test.bat neg_byref_17
+ // call ..\..\single-neg-test.bat neg_byref_18
+ // call ..\..\single-neg-test.bat neg_byref_19
+ // call ..\..\single-neg-test.bat neg_byref_21
+ // call ..\..\single-neg-test.bat neg_byref_22
+ // call ..\..\single-neg-test.bat neg_byref_23
+ // call ..\..\single-neg-test.bat neg36
+ // call ..\..\single-neg-test.bat neg17
+ // call ..\..\single-neg-test.bat neg26
+ // call ..\..\single-neg-test.bat neg27
+ // call ..\..\single-neg-test.bat neg25
+ // call ..\..\single-neg-test.bat neg03
+ // call ..\..\single-neg-test.bat neg23
+ // call ..\..\single-neg-test.bat neg22
+ // call ..\..\single-neg-test.bat neg21
+ // call ..\..\single-neg-test.bat neg04
+ // call ..\..\single-neg-test.bat neg05
+ // call ..\..\single-neg-test.bat neg06
+ // call ..\..\single-neg-test.bat neg06_a
+ // call ..\..\single-neg-test.bat neg06_b
+ // call ..\..\single-neg-test.bat neg08
+ // call ..\..\single-neg-test.bat neg09
+ // call ..\..\single-neg-test.bat neg11
+ // call ..\..\single-neg-test.bat neg12
+ // call ..\..\single-neg-test.bat neg13
+ // call ..\..\single-neg-test.bat neg14
+ // call ..\..\single-neg-test.bat neg16
+ // call ..\..\single-neg-test.bat neg18
+ // call ..\..\single-neg-test.bat neg19
+ // call ..\..\single-neg-test.bat neg01
+ // call ..\..\single-neg-test.bat neg02
+ // call ..\..\single-neg-test.bat neg15
+
+ do! processor.For(["neg34"; "neg33"; "neg30"; "neg31"; "neg29"; "neg28"; "neg07"; "neg_byref_20"; "neg_byref_1"; "neg_byref_2"; "neg_byref_3"; "neg_byref_4"; "neg_byref_5"; "neg_byref_6"; "neg_byref_7"; "neg_byref_8"; "neg_byref_10"; "neg_byref_11"; "neg_byref_12"; "neg_byref_13"; "neg_byref_14"; "neg_byref_15"; "neg_byref_16"; "neg_byref_17"; "neg_byref_18"; "neg_byref_19"; "neg_byref_21"; "neg_byref_22"; "neg_byref_23"; "neg36"; "neg17"; "neg26"; "neg27"; "neg25"; "neg03"; "neg23"; "neg22"; "neg21"; "neg04"; "neg05"; "neg06"; "neg06_a"; "neg06_b"; "neg08"; "neg09"; "neg11"; "neg12"; "neg13"; "neg14"; "neg16"; "neg18"; "neg19"; "neg01"; "neg02"; "neg15" ], singleNegTest)
+
+ // echo Some random positive cases found while developing the negative tests
+ // "%FSC%" %fsc_flags% -a -o:pos01a.dll pos01a.fsi pos01a.fs
+ do! fsc "%s -a -o:pos01a.dll" fsc_flags ["pos01a.fsi"; "pos01a.fs"]
+
+ // "%PEVERIFY%" pos01a.dll
+ do! peverify "pos01a.dll"
+
+ // "%FSC%" %fsc_flags% -a -o:pos02.dll pos02.fs
+ do! fsc "%s -a -o:pos02.dll" fsc_flags ["pos02.fs"]
+
+ // "%PEVERIFY%" pos02.dll
+ do! peverify "pos02.dll"
+
+ // call ..\..\single-neg-test.bat neg35
+ do! singleNegTest "neg35"
+
+ // "%FSC%" %fsc_flags% -a -o:pos05.dll pos05.fs
+ do! fsc "%s -a -o:pos05.dll" fsc_flags ["pos05.fs"]
+
+ })
diff --git a/tests/windowsPlatform.fs b/tests/windowsPlatform.fs
new file mode 100644
index 00000000000..d5af155c10a
--- /dev/null
+++ b/tests/windowsPlatform.fs
@@ -0,0 +1,101 @@
+[]
+module WindowsPlatform
+
+open PlatformHelpers
+
+// REM == Find out path to native 'Program Files 32bit', no matter what
+// REM == architecture we are running on and no matter what command
+// REM == prompt we came from.
+// IF /I "%OSARCH%"=="x86" set X86_PROGRAMFILES=%ProgramFiles%
+// IF /I "%OSARCH%"=="IA64" set X86_PROGRAMFILES=%ProgramFiles(x86)%
+// IF /I "%OSARCH%"=="AMD64" set X86_PROGRAMFILES=%ProgramFiles(x86)%
+let x86ProgramFilesDirectory envVars osArch =
+ match osArch with
+ | X86 -> envVars |> Map.find "ProgramFiles"
+ | IA64 -> envVars |> Map.find "ProgramFiles(x86)"
+ | AMD64 -> envVars |> Map.find "ProgramFiles(x86)"
+ | Unknown os -> failwithf "OSARCH '%s' not supported" os
+
+let private parseProcessorArchitecture (s : string) =
+ match s.ToUpper() with
+ | "X86" -> X86
+ | "IA64" -> IA64
+ | "AMD64" -> AMD64
+ | arc -> Unknown s
+
+///
+/// Return current process architecture, using PROCESSOR_ARCHITECTURE environment variable
+///
+let processorArchitecture envVars =
+ match envVars |> Map.tryFind "PROCESSOR_ARCHITECTURE" |> Option.map parseProcessorArchitecture with
+ | Some x -> x
+ | None -> failwithf "environment variable '%s' required " "PROCESSOR_ARCHITECTURE"
+
+///
+/// Return real processor architecture (ignore WOW64)
+/// more info: http://blogs.msdn.com/b/david.wang/archive/2006/03/26/howto-detect-process-bitness.aspx
+/// use PROCESSOR_ARCHITEW6432 and PROCESSOR_ARCHITECTURE environment variables
+///
+let osArch envVars =
+ // SET OSARCH=%PROCESSOR_ARCHITECTURE%
+ // IF NOT "%PROCESSOR_ARCHITEW6432%"=="" SET OSARCH=%PROCESSOR_ARCHITEW6432%
+ match envVars |> Map.tryFind "PROCESSOR_ARCHITEW6432" |> Option.map parseProcessorArchitecture with
+ | Some arc -> arc
+ | None -> processorArchitecture envVars
+
+
+// %~i - expands %i removing any surrounding quotes (")
+// %~fi - expands %i to a fully qualified path name
+// %~di - expands %i to a drive letter only
+// %~pi - expands %i to a path only
+// %~ni - expands %i to a file name only
+// %~xi - expands %i to a file extension only
+// %~si - expanded path contains short names only
+
+open Microsoft.Win32
+
+let regQuery path value (baseKey: RegistryKey) =
+ use regKey = baseKey.OpenSubKey(path, false)
+
+ if (regKey = null) then None
+ else
+ match regKey.GetValue(value) with
+ | null -> None
+ | x -> Some x
+
+open System.Text.RegularExpressions
+open FSharpTestSuiteTypes
+
+let visualStudioVersion () =
+
+ let hklm32 = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32)
+ let keys = hklm32.OpenSubKey(@"Software\Microsoft\VisualStudio\14.0\Setup").GetSubKeyNames()
+ let findstr r = Array.exists (fun t -> Regex.IsMatch(t, r)) keys
+
+ // reg query "%REG_SOFTWARE%\Microsoft\VisualStudio\14.0\Setup" | findstr /r /c:"Express .* for Windows Desktop" > NUL
+ // if NOT ERRORLEVEL 1 (
+ // set INSTALL_SKU=DESKTOP_EXPRESS
+ // goto :done_SKU
+ // )
+ if findstr "Express .* for Windows Desktop"
+ then Some INSTALL_SKU.DesktopExpress
+
+ // reg query "%REG_SOFTWARE%\Microsoft\VisualStudio\14.0\Setup" | findstr /r /c:"Express .* for Web" > NUL
+ // if NOT ERRORLEVEL 1 (
+ // set INSTALL_SKU=WEB_EXPRESS
+ // goto :done_SKU
+ // )
+ elif findstr "Express .* for Web"
+ then Some INSTALL_SKU.WebExpress
+
+ // reg query "%REG_SOFTWARE%\Microsoft\VisualStudio\14.0\Setup" | findstr /r /c:"Ultimate" > NUL
+ // if NOT ERRORLEVEL 1 (
+ // set INSTALL_SKU=ULTIMATE
+ // goto :done_SKU
+ // )
+ elif findstr "Ultimate"
+ then Some INSTALL_SKU.Ultimate
+
+ // set INSTALL_SKU=CLEAN
+ // :done_SKU
+ else Some INSTALL_SKU.Clean