diff --git a/test/hierarchies.test.vim b/test/hierarchies.test.vim new file mode 100644 index 0000000000..2592d32aa0 --- /dev/null +++ b/test/hierarchies.test.vim @@ -0,0 +1,172 @@ +function! Test_Call_Hierarchy() + call youcompleteme#test#setup#OpenFile( '/test/testdata/cpp/hierarchies.cc', {} ) + call cursor( [ 1, 5 ] ) + + " Check that f's callers are present + function! Check1( id ) + call assert_equal( py3eval( 'len( vim.buffers[ ' . string( hierarchy_buf_nr ) . ' ]' ), 4 ) + call assert_match( '^+Function: f.*:1', getbufline( hierarchy_buf_nr, 1 )[ 0 ] ) + call assert_match( '^ +Function: g.*:4', getbufline( hierarchy_buf_nr, 2 )[ 0 ] ) + call assert_match( '^ +Function: g.*:4', getbufline( hierarchy_buf_nr, 3 )[ 0 ] ) + call assert_match( '^ +Function: h.*:9', getbufline( hierarchy_buf_nr, 4 )[ 0 ] ) + call FeedAndCheckAgain( "\\", funcref( 'Check2' ) ) + endfunction + + " Check that g's callers are present + function! Check2( id ) + call assert_equal( py3eval( 'len( vim.buffers[ ' . string( hierarchy_buf_nr ) . ' ]' ), 5 ) + call assert_match( '^+Function: f.*:1', getbufline( hierarchy_buf_nr, 1 )[ 0 ] ) + call assert_match( '^ -Function: g.*:4', getbufline( hierarchy_buf_nr, 2 )[ 0 ] ) + call assert_match( '^ -Function: g.*:4', getbufline( hierarchy_buf_nr, 3 )[ 0 ] ) + call assert_match( '^ +Function: h.*:8', getbufline( hierarchy_buf_nr, 4 )[ 0 ] ) + call assert_match( '^ +Function: h.*:9', getbufline( hierarchy_buf_nr, 5 )[ 0 ] ) + call FeedAndCheckAgain( "\\\", funcref( 'Check3' ) ) + endfunction + + " Check that 1st h's callers are present + function! Check3( id ) + call assert_equal( py3eval( 'len( vim.buffers[ ' . string( hierarchy_buf_nr ) . ' ]' ), 5 ) + call assert_match( '^+Function: f.*:1', getbufline( hierarchy_buf_nr, 1 )[ 0 ] ) + call assert_match( '^ -Function: g.*:4', getbufline( hierarchy_buf_nr, 2 )[ 0 ] ) + call assert_match( '^ -Function: g.*:4', getbufline( hierarchy_buf_nr, 3 )[ 0 ] ) + call assert_match( '^ -Function: h.*:8', getbufline( hierarchy_buf_nr, 4 )[ 0 ] ) + call assert_match( '^ +Function: h.*:9', getbufline( hierarchy_buf_nr, 5 )[ 0 ] ) + call FeedAndCheckAgain( "\\", funcref( 'Check4' ) ) + endfunction + + " Check that 2nd h's callers are present + function! Check4( id ) + call assert_equal( py3eval( 'len( vim.buffers[ ' . string( hierarchy_buf_nr ) . ' ]' ), 5 ) + call assert_match( '^+Function: f.*:1', getbufline( hierarchy_buf_nr, 1 )[ 0 ] ) + call assert_match( '^ -Function: g.*:4', getbufline( hierarchy_buf_nr, 2 )[ 0 ] ) + call assert_match( '^ -Function: g.*:4', getbufline( hierarchy_buf_nr, 3 )[ 0 ] ) + call assert_match( '^ -Function: h.*:8', getbufline( hierarchy_buf_nr, 4 )[ 0 ] ) + call assert_match( '^ -Function: h.*:9', getbufline( hierarchy_buf_nr, 5 )[ 0 ] ) + call FeedAndCheckAgain( "\\\\\", funcref( 'Check5' ) ) + endfunction + + " Try to access callees of f + function! Check5( id ) + call assert_equal( py3eval( 'len( vim.buffers[ ' . string( hierarchy_buf_nr ) . ' ]' ), 5 ) + call assert_match( '^-Function: f.*:1', getbufline( hierarchy_buf_nr, 1 )[ 0 ] ) + call assert_match( '^ -Function: g.*:4', getbufline( hierarchy_buf_nr, 2 )[ 0 ] ) + call assert_match( '^ -Function: g.*:4', getbufline( hierarchy_buf_nr, 3 )[ 0 ] ) + call assert_match( '^ -Function: h.*:8', getbufline( hierarchy_buf_nr, 4 )[ 0 ] ) + call assert_match( '^ -Function: h.*:9', getbufline( hierarchy_buf_nr, 5 )[ 0 ] ) + call FeedAndCheckAgain( "\\\\\", funcref( 'Check6' ) ) + endfunction + + " Re-root at h + function! Check6( id ) + call assert_equal( py3eval( 'len( vim.buffers[ ' . string( hierarchy_buf_nr ) . ' ]' ), 1 ) + call assert_match( '^+Function: h', getbufline( hierarchy_buf_nr, 1 ) ) + call FeedAndCheckAgain( "\\", funcref( 'Check7' ) ) + endfunction + + " Expansion after re-rooting works. + " NOTE: Clangd does not support outgoing calls, hence, we are stuck at just h. + function! Check7( id ) + call assert_equal( py3eval( 'len( vim.buffers[ ' . string( hierarchy_buf_nr ) . ' ]' ), 1 ) + call assert_match( '^-Function: h', getbufline( hierarchy_buf_nr, 1 ) ) + call FeedAndCheckAgain( "\", funcref( 'Check8' ) ) + endfunction + + " Make sure it is closed + function! Check8( id ) + call assert_equal( len( popup_list() ), 0 ) + endfunction + + call youcompleteme#hierarchy#StartRequest( 'call' ) + call WaitForAssert( { -> assert_equal( len( popup_list() ), 1 ) } ) + let popup_ids = popup_list() + let hierarchy_win_id = popup_ids[ 0 ] + let hierarchy_buf_nr = winbufnr( hierarchy_win_id ) + " Check that `+Function f` is at the start of the only line in the popup + call assert_equal( py3eval( 'len( vim.buffers[ ' . string( hierarchy_buf_nr ) . ' ]' ), 1 ) + call assert_match( '^+Function: f', getbufline( hierarchy_buf_nr, 1 ) ) + call FeedAndCheckMain( "\", funcref( 'Check1' ) ) +endfunction + +function! Test_Type_Hierarchy() + call youcompleteme#test#setup#OpenFile( '/test/testdata/cpp/hierarchies.cc', {} ) + call cursor( [ 13, 8 ] ) + + " Check that B1's subtypes are present + function! Check1( id ) + call assert_equal( py3eval( 'len( vim.buffers[ ' . string( hierarchy_buf_nr ) . ' ]' ), 2 ) + call assert_match( '^+Struct: B1.*:13', getbufline( hierarchy_buf_nr, 1 )[ 0 ] ) + call assert_match( '^ +Struct: D1.*:16', getbufline( hierarchy_buf_nr, 2 )[ 0 ] ) + call FeedAndCheckAgain( "\\", funcref( 'Check2' ) ) + endfunction + + " Try to access D1's subtypes + function! Check2( id ) + call assert_equal( py3eval( 'len( vim.buffers[ ' . string( hierarchy_buf_nr ) . ' ]' ), 2 ) + call assert_match( '^+Struct: B1.*:13', getbufline( hierarchy_buf_nr, 1 )[ 0 ] ) + call assert_match( '^ -Struct: D1.*:16', getbufline( hierarchy_buf_nr, 2 )[ 0 ] ) + call FeedAndCheckAgain( "\\", funcref( 'Check3' ) ) + endfunction + + " Check that 1st h's callers are present + function! Check3( id ) + call assert_equal( py3eval( 'len( vim.buffers[ ' . string( hierarchy_buf_nr ) . ' ]' ), 3 ) + call assert_match( '^ +Struct: B0.*:12', getbufline( hierarchy_buf_nr, 1 )[ 0 ] ) + call assert_match( '^-Struct: B1.*:13', getbufline( hierarchy_buf_nr, 2 )[ 0 ] ) + call assert_match( '^ -Struct: D1.*:16', getbufline( hierarchy_buf_nr, 3 )[ 0 ] ) + call FeedAndCheckAgain( "\\", funcref( 'Check4' ) ) + endfunction + + " Check that 2nd h's callers are present + function! Check4( id ) + call assert_equal( py3eval( 'len( vim.buffers[ ' . string( hierarchy_buf_nr ) . ' ]' ), 3 ) + call assert_match( '^ -Struct: B0.*:12', getbufline( hierarchy_buf_nr, 1 )[ 0 ] ) + call assert_match( '^-Struct: B1.*:13', getbufline( hierarchy_buf_nr, 2 )[ 0 ] ) + call assert_match( '^ -Struct: D1.*:16', getbufline( hierarchy_buf_nr, 3 )[ 0 ] ) + call FeedAndCheckAgain( "\", funcref( 'Check5' ) ) + endfunction + + " Re-root at B0: supertypes->subtypes + function! Check5( id ) + call assert_equal( py3eval( 'len( vim.buffers[ ' . string( hierarchy_buf_nr ) . ' ]' ), 4 ) + call assert_match( '^+Struct: B0.*:12', getbufline( hierarchy_buf_nr, 1 )[ 0 ] ) + call assert_match( '^ +Struct: B1.*:13', getbufline( hierarchy_buf_nr, 2 )[ 0 ] ) + call assert_match( '^ +Struct: D0.*:15', getbufline( hierarchy_buf_nr, 3 )[ 0 ] ) + call assert_match( '^ +Struct: D1.*:16', getbufline( hierarchy_buf_nr, 4 )[ 0 ] ) + call FeedAndCheckAgain( "\\\\", funcref( 'Check6' ) ) + endfunction + + " Re-root at D1: subtypes->supertypes + function! Check6( id ) + call assert_equal( py3eval( 'len( vim.buffers[ ' . string( hierarchy_buf_nr ) . ' ]' ), 3 ) + call assert_match( '^ +Struct: B0.*:12', getbufline( hierarchy_buf_nr, 1 )[ 0 ] ) + call assert_match( '^ +Struct: B1.*:13', getbufline( hierarchy_buf_nr, 2 )[ 0 ] ) + call assert_match( '^+Struct: D1.*:16', getbufline( hierarchy_buf_nr, 3 )[ 0 ] ) + call FeedAndCheckAgain( "\\\", funcref( 'Check7' ) ) + endfunction + + " Expansion after re-rooting works. + function! Check7( id ) + call assert_equal( py3eval( 'len( vim.buffers[ ' . string( hierarchy_buf_nr ) . ' ]' ), 4 ) + call assert_match( '^ +Struct: B0.*:12', getbufline( hierarchy_buf_nr, 1 )[ 0 ] ) + call assert_match( '^ +Struct: B0.*:12', getbufline( hierarchy_buf_nr, 2 )[ 0 ] ) + call assert_match( '^ -Struct: B1.*:13', getbufline( hierarchy_buf_nr, 3 )[ 0 ] ) + call assert_match( '^-Struct: D1.*:16', getbufline( hierarchy_buf_nr, 4 )[ 0 ] ) + call FeedAndCheckAgain( "\", funcref( 'Check7' ) ) + endfunction + + " Make sure it is closed + function! Check8( id ) + call assert_equal( len( popup_list() ), 0 ) + endfunction + + call youcompleteme#hierarchy#StartRequest( 'type' ) + call WaitForAssert( { -> assert_equal( len( popup_list() ), 1 ) } ) + let popup_ids = popup_list() + let hierarchy_win_id = popup_ids[ 0 ] + let hierarchy_buf_nr = winbufnr( hierarchy_win_id ) + " Check that `+Function f` is at the start of the only line in the popup + py3 import vim + call assert_equal( py3eval( 'len( vim.buffers[ ' . string( hierarchy_buf_nr ) . ' ]' ), 1 ) + call assert_match( '^+Struct: B1', getbufline( hierarchy_buf_nr, 1 ) ) + call FeedAndCheckMain( "\", funcref( 'Check1' ) ) +endfunction diff --git a/test/testdata/cpp/hierarchies.cc b/test/testdata/cpp/hierarchies.cc new file mode 100644 index 0000000000..f2af7513de --- /dev/null +++ b/test/testdata/cpp/hierarchies.cc @@ -0,0 +1,16 @@ +int f(); + +int g() { + return f() + f(); +} + +int h() { + int x = g(); + return f() + x; +} + +struct B0 {}; +struct B1 : B0 {}; + +struct D0 : B0 {}; +struct D1 : B0, B1 {};