1 package CGI::Session::Test::Default;
7 use Scalar::Util "refaddr";
14 $CGI::Session::Test::Default::VERSION = '4.20';
16 =head1 CGI::Session::Test::Default
18 Run a suite of tests for a given CGI::Session::Driver
22 my $t = CGI::Session::Test::Default->new(
23 # These are all optional, with default as follows
29 Create a new test object, possibly overriding some defaults.
44 $self->{_skip} = { map { $_ => $_ } @{$self->{skip}} };
52 =head2 number_of_tests()
54 my $new_num = $t->number_of_tests($new_num);
56 A setter/accessor method to affect the number of tests to run,
57 after C<new()> has been called and before C<run()>.
65 $self->{tests} = $_[0];
68 return $self->{tests};
75 Run the test suite. See C<new()> for setting related options.
83 use_ok("CGI::Session", "CGI::Session loaded successfully!");
88 my $session = CGI::Session->load() or die CGI::Session->errstr;
89 ok($session, "empty session should be created");
91 ok($session->is_empty);
92 ok(!$session->is_expired);
96 $session = CGI::Session->new($self->{dsn}, '_DOESN\'T EXIST_', $self->{args}) or die CGI::Session->errstr;
97 ok( $session, "Session created successfully!");
100 # checking if the driver object created is really the driver requested:
102 my $dsn = $session->parse_dsn( $self->{dsn} );
103 ok( ref $session->_driver eq "CGI::Session::Driver::" . $dsn->{driver}, ref $dsn->{Driver} );
105 ok( $session->ctime && $session->atime, "ctime & atime are set");
106 ok( $session->atime == $session->ctime, "ctime == atime");
107 ok( !$session->etime, "etime not set yet");
109 ok( $session->id, "session id is " . $session->id);
111 $session->param('author', "Sherzod Ruzmetov");
112 $session->param(-name=>'emails', -value=>['sherzodr@cpan.org', 'sherzodr@handalak.com']);
113 $session->param('blogs', {
114 './lost+found' => 'http://author.handalak.com/',
115 'Yigitlik sarguzashtlari' => 'http://author.handalak.com/uz/'
118 ok( ($session->param) == 3, "session holds 3 params" . scalar $session->param );
119 ok( $session->param('author') eq "Sherzod Ruzmetov", "My name's correct!");
121 ok( ref ($session->param('emails')) eq 'ARRAY', "'emails' holds list of values" );
122 ok( @{ $session->param('emails') } == 2, "'emails' holds list of two values");
123 ok( $session->param('emails')->[0] eq 'sherzodr@cpan.org', "first value of 'emails' is correct!");
124 ok( $session->param('emails')->[1] eq 'sherzodr@handalak.com', "second value of 'emails' is correct!");
126 ok( ref( $session->param('blogs') ) eq 'HASH', "'blogs' holds a hash");
127 ok( $session->param('blogs')->{'./lost+found'} eq 'http://author.handalak.com/', "first blog is correct");
128 ok( $session->param('blogs')->{'Yigitlik sarguzashtlari'} eq 'http://author.handalak.com/uz/', "second blog is correct");
140 eval { $session = CGI::Session->load($self->{dsn}, $sid, $self->{args}) };
142 if ($@ || CGI::Session->errstr) {
143 Test::More::skip("couldn't load session, bailing out: SQLite/Storable support is TODO", 56);
146 is($@.CGI::Session->errstr,'','survived eval without error.');
147 ok($session, "Session was retrieved successfully");
148 ok(!$session->is_expired, "session isn't expired yet");
150 is($session->id,$sid, "session IDs are consistent");
151 ok($session->atime > $session->ctime, "ctime should be older than atime");
152 ok(!$session->etime, "etime shouldn't be set yet");
154 ok( ($session->param) == 3, "session should hold params" );
155 ok( $session->param('author') eq "Sherzod Ruzmetov", "my name's correct");
157 ok( ref ($session->param('emails')) eq 'ARRAY', "'emails' should hold list of values" );
158 ok( @{ $session->param('emails') } == 2, "'emails' should hold list of two values");
159 ok( $session->param('emails')->[0] eq 'sherzodr@cpan.org', "first value is correct!");
160 ok( $session->param('emails')->[1] eq 'sherzodr@handalak.com', "second value is correct!");
162 ok( ref( $session->param('blogs') ) eq 'HASH', "'blogs' holds a hash");
163 ok( $session->param('blogs')->{'./lost+found'} eq 'http://author.handalak.com/', "first blog is correct!");
164 ok( $session->param('blogs')->{'Yigitlik sarguzashtlari'} eq 'http://author.handalak.com/uz/', "second blog is correct!");
166 # TODO: test many any other variations of expire() syntax
167 $session->expire('+1s');
168 ok($session->etime == 1, "etime set to 1 second");
170 $session->expire("+1m");
171 ok($session->etime == 60, "etime set to one minute");
173 $session->expires("2h");
174 ok($session->etime == 7200, "etime set to two hours");
176 $session->expires("5d");
177 ok($session->etime == 432000, "etime set to 5 days");
179 $session->expires("-10s");
180 ok($session->etime == -10, "etime set to 10 seconds in the past");
183 # Setting the expiration time back to 1s, so that subsequent tests
184 # relying on this value pass
186 $session->expire("1s");
187 ok($session->etime == 1, "etime set back to one second");
188 eval { $session->close(); };
189 is($@, '', 'calling close method survives eval');
193 sleep(1); # <-- letting the time tick
198 my $session = CGI::Session->load($self->{dsn}, $sid, $self->{args}) or die CGI::Session->errstr;
199 ok($session, "Session instance loaded ");
200 ok(!$session->id, "session doesn't have ID");
201 ok($session->is_empty, "session is empty, which is the same as above");
202 #print $session->dump;
203 ok($session->is_expired, "session was expired");
204 ok(!$session->param('author'), "session data cleared");
208 $session = $session->new() or die CGI::Session->errstr;
209 #print $session->dump();
210 ok($session, "new session created");
211 ok($session->id, "session has id :" . $session->id );
212 ok(!$session->is_expired, "session isn't expired");
213 ok(!$session->is_empty, "session isn't empty");
214 ok($session->atime == $session->ctime, "access and creation times are same");
216 ok($session->id ne $sid, "it's a completely different session than above");
218 $driver = $session->_driver();
225 # We are intentionally removing the session stored in the datastore and will be requesting
226 # re-initialization of that id. This test is necessary since I noticed weird behaviors in
227 # some of my web applications that kept creating new sessions when the object requested
228 # wasn't in the datastore.
231 ok($driver->remove( $sid ), "Session '$sid' removed from datastore successfully");
233 my $session = CGI::Session->new($self->{dsn}, $sid, $self->{args} ) or die CGI::Session->errstr;
234 ok($session, "session object created successfully");
235 ok($session->id ne $sid, "claimed ID ($sid) couldn't be recovered. New ID is: " . $session->id);
243 my $session = CGI::Session->new($self->{dsn}, $sid, $self->{args}) or die CGI::Session->errstr;
244 ok($session, "Session object created successfully");
245 ok($session->id eq $sid, "claimed id ($sid) was recovered successfully!");
247 # Remove the object, finally!
254 my $session = CGI::Session->new($self->{dsn}, $sid, $self->{args}) or die CGI::Session->errstr;
255 ok($session, "Session object created successfully");
256 ok($session->id ne $sid, "New object created, because previous object was deleted");
260 # creating a simple object to be stored into session
261 my $simple_class = SimpleObjectClass->new();
262 ok($simple_class, "SimpleObjectClass created successfully");
264 $simple_class->name("Sherzod Ruzmetov");
265 $simple_class->emails(0, 'sherzodr@handalak.com');
266 $simple_class->emails(1, 'sherzodr@cpan.org');
267 $simple_class->blogs('lost+found', 'http://author.handalak.com/');
268 $simple_class->blogs('yigitlik', 'http://author.handalak.com/uz/');
269 $session->param('simple_object', $simple_class);
271 ok($session->param('simple_object')->name eq "Sherzod Ruzmetov");
272 ok($session->param('simple_object')->emails(1) eq 'sherzodr@cpan.org');
273 ok($session->param('simple_object')->blogs('yigitlik') eq 'http://author.handalak.com/uz/');
276 # creating an overloaded object to be stored into session
277 my $overloaded_class = OverloadedObjectClass->new("ABCDEFG");
278 ok($overloaded_class, "OverloadedObjectClass created successfully");
279 ok(overload::Overloaded($overloaded_class) , "OverloadedObjectClass is properly overloaded");
280 ok(ref ($overloaded_class) eq "OverloadedObjectClass", "OverloadedObjectClass is an object");
281 $session->param("overloaded_object", $overloaded_class);
283 ok($session->param("overloaded_object") eq "ABCDEFG");
285 my $simple_class2 = SimpleObjectClass->new();
286 ok($simple_class2, "SimpleObjectClass created successfully");
288 $simple_class2->name("Sherzod Ruzmetov");
289 $simple_class2->emails(0, 'sherzodr@handalak.com');
290 $simple_class2->emails(1, 'sherzodr@cpan.org');
291 $simple_class2->blogs('lost+found', 'http://author.handalak.com/');
292 $simple_class2->blogs('yigitlik', 'http://author.handalak.com/uz/');
293 my $embedded = OverloadedObjectClass->new("Embedded");
294 $session->param("embedded_simple_and_overloaded",[ undef, $simple_class2, $embedded, $embedded ]);
296 ok(!defined($session->param("embedded_simple_and_overloaded")->[0]),"First element of anonymous array undef");
298 ok($session->param("embedded_simple_and_overloaded")->[1]->name eq "Sherzod Ruzmetov");
299 ok($session->param("embedded_simple_and_overloaded")->[1]->emails(1) eq 'sherzodr@cpan.org');
300 ok($session->param("embedded_simple_and_overloaded")->[1]->blogs('yigitlik') eq 'http://author.handalak.com/uz/');
302 ok($session->param("embedded_simple_and_overloaded")->[2] eq "Embedded");
304 ok(refaddr($session->param("embedded_simple_and_overloaded")->[2]) == refaddr($session->param("embedded_simple_and_overloaded")->[3] ),
305 "Overloaded objects have matching addresses");
311 my $session = CGI::Session->new($self->{dsn}, $sid, $self->{args}) or die CGI::Session->errstr;
312 ok($session, "Session object created successfully");
313 ok($session->id eq $sid, "Previously stored object loaded successfully");
316 my $simple_object = $session->param("simple_object");
317 ok(ref $simple_object eq "SimpleObjectClass", "SimpleObjectClass loaded successfully");
319 my $dsn = CGI::Session->parse_dsn($self->{dsn});
320 ok_later { $simple_object->name eq "Sherzod Ruzmetov" };
321 ok_later { $simple_object->emails(1) eq 'sherzodr@cpan.org' };
322 ok_later { $simple_object->emails(0) eq 'sherzodr@handalak.com' };
323 ok_later { $simple_object->blogs('lost+found') eq 'http://author.handalak.com/' };
324 ok(ref $session->param("overloaded_object") );
325 ok($session->param("overloaded_object") eq "ABCDEFG", "Object is still overloaded");
326 ok(overload::Overloaded($session->param("overloaded_object")), "Object is really overloaded");
328 ok(!defined($session->param("embedded_simple_and_overloaded")->[0]),"First element of anonymous array undef");
330 my $simple_object2 = $session->param("embedded_simple_and_overloaded")->[1];
331 ok(ref $simple_object2 eq "SimpleObjectClass", "SimpleObjectClass loaded successfully");
333 ok_later { $simple_object2->name eq "Sherzod Ruzmetov" };
334 ok_later { $simple_object2->emails(1) eq 'sherzodr@cpan.org' };
335 ok_later { $simple_object2->emails(0) eq 'sherzodr@handalak.com' };
336 ok_later { $simple_object2->blogs('lost+found') eq 'http://author.handalak.com/' };
339 ok($session->param("embedded_simple_and_overloaded")->[2] eq "Embedded");
340 ok(overload::Overloaded($session->param("embedded_simple_and_overloaded")->[2]), "Object is really overloaded");
342 ok(refaddr($session->param("embedded_simple_and_overloaded")->[2]) == refaddr($session->param("embedded_simple_and_overloaded")->[3]),
343 "Overloaded objects have matching addresses");
348 $self->{test_number} = 0;
354 $CURRENT->{test_number} ++;
357 if($CURRENT->{_skip}->{$CURRENT->{test_number}}) {
358 Test::More::skip("Test does not apply to this setup.", 1);
362 &{"Test::More::$test"}(@_);
366 sub ok { skip_or_run("ok", @_); }
367 sub use_ok { skip_or_run("use_ok", @_); }
368 sub is { skip_or_run("is", @_); }
371 my($code, $name) = @_;
373 $CURRENT->{test_number} ++;
374 $name = '' unless $name;
377 if($CURRENT->{_skip}->{$CURRENT->{test_number}}) {
378 Test::More::skip("Test does not apply to this setup.", 1);
381 Test::More::ok($code->(), $name);
389 package SimpleObjectClass;
401 package OverloadedObjectClass;
417 return $_[0]->{str_value};
421 my ($self, $arg) = @_;
423 return ($self->as_string eq $arg);