Assert icon indicating copy to clipboard operation
Assert copied to clipboard

Consider adding <{}> option in message templates to allow execution of arbitrary code

Open nohwnd opened this issue 6 years ago • 1 comments

The templating that is used to generate assertion messages can expand few predefined tokens as well as any token that comes from Data hashtable that is passed to the function. I think this would be useful especially when merged to Pester, so in test descriptions we could do stuff like:

'Given value "<actual>" of type "<{$actual.GetType().Name}>"
and count "<{$actual.Count}>" it prints message "<expected>"'

And later we could simplify common usecases via built-in ~templates~ tokens, in fact the actualType ~template~ token already exists. This would give simple way of using it, with possibility to go advanced when the framework is limiting us.

One downside is that you would have to use single quoted string to avoid expanding the string prematurely.

Do we even need special syntax for this? Just expanding the string might be enough, but on the other hand <{}> would align better with the current syntax. BNut now I am not sure why we needed the custom syntax in the first place, when we could just do $actual, maybe to avoid explaining that you need to handle it with single qoutes.

Would anyone find this useful even for assertion messages? For which cases?

nohwnd avatar Aug 03 '17 11:08 nohwnd

Looking at this after a while. The <actual> syntax was a good choice, that way it does not matter if we use single or double quotes.

The token idea also seems valid, but instead of the proposed syntax of <actualType> which limits where *Type could be used, it would be better to implement this as a "format" such as <actual:type>. ( Ingnorig that ${actual:type} is technically a correct parameter name.


The any-code syntax seems interesting, but with enough formatters in place we don't need it. Maybe for nested properties, but that is simpler to solve by pre-processing the object. There seem to be two distinct groups of usages for test cases:

  • generating tests from a list of objects - here you could use the any-code syntax extensively, but it's also very easy to pre-process the objects
  • actual unit-testing - here the any-code syntax is useful, because you cannot back reference keys in hash tables to do things like @{ Value = 1,2,3; Count = Values.Count; Expected = 3 }. Which could also be solved by post processing the hash table, but it's a bit annoying.
@( @{ Value = 1,2,3; Count = 0; Expected = 3 } ) | 
    % { $_.Count = $_.Values.Count; $_ }

So doing something like this would be useful:

It -TestCases @(
    @{ $Value = 1,2,3 ; Expected = 3 }
) "Given array <value> with <value:count> items it counts that there are <expected> items" { }

The thing is, how many such general filters we can come up with? I can think of type and count, but what would be the others?

nohwnd avatar Oct 06 '18 13:10 nohwnd