Skip to content

Commit

Permalink
added data attribute to Mojo::JSON::Pointer
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Feb 19, 2014
1 parent e025126 commit 57695bc
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 38 deletions.
1 change: 1 addition & 0 deletions Changes
@@ -1,5 +1,6 @@

4.82 2014-02-19
- Added data attribute to Mojo::JSON::Pointer.
- Added decode_json and encode_json functions to Mojo::JSON.
- Fixed small decoding error bug in Mojo::JSON.
- Fixed bug in "user_agent_online.t".
Expand Down
39 changes: 34 additions & 5 deletions lib/Mojo/JSON/Pointer.pm
Expand Up @@ -3,11 +3,16 @@ use Mojo::Base -base;

use Scalar::Util 'looks_like_number';

has 'data';

sub contains { shift->_pointer(1, @_) }
sub get { shift->_pointer(0, @_) }

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

sub _pointer {
my ($self, $contains, $data, $pointer) = @_;
($data, $pointer) = ($self->data, $data) unless defined $pointer;

return $data unless $pointer =~ s!^/!!;
for my $p ($pointer eq '' ? ($pointer) : (split '/', $pointer)) {
Expand Down Expand Up @@ -41,23 +46,38 @@ Mojo::JSON::Pointer - JSON Pointers
use Mojo::JSON::Pointer;
my $pointer = Mojo::JSON::Pointer->new;
say $pointer->get({foo => [23, 'bar']}, '/foo/1');
say 'Contains "/foo".' if $pointer->contains({foo => [23, 'bar']}, '/foo');
my $pointer = Mojo::JSON::Pointer->new({foo => [23, 'bar']});
say $pointer->get('/foo/1');
say 'Contains "/foo".' if $pointer->contains('/foo');
=head1 DESCRIPTION
L<Mojo::JSON::Pointer> is a relaxed implementation of
L<RFC 6901|http://tools.ietf.org/html/rfc6901>.
=head1 ATTRIBUTES
L<Mojo::JSON::Pointer> implements the following attributes.
=head2 data
my $data = $pointer->data;
$pointer = $pointer->data({foo => 'bar'});
Data to be processed.
=head1 METHODS
L<Mojo::JSON::Pointer> inherits all methods from L<Mojo::Base> and implements
the following new ones.
=head2 contains
my $bool = $pointer->contains('/foo/1');
my $bool = $pointer->contains($data, '/foo/1');
Check if data structure contains a value that can be identified with the given
JSON Pointer.
JSON Pointer, defaults to using L</data>.
# True
$pointer->contains({'♥' => 'mojolicious'}, '/♥');
Expand All @@ -71,9 +91,11 @@ JSON Pointer.
=head2 get
my $value = $pointer->get('/foo/bar');
my $value = $pointer->get($data, '/foo/bar');
Extract value identified by the given JSON Pointer.
Extract value identified by the given JSON Pointer, defaults to using
L</data>.
# "mojolicious"
$pointer->get({'♥' => 'mojolicious'}, '/♥');
Expand All @@ -87,6 +109,13 @@ Extract value identified by the given JSON Pointer.
# "6"
$pointer->get({foo => 'bar', baz => [4, 5, 6]}, '/baz/2');
=head2 new
my $pointer = Mojo::JSON::Pointer->new;
my $pointer = Mojo::JSON::Pointer->new({foo => 'bar'});
Build new L<Mojo::JSON::Pointer> object.
=head1 SEE ALSO
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>.
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojo/Message.pm
Expand Up @@ -144,7 +144,7 @@ sub json {
my ($self, $pointer) = @_;
return undef if $self->content->is_multipart;
my $data = $self->{json} ||= j($self->body);
return $pointer ? Mojo::JSON::Pointer->new->get($data, $pointer) : $data;
return $pointer ? Mojo::JSON::Pointer->new($data)->get($pointer) : $data;
}

sub param { shift->body_params->param(@_) }
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojolicious/Command/get.pm
Expand Up @@ -80,7 +80,7 @@ sub run {

sub _json {
return unless my $data = j(shift);
return unless defined($data = Mojo::JSON::Pointer->new->get($data, shift));
return unless defined($data = Mojo::JSON::Pointer->new($data)->get(shift));
return _say($data) unless ref $data eq 'HASH' || ref $data eq 'ARRAY';
say encode_json($data);
}
Expand Down
6 changes: 3 additions & 3 deletions lib/Test/Mojo.pm
Expand Up @@ -144,14 +144,14 @@ sub json_has {
my ($self, $p, $desc) = @_;
$desc ||= qq{has value for JSON Pointer "$p"};
return $self->_test('ok',
!!Mojo::JSON::Pointer->new->contains($self->tx->res->json, $p), $desc);
!!Mojo::JSON::Pointer->new($self->tx->res->json)->contains($p), $desc);
}

sub json_hasnt {
my ($self, $p, $desc) = @_;
$desc ||= qq{has no value for JSON Pointer "$p"};
return $self->_test('ok',
!Mojo::JSON::Pointer->new->contains($self->tx->res->json, $p), $desc);
!Mojo::JSON::Pointer->new($self->tx->res->json)->contains($p), $desc);
}

sub json_is {
Expand Down Expand Up @@ -288,7 +288,7 @@ sub _build_ok {

sub _json {
my ($self, $method, $p) = @_;
return Mojo::JSON::Pointer->new->$method(j(@{$self->message // []}[1]), $p);
return Mojo::JSON::Pointer->new(j(@{$self->message // []}[1]))->$method($p);
}

sub _message {
Expand Down
52 changes: 24 additions & 28 deletions t/mojo/json_pointer.t
Expand Up @@ -12,13 +12,12 @@ ok $pointer->contains({foo => {bar => undef}}, '/foo/bar'),
'contains "/foo/bar"';

# "contains" (mixed)
ok $pointer->contains({foo => [0, 1, 2]}, ''), 'contains ""';
ok $pointer->contains({foo => [0, 1, 2]}, '/foo/0'), 'contains "/foo/0"';
ok !$pointer->contains({foo => [0, 1, 2]}, '/foo/9'),
'does not contain "/foo/9"';
ok !$pointer->contains({foo => [0, 1, 2]}, '/foo/bar'),
'does not contain "/foo/bar"';
ok !$pointer->contains({foo => [0, 1, 2]}, '/0'), 'does not contain "/0"';
$pointer = Mojo::JSON::Pointer->new({foo => [0, 1, 2]});
ok $pointer->contains(''), 'contains ""';
ok $pointer->contains('/foo/0'), 'contains "/foo/0"';
ok !$pointer->contains('/foo/9'), 'does not contain "/foo/9"';
ok !$pointer->contains('/foo/bar'), 'does not contain "/foo/bar"';
ok !$pointer->contains('/0'), 'does not contain "/0"';

# "get" (hash)
is_deeply $pointer->get({foo => 'bar'}, ''), {foo => 'bar'},
Expand All @@ -31,14 +30,11 @@ is_deeply $pointer->get({foo => {23 => {baz => 0}}}, '/foo/23'), {baz => 0},
# "get" (mixed)
is_deeply $pointer->get({foo => {bar => [1, 2, 3]}}, '/foo/bar'), [1, 2, 3],
'"/foo/bar" is "[1, 2, 3]"';
is $pointer->get({foo => {bar => [0, undef, 3]}}, '/foo/bar/0'), 0,
'"/foo/bar/0" is "0"';
is $pointer->get({foo => {bar => [0, undef, 3]}}, '/foo/bar/1'), undef,
'"/foo/bar/1" is "undef"';
is $pointer->get({foo => {bar => [0, undef, 3]}}, '/foo/bar/2'), 3,
'"/foo/bar/2" is "3"';
is $pointer->get({foo => {bar => [0, undef, 3]}}, '/foo/bar/6'), undef,
'"/foo/bar/6" is "undef"';
$pointer = Mojo::JSON::Pointer->new({foo => {bar => [0, undef, 3]}});
is $pointer->get('/foo/bar/0'), 0, '"/foo/bar/0" is "0"';
is $pointer->get('/foo/bar/1'), undef, '"/foo/bar/1" is "undef"';
is $pointer->get('/foo/bar/2'), 3, '"/foo/bar/2" is "3"';
is $pointer->get('/foo/bar/6'), undef, '"/foo/bar/6" is "undef"';

# "get" (encoded)
is $pointer->get([{'foo/bar' => 'bar'}], '/0/foo~1bar'), 'bar',
Expand Down Expand Up @@ -69,18 +65,18 @@ my $hash = {
' ' => 7,
'm~n' => 8
};
is_deeply $pointer->get($hash, ''), $hash, 'empty pointer is whole document';
is_deeply $pointer->get($hash, '/foo'), ['bar', 'baz'],
'"/foo" is "["bar", "baz"]"';
is $pointer->get($hash, '/foo/0'), 'bar', '"/foo/0" is "bar"';
is $pointer->get($hash, '/'), 0, '"/" is 0';
is $pointer->get($hash, '/a~1b'), 1, '"/a~1b" is 1';
is $pointer->get($hash, '/c%d'), 2, '"/c%d" is 2';
is $pointer->get($hash, '/e^f'), 3, '"/e^f" is 3';
is $pointer->get($hash, '/g|h'), 4, '"/g|h" is 4';
is $pointer->get($hash, '/i\\j'), 5, '"/i\\\\j" is 5';
is $pointer->get($hash, '/k"l'), 6, '"/k\\"l" is 6';
is $pointer->get($hash, '/ '), 7, '"/ " is 7';
is $pointer->get($hash, '/m~0n'), 8, '"/m~0n" is 8';
$pointer = Mojo::JSON::Pointer->new($hash);
is_deeply $pointer->get(''), $hash, 'empty pointer is whole document';
is_deeply $pointer->get('/foo'), ['bar', 'baz'], '"/foo" is "["bar", "baz"]"';
is $pointer->get('/foo/0'), 'bar', '"/foo/0" is "bar"';
is $pointer->get('/'), 0, '"/" is 0';
is $pointer->get('/a~1b'), 1, '"/a~1b" is 1';
is $pointer->get('/c%d'), 2, '"/c%d" is 2';
is $pointer->get('/e^f'), 3, '"/e^f" is 3';
is $pointer->get('/g|h'), 4, '"/g|h" is 4';
is $pointer->get('/i\\j'), 5, '"/i\\\\j" is 5';
is $pointer->get('/k"l'), 6, '"/k\\"l" is 6';
is $pointer->get('/ '), 7, '"/ " is 7';
is $pointer->get('/m~0n'), 8, '"/m~0n" is 8';

done_testing();

0 comments on commit 57695bc

Please sign in to comment.