Files
whetstone_DSL/editor/tests/step493_test.cpp

173 lines
6.6 KiB
C++
Raw Normal View History

// Step 493: Parse Full Whetstone Codebase Tests (12 tests)
#include "SelfHostCodebaseAudit.h"
#include <filesystem>
#include <fstream>
#include <iostream>
namespace fs = std::filesystem;
static int passed = 0, failed = 0;
#define TEST(name) { std::cout << " " << #name << "... "; }
#define PASS() { std::cout << "PASS\n"; ++passed; }
#define FAIL(msg) { std::cout << "FAIL: " << msg << "\n"; ++failed; }
#define CHECK(cond, msg) if (!(cond)) { FAIL(msg); return; } else {}
static CodebaseParseAudit runRealAudit() {
return SelfHostCodebaseAudit::auditDirectories({"editor/src", "editor/src/ast"});
}
void test_lists_headers_from_target_directories() {
TEST(lists_headers_from_target_directories);
auto files = SelfHostCodebaseAudit::listHeaderFiles({"editor/src", "editor/src/ast"});
CHECK(!files.empty(), "expected header files");
bool foundParser = false;
for (const auto& f : files) {
if (f.find("Parser.h") != std::string::npos) foundParser = true;
}
CHECK(foundParser, "expected parser-related header");
PASS();
}
void test_audit_reports_total_file_count_nonzero() {
TEST(audit_reports_total_file_count_nonzero);
auto audit = runRealAudit();
CHECK(audit.totalFiles > 0, "expected non-zero total files");
PASS();
}
void test_parse_rate_is_within_0_to_1() {
TEST(parse_rate_is_within_0_to_1);
auto audit = runRealAudit();
CHECK(audit.parseRate() >= 0.0, "parse rate below 0");
CHECK(audit.parseRate() <= 1.0, "parse rate above 1");
PASS();
}
void test_audit_collects_class_function_and_annotation_counts() {
TEST(audit_collects_class_function_and_annotation_counts);
auto audit = runRealAudit();
CHECK(audit.totalClasses >= 0, "class count should be non-negative");
CHECK(audit.totalFunctions >= 0, "function count should be non-negative");
CHECK(audit.totalAnnotationNodes >= 0, "annotation count should be non-negative");
PASS();
}
void test_each_file_has_path_and_parse_flag() {
TEST(each_file_has_path_and_parse_flag);
auto audit = runRealAudit();
CHECK(!audit.files.empty(), "expected file audits");
for (const auto& f : audit.files) {
CHECK(!f.path.empty(), "missing file path");
}
PASS();
}
void test_skipped_constructs_log_is_populated_when_hint_exceeds_parse() {
TEST(skipped_constructs_log_is_populated_when_hint_exceeds_parse);
fs::path dir = fs::temp_directory_path() / "whetstone_step493_skip";
fs::remove_all(dir);
fs::create_directories(dir);
fs::path file = dir / "sample.h";
{
std::ofstream out(file.string());
out << "class A {};\nclass B {};\nint f();\n";
}
auto audit = SelfHostCodebaseAudit::auditFiles({file.string()});
CHECK(!audit.files.empty(), "expected single audit file");
bool hasSkipSignal = !audit.files[0].skippedConstructs.empty() || !audit.unparseableConstructLog.empty();
CHECK(hasSkipSignal, "expected skipped/log signal");
fs::remove_all(dir);
PASS();
}
void test_unreadable_or_empty_header_is_logged() {
TEST(unreadable_or_empty_header_is_logged);
fs::path dir = fs::temp_directory_path() / "whetstone_step493_empty";
fs::remove_all(dir);
fs::create_directories(dir);
fs::path file = dir / "empty.h";
{
std::ofstream out(file.string());
}
auto audit = SelfHostCodebaseAudit::auditFiles({file.string()});
CHECK(!audit.unparseableConstructLog.empty(), "expected warning log for empty file");
fs::remove_all(dir);
PASS();
}
void test_meets_target_function_matches_threshold_semantics() {
TEST(meets_target_function_matches_threshold_semantics);
CodebaseParseAudit a;
a.totalFiles = 100;
a.parsedFiles = 95;
CHECK(a.meetsTarget(0.95), "95/100 should meet 95% target");
CHECK(!a.meetsTarget(0.96), "95/100 should not meet 96% target");
PASS();
}
void test_audit_files_supports_direct_file_list_mode() {
TEST(audit_files_supports_direct_file_list_mode);
auto files = SelfHostCodebaseAudit::listHeaderFiles({"editor/src"});
CHECK(!files.empty(), "expected files from src");
std::vector<std::string> subset;
subset.push_back(files[0]);
auto audit = SelfHostCodebaseAudit::auditFiles(subset);
CHECK(audit.totalFiles == 1, "expected one file in direct mode");
PASS();
}
void test_unparseable_construct_log_contains_file_path_prefixes() {
TEST(unparseable_construct_log_contains_file_path_prefixes);
fs::path dir = fs::temp_directory_path() / "whetstone_step493_log";
fs::remove_all(dir);
fs::create_directories(dir);
fs::path file = dir / "empty.h";
{ std::ofstream out(file.string()); }
auto audit = SelfHostCodebaseAudit::auditFiles({file.string()});
CHECK(!audit.unparseableConstructLog.empty(), "expected log entries");
CHECK(audit.unparseableConstructLog[0].find(file.string()) != std::string::npos,
"log missing file path prefix");
fs::remove_all(dir);
PASS();
}
void test_parse_rate_matches_parsed_over_total_ratio() {
TEST(parse_rate_matches_parsed_over_total_ratio);
CodebaseParseAudit a;
a.totalFiles = 4;
a.parsedFiles = 3;
CHECK(a.parseRate() > 0.74 && a.parseRate() < 0.76, "expected 0.75 parse rate");
PASS();
}
void test_real_codebase_audit_has_high_reasonable_coverage_signal() {
TEST(real_codebase_audit_has_high_reasonable_coverage_signal);
auto audit = runRealAudit();
CHECK(audit.totalFiles >= 50, "expected substantial header corpus");
CHECK(audit.parsedFiles >= 1, "expected at least one parsed file");
PASS();
}
int main() {
std::cout << "Step 493: Parse Full Whetstone Codebase Tests\n";
test_lists_headers_from_target_directories(); // 1
test_audit_reports_total_file_count_nonzero(); // 2
test_parse_rate_is_within_0_to_1(); // 3
test_audit_collects_class_function_and_annotation_counts(); // 4
test_each_file_has_path_and_parse_flag(); // 5
test_skipped_constructs_log_is_populated_when_hint_exceeds_parse(); // 6
test_unreadable_or_empty_header_is_logged(); // 7
test_meets_target_function_matches_threshold_semantics(); // 8
test_audit_files_supports_direct_file_list_mode(); // 9
test_unparseable_construct_log_contains_file_path_prefixes(); // 10
test_parse_rate_matches_parsed_over_total_ratio(); // 11
test_real_codebase_audit_has_high_reasonable_coverage_signal(); // 12
std::cout << "\nResults: " << passed << "/" << (passed + failed)
<< " passed\n";
return failed == 0 ? 0 : 1;
}