From: John Napiorkowski Date: Thu, 29 Oct 2015 15:22:19 +0000 (-0500) Subject: Merge branch '104-path_empty_brackets' of https://github.com/grim8634/catalyst-runtim... X-Git-Tag: 5.90102~3^2 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=commitdiff_plain;h=161710a39409d2afd256463471b8014a1c69adf4;hp=43b44b3a2ee087f00af6579d3b6ac63f8f645412 Merge branch '104-path_empty_brackets' of https://github.com/grim8634/catalyst-runtime into grim8634-104-path_empty_brackets --- diff --git a/Changes b/Changes index 4d86d01..644e0f5 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,13 @@ # This file documents the revision history for Perl extension Catalyst. +5.90102 - 2015-10-29 + - Better warnings when there's an error reading the psgi.input (billmosley++) + - Fixed spurious warnings in uri_for when using no arguments (melmothx++ and + paultcochrane++) + - Documentation improvements (paultcochrane++) + - Improvements to 'search_extra' configuration and tests around using + uri_for as a class method (cngarrison++) + 5.90101 - 2015-09-04 - Fixed a regression introduced in the last release which caused test case failure when using a version of Perl 5.14 or older. diff --git a/README.mkdn b/README.mkdn index 74be19d..ad3aa2d 100644 --- a/README.mkdn +++ b/README.mkdn @@ -1502,7 +1502,7 @@ This has been done since not all people need this feature and we wish to restric - `skip_complex_post_part_handling` - When creating body parameters from a POST, if we run into a multpart POST + When creating body parameters from a POST, if we run into a multipart POST that does not contain uploads, but instead contains inlined complex data (very uncommon) we cannot reliably convert that into field => value pairs. So instead we create an instance of [Catalyst::Request::PartData](https://metacpan.org/pod/Catalyst::Request::PartData). If this causes @@ -1522,7 +1522,7 @@ This has been done since not all people need this feature and we wish to restric If true, then do not try to character decode any wide characters in your request URL query or keywords. Most readings of the relevant specifications suggest these should be UTF-\* encoded, which is the default that [Catalyst](https://metacpan.org/pod/Catalyst) - will use, hwoever if you are creating a lot of URLs manually or have external + will use, however if you are creating a lot of URLs manually or have external evil clients, this might cause you trouble. If you find the changes introduced in Catalyst version 5.90080+ break some of your query code, you may disable the UTF-8 decoding globally using this configuration. @@ -1533,7 +1533,7 @@ This has been done since not all people need this feature and we wish to restric - `default_query_encoding` By default we decode query and keywords in your request URL using UTF-8, which - is our reading of the relevent specifications. This setting allows one to + is our reading of the relevant specifications. This setting allows one to specify a fixed value for how to decode your query. You might need this if you are doing a lot of custom encoding of your URLs and not using UTF-8. @@ -1558,15 +1558,15 @@ This has been done since not all people need this feature and we wish to restric - `data_handlers` - See ["DATA HANDLERS"](#data-handlers). - `stats_class_traits` - An arrayref of [Moose::Role](https://metacpan.org/pod/Moose::Role)s that get componsed into your stats class. + An arrayref of [Moose::Role](https://metacpan.org/pod/Moose::Role)s that get composed into your stats class. - `request_class_traits` - An arrayref of [Moose::Role](https://metacpan.org/pod/Moose::Role)s that get componsed into your request class. + An arrayref of [Moose::Role](https://metacpan.org/pod/Moose::Role)s that get composed into your request class. - `response_class_traits` - An arrayref of [Moose::Role](https://metacpan.org/pod/Moose::Role)s that get componsed into your response class. + An arrayref of [Moose::Role](https://metacpan.org/pod/Moose::Role)s that get composed into your response class. - `inject_components` diff --git a/lib/Catalyst.pm b/lib/Catalyst.pm index c290fff..820fc35 100644 --- a/lib/Catalyst.pm +++ b/lib/Catalyst.pm @@ -807,6 +807,11 @@ sub controller { my $comps = $c->components; my $check = $appclass."::Controller::".$name; return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check}; + foreach my $path (@{$appclass->config->{ setup_components }->{ search_extra }}) { + next unless $path =~ /.*::Controller/; + $check = $path."::".$name; + return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check}; + } } my @result = $c->_comp_search_prefixes( $name, qw/Controller C/ ); return map { $c->_filter_component( $_, @args ) } @result if ref $name; @@ -846,6 +851,11 @@ sub model { my $comps = $c->components; my $check = $appclass."::Model::".$name; return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check}; + foreach my $path (@{$appclass->config->{ setup_components }->{ search_extra }}) { + next unless $path =~ /.*::Model/; + $check = $path."::".$name; + return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check}; + } } my @result = $c->_comp_search_prefixes( $name, qw/Model M/ ); return map { $c->_filter_component( $_, @args ) } @result if ref $name; @@ -910,6 +920,11 @@ sub view { else { $c->log->warn( "Attempted to use view '$check', but does not exist" ); } + foreach my $path (@{$appclass->config->{ setup_components }->{ search_extra }}) { + next unless $path =~ /.*::View/; + $check = $path."::".$name; + return $c->_filter_component( $comps->{$check}, @args ) if exists $comps->{$check}; + } } my @result = $c->_comp_search_prefixes( $name, qw/View V/ ); return map { $c->_filter_component( $_, @args ) } @result if ref $name; @@ -1560,7 +1575,7 @@ sub uri_for { my $fragment = ((scalar(@args) && ref($args[-1]) eq 'SCALAR') ? pop @args : undef ); unless(blessed $path) { - if ($path =~ s/#(.+)$//) { + if (defined($path) and $path =~ s/#(.+)$//) { if(defined($1) and $fragment) { carp "Abiguious fragment declaration: You cannot define a fragment in '$path' and as an argument '$fragment'"; } @@ -2812,7 +2827,7 @@ We try each possible role in turn (and throw an error if none load) MyApp::TraitFor::Request::Foo Catalyst::TraitFor::Request::Foo -The namespace part 'TraitFor::Request' was choosen to assist in backwards +The namespace part 'TraitFor::Request' was chosen to assist in backwards compatibility with L which previously provided these features in a stand alone package. @@ -2843,7 +2858,7 @@ We try each possible role in turn (and throw an error if none load) MyApp::TraitFor::Response::Foo Catalyst::TraitFor::Responset::Foo -The namespace part 'TraitFor::Response' was choosen to assist in backwards +The namespace part 'TraitFor::Response' was chosen to assist in backwards compatibility with L which previously provided these features in a stand alone package. @@ -3090,7 +3105,7 @@ sub locate_components { my $config = shift; my @paths = qw( ::M ::Model ::V ::View ::C ::Controller ); - my $extra = delete $config->{ search_extra } || []; + my $extra = $config->{ search_extra } || []; unshift @paths, @$extra; @@ -4031,7 +4046,7 @@ We try each possible role in turn (and throw an error if none load) MyApp::TraitFor::Stats::Foo Catalyst::TraitFor::Stats::Foo -The namespace part 'TraitFor::Stats' was choosen to assist in backwards +The namespace part 'TraitFor::Stats' was chosen to assist in backwards compatibility with L which previously provided these features in a stand alone package. @@ -4245,7 +4260,7 @@ backwardly compatible). C -When creating body parameters from a POST, if we run into a multpart POST +When creating body parameters from a POST, if we run into a multipart POST that does not contain uploads, but instead contains inlined complex data (very uncommon) we cannot reliably convert that into field => value pairs. So instead we create an instance of L. If this causes @@ -4267,9 +4282,9 @@ parameter to true. C If true, then do not try to character decode any wide characters in your -request URL query or keywords. Most readings of the relevent specifications +request URL query or keywords. Most readings of the relevant specifications suggest these should be UTF-* encoded, which is the default that L -will use, hwoever if you are creating a lot of URLs manually or have external +will use, however if you are creating a lot of URLs manually or have external evil clients, this might cause you trouble. If you find the changes introduced in Catalyst version 5.90080+ break some of your query code, you may disable the UTF-8 decoding globally using this configuration. @@ -4282,7 +4297,7 @@ C C By default we decode query and keywords in your request URL using UTF-8, which -is our reading of the relevent specifications. This setting allows one to +is our reading of the relevant specifications. This setting allows one to specify a fixed value for how to decode your query. You might need this if you are doing a lot of custom encoding of your URLs and not using UTF-8. @@ -4319,19 +4334,19 @@ C - See L. C -An arrayref of Ls that get componsed into your stats class. +An arrayref of Ls that get composed into your stats class. =item * C -An arrayref of Ls that get componsed into your request class. +An arrayref of Ls that get composed into your request class. =item * C -An arrayref of Ls that get componsed into your response class. +An arrayref of Ls that get composed into your response class. =item * diff --git a/lib/Catalyst/Action.pm b/lib/Catalyst/Action.pm index 07f2f32..ea3e3e4 100644 --- a/lib/Catalyst/Action.pm +++ b/lib/Catalyst/Action.pm @@ -107,7 +107,7 @@ has number_of_args_constraints => ( return 1; # Its a normal 1 arg type constraint. } } else { - # We need to loop thru and error on ref types. We don't allow a ref type + # We need to loop through and error on ref types. We don't allow a ref type # in the middle. my $total = 0; foreach my $tc( @{$self->args_constraints}) { @@ -193,7 +193,7 @@ has number_of_captures_constraints => ( return 1; # Its a normal 1 arg type constraint. } } else { - # We need to loop thru and error on ref types. We don't allow a ref type + # We need to loop through and error on ref types. We don't allow a ref type # in the middle. my $total = 0; foreach my $tc( @{$self->captures_constraints}) { @@ -269,7 +269,7 @@ sub resolve_type_constraint { my @supers = $self->class->can('meta') ? map { $_->meta } $self->class->meta->superclasses : (); my @roles = $self->class->can('meta') ? $self->class->meta->calculate_all_roles : (); - # So look thru all the super and roles in order and return the + # So look through all the super and roles in order and return the # first type constraint found. We should probably find all matching # type constraints and try to do some sort of resolution. @@ -526,7 +526,7 @@ Does the Args match or not? =head2 resolve_type_constraint -Trys to find a type constraint if you have on on a type constrained method. +Tries to find a type constraint if you have on on a type constrained method. =head2 compare diff --git a/lib/Catalyst/Component.pm b/lib/Catalyst/Component.pm index 01e38f5..55f25c0 100644 --- a/lib/Catalyst/Component.pm +++ b/lib/Catalyst/Component.pm @@ -203,8 +203,8 @@ something like this: } B Generally when L starts, it initializes all the components -and passes the hashref present in any configutation information to the -COMPONET method. For example +and passes the hashref present in any configuration information to the +COMPONENT method. For example MyApp->config( 'Model::Foo' => { @@ -294,7 +294,7 @@ second argument is blessed (is a context) or not (is an application class name) it MUST return something valid for the case when the scope is application. This is required because a component maybe be called from the application scope even if it requires a context and you must prevent errors from being issued if this happens. -Remeber not all components that ACCEPT_CONTEXT actually need or use context information +Remember not all components that ACCEPT_CONTEXT actually need or use context information (and there is a school of thought that suggestions doing so is a design error anyway...) =head1 SEE ALSO diff --git a/lib/Catalyst/Contributing.pod b/lib/Catalyst/Contributing.pod index b4054df..e5397ef 100644 --- a/lib/Catalyst/Contributing.pod +++ b/lib/Catalyst/Contributing.pod @@ -2,7 +2,7 @@ =head1 Name -Catalyst::Contributing - Contributing to Catalyst and Change managment +Catalyst::Contributing - Contributing to Catalyst and Change management =head1 Description @@ -23,7 +23,7 @@ Going further, if we allow ourselves to look hard at projects outside of Perl we =head2 Reporting a bug -Reported bugs via RT or L that come with attached test cases will be more likely addressed quickly than those that do not. Proposing a bugfix patch is also alwaysvery welcomed, although it is recommended to stick as closely as possible to an actual bug (rather than a feature change) and to not include unneeded changes in your patch such as formatting corrections. In any case it is recommended before spending a lot of time on a patch to discuss the issue and your proposed solution, else you risk spending a lot of time on code that may not get merged, which tends to be frustrating. +Reported bugs via RT or L that come with attached test cases will be more likely addressed quickly than those that do not. Proposing a bugfix patch is also always very welcome, although it is recommended to stick as closely as possible to an actual bug (rather than a feature change) and to not include unneeded changes in your patch such as formatting corrections. In any case it is recommended before spending a lot of time on a patch to discuss the issue and your proposed solution, else you risk spending a lot of time on code that may not get merged, which tends to be frustrating. For bug patches you should create a new branch from the current master. diff --git a/lib/Catalyst/Controller.pm b/lib/Catalyst/Controller.pm index a5b400f..b50a2ff 100644 --- a/lib/Catalyst/Controller.pm +++ b/lib/Catalyst/Controller.pm @@ -900,7 +900,7 @@ declared attributes you must quote them: If you use 'reference' type constraints (such as ArrayRef[Int]) that have an unknown number of allowed matches, we set this the same way "Args" is. Please keep in mind -that actions with an undetermined number of args match at lower precidence than those +that actions with an undetermined number of args match at lower precedence than those with a fixed number. You may use reference types such as Tuple from L that allows you to fix the number of allowed args. For example Args(Tuple[Int,Int]) would be determined to be two args (or really the same as Args(Int,Int).) You may diff --git a/lib/Catalyst/Delta.pod b/lib/Catalyst/Delta.pod index 7959a6e..95afdc0 100755 --- a/lib/Catalyst/Delta.pod +++ b/lib/Catalyst/Delta.pod @@ -13,12 +13,12 @@ Support for type constraints in Args and CaptureArgs has been improved. You may now inherit from a base controller that declares type constraints and use roles that declare type constraints. See L for more. -You may now. also use a full type constraint namespace instead of inporting type +You may now. also use a full type constraint namespace instead of importing type constraints into your package namespace. We changed the way the middleware stash works so that it no longer localizes the PSGI env hashref. This was done to fix bugs where people set PSGI ENV hash -keys and found them to dissappear in certain cases. It also means that now if +keys and found them to disappear in certain cases. It also means that now if a sub applications sets stash variables, that stash will now bubble up to the parent application. This may be a breaking change for you since previous versions of this code did not allow that. A workaround is to explicitly delete @@ -65,7 +65,7 @@ you used to check for the object you might find that code is no longer needed =head3 'case_sensitive' configuration -At one point in time we allowed you to set a 'case_sensitive' configuraion value so +At one point in time we allowed you to set a 'case_sensitive' configuration value so that you could find actions by their private names using mixed case. We highly discourage that. If you are using this 'feature' you should be on notice that we plan to remove the code around it in the near future. @@ -108,7 +108,7 @@ any subclasses. For example: 'Model::Foo' => { a => 100 }, }); -Injected components are useful to reduce the ammount of nearly empty boilerplate classes +Injected components are useful to reduce the amount of nearly empty boilerplate classes you might have, particularly when first starting an application. =head3 Component setup changes. @@ -199,7 +199,7 @@ Plack middleware to aid in backwards compatibility. =head3 Distinguish between body null versus undef. -We also now more carefully distingush the different between a body set +We also now more carefully distinguish the different between a body set to '' and a body that is undef. This might lead to situations where again you'll get a content-length were you didn't get one before or where a supporting server will start chunking output. If this is an @@ -208,7 +208,7 @@ or report specific problems to the dev team. =head3 More Catalyst Middleware -We have started migrating code in Catalyst to equivilent Plack +We have started migrating code in Catalyst to equivalent Plack Middleware when such exists and is correct to do so. For example we now use L to determine content length of a response when none is provided. This replaces similar code inlined with L diff --git a/lib/Catalyst/Middleware/Stash.pm b/lib/Catalyst/Middleware/Stash.pm index 0ed488d..c8d5945 100644 --- a/lib/Catalyst/Middleware/Stash.pm +++ b/lib/Catalyst/Middleware/Stash.pm @@ -61,7 +61,7 @@ We store a coderef under the C which can be dereferenced with key values or nothing to access the underlying hashref. Anything placed into the stash will be available in the stash of any 'mounted' -Catalyst applictions. A mounted Catalyst application may set the stash and +Catalyst applications. A mounted Catalyst application may set the stash and 'pass back' information to the parent application. Non Catalyst applications may use this middleware to access and set stash values. diff --git a/lib/Catalyst/Request.pm b/lib/Catalyst/Request.pm index 3bcc6c2..1306b94 100644 --- a/lib/Catalyst/Request.pm +++ b/lib/Catalyst/Request.pm @@ -293,7 +293,10 @@ sub prepare_body { # Check for definedness as you could read '0' while ( defined ( my $chunk = $self->read() ) ) { $self->prepare_body_chunk($chunk); - $stream_buffer->print($chunk) if $stream_buffer; + next unless $stream_buffer; + + $stream_buffer->print($chunk) + || die sprintf "Failed to write %d bytes to psgi.input file: $!", length( $chunk ); } # Ok, we read the body. Lets play nice for any PSGI app down the pipe diff --git a/lib/Catalyst/RouteMatching.pod b/lib/Catalyst/RouteMatching.pod index 54dc51d..3d26706 100644 --- a/lib/Catalyst/RouteMatching.pod +++ b/lib/Catalyst/RouteMatching.pod @@ -25,7 +25,7 @@ that if the request is '/foo/bar/baz' That means the action 'baz' matches: sub bar :Path('bar') Args(1) { ...} sub baz :Path('bar/baz') Args(0) { ... } -Path length matches take precidence over all other types of matches (included HTTP +Path length matches take precedence over all other types of matches (included HTTP Method, Scheme, etc.). The same holds true for Chained actions. Generally the chain that matches the most PathParts wins. @@ -37,7 +37,7 @@ action with 'Args' always get the last chance to match. =head2 When two or more actions match a given Path -Sometimes two or more actions match the same path and all have the same pathpart +Sometimes two or more actions match the same path and all have the same PathPart length. For example: package MyApp::Controller::Root; @@ -80,7 +80,7 @@ your 'catchall' actions higher in the controller. =head2 Type Constraints in Args and Capture Args Beginning in Version 5.90090+ you may use L, L or L -type constraints to futher declare allowed matching for Args or CaptureArgs. Here +type constraints to further declare allowed matching for Args or CaptureArgs. Here is a simple example: package MyApp::Controller::User; @@ -264,7 +264,7 @@ and interests. =head3 Match order when more than one Action matches a path. As previously described, L will match 'the longest path', which generally means -that named path / path_parts will take precidence over Args or CaptureArgs. However, what +that named path / path_parts will take precedence over Args or CaptureArgs. However, what will happen if two actions match the same path with equal args? For example: sub an_int :Path(user) Args(Int) { @@ -286,7 +286,7 @@ action NEVER gets hit. You would need to reverse the order: Now requests that match this path would first hit the 'an_int' action and will check to see if the argument is an integer. If it is, then the action will execute, otherwise it will pass and -the dispatcher will check the next matching action (in this case we fall thru to the 'an_any' +the dispatcher will check the next matching action (in this case we fall through to the 'an_any' action). =head3 Type Constraints and Chained Actions @@ -327,7 +327,7 @@ well as Args. For Example: sub int_priority_link3 :Chained(link_tuple) PathPart('') Args(Int) { } -These chained actions migth create match tables like the following: +These chained actions might create match tables like the following: [debug] Loaded Chained actions: .-------------------------------------+--------------------------------------. @@ -376,7 +376,7 @@ the rule described in the previous section should be followed, which is that L would be checked before C. The same applies for actions that are midway links in a longer chain. In this case C would be checked before C. So as always we -recommend that you place you priority or most constrainted actions last and you least or catch-all +recommend that you place you priority or most constrained actions last and you least or catch-all actions first. Although this reverse order checking may seen counter intuitive it does have the added benefit that diff --git a/lib/Catalyst/UTF8.pod b/lib/Catalyst/UTF8.pod index d8bce96..33c9c1f 100644 --- a/lib/Catalyst/UTF8.pod +++ b/lib/Catalyst/UTF8.pod @@ -315,7 +315,7 @@ an instance of an object L which will contain all t information needed for you to perform custom parser of the data. Ideally we'd fix L to be smarter about decoding so please submit your cases of -this so we can add inteligence to the parser and find a way to extract a valid value out +this so we can add intelligence to the parser and find a way to extract a valid value out of it. =head1 UTF8 Encoding in Body Response diff --git a/lib/Catalyst/Upgrading.pod b/lib/Catalyst/Upgrading.pod index 432e3d0..1c9de49 100644 --- a/lib/Catalyst/Upgrading.pod +++ b/lib/Catalyst/Upgrading.pod @@ -6,7 +6,7 @@ Catalyst::Upgrading - Instructions for upgrading to the latest Catalyst We changed the way the middleware stash works so that it no longer localizes the PSGI env hashref. This was done to fix bugs where people set PSGI ENV hash -keys and found them to dissappear in certain cases. It also means that now if +keys and found them to disappear in certain cases. It also means that now if a sub applications sets stash variables, that stash will now bubble up to the parent application. This may be a breaking change for you since previous versions of this code did not allow that. A workaround is to explicitly delete @@ -69,10 +69,10 @@ reports are very welcomed. L has a new method 'inject_component' which works the same as the method of the same name in L. You should start converting any use of the non core method in your code as future changes to Catalyst will be -sychronized to the core method first. We reserve the right to cease support +synchronized to the core method first. We reserve the right to cease support of the non core version should we reach a point in time where it cannot be properly supported as an external module. Luckily this should be a trivial -search and replace. Change all occurances of: +search and replace. Change all occurences of: CatalystX::InjectComponent->inject(...) @@ -141,8 +141,8 @@ and now in core: }, ); -Although the cored behavior requires more code, its better separates concerns -as well as plays more into core Catalyst expections of how configuration shoul +Although the core behavior requires more code, it better separates concerns +as well as plays more into core Catalyst expectations of how configuration should look. Also we added a new develop console mode only warning when you call a component @@ -218,16 +218,16 @@ that will revert you code to the previous behavior. =head2 More backwards compatibility options with UTF-8 changes -In order to give better backwards compatiblity with the 5.90080+ UTF-8 changes +In order to give better backwards compatibility with the 5.90080+ UTF-8 changes we've added several configuration options around control of how we try to decode your URL keywords / query parameters. C If true, then do not try to character decode any wide characters in your -request URL query or keywords. Most readings of the relevent specifications +request URL query or keywords. Most readings of the relevant specifications suggest these should be UTF-* encoded, which is the default that L -will use, hwoever if you are creating a lot of URLs manually or have external +will use, however if you are creating a lot of URLs manually or have external evil clients, this might cause you trouble. If you find the changes introduced in Catalyst version 5.90080+ break some of your query code, you may disable the UTF-8 decoding globally using this configuration. @@ -238,7 +238,7 @@ C C By default we decode query and keywords in your request URL using UTF-8, which -is our reading of the relevent specifications. This setting allows one to +is our reading of the relevant specifications. This setting allows one to specify a fixed value for how to decode your query. You might need this if you are doing a lot of custom encoding of your URLs and not using UTF-8. diff --git a/t/aggregate/unit_core_component_loading.t b/t/aggregate/unit_core_component_loading.t index 2c53144..a408dd7 100644 --- a/t/aggregate/unit_core_component_loading.t +++ b/t/aggregate/unit_core_component_loading.t @@ -2,7 +2,7 @@ # (do not forget to update the number of components in test 3 as well) # 5 extra tests for the loading options # One test for components in inner packages -use Test::More tests => 2 + 6 * 24 + 8 + 1; +use Test::More tests => 2 + 6 * 24 + 9 + 1; use strict; use warnings; @@ -152,12 +152,20 @@ foreach my $component (@components) { ); } + make_component_file( + $libdir, + 'ExternalExtra', + 'Controller', + 'Controller', + 'FooExternal', + ); + eval qq( package $appclass; use Catalyst; $shut_up_deprecated_warnings __PACKAGE__->config->{ setup_components } = { - search_extra => [ '::Extra' ], + search_extra => [ '::Extra', 'ExternalExtra::Controller' ], except => [ "${appclass}::Controller::Foo" ] }; __PACKAGE__->setup; @@ -167,11 +175,13 @@ can_ok( $appclass, 'components'); $complist = $appclass->components; -is(scalar keys %$complist, 24+1, "Correct number of components loaded"); +is(scalar keys %$complist, 24+2, "Correct number of components loaded"); ok( !exists $complist->{ "${appclass}::Controller::Foo" }, 'Controller::Foo was skipped' ); ok( exists $complist->{ "${appclass}::Extra::Foo" }, 'Extra::Foo was loaded' ); +isa_ok($appclass->controller('FooExternal'), 'Catalyst::Controller', 'ExternalExtra::Controller::FooExternal was loaded'); + rmtree($libdir); $appclass = "ComponentOnce"; diff --git a/t/aggregate/unit_core_uri_for.t b/t/aggregate/unit_core_uri_for.t index a541508..ab256f0 100644 --- a/t/aggregate/unit_core_uri_for.t +++ b/t/aggregate/unit_core_uri_for.t @@ -66,6 +66,12 @@ is( ); is( + Catalyst::uri_for( $context, '0#fragment', { param1 => 'value1' } )->as_string, + 'http://127.0.0.1/foo/yada/0?param1=value1#fragment', + 'URI for path 0 with fragment and query params 1' +); + +is( Catalyst::uri_for( $context, '/bar#fragment^%$', { param1 => 'value1' } )->as_string, 'http://127.0.0.1/foo/bar?param1=value1#fragment^%$', 'URI for path with fragment and query params 3' @@ -77,6 +83,59 @@ is( 'URI for path with fragment and query params 3' ); +is( + Catalyst::uri_for( 'TestApp', '/bar/baz' )->as_string, + '/bar/baz', + 'URI for absolute path, called with only class name' +); + +## relative action (or path) doesn't make sense when calling as class method +# is( +# Catalyst::uri_for( 'TestApp', 'bar/baz' )->as_string, +# '/yada/bar/baz', +# 'URI for relative path, called with only class name' +# ); + +is( + Catalyst::uri_for( 'TestApp', '/', 'arg1', 'arg2' )->as_string, + '/arg1/arg2', + 'URI for root action with args, called with only class name' +); + +## relative action (or path) doesn't make sense when calling as class method +# is( Catalyst::uri_for( 'TestApp', '../quux' )->as_string, +# '/quux', 'URI for relative dot path, called with only class name' ); + +is( + Catalyst::uri_for( 'TestApp', '/quux', { param1 => 'value1' } )->as_string, + '/quux?param1=value1', + 'URI for quux action with query params, called with only class name' +); + +is (Catalyst::uri_for( 'TestApp', '/bar/wibble?' )->as_string, + '/bar/wibble%3F', 'Question Mark gets encoded, called with only class name' +); + +## relative action (or path) doesn't make sense when calling as class method +# is( Catalyst::uri_for( 'TestApp', qw/bar wibble?/, 'with space' )->as_string, +# '/yada/bar/wibble%3F/with%20space', 'Space gets encoded, called with only class name' +# ); + +is( + Catalyst::uri_for( 'TestApp', '/bar', 'with+plus', { 'also' => 'with+plus' })->as_string, + '/bar/with+plus?also=with%2Bplus', + 'Plus is not encoded, called with only class name' +); + +TODO: { + local $TODO = 'broken by 5.7008'; + is( + Catalyst::uri_for( $context, '/bar#fragment', { param1 => 'value1' } )->as_string, + 'http://127.0.0.1/foo/bar?param1=value1#fragment', + 'URI for path with fragment and query params' + ); +} + # test with utf-8 is( Catalyst::uri_for( $context, 'quux', { param1 => "\x{2620}" } )->as_string, @@ -94,7 +153,26 @@ is( Catalyst::uri_for( $context, 'quux', { param1 => $request->base } )->as_string, 'http://127.0.0.1/foo/yada/quux?param1=http%3A%2F%2F127.0.0.1%2Ffoo', 'URI for undef action with query param as object' -); + ); + +# test with empty arg +{ + my @warnings; + local $SIG{__WARN__} = sub { push @warnings, @_ }; + is( + Catalyst::uri_for( $context )->as_string, + 'http://127.0.0.1/foo/yada', + 'URI with no action' + ); + + is( + Catalyst::uri_for( $context, 0 )->as_string, + 'http://127.0.0.1/foo/yada/0', + 'URI with 0 path' + ); + + is_deeply(\@warnings, [], "No warnings with no path argument"); +} $request->base( URI->new('http://localhost:3000/') ); $request->match( 'orderentry/contract' ); diff --git a/t/aggregate/unit_core_uri_for_action.t b/t/aggregate/unit_core_uri_for_action.t index 4036f88..7341365 100644 --- a/t/aggregate/unit_core_uri_for_action.t +++ b/t/aggregate/unit_core_uri_for_action.t @@ -77,6 +77,36 @@ my $context = TestApp->new( { namespace => 'yada', } ); + + + +# this works, using $ctx +is($context->uri_for( 'TestApp', $context->controller('Action::Chained')->action_for('endpoint')), + "http://127.0.0.1/foo/yada/chained/foo/end", + "uri_for a controller and action"); + +# this fails, uri_for returns undef, why isn't this one working?? +is( $context->uri_for_action( '/action/chained/endpoint' ), + 'http://127.0.0.1/chained/foo/end', + "uri_for a controller and action as string"); + +# this fails, uri_for returns undef +is(Catalyst::uri_for_action( 'TestApp', $context->controller('Action::Chained')->action_for('endpoint')), + "/chained/foo/end", + "uri_for a controller and action, called with only class name"); + +# this fails, uri_for returns undef +is(Catalyst::uri_for_action( 'TestApp', '/action/chained/endpoint' ), + "/chained/foo/end", + "uri_for a controller and action as string, called with only class name"); + +# this fails, uri_for returns undef +is(Catalyst::uri_for_action( 'TestApp', $chained_action), + "/chained/foo/end", + "uri_for action via dispatcher, called with only class name"); + + + is($context->uri_for($context->controller('Action')), "http://127.0.0.1/foo/yada/action/", "uri_for a controller"); diff --git a/t/author/spelling.t b/t/author/spelling.t index f55ea40..c90f51a 100644 --- a/t/author/spelling.t +++ b/t/author/spelling.t @@ -12,7 +12,7 @@ add_stopwords(qw( fastcgi nginx Lighttpd IIS middlewares backend IRC IOLayer ctx _application MyApp restarter httponly Utils stash's unescapes actionchain dispatchtype dispatchtypes redispatch redispatching - CaptureArgs ChainedParent PathPart PathPrefix + CaptureArgs ChainedParent PathPart PathParts PathPrefix BUILDARGS metaclass namespaces pre ARGV ReverseProxy TT UI filename tempname request's subdirectory ini uninstalled uppercased wiki bitmask uri url urls dir hostname proxied http https IP SSL @@ -22,7 +22,7 @@ add_stopwords(qw( UTF unicode async codebase dev encodable filenames params MyMiddleware Sendfile JSON xml POSTs POSTed RESTful performant subref actionrole chunked chunking codewise distingush equivilent plack Javascript gzipping - ConfigLoader getline whitepaper matchable + ConfigLoader getline whitepaper matchable TBD WIP Andreas André Ashton @@ -74,6 +74,7 @@ add_stopwords(qw( Rodland Ruthven Sascha + Scala Schutz Sedlacek Sheidlower @@ -91,10 +92,13 @@ add_stopwords(qw( Yuval abraxxa abw + alls + andrewalker andyg audreyt bricas chansen + codebases davewood dhoss dkubb @@ -116,6 +120,7 @@ add_stopwords(qw( mgrimes miyagawa mst + multipart Napiorkowski naughton ningu @@ -127,6 +132,7 @@ add_stopwords(qw( rainboxx sri szbalint + uploadtmp vanstyn willert wreis