From 32876c89e74abbaf895365431ef6890e99ffdc87 Mon Sep 17 00:00:00 2001 From: Aditya Patwardhan Date: Tue, 24 Apr 2018 16:10:29 -0700 Subject: [PATCH] Added Tests for Markdown cmdlets --- .../utility/ConvertFromMarkdownCommand.cs | 70 +++--- .../resources/ConvertMarkdownStrings.resx | 3 - .../MarkdownCmdlets.Tests.ps1 | 216 ++++++++++++++++++ 3 files changed, 247 insertions(+), 42 deletions(-) create mode 100644 test/powershell/Modules/Microsoft.PowerShell.Utility/MarkdownCmdlets.Tests.ps1 diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ConvertFromMarkdownCommand.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ConvertFromMarkdownCommand.cs index 3371d8500d..cb76de25ee 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ConvertFromMarkdownCommand.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/ConvertFromMarkdownCommand.cs @@ -7,7 +7,9 @@ using System.Threading.Tasks; using System.Collections.ObjectModel; using System.Collections.Generic; using System.Management.Automation; +using System.Management.Automation.Internal; using Microsoft.PowerShell.MarkdownRender; +using Dbg = System.Management.Automation; namespace Microsoft.PowerShell.Commands { @@ -99,10 +101,10 @@ namespace Microsoft.PowerShell.Commands } else { - string errorMessage = StringUtil.Format(ConvertMarkdownStrings.InvalidInputObjectType, inputObj.GetType()); + string errorMessage = StringUtil.Format(ConvertMarkdownStrings.InvalidInputObjectType, baseObj.GetType()); ErrorRecord errorRecord = new ErrorRecord( new InvalidDataException(errorMessage), - "ConvertFromMarkdownInvalidInputObject", + "InvalidInputObject", ErrorCategory.InvalidData, InputObject); @@ -126,55 +128,31 @@ namespace Microsoft.PowerShell.Commands { foreach (var path in paths) { + // ResolvePath checks for file existence. var resolvedPaths = ResolvePath(path, isLiteral); foreach (var resolvedPath in resolvedPaths) { - if (File.Exists(resolvedPath)) - { - WriteObject( + WriteObject( MarkdownConverter.Convert( ReadContentFromFile(resolvedPath).Result, conversionType, optionInfo) ); - } - else - { - string errorMessage = StringUtil.Format(ConvertMarkdownStrings.InputFileNotFound, resolvedPath); - var errorRecord = new ErrorRecord( - new FileNotFoundException(errorMessage), - "ConvertFromMarkdownFileNotFound", - ErrorCategory.ResourceUnavailable, - resolvedPath); - - WriteError(errorRecord); - } } } } private async Task ReadContentFromFile(string filePath) { - if (File.Exists(filePath)) - { - using (StreamReader reader = new StreamReader(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))) - { - string mdContent = await reader.ReadToEndAsync(); - return mdContent; - } - } - else - { - string errorMessage = StringUtil.Format(ConvertMarkdownStrings.InputFileNotFound, filePath); - var errorRecord = new ErrorRecord( - new FileNotFoundException(errorMessage), - "ConvertFromMarkdownFileNotFound", - ErrorCategory.ResourceUnavailable, - resolvedPath); + Dbg.Diagnostics.Assert(File.Exists(filePath), "Caller should make sure the file exists."); - WriteError(errorRecord); + using (StreamReader reader = new StreamReader(new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))) + { + string mdContent = await reader.ReadToEndAsync(); + return mdContent; } + } private List ResolvePath(string path, bool isLiteral) @@ -183,20 +161,34 @@ namespace Microsoft.PowerShell.Commands PSDriveInfo drive = null; List resolvedPaths = new List(); - if (isLiteral) + try { - resolvedPaths.Add(Context.SessionState.Path.GetUnresolvedProviderPathFromPSPath(path, out provider, out drive)); + if (isLiteral) + { + resolvedPaths.Add(Context.SessionState.Path.GetUnresolvedProviderPathFromPSPath(path, out provider, out drive)); + } + else + { + resolvedPaths.AddRange(Context.SessionState.Path.GetResolvedProviderPathFromPSPath(path, out provider)); + } } - else + catch (ItemNotFoundException infe) { - resolvedPaths.AddRange(Context.SessionState.Path.GetResolvedProviderPathFromPSPath(path, out provider)); + string errorMessage = StringUtil.Format(ConvertMarkdownStrings.InputFileNotFound, path); + var errorRecord = new ErrorRecord( + infe, + "FileNotFound", + ErrorCategory.ResourceUnavailable, + path); + + WriteError(errorRecord); } if (!provider.Name.Equals("FileSystem", StringComparison.OrdinalIgnoreCase)) { string errorMessage = StringUtil.Format(ConvertMarkdownStrings.FileSystemPathsOnly, path); ErrorRecord errorRecord = new ErrorRecord(new ArgumentException(), - "ConvertFromMarkdownOnlySupportsFileSystemPaths", + "OnlyFileSystemPathsSupported", ErrorCategory.InvalidArgument, path); WriteError(errorRecord); diff --git a/src/Microsoft.PowerShell.Commands.Utility/resources/ConvertMarkdownStrings.resx b/src/Microsoft.PowerShell.Commands.Utility/resources/ConvertMarkdownStrings.resx index 9bf09f3c12..5eff4c73f5 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/resources/ConvertMarkdownStrings.resx +++ b/src/Microsoft.PowerShell.Commands.Utility/resources/ConvertMarkdownStrings.resx @@ -126,7 +126,4 @@ The given path '{0}' is not supported. This command only supports the FileSystem Provider paths. - - The given path '{0}' is not supported. This command only supports the FileSystem Provider paths. - diff --git a/test/powershell/Modules/Microsoft.PowerShell.Utility/MarkdownCmdlets.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Utility/MarkdownCmdlets.Tests.ps1 new file mode 100644 index 0000000000..3424b1949d --- /dev/null +++ b/test/powershell/Modules/Microsoft.PowerShell.Utility/MarkdownCmdlets.Tests.ps1 @@ -0,0 +1,216 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +Describe 'ConvertFrom-Markdown tests' -Tags 'CI' { + + BeforeAll { + $esc = [char]0x1b + + function GetExpectedString + { + [CmdletBinding()] + param( + [ValidateSet( + "Header1", "Header2", "Header3", "Header4", "Header5", "Header6", + "Code", "CodeBlock", + "Link", "Image", + "Bold", "Italics")] + [Parameter()] + [string] $ElementType, + + [string] $Text, + + [string] $CodeFormatString, + + [string] $CodeText + ) + + switch($elementType) + { + "Header1" { "$esc[7m$text$esc[0m`n`n" } + "Header2" { "$esc[4;93m$text$esc[0m`n`n" } + "Header3" { "$esc[4;94m$text$esc[0m`n`n" } + "Header4" { "$esc[4;95m$text$esc[0m`n`n" } + "Header5" { "$esc[4;96m$text$esc[0m`n`n" } + "Header6" { "$esc[4;97m$text$esc[0m`n`n" } + + "Code" { ($CodeFormatString -f "$esc[48;2;155;155;155;38;2;30;30;30m$CodeText$esc[0m") + "`n`n" } + "CodeBlock" { + $expectedString = @() + $CodeText -split "`n" | ForEach-Object { $expectedString += "$esc[48;2;155;155;155;38;2;30;30;30m$_$esc[500@$esc[0m" } + $returnString = $expectedString -join "`n" + "$returnString`n`n" + } + + "Link" { "$esc[4;38;5;117m`"$text`"$esc[0m`n" } + "Image" { "$esc[33m[$text]$esc[0m`n" } + "Bold" { "$esc[1m$text$esc[0m`n" } + "Italics" { "$esc[36m$text$esc[0m`n" } + } + } + + function GetExpectedHTML + { + [CmdletBinding()] + param( + [ValidateSet( + "Header1", "Header2", "Header3", "Header4", "Header5", "Header6", + "Code", "CodeBlock", + "Link", "Image", + "Bold", "Italics")] + [Parameter()] + [string] $ElementType, + + [string] $Text, + + [string] $Url, + + [string] $CodeFormatString, + + [string] $CodeText + ) + + $id = $Text.Replace(" ","-").ToLowerInvariant() + + switch($elementType) + { + "Header1" { "

$text

`n" } + "Header2" { "

$text

`n" } + "Header3" { "

$text

`n" } + "Header4" { "

$text

`n" } + "Header5" { "
$text
`n" } + "Header6" { "
$text
`n" } + + "Code" { "

" + ($CodeFormatString -f "$CodeText") + "

`n" } + "CodeBlock" { "
$CodeText`n
`n" } + + "Link" { "

$text

`n" } + "Image" { "

`"$text`"

`n" } + "Bold" { "

$text

`n" } + "Italics" { "

$text

`n" } + } + } + } + + Context 'Basic tests' { + BeforeAll { + $esc = [char]0x1b + $mdFile = New-Item -Path $TestDrive/input.md -Value "Some **test string** to write in a file" -Force + $mdLiteralPath = New-Item -Path $TestDrive/LiteralPath.md -Value "Some **test string** to write in a file" -Force + $expectedStringFromFile = "Some $esc[1mtest string$esc[0m to write in a file`n`n" + + $codeBlock = @' +``` +bool function() +{ +} +``` +'@ + + $codeBlockText = @" +bool function()`n{`n} +"@ + + $TestCases = @( + @{ element = 'Header1'; InputMD = '# Header 1'; Text = 'Header 1' } + @{ element = 'Header2'; InputMD = '## Header 2'; Text = 'Header 2' } + @{ element = 'Header3'; InputMD = '### Header 3'; Text = 'Header 3' } + @{ element = 'Header4'; InputMD = '#### Header 4'; Text = 'Header 4' } + @{ element = 'Header5'; InputMD = '##### Header 5'; Text = 'Header 5' } + @{ element = 'Header6'; InputMD = '###### Header 6'; Text = 'Header 6' } + @{ element = 'Code'; InputMD = 'This is a `code` sample'; CodeFormatString = 'This is a {0} sample'; CodeText = 'code'} + @{ element = 'CodeBlock'; InputMD = $codeBlock; CodeText = $codeBlockText } + @{ element = 'Link'; InputMD = '[GitHub](https://www.github.com)'; Text = 'GitHub'; Url = 'https://www.github.com'} + @{ element = 'Image'; InputMD = '![alt-text](https://bing.com/ps.svg)'; Text = 'alt-text'; Url = 'https://bing.com/ps.svg'} + @{ element = 'Bold'; InputMD = '**bold text**'; Text = 'bold text' } + @{ element = 'Italics'; InputMD = '*italics text*'; Text = 'italics text' } + ) + } + + + It 'Can convert element : to vt100 using pipeline input' -TestCases $TestCases { + param($element, $inputMD, $text, $codeFormatString, $codeText) + + $output = $inputMD | ConvertFrom-Markdown -AsVT100EncodedString + + if($element -like 'Header?' -or + $element -eq 'Link' -or + $element -eq 'Image' -or + $element -eq 'Bold' -or + $element -eq 'Italics') + { + $expectedString = GetExpectedString -ElementType $element -Text $text + } + elseif($element -eq 'Code') + { + $expectedString = GetExpectedString -ElementType $element -CodeFormatString $codeFormatString -CodeText $codeText + } + elseif($element -eq 'CodeBlock') + { + $expectedString = GetExpectedString -ElementType $element -CodeText $codeText + } + + $output.VT100EncodedString | Should BeExactly $expectedString + } + + It 'Can convert element : to HTML using pipeline input' -TestCases $TestCases { + param($element, $inputMD, $text, $codeFormatString, $codeText, $url) + + $output = $inputMD | ConvertFrom-Markdown + + if($element -like 'Header?' -or + $element -eq 'Bold' -or + $element -eq 'Italics') + { + $expectedString = GetExpectedHTML -ElementType $element -Text $text + } + elseif($element -eq 'Code') + { + $expectedString = GetExpectedHTML -ElementType $element -CodeFormatString $codeFormatString -CodeText $codeText + } + elseif($element -eq 'CodeBlock') + { + $expectedString = GetExpectedHTML -ElementType $element -CodeText $codeText + } + elseif ($element -eq 'Link') + { + $expectedString = GetExpectedHTML -ElementType $element -Text $text -Url $url + } + elseif ($element -eq 'Image') + { + $expectedString = GetExpectedHTML -ElementType $element -Text $text -Url $url + } + + $output.Html | Should BeExactly $expectedString + } + + It 'Can convert input from a file path to vt100 encoded string' { + $output = ConvertFrom-Markdown -Path $mdFile.FullName -AsVT100EncodedString + $output.VT100EncodedString | Should BeExactly $expectedStringFromFile + } + + It 'Can convert input from a fileinfo object to vt100 encoded string' { + $ouputFromFileInfo = $mdFile | ConvertFrom-Markdown -AsVT100EncodedString + $ouputFromFileInfo.VT100EncodedString | Should BeExactly $expectedStringFromFile + } + + It 'Can convert input from a literal path to vt100 encoded string' { + $output = ConvertFrom-Markdown -Path $mdLiteralPath -AsVT100EncodedString + $output.VT100EncodedString | Should BeExactly $expectedStringFromFile + } + } + + Context "ConvertFrom-Markdown error cases" { + It "Gets an error if path is not FileSystem provider path" { + { ConvertFrom-Markdown -Path Env:\PSModulePath -ErrorAction Stop } | Should -Throw -ErrorId 'OnlyFileSystemPathsSupported,Microsoft.PowerShell.Commands.ConvertFromMarkdownCommand' + } + + It "Gets an error if path does not exist" { + { ConvertFrom-Markdown -Path DoestnotExist -ErrorAction Stop } | Should -Throw -ErrorId 'FileNotFound,Microsoft.PowerShell.Commands.ConvertFromMarkdownCommand' + } + + It "Gets an error if input object type is not correct" { + { ConvertFrom-Markdown -InputObject 1 -ErrorAction Stop } | Should -Throw -ErrorId 'InvalidInputObject,Microsoft.PowerShell.Commands.ConvertFromMarkdownCommand' + } + } +}