[t/spec] Fudge test which fails because of hyper issues.
[pugs.git] / t / spec / S03-metaops / reduce.t
blob2e97d7d3a383abf7e679a1307827e4e141d36fb3
1 use v6;
2 use Test;
4 plan 88;
6 =begin pod
8 =head1 DESCRIPTION
10 This test tests the C<[...]> reduce metaoperator.
12 Reference:
13 L<"http://groups.google.de/group/perl.perl6.language/msg/bd9eb275d5da2eda">
15 =end pod
17 # L<S03/"Reduction operators">
19 # [...] reduce metaoperator
21   my @array = <5 -3 7 0 1 -9>;
22   my $sum   = 5 + -3 + 7 + 0 + 1 + -9; # laziness :)
24   is(([+] @array),      $sum, "[+] works");
25   is(([*]  1,2,3),    (1*2*3), "[*] works");
26   is(([-]  1,2,3),    (1-2-3), "[-] works");
27   is(([/]  12,4,3),  (12/4/3), "[/] works");
28   is(([div]  12,4,3),  (12 div 4 div 3), "[div] works");
29   is(([**] 2,2,3),  (2**2**3), "[**] works");
30   is(([%]  13,7,4), (13%7%4),  "[%] works");
31   is(([mod]  13,7,4), (13 mod 7 mod 4),  "[mod] works");
33   is((~ [\+] @array), "5 2 9 9 10 1", "[\\+] works");
34   is((~ [\-] 1, 2, 3), "1 -1 -4",      "[\\-] works");
38   is ([~] <a b c d>), "abcd", "[~] works";
39   is (~ [\~] <a b c d>), "a ab abc abcd", "[\\~] works";
43     ok (    [<]  1, 2, 3, 4), "[<] works (1)";
44     ok (not [<]  1, 3, 2, 4), "[<] works (2)";
45     ok (    [>]  4, 3, 2, 1), "[>] works (1)";
46     ok (not [>]  4, 2, 3, 1), "[>] works (2)";
47     ok (    [==] 4, 4, 4),    "[==] works (1)";
48     ok (not [==] 4, 5, 4),    "[==] works (2)";
49     ok (    [!=] 4, 5, 6),    "[!=] works (1)";
50     ok (not [!=] 4, 4, 4),    "[!=] works (2)";
54     ok (! [eq] <a a b a>),    '[eq] basic sanity (positive)';
55     ok (  [eq] <a a a a>),    '[eq] basic sanity (negative)';
56     ok (  [ne] <a b c a>),    '[ne] basic sanity (positive)';
57     ok (! [ne] <a a b c>),    '[ne] basic sanity (negative)';
58     ok (  [lt] <a b c e>),    '[lt] basic sanity (positive)';
59     ok (! [lt] <a a c e>),    '[lt] basic sanity (negative)';
62 #?rakudo skip "=:= NYI"
64     my ($x, $y);
65     ok (    [=:=]  $x, $x, $x), '[=:=] basic sanity 1';
66     ok (not [=:=]  $x, $y, $x), '[=:=] basic sanity 2';
67     ok (    [!=:=] $x, $y, $x), '[!=:=] basic sanity (positive)';
68     ok (not [!=:=] $y, $y, $x), '[!=:=] basic sanity (negative)';
69     $y := $x;
70     ok (    [=:=]  $y, $x, $y), '[=:=] after binding';
74     my $a = [1, 2];
75     my $b = [1, 2];
77     ok (    [===] 1, 1, 1, 1),      '[===] with literals';
78     ok (    [===] $a, $a, $a),      '[===] with vars (positive)';
79     ok (not [===] $a, $a, [1, 2]),  '[===] with vars (negative)';
80     ok (    [!===] $a, $b, $a),     '[!===] basic sanity (positive)';
81     ok (not [!===] $a, $b, $b),     '[!===] basic sanity (negative)';
85     is (~ [\<]  1, 2, 3, 4), "1 1 1 1", "[\\<] works (1)";
86     is (~ [\<]  1, 3, 2, 4), "1 1 0 0", "[\\<] works (2)";
87     is (~ [\>]  4, 3, 2, 1), "1 1 1 1", "[\\>] works (1)";
88     is (~ [\>]  4, 2, 3, 1), "1 1 0 0", "[\\>] works (2)";
89     is (~ [\==]  4, 4, 4),   "1 1 1",   "[\\==] works (1)";
90     is (~ [\==]  4, 5, 4),   "1 0 0",   "[\\==] works (2)";
91     is (~ [\!=]  4, 5, 6),   "1 1 1",   "[\\!=] works (1)";
92     is (~ [\!=]  4, 5, 5),   "1 1 0",   "[\\!=] works (2)";
93     is (~ [\**]  1, 2, 3),   "3 8 1",   "[\\**] (right assoc) works (1)";
94     is (~ [\**]  3, 2, 0),   "0 1 3",   "[\\**] (right assoc) works (2)";
98   my @array = (Mu, Mu, 3, Mu, 5);
99   is ([//]  @array), 3, "[//] works";
100    #?rakudo skip '[orelse]'
101   is ([orelse] @array), 3, "[orelse] works";
105   my @array = (Mu, Mu, 0, 3, Mu, 5);
106   is ([||] @array), 3, "[||] works";
107   is ([or] @array), 3, "[or] works";
109   # Mu as well as [//] should work too, but testing it like
110   # this would presumably emit warnings when we have them.
111   is (~ [\||] 0, 0, 3, 4, 5), "0 0 3 3 3", "[\\||] works";
114 # not currently legal without an infix subscript operator
115 # {
116 #   my $hash = {a => {b => {c => {d => 42, e => 23}}}};
117 #   is try { [.{}] $hash, <a b c d> }, 42, '[.{}] works';
118 # }
120 # {
121 #   my $hash = {a => {b => 42}};
122 #   is ([.{}] $hash, <a b>), 42, '[.{}] works two levels deep';
123 # }
125 # {
126 #   my $arr = [[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]];
127 #   is ([.[]] $arr, 1, 0, 2), 9, '[.[]] works';
128 # }
131   # 18:45 < autrijus> hm, I found a way to easily do linked list consing in Perl6
132   # 18:45 < autrijus> [=>] 1..10;
133   my $list = [=>] 1,2,3;
134   is $list.key,                 1, "[=>] works (1)";
135   is (try {$list.value.key}),   2, "[=>] works (2)";
136   is (try {$list.value.value}), 3, "[=>] works (3)";
140     my @array = <5 -3 7 0 1 -9>;
141     # according to http://irclog.perlgeek.de/perl6/2008-09-10#i_560910
142     # [,] returns a scalar (holding an Array)
143     my $count = 0;
144     $count++ for [,] @array;
145     is $count, 1, '[,] returns a single Array';
146     ok ([,] @array) ~~ Positional, '[,] returns something Positional';
149 # Following two tests taken verbatim from former t/operators/reduce.t
150 lives_ok({my @foo = [1..3] >>+<< [1..3] >>+<< [1..3]},'Sanity Check');
151 #?rakudo todo "[1..3] >>+<< [1..3] returns [[2, 4, 6]] at the moment"
152 lives_ok({my @foo = [>>+<<] ([1..3],[1..3],[1..3])},'Parse [>>+<<]');
154 # Check that user defined infix ops work with [...], too.
155 #?pugs todo 'bug'
156 #?rakudo skip 'reduce of user defined op'
158     sub infix:<more_than_plus>(Int $a, Int $b) { $a + $b + 1 }
159     is (try { [more_than_plus] 1, 2, 3 }), 8, "[...] reduce metaop works on user defined ops";
162 # {
163 #   my $arr = [ 42, [ 23 ] ];
164 #   $arr[1][1] = $arr;
166 #   is try { [.[]] $arr, 1, 1, 1, 1, 1, 0 }, 23, '[.[]] works with infinite data structures';
167 # }
169 # {
170 #   my $hash = {a => {b => 42}};
171 #   $hash<a><c> = $hash;
173 #   is try { [.{}] $hash, <a c a c a b> }, 42, '[.{}] works with infinite data structures';
174 # }
176 # L<S03/"Reduction operators"/"Among the builtin operators, [+]() returns 0 and [*]() returns 1">
178 is( ([*]()), 1, "[*]() returns 1");
179 is( ([+]()), 0, "[+]() returns 0");
181 is( ([*] 41), 41, "[*] 41 returns 41");
182 is( ([*] 42), 42, "[*] 42 returns 42");
183 is( ~([\*] 42), "42", "[\*] 42 returns (42)");
184 is( ([~] 'towel'), 'towel', "[~] 'towel' returns 'towel'");
185 is( ([~] 'washcloth'), 'washcloth', "[~] 'washcloth' returns 'washcloth'");
186 is( ([\~] 'towel'), 'towel', "[\~] 'towel' returns 'towel'");
187 ok( ([\~] 'towel') ~~ Iterable, "[\~] 'towel' returns something Iterable");
188 is( ([<] 42), Bool::True, "[<] 42 returns true");
189 is( ~([\<] 42), "1", "[\<] 42 returns '1'");
190 ok( ([\<] 42) ~~ Iterable, "[\<] 42 returns something Iterable");
192 is( ([\*] 1..*).[^10].join(', '), '1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800', 
193     'triangle reduce is lazy');
194 is( ([\R~] 'a'..*).[^8].join(', '), 'a, ba, cba, dcba, edcba, fedcba, gfedcba, hgfedcba',
195     'triangle reduce is lazy');
197 # RT #65164 (TODO: implement [^^])
198 #?rakudo skip 'implement [^^]'
200     is [^^](0, 42), 42, '[^^] works (one of two true)';
201     is [^^](42, 0), 42, '[^^] works (one of two true)';
202     ok ! [^^](1, 42),   '[^^] works (two true)';
203     ok ! [^^](0, 0),    '[^^] works (two false)';
205     ok ! [^^](0, 0, 0), '[^^] works (three false)';
206     ok ! [^^](5, 9, 17), '[^^] works (three true)';
208     is [^^](5, 9, 0),  (5 ^^ 9 ^^ 0),  '[^^] mix 1';
209     is [^^](5, 0, 17), (5 ^^ 0 ^^ 17), '[^^] mix 2';
210     is [^^](0, 9, 17), (0 ^^ 9 ^^ 17), '[^^] mix 3';
211     is [^^](5, 0, 0),  (5 ^^ 0 ^^ 0),  '[^^] mix 4';
212     is [^^](0, 9, 0),  (0 ^^ 9 ^^ 0),  '[^^] mix 5';
213     is [^^](0, 0, 17), (0 ^^ 0 ^^ 17), '[^^] mix 6';
216 # RT #75234
217 # rakudo had a problem where once-used meta operators weren't installed
218 # in a sufficiently global location, so using a meta operator in class once
219 # makes it unusable further on
221     class A {
222         method m { return [~] gather for ^3 {take 'a'} }
223     }
224     class B {
225         method n { return [~] gather for ^4 {take 'b'}}
226     }
227     is A.new.m, 'aaa',  '[~] works in first class';
228     is B.new.n, 'bbbb', '[~] works in second class';
229     is ([~] 1, 2, 5), '125', '[~] works outside class';
232 # vim: ft=perl6