@@ -378,16 +378,16 @@ verify_tree_next_prev(tsk_treeseq_t *ts)
378378}
379379
380380static void
381- verify_tree_diffs (tsk_treeseq_t * ts )
381+ verify_tree_diffs (tsk_treeseq_t * ts , tsk_flags_t options )
382382{
383- int ret ;
383+ int ret , valid_tree ;
384384 tsk_diff_iter_t iter ;
385385 tsk_tree_t tree ;
386386 tsk_edge_list_node_t * record ;
387387 tsk_edge_list_t records_out , records_in ;
388- size_t num_nodes = tsk_treeseq_get_num_nodes (ts );
389- size_t j , num_trees ;
390- double left , right ;
388+ tsk_size_t num_nodes = tsk_treeseq_get_num_nodes (ts );
389+ tsk_size_t j , num_trees ;
390+ double lft , rgt ;
391391 tsk_id_t * parent = malloc (num_nodes * sizeof (tsk_id_t ));
392392 tsk_id_t * child = malloc (num_nodes * sizeof (tsk_id_t ));
393393 tsk_id_t * sib = malloc (num_nodes * sizeof (tsk_id_t ));
@@ -400,17 +400,17 @@ verify_tree_diffs(tsk_treeseq_t *ts)
400400 child [j ] = TSK_NULL ;
401401 sib [j ] = TSK_NULL ;
402402 }
403- ret = tsk_diff_iter_init (& iter , ts );
403+ ret = tsk_diff_iter_init (& iter , ts , options );
404404 CU_ASSERT_EQUAL_FATAL (ret , 0 );
405405 ret = tsk_tree_init (& tree , ts , 0 );
406406 CU_ASSERT_EQUAL_FATAL (ret , 0 );
407- ret = tsk_tree_first (& tree );
408- CU_ASSERT_EQUAL_FATAL (ret , 1 );
407+ valid_tree = tsk_tree_first (& tree );
408+ CU_ASSERT_EQUAL_FATAL (valid_tree , 1 );
409409 tsk_diff_iter_print_state (& iter , _devnull );
410410
411411 num_trees = 0 ;
412- while (( ret = tsk_diff_iter_next ( & iter , & left , & right , & records_out , & records_in ))
413- == 1 ) {
412+ while (
413+ ( ret = tsk_diff_iter_next ( & iter , & lft , & rgt , & records_out , & records_in )) == 1 ) {
414414 tsk_diff_iter_print_state (& iter , _devnull );
415415 num_trees ++ ;
416416 /* Update forwards */
@@ -420,9 +420,11 @@ verify_tree_diffs(tsk_treeseq_t *ts)
420420 for (record = records_in .head ; record != NULL ; record = record -> next ) {
421421 parent [record -> edge .child ] = record -> edge .parent ;
422422 }
423- /* Now check against the sparse tree iterator. */
424- for (j = 0 ; j < num_nodes ; j ++ ) {
425- CU_ASSERT_EQUAL (parent [j ], tree .parent [j ]);
423+ if (valid_tree ) {
424+ /* Now check against the sparse tree iterator. */
425+ for (j = 0 ; j < num_nodes ; j ++ ) {
426+ CU_ASSERT_EQUAL (parent [j ], tree .parent [j ]);
427+ }
426428 }
427429 /* Update backwards */
428430 for (record = records_out .tail ; record != NULL ; record = record -> prev ) {
@@ -431,21 +433,34 @@ verify_tree_diffs(tsk_treeseq_t *ts)
431433 for (record = records_in .tail ; record != NULL ; record = record -> prev ) {
432434 parent [record -> edge .child ] = record -> edge .parent ;
433435 }
434- /* Now check against the sparse tree iterator. */
435- for (j = 0 ; j < num_nodes ; j ++ ) {
436- CU_ASSERT_EQUAL (parent [j ], tree .parent [j ]);
437- }
438- CU_ASSERT_EQUAL (tree .left , left );
439- CU_ASSERT_EQUAL (tree .right , right );
440- ret = tsk_tree_next (& tree );
441- if (num_trees < tsk_treeseq_get_num_trees (ts )) {
442- CU_ASSERT_EQUAL (ret , 1 );
436+ if (valid_tree ) {
437+ /* Now check against the sparse tree iterator. */
438+ for (j = 0 ; j < num_nodes ; j ++ ) {
439+ CU_ASSERT_EQUAL (parent [j ], tree .parent [j ]);
440+ }
441+ CU_ASSERT_EQUAL (tree .left , lft );
442+ CU_ASSERT_EQUAL (tree .right , rgt );
443+ valid_tree = tsk_tree_next (& tree );
444+ if (num_trees < tsk_treeseq_get_num_trees (ts )) {
445+ CU_ASSERT_EQUAL (valid_tree , 1 );
446+ } else {
447+ CU_ASSERT_EQUAL (valid_tree , 0 );
448+ }
443449 } else {
444- CU_ASSERT_EQUAL (ret , 0 );
450+ CU_ASSERT_TRUE_FATAL (options & TSK_INCLUDE_TERMINAL );
451+ for (j = 0 ; j < num_nodes ; j ++ ) {
452+ CU_ASSERT_EQUAL (parent [j ], -1 );
453+ }
454+ CU_ASSERT_EQUAL (lft , tsk_treeseq_get_sequence_length (ts ));
455+ CU_ASSERT_EQUAL (rgt , tsk_treeseq_get_sequence_length (ts ));
445456 }
446457 }
447- CU_ASSERT_EQUAL (num_trees , tsk_treeseq_get_num_trees (ts ));
448- CU_ASSERT_EQUAL_FATAL (ret , 0 );
458+ if (options & TSK_INCLUDE_TERMINAL ) {
459+ CU_ASSERT_EQUAL (num_trees , tsk_treeseq_get_num_trees (ts ) + 1 );
460+ } else {
461+ CU_ASSERT_EQUAL (num_trees , tsk_treeseq_get_num_trees (ts ));
462+ }
463+ CU_ASSERT_EQUAL_FATAL (valid_tree , 0 );
449464 ret = tsk_diff_iter_free (& iter );
450465 CU_ASSERT_EQUAL_FATAL (ret , 0 );
451466 ret = tsk_tree_free (& tree );
@@ -4597,7 +4612,8 @@ test_simple_diff_iter(void)
45974612 tsk_treeseq_from_text (& ts , 10 , paper_ex_nodes , paper_ex_edges , NULL , NULL , NULL ,
45984613 paper_ex_individuals , NULL , 0 );
45994614
4600- verify_tree_diffs (& ts );
4615+ verify_tree_diffs (& ts , 0 );
4616+ verify_tree_diffs (& ts , TSK_INCLUDE_TERMINAL );
46014617
46024618 ret = tsk_treeseq_free (& ts );
46034619 CU_ASSERT_EQUAL (ret , 0 );
@@ -4611,7 +4627,8 @@ test_nonbinary_diff_iter(void)
46114627
46124628 tsk_treeseq_from_text (& ts , 100 , nonbinary_ex_nodes , nonbinary_ex_edges , NULL , NULL ,
46134629 NULL , NULL , NULL , 0 );
4614- verify_tree_diffs (& ts );
4630+ verify_tree_diffs (& ts , 0 );
4631+ verify_tree_diffs (& ts , TSK_INCLUDE_TERMINAL );
46154632
46164633 ret = tsk_treeseq_free (& ts );
46174634 CU_ASSERT_EQUAL (ret , 0 );
@@ -4625,7 +4642,8 @@ test_unary_diff_iter(void)
46254642
46264643 tsk_treeseq_from_text (
46274644 & ts , 10 , unary_ex_nodes , unary_ex_edges , NULL , NULL , NULL , NULL , NULL , 0 );
4628- verify_tree_diffs (& ts );
4645+ verify_tree_diffs (& ts , 0 );
4646+ verify_tree_diffs (& ts , TSK_INCLUDE_TERMINAL );
46294647
46304648 ret = tsk_treeseq_free (& ts );
46314649 CU_ASSERT_EQUAL (ret , 0 );
@@ -4639,7 +4657,38 @@ test_internal_sample_diff_iter(void)
46394657
46404658 tsk_treeseq_from_text (& ts , 10 , internal_sample_ex_nodes , internal_sample_ex_edges ,
46414659 NULL , NULL , NULL , NULL , NULL , 0 );
4642- verify_tree_diffs (& ts );
4660+ verify_tree_diffs (& ts , 0 );
4661+ verify_tree_diffs (& ts , TSK_INCLUDE_TERMINAL );
4662+
4663+ ret = tsk_treeseq_free (& ts );
4664+ CU_ASSERT_EQUAL (ret , 0 );
4665+ }
4666+
4667+ static void
4668+ test_multiroot_diff_iter (void )
4669+ {
4670+ int ret ;
4671+ tsk_treeseq_t ts ;
4672+
4673+ tsk_treeseq_from_text (& ts , 10 , multiroot_ex_nodes , multiroot_ex_edges , NULL , NULL ,
4674+ NULL , NULL , NULL , 0 );
4675+ verify_tree_diffs (& ts , 0 );
4676+ verify_tree_diffs (& ts , TSK_INCLUDE_TERMINAL );
4677+
4678+ ret = tsk_treeseq_free (& ts );
4679+ CU_ASSERT_EQUAL (ret , 0 );
4680+ }
4681+
4682+ static void
4683+ test_empty_diff_iter (void )
4684+ {
4685+ int ret ;
4686+ tsk_treeseq_t ts ;
4687+
4688+ tsk_treeseq_from_text (
4689+ & ts , 10 , empty_ex_nodes , empty_ex_edges , NULL , NULL , NULL , NULL , NULL , 0 );
4690+ verify_tree_diffs (& ts , 0 );
4691+ verify_tree_diffs (& ts , TSK_INCLUDE_TERMINAL );
46434692
46444693 ret = tsk_treeseq_free (& ts );
46454694 CU_ASSERT_EQUAL (ret , 0 );
@@ -6041,6 +6090,8 @@ main(int argc, char **argv)
60416090 { "test_nonbinary_diff_iter" , test_nonbinary_diff_iter },
60426091 { "test_unary_diff_iter" , test_unary_diff_iter },
60436092 { "test_internal_sample_diff_iter" , test_internal_sample_diff_iter },
6093+ { "test_multiroot_diff_iter" , test_multiroot_diff_iter },
6094+ { "test_empty_diff_iter" , test_empty_diff_iter },
60446095
60456096 /* Sample sets */
60466097 { "test_simple_sample_sets" , test_simple_sample_sets },
0 commit comments