const { test } = require('node:test'); const fs = require('node:fs'); const os = require('node:os'); const path = require('node:path'); const assert = require('node:assert/strict'); const { DatabaseSync } = require('node:sqlite'); const { ExtensionManager } = require('../../dist/plugins/manager'); process.env.CODEGRAPH_TELEMETRY = '0'; process.env.CODEGRAPH_PARSE_WORKERS = '2'; test('Drupal explicit flows resolve; comments, strings, computed ids, cycles and ambiguous plugin ids stay unresolved', async () => { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'cg-drupal-negative-')); try { const files = { 'composer.json': JSON.stringify({ name: 'drupal/recovery' }), 'sample.routing.yml': `sample.valid: path: '/sample/{id}' defaults: _controller: '\\Drupal\\sample\\Handler::run' sample.unknown: path: '/unknown' defaults: _controller: '\\Missing\\Controller::missing' `, 'sample.services.yml': `services: sample.handler: class: Drupal\\sample\\Handler arguments: ['@sample.dep', '@missing', '@cycle.a'] sample.dep: class: Drupal\\sample\\Dependency cycle.a: alias: cycle.b cycle.b: alias: cycle.a `, 'Handler.php': `createInstance('valid'); $manager->createInstance('duplicate'); $dispatcher->dispatch($event, 'sample.done'); $modules->invokeAll('sample'); } public function noise() { // \\Drupal::service('sample.dep'); $example = "\\Drupal::service('sample.dep')"; /* $modules->invokeAll('sample'); */ $computed = 'sample.dep'; \\Drupal::service($computed); $manager->createInstance($plugin); } } class Dependency {} `, 'sample.module': ` 'onDone']; } public function onDone() {} } `, 'Valid.php': ` e.source === source && e.target === target && e.label === label), JSON.stringify({ source, target, label, edges })); assert.deepEqual(edges.filter(e => e.source === 'noise'), [], 'Non-code and computed lookups are not graph evidence'); assert.deepEqual(edges.filter(e => e.source === '/unknown'), []); assert.ok(!edges.some(e => e.label === 'Drupal plugin construction' && e.target.startsWith('Duplicate'))); } finally { db.close(); } } finally { fs.rmSync(root, { recursive: true, force: true }); } });