2012-03-01 71 views
4

我在Test::More寻找像is_deeply这样的测试程序。 。 有来自Test::Deepcmp_bag但这只在阵列本身上运行,而不是可怕的大哈希的阵列-的哈希值的数据结构,我传递有什么样:is_deeply测试忽略数组顺序?

is_deeply $got, $expected, { 
    array => cmp_bag, 
    # and other configuration... 
}, "Ugly data structure should be the same, barring array order."; 

澄清

我可以递归深入到我的$expected$got对象和数组转换成袋的对象:

sub bagIt { 
    my $obj = shift; 
    switch (ref($obj)) { 
     case "ARRAY" { 
      return bag([ 
       map { $_ = bagIt($_) } 
       @$obj 
      ]); 
     } case "HASH" { 
      return { 
       map { $_ => bagIt($obj->{$_}) } 
       keys %$obj 
      }; 
     } else { 
      return $obj; 
     } 
    } 
} 

我想知道是否有办法告诉is_deeply的一些变种为我做这个。

+1

你可以使用[Data :: Rmap](http://search.cpan.org/~bowmanbs/Data-Rmap-0.62/lib/Data/Rmap.pm)来重写bagIt,但是我怀疑额外的依赖是值得的几个额外的代码行......如果它在答案中,我会为bagIt投票。 – Dallaylaen 2012-03-02 10:56:56

回答

1

貌似没有在Test::Deep或其他Test::*选项包将每个数组视为一个包集。下面的函数工作,但效率不高的测试在大数据结构:

sub bagIt { 
    my $obj = shift; 
    my $ref = ref($obj); 
    if ($ref eq 'ARRAY') { 
     return Test::Deep::bag(
      map { $_ = bagIt($_) } 
      @$obj 
     ); 
    } elsif ($ref eq 'HASH') { 
     return { 
      map { $_ => bagIt($obj->{$_}) } 
      keys %$obj 
     }; 
    } else { 
     return $obj; 
    } 
} 

最后,我结束了我的重构代码,不依靠这样的粗粒度的测试。

2

那么,从Test::Deep docs,cmp_bag(\@got, \@bag, $name)只是cmp_deeply(\@got, bag(@bag), $name)的简写。

is_deeply($got, { 
    array => bag(qw/the values you expect/), 
    # and other expected values 
}, "Ugly data structure should be the same, barring array order."); 
+1

感谢您的回复。更新了要澄清的问题。问题是,我将不得不遍历数据结构,手动将ARRAY转换为包对象。我想知道是否有一些Test :: * lib可以做到这一点,比较深层次的平等。 – devoid 2012-03-01 21:41:20

2

使用你已经写好了bagIt功能,你总是可以做出is_deeply的包装,对你适用bagIt

sub is_deep_bag { 
    splice @_, 1, 1, bagIt($_[1]); 
    goto &is_deeply # magic goto so that errors are reported on the right line 
}