For Perl developers, one module at a time
Perl ClinicModern Perl for the module you have - then the tests it is missing.
Paste a Perl module or script, and its .t file if you have one. Free in your browser: every legacy idiom and real defect, with the line and the fix - use v5.36, signatures instead of @_, three-argument open checked for errors, new Class(...), string eval, SQL built by interpolation, a module that does not end in 1; - and which public subs your tests actually call. A run reviews and rewrites the module, or writes the Test2::V0 test file; the page re-scans what comes back.
1 Your code free
2 The scan free
Against the rules of the two Perl skills, for the version above. Nothing leaves your browser for this part.
Where the problems are
What the tests call
Findings
3 The review or the tests metered
The reply, as it came
Findings
The scan's calls
Diff
The rewrite
Kept on purpose
Caveats
Covered
Skipped
Expected to fail against the current code
Diff against your .t
The test file
Run:
Caveats
Checked against the scan
Saved modules
How it works
The scan reads the code with POD, comments and __END__ ignored, and applies the rules of the perl-patterns and perl-testing skills: use v5.36 instead of the strict/warnings/feature boilerplate, signatures, a bare return;, three-argument open with a lexical handle and a checked result, Class->new, no string eval or symbolic references, placeholders in SQL, Exporter 'import' with @EXPORT_OK, Moo over blessed hashrefs, named captures and postfix dereference; for the tests, Test2::V0, done_testing, dies {} and lives {}, Test::MockModule rather than glob assignment. A rule whose feature your Perl lacks says "upgrade first" or stays quiet.
The review and the tests are written by a language model from your code and the scan's facts. The page holds the reply to the scan: every error and warning must be answered by rule id; the rewrite is re-scanned here, and a package, public sub or export that disappeared is named; the test file must use Test2::V0, end in done_testing, account for every public sub, and call nothing the module does not define. Nothing is run; check with perl -c and prove -l.