@ -1696,7 +1696,10 @@ fn graph_chain() {
// B's line should use `└──`.
let line_b = stdout . lines ( ) . find ( | l | l . contains ( & id_b ) ) . unwrap ( ) ;
assert! ( line_b . contains ( "└──" ) , "child should use └── connector: {line_b}" ) ;
assert! (
line_b . contains ( "└──" ) ,
"child should use └── connector: {line_b}"
) ;
}
/// `nbd graph <id>` for ticket A shows A and its dependents but not unrelated
@ -1714,7 +1717,10 @@ fn graph_single_ticket_subtree() {
assert! ( stdout . contains ( & id_a ) , "root should be in subtree" ) ;
assert! ( stdout . contains ( & id_b ) , "dependent should be in subtree" ) ;
assert! ( ! stdout . contains ( & id_c ) , "unrelated ticket should be absent: {stdout}" ) ;
assert! (
! stdout . contains ( & id_c ) ,
"unrelated ticket should be absent: {stdout}"
) ;
}
/// `nbd graph --json` produces valid JSON with `nodes` and `edges` arrays.
@ -1730,12 +1736,22 @@ fn graph_json_output() {
let parsed : serde_json ::Value =
serde_json ::from_str ( & stdout ) . expect ( "--json should produce valid JSON" ) ;
let nodes = parsed [ "nodes" ] . as_array ( ) . expect ( "nodes should be an array" ) ;
let edges = parsed [ "edges" ] . as_array ( ) . expect ( "edges should be an array" ) ;
let nodes = parsed [ "nodes" ]
. as_array ( )
. expect ( "nodes should be an array" ) ;
let edges = parsed [ "edges" ]
. as_array ( )
. expect ( "edges should be an array" ) ;
let node_ids : Vec < & str > = nodes . iter ( ) . map ( | n | n [ "id" ] . as_str ( ) . unwrap ( ) ) . collect ( ) ;
assert! ( node_ids . contains ( & id_a . as_str ( ) ) , "nodes should include id_a" ) ;
assert! ( node_ids . contains ( & id_b . as_str ( ) ) , "nodes should include id_b" ) ;
assert! (
node_ids . contains ( & id_a . as_str ( ) ) ,
"nodes should include id_a"
) ;
assert! (
node_ids . contains ( & id_b . as_str ( ) ) ,
"nodes should include id_b"
) ;
assert_eq! ( edges . len ( ) , 1 , "should have exactly one edge (A blocks B)" ) ;
assert_eq! ( edges [ 0 ] [ "from" ] . as_str ( ) . unwrap ( ) , id_a ) ;
assert_eq! ( edges [ 0 ] [ "to" ] . as_str ( ) . unwrap ( ) , id_b ) ;
@ -1776,7 +1792,10 @@ fn graph_filter() {
let stdout = String ::from_utf8 ( output . stdout ) . unwrap ( ) ;
assert! ( stdout . contains ( & id_bug ) , "bug ticket should be visible" ) ;
assert! ( ! stdout . contains ( & id_task ) , "task ticket should be excluded: {stdout}" ) ;
assert! (
! stdout . contains ( & id_task ) ,
"task ticket should be excluded: {stdout}"
) ;
}
/// `nbd graph <3-char-prefix>` resolves to the correct ticket using prefix
@ -1794,5 +1813,80 @@ fn graph_partial_id() {
String ::from_utf8_lossy ( & output . stderr )
) ;
let stdout = String ::from_utf8 ( output . stdout ) . unwrap ( ) ;
assert! ( stdout . contains ( & id_a ) , "resolved ticket should appear in output" ) ;
assert! (
stdout . contains ( & id_a ) ,
"resolved ticket should appear in output"
) ;
}
// ── update diff output tests ──────────────────────────────────────────────────
/// `nbd update <id> --status in_progress` (no `--json`) prints `- status:` and
/// `+ status:` lines showing what changed.
#[ test ]
fn update_no_json_prints_diff ( ) {
let env = TestEnv ::new ( ) ;
let id = env . create ( & [ "--title" , "Diff test" ] ) ;
let output = env . run ( & [ "update" , & id , "--status" , "in_progress" ] ) ;
assert! (
output . status . success ( ) ,
"update failed: {}" ,
String ::from_utf8_lossy ( & output . stderr )
) ;
let stdout = String ::from_utf8 ( output . stdout ) . unwrap ( ) ;
assert! (
stdout . contains ( "- status:" ) ,
"should show old status line: {stdout}"
) ;
assert! (
stdout . contains ( "+ status:" ) ,
"should show new status line: {stdout}"
) ;
assert! ( stdout . contains ( "todo" ) , "should show old value: {stdout}" ) ;
assert! (
stdout . contains ( "in_progress" ) ,
"should show new value: {stdout}"
) ;
}
/// `nbd update <id> --json` still prints full JSON (no diff).
#[ test ]
fn update_with_json_flag_prints_full_ticket ( ) {
let env = TestEnv ::new ( ) ;
let id = env . create ( & [ "--title" , "JSON update test" ] ) ;
let output = env . run ( & [ "update" , & id , "--status" , "in_progress" , "--json" ] ) ;
assert! (
output . status . success ( ) ,
"update --json failed: {}" ,
String ::from_utf8_lossy ( & output . stderr )
) ;
let stdout = String ::from_utf8 ( output . stdout ) . unwrap ( ) ;
// Must be valid JSON containing the updated ticket.
let parsed : serde_json ::Value =
serde_json ::from_str ( & stdout ) . expect ( "--json output should be valid JSON" ) ;
assert_eq! ( parsed [ "status" ] , "in_progress" ) ;
assert_eq! ( parsed [ "title" ] , "JSON update test" ) ;
// Should NOT contain diff markers.
assert! (
! stdout . contains ( "- status:" ) ,
"JSON output should not contain diff markers: {stdout}"
) ;
}
/// `nbd update` with no changes prints `(no changes)`.
#[ test ]
fn update_no_changes_prints_no_changes ( ) {
let env = TestEnv ::new ( ) ;
let id = env . create ( & [ "--title" , "Unchanged" ] ) ;
// Update with no field changes (supply same status).
let output = env . run ( & [ "update" , & id , "--status" , "todo" ] ) ;
assert! ( output . status . success ( ) ) ;
let stdout = String ::from_utf8 ( output . stdout ) . unwrap ( ) ;
assert! (
stdout . contains ( "(no changes)" ) ,
"should print '(no changes)' when nothing changed: {stdout}"
) ;
}