Test-XML-Simple-1.04/000755 005064 000024 00000000000 12101047361 015515 5ustar00joemcmahonstaff000000 000000 Test-XML-Simple-1.04/Changes000644 005064 000024 00000004570 12101046670 017020 0ustar00joemcmahonstaff000000 000000 Revision history for Perl extension Test::XML::Simple. 1.04 Sat Jan 26 13:42:07 PST 2013 - Update POD 1.03 Sat Jan 26 13:37:11 PST 2013 - Update README 1.02 Fri Jan 25 18:09:24 PST 2013 - Added ability to pass in a XML::LibXML::Document object - clean up unused variable Thanks to bor@GitHub (Sergiy Borodych) for the fixes! 1.01 Tue Jun 5 12:44:22 PDT 2012 - Changed LEGAL section to LICENSE so CPANTS sees it. - Change XML::LibXML min version to 1.99 so tests are consistent. 1.00 Sat Sep 19 02:52:31 PDT 2009 - Switched to Test::Builder::Tester for testing to get rid of problems with threaded Perls and Test::Builder::Capture. - Fixed test levels for call so that test failures are reported at the invocation of the test rather than down inside the module. 0.10 Sun Aug 23 15:29:16 PDT 2009 - Added license - Added Test::LongString prereq as per AKAPLAN - Fixed META.yml to be a known-good format 0.09 Tue Dec 20 17:20:44 PST 2005 - xml_like did not return a true value when it works properly. 0.08 Tue Dec 20 16:04:14 PST 2005 - Make sure the backup error message for xml_like includes the user's supplied comment. 0.07 Tue Dec 20 14:25:52 PST 2005 - change xml_like to search through all text and CDATA sections whe doing a match. 0.06 Fri Dec 9 16:42:11 PST 2005 - Fixed some really egregious errors in the XML comparisons. (Note to self: find *all* the interface differences next time!) - added _long versions of the test functions. these use Test::More's comparisons. The xml_is, xml_like, and xml_is_deeply functions all use Test::Longstring, for those who want the same tests, less filling. 0.05 Mon Nov 28 14:41:58 2005 - Switched to XML::LibXML - reordered Test::Tester to the top in all tests - fixed test tests that had no result testing - tests now fail with the appropriate message instead of diag'ing it 0.04 Wed Sep 14 14:43:10 2005 - Fixed xml_is and xml_like to handle attributes better (//node[@attr] will now actually return the value of the attribute instead of dying) 0.03 Thu Sep 8 17:36:52 2005 - Updated docs (included docs for xml_is_deeply) - Added tests 0.02 Thu Apr 21 14:05:42 2005 - added Test::Tester to the prereqs (oops). 0.01 Tue Mar 1 08:18:07 2005 - original version; created by h2xs 1.21 with options -AX -n Test::XML::Simple Test-XML-Simple-1.04/lib/000755 005064 000024 00000000000 12101047361 016263 5ustar00joemcmahonstaff000000 000000 Test-XML-Simple-1.04/Makefile.PL000644 005064 000024 00000001542 12100635213 017467 0ustar00joemcmahonstaff000000 000000 use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. WriteMakefile( 'NAME' => 'Test::XML::Simple', 'VERSION_FROM' => 'lib/Test/XML/Simple.pm', # finds $VERSION 'LICENSE' => 'artistic', 'PREREQ_PM' => { Test::Builder => 0, Test::Builder::Tester => 0, Test::More => 0, Test::LongString => 0, XML::LibXML => 1.99, }, # e.g., Module::Name => 1.1 ($] >= 5.005 ? ## Add these new keywords supported since 5.005 (ABSTRACT_FROM => 'lib/Test/XML/Simple.pm', # retrieve abstract from module AUTHOR => 'Joe McMahon ') : ()), ); Test-XML-Simple-1.04/MANIFEST000644 005064 000024 00000000527 12101047361 016652 0ustar00joemcmahonstaff000000 000000 Changes lib/Test/XML/Simple.pm Makefile.PL MANIFEST README t/01load.t t/02import.t t/03valid.t t/04node.t t/05is.t t/06like.t t/07deeply.t t/08attr.t t/pod-coverage.t t/pod.t META.yml Module YAML meta-data (added by MakeMaker) META.json Module JSON meta-data (added by MakeMaker) Test-XML-Simple-1.04/META.json000644 005064 000024 00000002001 12101047361 017127 0ustar00joemcmahonstaff000000 000000 { "abstract" : "easy testing for XML", "author" : [ "Joe McMahon " ], "dynamic_config" : 1, "generated_by" : "ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.120630", "license" : [ "artistic_1" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : "2" }, "name" : "Test-XML-Simple", "no_index" : { "directory" : [ "t", "inc" ] }, "prereqs" : { "build" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "Test::Builder" : "0", "Test::Builder::Tester" : "0", "Test::LongString" : "0", "Test::More" : "0", "XML::LibXML" : "1.99" } } }, "release_status" : "stable", "version" : "1.04" } Test-XML-Simple-1.04/META.yml000644 005064 000024 00000001075 12101047361 016771 0ustar00joemcmahonstaff000000 000000 --- abstract: 'easy testing for XML' author: - 'Joe McMahon ' build_requires: ExtUtils::MakeMaker: 0 configure_requires: ExtUtils::MakeMaker: 0 dynamic_config: 1 generated_by: 'ExtUtils::MakeMaker version 6.62, CPAN::Meta::Converter version 2.120630' license: artistic meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: 1.4 name: Test-XML-Simple no_index: directory: - t - inc requires: Test::Builder: 0 Test::Builder::Tester: 0 Test::LongString: 0 Test::More: 0 XML::LibXML: 1.99 version: 1.04 Test-XML-Simple-1.04/README000644 005064 000024 00000002037 12101046102 016367 0ustar00joemcmahonstaff000000 000000 Test::XML::Simple ============================ This module provides a test class which makes it easy to do basic Test::More style tests on XML input. use Test::XML::Simple test => 5; xml_valid $xml, 'Is valid XML'; xml_node $xml, "/xpath/expression", "specified xpath node is present"; xml_text_is $xml, '/xpath/expr', "expected value", "specified text present"; xml_text_like $xml, '/xpath/expr', qr/expected/, "regex text present"; xml_is_deeply $xml, '/xpath/expr', $xml_fragment, "fragment matches path"; INSTALLATION To install this module type the following: perl Makefile.PL make make test make install DEPENDENCIES This module requires these other modules and libraries: Test::Builder Test::LongString Test::More XML::LibXML COPYRIGHT AND LICENCE Copyright (C) 2005-2013 by Yahoo! and Joe McMahon This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.6.1 or, at your option, any later version of Perl 5 you may have available. Test-XML-Simple-1.04/t/000755 005064 000024 00000000000 12101047361 015760 5ustar00joemcmahonstaff000000 000000 Test-XML-Simple-1.04/t/01load.t000644 005064 000024 00000000070 12100635213 017220 0ustar00joemcmahonstaff000000 000000 use Test::More tests => 1; use_ok("Test::XML::Simple"); Test-XML-Simple-1.04/t/02import.t000644 005064 000024 00000000434 12100635213 017620 0ustar00joemcmahonstaff000000 000000 use Test::More tests => 5; use Test::XML::Simple; ok(defined \&xml_valid, "xml_valid imported"); ok(defined \&xml_node, "xml_node imported"); ok(defined \&xml_is, "xml_is imported"); ok(defined \&xml_is_deeply, "xml_is_deeply imported"); ok(defined \&xml_like, "xml_like imported"); Test-XML-Simple-1.04/t/03valid.t000644 005064 000024 00000002630 12100635224 017410 0ustar00joemcmahonstaff000000 000000 use Test::Builder::Tester tests=>6; use Test::More; use Test::XML::Simple; use XML::LibXML; my $totally_invalid = < but this isn't good EOS my $valid = < Sacred Love Sting USA A&M 12.99 2003 EOS my $xml_doc = XML::LibXML->createDocument( '1.0' ); my $not_xml_doc = bless {}, 'Foo::Bar'; test_out("not ok 1 - XML is not defined"); test_fail(+1); xml_valid(undef, "no xml"); test_test('undef'); test_out("not ok 1 - string can't contain XML: no tags"); test_fail(+1); xml_valid($totally_invalid, "invalid xml"); test_test('non-XML string'); test_out("ok 1 - good xml"); xml_valid($valid, "good xml"); test_test('good xml'); test_out("not ok 1 - :2: parser error : Premature end of data in tag nomatch line 1\n# \n# ^\n# :2: parser error : Premature end of data in tag imatag line 1\n# \n# ^"); test_fail(+1); xml_valid($broken_xml, "invalid xml"); test_test(title=>'bad XML', skip_err=>1); test_out('ok 1 - good xml doc object'); xml_valid( $xml_doc, 'good xml doc object' ); test_test('good xml doc object'); test_out("not ok 1 - accept only 'XML::LibXML::Document' as object"); test_fail(+1); xml_valid( $not_xml_doc, 'not xml doc object' ); test_test('not xml doc object'); Test-XML-Simple-1.04/t/04node.t000644 005064 000024 00000001427 12100635213 017240 0ustar00joemcmahonstaff000000 000000 use Test::Builder::Tester tests => 4; use Test::XML::Simple; my $xml = < Sacred Love Sting USA A&M 12.99 2003 EOS test_out('ok 1 - good node'); xml_node($xml, "//ARTIST", "good node"); test_test('xml_node, good node'); test_out("not ok 1 - Couldn't find /CATALOG/ARTIST"); test_fail(+1); xml_node($xml, "/CATALOG/ARTIST", "bad path"); test_test('xml_node, bad path'); test_out('ok 1 - full path'); xml_node($xml, "/CATALOG/CD/ARTIST", "full path"); test_test('xml_node, full path'); test_out("not ok 1 - Couldn't find //FORMAT"); test_fail(+1); xml_node($xml, "//FORMAT", "bad node"); test_test('xml_node, bad node'); Test-XML-Simple-1.04/t/05is.t000644 005064 000024 00000002606 12100635213 016727 0ustar00joemcmahonstaff000000 000000 use Test::Builder::Tester; use Test::More tests=>6; use Test::XML::Simple; my $xml = < Sacred Love Sting USA A&M 12.99 2003 EOS test_out("ok 1 - good node"); xml_is($xml, "//ARTIST", 'Sting', "good node"); test_test("node match"); test_out('ok 1 - good node'); xml_is_long($xml, "//ARTIST", 'Sting', "good node"); test_test("long node match"); test_out('ok 1 - full path'); xml_is($xml, "/CATALOG/CD/ARTIST", 'Sting', "full path"); test_test("node match"); test_out('ok 1 - full path'); xml_is_long($xml, "/CATALOG/CD/ARTIST", 'Sting', "full path"); test_test("long node match"); test_out('not ok 1 - good node'); test_err(qq<# Failed test 'good node' # at t/05is.t line 43. # got: "Sting" # length: 5 # expected: "Weird Al" # length: 8 # strings begin to differ at char 1 (line 1 column 1)>); xml_is($xml, "//ARTIST", 'Weird Al', "good node"); test_test("node miss"); test_out('not ok 1 - full path'); test_err(qq<# Failed test 'full path' # at t/05is.t line 54. # got: "Sting" # length: 5 # expected: "Weird Al" # length: 8 # strings begin to differ at char 1 (line 1 column 1)>); xml_is($xml, "/CATALOG/CD/ARTIST", 'Weird Al', "full path"); test_test("full path miss"); Test-XML-Simple-1.04/t/06like.t000644 005064 000024 00000002073 12100635213 017237 0ustar00joemcmahonstaff000000 000000 use Test::Builder::Tester tests=>4; use Test::XML::Simple; my $xml = < Sacred Love Sting USA A&M 12.99 2003 EOS test_out('ok 1 - good node'); xml_like($xml, "//ARTIST", qr/st/i, "good node"); test_test('node match'); test_out('ok 1 - full path'); xml_like($xml, "/CATALOG/CD/ARTIST", qr/ing/, "full path"); test_test('full path match'); test_out('not ok 1 - good node - no match in tag contents (including CDATA)'); test_err(qq(# Failed test 'good node - no match in tag contents (including CDATA)' # at t/06like.t line 29.) ); xml_like($xml, "//ARTIST", qr/Weird Al/, "good node"); test_test('bad node match'); test_out('not ok 1 - full path - no match in tag contents (including CDATA)'); test_err(qq(# Failed test 'full path - no match in tag contents (including CDATA)' # at t/06like.t line 35.) ); xml_like($xml, "/CATALOG/CD/ARTIST", qr/Weird Al/, "full path"); test_test('bad full path match'); Test-XML-Simple-1.04/t/07deeply.t000644 005064 000024 00000001064 12100635213 017575 0ustar00joemcmahonstaff000000 000000 use Test::Builder::Tester tests=>2; use Test::XML::Simple; my $xml = < Sacred Love Sting USA A&M 12.99 2003 EOS my $fragment = <Sting EOS test_out("ok 1 - deep match"); xml_is_deeply($xml, "//ARTIST", $fragment, "deep match"); test_test('deep match'); test_out('ok 1 - identical match'); xml_is_deeply($xml, "/", $xml, "identical match"); test_test('identical match'); Test-XML-Simple-1.04/t/08attr.t000644 005064 000024 00000001132 12100635213 017262 0ustar00joemcmahonstaff000000 000000 use Test::Builder::Tester tests=>3; use Test::XML::Simple; my $with_attr = <this is a result EOS test_out('ok 1 - nonempty works'); xml_is($with_attr, '//results/@total', "1", "nonempty works"); test_test('nonempty'); my $two_tag = < EOS test_out('ok 1 - two-tag works'); xml_is($two_tag, '//results/@total', "0", "two-tag works"); test_test('two-tag'); my $collapsed = < EOS test_out('ok 1 - collapsed works'); xml_is($collapsed, '//results/@total', "0", "collapsed works"); test_test('collapsed'); Test-XML-Simple-1.04/t/pod-coverage.t000644 005064 000024 00000000255 12100635213 020520 0ustar00joemcmahonstaff000000 000000 #!perl -Tw use Test::More; eval "use Test::Pod::Coverage 1.04"; plan skip_all => "Test::Pod::Coverage 1.04 required for testing POD coverage" if $@; all_pod_coverage_ok(); Test-XML-Simple-1.04/t/pod.t000644 005064 000024 00000000215 12100635213 016723 0ustar00joemcmahonstaff000000 000000 #!perl -Tw use Test::More; eval "use Test::Pod 1.14"; plan skip_all => "Test::Pod 1.14 required for testing POD" if $@; all_pod_files_ok(); Test-XML-Simple-1.04/lib/Test/000755 005064 000024 00000000000 12101047361 017202 5ustar00joemcmahonstaff000000 000000 Test-XML-Simple-1.04/lib/Test/XML/000755 005064 000024 00000000000 12101047361 017642 5ustar00joemcmahonstaff000000 000000 Test-XML-Simple-1.04/lib/Test/XML/Simple.pm000644 005064 000024 00000017476 12101046701 021445 0ustar00joemcmahonstaff000000 000000 package Test::XML::Simple; use strict; use warnings; our $VERSION = '1.04'; use Test::Builder; use Test::More; use Test::LongString; use XML::LibXML; my $Test = Test::Builder->new(); my $Xml; sub import { my $self = shift; my $caller = caller; no strict 'refs'; *{$caller.'::xml_valid'} = \&xml_valid; *{$caller.'::xml_node'} = \&xml_node; *{$caller.'::xml_is'} = \&xml_is; *{$caller.'::xml_is_long'} = \&xml_is_long; *{$caller.'::xml_is_deeply'} = \&xml_is_deeply; *{$caller.'::xml_is_deeply_long'} = \&xml_is_deeply_long; *{$caller.'::xml_like'} = \&xml_like; *{$caller.'::xml_like_long'} = \&xml_like_long; $Test->exported_to($caller); $Test->plan(@_); } sub xml_valid($;$) { my ($xml, $comment) = @_; my $parsed_xml = _valid_xml($xml); return 0 unless $parsed_xml; ok $parsed_xml, $comment; } sub _valid_xml { my $xml = shift; local $Test::Builder::Level = $Test::Builder::Level + 2; return fail("XML is not defined") unless defined $xml; return fail("XML is missing") unless $xml; if ( ref $xml ) { return fail("accept only 'XML::LibXML::Document' as object") unless ref $xml eq 'XML::LibXML::Document'; $Xml = $xml; } else { return fail("string can't contain XML: no tags") unless ($xml =~ //); eval { $Xml = XML::LibXML->new->parse_string($xml); }; do { chomp $@; return fail($@) } if $@; } return $Xml; } sub _find { my ($xml_xpath, $xpath) = @_; my @nodeset = $xml_xpath->findnodes($xpath); local $Test::Builder::Level = $Test::Builder::Level + 2; return fail("Couldn't find $xpath") unless @nodeset; wantarray ? @nodeset : \@nodeset; } sub xml_node($$;$) { my ($xml, $xpath, $comment) = @_; my $parsed_xml = _valid_xml($xml); return 0 unless $parsed_xml; my $nodeset = _find($parsed_xml, $xpath); return 0 if !$nodeset; ok(scalar @$nodeset, $comment); } sub xml_is($$$;$) { _xml_is(\&is_string, @_); } sub xml_is_long($$$;$) { _xml_is(\&is, @_); } sub _xml_is { my ($comp_sub, $xml, $xpath, $value, $comment) = @_; local $Test::Builder::Level = $Test::Builder::Level + 2; my $parsed_xml = _valid_xml($xml); return 0 unless $parsed_xml; my $nodeset = _find($parsed_xml, $xpath); return 0 if !$nodeset; foreach my $node (@$nodeset) { my @kids = $node->getChildNodes; if (@kids) { $comp_sub->($kids[0]->toString, $value, $comment); } else { my $got = $node->toString; $got =~ s/^.*="(.*)"/$1/; is $got, $value, $comment; } } } sub xml_is_deeply($$$;$) { _xml_is_deeply(\&is_string, @_); } sub xml_is_deeply_long($$$;$) { _xml_is_deeply(\&is, @_); } sub _xml_is_deeply { my ($is_sub, $xml, $xpath, $candidate, $comment) = @_; my $parsed_xml = _valid_xml($xml); return 0 unless $parsed_xml; my $candidate_xp; eval {$candidate_xp = XML::LibXML->new->parse_string($candidate) }; return 0 unless $candidate_xp; my $parsed_thing = $parsed_xml->findnodes($xpath)->[0]; my $candidate_thing = $candidate_xp->findnodes('/')->[0]; $candidate_thing = $candidate_thing->documentElement if $parsed_thing->isa('XML::LibXML::Element'); $is_sub->($parsed_thing->toString, $candidate_thing->toString, $comment); } sub xml_like($$$;$) { _xml_like(\&like_string, @_); } sub xml_like_long($$$;$) { _xml_like(\&like, @_); } sub _xml_like { my ($like_sub, $xml, $xpath, $regex, $comment) = @_; my $parsed_xml = _valid_xml($xml); return 0 unless $parsed_xml; my $nodeset = _find($parsed_xml, $xpath); return 0 if !$nodeset; foreach my $node (@$nodeset) { my @kids = $node->getChildNodes; my $found; if (@kids) { foreach my $kid (@kids) { if ($kid->toString =~ /$regex/) { $found = 1; return $like_sub->($kid->toString, $regex, $comment); } } if (! $found) { $comment = "(no comment)" unless defined $comment; local $Test::Builder::Level = $Test::Builder::Level + 2; return ok(0, "$comment - no match in tag contents (including CDATA)"); } } else { my $got = $node->toString; $got =~ s/^.*="(.*)"/$1/; local $Test::Builder::Level = $Test::Builder::Level + 2; return $like_sub->(like $got, $regex, $comment); } } } 1; __END__ =head1 NAME Test::XML::Simple - easy testing for XML =head1 SYNOPSIS use Test::XML::Simple tests => 8; # pass string with XML as argument xml_valid $xml, "Is valid XML"; xml_node $xml, "/xpath/expression", "specified xpath node is present"; xml_is, $xml, '/xpath/expr', "expected value", "specified text present"; xml_like, $xml, '/xpath/expr', qr/expected/, "regex text present"; xml_is_deeply, $xml, '/xpath/expr', $xml2, "structure and contents match"; # XML::LibXML::Document can be passed as argument too # that allow you to test a big documents with several tests my $xml_doc = XML::LibXML->createDocument( '1.0' ); xml_valid $xml_doc, 'Is valid XML'; xml_node $xml_doc, '/xpath/expression', 'specified xpath node is present'; xml_like, $xml_doc, '/xpath/expression', qr/expected result/, 'regex present'; # Not yet implemented: # xml_like_deeply would be nice too... =head1 DESCRIPTION C is a very basic class for testing XML. It uses the XPath syntax to locate nodes within the XML. You can also check all or part of the structure vs. an XML fragment. All routines accept as first argument string with XML or XML::LibXML::Document object. =head1 TEST ROUTINES =head2 xml_valid $xml, 'test description' Pass an XML file or fragment to this test; it succeeds if the XML (fragment) is valid. =head2 xml_node $xml, $xpath, 'test description' Checks the supplied XML to see if the node described by the supplied XPath expression is present. Test fails if it is not present. =head2 xml_is_long $xml, $xpath, $value, 'test description' Finds the node corresponding to the supplied XPath expression and compares it to the supplied value. Succeeds if the two values match. Uses Test::More's C function to do the comparison. =head2 xml_is $xml, $xpath, $value, 'test description' Finds the node corresponding to the supplied XPath expression and compares it to the supplied value. Succeeds if the two values match. Uses Test::LongString's C function to do the test. =head2 xml_like_long $xml, $xpath, $regex, 'test description' Find the XML corresponding to the the XPath expression and check it against the supplied regular expression. Succeeds if they match. Uses Test::More's C function to do the comparison. =head2 xml_like $xml, $xpath, $regex, 'test description' Find the XML corresponding to the the XPath expression and check it against the supplied regular expression. Succeeds if they match. Uses Test::LongString's C function to do the test. =head2 xml_is_deeply_long $xml, $xpath, $xml2, 'test description' Find the piece of XML corresponding to the XPath expression, and compare its structure and contents to the second XML (fragment) supplied. Succeeds if they match in structure and content. Uses Test::More's C function to do the comparison. =head2 xml_is_deeply $xml, $xpath, $xml2, 'test description' Find the piece of XML corresponding to the XPath expression, and compare its structure and contents to the second XML (fragment) supplied. Succeeds if they match in structure and content. Uses Test::LongString's C function to do the test. =head1 AUTHOR Joe McMahon, Emcmahon@cpan.orgE =head1 LICENSE Copyright (c) 2005-2013 by Yahoo! and Joe McMahon This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.6.1 or, at your option, any later version of Perl 5 you may have available. =head1 SEE ALSO L, L, L. =cut