1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//! GAP-E2E-010 (v1.0.89): regression tests for `codex-models --json` and
//! `pending --db`.
//!
//! Background:
//! - Before the fix, `sqlite-graphrag codex-models --json` failed with
//! `unexpected argument '--json'` because the variant was declared as a
//! bare unit variant (`CodexModels`). Agent pipelines that append `--json`
//! to every invocation broke.
//! - Before the fix, `sqlite-graphrag pending list --db <PATH>` failed
//! with `unexpected argument '--db'` because `PendingListArgs` and
//! `PendingShowArgs` did not declare the field. Operators running two
//! databases side-by-side could not target a specific file.
//!
//! These tests confirm both surfaces accept their flags without error and
//! that the dispatch path is wired correctly.
use clap::Parser;
use sqlite_graphrag::cli::{Cli, Commands};
// ---------------------------------------------------------------------------
// GAP-E2E-010 (a): codex-models --json is accepted as a no-op
// ---------------------------------------------------------------------------
#[test]
fn codex_models_json_flag_accepted_as_noop() {
// Before the fix: try_parse_from returned Err("unexpected argument '--json'").
// After the fix: parse succeeds and the json flag is captured as true.
let cli = Cli::try_parse_from(["sqlite-graphrag", "codex-models", "--json"])
.expect("codex-models --json deve ser aceito como no-op");
match cli.command {
Some(Commands::CodexModels(args)) => {
assert!(
args.json,
"CodexModelsArgs.json deve ser true quando --json é passado"
);
}
other => panic!("esperava CodexModels, recebi: {other:?}"),
}
}
#[test]
fn codex_models_without_json_still_parses() {
// Back-compat: bare `codex-models` (without --json) must still parse.
let cli = Cli::try_parse_from(["sqlite-graphrag", "codex-models"])
.expect("codex-models sem --json deve continuar parseando");
match cli.command {
Some(Commands::CodexModels(args)) => {
assert!(
!args.json,
"CodexModelsArgs.json deve ser false quando --json é omitido"
);
}
other => panic!("esperava CodexModels, recebi: {other:?}"),
}
}
#[test]
fn codex_models_json_flag_does_not_appear_in_help() {
// `hide = true` garante que --json não polui a saída de `codex-models --help`
// para operadores humanos. Agentes descobrem o no-op por docs, não por help.
// FIX-1 (v1.0.89): clap 4.6 requires (not
// ) because needs .
// returns (shared borrow), which
// cannot be mutated in place.
let mut cmd = <Cli as clap::CommandFactory>::command();
let help = cmd
.find_subcommand_mut("codex-models")
.expect("codex-models subcommand deve existir")
.render_help();
assert!(
!help.to_string().contains("--json"),
"--json deve estar escondido (hide = true) na help do codex-models"
);
}
// ---------------------------------------------------------------------------
// GAP-E2E-010b: pending list --db and pending show --db are accepted
// ---------------------------------------------------------------------------
#[test]
fn pending_list_db_flag_is_accepted() {
let cli = Cli::try_parse_from([
"sqlite-graphrag",
"pending",
"list",
"--db",
"/tmp/some-graphrag.sqlite",
])
.expect("pending list --db deve ser aceito");
match cli.command {
Some(Commands::Pending(p)) => match p.cmd {
sqlite_graphrag::commands::pending::PendingCmd::List(args) => {
assert_eq!(
args.db.as_deref(),
Some("/tmp/some-graphrag.sqlite"),
"PendingListArgs.db deve capturar o valor passado"
);
}
other => panic!("esperava PendingCmd::List, recebi: {other:?}"),
},
other => panic!("esperava Pending, recebi: {other:?}"),
}
}
#[test]
fn pending_show_db_flag_is_accepted() {
let cli = Cli::try_parse_from([
"sqlite-graphrag",
"pending",
"show",
"42",
"--db",
"/tmp/another.sqlite",
])
.expect("pending show --db deve ser aceito");
match cli.command {
Some(Commands::Pending(p)) => match p.cmd {
sqlite_graphrag::commands::pending::PendingCmd::Show(args) => {
assert_eq!(args.pending_id, 42);
assert_eq!(
args.db.as_deref(),
Some("/tmp/another.sqlite"),
"PendingShowArgs.db deve capturar o valor passado"
);
}
other => panic!("esperava PendingCmd::Show, recebi: {other:?}"),
},
other => panic!("esperava Pending, recebi: {other:?}"),
}
}
#[test]
fn pending_list_without_db_uses_default_path() {
// Back-compat: omitir --db deve produzir None (AppPaths::resolve decide).
let cli = Cli::try_parse_from(["sqlite-graphrag", "pending", "list"])
.expect("pending list sem --db deve continuar parseando");
match cli.command {
Some(Commands::Pending(p)) => match p.cmd {
sqlite_graphrag::commands::pending::PendingCmd::List(args) => {
assert!(
args.db.is_none(),
"PendingListArgs.db deve ser None quando --db é omitido"
);
}
other => panic!("esperava PendingCmd::List, recebi: {other:?}"),
},
other => panic!("esperava Pending, recebi: {other:?}"),
}
}