<commit_before>use v6;

# L<S10/Packages>

use Test;

plan 47;

regex fairly_conclusive_platform_error {:i ^\N*<<Null?>>}

regex likely_perl6_not_found_err
    {:i ^\N*<<not>>\N*<<[f[i|ou]nd|located?|access[ed]?]>>}

package Empty {}
package AlsoEmpty::Nested {}

package Simple {
    enum B <a>;
    class Bar {method baz {'hi'}};
    our $forty_two = 42;
}

is Simple::Bar.new.baz, 'hi', 'class test';

#?rakudo todo 'ticket uses role; RT #62900'
{
    is  eval('~AlsoEmpty'), 'AlsoEmpty()',
        'autovivification(?) for nested packages'
}

#?rakudo todo 'RT #65404'
{
    lives_ok {Empty.perl ne "tbd"}, 'test for working .perl method'
}

# change to match likely error (top of file) when passes
{
    eval_dies_ok 'Empty::no_such_sub()', 'Non-existent sub through package';
}

# Not sure whether you should be able to access something in package this way
# might change to match likely error (top of file) when passes
#?rakudo todo 'RT #63432'
{
    eval_dies_ok 'Empty.no_such_sub_or_prop',
                 'Non-existent method with package';
}

#?rakudo todo 'RT #63826'
{
    enum SimpleB <a>; # useful for fudging success
    is eval('Simple::B::a'), 0, 'enum in package'
}

# more sophisticated variants of test exist elsewhere - but seems basic ...
#?rakudo skip 'RT #59484'
{
    is  eval('package Simp2 {sub pkg { $?PACKAGE }}; Simp2::pkg'),
        'Simp2', 'access to $?PACKAGE variable'
}

{
    lives_ok {Simple::Bar.new.WHO}, 'some WHO implementation';
    #?rakudo skip 'ticket based only on class... RT #60446'
    is ~(Simple::Bar.new.WHO), 'Simple::Bar',
        'WHO implementation with longname';
}

lives_ok {package A1 { role B1 {}; class C1 does A1::B1 {}} },
    'can refer to role using package';

#?rakudo todo 'ticket based on module; RT #63510'
{
    eval_lives_ok '{package A2 { role B2 {}; class C2 does B2 {} }}',
        'since role is in package should not need package name';
}

{
    my $x;

    eval '$x = RT64828g; grammar RT64828g {}';
    ok  $!  ~~ Exception, 'reference to grammar before definition dies';
    #?rakudo todo 'RT #64828'
    ok "$!" ~~ / RT64828g /, 'error message mentions the undefined grammar';

    eval '$x = RT64828m; module RT64828m {}';
    ok  $!  ~~ Exception, 'reference to module before definition dies';
    #?rakudo todo 'RT #64828'
    ok "$!" ~~ / RT64828m /, 'error message mentions the undefined module';

    eval '$x = RT64828r; role RT64828r {}';
    ok  $!  ~~ Exception, 'reference to role before definition dies';
    #?rakudo todo 'RT #64828'
    ok "$!" ~~ / RT64828r /, 'error message mentions the undefined role';

    eval '$x = RT64828c; class RT64828c {}';
    ok  $!  ~~ Exception, 'reference to class before definition dies';
    ok "$!" ~~ / RT64828c /, 'error message mentions the undefined class';

    eval '$x = RT64828p; package RT64828p {}';
    ok  $!  ~~ Exception, 'reference to package before definition dies';
    #?rakudo todo 'RT #64828'
    ok "$!" ~~ / RT64828p /, 'error message mentions the undefined package';
}

#?rakudo todo 'ticket based on class(es) not package; RT #65022'
{
    eval_lives_ok '{
        package C1Home { class Baz {} };
        package C2Home { class Baz {} }
    }', 'two different packages should be two different Baz';

    eval_lives_ok '{
        package E1Home { enum EHomeE <a> };
        package E2Home { role EHomeE {}; class EHomeC does E2Home::EHomeE {} }
    }', 'two different packages should be two different EHomeE';        
}

# making test below todo causes trouble right now ...
{
    eval_lives_ok 'package InternalCall { sub foo() { return 42 }; foo() }',
        'call of method defined in package';
}

#?rakudo todo 'RT #64606'
{
    eval_lives_ok 'package DoMap {my @a = map { $_ }, (1, 2, 3)}}',
        'map in package';
}

my $outer_lex = 17;
{
    package RetOuterLex {sub outer_lex_val { $outer_lex } };
    is eval('RetOuterLex::outer_lex_val()'), $outer_lex, 'use outer lexical'
}

our $outer_package = 19;
#?rakudo todo 'ticket used class; RT #63588'
{
    package RetOuterPack {sub outer_pack_val { $outer_package } };
    is  eval('RetOuterPack::outer_pack_val()'), $outer_package,
        'use outer package var';

    eval_lives_ok
        'package ModOuterPack { $outer_package = 3 }; $outer_package',
        'Should be able to update outer package var';
}

# change tests to match likely error (top of file) when they pass
#?rakudo todo 'RT #64204'
{
    eval 'my $x = ::P';
    ok  ~$! !~~ /<fairly_conclusive_platform_error>/, 
        'simple package case that should not blow platform';

    eval 'A::B';
    ok  ~$! ~~ /<likely_perl6_not_found_err>/,
        'another simple package case that should not blow platform';
}

#?rakudo skip 'RT #64606'
eval_lives_ok q' module MapTester { (1, 2, 3).map: { $_ } } ', 
              'map works in a module (RT #64606)';

# used to be a  pugs regression
{
    BEGIN { @*INC.push: 't/spec/packages' }
    use ArrayInit;
    my $first_call = array_init();
    is array_init(), $first_call,
       'array initialization works fine in imported subs';
}

# RT #68290
{
    eval_dies_ok q[class A { sub a { say "a" }; sub a { say "a" } }],
                 'sub redefined in class dies';
    eval_dies_ok q[package P { sub p { say "p" }; sub p { say "p" } }],
                 'sub redefined in package dies';
    eval_dies_ok q[module M { sub m { say "m" }; sub m { say "m" } }],
                 'sub redefined in module dies';
    #?rakudo 2 skip 'RT #68290'
    eval_dies_ok q[grammar B { token b { 'b' }; token b { 'b' } };],
                 'token redefined in grammar dies';
    eval_dies_ok q[class C { method c { say "c" }; method c { say "c" } }],
                 'method redefined in class dies';
}

#?rakudo todo 'RT #64688'
{
    eval_lives_ok 'class RT64688_c1;use Test', 'use after class line';
    eval_lives_ok 'class RT64688_c1 { use Test }', 'use in class block';
    eval_lives_ok 'module RT64688_m1;use Test', 'use after module line';
    eval_lives_ok 'module RT64688_m2 { use Test }', 'use in module block';
    eval_lives_ok 'package RT64688_p1;use Test', 'use after package line';
    eval_lives_ok 'package RT64688_p2 { use Test }', 'use in package block';
    eval_lives_ok 'grammar RT64688_g1;use Test', 'use after grammar line';
    eval_lives_ok 'grammar RT64688_g2 { use Test }', 'use in grammar block';
    eval_lives_ok 'role RT64688_r1;use Test', 'use after role line';
    eval_lives_ok 'role RT64688_r2 { use Test }', 'use in role block';
}

# vim: ft=perl6<commit_msg>[t/spec] fudge S10-packages/basic.t for rakudo<commit_after>use v6;

# L<S10/Packages>

use Test;

plan 47;

#?rakudo emit #
regex fairly_conclusive_platform_error {:i ^\N*<<Null?>>}

#?rakudo emit #
regex likely_perl6_not_found_err {:i ^\N*<<not>>\N*<<[f[i|ou]nd|located?|access[ed]?]>>}

package Empty {}
package AlsoEmpty::Nested {}

package Simple {
    #?rakudo emit #
    enum B <a>;
    #?rakudo emit #
    class Bar {method baz {'hi'}};
    our $forty_two = 42;
}

#?rakudo skip 'nested packages'
is Simple::Bar.new.baz, 'hi', 'class test';

#?rakudo skip 'ticket uses role; RT #62900'
{
    is  eval('~AlsoEmpty'), 'AlsoEmpty()',
        'autovivification(?) for nested packages'
}

#?rakudo skip 'RT #65404'
{
    lives_ok {Empty.perl ne "tbd"}, 'test for working .perl method'
}

# change to match likely error (top of file) when passes
{
    eval_dies_ok 'Empty::no_such_sub()', 'Non-existent sub through package';
}

# Not sure whether you should be able to access something in package this way
# might change to match likely error (top of file) when passes
{
    eval_dies_ok 'Empty.no_such_sub_or_prop',
                 'Non-existent method with package';
}

#?rakudo todo 'RT #63826'
{
    enum SimpleB <a>; # useful for fudging success
    is eval('Simple::B::a'), 0, 'enum in package'
}

# more sophisticated variants of test exist elsewhere - but seems basic ...
#?rakudo skip 'RT #59484'
{
    is  eval('package Simp2 {sub pkg { $?PACKAGE }}; Simp2::pkg'),
        'Simp2', 'access to $?PACKAGE variable'
}

{
    #?rakudo todo 'WHO'
    lives_ok {Simple::Bar.new.WHO}, 'some WHO implementation';
    #?rakudo skip 'ticket based only on class... RT #60446'
    is ~(Simple::Bar.new.WHO), 'Simple::Bar',
        'WHO implementation with longname';
}

#?rakudo skip 'role in package'
eval_lives_ok 'package A1 { role B1 {}; class C1 does A1::B1 {}} ',
    'can refer to role using package';

{
    eval_lives_ok '{package A2 { role B2 {}; class C2 does B2 {} }}',
        'since role is in package should not need package name';
}

{
    my $x;

    eval '$x = RT64828g; grammar RT64828g {}';
    ok  $!  ~~ Exception, 'reference to grammar before definition dies';
    ok "$!" ~~ / RT64828g /, 'error message mentions the undefined grammar';

    eval '$x = RT64828m; module RT64828m {}';
    ok  $!  ~~ Exception, 'reference to module before definition dies';
    ok "$!" ~~ / RT64828m /, 'error message mentions the undefined module';

    eval '$x = RT64828r; role RT64828r {}';
    ok  $!  ~~ Exception, 'reference to role before definition dies';
    ok "$!" ~~ / RT64828r /, 'error message mentions the undefined role';

    eval '$x = RT64828c; class RT64828c {}';
    ok  $!  ~~ Exception, 'reference to class before definition dies';
    ok "$!" ~~ / RT64828c /, 'error message mentions the undefined class';

    eval '$x = RT64828p; package RT64828p {}';
    ok  $!  ~~ Exception, 'reference to package before definition dies';
    ok "$!" ~~ / RT64828p /, 'error message mentions the undefined package';
}

#?rakudo todo 'ticket based on class(es) not package; RT #65022'
{
    eval_lives_ok '{
        package C1Home { class Baz {} };
        package C2Home { class Baz {} }
    }', 'two different packages should be two different Baz';

    eval_lives_ok '{
        package E1Home { enum EHomeE <a> };
        package E2Home { role EHomeE {}; class EHomeC does E2Home::EHomeE {} }
    }', 'two different packages should be two different EHomeE';        
}

# making test below todo causes trouble right now ...
{
    eval_lives_ok 'package InternalCall { sub foo() { return 42 }; foo() }',
        'call of method defined in package';
}

#?rakudo todo 'RT #64606'
{
    eval_lives_ok 'package DoMap {my @a = map { $_ }, (1, 2, 3)}}',
        'map in package';
}

my $outer_lex = 17;
{
    package RetOuterLex {sub outer_lex_val { $outer_lex } };
    is eval('RetOuterLex::outer_lex_val()'), $outer_lex, 'use outer lexical'
}

our $outer_package = 19;
{
    package RetOuterPack {sub outer_pack_val { $outer_package } };
    is  eval('RetOuterPack::outer_pack_val()'), $outer_package,
        'use outer package var';

    eval_lives_ok
        'my $outer; package ModOuterPack { $outer= 3 }; $outer',
        'Should be able to update outer package var';
}

# change tests to match likely error (top of file) when they pass
#?rakudo skip 'regex declarations; RT 64204'
{
    eval 'my $x = ::P';
    ok  ~$! !~~ /<fairly_conclusive_platform_error>/, 
        'simple package case that should not blow platform';

    eval 'A::B';
    ok  ~$! ~~ /<likely_perl6_not_found_err>/,
        'another simple package case that should not blow platform';
}

#?rakudo skip 'RT #64606'
eval_lives_ok q' module MapTester { (1, 2, 3).map: { $_ } } ', 
              'map works in a module (RT #64606)';

# used to be a  pugs regression
{
    BEGIN { @*INC.push: 't/spec/packages' }
    use ArrayInit;
    my $first_call = array_init();
    is array_init(), $first_call,
       'array initialization works fine in imported subs';
}

# RT #68290
{
    #?rakudo 3 todo 'RT 68290'
    eval_dies_ok q[class A { sub a { say "a" }; sub a { say "a" } }],
                 'sub redefined in class dies';
    eval_dies_ok q[package P { sub p { say "p" }; sub p { say "p" } }],
                 'sub redefined in package dies';
    eval_dies_ok q[module M { sub m { say "m" }; sub m { say "m" } }],
                 'sub redefined in module dies';
    #?rakudo 2 skip 'RT #68290'
    eval_dies_ok q[grammar B { token b { 'b' }; token b { 'b' } };],
                 'token redefined in grammar dies';
    eval_dies_ok q[class C { method c { say "c" }; method c { say "c" } }],
                 'method redefined in class dies';
}

{
    eval_lives_ok 'class RT64688_c1;use Test', 'use after class line';
    #?rakudo todo 'RT #64688'
    eval_lives_ok 'class RT64688_c1 { use Test }', 'use in class block';
    eval_lives_ok 'module RT64688_m1;use Test', 'use after module line';
    #?rakudo todo 'RT #64688'
    eval_lives_ok 'module RT64688_m2 { use Test }', 'use in module block';
    eval_lives_ok 'package RT64688_p1;use Test', 'use after package line';
    #?rakudo todo 'RT #64688'
    eval_lives_ok 'package RT64688_p2 { use Test }', 'use in package block';
    eval_lives_ok 'grammar RT64688_g1;use Test', 'use after grammar line';
    #?rakudo todo 'RT #64688'
    eval_lives_ok 'grammar RT64688_g2 { use Test }', 'use in grammar block';
    eval_lives_ok 'role RT64688_r1;use Test', 'use after role line';
    #?rakudo todo 'RT #64688'
    eval_lives_ok 'role RT64688_r2 { use Test }', 'use in role block';
}

# vim: ft=perl6
{'fraction_non_alphanumeric': 0.13704350466934934, 'fraction_numerical': 0.04153063548705489, 'mean_word_length': 3.1499684940138626, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2806863', 'n_tokens_mistral': 4962, 'n_tokens_neox': 4508, 'n_words': 1497}