Skip to content

Commit

Permalink
consistent scalar and list context
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Feb 23, 2015
1 parent fb4a91f commit 61f1e70
Show file tree
Hide file tree
Showing 10 changed files with 52 additions and 57 deletions.
6 changes: 6 additions & 0 deletions Changes
@@ -1,6 +1,10 @@

6.0 2015-02-24
- Code name "Clinking Beer Mugs", this is a major release.
- Removed name listing support from param method in Mojolicious::Controller.
- Removed name listing support from param method in Mojo::Parameters.
- Removed name listing support from param method in
Mojolicious::Validator::Validation.
- Removed multi-name support from cookie, param and signed_cookie methods in
Mojolicious::Controller.
- Removed multi-name support from param method in
Expand All @@ -19,6 +23,8 @@
- Removed deprecated render_exception and render_not_found methods from
Mojolicious::Controller.
- Removed deprecated keep_alive_requests setting from Hypnotoad.
- Added names method to Mojo::Parameters.
- Added names method to Mojolicious::Validator::Validation.

5.82 2015-02-22
- Deprecated Mojo::Reactor::is_readable.
Expand Down
1 change: 0 additions & 1 deletion lib/Mojo/Message/Request.pm
Expand Up @@ -401,7 +401,6 @@ Check C<X-Requested-With> header for C<XMLHttpRequest> value.
=head2 param
my @names = $req->param;
my $value = $req->param('foo');
Access C<GET> and C<POST> parameters extracted from the query string and
Expand Down
18 changes: 11 additions & 7 deletions lib/Mojo/Parameters.pm
Expand Up @@ -61,18 +61,13 @@ sub merge {
return $self;
}

sub names { [sort keys %{shift->to_hash}] }

sub new { @_ > 1 ? shift->SUPER::new->parse(@_) : shift->SUPER::new }

sub param {
my ($self, $name) = (shift, shift);

# List names
return sort keys %{$self->to_hash} unless defined $name;

# Last value
return $self->every_param($name)->[-1] unless @_;

# Replace values
$self->remove($name);
return $self->append($name => ref $_[0] eq 'ARRAY' ? $_[0] : [@_]);
}
Expand Down Expand Up @@ -285,6 +280,15 @@ Merge parameters. Note that this method will normalize the parameters.
# "yada=yada"
Mojo::Parameters->new('foo=bar&yada=yada')->merge(foo => undef);
=head2 names
my $names = $params->names;
Return a list of all parameter names.
# Names of all parameters
say for @{$params->names};
=head2 new
my $params = Mojo::Parameters->new;
Expand Down
18 changes: 1 addition & 17 deletions lib/Mojolicious/Controller.pm
Expand Up @@ -146,23 +146,8 @@ sub on {

sub param {
my ($self, $name) = (shift, shift);

# List names
my $captures = $self->stash->{'mojo.captures'} ||= {};
unless (defined $name) {
my $req = $self->req;
my @keys = $req->param;
push @keys, map { $_->name } @{$req->uploads};
push @keys, grep { !$RESERVED{$_} } keys %$captures;
my %seen;
return sort grep { !$seen{$_}++ } @keys;
}

# Value
return $self->every_param($name)->[-1] unless @_;

# Override values
$captures->{$name} = @_ > 1 ? [@_] : $_[0];
$self->stash->{'mojo.captures'}{$name} = @_ > 1 ? [@_] : $_[0];
return $self;
}

Expand Down Expand Up @@ -589,7 +574,6 @@ status.
=head2 param
my @names = $c->param;
my $value = $c->param('foo');
$c = $c->param(foo => 'ba;r');
$c = $c->param(foo => qw(ba;r baz));
Expand Down
26 changes: 18 additions & 8 deletions lib/Mojolicious/Validator/Validation.pm
Expand Up @@ -45,7 +45,7 @@ sub csrf_protect {
sub error {
my $self = shift;

return sort keys %{$self->{error}} unless defined(my $name = shift);
return [sort keys %{$self->{error}}] unless defined(my $name = shift);
return $self->{error}{$name} unless @_;
$self->{error}{$name} = shift;
delete $self->output->{$name};
Expand All @@ -64,6 +64,8 @@ sub has_error { $_[1] ? exists $_[0]{error}{$_[1]} : !!keys %{$_[0]{error}} }

sub is_valid { exists $_[0]->output->{$_[1] // $_[0]->topic} }

sub names { [sort keys %{shift->output}] }

sub optional {
my ($self, $name) = @_;

Expand All @@ -75,11 +77,7 @@ sub optional {
return $self->topic($name);
}

sub param {
my ($self, $name) = @_;
return sort keys %{$self->output} unless defined $name;
return $self->every_param($name)->[-1];
}
sub param { shift->every_param(shift)->[-1] }

sub required {
my ($self, $name) = @_;
Expand Down Expand Up @@ -171,13 +169,17 @@ Validate C<csrf_token> and protect from cross-site request forgery.
=head2 error
my @names = $validation->error;
my $names = $validation->error;
my $err = $validation->error('foo');
$validation = $validation->error(foo => ['custom_check']);
Get or set details for failed validation check, at any given time there can
only be one per field.
# Names of all parameters that failed validation
say for @{$validation->error};
# Details about failed validation
my ($check, $result, @args) = @{$validation->error('foo')};
=head2 every_param
Expand Down Expand Up @@ -211,6 +213,15 @@ Check if validation resulted in errors, defaults to checking all fields.
Check if validation was successful and field has a value, defaults to checking
the current L</"topic">.
=head2 names
my $names = $validation->names;
Return a list of all validated parameter names.
# Names of all parameters that passed validation
say for @{$validation->names};
=head2 optional
$validation = $validation->optional('foo');
Expand All @@ -219,7 +230,6 @@ Change validation L</"topic">.
=head2 param
my @names = $validation->param;
my $value = $validation->param('foo');
Access validated parameters. If there are multiple values sharing the same
Expand Down
4 changes: 2 additions & 2 deletions t/mojo/parameters.t
Expand Up @@ -47,14 +47,14 @@ $params->param(foo => 'bar');
is_deeply [$params->param('foo')], ['bar'], 'right structure';
is_deeply $params->param(foo => qw(baz yada))->every_param('foo'),
[qw(baz yada)], 'right structure';
is_deeply [$params->param], [qw(a b c foo x y z)], 'right structure';
is_deeply $params->names, [qw(a b c foo x y z)], 'right structure';

# Append
$params = Mojo::Parameters->new('q=1');
$params->append(a => 4, a => 5, b => 6, b => 7);
is_deeply $params->to_hash, {a => [4, 5], b => [6, 7], q => 1},
'right structure';
is_deeply [$params->param], [qw(a b q)], 'right structure';
is_deeply $params->names, [qw(a b q)], 'right structure';
$params = Mojo::Parameters->new(foo => '', bar => 'bar');
is $params->to_string, 'foo=&bar=bar', 'right format';
$params = Mojo::Parameters->new(bar => 'bar', foo => '');
Expand Down
7 changes: 0 additions & 7 deletions t/mojolicious/dispatch.t
Expand Up @@ -100,7 +100,6 @@ is $c->param(template => 'test')->param('template'), undef,
'value is reserved';
is $c->param(text => 'test')->param('text'), undef, 'value is reserved';
is $c->param(variant => 'test')->param('variant'), undef, 'value is reserved';
is_deeply [$c->param], [], 'values are hidden';

# Controller with application and routes
$c = Test::Controller->new;
Expand Down Expand Up @@ -173,37 +172,31 @@ is $c->stash->{test}, 23, 'right value';
is $c->param('controller'), undef, 'no value';
is $c->param('action'), undef, 'no value';
is $c->param('capture'), 'hello', 'right value';
is_deeply [$c->param], ['capture'], 'right names';
$c->param(capture => 'bye');
is $c->param('controller'), undef, 'no value';
is $c->param('action'), undef, 'no value';
is $c->param('capture'), 'bye', 'right value';
is_deeply [$c->param], ['capture'], 'right names';
$c->param(capture => undef);
is $c->param('controller'), undef, 'no value';
is $c->param('action'), undef, 'no value';
is $c->param('capture'), undef, 'no value';
is_deeply [$c->param], ['capture'], 'no names';
$c->req->param(foo => 'bar');
is $c->param('controller'), undef, 'no value';
is $c->param('action'), undef, 'no value';
is $c->param('capture'), undef, 'no value';
is $c->param('foo'), 'bar', 'right value';
is_deeply [$c->param], [qw(capture foo)], 'right names';
$c->req->param(bar => 'baz');
is $c->param('controller'), undef, 'no value';
is $c->param('action'), undef, 'no value';
is $c->param('capture'), undef, 'no value';
is $c->param('foo'), 'bar', 'right value';
is $c->param('bar'), 'baz', 'right value';
is_deeply [$c->param], [qw(bar capture foo)], 'right names';
$c->req->param(action => 'baz');
is $c->param('controller'), undef, 'no value';
is $c->param('action'), 'baz', 'no value';
is $c->param('capture'), undef, 'no value';
is $c->param('foo'), 'bar', 'right value';
is $c->param('bar'), 'baz', 'right value';
is_deeply [$c->param], [qw(action bar capture foo)], 'right names';
ok $c->render_called, 'rendered';

# Escaping
Expand Down
7 changes: 3 additions & 4 deletions t/mojolicious/lite_app.t
Expand Up @@ -115,7 +115,7 @@ get '/query_string' => sub {

get '/reserved' => sub {
my $c = shift;
$c->render(text => $c->param('data') . join(',', $c->param));
$c->render(text => $c->param('data'));
};

get '/custom_name' => 'auto_name';
Expand Down Expand Up @@ -575,10 +575,9 @@ $t->get_ok('/query_string?http://mojolicio.us/perldoc?foo=bar')

# Reserved stash values
$t->get_ok('/reserved?data=just-works')->status_is(200)
->header_is(Server => 'Mojolicious (Perl)')->content_is('just-worksdata');
->header_is(Server => 'Mojolicious (Perl)')->content_is('just-works');
$t->get_ok('/reserved?data=just-works&json=test')->status_is(200)
->header_is(Server => 'Mojolicious (Perl)')
->content_is('just-worksdata,json');
->header_is(Server => 'Mojolicious (Perl)')->content_is('just-works');

# Exception in inline template
$t->get_ok('/inline/exception')->status_is(500)
Expand Down
11 changes: 5 additions & 6 deletions t/mojolicious/upload_lite_app.t
Expand Up @@ -17,8 +17,7 @@ post '/upload' => sub {
. $file->asset->slurp
. $c->param('test')
. ($headers->content_type // '')
. ($headers->header('X-X') // '')
. join(',', $c->param));
. ($headers->header('X-X') // ''));
};

post '/multi' => sub {
Expand All @@ -33,22 +32,22 @@ my $t = Test::Mojo->new;
my $file = Mojo::Asset::File->new->add_chunk('lalala');
$t->post_ok('/upload' => form =>
{file => {file => $file, filename => 'x'}, test => 'tset'})
->status_is(200)->content_is('xlalalatsetfile,test');
->status_is(200)->content_is('xlalalatset');

# Path
$t->post_ok(
'/upload' => form => {file => {file => $file->path}, test => 'foo'})
->status_is(200)->content_like(qr!lalalafoofile,test$!);
->status_is(200)->content_like(qr!lalalafoo$!);

# Memory
$t->post_ok(
'/upload' => form => {file => {content => 'alalal'}, test => 'tset'})
->status_is(200)->content_is('filealalaltsetfile,test');
->status_is(200)->content_is('filealalaltset');

# Memory with headers
my $hash = {content => 'alalal', 'Content-Type' => 'foo/bar', 'X-X' => 'Y'};
$t->post_ok('/upload' => form => {file => $hash, test => 'tset'})
->status_is(200)->content_is('filealalaltsetfoo/barYfile,test');
->status_is(200)->content_is('filealalaltsetfoo/barY');

# Multiple file uploads
$t->post_ok('/multi?name=file1&name=file2' => form =>
Expand Down
11 changes: 6 additions & 5 deletions t/mojolicious/validation_lite_app.t
Expand Up @@ -32,19 +32,20 @@ my $t = Test::Mojo->new;

# Required and optional values
my $validation = $t->app->validation->input({foo => 'bar', baz => 'yada'});
is_deeply [$validation->error], [], 'no names';
is_deeply $validation->names, [], 'no names';
is_deeply $validation->error, [], 'no names';
is $validation->param('foo'), undef, 'no value';
is_deeply $validation->every_param('foo'), [], 'no values';
ok $validation->required('foo')->is_valid, 'valid';
is_deeply $validation->output, {foo => 'bar'}, 'right result';
is $validation->param('foo'), 'bar', 'right value';
is_deeply $validation->every_param('foo'), ['bar'], 'right values';
is_deeply [$validation->param], ['foo'], 'right names';
is_deeply $validation->names, ['foo'], 'right names';
ok !$validation->has_error, 'no error';
ok $validation->optional('baz')->is_valid, 'valid';
is_deeply $validation->output, {foo => 'bar', baz => 'yada'}, 'right result';
is $validation->param('baz'), 'yada', 'right value';
is_deeply [$validation->param], [qw(baz foo)], 'right names';
is_deeply $validation->names, [qw(baz foo)], 'right names';
ok !$validation->has_error, 'no error';
ok !$validation->optional('does_not_exist')->is_valid, 'not valid';
is_deeply $validation->output, {foo => 'bar', baz => 'yada'}, 'right result';
Expand All @@ -70,7 +71,7 @@ ok !$validation->optional('yada')->equal_to('foo')->is_valid, 'not valid';
is_deeply $validation->output, {foo => 'bar'}, 'right result';
ok $validation->has_error, 'has error';
is_deeply $validation->error('yada'), [qw(equal_to 1 foo)], 'right error';
is_deeply [$validation->error], [qw(baz yada)], 'right names';
is_deeply $validation->error, [qw(baz yada)], 'right names';

# In
$validation = $t->app->validation->input(
Expand All @@ -84,7 +85,7 @@ ok !$validation->required('baz')->in(qw(yada whatever))->is_valid, 'not valid';
is_deeply $validation->output, {foo => [qw(bar whatever)]}, 'right result';
ok $validation->has_error, 'has error';
is_deeply $validation->error('baz'), [qw(in 1 yada whatever)], 'right error';
is_deeply [$validation->error], ['baz'], 'right names';
is_deeply $validation->error, ['baz'], 'right names';

# Like
$validation = $t->app->validation->input({foo => 'bar', baz => 'yada'});
Expand Down

0 comments on commit 61f1e70

Please sign in to comment.