Skip to content
Draft
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
101 changes: 101 additions & 0 deletions test/FsAutoComplete.Tests.Lsp/DecompilerTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
module FsAutoComplete.Tests.Lsp.DecompilerTests

open Expecto
open FsAutoComplete.Decompiler
open FSharp.Compiler.Text

/// Tests for the Decompiler module utility functions
module DecompilerTests =

/// Tests for file name sanitization
let fileNameSanitizationTests =
testList "File Name Sanitization" [

testCase "toSafeFileNameRegex compilation" <| fun _ ->
// Test that the regex compiles and works on basic unsafe characters
let regex = toSafeFileNameRegex
let testInput = "test<>file"
let result = regex.Replace(testInput, "_")
Expect.equal result "test__file" "Should replace unsafe characters with underscores"

testCase "handles multiple unsafe characters" <| fun _ ->
let regex = toSafeFileNameRegex
let testInput = "test|file:name?"
let result = regex.Replace(testInput, "_")
Expect.equal result "test_file_name_" "Should replace all unsafe characters"

testCase "leaves safe characters unchanged" <| fun _ ->
let regex = toSafeFileNameRegex
let testInput = "SafeFileName123.cs"
let result = regex.Replace(testInput, "_")
Expect.equal result "SafeFileName123.cs" "Should leave safe characters unchanged"
]

/// Tests for type accessibility and compilation
let typeAccessibilityTests =
testList "Type Accessibility Tests" [

testCase "DecompileError type is accessible" <| fun _ ->
let decompileErrorType = typeof<DecompileError>
Expect.isNotNull decompileErrorType "DecompileError type should be accessible"

testCase "ExternalContentPosition type is accessible" <| fun _ ->
let externalContentPositionType = typeof<ExternalContentPosition>
Expect.isNotNull externalContentPositionType "ExternalContentPosition type should be accessible"

testCase "FindExternalDeclarationError type is accessible" <| fun _ ->
let errorType = typeof<FindExternalDeclarationError>
Expect.isNotNull errorType "FindExternalDeclarationError type should be accessible"
]

/// Tests for ExternalContentPosition record structure
let externalContentPositionTests =
testList "ExternalContentPosition Tests" [

testCase "ExternalContentPosition record construction" <| fun _ ->
let pos = Position.fromZ 10 5
let position: ExternalContentPosition = {
File = "test.cs"
Position = pos
}

Expect.equal position.File "test.cs" "Should set file correctly"
Expect.equal position.Position.Line 10 "Should set position line correctly"
Expect.equal position.Position.Column 5 "Should set position column correctly"

testCase "ExternalContentPosition with empty file" <| fun _ ->
let pos = Position.fromZ 0 0
let position: ExternalContentPosition = {
File = ""
Position = pos
}

Expect.equal position.File "" "Should handle empty file name"
Expect.equal position.Position.Line 0 "Should handle zero position"
]

/// Tests for module compilation and function accessibility
let moduleAccessibilityTests =
testList "Module Accessibility Tests" [

testCase "core functions exist" <| fun _ ->
// Use reflection to verify the function exists and is accessible
let decompilerModule = typeof<DecompileError>.DeclaringType

let decompilerForFileMethod = decompilerModule.GetMethod("decompilerForFile")
Expect.isNotNull decompilerForFileMethod "decompilerForFile function should exist"

let decompileMethod = decompilerModule.GetMethod("decompile")
Expect.isNotNull decompileMethod "decompile function should exist"

let tryFindMethod = decompilerModule.GetMethod("tryFindExternalDeclaration")
Expect.isNotNull tryFindMethod "tryFindExternalDeclaration function should exist"
]

let tests =
testList "Decompiler Tests" [
DecompilerTests.fileNameSanitizationTests
DecompilerTests.typeAccessibilityTests
DecompilerTests.externalContentPositionTests
DecompilerTests.moduleAccessibilityTests
]
6 changes: 6 additions & 0 deletions test/FsAutoComplete.Tests.Lsp/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ open FsAutoComplete.Tests.ScriptTest
open FsAutoComplete.Tests.ExtensionsTests
open FsAutoComplete.Tests.InteractiveDirectivesTests
open FsAutoComplete.Tests.Lsp.CoreUtilsTests
open FsAutoComplete.Tests.Lsp.SourcelinkTests
open FsAutoComplete.Tests.Lsp.DecompilerTests
open FsAutoComplete.Tests.Lsp.RecordStubGeneratorTests
open Ionide.ProjInfo
open System.Threading
open Serilog.Filters
Expand Down Expand Up @@ -143,6 +146,9 @@ let lspTests =
let generalTests = testList "general" [
testList (nameof (Utils)) [ Utils.Tests.Utils.tests; Utils.Tests.TextEdit.tests ]
UtilsTests.allTests
FsAutoComplete.Tests.Lsp.SourcelinkTests.tests
FsAutoComplete.Tests.Lsp.DecompilerTests.tests
FsAutoComplete.Tests.Lsp.RecordStubGeneratorTests.tests
InlayHintTests.explicitTypeInfoTests sourceTextFactory
FindReferences.tryFixupRangeTests sourceTextFactory
]
Expand Down
115 changes: 115 additions & 0 deletions test/FsAutoComplete.Tests.Lsp/RecordStubGeneratorTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
module FsAutoComplete.Tests.Lsp.RecordStubGeneratorTests

open Expecto
open FsAutoComplete.RecordStubGenerator
open FSharp.Compiler.Text

/// Tests for the RecordStubGenerator module
module RecordStubGeneratorTests =

/// Tests for PositionKind enumeration and basic types
let positionKindTests =
testList "PositionKind Tests" [

testCase "PositionKind cases are defined" <| fun _ ->
// Test that all position kind cases are accessible
let _afterLeftBrace = PositionKind.AfterLeftBrace
let _afterCopyExpression = PositionKind.AfterCopyExpression
let _afterLastField = PositionKind.AfterLastField

Expect.isTrue true "AfterLeftBrace should be defined"
Expect.isTrue true "AfterCopyExpression should be defined"
Expect.isTrue true "AfterLastField should be defined"

testCase "PositionKind pattern matching works" <| fun _ ->
let testKind = PositionKind.AfterLeftBrace

let result =
match testKind with
| PositionKind.AfterLeftBrace -> "after brace"
| PositionKind.AfterCopyExpression -> "after copy"
| PositionKind.AfterLastField -> "after field"

Expect.equal result "after brace" "Pattern matching should work correctly"
]

/// Tests for RecordStubsInsertionParams type and construction
let insertionParamsTests =
testList "RecordStubsInsertionParams Tests" [

testCase "RecordStubsInsertionParams construction" <| fun _ ->
let pos = Position.fromZ 5 10
let insertionParams = {
Kind = PositionKind.AfterLeftBrace
InsertionPos = pos
IndentColumn = 4
}

Expect.equal insertionParams.Kind PositionKind.AfterLeftBrace "Kind should be set correctly"
Expect.equal insertionParams.InsertionPos.Line 5 "Position line should be set correctly"
Expect.equal insertionParams.InsertionPos.Column 10 "Position column should be set correctly"
Expect.equal insertionParams.IndentColumn 4 "IndentColumn should be set correctly"
]

/// Tests for RecordExpr type accessibility
let recordExprTests =
testList "RecordExpr Tests" [

testCase "RecordExpr type structure" <| fun _ ->
// Test that we can access the RecordExpr type and its fields
let recordExprType = typeof<RecordExpr>
Expect.isNotNull recordExprType "RecordExpr type should be accessible"

// Check that the required fields exist
let exprField = recordExprType.GetProperty("Expr")
let copyExprField = recordExprType.GetProperty("CopyExprOption")
let fieldExprListField = recordExprType.GetProperty("FieldExprList")
let lastKnownPosField = recordExprType.GetProperty("LastKnownGoodPosForSymbolLookup")

Expect.isNotNull exprField "Expr field should exist"
Expect.isNotNull copyExprField "CopyExprOption field should exist"
Expect.isNotNull fieldExprListField "FieldExprList field should exist"
Expect.isNotNull lastKnownPosField "LastKnownGoodPosForSymbolLookup field should exist"
]

/// Tests for module compilation and function accessibility
let moduleAccessibilityTests =
testList "Module Accessibility Tests" [

testCase "key functions exist" <| fun _ ->
// Use reflection to verify the function exists and is accessible
let moduleType = typeof<RecordExpr>.DeclaringType

let formatRecordMethod = moduleType.GetMethod("formatRecord")
Expect.isNotNull formatRecordMethod "formatRecord function should exist and be accessible"

let tryFindRecordExprMethod = moduleType.GetMethod("tryFindRecordExprInBufferAtPos")
Expect.isNotNull tryFindRecordExprMethod "tryFindRecordExprInBufferAtPos function should exist"

let shouldGenerateMethod = moduleType.GetMethod("shouldGenerateRecordStub")
Expect.isNotNull shouldGenerateMethod "shouldGenerateRecordStub function should exist"
]

/// Tests for Position integration
let positionTests =
testList "Position Integration Tests" [

testCase "Position creation and usage" <| fun _ ->
// Test Position utility functions used in the module
let pos1 = Position.fromZ 10 5
let pos2 = Position.fromZ 10 5
let pos3 = Position.fromZ 11 5

Expect.equal pos1.Line pos2.Line "Same positions should have same line"
Expect.equal pos1.Column pos2.Column "Same positions should have same column"
Expect.notEqual pos1.Line pos3.Line "Different positions should have different line"
]

let tests =
testList "RecordStubGenerator Tests" [
RecordStubGeneratorTests.positionKindTests
RecordStubGeneratorTests.insertionParamsTests
RecordStubGeneratorTests.recordExprTests
RecordStubGeneratorTests.moduleAccessibilityTests
RecordStubGeneratorTests.positionTests
]
65 changes: 65 additions & 0 deletions test/FsAutoComplete.Tests.Lsp/SourcelinkTests.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
module FsAutoComplete.Tests.Lsp.SourcelinkTests

open Expecto
open FsAutoComplete.Sourcelink

/// Tests for the Sourcelink module functions that are accessible
module SourcelinkTests =

/// Tests for module compilation and basic accessibility
let basicAccessibilityTests =
testList "Basic Accessibility Tests" [

testCase "Sourcelink module compiles and is accessible" <| fun _ ->
// Test that the module compiles and key types are accessible
let sourceLinkJsonType = typeof<SourceLinkJson>
Expect.isNotNull sourceLinkJsonType "SourceLinkJson type should be accessible"

testCase "Errors type is accessible" <| fun _ ->
let errorsType = typeof<Errors>
Expect.isNotNull errorsType "Errors type should be accessible"

testCase "key functions exist via reflection" <| fun _ ->
// Use reflection to verify key functions exist
let sourceLinkJsonType = typeof<SourceLinkJson>
let moduleType = sourceLinkJsonType.DeclaringType

let tryFetchMethod = moduleType.GetMethod("tryFetchSourcelinkFile")
Expect.isNotNull tryFetchMethod "tryFetchSourcelinkFile function should exist"
]

/// Tests for error types
let errorTests =
testList "Error Type Tests" [

testCase "Basic error cases are accessible" <| fun _ ->
// Test that basic error cases can be constructed
let _noInfoError = Errors.NoInformation
let _invalidJsonError = Errors.InvalidJson
let _missingSourceError = Errors.MissingSourceFile
let _missingPatternsError = Errors.MissingPatterns

Expect.isTrue true "NoInformation error should be accessible"
Expect.isTrue true "InvalidJson error should be accessible"
Expect.isTrue true "MissingSourceFile error should be accessible"
Expect.isTrue true "MissingPatterns error should be accessible"

testCase "Error pattern matching works" <| fun _ ->
let testError error =
match error with
| Errors.NoInformation -> "no-info"
| Errors.InvalidJson -> "invalid-json"
| Errors.MissingSourceFile -> "missing-source"
| Errors.MissingPatterns -> "missing-patterns"

Expect.equal (testError Errors.NoInformation) "no-info" "NoInformation pattern should match"
Expect.equal (testError Errors.InvalidJson) "invalid-json" "InvalidJson pattern should match"
Expect.equal (testError Errors.MissingSourceFile) "missing-source" "MissingSourceFile pattern should match"
Expect.equal (testError Errors.MissingPatterns) "missing-patterns" "MissingPatterns pattern should match"
]

let tests =
testList "Sourcelink Tests" [
SourcelinkTests.basicAccessibilityTests
SourcelinkTests.errorTests
]