mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-24 03:08:45 +08:00
test: add Drupal accuracy negatives and measured corpus samples
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
const {test}=require('node:test');
|
||||
const fs=require('node:fs'),os=require('node:os'),path=require('node:path'),assert=require('node:assert/strict');
|
||||
const {ExtensionManager}=require('../../dist/plugins/manager');
|
||||
const {DatabaseSync}=require('node:sqlite');
|
||||
Object.assign(process.env,{CODEGRAPH_TELEMETRY:'0',CODEGRAPH_PARSE_WORKERS:'2',CODEGRAPH_RESOLVE_WORKERS:'0'});
|
||||
test('Drupal declarations and event registrations distinguish executable wiring from quoted and commented examples',async()=>{
|
||||
const root=fs.mkdtempSync(path.join(os.tmpdir(),'cg-drupal-accuracy-'));
|
||||
const files={
|
||||
'composer.json':JSON.stringify({name:'drupal/accuracy'}),
|
||||
'sample.services.yml':`services:
|
||||
sample.dep:
|
||||
class: Drupal\\sample\\Dependency
|
||||
`,
|
||||
'Calls.php':`<?php
|
||||
namespace Drupal\\sample;
|
||||
class Calls {
|
||||
public function good() { \\Drupal::service('sample.dep'); $dispatcher->dispatch($event, 'done'); }
|
||||
public function bad() { NotDrupal::service('sample.dep'); $dispatcher->dispatch($event, 'fake'); }
|
||||
}
|
||||
class Dependency {}
|
||||
`,
|
||||
'Subscriber.php':`<?php
|
||||
namespace Drupal\\sample;
|
||||
use Symfony\\Component\\EventDispatcher\\EventSubscriberInterface;
|
||||
class Subscriber implements EventSubscriberInterface {
|
||||
public static function getSubscribedEvents() {
|
||||
// $events['fake'] = 'onFake';
|
||||
$example = "'fake' => 'onFake'";
|
||||
return ['done' => ['onDone', 100]];
|
||||
}
|
||||
public function onDone() {}
|
||||
public function onFake() {}
|
||||
}
|
||||
`,
|
||||
'Plugins.php':`<?php
|
||||
namespace Drupal\\sample;
|
||||
/** @Block(id = "real") */
|
||||
class RealPlugin {
|
||||
public function example() { $text = '@Block(id = "fake")'; }
|
||||
}
|
||||
class NoPlugin {}
|
||||
`,
|
||||
'Hooks.php':`<?php
|
||||
namespace Drupal\\sample;
|
||||
class Hooks {
|
||||
// #[\\Drupal\\Core\\Hook\\Attribute\\Hook('fake')]
|
||||
public function notHook() {}
|
||||
#[\\Drupal\\Core\\Hook\\Attribute\\Hook('done')]
|
||||
public function actualHook() {}
|
||||
public function dispatch() { $modules->invokeAll('fake'); $modules->invokeAll('done'); }
|
||||
}
|
||||
`};
|
||||
try {
|
||||
for(const [name,body]of Object.entries(files))fs.writeFileSync(path.join(root,name),body);
|
||||
await new ExtensionManager(root).install({bytes:fs.readFileSync('dist/extensions/drupal.cgext'),replaces:['drupal']});
|
||||
const db=new DatabaseSync(path.join(root,'.codegraph/codegraph.db'),{readOnly:true});
|
||||
try {
|
||||
const edges=db.prepare("SELECT s.name source,t.name target,json_extract(e.metadata,'$.label') label FROM edges e JOIN nodes s ON s.id=e.source JOIN nodes t ON t.id=e.target WHERE json_extract(e.metadata,'$.synthesizedBy')='drupal'").all();
|
||||
for(const [source,target,label] of [['good','Dependency','Drupal service lookup'],['good','onDone','Drupal event done'],['dispatch','actualHook','Drupal hook done']])assert.ok(edges.some(e=>e.source===source&&e.target===target&&e.label===label),JSON.stringify({source,target,label,edges}));
|
||||
assert.deepEqual(edges.filter(e=>e.source==='bad'||e.target==='onFake'||e.target==='notHook'),[],'Unrelated static receiver and commented/string declarations are not wiring');
|
||||
assert.deepEqual(db.prepare("SELECT name FROM nodes WHERE kind='component' AND id LIKE 'plugin:drupal:%' ORDER BY name").all().map(n=>n.name),['Block:real']);
|
||||
}finally{db.close();}
|
||||
}finally{fs.rmSync(root,{recursive:true,force:true});}
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
// One isolated sample. Orchestration alternates arms; never flush shared host caches.
|
||||
const fs=require('node:fs'),path=require('node:path'),cp=require('node:child_process'),crypto=require('node:crypto'),assert=require('node:assert/strict');
|
||||
const {DatabaseSync}=require('node:sqlite');
|
||||
const {CodeGraph}=require('../../dist');
|
||||
const {ExtensionManager}=require('../../dist/plugins/manager');
|
||||
Object.assign(process.env,{CODEGRAPH_TELEMETRY:'0',CODEGRAPH_PARSE_WORKERS:'2',CODEGRAPH_RESOLVE_WORKERS:'0',CODEGRAPH_SYNTH_TIMINGS:'all'});
|
||||
const [project,mode,operation,output,artifact='dist/extensions/drupal.cgext']=process.argv.slice(2);
|
||||
const hash=b=>crypto.createHash('sha256').update(b).digest('hex');
|
||||
function graphSnapshot(){const db=new DatabaseSync(path.join(project,'.codegraph/codegraph.db'),{readOnly:true});try{
|
||||
const nodes=db.prepare('SELECT * FROM nodes ORDER BY id').all().map(({updated_at,...n})=>n);
|
||||
const edges=db.prepare('SELECT source,target,kind,metadata,line,col,provenance FROM edges ORDER BY source,target,kind,line,col,metadata').all();
|
||||
return {files:db.prepare('SELECT count(*) n FROM files').get().n,nodes:nodes.length,edges:edges.length,pluginEdges:edges.filter(e=>JSON.parse(e.metadata||'{}').synthesizedBy==='drupal').length,hash:hash(JSON.stringify({nodes,edges}))};
|
||||
}finally{db.close();}}
|
||||
(async()=>{
|
||||
assert.ok(['builtin','external'].includes(mode));assert.ok(['first','rebuild','sync'].includes(operation));
|
||||
const started=performance.now(),cpu=process.cpuUsage();let result;
|
||||
if(operation==='first'&&mode==='external')result=await new ExtensionManager(project).install({bytes:fs.readFileSync(artifact),replaces:['drupal']});
|
||||
else {const graph=CodeGraph.isInitialized(project)?await CodeGraph.open(project):await CodeGraph.init(project);try{result=operation==='rebuild'?await graph.refreshPluginIndex():operation==='sync'?await graph.sync():await graph.indexAll();}finally{graph.close();}}
|
||||
assert.ok(!result?.filesErrored && result?.success!==false,JSON.stringify(result));
|
||||
const measured={wallMs:performance.now()-started,cpu:process.cpuUsage(cpu),resources:process.resourceUsage()};
|
||||
const record={revision:cp.execFileSync('git',['rev-parse','HEAD'],{encoding:'utf8'}).trim(),dirty:!!cp.execFileSync('git',['status','--porcelain'],{encoding:'utf8'}).trim(),project,mode,operation,artifactSHA:mode==='external'?hash(fs.readFileSync(artifact)):null,node:process.version,platform:process.platform,...measured,graph:graphSnapshot()};
|
||||
fs.mkdirSync(path.dirname(output),{recursive:true});fs.writeFileSync(output,JSON.stringify(record,null,2));console.log(JSON.stringify(record));
|
||||
})().catch(e=>{console.error(e);process.exitCode=1;});
|
||||
Reference in New Issue
Block a user