Merge branch '104-path_empty_brackets' of https://github.com/grim8634/catalyst-runtim...
John Napiorkowski [Thu, 29 Oct 2015 15:22:19 +0000 (10:22 -0500)]
17 files changed:
Changes
README.mkdn
lib/Catalyst.pm
lib/Catalyst/Action.pm
lib/Catalyst/Component.pm
lib/Catalyst/Contributing.pod
lib/Catalyst/Controller.pm
lib/Catalyst/Delta.pod
lib/Catalyst/Middleware/Stash.pm
lib/Catalyst/Request.pm
lib/Catalyst/RouteMatching.pod
lib/Catalyst/UTF8.pod
lib/Catalyst/Upgrading.pod
t/aggregate/unit_core_component_loading.t
t/aggregate/unit_core_uri_for.t
t/aggregate/unit_core_uri_for_action.t
t/author/spelling.t

diff --git a/Changes b/Changes
index 4d86d01..644e0f5 100644 (file)
--- 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.
index 74be19d..ad3aa2d 100644 (file)
@@ -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`
 
index c290fff..820fc35 100644 (file)
@@ -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<CatalystX::RoleApplicator> 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<CatalystX::RoleApplicator> 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<CatalystX::RoleApplicator> which previously provided
 these features in a stand alone package.
 
@@ -4245,7 +4260,7 @@ backwardly compatible).
 
 C<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 L<Catalyst::Request::PartData>.  If this causes
@@ -4267,9 +4282,9 @@ parameter to true.
 C<do_not_decode_query>
 
 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<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.
@@ -4282,7 +4297,7 @@ C<decode_query_using_global_encoding>
 C<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.
 
@@ -4319,19 +4334,19 @@ C<data_handlers> - See L<DATA HANDLERS>.
 
 C<stats_class_traits>
 
-An arrayref of L<Moose::Role>s that get componsed into your stats class.
+An arrayref of L<Moose::Role>s that get composed into your stats class.
 
 =item *
 
 C<request_class_traits>
 
-An arrayref of L<Moose::Role>s that get componsed into your request class.
+An arrayref of L<Moose::Role>s that get composed into your request class.
 
 =item *
 
 C<response_class_traits>
 
-An arrayref of L<Moose::Role>s that get componsed into your response class.
+An arrayref of L<Moose::Role>s that get composed into your response class.
 
 =item *
 
index 07f2f32..ea3e3e4 100644 (file)
@@ -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
 
index 01e38f5..55f25c0 100644 (file)
@@ -203,8 +203,8 @@ something like this:
   }
 
 B<NOTE:> Generally when L<Catalyst> 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
index b4054df..e5397ef 100644 (file)
@@ -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<Github Issues|https://github.com/perl-catalyst/catalyst-runtime/issues> 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<Github Issues|https://github.com/perl-catalyst/catalyst-runtime/issues> 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.
 
index a5b400f..b50a2ff 100644 (file)
@@ -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<Types::Standard>
 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
index 7959a6e..95afdc0 100755 (executable)
@@ -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<Catalyst::RouteMatching> 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<Plack::Middleware::ContentLength> to determine content length of a response
 when none is provided.  This replaces similar code inlined with L<Catalyst>
index 0ed488d..c8d5945 100644 (file)
@@ -61,7 +61,7 @@ We store a coderef under the C<PSGI_KEY> 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.
 
index 3bcc6c2..1306b94 100644 (file)
@@ -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
index 54dc51d..3d26706 100644 (file)
@@ -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<Moose>, L<MooseX::Types> or L<Type::Tiny>
-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<Catalyst> 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<C
 will start with the last defined action and work upward.  For example the action C<int_priority_chain>
 would be checked before C<any_priority_chain>.  The same applies for actions that are midway links
 in a longer chain.  In this case C<link_int> would be checked before C<link_any>.  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
index d8bce96..33c9c1f 100644 (file)
@@ -315,7 +315,7 @@ an instance of an object L<Catalyst::Request::PartData> which will contain all t
 information needed for you to perform custom parser of the data.
 
 Ideally we'd fix L<Catalyst> 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
index 432e3d0..1c9de49 100644 (file)
@@ -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<Catalyst::Utils> has a new method 'inject_component' which works the same as the method of
 the same name in L<CatalystX::InjectComponent>.  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<do_not_decode_query>
 
 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<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.
@@ -238,7 +238,7 @@ C<decode_query_using_global_encoding>
 C<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.
 
index 2c53144..a408dd7 100644 (file)
@@ -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";
index a541508..ab256f0 100644 (file)
@@ -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' );
index 4036f88..7341365 100644 (file)
@@ -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");
index f55ea40..c90f51a 100644 (file)
@@ -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