Skip to content

Commit

Permalink
Fix positional parameter binding for FilterScript (#5)
Browse files Browse the repository at this point in the history
* Allow FilterScript to be a positional argument

- Change Find-Member and Find-Type to allow either FilterScript or
  Name to be in position 0 based on type.
  (e.g. Find-Type { $_.Name } or Find-Type Name)

- Add tests for positional binding.

- Remove a method in TypeArgumentCompleter that was left in by mistake
  and isn't used.

* Fix argument completer for Find-Type

Added the argument completer back onto Find-Type and fixed the bad test
for type name validation.
  • Loading branch information
SeeminglyScience authored Aug 28, 2017
1 parent c38c911 commit d136325
Show file tree
Hide file tree
Showing 9 changed files with 108 additions and 32 deletions.
36 changes: 33 additions & 3 deletions docs/en-US/Find-Member.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ Find properties, methods, fields, etc that fit specific criteria.

## SYNTAX

### ByFilter (Default)

```powershell
Find-Member [-ParameterType <Type>] [-ReturnType <Type>] [-IncludeSpecialName] [-MemberType <MemberTypes>]
[-Static] [-Instance] [-Abstract] [-Virtual] [[-FilterScript] <ScriptBlock>] [-Name <String>] [-Force]
[-RegularExpression] [-InputObject <PSObject>]
```

### ByName

```powershell
Find-Member [-ParameterType <Type>] [-ReturnType <Type>] [-IncludeSpecialName] [-MemberType <MemberTypes>]
[-Static] [-Instance] [-Abstract] [-Virtual] [-FilterScript <ScriptBlock>] [[-Name] <String>] [-Force]
Expand Down Expand Up @@ -144,10 +154,20 @@ Specifies a ScriptBlock to invoke as a filter. The variable "$_" or "$PSItem" co
```yaml
Type: ScriptBlock
Parameter Sets: (All)
Parameter Sets: ByFilter
Aliases:

Required: False
Position: 0
Default value: None
Accept pipeline input: False
Accept wildcard characters: False

Type: ScriptBlock
Parameter Sets: ByName
Aliases:

Required: True
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Expand Down Expand Up @@ -241,14 +261,24 @@ Specifies the member name to match.
```yaml
Type: String
Parameter Sets: (All)
Parameter Sets: ByName
Aliases:

Required: False
Position: 0
Default value: None
Accept pipeline input: False
Accept wildcard characters: True

Type: String
Parameter Sets: ByFilter
Aliases:

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: True
```
### -ParameterType
Expand Down
38 changes: 34 additions & 4 deletions docs/en-US/Find-Type.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,19 @@ Find .NET classes in the AppDomain.

## SYNTAX

### ByFilter (Default)

```powershell
Find-Type [[-Namespace] <String>] [-FullName <String>] [-InheritsType <Type>] [-ImplementsInterface <Type>]
[-Abstract] [-Interface] [-ValueType] [[-FilterScript] <ScriptBlock>] [-Name <String>] [-Force]
[-RegularExpression] [-InputObject <PSObject>]
```

### ByName

```powershell
Find-Type [[-Namespace] <String>] [-FullName <String>] [-InheritsType <Type>] [-ImplementsInterface <Type>]
[[-Name] <String>] [-Abstract] [-Interface] [-ValueType] [-FilterScript <ScriptBlock>] [-Force]
[-Abstract] [-Interface] [-ValueType] [-FilterScript <ScriptBlock>] [[-Name] <String>] [-Force]
[-RegularExpression] [-InputObject <PSObject>]
```

Expand Down Expand Up @@ -73,10 +83,20 @@ Specifies a ScriptBlock to invoke as a filter. The variable "$_" or "$PSItem" co

```yaml
Type: ScriptBlock
Parameter Sets: (All)
Parameter Sets: ByFilter
Aliases:

Required: False
Position: 0
Default value: None
Accept pipeline input: False
Accept wildcard characters: False

Type: ScriptBlock
Parameter Sets: ByName
Aliases:

Required: True
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Expand Down Expand Up @@ -169,14 +189,24 @@ Specifies the name of the type to match. For example, the name of the type "Syst
```yaml
Type: String
Parameter Sets: (All)
Parameter Sets: ByName
Aliases:

Required: False
Position: 0
Default value: None
Accept pipeline input: False
Accept wildcard characters: True

Type: String
Parameter Sets: ByFilter
Aliases:

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: True
```
### -Namespace
Expand Down
4 changes: 2 additions & 2 deletions module/ClassExplorer.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
RootModule = 'ClassExplorer.psm1'

# Version number of this module.
ModuleVersion = '1.0.0'
ModuleVersion = '1.0.1'

# Supported PSEditions
CompatiblePSEditions = 'Desktop', 'Core'
Expand Down Expand Up @@ -88,7 +88,7 @@ PrivateData = @{
# IconUri = ''

# ReleaseNotes of this module
# ReleaseNotes = ''
ReleaseNotes = '- Fix positional binding of FilterScript for Find-Member and Find-Type.'

} # End of PSData hashtable

Expand Down
2 changes: 1 addition & 1 deletion src/ClassExplorer/Commands/FindMemberCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace ClassExplorer.Commands
/// The Find-Member cmdlet searches the current AppDomain for matching members.
/// </summary>
[OutputType(typeof(MemberInfo))]
[Cmdlet(VerbsCommon.Find, "Member")]
[Cmdlet(VerbsCommon.Find, "Member", DefaultParameterSetName = "ByFilter")]
public class FindMemberCommand : FindReflectionObjectCommandBase<MemberInfo>
{
private BindingFlags _flags;
Expand Down
6 changes: 4 additions & 2 deletions src/ClassExplorer/Commands/FindReflectionObjectCommandBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ public abstract class FindReflectionObjectCommandBase<TMemberType> : Cmdlet
/// <summary>
/// Gets or sets a ScriptBlock to invoke as a predicate filter.
/// </summary>
[Parameter]
[Parameter(Position = 0, ParameterSetName="ByFilter")]
[Parameter(ParameterSetName="ByName")]
[ValidateNotNull]
public virtual ScriptBlock FilterScript { get; set; }

/// <summary>
/// Gets or sets the name to match.
/// </summary>
[Parameter(Position = 0)]
[Parameter(Position = 0, ParameterSetName="ByName")]
[Parameter(ParameterSetName="ByFilter")]
[SupportsWildcards]
[ValidateNotNullOrEmpty]
public virtual string Name { get; set; }
Expand Down
22 changes: 11 additions & 11 deletions src/ClassExplorer/Commands/FindTypeCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace ClassExplorer.Commands
/// The FindType cmdlet searches the AppDomain for matching types.
/// </summary>
[OutputType(typeof(Type))]
[Cmdlet(VerbsCommon.Find, "Type")]
[Cmdlet(VerbsCommon.Find, "Type", DefaultParameterSetName = "ByFilter")]
public class FindTypeCommand : FindReflectionObjectCommandBase<Type>
{
/// <summary>
Expand All @@ -23,6 +23,16 @@ public class FindTypeCommand : FindReflectionObjectCommandBase<Type>
[SupportsWildcards]
public string Namespace { get; set; }

/// <summary>
/// Gets or sets the type name to match.
/// </summary>
[Parameter(Position = 0, ParameterSetName = "ByName")]
[Parameter(ParameterSetName = "ByFilter")]
[ValidateNotNullOrEmpty]
[SupportsWildcards]
[ArgumentCompleter(typeof(TypeNameArgumentCompleter))]
public override string Name { get; set; }

/// <summary>
/// Gets or sets the full type name to match.
/// </summary>
Expand All @@ -48,16 +58,6 @@ public class FindTypeCommand : FindReflectionObjectCommandBase<Type>
[ArgumentCompleter(typeof(TypeArgumentCompleter))]
public Type ImplementsInterface { get; set; }

/// <summary>
/// Gets or sets the type name to match.
/// </summary>
[Parameter(Position = 0, ParameterSetName = "ByName")]
[Parameter(ParameterSetName = "__AllParameterSets")]
[ValidateNotNullOrEmpty]
[SupportsWildcards]
[ArgumentCompleter(typeof(TypeNameArgumentCompleter))]
public override string Name { get; set; }

/// <summary>
/// Gets or sets a value indicating whether to only match abstract classes.
/// </summary>
Expand Down
8 changes: 0 additions & 8 deletions src/ClassExplorer/TypeArgumentCompleter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,6 @@ public IEnumerable<CompletionResult> CompleteArgument(
return GetTypesForCompletion(wordToComplete).Select(NewResult);
}

private static bool CompletionTypeFilter(Type m, object filterCriteria)
{
return m.IsPublic &&
filterCriteria is string wordToComplete
? m.Name.StartsWith(wordToComplete, StringComparison.InvariantCultureIgnoreCase)
: false;
}

private static CompletionResult NewResult(Type type)
{
return new CompletionResult(
Expand Down
1 change: 1 addition & 0 deletions test/Completion.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Describe 'Completion tests' {
$results = complete 'Find-Type -Name Toke'

$results.CompletionMatches | ShouldAll { $_.CompletionText.StartsWith('Token') }
$results.CompletionMatches | Should -Not -BeNullOrEmpty
}
It 'can complete type full names' {
$results = complete 'Find-Member -ReturnType Ast'
Expand Down
23 changes: 22 additions & 1 deletion test/Find-Type.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,27 @@ Describe 'Find-Type tests' {
Get-Item . | Find-Type | Should -Be ([System.IO.DirectoryInfo])
}
}

Context 'Positional parameter binding' {
It 'accepts a scriptblock in position 0' {
Find-Type { $_.Name -eq 'runspace' } | Should -Be ([runspace])
}

It 'accepts a name in position 0' {
Find-Type RunspaceMode | Should -Be ([System.Management.Automation.RunspaceMode])
}

It 'accepts both a name and a script block as named parameters in the same command' {
Find-Type -Name Runspace* -FilterScript { $_.IsAbstract } |
ShouldAny { $_ -eq [runspace] }
}

It 'accepts namespace at position 1' {
Find-Type PowerShell* System.Management.Automation.Runspaces |
Should -Be ([System.Management.Automation.Runspaces.PowerShellProcessInstance])
}
}

It 'can find all types' {
$result = Find-Type | Measure-Object

Expand All @@ -30,7 +51,7 @@ Describe 'Find-Type tests' {
$result | Should -Be ([powershell])
}
It 'matches by name' {
Find-Type runspace | Should -Be ([runspace])
Find-Type RunspaceMode | Should -Be ([System.Management.Automation.RunspaceMode])
}
It 'matches by namespace' {
Find-Type -Namespace System.Timers | ShouldAll { $_.Namespace -eq 'System.Timers' }
Expand Down

0 comments on commit d136325

Please sign in to comment.