Developer-Dashboard

 view release on metacpan or  search on metacpan

t/15-release-metadata.t  view on Meta::CPAN

    like( $doc, qr/\.js.*node|node.*\.js/s, 'docs describe direct executable JavaScript command and hook dispatch through node' );
    like( $doc, qr/\.py.*python|python.*\.py/s, 'docs describe direct executable Python command and hook dispatch through python' );
    like( $doc, qr/\.java.*javac.*java|javac.*\.java.*java/s, 'docs describe direct executable Java command and hook dispatch through javac and java' );
    like( $doc, qr/dashboard hi|dashboard foo/, 'docs include concrete custom-command examples for source-backed CLI dispatch' );
    unlike( $doc, qr/CPANManager/, 'docs do not describe a dedicated CPAN manager module for a removed browser workspace runtime driver flow' );
    like( $doc, qr/Developer::Dashboard::SKILLS/, 'docs point readers at the shipped skill POD module' );
    unlike( $doc, qr/standalone `of` and `open-file`|standalone of and open-file/, 'docs no longer advertise public standalone of/open-file executables' );
    unlike( $doc, qr/standalone `ticket` executable|standalone ticket executable/, 'docs no longer advertise a public standalone ticket executable' );
    like( $doc, qr/Developer::Dashboard::Runtime::Result/, 'docs use the namespaced Runtime::Result module name' );
    like( $doc, qr/Developer::Dashboard::Folder/, 'docs use the namespaced Folder module name' );
    like( $doc, qr/Folder->all|all_paths|new_from_all_folders|Collector->new_from_all_folders/, 'docs mention the public Perl path inventory API' );
    like( $doc, qr/dashboard which/, 'docs mention the command inspection helper explicitly' );
    like( $doc, qr/COMMAND \/full\/path|HOOK \/full\/path/, 'docs describe the COMMAND and HOOK output shape for dashboard which' );
    like( $doc, qr/--edit.*dashboard open-file|dashboard open-file.*--edit/s, 'docs describe dashboard which --edit re-entering dashboard open-file' );
    like( $doc, qr/Developer::Dashboard::EnvAudit/, 'docs mention the env provenance audit API' );
    like( $doc, qr/\.env\.pl|\.env/, 'docs describe layered env files explicitly' );
    like( $doc, qr/skill-local env files (?:load|are loaded) only when a skill command|skill env files only load when a skill command/i, 'docs describe skill-local env loading isolation' );
    like( $doc, qr/\.env.*before.*\.env\.pl|\.env\.pl.*after.*\.env/s, 'docs describe same-level .env before .env.pl ordering' );
    like( $doc, qr/\$NAME|\$\{NAME:-default\}|\$\{Namespace::function\(\):-default\}/, 'docs describe supported plain env expansion forms' );
    like( $doc, qr/whole-line `\/\/` comments|whole-line C<\/\/> comments|block comments.*multiple lines|block comments.*multi-line/i, 'docs describe supported .env comment syntax including // and block comments' );
    like( $doc, qr/vX\.XX\S*\s+tag\s+so\s+the\s+tag-triggered\s+GitHub\s+release\s+workflow/s, 'docs describe pushing a vX.XX tag as the trigger for the tag-driven GitHub release workflow' );
    like( $doc, qr/tarball,\s+checksum,\s+and\s+detached\s+signature\s+assets/s, 'docs name the tarball, checksum and detached signature assets that the release workflow publishes' );
    like( $doc, qr/Signed-Releases/, 'docs name the Signed-Releases Scorecard check that the published release assets back' );
    like( $doc, qr/\.intoto\.jsonl/, 'docs name the provenance asset, because signing alone leaves Signed-Releases capped below full marks' );
    like( $doc, qr/build\s+provenance/i, 'docs describe the release as carrying build provenance and not merely a signature' );
}

for my $doc (
    [ 'README.md', $readme ],
    [ 'lib/Developer/Dashboard.pm', $pm ],
    [ 'doc/housekeeper-rotation.md', $housekeeper_rotation_doc ],
  )
{
    my ( $label, $content ) = @{$doc};
    next if !defined $content || $content eq '';
    like(
        $content,
        qr/local .* explicit numeric timezone offset|explicit numeric timezone offset .* local/s,
        "$label documents that collector-visible timestamps follow the machine local timezone with an explicit offset",
    );
}

for my $doc ( grep { defined && $_ ne '' } ( $skill_guide, $skills_pod ) ) {
    like( $doc, qr/dashboard skills install/, 'skill authoring docs explain installation' );
    like( $doc, qr/dashboard skills install browser foo\/bar git\@github\.com:user\/example-skill\.git/, 'skill authoring docs explain multi-source skill installs' );
    like( $doc, qr/dashboard skill list|C<dashboard skill>/, 'skill authoring docs explain the singular skill management alias' );
    like( $doc, qr/\.gitignore.*skills\/<repo-name>\/|\.gitignore.*skills\/E<lt>repo-nameE<gt>\//s, 'skill authoring docs explain home gitignore skill tree registration' );
    like( $doc, qr/\/absolute\/path\/to\/example-skill/, 'skill authoring docs explain direct local skill installs' );
    like( $doc, qr/\.git\/.*\.env.*VERSION|\.env.*VERSION.*\.git\//is, 'skill authoring docs explain local skill qualification' );
    like( $doc, qr/dashboard example-skill\.hello/, 'skill authoring docs explain dotted command dispatch' );
    unlike( $doc, qr/dashboard skill example-skill/, 'skill authoring docs no longer describe the removed singular dispatcher' );
    like( $doc, qr{~/.developer-dashboard/skills/<repo-name>/|F<~/.developer-dashboard/skills/E<lt>repo-nameE<gt>/>}, 'skill authoring docs describe the isolated skill root' );
    like( $doc, qr/DD-OOP-LAYERS.*skill|skill.*DD-OOP-LAYERS/is, 'skill authoring docs describe layered skill lookup through DD-OOP-LAYERS' );
    like( $doc, qr/deepest.*shadow|shadow.*deepest|deepest matching repo name/is, 'skill authoring docs describe deepest-layer skill shadowing' );
    like( $doc, qr/cli\/<command>\.d|cli\/E<lt>commandE<gt>\.d/, 'skill authoring docs explain skill hook directories' );
    like( $doc, qr/dashboards\//, 'skill authoring docs explain skill bookmark storage' );
    like( $doc, qr{/app/<repo-name>|/app/E<lt>repo-nameE<gt>|/skill/<repo-name>/bookmarks/<id>|/skill/E<lt>repo-nameE<gt>/bookmarks/E<lt>idE<gt>}, 'skill authoring docs explain skill bookmark routes' );
    like( $doc, qr{/ajax/<repo-name>/|/ajax/E<lt>repo-nameE<gt>/|/js/<repo-name>/|/css/<repo-name>/|/others/<repo-name>/}, 'skill authoring docs explain skill-local ajax and public asset routes' );
    like( $doc, qr/TITLE:.*BOOKMARK:.*HTML:.*CODE1:/s, 'skill authoring docs explain bookmark section syntax' );
    like( $doc, qr/fetch_value\(|stream_value\(|stream_data\(/, 'skill authoring docs explain bookmark browser helpers' );
    like( $doc, qr/Ajax\(file\s*=>\s*'name'|C<Ajax\(file =E<gt> 'name'/, 'skill authoring docs explain saved Ajax endpoints' );
    like( $doc, qr/nav\/\*\.tt|nav\/foo\.tt/, 'skill authoring docs explain nav bookmark structure' );
    like( $doc, qr{~/.developer-dashboard/cli/<command>\.d|~/.developer-dashboard/cli/E<lt>commandE<gt>\.d}, 'skill authoring docs explain dashboard-wide custom CLI hooks' );
    like( $doc, qr/DEVELOPER_DASHBOARD_SKILL_ROOT/, 'skill authoring docs explain the skill command environment' );
    like( $doc, qr/LAST_RESULT/, 'skill authoring docs explain previous-hook payloads' );
    like( $doc, qr/RESULT_FILE|LAST_RESULT_FILE/, 'skill authoring docs explain file-backed hook result overflow handling' );
    like( $doc, qr/\[\[STOP\]\]/, 'skill authoring docs explain explicit hook stop markers' );
    like( $doc, qr/_example-skill|_<repo-name>|_E<lt>repo-nameE<gt>|_something/, 'skill authoring docs explain underscored skill config merge keys' );
    like( $doc, qr/aptfile/, 'skill authoring docs explain isolated apt dependency installation' );
    like( $doc, qr/cpanfile/, 'skill authoring docs explain isolated dependency installation' );
    like( $doc, qr/config\/docker/, 'skill authoring docs explain skill docker roots' );
    like( $doc, qr/FAQ/i, 'skill authoring docs include an FAQ section' );
    unlike( $doc, qr/FORM\.TT:|FORM:/, 'skill authoring docs no longer document removed FORM bookmark directives' );
}

for my $path (@doc_paths) {
    my $doc = _slurp($path);
    unlike( $doc, qr/\blegacy\b/i, "$path no longer mentions the retired internal wording" );
    unlike( $doc, qr/`FORM\.TT:`|`FORM:`|\bFORM\.TT\b/, "$path no longer documents removed FORM bookmark directives" );
}

for my $path (@pod_paths) {
    my $pod = _extract_pod( _slurp($path) );
    unlike( $pod, qr/\blegacy\b/i, "$path POD no longer mentions the retired internal wording" );
    unlike( $pod, qr/C<FORM\.TT:>|C<FORM:>|\bFORM\.TT\b/, "$path POD no longer documents removed FORM bookmark directives" );
}

# DD-434: the auth regression test's own POD is security documentation, so it
# must describe the DNS-rebinding admin-trust invariant as enforced rather than
# as an open gap, and must not advertise a TODO block the file does not carry.
# DD-387 closed that gap; the POD went stale behind it and told readers a
# loopback admin-elevation hole was merely "documented" and still open.
{
    my $auth_hunt      = _slurp( _repo_path( 't', '57-hunt-auth.t' ) );
    my $auth_hunt_pod  = _extract_pod($auth_hunt);
    my $auth_hunt_body = $auth_hunt;
    $auth_hunt_body =~ s/\n__END__\n.*\z//s;

    unlike( $auth_hunt_pod, qr/gap that remains/i, 'auth regression POD no longer calls the DNS-rebinding gap outstanding' );
    unlike( $auth_hunt_pod, qr/\bresidual\b/i,     'auth regression POD no longer calls the DNS-rebinding trust decision residual' );
    unlike( $auth_hunt_pod, qr/still[- ]open/i,    'auth regression POD no longer calls the DNS-rebinding tightening still open' );
    unlike( $auth_hunt_pod, qr/\bTODO\b/,          'auth regression POD no longer cites a TODO block' );
    unlike( $auth_hunt_body, qr/\bTODO\b/,         'auth regression test body carries no TODO block for its POD to cite' );
    like( $auth_hunt_pod, qr/DNS-rebinding/,       'auth regression POD still names the DNS-rebinding invariant it guards' );
    like( $auth_hunt_body, qr/DNS-rebinding admin-trust/, 'auth regression test body still pins the DNS-rebinding admin-trust invariant' );
}

for my $doc ( grep { defined && $_ ne '' } ($readme) ) {
    like( $doc, qr/install\.sh/, 'README documents the repo bootstrap installer' );
    like( $doc, qr/cpanm --no-wget --notest Developer::Dashboard/, 'README documents the repo bootstrap installer cpanm contract' );
    like( $doc, qr/aptfile.*apkfile.*brewfile|aptfile.*brewfile.*apkfile|apkfile.*aptfile.*brewfile|apkfile.*brewfile.*aptfile|brewfile.*aptfile.*apkfile|brewfile.*apkfile.*aptfile/is, 'README documents the repo bootstrap package manifests' );
    like( $doc, qr/checkout-only.*install\.sh|install\.sh.*checkout-only/is, 'README documents install.sh as a checkout-only bootstrap script instead of an installed CPAN command' );
    like( $doc, qr/checkout-only.*install\.ps|install\.ps.*checkout-only/is, 'README and POD document install.ps1 as a checkout-only bootstrap script instead of an installed CPAN command' );
    like( $doc, qr/PowerShell.*install\.ps|install\.ps.*PowerShell/is, 'README and POD document install.ps1 as the Windows bootstrap entrypoint' );
    like( $doc, qr/dashboard skills install/, 'README documents skill installation' );
    like( $doc, qr/dashboard skills install browser foo\/bar git\@github\.com:user\/example-skill\.git/, 'README documents multi-source skill installation' );
    like( $doc, qr/dashboard skill list|`dashboard skill`/, 'README documents the singular skill management alias' );
    like( $doc, qr/\.gitignore.*skills\/<repo-name>\//s, 'README documents home gitignore skill tree registration' );
    like( $doc, qr/dashboard skills install \/absolute\/path\/to\/example-skill/, 'README documents direct local skill installation' );
    like( $doc, qr/dashboard skills uninstall/, 'README documents skill uninstallation' );
    like( $doc, qr/Update registered skills.*dashboard skills install/s, 'README documents bare install as the registered-skill update command' );



( run in 0.831 second using v1.01-cache-2.11-cpan-9789f410c06 )