feat: establish first-class lexical language parity #2

Merged
trevon merged 14 commits from feat/language-parity-foundation into bench/yams-architecture-reproducibility 2026-08-30 22:09:40 +00:00
8 changed files with 201 additions and 0 deletions
Showing only changes of commit 1935710459 - Show all commits

test(scan): add first-class language fixtures

trvon 2026-08-30 14:53:30 -06:00
Signed by: trevon
GPG key ID: 38686EA797D7A8A7

View file

@ -49,6 +49,11 @@ fixtures for:
- duplicate symbols, nested scopes, strings, comments, and unsupported syntax;
- stable graph identities and evidence under repeated scans.
The positive baseline corpus lives in `tests/fixtures/languages`, with its
shared contract in `tests/language_parity.rs`. Gap slices should extend these
fixtures with a positive construct and its nearest clean negative before
changing extraction behavior.
Real-repository benchmarks supplement these fixtures but do not replace them.
Compare graph counts and health metrics only after confirming that analyzed
files, constructs, and evidence coverage remain stable. A lower health score can

13
tests/fixtures/languages/c/basic.c vendored Normal file
View file

@ -0,0 +1,13 @@
#include "support.h"
struct Worker {
int state;
};
int start() {
return helper();
}
int helper() {
return 0;
}

12
tests/fixtures/languages/cpp/basic.cpp vendored Normal file
View file

@ -0,0 +1,12 @@
#include "support.hpp"
class Worker : public Base {
public:
void start() {
helper();
}
};
int helper() {
return 0;
}

View file

@ -0,0 +1,9 @@
import 'package:example/base.dart';
class Controller extends Base {
void start() {
helper();
}
void helper() {}
}

View file

@ -0,0 +1,9 @@
import { Base } from './base.js';
class Worker extends Base {}
function start() {
helper();
}
function helper() {}

View file

@ -0,0 +1,9 @@
use crate::support::Dependency;
pub struct Worker;
pub fn start() {
helper();
}
fn helper() {}

View file

@ -0,0 +1,9 @@
import { Base } from './base.js';
class Worker extends Base {}
function start(): void {
helper();
}
function helper(): void {}

135
tests/language_parity.rs Normal file
View file

@ -0,0 +1,135 @@
use brick::model::{EdgeKind, NodeKind};
use brick::scan::scan;
use std::path::PathBuf;
struct FixtureCase {
directory: &'static str,
language: &'static str,
classes: &'static [&'static str],
functions: &'static [&'static str],
imports: usize,
inherits: usize,
calls: usize,
}
#[test]
fn first_class_language_fixtures_have_stable_baseline_evidence() {
let cases = [
FixtureCase {
directory: "dart",
language: "dart",
classes: &["Controller"],
functions: &["helper", "start"],
imports: 1,
inherits: 1,
calls: 1,
},
FixtureCase {
directory: "rust",
language: "rust",
classes: &["Worker"],
functions: &["helper", "start"],
imports: 1,
inherits: 0,
calls: 1,
},
FixtureCase {
directory: "c",
language: "cpp",
classes: &["Worker"],
functions: &["helper", "start"],
imports: 1,
inherits: 0,
calls: 1,
},
FixtureCase {
directory: "cpp",
language: "cpp",
classes: &["Worker"],
functions: &["helper", "start"],
imports: 1,
inherits: 1,
calls: 1,
},
FixtureCase {
directory: "javascript",
language: "javascript",
classes: &["Worker"],
functions: &["helper", "start"],
imports: 1,
inherits: 1,
calls: 1,
},
FixtureCase {
directory: "typescript",
language: "typescript",
classes: &["Worker"],
functions: &["helper", "start"],
imports: 1,
inherits: 1,
calls: 1,
},
];
for case in cases {
assert_fixture(case);
}
}
fn assert_fixture(case: FixtureCase) {
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests/fixtures/languages")
.join(case.directory);
let building = scan(&root).unwrap();
let mut classes: Vec<_> = building
.nodes
.iter()
.filter(|node| {
node.language.as_deref() == Some(case.language) && node.kind == NodeKind::Class
})
.map(|node| node.name.as_str())
.collect();
let mut functions: Vec<_> = building
.nodes
.iter()
.filter(|node| {
node.language.as_deref() == Some(case.language) && node.kind == NodeKind::Function
})
.map(|node| node.name.as_str())
.collect();
classes.sort_unstable();
functions.sort_unstable();
assert_eq!(classes, case.classes, "{} class baseline", case.directory);
assert_eq!(
functions, case.functions,
"{} function baseline",
case.directory
);
assert_eq!(
edge_count(&building, EdgeKind::Imports),
case.imports,
"{} import baseline",
case.directory
);
assert_eq!(
edge_count(&building, EdgeKind::Inherits),
case.inherits,
"{} inheritance baseline",
case.directory
);
assert_eq!(
edge_count(&building, EdgeKind::Calls),
case.calls,
"{} call baseline",
case.directory
);
}
fn edge_count(building: &brick::Building, kind: EdgeKind) -> usize {
building
.edges
.iter()
.filter(|edge| edge.kind == kind)
.count()
}