Skip to content

Commit

Permalink
Item8635: lets define a little more precisely, and in the process add…
Browse files Browse the repository at this point in the history
… something more useful than yetanother - plus tests

git-svn-id: http://svn.foswiki.org/trunk@7600 0b4bb1d4-4e5a-0410-9cc4-b2b747904278
  • Loading branch information
SvenDowideit authored and SvenDowideit committed May 31, 2010
1 parent 11a0db1 commit d1b24af
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 26 deletions.
43 changes: 43 additions & 0 deletions UnitTestContrib/test/unit/Fn_FOREACH.pm
Expand Up @@ -569,6 +569,31 @@ sub test_not_topics {

$this->assert_str_equals(
'1:(A);2:(B);3:(C)', $result );

#use all the topic based thingies and see what they do, so that anyone modifying this code has an idea of what they are in for.
$result =
$this->{test_topicObject}->expandMacros(
'%FOREACH{"A,B,C" type="string" format="$index:($item) - $web, $topic, $parent, $text, $locked,
$date, $isodate, $rev, $username, $wikiname, $wikiusername,
$createdate, $createusername, $createwikiname, $createwikiusername,
$summary, $changes, $formname, $formfield, $pattern, $count,
$ntopics, $nhits, $pager" separator=";"}%'
);

$this->assert_str_equals(
'1:(A) - $web, $topic, $parent, $text, $locked,
$longdate, $iso, $rev, $username, $wikiname, $wikiusername,
01 Jan 1970 - 00:00, guest, WikiGuest, TemporarySEARCHUsersWeb.WikiGuest,
$summary, $changes, $formname, $formfield, $pattern, $count,
1, 1, $pager;2:(B) - $web, $topic, $parent, $text, $locked,
$longdate, $iso, $rev, $username, $wikiname, $wikiusername,
01 Jan 1970 - 00:00, guest, WikiGuest, TemporarySEARCHUsersWeb.WikiGuest,
$summary, $changes, $formname, $formfield, $pattern, $count,
2, 2, $pager;3:(C) - $web, $topic, $parent, $text, $locked,
$longdate, $iso, $rev, $username, $wikiname, $wikiusername,
01 Jan 1970 - 00:00, guest, WikiGuest, TemporarySEARCHUsersWeb.WikiGuest,
$summary, $changes, $formname, $formfield, $pattern, $count,
3, 3, $pager', $result );
}

#%STARTINCLUDE%| =$n= or =$n()= | New line. Use =$n()= if followed by alphanumeric character, e.g. write =Foo$n()Bar= instead of =Foo$nBar= |
Expand Down Expand Up @@ -600,7 +625,25 @@ sub test_standard_escapes {
"RESULT: ,
OkATopic\"OkBTopic\"OkTopic\"&", $result
);

#do the string version too - so long as there are no topic specific expansions, the output needs to be identical
$result =
$this->{test_topicObject}->expandMacros(
'%FOREACH{
"OkATopic,OkBTopic,OkTopic"
type="String"
header="RESULT: $comma"
footer="$amp"
nonoise="on"
format="$topic"
separator="$quot"
}%'
);

$this->assert_str_equals(
"RESULT: ,
OkATopic\"OkBTopic\"OkTopic\"&", $result
);
}


Expand Down
16 changes: 14 additions & 2 deletions UnitTestContrib/test/unit/Fn_SEARCH.pm
Expand Up @@ -1902,19 +1902,21 @@ HERE
#TODO: rewrite using named params for more flexibility
#need summary, and multiple
sub _multiWebSeptic {
my ( $this, $head, $foot, $sep, $results, $expected ) = @_;
my ( $this, $head, $foot, $sep, $results, $expected, $format ) = @_;
my $str = $results ? '*Preferences' : 'Septic';
$head = $head ? 'header="HEAD($web)"' : '';
$foot = $foot ? 'footer="FOOT($ntopics,$nhits)"' : '';
$sep = defined $sep ? "separator=\"$sep\"" : '';
$format = '$topic' unless (defined($format));

my $result = $this->{test_topicObject}->expandMacros(
"%SEARCH{\"name~'$str'\"
web=\"System,Main\"
type=\"query\"
nosearch=\"on\"
nosummary=\"on\"
nototal=\"on\"
format=\"\$topic\"
format=\"$format\"
$head $foot $sep }%"
);
$expected =~ s/\n$//s;
Expand All @@ -1933,6 +1935,16 @@ WebPreferences
EXPECT
}

sub verify_multiWeb_no_header_no_footer_no_separator_with_results_counters {
my $this = shift;
$this->_multiWebSeptic( 0, 0, undef, 1, <<EXPECT, '$nhits, $ntopics, $index, $topic');
1, 1, 1, DefaultPreferences
2, 2, 2, WebPreferences
1, 1, 3, SitePreferences
2, 2, 4, WebPreferences
EXPECT
}

sub verify_multiWeb_no_header_no_footer_no_separator_no_results {
my $this = shift;
$this->_multiWebSeptic( 0, 0, undef, 0, <<EXPECT);
Expand Down
2 changes: 2 additions & 0 deletions core/data/System/FormattedSearch.txt
Expand Up @@ -78,6 +78,8 @@ Format tokens that can be used in the format string:
| =$locked= | LOCKED flag (if any) |
| =$date= | Time stamp of last topic update, e.g. =%GMTIME{"$day $mon $year - $hour:$min"}%= |
| =$isodate= | Time stamp of last topic update, e.g. =%GMTIME{"$year-$mo-$dayT$hour:$minZ"}%= |
| =$index= | number of total results - can be used as a running counter in the =format=, or in the =footer=. This $index is not affected by web based partitioning of results. |
| =$item= | the full name of a result item - in a SEARCH context, equivalent to =$web.$topic= |
| =$rev= | Number of last topic revision, e.g. =4= |
| =$username= | Login name of last topic update, e.g. =jsmith= |
| =$wikiname= | Wiki user name of last topic update, e.g. =<nop>JohnSmith= |
Expand Down
12 changes: 7 additions & 5 deletions core/data/System/VarFOREACH.txt
Expand Up @@ -11,20 +11,22 @@ __WARNING:__ the syntax is developing. eg. =$topic= is a legacy of the original
| =header="..."= | Text to come before the formated output | =""= |
| =footer="..."= | Text to come after the formated output | =""= |
| =separator="n"= | separator between formatted elements | ="$n"= |
| =type=""= | treat input list as either =topic= or =string= | ="topic"= |
* Examples:
* =%<nop>FOREACH{"one,two,three" format=" * $item"}%=
* =%<nop>FOREACH{"one,two,three" type="string" format=" * $item"}%=
* =%<nop>FOREACH{"%SKIN%" header="the Skin setting is evaluated in this order:" format=" 1 =$topic=" footer=" 1 =default="}%=
* Related: [[%IF{"'%INCLUDINGTOPIC%'='Macros'" then="#"}%VarSEARCH][SEARCH]]

---++ Supported formatting tokens
If the format string contains _any_ of the topic-specific format tokens
If =type="topic"= (the default) the format string can contain _any_ of the topic-specific format tokens
specified in FormattedSearch (=$web=, =$topic=, =$parent=, =$text=, =$locked=,
=$date=, =$isodate=, =$rev=, =$username=, =$wikiname=, =$wikiusername=,
=$date=, =$isodate=, =$index=, =$item=, =$rev=, =$username=, =$wikiname=, =$wikiusername=,
=$createdate=, =$createusername=, =$createwikiname=, =$createwikiusername=,
=$summary=, =$changes=, =$formname=, =$formfield=, =$pattern=, =$count=,
=$ntopics=, =$nhits=, =$pager=) _or if =format= is not given_ then the list is treated as a list of *topic names* (with optional web specifier) and all the formatting tokens from FormattedSearch work.
=$ntopics=, =$nhits=, =$pager=).

Otherwise if none of these tokens is used, the parameter is treated as a simple list of strings. In this case, the format tokens =$index= and =$item= will return the position of the item in the list (1-based), and the item itself, respectively.
If =type="string"= then the comma separated list is treated as a simple list of strings.
In this case, the format tokens =$index= and =$item= will return the position of the item in the list (1-based), and the item itself, respectively.

%I% For more sophisticated handling of lists, consider installing Foswiki:Extensions.FilterPlugin.

Expand Down
46 changes: 27 additions & 19 deletions core/lib/Foswiki/Search.pm
Expand Up @@ -371,6 +371,7 @@ sub searchWeb {
# output footer of $web
$result =~ s/\$ntopics/0/gs;
$result =~ s/\$nhits/0/gs;
$result =~ s/\$index/0/gs;

#legacy SEARCH counter support
$result =~ s/%NTOPICS%/0/go;
Expand Down Expand Up @@ -698,6 +699,7 @@ sub formatResults {
my $web = $baseWeb;
my $webObject = new Foswiki::Meta( $session, $web );
my $lastWebProcessed = '';
#total number of topics and hits - not reset when we swap webs
my $ttopics = 0;
my $thits = 0;

Expand Down Expand Up @@ -818,6 +820,7 @@ sub formatResults {

$processedfooter =~ s/\$ntopics/$ntopics/gs;
$processedfooter =~ s/\$nhits/$nhits/gs;
$processedfooter =~ s/\$index/$thits/gs;

#legacy SEARCH counter support
$processedfooter =~ s/%NTOPICS%/$ntopics/go;
Expand Down Expand Up @@ -897,6 +900,7 @@ sub formatResults {
$processedheader =~ s/%WEB%/$web/go;
$processedheader =~ s/\$ntopics/($ntopics-1)/gse;
$processedheader =~ s/\$nhits/($nhits-1)/gse;
$processedheader =~ s/\$index/($thits-1)/gs;
$processedheader =
$this->formatCommon( $processedheader, \%pager_formatting );
&$callback( $cbdata, $processedheader );
Expand Down Expand Up @@ -946,7 +950,7 @@ sub formatResults {
{
'\$ntopics' => sub { return $ntopics },
'\$nhits' => sub { return $nhits },
'\$index' => sub { return $nhits },
'\$index' => sub { return $thits },
'\$item' => sub { return $listItem },

%pager_formatting,
Expand Down Expand Up @@ -1026,6 +1030,7 @@ sub formatResults {
# output footer of $web
$footer =~ s/\$ntopics/$ntopics/gs;
$footer =~ s/\$nhits/$nhits/gs;
$footer =~ s/\$index/$thits/gs;

#legacy SEARCH counter support
$footer =~ s/%NTOPICS%/$ntopics/go;
Expand Down Expand Up @@ -1112,7 +1117,7 @@ sub formatResult {
$out =
$session->renderer->renderRevisionInfo( $topicObject, $revNum, $out ) if (defined($topic));

if ( $out =~ m/\$text/ ) {
if ( $out =~ m/\$text/ and defined($topic)) { #TODO: don't muck with text if we're not even a topic
$text = $topicObject->text() unless defined $text;
$text = '' unless defined $text;

Expand Down Expand Up @@ -1152,23 +1157,26 @@ sub formatResult {

}
else {
$out =~ s/\$summary(?:\(([^\)]*)\))?/
$topicObject->summariseText( $1, $text, $searchOptions )/ges;
$out =~ s/\$changes(?:\(([^\)]*)\))?/
$topicObject->summariseChanges($1, $revNum)/ges;
$out =~ s/\$formfield\(\s*([^\)]*)\s*\)/
displayFormField( $topicObject, $1 )/ges;
$out =~ s/\$parent\(([^\)]*)\)/
Foswiki::Render::breakName(
$topicObject->getParent(), $1 )/ges;
$out =~ s/\$parent/$topicObject->getParent()/ges;
$out =~ s/\$formname/$topicObject->getFormName()/ges;
$out =~ s/\$count\((.*?\s*\.\*)\)/_countPattern( $text, $1 )/ges;

# FIXME: Allow all regex characters but escape them
# Note: The RE requires a .* at the end of a pattern to avoid false positives
# in pattern matching
$out =~ s/\$pattern\((.*?\s*\.\*)\)/_extractPattern( $text, $1 )/ges;
#TODO: more topic specific bits
if (defined($topic)) {
$out =~ s/\$summary(?:\(([^\)]*)\))?/
$topicObject->summariseText( $1, $text, $searchOptions )/ges;
$out =~ s/\$changes(?:\(([^\)]*)\))?/
$topicObject->summariseChanges($1, $revNum)/ges;
$out =~ s/\$formfield\(\s*([^\)]*)\s*\)/
displayFormField( $topicObject, $1 )/ges;
$out =~ s/\$parent\(([^\)]*)\)/
Foswiki::Render::breakName(
$topicObject->getParent(), $1 )/ges;
$out =~ s/\$parent/$topicObject->getParent()/ges;
$out =~ s/\$formname/$topicObject->getFormName()/ges;
$out =~ s/\$count\((.*?\s*\.\*)\)/_countPattern( $text, $1 )/ges;

# FIXME: Allow all regex characters but escape them
# Note: The RE requires a .* at the end of a pattern to avoid false positives
# in pattern matching
$out =~ s/\$pattern\((.*?\s*\.\*)\)/_extractPattern( $text, $1 )/ges;
}
$out =~ s/\r?\n/$newLine/gos if ($newLine);
if ( !defined($separator) ) {

Expand Down
1 change: 1 addition & 0 deletions core/lib/Foswiki/Store/VC/Handler.pm
Expand Up @@ -261,6 +261,7 @@ down to 1.

sub getRevisionHistory {
my $this = shift;
ASSERT($this->{file}) if DEBUG;
unless ( -e $this->{rcsFile} ) {
if ( -e $this->{file} ) {
return new Foswiki::ListIterator( [1] );
Expand Down

0 comments on commit d1b24af

Please sign in to comment.