We only need local $? if we inline calls to DEMOLISH
[gitmo/Moose.git] / t / type_constraints / name_conflicts.t
CommitLineData
340ad0aa 1#!/usr/bin/env perl
2use strict;
3use warnings;
4use Test::More;
5use Test::Fatal;
6
7use Moose::Util::TypeConstraints;
8
9{
10 package Types;
11 use Moose::Util::TypeConstraints;
12
13 type 'Foo1';
14 subtype 'Foo2', as 'Str';
15 class_type 'Foo3';
16 role_type 'Foo4';
17
18 { package Foo5; use Moose; }
19 { package Foo6; use Moose::Role; }
20 { package IsaAttr; use Moose; has foo => (is => 'ro', isa => 'Foo7'); }
21 { package DoesAttr; use Moose; has foo => (is => 'ro', does => 'Foo8'); }
22}
23
24{
25 my $anon = 0;
26 my @checks = (
27 [1, sub { type $_[0] }, 'type'],
28 [1, sub { subtype $_[0], as 'Str' }, 'subtype'],
29 [1, sub { class_type $_[0] }, 'class_type'],
30 [1, sub { role_type $_[0] }, 'role_type'],
31 # should these two die?
32 [0, sub { eval "package $_[0]; use Moose; 1" || die $@ }, 'use Moose'],
33 [0, sub { eval "package $_[0]; use Moose::Role; 1" || die $@ }, 'use Moose::Role'],
34 [0, sub {
35 $anon++;
36 eval <<CLASS || die $@;
37 package Anon$anon;
38 use Moose;
39 has foo => (is => 'ro', isa => '$_[0]');
40 1
41CLASS
42 }, 'isa => "Thing"'],
43 [0, sub {
44 $anon++;
45 eval <<CLASS || die $@;
46 package Anon$anon;
47 use Moose;
48 has foo => (is => 'ro', does => '$_[0]');
49 1
50CLASS
51 }, 'does => "Thing"'],
52 );
53
54 sub check_conflicts {
55 my ($type_name) = @_;
56 my $type = find_type_constraint($type_name);
57 for my $check (@checks) {
58 my ($should_fail, $code, $desc) = @$check;
59
60 $should_fail = 0
61 if overriding_with_equivalent_type($type, $desc);
62 unload_class($type_name);
63
64 if ($should_fail) {
65 like(
66 exception { $code->($type_name) },
67 qr/^The type constraint '$type_name' has already been created in [\w:]+ and cannot be created again in [\w:]+/,
68 "trying to override $type_name via '$desc' should die"
69 );
70 }
71 else {
72 is(
73 exception { $code->($type_name) },
74 undef,
75 "trying to override $type_name via '$desc' should do nothing"
76 );
77 }
78 is($type, find_type_constraint($type_name), "type didn't change");
79 }
80 }
81
82 sub unload_class {
83 my ($class) = @_;
84 my $meta = Class::MOP::class_of($class);
85 return unless $meta;
86 $meta->add_package_symbol('@ISA', []);
87 $meta->remove_package_symbol('&'.$_)
88 for $meta->list_all_package_symbols('CODE');
89 undef $meta;
90 Class::MOP::remove_metaclass_by_name($class);
91 }
92
93 sub overriding_with_equivalent_type {
94 my ($type, $desc) = @_;
95 if ($type->isa('Moose::Meta::TypeConstraint::Class')) {
96 return 1 if $desc eq 'use Moose'
97 || $desc eq 'class_type'
98 || $desc eq 'isa => "Thing"';
99 }
100 if ($type->isa('Moose::Meta::TypeConstraint::Role')) {
101 return 1 if $desc eq 'use Moose::Role'
102 || $desc eq 'role_type'
103 || $desc eq 'does => "Thing"';
104 }
105 return;
106 }
107}
108
109{
110 check_conflicts($_) for map { "Foo$_" } 1..8;
111}
112
113done_testing;