Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/fsharp/utils/FileSystem.fs
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,7 @@ type DefaultAssemblyLoader() =

[<Experimental("This FCS API/Type is experimental and subject to change.")>]
type IFileSystem =
// note: do not add members if you can put generic implementation under StreamExtensions below.
abstract AssemblyLoader: IAssemblyLoader
abstract OpenFileForReadShim: filePath: string * ?useMemoryMappedFile: bool * ?shouldShadowCopy: bool -> Stream
abstract OpenFileForWriteShim: filePath: string * ?fileMode: FileMode * ?fileAccess: FileAccess * ?fileShare: FileShare -> Stream
Expand All @@ -435,6 +436,7 @@ type IFileSystem =
abstract EnumerateFilesShim: path: string * pattern: string -> string seq
abstract EnumerateDirectoriesShim: path: string -> string seq
abstract IsStableFileHeuristic: fileName: string -> bool
// note: do not add members if you can put generic implementation under StreamExtensions below.

[<Experimental("This FCS API/Type is experimental and subject to change.")>]
type DefaultFileSystem() as this =
Expand Down Expand Up @@ -696,6 +698,10 @@ module public StreamExtensions =
let encoding = defaultArg encoding Encoding.UTF8
s.ReadLines(encoding) |> Seq.toArray

member s.WriteAllText(text: string) =
use writer = new StreamWriter(s)
writer.Write text

/// If we are working with the view stream from mmf, we wrap it in RawByteMemory (which does zero copy, bu just using handle from the views stream).
/// However, when we use any other stream (FileStream, MemoryStream, etc) - we just read everything from it and expose via ByteArrayMemory.
member s.AsByteMemory() : ByteMemory =
Expand Down
1 change: 1 addition & 0 deletions src/fsharp/utils/FileSystem.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ module public StreamExtensions =
member ReadAllText : ?encoding: Encoding -> string
member ReadLines : ?encoding: Encoding -> string seq
member ReadAllLines : ?encoding: Encoding -> string array
member WriteAllText : text: string -> unit
member AsByteMemory : unit -> ByteMemory

[<AutoOpen>]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
</PropertyGroup>

<ItemGroup>
<Compile Include="..\fsharp\TestHelpers.fs" Link="TestHelpers.fs" />
<Compile Include="LibraryTestFx.fs" />
<Compile Include="SurfaceArea.netstandard.fs" />
<Compile Include="..\service\FsUnit.fs">
Expand Down

Large diffs are not rendered by default.

90 changes: 19 additions & 71 deletions tests/FSharp.Compiler.Service.Tests/LibraryTestFx.fs
Original file line number Diff line number Diff line change
Expand Up @@ -54,77 +54,25 @@ module SurfaceArea =
|]

let actual =
types |> Array.collect getTypeMemberStrings

types
|> Array.collect getTypeMemberStrings
|> Array.sort
|> String.concat Environment.NewLine
asm, actual

// verify public surface area matches expected
let verify expected platform (baseline: string) =
printfn "Verify"
let normalize (s:string) =
Regex.Replace(s, "(\\r\\n|\\n|\\r)+", "\r\n").Trim()

let asm, actualNotNormalized = getActual ()
let actual = actualNotNormalized |> Seq.map normalize |> Seq.filter (String.IsNullOrWhiteSpace >> not) |> set

let expected =
// Split the "expected" string into individual lines, then normalize it.
(normalize expected).Split([|"\r\n"; "\n"; "\r"|], StringSplitOptions.RemoveEmptyEntries)
|> set

//
// Find types/members which exist in exactly one of the expected or actual surface areas.
//

/// Surface area types/members which were expected to be found but missing from the actual surface area.
let unexpectedlyMissing = Set.difference expected actual

/// Surface area types/members present in the actual surface area but weren't expected to be.
let unexpectedlyPresent = Set.difference actual expected

// If both sets are empty, the surface areas match so allow the test to pass.
if Set.isEmpty unexpectedlyMissing
&& Set.isEmpty unexpectedlyPresent then
// pass
()
else

let logFile =
let workDir = TestContext.CurrentContext.WorkDirectory
sprintf "%s\\FSharp.CompilerService.SurfaceArea.%s.txt" workDir platform

FileSystem.OpenFileForWriteShim(logFile).Write(String.Join("\r\n", actual))

// The surface areas don't match; prepare an easily-readable output message.
let msg =
let inline newLine (sb : System.Text.StringBuilder) = sb.AppendLine () |> ignore
let sb = System.Text.StringBuilder ()
Printf.bprintf sb "Assembly: %A" asm
newLine sb
sb.AppendLine "Expected and actual surface area don't match. To see the delta, run:" |> ignore
Printf.bprintf sb " windiff %s %s" baseline logFile
newLine sb
newLine sb
sb.AppendLine "To update the baseline copy the contents of this:" |> ignore
Printf.bprintf sb " %s" logFile
newLine sb
sb.AppendLine "into this:" |> ignore
Printf.bprintf sb " %s" baseline
newLine sb
newLine sb
sb.Append "Unexpectedly missing (expected, not actual):" |> ignore
for s in unexpectedlyMissing do
newLine sb
sb.Append " " |> ignore
sb.Append s |> ignore
newLine sb
newLine sb
sb.Append "Unexpectedly present (actual, not expected):" |> ignore
for s in unexpectedlyPresent do
newLine sb
sb.Append " " |> ignore
sb.Append s |> ignore
newLine sb
sb.ToString ()

failwith msg
let verify expectedFile actualFile =
let normalize text = Regex.Replace(text, "(\\r\\n|\\n|\\r)+", "\r\n").Trim()
let _asm, actual = getActual ()
let actual = normalize actual
let expected = normalize (System.IO.File.ReadAllText expectedFile)
match Tests.TestHelpers.assembleDiffMessage actual expected with
| None -> ()
| Some diff ->
FileSystem
.OpenFileForWriteShim(actualFile)
.WriteAllText(actual)

failwith
$"surface area defined in\n\n{expectedFile}\n\ndoesn't match actual in\n\n{actualFile}\n\nCompare the files and adjust accordingly.
{diff}"
Loading