Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 0df574451d
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 253 lines (197 sloc) 14.076 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252
use v6;
use Test;

# L<S03/List infix precedence/"the sequence operator">

plan 124;

# single-term sequence

is ~( 1 ... 1 ), '1', '1 ... 1';
is ~( 'a' ... 'a' ), 'a', "'a' ... 'a'";

# finite sequence that exactly hit their limit

is (1 ... 5).join(', '), '1, 2, 3, 4, 5', 'simple sequence with one item on the LHS';
is (1 ... -3).join(', '), '1, 0, -1, -2, -3', 'simple decreasing sequence with one item on the LHS';
is (1, 3 ... 9).join(', '), '1, 3, 5, 7, 9', 'simple additive sequence with two items on the LHS';
is (1, 0 ... -3).join(', '), '1, 0, -1, -2, -3', 'simple decreasing additive sequence with two items on the LHS';
is (1, 3, 5 ... 9).join(', '), '1, 3, 5, 7, 9', 'simple additive sequence with three items on the LHS';
is (1, 3, 9 ... 81).join(', '), '1, 3, 9, 27, 81', 'simple multiplicative sequence with three items on the LHS';
is (81, 27, 9 ... 1).join(', '), '81, 27, 9, 3, 1', 'decreasing multiplicative sequence with three items on the LHS';
is (1, { $_ + 2 } ... 9).join(', '), '1, 3, 5, 7, 9', 'simple sequence with one item and block closure on the LHS';
is (1, *+2 ... 9).join(', '), '1, 3, 5, 7, 9', 'simple sequence with one item and * closure on the LHS';
is (1, { $_ - 2 } ... -7).join(', '), '1, -1, -3, -5, -7', 'simple sequence with one item and closure on the LHS';
is (1, 3, 5, { $_ + 2 } ... 13).join(', '), '1, 3, 5, 7, 9, 11, 13', 'simple sequence with three items and block closure on the LHS';

is (1, { 1 / ((1 / $_) + 1) } ... 1/5).map({.perl}).join(', '), '1, 1/2, 1/3, 1/4, 1/5', 'tricky sequence with one item and closure on the LHS';
is (1, { -$_ } ... 1).join(', '), '1', 'simple alternating sequence with one item and closure on the LHS';
is (1, { -$_ } ... 3).[^5].join(', '), '1, -1, 1, -1, 1', 'simple alternating sequence with one item and closure on the LHS';

is ({ 3+2; } ... *).[^5].join(', '), '5, 5, 5, 5, 5', 'sequence with one scalar containing Code on the LHS';

is (1 ... 5, 6, 7).join(', '), '1, 2, 3, 4, 5, 6, 7', 'simple sequence with two further terms on the RHS';
is (1 ... 5, 4, 3).join(', '), '1, 2, 3, 4, 5, 4, 3', 'simple sequence with two extra terms on the RHS';
is (1 ... 5, 'xyzzy', 'plugh').join(', '), '1, 2, 3, 4, 5, xyzzy, plugh', 'simple sequence with two weird items on the RHS';

# infinite sequence that go past their limit
{
is (1 ... 5.5).munch(6).join(', '), '1, 2, 3, 4, 5, 6', 'simple sequence with one item on the LHS';
is (1 ... -3.5).munch(6).join(', '), '1, 0, -1, -2, -3, -4', 'simple decreasing sequence with one item on the LHS';
is (1, 3 ... 10).munch(6).join(', '), '1, 3, 5, 7, 9, 11', 'simple additive sequence with two items on the LHS';
is (1, 0 ... -3.5).munch(6).join(', '), '1, 0, -1, -2, -3, -4', 'simple decreasing additive sequence with two items on the LHS';
is (1, 3, 5 ... 10).munch(6).join(', '), '1, 3, 5, 7, 9, 11', 'simple additive sequence with three items on the LHS';
is (1, 3, 9 ... 100).munch(6).join(', '), '1, 3, 9, 27, 81, 243', 'simple multiplicative sequence with three items on the LHS';
is (81, 27, 9 ... 8/9).munch(6), (81, 27, 9, 3, 1, 1/3), 'decreasing multiplicative sequence with three items on the LHS';
is (1, { $_ + 2 } ... 10).munch(6).join(', '), '1, 3, 5, 7, 9, 11', 'simple sequence with one item and block closure on the LHS';
is (1, *+2 ... 10).munch(6).join(', '), '1, 3, 5, 7, 9, 11', 'simple sequence with one item and * closure on the LHS';
is (1, { $_ - 2 } ... -8).munch(6).join(', '), '1, -1, -3, -5, -7, -9', 'simple sequence with one item and closure on the LHS';
is (1, 3, 5, { $_ + 2 } ... 14).munch(8).join(', '), '1, 3, 5, 7, 9, 11, 13, 15', 'simple sequence with three items and block closure on the LHS';

is (1, { 1 / ((1 / $_) + 1) } ... 11/60).munch(6).map({.perl}).join(', '), '1, 1/2, 1/3, 1/4, 1/5, 1/6', 'tricky sequence with one item and closure on the LHS';
is (1, { -$_ } ... 0).munch(4).join(', '), '1, -1, 1, -1', 'simple alternating sequence with one item and closure on the LHS';

is (1 ... 5.5, 6, 7).[^8].join(', '), '1, 2, 3, 4, 5, 6, 7, 8', 'simple sequence with two further terms on the RHS';
is (1 ... 5.5, 4, 3).[^8].join(', '), '1, 2, 3, 4, 5, 6, 7, 8', 'simple sequence with two extra terms on the RHS';
is (1 ... 5.5, 'xyzzy', 'plugh').[^8].join(', '), '1, 2, 3, 4, 5, 6, 7, 8', 'simple sequence with two weird items on the RHS';
}
# infinite sequence without limits

is (1 ... *).[^5].join(', '), '1, 2, 3, 4, 5', 'simple sequence with one item on the LHS';
is (1, 3 ... *).[^5].join(', '), '1, 3, 5, 7, 9', 'simple additive sequence with two items on the LHS';
is (1, 0 ... *).[^5].join(', '), '1, 0, -1, -2, -3', 'simple decreasing additive sequence with two items on the LHS';
is (1, 3, 5 ... *).[^5].join(', '), '1, 3, 5, 7, 9', 'simple additive sequence with three items on the LHS';
is (8, 7, 6 ... *).[^5].join(', '), '8, 7, 6, 5, 4', 'simple decreasing additive sequence with three items on the LHS';
is (1, 3, 9 ... *).[^5].join(', '), '1, 3, 9, 27, 81', 'simple multiplicative sequence with three items on the LHS';
is (81, 27, 9 ... *).[^5].join(', '), '81, 27, 9, 3, 1', 'decreasing multiplicative sequence with three items on the LHS';
is (1, { $_ + 2 } ... *).[^5].join(', '), '1, 3, 5, 7, 9', 'simple sequence with one item and block closure on the LHS';
is (1, *+2 ... *).[^5].join(', '), '1, 3, 5, 7, 9', 'simple sequence with one item and * closure on the LHS';
is (1, { $_ - 2 } ... *).[^5].join(', '), '1, -1, -3, -5, -7', 'simple sequence with one item and closure on the LHS';
is (1, 3, 5, { $_ + 2 } ... *).[^7].join(', '), '1, 3, 5, 7, 9, 11, 13', 'simple sequence with three items and block closure on the LHS';

is (1, { 1 / ((1 / $_) + 1) } ... *).[^5].map({.perl}).join(', '), '1, 1/2, 1/3, 1/4, 1/5', 'tricky sequence with one item and closure on the LHS';
is (1, { -$_ } ... *).[^5].join(', '), '1, -1, 1, -1, 1', 'simple alternating sequence with one item and closure on the LHS';

is (1 ... *, 6, 7).[^7].join(', '), '1, 2, 3, 4, 5, 6, 7', 'simple sequence with two further terms on the RHS';
is (1 ... *, 4, 3).[^7].join(', '), '1, 2, 3, 4, 5, 6, 7', 'simple sequence with two extra terms on the RHS';
is (1 ... *, 'xyzzy', 'plugh').[^7].join(', '), '1, 2, 3, 4, 5, 6, 7', 'simple sequence with two weird items on the RHS';

# constant sequence

is ('c', { $_ } ... *).[^10].join(', '), 'c, c, c, c, c, c, c, c, c, c', 'constant sequence started with letter and identity closure';
is ('c', 'c' ... *).[^10].join(', '), 'c, c, c, c, c, c, c, c, c, c', 'constant sequence started with two letters';
is ('c', 'c', 'c' ... *).[^10].join(', '), 'c, c, c, c, c, c, c, c, c, c', 'constant sequence started with three letters';
is (1, 1 ... *).[^10].join(', '), '1, 1, 1, 1, 1, 1, 1, 1, 1, 1', 'constant sequence started with two numbers';
is (1, 1, 1 ... *).[^10].join(', '), '1, 1, 1, 1, 1, 1, 1, 1, 1, 1', 'constant sequence started with three numbers';

# misleading starts

is (1, 1, 1, 2, 3 ... 10).[^10].join(', '), '1, 1, 1, 2, 3, 4, 5, 6, 7, 8', 'sequence started with three identical numbers, but then goes arithmetic';
is (1, 1, 1, 2, 4 ... 16).join(', '), '1, 1, 1, 2, 4, 8, 16', 'sequence started with three identical numbers, but then goes geometric';
is (4, 2, 1, 2, 4 ... 16).join(', '), '4, 2, 1, 2, 4, 8, 16', 'geometric sequence started in one direction and continues in the other';

# some tests taken from Spec

is (False, &prefix:<!> ... *).[^6].join(', '), (False, True, False, True, False, True).join(', '), "alternating False and True";
is (False, &prefix:<!> ... *).[^10].grep(Bool).elems, 10, "alternating False and True is always Bool";
#?rakudo skip 'loops'
is (1,2,&[+] ... 8).join(', ') , "1, 2, 3, 5, 8" , "Using &[+] works";
is (False, { !$_ } ... *).[^6].join(', '), (False, True, False, True, False, True).join(', '), "alternating False and True";
is (False, { !$_ } ... *).[^10].grep(Bool).elems, 10, "alternating False and True is always Bool";

# L<S03/List infix precedence/'"asymptotically approaching" is not the same as "equals"'>
# infinite sequence with limits

is ~(1, 1/2, 1/4 ... 0).[^5].map({.perl}), '1 1/2 1/4 1/8 1/16', 'geometric sequence that never reaches its limit';
is ~(1, -1/2, 1/4 ... 0).[^5].map({.perl}), '1 -1/2 1/4 -1/8 1/16', 'alternating geometric sequence that never reaches its limit';
is (1, { 1 / ((1 / $_) + 1) } ... 0).[^5].map({.perl}).join(', '), '1, 1/2, 1/3, 1/4, 1/5', '"harmonic" sequence that never reaches its limit';

# empty sequence

# L<S03/List infix precedence/'limit value is on the "wrong"'>
{
is (1, 2 ... 0).munch(3), (1,2,3), 'No more: limit value is on the wrong side';
}

# L<S03/List infix precedence/excludes the limit if it happens to match exactly>
# excluded limits via "...^"
{
is (1 ...^ 5).join(', '), '1, 2, 3, 4', 'exclusive sequence';
is (1 ...^ -3).join(', '), '1, 0, -1, -2', 'exclusive decreasing sequence';
is (1 ...^ 5.5).munch(6).join(', '), '1, 2, 3, 4, 5, 6', "exclusive sequence that couldn't hit its limit anyway";
is (1, 3, 9 ...^ 81).join(', '), '1, 3, 9, 27', 'exclusive geometric sequence';
is (81, 27, 9 ...^ 2).munch(5).join(', '), '81, 27, 9, 3, 1', "exclusive decreasing geometric sequence that couldn't hit its limit anyway";
is (2, -4, 8 ...^ 32).join(', '), '2, -4, 8, -16', 'exclusive alternating geometric sequence';
is (2, -4, 8 ...^ -32).munch(6).join(', '), '2, -4, 8, -16, 32, -64', 'exclusive alternating geometric sequence (not an exact match)';
is (1, { $_ + 2 } ...^ 9).join(', '), '1, 3, 5, 7', 'exclusive sequence with closure';
is (1 ...^ 1), (), 'empty exclusive sequence';
is (1, 1 ...^ 1), (), 'empty exclusive constant sequence';
is (1, 2 ...^ 0).munch(3), (1, 2, 3), 'empty exclusive arithmetic sequence';
is (1, 2 ...^ 0, 'xyzzy', 'plugh').[^3].join(', '), '1, 2, 3', 'exclusive sequence empty but for extra items';
is ~(1 ...^ 0), '1', 'singleton exclusive sequence';
is (4...^5).join(', '), '4', '4...^5 should parse as 4 ...^ 5 and not 4 ... ^5';
}


# RT #75698
#?rakudo skip 'junctions'
ok ?(one((-5 ... ^5).flat) == 0), '-5 ... ^5 produces just one zero';

# RT #75316
#?rakudo todo 'mysterious'
isa_ok (1...()), Failure,
'empty list on right side of sequence operator does not cause infinite loop';

# RT #73508
is (1,2,4...*)[10], 1024,
'element from list generated using infinite sequence is accessible by index';

# RT #72914
is (4 ... ^5).join(', '), '4, 3, 2, 1, 0, 1, 2, 3, 4',
'geometric sequence started in one direction and continues in the other with exclusion';

lives_ok { (1 ... 5).perl }, 'Can take .perl of sequence';
is eval((1 ... 5).perl).join(','), '1,2,3,4,5',
'eval($sequence.perl) reproduces result list';

#?rakudo todo 'Z~'
is ~((1 ... *) Z~ ('a' ... 'z')).munch(5), "1a 2b 3c 4d 5e", "Zipping two sequence in parallel";

{
is (1, 2, 4 ... 3).munch(4), (1, 2, 4, 8), "sequence that does not hit the limit";
is (1, 2, 4 ... 2), (1, 2), "sequence that aborts during LHS";

is (1, 2, 4 ... 1.5).munch(4), (1,2,4,8), "sequence that does not hit the limit";
is (1, 2, 4 ... 1), (1), "sequence that aborts during LHS";

is ~(1, -2, 4 ... 1), '1', 'geometric sequence with smaller RHS and sign change';
is ~(1, -2, 4 ... 2).munch(4), '1 -2 4 -8', 'geometric sequence with smaller RHS and sign change';
is ~(1, -2, 4 ... 3).munch(4), '1 -2 4 -8', 'geometric sequence with smaller RHS and sign change';
is ~(1, -2, 4 ... 25).munch(10), '1 -2 4 -8 16 -32 64 -128 256 -512', 'geometric sequence with sign-change and non-matching end point';

is (1, 2, 4, 5, 6 ... 2), (1, 2), "sequence that aborts during LHS, before actual calculations kick in";

is (1, 2, 4, 5, 6 ... 3).munch(6), (1,2,4,5,6,7), "sequence that aborts during LHS, before actual calculations kick in";
}

# tests for the types returned

{
my @a = 1, 2, 3 ... 100;
is @a.elems, 100, "1, 2, 3 ... 100 generates a sequence with one hundred elements...";
is @a.grep(Int).elems, 100, "... all of which are Ints";
}

{
my @a = 1.Rat, 2.Rat, 3.Rat ... 100;
is @a.elems, 100, "1.Rat, 2.Rat, 3.Rat ... 100 generates a sequence with one hundred elements...";
is @a.grep(Rat).elems, 100, "... all of which are Rats";
}

{
my @a = 1.Num, 2.Num, 3.Num ... 100;
is @a.elems, 100, "1.Num, 2.Num, 3.Num ... 100 generates a sequence with one hundred elements...";
is @a.grep(Num).elems, 100, "... all of which are Nums";
}

{
my @a = 1, 2, 4 ... 64;
is @a.elems, 7, "1, 2, 4 ... 64 generates a sequence with seven elements...";
#?rakudo todo 'types'
is @a.grep(Int).elems, @a.elems, "... all of which are Ints";
}

{
my @a = 1.Rat, 2.Rat, 4.Rat ... 64;
is @a.elems, 7, "1.Rat, 2.Rat, 4.Rat ... 64 generates a sequence with seven elements...";
is @a.grep(Rat).elems, 7, "... all of which are Rats";
}

{
my @a = 1.Num, 2.Num, 4.Num ... 64;
is @a.elems, 7, "1.Num, 2.Num, 4.Num ... 64 generates a sequence with seven elements...";
is @a.grep(Num).elems, 7, "... all of which are Nums";
}

# RT #74606
is (1, +* ... *).[^5].join('|'), (1 xx 5).join('|'),
'1, +* works for sequence';

# RT #75768
#?rakudo todo 'RT 75768'
is ~(1...10)[2...4], '3 4 5', 'can index sequence with sequence';

{
is (1, 2 ... *>=5), (1,2,3,4,5), "sequence with code on the rhs";
is (1, 2 ... *>5), (1,2,3,4,5,6), "sequence with code on the rhs";
is (1, 2 ...^ *>=5), (1,2,3,4), "exclusive sequence with code on the rhs";
is (1, 2 ...^ *>5), (1,2,3,4,5), "exclusive sequence with code on the rhs";
}

#?rakudo todo 'sequence + last'
is (1, 2 , {last if $_>=5; $_+1} ... *), (1,2,3,4,5), "sequence that lasts in the last item of lhs";

{
is (1..* ... 5), (1, 2, 3, 4, 5), '1..* ... 5';
my @fib := (0, 1, *+* ... * );
#?rakudo todo '@fib ... 8'
is (@fib ... 8), (0 , 1, 1, 2 , 3, 5, 8), '@fib ... 8';
}

# RT #78324
is (32,16,8 ...^ Rat), (32,16,8) , 'stop on a matching type';

# RT #75828
eval_dies_ok '1, 2, 3, ... 5', 'comma before sequence operator is caught';

# RT #73268
is ~(1...^*).munch(10), '1 2 3 4 5 6 7 8 9 10', 'RT #73268';

done;

# vim: ft=perl6
Something went wrong with that request. Please try again.