Skip to content

Instantly share code, notes, and snippets.

@maio
Created August 9, 2011 21:34
Show Gist options
  • Save maio/1135264 to your computer and use it in GitHub Desktop.
Save maio/1135264 to your computer and use it in GitHub Desktop.
Jasmine matchers clone in Perl
# Perl clone of:
# https://github.com/pivotal/jasmine/wiki/Matchers
# https://github.com/pivotal/jasmine/wiki
use Test::Spec;
# usage
describe 'Expect' => sub {
describe 'implementing matcher' => sub {
it toEqual => sub {
expect(10)->toEqual(10);
};
it toContain => sub {
expect( [ 1, 2, 3 ] )->toContain(3);
};
it toMatch => sub {
expect('abcd')->toMatch(qr/bc/);
};
it toThrow => sub {
expect( sub { die 'miserable failure' } )
->toThrow(qr/miserable failure/);
};
};
it 'supports custom matcher' => sub {
registerMatchers( toPass => sub { pass() } );
expect("anything")->toPass();
};
};
# testing framework specific code (Test::Spec, Test::Class, ...)
my %customMatcher; # fw should reset this at appropriate time (after each test?)
sub registerMatchers { %customMatcher = ( %customMatcher, @_ ); }
sub expect {
my $expect = Expect->new( given => shift );
while (my ($name, $codeRef) = each %customMatcher) {
$expect->registerMatcher( $name => $codeRef);
}
return $expect;
}
# expectation library
{
package Expect;
use Moose;
use Test::More;
use Test::Exception;
use Data::Dump 'pp';
has 'given' => ( is => 'ro' );
has 'matcher' => (
traits => ['Hash'],
is => 'rw',
isa => 'HashRef[CodeRef]',
handles => {
registerMatcher => 'set',
},
default => sub {
return {
toEqual => sub {
my ( $given, $actual ) = @_;
is( $given, $actual );
},
toContain => sub {
my ( $given, $actual ) = @_;
ok( $actual ~~ $given ) or do {
diag("");
diag("Expected " . pp($given) . " to contain " .
pp($actual) . ".");
diag("");
}
},
toMatch => sub {
my ( $given, $actual ) = @_;
like( $given, $actual );
},
toThrow => sub {
my ( $given, $actual ) = @_;
throws_ok(sub { $given->(); }, $actual);
},
}
}
);
our $AUTOLOAD;
sub AUTOLOAD {
my ($self, @args) = @_;
my $name = $AUTOLOAD;
$name =~ s/.*://;
local $Test::Builder::Level = $Test::Builder::Level + 2;
$self->matcher->{$name}->($self->given, @args);
# TODO: throw unknown matcher error
}
1;
}
runtests unless caller;
guard 'prove' do
watch(%r{^.*\.t$})
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment