Skip to content

Commit

Permalink
HTML::Selector::XPath support (optional)
Browse files Browse the repository at this point in the history
This adds 2 new attributes to ->new:

css_selector => 1 means that any paths passed to ok/is/etc will
first be transformed by HTML::Selector::XPath (if it is available,
or the script will die).

path_generator => sub { ... } allows people to pass a custom sub
to generate XPaths from the string passed, which may come in
handy for someone
  • Loading branch information
Oliver Charles committed Sep 28, 2009
1 parent aa8c308 commit d808632
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 10 deletions.
22 changes: 13 additions & 9 deletions Build.PL
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,31 @@ use Module::Build;
Module::Build->new(
module_name => 'Test::XPath',
license => 'perl',
configure_requires => {
'Module::Build' => '0.30',
},
configure_requires => { 'Module::Build' => '0.30', },
build_requires => {
'Module::Build' => '0.30',
'Test::More' => '0.70',
},
requires => {
requires => {
'Test::Builder' => '0.70',
'XML::LibXML' => '1.69',
'perl' => 5.006002,
},
recommends => {
recommends => {
'Test::Pod' => '1.20',
'Test::Pod::Coverage' => '1.06',
},
meta_merge => {
auto_features => {
selectors => {
description => 'CSS selectors support',
requires => { 'HTML::Selector::XPath' => '0.03', }
}
},
meta_merge => {
resources => {
homepage => 'http://search.cpan.org/dist/Test-XPath/',
bugtracker => 'http://github.com/theory/test-xpath/issues/',
repository => 'http://github.com/theory/test-xpath/tree/',
homepage => 'http://search.cpan.org/dist/Test-XPath/',
bugtracker => 'http://github.com/theory/test-xpath/issues/',
repository => 'http://github.com/theory/test-xpath/tree/',
}
},
)->create_build_script;
36 changes: 35 additions & 1 deletion lib/Test/XPath.pm
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,16 @@ sub new {
return bless {
xpc => $xpc,
node => $doc->documentElement,
gen => $p{xpath_generator}
|| ($p{css_selector} ? \&_css_selector : sub { shift })
};
}

sub ok {
my ($self, $xpath, $code, $desc) = @_;
my $xpc = $self->{xpc};
my $Test = Test::Builder->new;
$xpath = $self->{gen}->($xpath);

# Code and desc can be reversed, to support PerlX::MethodCallWithBlock.
($code, $desc) = ($desc, $code) if ref $desc eq 'CODE';
Expand Down Expand Up @@ -54,6 +57,7 @@ sub ok {

sub not_ok {
my ($self, $xpath, $desc) = @_;
$xpath = $self->{gen}->($xpath);
my $Test = Test::Builder->new;
$Test->ok( !$self->{xpc}->exists($xpath, $self->{node}), $desc);
}
Expand All @@ -69,7 +73,7 @@ sub xpc { shift->{xpc} }

sub _findv {
my $self = shift;
$self->{xpc}->findvalue(shift, $self->{node});
$self->{xpc}->findvalue($self->{gen}->(shift), $self->{node});
}

sub _doc {
Expand Down Expand Up @@ -104,6 +108,14 @@ sub _doc {
);
}

sub _css_selector {
my $path = shift;
eval 'require HTML::Selector::XPath';
die "Please install HTML::Selector::XPath to use CSS selectors"
if $@;
return HTML::Selector::XPath->new($path)->to_xpath;
}

# Add Test::XML::XPath compatibility?
# sub like_xpath($$;$) { __PACKAGE__->new( xml => shift )->ok( @_ ) }
# sub unlike_xpath($$;$) { __PACKAGE__->new( xml => shift )->not_ok( @_ ) }
Expand Down Expand Up @@ -365,6 +377,28 @@ L<XML::LibXML::Parser options|XML::LibXML::Parser/"PARSER OPTIONS">, such as
"validation", "recover", and "no_network". These can be useful for tweaking
the behavior of the parser.
=item C<css_selector>
css_selector => 1,
Any paths passed to ok(), is() etc will be first preprocessed by
HTML::Selector::XPath. This allows you to use CSS selector syntax, which can
be more compact for simple expressions. For example:
$tx->is('div#content div.article h1', '...')
Is equivilent to:
$tx->is('//div[@id="content"]//div[@class="article"]//h1', '...')
=item C<path_generator>
path_generator => sub { my $xpath = shift; }
Allows a subroutine reference to be passed in, which will be used whenever a XPath
is required. This allows you to transform the XPath, for example you may have
some custom syntax which is much more concise than an XPath.
=back
=head1 Instance Interface
Expand Down

0 comments on commit d808632

Please sign in to comment.