Test::ClassAPI(3pm)

πŸ“¦
version 1.07 Β· 4 versions
, in debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

✨ Test::ClassAPI ✨

okay bestie, so this is Test::ClassAPI (a Perl module, version 1.07, lives in the User Contributed Perl Documentation section of your man pages πŸ’…) and it is literally your little sanity-check bestie for big ol' class trees.


🌸 NAME 🌸

Test::ClassAPI β€” gives you basic first-pass API testing for large class trees. that's the whole vibe. πŸ¦‹


πŸ’– VERSION πŸ’–

version 1.07 β€” periodt.


πŸŽ€ DESCRIPTION πŸŽ€

so like. when you've got an API with a HUGE number of classes, you don't always wanna go full deep-dive test mode right away. you want a quick lil once-over first β€” just to make sure your classes, your methods, and your inheritance are all correct β€” before you commit to the full comprehensive testing situation. and that's exactly what this module does for you. no cap. πŸ”₯

🌈 Using Test::ClassAPI 🌈

okay so the way this works: you write a pretty standard looking test script, and you tuck the API description into a __DATA__ section at the very end of the script. it's giving very clean, very demure.

#!/usr/bin/perl

# Test the API for Foo::Bar
use strict;
use Test::More 'tests' => 123; # Optional
use Test::ClassAPI;

# Load the API to test
use Foo::Bar;

# Execute the tests
Test::ClassAPI->execute;

__DATA__

Foo::Bar::Thing=interface
Foo::Bar::Object=abstract
Foo::Bar::Planet=class

[Foo::Bar::Thing]
foo=method

[Foo::Bar::Object]
bar=method
whatsit=method

[Foo::Bar::Planet]
Foo::Bar::Object=isa
Foo::Bar::Thing=isa
blow_up=method
freeze=method
thaw=method

so if you look at that test script, the code itself is honestly super simple. first we load Test::More and Test::ClassAPI. and listen β€” loading Test::More and specifying a test plan is optional, because Test::ClassAPI will just hand you a plan automatically if you need one. she's self-sufficient like that. πŸ‘‘

and then after that comes the compulsory __DATA__ section with your API description. this description is provided in the general form of a Windows style .ini file, and it's structured like this ⬇️

🧚 Class Manifest 🧚

at the beginning of the file β€” in the root section of the config file β€” you've got a list of entries where the key is a class name and the value is one of either 'class', 'abstract', or 'interface'. three options, pick your fighter:

  • 'class' β€” this one means a fully fledged class. like, a real one. the class gets tested to make sure it's actually been loaded, and the existence of every single method listed in the section (and its superclasses) gets tested for too.
  • 'abstract' β€” this one means an abstract class. it's part of our class tree and it needs to exist, but it's never instantiated directly, so it does not have to itself implement all of the methods listed for it. generally, lots of individual 'class' entries will inherit from an 'abstract', which means a method listed in the abstract's section gets tested for in all of its subclasses. cute, right? πŸ’œ
  • 'interface' β€” this one means an external interface that is not part of our class tree, but is inherited from by one or more of our classes. so the methods listed in the interface's section get tested for in all the classes that inherit from it. for example, if a class inherits from β€” and implements β€” the File::Handle interface, you could add a "File::Handle=interface" entry, with the "[File::Handle]" section listing all the methods in File::Handle that our class tree actually cares about. and important: no tests for class or method existence are done on the interface itself. she's just here for the vibes. ✨

πŸ¦‹ Class Sections πŸ¦‹

every class listed in the class manifest MUST have its own individual section, indicated by [Class::Name], containing a set of entries where the key is the name of something to test and the value is the type of test for it. mandatory bestie, no skipping.

  • 'isa' β€” this test checks inheritance, making sure that the class the section is for is (by some path) a sub-class of something else. and ngl, it does not have to be an immediate sub-class. also, any class referred to (recursively) in an 'isa' test will have its 'method' test entries applied to the class as well. it's giving ripple effect. 🌊
  • 'method' β€” this is a simple method existence test, using "UNIVERSAL::can" to make sure that the method exists in the class. simple, effective, iconic.

πŸ’… METHODS πŸ’…

⭐ execute

"Test::ClassAPI" has a single method, "execute", and it's what kicks off the whole testing process. she accepts a single option argument, 'complete', which tells the testing process that the API you listed should be considered a complete list of the entire API. turning this on enables an additional test for each class, making sure that every public method in the class is detailed in the API description and that nothing has been "missed". so like, if you're a completionist, this is your moment. πŸ’―


🫢 SUPPORT 🫢

found a bug? 😭 bestie, submit it through the RT bug tracker at <https://rt.cpan.org/Public/Dist/Display.html?Name=Test-ClassAPI> β€” or you can email bug-Test-ClassAPI@rt.cpan.org.


πŸ‘‘ AUTHOR πŸ‘‘

Adam Kennedy <adamk@cpan.org>


🌟 CONTRIBUTORS 🌟

  • Adam Kennedy <adam@ali.as>
  • Karen Etheridge <ether@cpan.org>

This software is copyright (c) 2003 by Adam Kennedy.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.


so yeah, that's the whole page bestie πŸŽ€

and a lil sign-off for the girlies: this one was documented under perl v5.34.0, dated 2022-06-17, and it lives in the Test::ClassAPI(3pm) man page. slay, go forth, and may your class trees always pass the vibe check. πŸ’–βœ¨πŸ¦‹πŸŒΈ

πŸ“¦ where this page comes from