-
Notifications
You must be signed in to change notification settings - Fork 38
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Item14152: Continue with the extensions tests.
- Added the forgotten test suite ExtensionsTests. - Fixed a but with unreset iteration over method list.
- Loading branch information
Showing
5 changed files
with
504 additions
and
70 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,368 @@ | ||
# See bottom of file for license and copyright information | ||
|
||
package Foswiki::ExtensionsTests::SampleClass { | ||
use Foswiki::Class qw(extensible); | ||
extends qw(Foswiki::Object); | ||
|
||
has allowFlowControl => ( | ||
is => 'rw', | ||
default => 0, | ||
); | ||
|
||
pluggable testPluggableMethod => sub { | ||
my $this = shift; | ||
|
||
return wantarray | ||
? ( qw(This is a sample return array), @_ ) | ||
: "This is a sample string {" . join( "}{", @_ ) . "}"; | ||
}; | ||
} | ||
|
||
package ExtensionsTests; | ||
|
||
use Assert; | ||
use Foswiki::Exception (); | ||
|
||
use Foswiki::Class; | ||
extends qw(FoswikiFnTestCase); | ||
|
||
$| = 1; | ||
|
||
# List of all auto generated extension modules. | ||
has autoGenerated => ( | ||
is => 'rw', | ||
default => sub { [] }, | ||
); | ||
|
||
around set_up => sub { | ||
my $orig = shift; | ||
my $this = shift; | ||
|
||
my $mKey = ( grep { /ExtensionsTests/ } keys %INC )[0]; | ||
$this->app->env->{FOSWIKI_EXTLIBS} = | ||
File::Spec->catdir( ( File::Spec->splitpath( $INC{$mKey} ) )[1], | ||
'TestExtensions' ); | ||
|
||
# Disable all extensions generated by previous tests. | ||
$this->app->env->{FOSWIKI_DISABLED_EXTENSIONS} = $this->autoGenerated; | ||
|
||
$this->app->cfg->data->{DisableAllPlugins} = 1; | ||
|
||
$orig->( $this, @_ ); | ||
}; | ||
|
||
sub _getExtName { | ||
my $this = shift; | ||
|
||
state $idx = 0; | ||
|
||
return sprintf( 'Foswiki::Extension::Ext::Auto%04d', $idx++ ); | ||
} | ||
|
||
sub _genExtModules { | ||
my $this = shift; | ||
my ( $count, @extCode ) = @_; | ||
|
||
my @extNames; | ||
for ( 1 .. $count ) { | ||
my $extName = $this->_getExtName; | ||
my $code = shift @extCode // ''; | ||
my $ret = eval <<EXT; | ||
package $extName; | ||
use Foswiki::Class qw(extension); | ||
extends qw(Foswiki::Extension); | ||
Foswiki::Extensions::registerExtModule('$extName'); | ||
$code | ||
1; | ||
EXT | ||
unless ($ret) { | ||
Foswiki::Exception::Fatal->throw( | ||
text => "Extension module cannot be generated: " | ||
. Foswiki::Exception::errorStr($@) ); | ||
} | ||
push @extNames, $extName; | ||
} | ||
|
||
# Remember what extensions have been autogenerated. | ||
push @{ $this->autoGenerated }, @extNames; | ||
|
||
return @extNames; | ||
} | ||
|
||
sub _setExtDependencies { | ||
my $this = shift; | ||
my %deps = @_; | ||
|
||
foreach my $extName ( keys %deps ) { | ||
my $dep = $deps{$extName}; | ||
Foswiki::Extensions::registerDeps( $extName, | ||
ref($dep) ? @{$dep} : $dep ); | ||
} | ||
} | ||
|
||
sub _disableAllCurrentExtensions { | ||
my $this = shift; | ||
$this->app->env->{FOSWIKI_DISABLED_EXTENSIONS} = | ||
[@Foswiki::Extensions::extModules]; | ||
} | ||
|
||
sub test_orderedList { | ||
my $this = shift; | ||
|
||
# First disable all previously loaded extensions. | ||
$this->_disableAllCurrentExtensions; | ||
|
||
my @ext = $this->_genExtModules(4); | ||
$this->_setExtDependencies( | ||
$ext[0] => $ext[2], | ||
$ext[2] => $ext[3], | ||
$ext[3] => $ext[1], | ||
); | ||
$this->reCreateFoswikiApp; | ||
|
||
my $expected = [ @ext[ 1, 3, 2, 0 ] ]; | ||
|
||
$this->assert_deep_equals( | ||
$expected, | ||
$this->app->extensions->orderedList, | ||
"Wrong order of extensions" | ||
); | ||
} | ||
|
||
sub test_manual_disable { | ||
my $this = shift; | ||
|
||
my @ext = $this->_genExtModules(2); | ||
$this->app->env->{FOSWIKI_DISABLED_EXTENSIONS} = $ext[1]; | ||
$this->reCreateFoswikiApp; | ||
|
||
$this->assert_not_null( | ||
$this->app->extensions->extensions->{ $ext[0] }, | ||
"First extension is expected to be initialized" | ||
); | ||
$this->assert( !$this->app->extensions->extEnabled( $ext[1] ), | ||
"Second extensions is expected to be disabled but it is not" ); | ||
$this->assert_str_equals( | ||
"Disabled by FOSWIKI_DISABLED_EXTENSIONS environment variable.", | ||
$this->app->extensions->disabledExtensions->{ $ext[1] } | ||
); | ||
} | ||
|
||
sub test_depend_on_manual_disable { | ||
my $this = shift; | ||
|
||
my @ext = $this->_genExtModules(4); | ||
$this->app->env->{FOSWIKI_DISABLED_EXTENSIONS} = $ext[1]; | ||
$this->_setExtDependencies( | ||
$ext[3] => $ext[2], | ||
$ext[2] => $ext[1], | ||
); | ||
|
||
$this->reCreateFoswikiApp; | ||
|
||
$this->assert_not_null( | ||
$this->app->extensions->extensions->{ $ext[0] }, | ||
"First extension is expected to be initialized" | ||
); | ||
$this->assert( !$this->app->extensions->extEnabled( $ext[1] ), | ||
"Second extensions is expected to be disabled but it is not" ); | ||
$this->assert_str_equals( | ||
"Disabled by FOSWIKI_DISABLED_EXTENSIONS environment variable.", | ||
$this->app->extensions->disabledExtensions->{ $ext[1] } | ||
); | ||
$this->assert( | ||
!$this->app->extensions->extEnabled( $ext[2] ), | ||
"Third extensions is expected to be disabled but it is not" | ||
); | ||
$this->assert( !$this->app->extensions->extEnabled( $ext[3] ), | ||
"Fourth extensions is expected to be disabled but it is not" ); | ||
|
||
$this->assert_str_contains( "Disabled extension", | ||
$this->app->extensions->disabledExtensions->{ $ext[2] } ); | ||
|
||
$this->assert_str_contains( "Disabled extension", | ||
$this->app->extensions->disabledExtensions->{ $ext[3] } ); | ||
} | ||
|
||
sub test_circular_deps { | ||
my $this = shift; | ||
|
||
$this->_disableAllCurrentExtensions; | ||
|
||
my @ext = $this->_genExtModules(4); | ||
$this->_setExtDependencies( | ||
$ext[0] => $ext[2], | ||
$ext[3] => $ext[1], | ||
$ext[1] => $ext[3], | ||
); | ||
$this->reCreateFoswikiApp; | ||
|
||
my $expected = [ @ext[ 2, 0 ] ]; | ||
|
||
$this->assert_deep_equals( | ||
$expected, | ||
$this->app->extensions->orderedList, | ||
"Wrong order of extensions" | ||
); | ||
|
||
$this->assert_str_contains( "Circular dependecy found for ", | ||
$this->app->extensions->disabledExtensions->{ $ext[1] } ); | ||
|
||
$this->assert_str_contains( "Circular dependecy found for ", | ||
$this->app->extensions->disabledExtensions->{ $ext[3] } ); | ||
} | ||
|
||
sub test_pluggable_methods { | ||
my $this = shift; | ||
|
||
$this->_disableAllCurrentExtensions; | ||
my @ext = $this->_genExtModules( | ||
3, | ||
<<'EXT1', | ||
plugBefore 'Foswiki::ExtensionsTests::SampleClass::testPluggableMethod' => sub { | ||
my $this = shift; | ||
my ($params) = @_; | ||
$this->_traceMsg(""); | ||
# We expect at least to parameters to be passed in. | ||
$params->{args}[1] = "ext1ArgFromBefore"; | ||
}; | ||
EXT1 | ||
<<'EXT2', | ||
plugAround 'Foswiki::ExtensionsTests::SampleClass::testPluggableMethod' => sub { | ||
my $this = shift; | ||
my ($params) = @_; | ||
$this->_traceMsg(""); | ||
# Only if flow control is allowed by the calling test code. | ||
if ($params->{object}->allowFlowControl) { | ||
my $rc = 'ext2ReturnFromAround'; | ||
if ( $params->{wantarray} ) { | ||
$params->{rc} = [$rc]; | ||
} | ||
elsif ( defined $params->{wantarray} ) { | ||
$params->{rc} .= ($params->{rc} ? " " : "") . $rc; | ||
} | ||
delete $params->{ext3Flag1}; | ||
Foswiki::Exception::Ext::Last->throw( | ||
rc => $params->{rc}, | ||
extension => $this, | ||
); | ||
} | ||
}; | ||
EXT2 | ||
<<'EXT3', | ||
plugBefore 'Foswiki::ExtensionsTests::SampleClass::testPluggableMethod' => sub { | ||
my $this = shift; | ||
my ($params) = @_; | ||
$this->_traceMsg(""); | ||
$params->{ext3Flag1} = 1; | ||
$params->{ext3Flag2} = 1; | ||
}; | ||
plugAfter 'Foswiki::ExtensionsTests::SampleClass::testPluggableMethod' => sub { | ||
my $this = shift; | ||
my ($params) = @_; | ||
$this->_traceMsg(""); | ||
foreach my $flag (qw(ext3Flag1 ext3Flag2)) { | ||
if ($params->{$flag}) { | ||
my $rc = "with_$flag"; | ||
if ($params->{wantarray}) { | ||
push @{$params->{rc}}, $rc; | ||
} | ||
elsif (defined $params->{wantarray}) { | ||
$params->{rc} .= " $rc"; | ||
} | ||
} | ||
} | ||
}; | ||
EXT3 | ||
); | ||
$this->_setExtDependencies( | ||
$ext[2] => $ext[1], | ||
$ext[1] => $ext[0], | ||
); | ||
|
||
$this->reCreateFoswikiApp; | ||
|
||
my $testClass = 'Foswiki::ExtensionsTests::SampleClass'; | ||
my $testMethod = 'testPluggableMethod'; | ||
$this->assert( | ||
defined $Foswiki::Extensions::pluggables{$testClass}{$testMethod}, | ||
"Method " | ||
. $testMethod | ||
. " of class " | ||
. $testClass | ||
. " is not registered as pluggable!" | ||
); | ||
|
||
my $testObj = $this->create('Foswiki::ExtensionsTests::SampleClass'); | ||
|
||
$this->assert( $testObj->DOES('Foswiki::Aux::_ExtensibleRole'), | ||
"Test object of class " | ||
. ref($testObj) | ||
. " doesn't have extensible role!" ); | ||
|
||
my @args; | ||
@args = qw(arg1 arg2); | ||
my $rc = $testObj->testPluggableMethod(@args); | ||
|
||
$this->assert_str_equals( | ||
'This is a sample string {arg1}{ext1ArgFromBefore} with_ext3Flag1 with_ext3Flag2', | ||
$rc | ||
); | ||
|
||
@args = qw(arg1 arg2); | ||
my @rc = $testObj->testPluggableMethod(@args); | ||
|
||
$this->assert_deep_equals( | ||
[ | ||
qw(This is a sample return array arg1 ext1ArgFromBefore with_ext3Flag1 with_ext3Flag2) | ||
], | ||
\@rc | ||
); | ||
|
||
$testObj->allowFlowControl(1); | ||
@args = qw(arg1 arg2); | ||
$rc = $testObj->testPluggableMethod(@args); | ||
|
||
$this->assert_str_equals( 'ext2ReturnFromAround with_ext3Flag2', $rc ); | ||
|
||
@args = qw(arg1 arg2); | ||
@rc = $testObj->testPluggableMethod(@args); | ||
|
||
$this->assert_deep_equals( [qw(ext2ReturnFromAround with_ext3Flag2)], | ||
[@rc] ); | ||
} | ||
|
||
1; | ||
__END__ | ||
Foswiki - The Free and Open Source Wiki, http://foswiki.org/ | ||
Copyright (C) 2016 Foswiki Contributors. Foswiki Contributors | ||
are listed in the AUTHORS file in the root of this distribution. | ||
NOTE: Please extend that file, not this notice. | ||
This program is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU General Public License | ||
as published by the Free Software Foundation; either version 2 | ||
of the License, or (at your option) any later version. For | ||
more details read LICENSE in the root of this distribution. | ||
This program is distributed in the hope that it will be useful, | ||
but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | ||
As per the GPL, removal of this notice is prohibited. |
Oops, something went wrong.