The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.
use strict;
use warnings;
use Test::More;
use Moose::Util qw(does_role);

{ package Class;
  use Moose;
  use MooseX::APIRole;

  sub foo {}
  sub bar {}

  make_api_role 'Class::API';
  Class->meta->make_immutable;
}

my $class = Class->new;
ok $class->meta->has_api_role, 'has api role';
ok does_role($class, 'Class::API'), 'class does its API role';

is_deeply [sort $class->meta->get_api_role->get_required_method_list],
          [sort qw/foo bar/],
    'got required methods';

{ package Role;
  use Moose::Role;
  use MooseX::APIRole;

  sub baz {}

  set_api_role_name('Role::API');
}


is_deeply [sort Role->meta->api_role->get_required_method_list],
          [sort qw/baz/],
    'got required methods on Role';

ok(Role->meta->has_api_role, 'Role now has an API role');

is(Role->meta->api_role->name, 'Role::API');
ok !does_role('Role', Role->meta->get_api_role), 'Role does not do its API role';

{ package Another::Role;
  use Moose::Role;

  sub quux {}
} # tests handling of non MooseX::APIRole super-roles

{ package So::Many::Roles;
  use Moose::Role;
  use MooseX::APIRole;

  sub gorch {}

  set_api_role_name('So::Many::APIs');
} # tests handling on non-vivified MooseX::APIRole roles

{ package Subclass;
  use Moose;
  use MooseX::APIRole;

  extends 'Class';
  with 'Role', 'Another::Role', 'So::Many::Roles';

  sub arbitrary_name {}

  make_api_role 'Subclass::API';
}

ok does_role('Subclass', 'Subclass::API'), 'subclass does its api';
is_deeply [sort Subclass->meta->get_api_role->get_required_method_list],
          [sort qw/foo bar baz quux gorch arbitrary_name/],
    'got required methods';

ok does_role('Subclass', 'Class::API'), q{subclass does parent's API};
ok does_role('Subclass', 'Role::API'), q{subclass does Role's API};
ok does_role('Subclass', 'So::Many::APIs'),
    q{subclass does unvivified but named API};
ok does_role('Subclass', MooseX::APIRole::Internals::role_for(Another::Role->meta)),
    q{subclass does autogenerated API role};

done_testing;