use Test;

plan 730;

### for now
sub matchcheck(*@) { 1 }

# L<S05/Backtracking control/"To force the preceding atom to do no
# backtracking">

##   Backtracking control tests
#### a* a			bazaar		y	control
ok 'bazaar' ~~ /a* a/, 'control';

#### a*: a			bazaar		n	basic
ok !('bazaar' ~~ /a*: a/), 'basic';

#### ^[a|b]*  aba		abbabbababba	y	control
ok 'abbabbababba' ~~ /^[a|b]*  aba/, 'control';

#### ^[a|b]*: aba		abbabbababba	n	outside a group
ok !('abbabbababba' ~~ /^[a|b]*: aba/), 'outside a group';

#### \d+:			123abc		y	cut on character class shortcut
ok '123abc' ~~ /\d+:/, 'cut on character class shortcut';

#### \d+:			abc		n	cut on character class shortcut
ok 'abc' !~~ /\d+:/, 'cut on character class shortcut';

#### [ if    not | ify ]	verify		y	control
ok 'verify' ~~ /[ if    not | ify ]/, 'control';

# L<S05/Backtracking control/"Backtracking over a double colon">

#### [ if :: not | ify ]	verify		n	inside a group
#?rakudo skip ':: NYI'
ok 'verify' !~~ /[ if :: not | ify ]/, 'inside a group';

####   if :: not | ify	verify		n	the default all group
#?rakudo skip ':: NYI'
ok 'verify' !~~ /  if :: not | ify/, 'the default all group';

#### [ if :  not | ify ]	verify		y	simple backtrack still works
#?pugs todo 'feature'
ok 'verify' ~~ /[ if :  not | ify ]/, 'simple backtrack still works';

#### [ if :: not | ify ] | verify	verify	y	rule continues
#?pugs todo 'feature'
#?rakudo skip ':: NYI'
ok 'verify' ~~ /[ if :: not | ify ] | verify/, 'rule continues';

# L<S05/Backtracking control/"Backtracking over a triple colon">
#### [ when     ever ] | whence	whence	y	full backtrack failure
ok 'whence' ~~ /[ when     ever ] | whence/, 'full backtrack failure';

#### [ when ::: ever ] | whence	whence	n	full backtrack failure
#?rakudo skip '::: NYI'
ok 'whence' !~~ /[ when ::: ever ] | whence/, 'full backtrack failure';

#### ab::cd | gh::ij		xyabghij	y	group cut at top
#?pugs todo 'feature'
#?rakudo skip ':: NYI'
ok 'xyabghij' ~~ /ab::cd | gh::ij/, 'group cut at top';

#### ab:::cd | gh:::ij	xyabghij	n	rule cut at top
#?rakudo skip ':: NYI'
ok 'xyabghij' !~~ /ab:::cd | gh:::ij/, 'rule cut at top';

#### [ab::cd | gh::ij]	xyabghij	y	group cut in group
#?pugs todo 'feature'
#?rakudo skip ':: NYI'
ok 'xyabghij' ~~ /[ab::cd | gh::ij]/, 'group cut in group';

#### [ab:::cd | gh:::ij]	xyabghij	n	rule cut in group
#?rakudo skip '::: NYI'
ok 'xyabghij' !~~ /[ab:::cd | gh:::ij]/, 'rule cut in group';

#### [ ab | abc ]: de	xyzabcde	n	no backtrack into group
#?rakudo todo 'unknown'
ok 'xyzabcde' !~~ /[ ab | abc ]: de/, 'no backtrack into group';

#### ( ab | abc ): de	xyzabcde	n	no backtrack into subpattern
ok 'xyzabcde' !~~ /( ab | abc ): de/, 'no backtrack into subpattern';

#### [ when <commit> ever ] | whence	whence	n	full backtrack failure
#?pugs todo 'feature'
#?rakudo skip '<commit> not implemented'
ok 'whence' !~~ /[ when <commit> ever ] | whence/, 'full backtrack failure';

#L<S05/Modifiers/"The new :ratchet modifier">

#### :ratchet a* a		bazaar		n	ratchet modifier
ok 'bazaar' !~~ /:ratchet a* a/, 'ratchet modifier';

#### :ratchet a*! a		bazaar		y	force backtracking !
ok 'bazaar' ~~ /:ratchet a*! a/, 'force backtracking !';

#L<S05/Unchanged syntactic features/"Capturing: (...)">

##   captures
#### (a.)..(..)		zzzabcdefzzz	y			basic match
ok 'zzzabcdefzzz' ~~ /(a.)..(..)/, 'basic match';

#### (a.)..(..)		zzzabcdefzzz	/mob: <abcdef @ 3>/	basic $0
ok ('zzzabcdefzzz' ~~ /(a.)..(..)/) && matchcheck($/, q/mob: <abcdef @ 3>/), 'basic $0';

#### (a.)..(..)		zzzabcdefzzz	/mob 0: <ab @ 3>/	basic $1
ok ('zzzabcdefzzz' ~~ /(a.)..(..)/) && matchcheck($/, q/mob 0: <ab @ 3>/), 'basic $1';

#### (a.)..(..)		zzzabcdefzzz	/mob 1: <ef @ 7>/	basic $2
ok ('zzzabcdefzzz' ~~ /(a.)..(..)/) && matchcheck($/, q/mob 1: <ef @ 7>/), 'basic $2';

#### (a(b(c))(d))		abcd		y			nested match
ok 'abcd' ~~ /(a(b(c))(d))/, 'nested match';

#### (a(b(c))(d))		abcd		/mob: <abcd @ 0>/	nested match
ok ('abcd' ~~ /(a(b(c))(d))/) && matchcheck($/, q/mob: <abcd @ 0>/), 'nested match';

#### (a(b(c))(d))		abcd		/mob 0: <abcd @ 0>/	nested match
ok ('abcd' ~~ /(a(b(c))(d))/) && matchcheck($/, q/mob 0: <abcd @ 0>/), 'nested match';

#### (a(b(c))(d))		abcd		/mob 0 0: <bc @ 1>/	nested match
ok ('abcd' ~~ /(a(b(c))(d))/) && matchcheck($/, q/mob 0 0: <bc @ 1>/), 'nested match';

#### (a(b(c))(d))		abcd		/mob 0 0 0: <c @ 2>/	nested match
ok ('abcd' ~~ /(a(b(c))(d))/) && matchcheck($/, q/mob 0 0 0: <c @ 2>/), 'nested match';

#### (a(b(c))(d))		abcd		/mob 0 1: <d @ 3>/	nested match
ok ('abcd' ~~ /(a(b(c))(d))/) && matchcheck($/, q/mob 0 1: <d @ 3>/), 'nested match';

#### ((\w+)+)		abcd		/mob: <abcd @ 0>/	nested match
ok ('abcd' ~~ /((\w+)+)/) && matchcheck($/, q/mob: <abcd @ 0>/), 'nested match';

#### ((\w+)+)		abcd		/mob 0: <abcd @ 0>/	nested match
ok ('abcd' ~~ /((\w+)+)/) && matchcheck($/, q/mob 0: <abcd @ 0>/), 'nested match';

#### ((\w+)+)		abcd		/mob 0 0 0: <abcd @ 0>/	nested match
ok ('abcd' ~~ /((\w+)+)/) && matchcheck($/, q/mob 0 0 0: <abcd @ 0>/), 'nested match';

#### ((\w+)+)	ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz	/mob: <ABCD/	nested match
ok ('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' ~~ /((\w+)+)/) && matchcheck($/, q/mob: <ABCD/), 'nested match';

#### ((\w+)+)	ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz	/mob 0: <ABCD/	nested match
ok ('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' ~~ /((\w+)+)/) && matchcheck($/, q/mob 0: <ABCD/), 'nested match';

#### ((\w+)+)	ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz	/mob 0 0 0: <ABCD/	nested match
ok ('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' ~~ /((\w+)+)/) && matchcheck($/, q/mob 0 0 0: <ABCD/), 'nested match';

#### (a) [ (bc) (d) | .* (ef) ] .* (g)	abcdefg	/mob 0: <a @ 0>/	alt subpattern before group
ok ('abcdefg' ~~ /(a) [ (bc) (d) | .* (ef) ] .* (g)/) && matchcheck($/, q/mob 0: <a @ 0>/), 'alt subpattern before group';

#### (a) [ (bc) (d) | .* (ef) ] .* (g)	abcdefg	/mob 1: <bc @ 1>/	alt subpattern in group
ok ('abcdefg' ~~ /(a) [ (bc) (d) | .* (ef) ] .* (g)/) && matchcheck($/, q/mob 1: <bc @ 1>/), 'alt subpattern in group';

#### (a) [ (bc) (d) | .* (ef) ] .* (g)	abcdefg	/mob 2: <d @ 3>/	alt subpattern in group
ok ('abcdefg' ~~ /(a) [ (bc) (d) | .* (ef) ] .* (g)/) && matchcheck($/, q/mob 2: <d @ 3>/), 'alt subpattern in group';

#### (a) [ (bc) (d) | .* (ef) ] .* (g)	abcdefg	/mob 3: <g @ 6>/	alt subpattern after group
ok ('abcdefg' ~~ /(a) [ (bc) (d) | .* (ef) ] .* (g)/) && matchcheck($/, q/mob 3: <g @ 6>/), 'alt subpattern after group';

#### (a) [ (bc) (x) | .* (ef) ] .* (g)	abcdefg	/mob 1: <ef @ 4>/	2nd alt subpattern in group
ok ('abcdefg' ~~ /(a) [ (bc) (x) | .* (ef) ] .* (g)/) && matchcheck($/, q/mob 1: <ef @ 4>/), '2nd alt subpattern in group';

#### (a) [ (bc) (x) | .* (ef) ] .* (g)	abcdefg	/mob 3: <g @ 6>/	2nd alt subpattern after group
ok ('abcdefg' ~~ /(a) [ (bc) (x) | .* (ef) ] .* (g)/) && matchcheck($/, q/mob 3: <g @ 6>/), '2nd alt subpattern after group';

#### ( (.) )*				abc	/mob 0 1 0: <b @ 1>/	nested repeated captures
ok ('abc' ~~ /( (.) )*/) && matchcheck($/, q/mob 0 1 0: <b @ 1>/), 'nested repeated captures';

#### [ (.) ]*				abc	/mob 0 1: <b @ 1>/	nested repeated captures
ok ('abc' ~~ /[ (.) ]*/) && matchcheck($/, q/mob 0 1: <b @ 1>/), 'nested repeated captures';

#### ( [.] )*				abc	/mob 0 1: <b @ 1>/	nested repeated captures
ok ('abc' ~~ /( [.] )*/) && matchcheck($/, q/mob 0 1: <b @ 1>/), 'nested repeated captures';

#### (.) (.) $7=(.) (.) $4=(.)		abcdefg	/mob 0: <a @ 0>/	numbered aliases $1
ok ('abcdefg' ~~ /(.) (.) $7=(.) (.) $4=(.)/) && matchcheck($/, q/mob 0: <a @ 0>/), 'numbered aliases $1';

#### (.) (.) $7=(.) (.) $4=(.)		abcdefg	/mob 1: <b @ 1>/	numbered aliases $2
ok ('abcdefg' ~~ /(.) (.) $7=(.) (.) $4=(.)/) && matchcheck($/, q/mob 1: <b @ 1>/), 'numbered aliases $2';

#### (.) (.) $7=(.) (.) $4=(.)		abcdefg	/mob 7: <c @ 2>/	numbered aliases $7
ok ('abcdefg' ~~ /(.) (.) $7=(.) (.) $4=(.)/) && matchcheck($/, q/mob 7: <c @ 2>/), 'numbered aliases $7';

#### (.) (.) $7=(.) (.) $4=(.)		abcdefg	/mob 8: <d @ 3>/	numbered aliases $8
ok ('abcdefg' ~~ /(.) (.) $7=(.) (.) $4=(.)/) && matchcheck($/, q/mob 8: <d @ 3>/), 'numbered aliases $8';

#### (.) (.) $7=(.) (.) $4=(.)		abcdefg	/mob 4: <e @ 4>/	numbered aliases $4
ok ('abcdefg' ~~ /(.) (.) $7=(.) (.) $4=(.)/) && matchcheck($/, q/mob 4: <e @ 4>/), 'numbered aliases $4';

#### $1=[ (.) (.) (.) ] (.)			abcdefg	/mob 1: <abc @ 0>/	perl5 numbered captures $1
ok ('abcdefg' ~~ /$1=[ (.) (.) (.) ] (.)/) && matchcheck($/, q/mob 1: <abc @ 0>/), 'perl5 numbered captures $1';

#### $1=[ (.) (.) (.) ] (.)			abcdefg	/mob 2: <a @ 0>/	perl5 numbered captures $1
ok ('abcdefg' ~~ /$1=[ (.) (.) (.) ] (.)/) && matchcheck($/, q/mob 2: <a @ 0>/), 'perl5 numbered captures $1';

#### $1=[ (.) (.) (.) ] (.)			abcdefg	/mob 3: <b @ 1>/	perl5 numbered captures $1
ok ('abcdefg' ~~ /$1=[ (.) (.) (.) ] (.)/) && matchcheck($/, q/mob 3: <b @ 1>/), 'perl5 numbered captures $1';

#### $1=[ (.) (.) (.) ] (.)			abcdefg	/mob 4: <c @ 2>/	perl5 numbered captures $1
ok ('abcdefg' ~~ /$1=[ (.) (.) (.) ] (.)/) && matchcheck($/, q/mob 4: <c @ 2>/), 'perl5 numbered captures $1';

#### $1=[ (.) (.) (.) ] (.)			abcdefg	/mob 5: <d @ 3>/	perl5 numbered captures $1
ok ('abcdefg' ~~ /$1=[ (.) (.) (.) ] (.)/) && matchcheck($/, q/mob 5: <d @ 3>/), 'perl5 numbered captures $1';

#### :s $<key>=[\w+] \= $<val>=[\S+]	 abc = 123	/mob<key>: <abc @ 1>/	named capture
#?pugs todo 'feature'
ok (' abc = 123' ~~ /:s $<key>=[\w+] \= $<val>=[\S+]/) && matchcheck($/, q/mob<key>: <abc @ 1>/), 'named capture';

#### :s $<key>=[\w+] \= $<val>=[\S+]	 abc = 123	/mob<val>: <123 @ 7>/	named capture
#?pugs todo 'feature'
ok (' abc = 123' ~~ /:s $<key>=[\w+] \= $<val>=[\S+]/) && matchcheck($/, q/mob<val>: <123 @ 7>/), 'named capture';

#### :s (\w+) $<foo>=(\w+) (\w+)		abc def ghi	/mob<foo>: <def @ 4>/	mixing named and unnamed capture
#?pugs todo 'feature'
ok ('abc def ghi' ~~ /:s (\w+) $<foo>=(\w+) (\w+)/) && matchcheck($/, q/mob<foo>: <def @ 4>/), 'mixing named and unnamed capture';

#### :s (\w+) $<foo>=(\w+) (\w+)		abc def ghi	/mob 1: <ghi @ 8>/	mixing named and unnamed capture
#?pugs todo 'feature'
ok ('abc def ghi' ~~ /:s (\w+) $<foo>=(\w+) (\w+)/) && matchcheck($/, q/mob 1: <ghi @ 8>/), 'mixing named and unnamed capture';

#### <alpha> [ \- <alpha> ]?			abc def ghi	/mob<alpha> 0: <a @ 0>/	multiple subrule captures in same scope
#?pugs todo 'feature'
ok ('abc def ghi' ~~ /<alpha> [ \- <alpha> ]?/) && matchcheck($/, q/mob<alpha> 0: <a @ 0>/), 'multiple subrule captures in same scope';

#### [(.)$0]+				bookkeeper	y			backreference
#?pugs todo 'feature'
ok 'bookkeeper' ~~ /[(.)$0]+/, 'backreference';

#### (\w+) <+ws> $0				hello hello	y			backreference at end of string
#?pugs todo 'feature'
ok 'hello hello' ~~ /(\w+) <+ws> $0/, 'backreference at end of string';

#### [(.)$0]+				bookkeeper	/mob 0 0: <o @ 1>/	backref $1
#?pugs todo 'feature'
ok ('bookkeeper' ~~ /[(.)$0]+/) && matchcheck($/, q/mob 0 0: <o @ 1>/), 'backref $1';

#### [(.)$0]+				bookkeeper	/mob 0 1: <k @ 3>/	backref $1
#?pugs todo 'feature'
ok ('bookkeeper' ~~ /[(.)$0]+/) && matchcheck($/, q/mob 0 1: <k @ 3>/), 'backref $1';

#### [(.)$0]+				bookkeeper	/mob 0 2: <e @ 5>/	backref $1
#?pugs todo 'feature'
ok ('bookkeeper' ~~ /[(.)$0]+/) && matchcheck($/, q/mob 0 2: <e @ 5>/), 'backref $1';

#### (.)*x					123x		/mob: <123x @ 0>/	repeated dot capture
#?pugs todo 'feature'
ok ('123x' ~~ /(.)*x/) && matchcheck($/, q/mob: <123x @ 0>/), 'repeated dot capture';


#### $<key>=<alpha>				12ab34		/mob<key>: <a @ 2>/	alias capture
ok (