In module Test§

See primary documentation in context for sub is-deeply

multi is-deeply(Seq:D $got, Seq:D $expected, $reason = '')
multi is-deeply(Seq:D $got, Mu $expected, $reason = '')
multi is-deeply(Mu $got, Seq:D $expected, $reason = '')
multi is-deeply(Mu $got, Mu $expected, $reason = '')

Marks a test as passed if the first and second parameters are equivalent, using the same semantics as the eqv operator. This is the best way to check for equality of (deep) data structures. The function accepts an optional description of the test as the last argument.

use Test;
plan 1;

sub string-info(Str() $_) {
    Map.new: (
      length  =>  .chars,
      char-counts => Bag.new-from-pairs: (
          letters => +.comb(/<:letter>/),
          digits  => +.comb(/<:digit>/),
          other   => +.comb(/<.-:letter-:digit>/),
    ))
}

is-deeply string-info('42 Butterflies ♥ Raku'), Map.new((
    :21length,
    char-counts => Bag.new-from-pairs: ( :15letters, :2digits, :4other, )
)), 'string-info gives right info';

Note: for historical reasons, Seq:D arguments to is-deeply get converted to Lists by calling .cache on them. If you want to ensure strict Seq comparisons, use cmp-ok $got, 'eqv', $expected, $desc instead.