$directory = Split-Path -Parent $MyInvocation.MyCommand.Path
$testRootDirectory = Split-Path -Parent $directory

Import-Module PSScriptAnalyzer
Import-Module (Join-Path $testRootDirectory "PSScriptAnalyzerTestHelper.psm1")

$editableTextType = "Microsoft.Windows.PowerShell.ScriptAnalyzer.EditableText"
$textEditType = "Microsoft.Windows.PowerShell.ScriptAnalyzer.TextEdit"

Describe "EditableText class" {
    Context "When a sigle edit is given for application" {
        It "Should replace in a single line string in the middle" {
            $def = 'This is just a single line.'
            $edit = New-Object -TypeName $textEditType -ArgumentList 1,14,1,22,"one"
            $editableText = New-Object -TypeName $editableTextType -ArgumentList $def
            $result = $editableText.ApplyEdit($edit)
            $result.ToString() | Should Be "This is just one line."
        }

        It "Should replace in a single line string in the start" {
            $def = 'This is just a single line.'
            $edit = New-Object -TypeName $textEditType -ArgumentList 1,1,1,5,"That"
            $editableText = New-Object -TypeName $editableTextType -ArgumentList $def
            $result = $editableText.ApplyEdit($edit)
            $result.ToString() | Should Be 'That is just a single line.'
        }

        It "Should replace in a single line string in the end" {
            $def = 'This is just a single line.'
            $edit = New-Object -TypeName $textEditType -ArgumentList 1,23,1,27,"sentence"
            $editableText = New-Object -TypeName $editableTextType -ArgumentList $def
            $result = $editableText.ApplyEdit($edit)
            $result.ToString() | Should Be 'This is just a single sentence.'
        }

        It "Should replace in multi-line string" {
            $def = @"
This is an outer string
that spans more than
two lines
"@
            $expected = @"
This is an outer string
that spans three
lines
"@
            $newText = @"
three

"@
            $edit = New-Object -TypeName $textEditType -ArgumentList 2,12,3,5,$newText
            $editableText = New-Object -TypeName $editableTextType -ArgumentList $def
            $result = $editableText.ApplyEdit($edit)
            $result.ToString() | Should Be $expected
        }

        It "Should delete in a multi-line string" {
            $def = @'
function foo {
    param(
        [bool] $param1,
        [bool] $whatif
    )
}
'@
            $expected = @'
function foo {
    param(
        [bool] $param1
    )
}
'@
            $newText = ''
            $edit = New-Object -TypeName $textEditType -ArgumentList 3,23,4,23,$newText
            $editableText = New-Object -TypeName $editableTextType -ArgumentList $def
            $result = $editableText.ApplyEdit($edit)
            $result.ToString() | Should Be $expected
        }

        It "Should insert in a multi-line string" {
            $def = @'
function foo {
    param(
        [bool] $param1
    )
}
'@
            $expected = @'
function foo {
    [CmdletBinding()]
    param(
        [bool] $param1
    )
}
'@
            # Editor does not allow trailing white-spaces, hence this weird construct.
            $s = ' '
            $newText = @"
    [CmdletBinding()]

"@
            $edit = New-Object -TypeName $textEditType -ArgumentList 2,1,2,1,$newText
            $editableText = New-Object -TypeName $editableTextType -ArgumentList $def
            $result = $editableText.ApplyEdit($edit)
            $result.ToString() | Should Be $expected
        }
     }
}
