Require Dist::Zilla 4.200016+
[gitmo/Moose.git] / t / native_traits / trait_string.t
CommitLineData
e3c07b19 1#!/usr/bin/perl
2
3use strict;
4use warnings;
5
8b9641b8 6use lib 't/lib';
7
e7724627 8use Moose ();
2c963694 9use Moose::Util::TypeConstraints;
8b9641b8 10use NoInlineAttribute;
a28e50e4 11use Test::More;
b10dde3a 12use Test::Fatal;
e7724627 13use Test::Moose;
e3c07b19 14
e3c07b19 15{
e7724627 16 my %handles = (
17 inc => 'inc',
18 append => 'append',
19 append_curried => [ append => '!' ],
20 prepend => 'prepend',
21 prepend_curried => [ prepend => '-' ],
22 replace => 'replace',
23 replace_curried => [ replace => qr/(.)$/, sub { uc $1 } ],
24 chop => 'chop',
25 chomp => 'chomp',
26 clear => 'clear',
27 match => 'match',
28 match_curried => [ match => qr/\D/ ],
29 length => 'length',
30 substr => 'substr',
31 substr_curried_1 => [ substr => (1) ],
32 substr_curried_2 => [ substr => ( 1, 3 ) ],
33 substr_curried_3 => [ substr => ( 1, 3, 'ong' ) ],
e3c07b19 34 );
e7724627 35
36 my $name = 'Foo1';
37
38 sub build_class {
39 my %attr = @_;
40
41 my $class = Moose::Meta::Class->create(
42 $name++,
43 superclasses => ['Moose::Object'],
44 );
45
8b9641b8 46 my @traits = 'String';
47 push @traits, 'NoInlineAttribute'
48 if delete $attr{no_inline};
49
e7724627 50 $class->add_attribute(
51 _string => (
8b9641b8 52 traits => \@traits,
e7724627 53 is => 'rw',
54 isa => 'Str',
55 default => q{},
56 handles => \%handles,
57 clearer => '_clear_string',
58 %attr,
59 ),
60 );
61
62 return ( $class->name, \%handles );
63 }
e3c07b19 64}
65
e7724627 66{
67 run_tests(build_class);
68 run_tests( build_class( lazy => 1, default => q{} ) );
cf0da4e2 69 run_tests( build_class( trigger => sub { } ) );
8b9641b8 70 run_tests( build_class( no_inline => 1 ) );
2c963694 71
72 # Will force the inlining code to check the entire hashref when it is modified.
73 subtype 'MyStr', as 'Str', where { 1 };
74
75 run_tests( build_class( isa => 'MyStr' ) );
76
77 coerce 'MyStr', from 'Str', via { $_ };
78
79 run_tests( build_class( isa => 'MyStr', coerce => 1 ) );
e7724627 80}
81
82sub run_tests {
83 my ( $class, $handles ) = @_;
84
85 can_ok( $class, $_ ) for sort keys %{$handles};
86
87 with_immutable {
88 my $obj = $class->new();
89
90 is( $obj->length, 0, 'length returns zero' );
91
92 $obj->_string('a');
93 is( $obj->length, 1, 'length returns 1 for new string' );
94
b10dde3a 95 like( exception { $obj->length(42) }, qr/Cannot call length with any arguments/, 'length throws an error when an argument is passed' );
e7724627 96
7f5ec80d 97 is( $obj->inc, 'b', 'inc returns new value' );
e7724627 98 is( $obj->_string, 'b', 'a becomes b after inc' );
99
b10dde3a 100 like( exception { $obj->inc(42) }, qr/Cannot call inc with any arguments/, 'inc throws an error when an argument is passed' );
e7724627 101
7f5ec80d 102 is( $obj->append('foo'), 'bfoo', 'append returns new value' );
e7724627 103 is( $obj->_string, 'bfoo', 'appended to the string' );
104
b10dde3a 105 like( exception { $obj->append( 'foo', 2 ) }, qr/Cannot call append with more than 1 argument/, 'append throws an error when two arguments are passed' );
e7724627 106
107 $obj->append_curried;
108 is( $obj->_string, 'bfoo!', 'append_curried appended to the string' );
109
b10dde3a 110 like( exception { $obj->append_curried('foo') }, qr/Cannot call append with more than 1 argument/, 'append_curried throws an error when two arguments are passed' );
e7724627 111
112 $obj->_string("has nl$/");
7f5ec80d 113 is( $obj->chomp, 1, 'chomp returns number of characters removed' );
e7724627 114 is( $obj->_string, 'has nl', 'chomped string' );
115
7f5ec80d 116 is( $obj->chomp, 0, 'chomp returns number of characters removed' );
e7724627 117 is(
118 $obj->_string, 'has nl',
119 'chomp is a no-op when string has no line ending'
120 );
e3c07b19 121
b10dde3a 122 like( exception { $obj->chomp(42) }, qr/Cannot call chomp with any arguments/, 'chomp throws an error when an argument is passed' );
e3c07b19 123
7f5ec80d 124 is( $obj->chop, 'l', 'chop returns character removed' );
e7724627 125 is( $obj->_string, 'has n', 'chopped string' );
e3c07b19 126
b10dde3a 127 like( exception { $obj->chop(42) }, qr/Cannot call chop with any arguments/, 'chop throws an error when an argument is passed' );
e3c07b19 128
e7724627 129 $obj->_string('x');
7f5ec80d 130 is( $obj->prepend('bar'), 'barx', 'prepend returns new value' );
e7724627 131 is( $obj->_string, 'barx', 'prepended to string' );
e3c07b19 132
e7724627 133 $obj->prepend_curried;
134 is( $obj->_string, '-barx', 'prepend_curried prepended to string' );
e3c07b19 135
7f5ec80d 136 is(
137 $obj->replace( qr/([ao])/, sub { uc($1) } ),
138 '-bArx',
139 'replace returns new value'
140 );
141
e7724627 142 is(
143 $obj->_string, '-bArx',
144 'substitution using coderef for replacement'
145 );
e3c07b19 146
e7724627 147 $obj->replace( qr/A/, 'X' );
148 is(
149 $obj->_string, '-bXrx',
150 'substitution using string as replacement'
151 );
e3c07b19 152
5394a1c7 153 $obj->_string('foo');
154 $obj->replace( qr/oo/, q{} );
155
156 is( $obj->_string, 'f',
157 'replace accepts an empty string as second argument' );
158
159 $obj->replace( q{}, 'a' );
160
161 is( $obj->_string, 'af',
162 'replace accepts an empty string as first argument' );
163
b10dde3a 164 like( exception { $obj->replace( {}, 'x' ) }, qr/The first argument passed to replace must be a string or regexp reference/, 'replace throws an error when the first argument is not a string or regexp' );
e3c07b19 165
b10dde3a 166 like( exception { $obj->replace( qr/x/, {} ) }, qr/The second argument passed to replace must be a string or code reference/, 'replace throws an error when the first argument is not a string or regexp' );
e3c07b19 167
e7724627 168 $obj->_string('Moosex');
169 $obj->replace_curried;
170 is( $obj->_string, 'MooseX', 'capitalize last' );
e3c07b19 171
e7724627 172 $obj->_string('abcdef');
e3c07b19 173
e7724627 174 is_deeply(
175 [ $obj->match(qr/([az]).*([fy])/) ], [ 'a', 'f' ],
176 'match -barx against /[aq]/ returns matches'
177 );
59de9de4 178
5394a1c7 179 is_deeply(
180 [ $obj->match(qr/([az]).*([fy])/) ], [ 'a', 'f' ],
181 'match -barx against /[aq]/ returns matches'
182 );
183
e7724627 184 ok(
185 scalar $obj->match('b'),
186 'match with string as argument returns true'
187 );
59de9de4 188
5394a1c7 189 ok(
190 scalar $obj->match(q{}),
191 'match with empty string as argument returns true'
192 );
193
b10dde3a 194 like( exception { $obj->match }, qr/Cannot call match without at least 1 argument/, 'match throws an error when no arguments are passed' );
59de9de4 195
b10dde3a 196 like( exception { $obj->match( {} ) }, qr/The argument passed to match must be a string or regexp reference/, 'match throws an error when an invalid argument is passed' );
59de9de4 197
e7724627 198 $obj->_string('1234');
199 ok( !$obj->match_curried, 'match_curried returns false' );
e3c07b19 200
e7724627 201 $obj->_string('one two three four');
202 ok( $obj->match_curried, 'match curried returns true' );
e3c07b19 203
e7724627 204 $obj->clear;
205 is( $obj->_string, q{}, 'clear' );
d50fc84a 206
b10dde3a 207 like( exception { $obj->clear(42) }, qr/Cannot call clear with any arguments/, 'clear throws an error when an argument is passed' );
d50fc84a 208
e7724627 209 $obj->_string('some long string');
210 is(
211 $obj->substr(1), 'ome long string',
212 'substr as getter with one argument'
213 );
214
215 $obj->_string('some long string');
216 is(
217 $obj->substr( 1, 3 ), 'ome',
218 'substr as getter with two arguments'
219 );
220
7f5ec80d 221 is(
222 $obj->substr( 1, 3, 'ong' ),
223 'ome',
224 'substr as setter returns replaced string'
225 );
e7724627 226
227 is(
228 $obj->_string, 'song long string',
229 'substr as setter with three arguments'
230 );
231
5394a1c7 232 $obj->substr( 1, 3, '' );
233
234 is(
235 $obj->_string, 's long string',
236 'substr as setter with three arguments, replacment is empty string'
237 );
238
b10dde3a 239 like( exception { $obj->substr }, qr/Cannot call substr without at least 1 argument/, 'substr throws an error when no argumemts are passed' );
e7724627 240
b10dde3a 241 like( exception { $obj->substr( 1, 2, 3, 4 ) }, qr/Cannot call substr with more than 3 arguments/, 'substr throws an error when four argumemts are passed' );
e7724627 242
b10dde3a 243 like( exception { $obj->substr( {} ) }, qr/The first argument passed to substr must be an integer/, 'substr throws an error when first argument is not an integer' );
e7724627 244
b10dde3a 245 like( exception { $obj->substr( 1, {} ) }, qr/The second argument passed to substr must be an integer/, 'substr throws an error when second argument is not an integer' );
e7724627 246
b10dde3a 247 like( exception { $obj->substr( 1, 2, {} ) }, qr/The third argument passed to substr must be a string/, 'substr throws an error when third argument is not a string' );
e7724627 248
249 $obj->_string('some long string');
250
251 is(
252 $obj->substr_curried_1, 'ome long string',
253 'substr_curried_1 returns expected value'
254 );
255
256 is(
257 $obj->substr_curried_1(3), 'ome',
258 'substr_curried_1 with one argument returns expected value'
259 );
260
261 $obj->substr_curried_1( 3, 'ong' );
262
263 is(
264 $obj->_string, 'song long string',
265 'substr_curried_1 as setter with two arguments'
266 );
267
268 $obj->_string('some long string');
269
270 is(
271 $obj->substr_curried_2, 'ome',
272 'substr_curried_2 returns expected value'
273 );
274
275 $obj->substr_curried_2('ong');
276
277 is(
278 $obj->_string, 'song long string',
279 'substr_curried_2 as setter with one arguments'
280 );
281
282 $obj->_string('some long string');
283
284 $obj->substr_curried_3;
285
286 is(
287 $obj->_string, 'song long string',
288 'substr_curried_3 as setter'
289 );
69048e4e 290
291 if ( $class->meta->get_attribute('_string')->is_lazy ) {
292 my $obj = $class->new;
293
294 $obj->append('foo');
295
296 is(
297 $obj->_string, 'foo',
298 'append with lazy default'
299 );
300 }
e7724627 301 }
302 $class;
303}
e3c07b19 304
a28e50e4 305done_testing;