gobby-code 1.3.3

Fast Rust CLI for Gobby's code index — AST-aware search, symbol navigation, and dependency graph
Documentation
use super::support::*;

fn write_identity(project: &std::path::Path, project_id: &str, name: &str) {
    fs::write(
        project.join(".gobby/gcode.json"),
        serde_json::json!({
            "id": project_id,
            "name": name,
            "created_at": "2026-06-16T00:00:00Z"
        })
        .to_string(),
    )
    .expect("write gcode identity");
}

fn seed_leftover_local_import(conn: &mut Client, caller_id: &str) {
    conn.execute(
        "INSERT INTO code_calls
            (project_id, caller_symbol_id, callee_symbol_id, callee_name, callee_target_kind,
             callee_external_module, file_path, line)
         VALUES ($1, $2, '', 'helper', 'local_import', 'src/utils.js', 'legacy.js', 99)",
        &[&JS_DEFAULT_LOCAL_PROJECT_ID, &caller_id],
    )
    .expect("seed leftover local_import row");
}

#[test]
fn index_resolves_local_javascript_default_imports_and_leftover_sweep() {
    let Some(env) = StandaloneEnv::from_env() else {
        eprintln!(
            "skipping JavaScript default local-import resolution; set GCODE_GRAPH_STANDALONE_DATABASE_URL, GCODE_GRAPH_STANDALONE_FALKOR_HOST, and GCODE_GRAPH_STANDALONE_FALKOR_PORT"
        );
        return;
    };

    let project = tempfile::tempdir().expect("temp project");
    fs::create_dir_all(project.path().join(".gobby")).expect("create .gobby");
    fs::create_dir_all(project.path().join("src")).expect("create src");
    fs::write(
        project.path().join("src/utils.js"),
        "export default function helper() {\n  return 42;\n}\n",
    )
    .expect("write utils.js");
    fs::write(
        project.path().join("src/main.js"),
        "import runHelper from './utils';\n\nexport function caller() {\n  return runHelper();\n}\n",
    )
    .expect("write main.js");
    write_identity(
        project.path(),
        JS_DEFAULT_LOCAL_PROJECT_ID,
        "graph-standalone-js-default-local",
    );

    let mut conn = Client::connect(&env.database_url, NoTls).expect("connect PostgreSQL");
    cleanup_project(&mut conn, JS_DEFAULT_LOCAL_PROJECT_ID).expect("cleanup JS default project");
    let _cleanup = ProjectCleanup::new(&env.database_url, JS_DEFAULT_LOCAL_PROJECT_ID);

    let indexed = run_gcode(&env, project.path(), &["index", "--full"]);
    assert_success(indexed, "gcode index --full");

    let helper_id = required_symbol_id(
        &mut conn,
        JS_DEFAULT_LOCAL_PROJECT_ID,
        "src/utils.js",
        "helper",
    );
    let caller_id = required_symbol_id(
        &mut conn,
        JS_DEFAULT_LOCAL_PROJECT_ID,
        "src/main.js",
        "caller",
    );
    assert_eq!(
        resolved_call_target(
            &mut conn,
            JS_DEFAULT_LOCAL_PROJECT_ID,
            "src/main.js",
            "runHelper"
        ),
        Some(helper_id.clone()),
        "JavaScript default import call did not resolve to the canonical helper symbol"
    );
    assert_eq!(
        pending_local_import_count(&mut conn, JS_DEFAULT_LOCAL_PROJECT_ID),
        0,
        "no local_import rows should survive the first completed index run"
    );

    seed_leftover_local_import(&mut conn, &caller_id);
    assert_eq!(
        pending_local_import_count(&mut conn, JS_DEFAULT_LOCAL_PROJECT_ID),
        1,
        "seeded leftover local_import row should be pending before the sweep"
    );

    let reindexed = run_gcode(&env, project.path(), &["index", "--full"]);
    assert_success(reindexed, "gcode index --full after leftover seed");
    assert_eq!(
        resolved_call_target(
            &mut conn,
            JS_DEFAULT_LOCAL_PROJECT_ID,
            "legacy.js",
            "helper"
        ),
        Some(helper_id),
        "full-index project sweep did not promote the leftover local_import row"
    );
    assert_eq!(
        pending_local_import_count(&mut conn, JS_DEFAULT_LOCAL_PROJECT_ID),
        0,
        "no local_import rows should survive the project-scoped sweep"
    );

    let rebuilt = json_command(&env, project.path(), &["graph", "rebuild"]);
    assert_eq!(rebuilt["success"], true);
    assert_caller_present(&env, project.path(), "helper", "caller", "after rebuild");
}