Skip to content
Draft
Show file tree
Hide file tree
Changes from 3 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
249 changes: 131 additions & 118 deletions src/tiPS/PowerShellTips.json

Large diffs are not rendered by default.

45 changes: 45 additions & 0 deletions src/tiPS/Private/TipsAlreadyShownFunctions.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -144,4 +144,49 @@ InModuleScope -ModuleName tiPS { # Must use InModuleScope to call private functi
}
}
}

Describe 'Calling GetLastShownTipId' {
BeforeEach {
# Use a temp configuration data directory instead of reading/overwriting the current user's configuration.
Mock -CommandName Get-TiPSDataDirectoryPath -MockWith {
[string] $directoryPath = "$TestDrive/tiPS" # Use $TestDrive variable so .NET methods can resolve the path.
if (-not (Test-Path -Path $directoryPath -PathType Container))
{
New-Item -Path $directoryPath -ItemType Directory -Force > $null
}
return $directoryPath
}

ClearTipIdsAlreadyShown
}

Context 'When no tips have been shown' {
It 'Should return null' {
$lastShownTipId = GetLastShownTipId
$lastShownTipId | Should -BeNullOrEmpty
}
}

Context 'When tips have been shown' {
It 'Should return the last shown tip ID' {
AppendTipIdToTipIdsAlreadyShown -TipId 'Tip1'
AppendTipIdToTipIdsAlreadyShown -TipId 'Tip2'
AppendTipIdToTipIdsAlreadyShown -TipId 'Tip3'

$lastShownTipId = GetLastShownTipId

$lastShownTipId | Should -Be 'Tip3'
}
}

Context 'When only one tip has been shown' {
It 'Should return that tip ID' {
AppendTipIdToTipIdsAlreadyShown -TipId 'OnlyTip'

$lastShownTipId = GetLastShownTipId

$lastShownTipId | Should -Be 'OnlyTip'
}
}
}
}
21 changes: 21 additions & 0 deletions src/tiPS/Private/TipsAlreadyShownFunctions.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,27 @@ function ClearTipIdsAlreadyShown
[System.IO.File]::WriteAllText($tipIdsAlreadyShownFilePath, [string]::Empty)
}

function GetLastShownTipId
{
[CmdletBinding()]
[OutputType([string])]
Param()

[string[]] $tipIdsAlreadyShown = ReadTipIdsAlreadyShownOrDefault
if ($tipIdsAlreadyShown.Count -eq 0)
{
return $null
}

[string] $lastShownTipId = $tipIdsAlreadyShown | Select-Object -Last 1
if ([string]::IsNullOrWhiteSpace($lastShownTipId))
{
return $null
}

return $lastShownTipId
}

function GetTipIdsAlreadyShownFilePath
{
[CmdletBinding()]
Expand Down
54 changes: 54 additions & 0 deletions src/tiPS/Public/Get-PowerShellTip.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,60 @@ Describe 'Get-PowerShellTip' {
$tip.CreatedDate | Should -Be $oldestTipDate
}
}

Context 'Given the Previous switch' {
BeforeEach {
# Use a temp configuration data directory instead of reading/overwriting the current user's configuration.
Mock -ModuleName $ModuleName -CommandName Get-TiPSDataDirectoryPath -MockWith {
[string] $directoryPath = "$TestDrive/tiPS" # Use $TestDrive variable so .NET methods can resolve the path.
if (-not (Test-Path -Path $directoryPath -PathType Container))
{
New-Item -Path $directoryPath -ItemType Directory -Force > $null
}
return $directoryPath
}
}

It 'Should return the last shown tip' {
InModuleScope -ModuleName $ModuleName {
# Show a tip to populate the last shown tip ID
AppendTipIdToTipIdsAlreadyShown -TipId '2023-07-16-powershell-is-open-source'
}

$tip = Get-PowerShellTip -Previous

$tip.Id | Should -Be '2023-07-16-powershell-is-open-source'
}

It 'Should write an error when no tips have been shown yet' {
InModuleScope -ModuleName $ModuleName {
# Clear all shown tips
ClearTipIdsAlreadyShown
}

Get-PowerShellTip -Previous -ErrorVariable error -ErrorAction SilentlyContinue > $null
$error | Should -Not -BeNullOrEmpty
}

It 'Should not mark the tip as shown again' {
InModuleScope -ModuleName $ModuleName {
# Show a tip to populate the last shown tip ID
AppendTipIdToTipIdsAlreadyShown -TipId '2023-07-16-powershell-is-open-source'

# Get count of shown tips before calling -Previous
[string[]] $tipIdsBeforePrevious = ReadTipIdsAlreadyShownOrDefault

# Get the previous tip
Get-PowerShellTip -Previous > $null

# Get count of shown tips after calling -Previous
[string[]] $tipIdsAfterPrevious = ReadTipIdsAlreadyShownOrDefault

# The count should be the same
$tipIdsAfterPrevious.Count | Should -Be $tipIdsBeforePrevious.Count
}
}
}
}

InModuleScope -ModuleName tiPS { # Must use InModuleScope to access script-level variables of the module.
Expand Down
39 changes: 37 additions & 2 deletions src/tiPS/Public/Get-PowerShellTip.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ function Get-PowerShellTip

When this parameter is used, the list of tips shown is not updated.

.PARAMETER Previous
Return the last tip that was shown.

When this parameter is used, the list of tips shown is not updated.

.INPUTS
You can pipe a [string] of the ID of the tip to retrieve, or a PSCustomObject with a [string] 'Id' property.

Expand All @@ -43,6 +48,11 @@ function Get-PowerShellTip

Get all tips.

.EXAMPLE
Get-PowerShellTip -Previous

Get the last tip that was shown.

.EXAMPLE
'2023-07-16-powershell-is-open-source' | Get-PowerShellTip

Expand All @@ -56,6 +66,7 @@ function Get-PowerShellTip

[CmdletBinding(DefaultParameterSetName = 'Default')]
[OutputType([tiPS.PowerShellTip], ParameterSetName = 'Default')]
[OutputType([tiPS.PowerShellTip], ParameterSetName = 'Previous')]
[OutputType([System.Collections.Specialized.OrderedDictionary], ParameterSetName = 'AllTips')]
Param
(
Expand All @@ -64,8 +75,11 @@ function Get-PowerShellTip
HelpMessage = 'The ID of the tip to retrieve. If not supplied, a random tip will be returned.')]
[string] $Id,

[Parameter(ParameterSetName = 'AllTips', Mandatory = $false, HelpMessage = 'Return all tips.')]
[switch] $AllTips
[Parameter(ParameterSetName = 'AllTips', HelpMessage = 'Return all tips.')]
[switch] $AllTips,

[Parameter(ParameterSetName = 'Previous', HelpMessage = 'Return the last tip that was shown.')]
[switch] $Previous
)

Process
Expand All @@ -75,6 +89,27 @@ function Get-PowerShellTip
return ReadAllPowerShellTipsFromJsonFile
}

if ($Previous)
{
$lastShownTipId = GetLastShownTipId
if ($null -eq $lastShownTipId)
{
Write-Error "No tips have been shown yet."
return
}

[hashtable] $allTips = ReadAllPowerShellTipsFromJsonFile
[bool] $tipIdDoesNotExist = (-not $allTips.Contains($lastShownTipId))
if ($tipIdDoesNotExist)
{
Write-Error "The last shown tip with ID '$lastShownTipId' no longer exists."
return
}

[tiPS.PowerShellTip] $tip = $allTips[$lastShownTipId]
return $tip
}

[bool] $allTipsHaveBeenShown = $script:UnshownTips.Count -eq 0
if ($allTipsHaveBeenShown)
{
Expand Down
36 changes: 36 additions & 0 deletions src/tiPS/Public/Write-PowerShellTip.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,40 @@ Describe 'Write-PowerShellTip' {
Should -InvokeVerifiable # Verify that the Write-Host mock was called.
}
}

Context 'Given the Previous switch' {
BeforeEach {
# Use a temp configuration data directory instead of reading/overwriting the current user's configuration.
Mock -ModuleName $ModuleName -CommandName Get-TiPSDataDirectoryPath -MockWith {
[string] $directoryPath = "$TestDrive/tiPS" # Use $TestDrive variable so .NET methods can resolve the path.
if (-not (Test-Path -Path $directoryPath -PathType Container))
{
New-Item -Path $directoryPath -ItemType Directory -Force > $null
}
return $directoryPath
}
}

It 'Should write the last shown tip without error' {
InModuleScope -ModuleName $ModuleName {
# Show a tip to populate the last shown tip ID
AppendTipIdToTipIdsAlreadyShown -TipId '2023-07-16-powershell-is-open-source'
}

$Error.Clear()
{ Write-PowerShellTip -Previous } | Should -Not -Throw
Should -InvokeVerifiable # Verify that the Write-Host mock was called.
$Error[0] | Should -BeNullOrEmpty
}

It 'Should write an error when no tips have been shown yet' {
InModuleScope -ModuleName $ModuleName {
# Clear all shown tips
ClearTipIdsAlreadyShown
}

Write-PowerShellTip -Previous -ErrorVariable tipError -ErrorAction SilentlyContinue > $null
$tipError | Should -Not -BeNullOrEmpty
}
}
}
28 changes: 24 additions & 4 deletions src/tiPS/Public/Write-PowerShellTip.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ function Write-PowerShellTip
The ID of the tip to write. If not supplied, a random tip will be written.
If no tip with the specified ID exists, an error is written.

.PARAMETER Previous
Write the last tip that was shown instead of a new tip.
The tip is not marked as shown again when using this parameter.

.INPUTS
You can pipe a [string] of the ID of the tip to write, or a PSCustomObject with a [string] 'Id' property.

Expand All @@ -29,20 +33,36 @@ function Write-PowerShellTip
Write-PowerShellTip -Id '2023-07-16-powershell-is-open-source'

Write the tip with the specified ID.

.EXAMPLE
Write-PowerShellTip -Previous

Write the last tip that was shown.
#>
[CmdletBinding()]
[CmdletBinding(DefaultParameterSetName = 'Default')]
[Alias('Tips')]
[OutputType([void])]
Param
(
[Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true,
[Parameter(ParameterSetName = 'Default', Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true,
HelpMessage = 'The ID of the tip to write. If not supplied, a random tip will be written.')]
[string] $Id
[string] $Id,

[Parameter(ParameterSetName = 'Previous', HelpMessage = 'Write the last tip that was shown.')]
[switch] $Previous
)

Process
{
[tiPS.PowerShellTip] $tip = Get-PowerShellTip -Id $Id
if ($Previous)
{
[tiPS.PowerShellTip] $tip = Get-PowerShellTip -Previous
}
else
{
[tiPS.PowerShellTip] $tip = Get-PowerShellTip -Id $Id
}

if ($null -ne $tip)
{
WritePowerShellTipToTerminal -Tip $tip
Expand Down
Loading