use strictures 1; use Test::More; use HTML::Zoom::Parser::BuiltIn; use HTML::Zoom::Producer::BuiltIn; use HTML::Zoom::SelectorParser; use HTML::Zoom::FilterBuilder; use HTML::Zoom::FilterStream; my $tmpl = <
Bob Builder
END sub src_stream { HTML::Zoom::Parser::BuiltIn->new->html_to_stream($tmpl); } sub html_sink { HTML::Zoom::Producer::BuiltIn->new->html_from_stream($_[0]) } my $fb = HTML::Zoom::FilterBuilder->new; my $sp = HTML::Zoom::SelectorParser->new; sub filter { my ($stream, $sel, $cb) = @_; return HTML::Zoom::FilterStream->new({ stream => $stream, match => $sp->parse_selector($sel), filter => do { local $_ = $fb; $cb->($fb) } }); } sub run_for (&;$) { my $cb = shift; (html_sink (filter src_stream, (shift or '.main'), $cb ) ) } my ($expect, @ev); ($expect = $tmpl) =~ s/class="main"/class="foo"/; is( run_for { $_->set_attribute( 'class' => 'foo' ) }, $expect, 'set attribute on existing attribute' ); ($expect = $tmpl) =~ s/name="cow" class="main"/name="bar" class="foo"/; is( run_for { $_->set_attr({ 'class' => 'foo', 'name' => 'bar'}) }, $expect, 'set attributes using hashref form (shorthand)' ); ($expect = $tmpl) =~ s/class="main"/class="main" foo="bar"/; is( run_for { $_->set_attribute( 'foo' => 'bar' ) }, $expect, 'set attribute on non existing attribute' ); ($expect = $tmpl) =~ s/class="main"/class="main foo"/; is( run_for { $_->add_to_attribute( 'class' => 'foo' ) }, $expect, 'add attribute on existing attribute' ); ($expect = $tmpl) =~ s/class="main"/class="main foo"/; is( run_for { $_->add_class('foo') }, $expect, 'add attribute on existing attribute (shorthand)' ); ($expect = $tmpl) =~ s/class="main"/class="main" id="foo"/; is( run_for { $_->set_id('foo') }, $expect, 'set_id (shorthand)' ); ($expect = $tmpl) =~ s/class="main"/class="main" foo="bar"/; is( run_for { $_->add_to_attribute( 'foo' => 'bar' ) }, $expect, 'add attribute on non existing attribute' ); ($expect = $tmpl) =~ s/ class="main"//; is( run_for { $_->remove_attribute({ name => 'class' }) }, $expect, 'remove attribute on existing attribute' ); is( run_for { $_->remove_attribute({ name => 'foo' }) }, $tmpl, 'remove attribute on non existing attribute' ); ($expect = $tmpl) =~ s/class="main"/class=""/; is( run_for { $_->remove_from_attribute({ class => 'main' }) }, $expect, 'remove name from attribute' ); is( run_for { $_->remove_from_attribute({ madeup => 'main' }) }, $tmpl, 'remove name from non existing attribute (ignored)' ); ($expect = $tmpl) =~ s/class="main"/class=""/; is( run_for { $_->remove_class( 'main' ) }, $expect, 'remove_class' ); ($expect = $tmpl) =~ s/ class="main"//; is( run_for { $_->transform_attribute({ name => 'class', code => sub { my $a = shift; return if $a eq 'main'; return $a; }, }) }, $expect, 'transform_attribute deletes the attr if code returns undef', ); ($expect = $tmpl) =~ s/ class="main"/ class="moan"/; is( run_for { $_->transform_attribute({ name => 'class', code => sub { ( my $b = shift ) =~ s/main/moan/; $b }, }) }, $expect, 'transform_attribute transforms something', ); ($expect = $tmpl) =~ s/ class="main"/ class="main" noggin="zonk"/; is( run_for { $_->transform_attribute({ name => 'noggin', code => sub { 'zonk' }, }) }, $expect, 'transform_attribute adds attribute if not there before', ); is( run_for { $_->transform_attribute({ name => 'noggin', code => sub { }, }) }, $tmpl, 'transform_attribute on nonexistent att does not add it if code returns undef', ); ($expect = $tmpl) =~ s/(?= 'TEXT', raw => 'O HAI' } ]; is( run_for { $_->add_before($ohai) }, $expect, 'add_before ok' ); ($expect = $tmpl) =~ s/(?<=<\/div>)/O HAI/; is( run_for { $_->add_after($ohai) }, $expect, 'add_after ok' ); ($expect = $tmpl) =~ s/(?<=class="main">)/O HAI/; is( run_for { $_->prepend_content($ohai) }, $expect, 'prepend_content ok' ); ($expect = $tmpl) =~ s/
/
O HAI<\/hr>/; is( (run_for { $_->prepend_content($ohai) } 'hr'), $expect, 'prepend_content ok with in place close' ); is( run_for { $_->replace($ohai) }, ' O HAI ', 'replace ok' ); @ev = (); is( run_for { $_->collect({ into => \@ev }) }, ' ', 'collect removes without passthrough' ); is( HTML::Zoom::Producer::BuiltIn->html_from_events(\@ev), '
Bob Builder
', 'collect collected right events' ); @ev = (); is( run_for { $_->collect({ into => \@ev, content => 1 }) }, '
', 'collect w/content removes correctly' ); is( HTML::Zoom::Producer::BuiltIn->html_from_events(\@ev), ' Bob Builder
', 'collect w/content collects correctly' ); is( run_for { $_->replace($ohai, { content => 1 }) }, '
O HAI
', 'replace w/content' ); ($expect = $tmpl) =~ s/(?=<\/div>)/O HAI/; is( run_for { $_->append_content($ohai) }, $expect, 'append content ok' ); my $r_content = sub { my $r = shift; sub { $_->replace($r, { content => 1 }) } }; is( run_for { $_->repeat( [ sub { filter filter($_ => '.name' => $r_content->('mst')) => '.career' => $r_content->('Chainsaw Wielder') }, sub { filter filter($_ => '.name' => $r_content->('mdk')) => '.career' => $r_content->('Adminion') }, ] ) }, q{
mst Chainsaw Wielder
mdk Adminion
}, 'repeat ok' ); is( run_for { $_->repeat_content( [ sub { filter filter($_ => '.name' => $r_content->('mst')) => '.career' => $r_content->('Chainsaw Wielder') }, sub { filter filter($_ => '.name' => $r_content->('mdk')) => '.career' => $r_content->('Adminion') }, ] ) }, q{
mst Chainsaw Wielder
mdk Adminion
}, 'repeat_content ok' ); is( run_for { my @between; $_->repeat_content( [ sub { HTML::Zoom::ArrayStream->new({ array => [ (filter filter($_ => '.name' => $r_content->('mst')) => '.career' => $r_content->('Chainsaw Wielder')), HTML::Zoom::ArrayStream->new({ array => \@between }) ] })->flatten }, sub { filter filter($_ => '.name' => $r_content->('mdk')) => '.career' => $r_content->('Adminion') }, ], { filter => sub { filter $_[0] => 'hr' => sub { $_->collect({ into => \@between }) } } } ) }, q{
mst Chainsaw Wielder
mdk Adminion
}, 'repeat_content with filter ok' ); is( run_for { my @between; $_->repeat_content( [ sub { filter filter($_ => '.name' => $r_content->('mst')) => '.career' => $r_content->('Chainsaw Wielder') }, sub { filter filter($_ => '.name' => $r_content->('mdk')) => '.career' => $r_content->('Adminion') }, ], { repeat_between => 'hr' } ) }, q{
mst Chainsaw Wielder
mdk Adminion
}, 'repeat_content using repeat_between ok' ); done_testing;