use Test; plan 35; use Zef; use Zef::Config; use Zef::Client; use Zef::Distribution; my $json = q:to/META6/; { "raku":"6.c", "name":"Test::Complex::Depends", "version":"0", "auth":"github:stranger", "description":"Test hash-based depends and native depends parsing", "license":"none", "depends": [ "Zef::Client", { "from": "native", "name": { "by-distro.name": { "macosx": "mac", "win32" : "win", "linux" : "linux", "" : "unknown" } } } ], "build-depends": [ "Zef::Build" ], "test-depends": [ "Zef::Test" ], "provides": { } } META6 my $dist = Zef::Distribution.new(|Rakudo::Internals::JSON.from-json($json)); ok any($dist.depends-specs.map(*.name)) ~~ 'Zef::Client'; ok any($dist.depends-specs.map(*.from-matcher)) ~~ 'Raku'; ok any($dist.depends-specs.map(*.name)) ~~ any('mac', 'win', 'linux', 'unknown'); ok any($dist.depends-specs.map(*.from-matcher)) ~~ 'native'; with Zef::Distribution.new(|Rakudo::Internals::JSON.from-json(q:to/META6/)) -> $dist { { "raku":"6.c", "name":"Test::Complex::Depends", "version":"0", "auth":"github:stranger", "description":"Test hash-based depends and native depends parsing", "license":"none", "depends": { "runtime" : { "requires" : [ { "by-distro.name": { "win32": ["Foo::Win32_1", "Foo::Win32_2"], "linux": ["Foo::Linux_1", "Foo::Linux_2"], "" : ["Foo::Unknown_1", "Foo::Unknown_2"] } } ] } }, "provides": { } } META6 is $dist.depends-specs.elems, 2; ok any($dist.depends-specs.map(*.name)) ~~ any("Foo::Win32_1", "Foo::Linux_1", "Foo::Unknown_1"); ok any($dist.depends-specs.map(*.name)) ~~ any("Foo::Win32_2", "Foo::Linux_2", "Foo::Unknown_2"); ok any($dist.depends-specs.map(*.from-matcher)) ~~ 'Raku'; } # mixed depends types with Zef::Distribution.new(|Rakudo::Internals::JSON.from-json(q:to/META6/)) -> $dist { { "raku":"6.c", "name":"Test::Complex::Depends", "version":"0", "auth":"github:stranger", "description":"Test hash-based depends and native depends parsing", "license":"none", "build-depends" : [ "Foo::Build" ], "test-depends" : [ "Foo::Test" ], "depends": { "runtime" : { "requires" : [ { "by-distro.name": { "win32": "Win32::Runtime", "linux": "Linux::Runtime", "" : "Unknown::Runtime" } } ] }, "build" : { "requires" : [ "Foo::BuildX" ] }, "test" : { "requires" : [ "Foo::TestX" ] } }, "provides": { } } META6 is $dist.depends-specs.elems, 1; is $dist.build-depends-specs.elems, 2; is $dist.test-depends-specs.elems, 2; ok any($dist.depends-specs.map(*.name)) ~~ any("Win32::Runtime", "Linux::Runtime", "Unknown::Runtime"); ok any($dist.build-depends-specs.map(*.name)) ~~ 'Foo::Build'; ok any($dist.build-depends-specs.map(*.name)) ~~ 'Foo::BuildX'; ok any($dist.test-depends-specs.map(*.name)) ~~ 'Foo::Test'; ok any($dist.test-depends-specs.map(*.name)) ~~ 'Foo::TestX'; } with Zef::Distribution.new(|Rakudo::Internals::JSON.from-json(q:to/META6/)) -> $dist { { "raku":"6.c", "name":"Test::Complex::Depends", "version":"0", "auth":"github:stranger", "description":"Test hash-based depends and native depends parsing", "license":"none", "depends": [ "Foo", {"any": ["Bar", "Baz"]} ], "provides": { } } META6 is $dist.depends-specs()[1].specs[1].name, "Baz" or note $dist.depends-specs; } with Zef::Distribution.new(|Rakudo::Internals::JSON.from-json(q:to/META6/)) -> $dist { { "raku":"6.c", "name":"Test::Complex::Depends", "version":"0", "auth":"github:stranger", "description":"Test hash-based depends and native depends parsing", "license":"none", "depends": [ "Foo", {"any": ["Bar", "Baz"]} ], "provides": { } } META6 my class Zef::Client::Fake is Zef::Client { method list-installed(*@) { [] } } my $client = Zef::Client::Fake.CREATE; $client.depends = True; is $client.list-dependencies( Candidate.new(:$dist), )[1].specs[0].name, "Bar"; } my $guess-path = $?FILE.IO.parent.parent.child('resources/config.json'); my $config-file = $guess-path.e ?? ~$guess-path !! Zef::Config::guess-path(); my $config = Zef::Config::parse-file($config-file); my $recommendation-manager = ( Zef::Repository but role :: { method plugins(*@) { [ [ class :: does PackageRepository { method search(*@identities --> Seq) { gather for @identities -> $as { take Candidate.new(:dist(Zef::Distribution.new(:name($as))), :$as, :from) if $as ∈ ; take Candidate.new(:dist(Zef::Distribution.new(:name($as), :depends['Unsatisfiable'])), :$as, :from) if $as eq 'HasUnsatisfiableDep'; take Candidate.new(:dist(Zef::Distribution.new(:name($as), :depends['HasUnsatisfiableDep'])), :$as, :from) if $as eq 'HasTransitivelyUnsatisfiableDep'; take Candidate.new(:dist(Zef::Distribution.new(:name($as), :depends[{:any["AvailableToo", "Available"]},])), :$as, :from) if $as eq 'DependsOnAvailableTooOrAvailable'; } } }, ], ] } } ).new(:backends[]); for ( ["Available", {:any["Unavailable", "Installed"]}] => -> $prereq-candidates { is $prereq-candidates.elems, 1; is $prereq-candidates[0].dist.name, "Available"; }, [{:any["Unavailable", "Available"]},] => -> $prereq-candidates { is $prereq-candidates.elems, 1; is $prereq-candidates[0].dist.name, "Available"; }, ["Available", {:any["Unavailable", "AvailableToo"]}] => -> $prereq-candidates { is $prereq-candidates.elems, 2; is $prereq-candidates.map(*.dist.name).sort, ; }, [{:any["AvailableToo", "Available"]}, "Available"] => -> $prereq-candidates { is $prereq-candidates.elems, 1; is $prereq-candidates.map(*.dist.name).sort, ; }, ["DependsOnAvailableTooOrAvailable", "Available"] => -> $prereq-candidates { is $prereq-candidates.elems, 2; is $prereq-candidates.map(*.dist.name).sort, ; }, ["DependsOnAvailableTooOrAvailable"] => -> $prereq-candidates { is $prereq-candidates.elems, 2; is $prereq-candidates.map(*.dist.name).sort, ; }, ["Available", {:any["HasUnsatisfiableDep", "AvailableToo"]}] => -> $prereq-candidates { is $prereq-candidates.elems, 2; is $prereq-candidates.map(*.dist.name).sort, ; }, ["Available", {:any["HasTransitivelyUnsatisfiableDep", "AvailableToo"]}] => -> $prereq-candidates { is $prereq-candidates.elems, 2; is $prereq-candidates.map(*.dist.name).sort, ; }, ) -> $test { with Zef::Distribution.new( :raku<6.c>, :name, :version<0>, :auth('github:stranger'), :description('Test hash-based depends and native depends parsing'), :license, :depends($test.key), :provides{ }, ) -> $dist { my class Zef::Client::Fake is Zef::Client { method list-installed(*@) { [Candidate.new(:dist(Zef::Distribution.new(:name)))] } method logger() { class :: { method emit($) { } } } } my $client = Zef::Client::Fake.new(:$config, :$recommendation-manager); $client.depends = True; my $prereq-candidates = $client.find-prereq-candidates( Candidate.new(:$dist), ); $test.value.($prereq-candidates); } } subtest 'X::Zef::UnsatisfiableDependency' => { for ( ["Unavailable"], ["Available", "Unavailable"], ["Available", {:any["Unavailable", "Unavailable2"]}], ["Available", {:any[{:name, :from}, {:name, :from}]}], ) -> $test { with Zef::Distribution.new( :raku<6.c>, :name, :version<0>, :auth('github:stranger'), :description('Test hash-based depends and native depends parsing'), :license, :depends($test), :provides{ }, ) -> $dist { my class Zef::Client::Fake is Zef::Client { method list-installed(*@) { [Candidate.new(:dist(Zef::Distribution.new(:name)))] } method logger() { class :: { method emit($) { } } } } my $client = Zef::Client::Fake.new(:$config, :$recommendation-manager); $client.depends = True; throws-like { $client.find-prereq-candidates(Candidate.new(:$dist)) }, X::Zef::UnsatisfiableDependency; } } }