2020
2121import os
2222import json
23- from typing import Dict , List
23+ from typing import Dict , List , Tuple
2424from unittest .mock import patch , MagicMock
2525import networkx as nx
2626from networkx import DiGraph
@@ -269,9 +269,11 @@ def test_get_symbol_table(test_fixture, analysis_json_fixture):
269269 target_files = None ,
270270 )
271271 code_analyzer .application = None
272- comp_unit = code_analyzer .get_symbol_table ()
273- assert comp_unit is not None
274- assert isinstance (comp_unit , Dict )
272+ symbol_table = code_analyzer .get_symbol_table ()
273+ assert symbol_table is not None
274+ assert isinstance (symbol_table , Dict )
275+ for _ , comp_unit in symbol_table .items ():
276+ assert isinstance (comp_unit , JCompilationUnit )
275277
276278
277279def test_get_application_view (test_fixture , analysis_json_fixture ):
@@ -298,7 +300,7 @@ def test_get_application_view(test_fixture, analysis_json_fixture):
298300 assert isinstance (app , JApplication )
299301
300302 # Test with source file
301- code_analyzer .source_code = "dummy .java"
303+ code_analyzer .source_code = "./tests/resources/java/application/sample.daytrader8-1.2/src/main/java/com/ibm/websphere/samples/daytrader/web/websocket/ActionMessage .java"
302304 app = code_analyzer .get_application_view ()
303305 assert app is not None
304306 assert isinstance (app , JApplication )
@@ -326,6 +328,7 @@ def test_get_system_dependency_graph(test_fixture, analysis_json_fixture):
326328 graph = code_analyzer .get_system_dependency_graph ()
327329 assert graph is not None
328330 assert isinstance (graph , list )
331+ assert len (graph ) > 0
329332 assert isinstance (graph [0 ], JGraphEdges )
330333
331334
@@ -342,7 +345,7 @@ def test_get_call_graph(test_fixture, analysis_json_fixture):
342345 source_code = None ,
343346 analysis_backend_path = None ,
344347 analysis_json_path = None ,
345- analysis_level = AnalysisLevel .symbol_table ,
348+ analysis_level = AnalysisLevel .call_graph ,
346349 use_graalvm_binary = False ,
347350 eager_analysis = False ,
348351 target_files = None ,
@@ -352,7 +355,7 @@ def test_get_call_graph(test_fixture, analysis_json_fixture):
352355 assert isinstance (graph , DiGraph )
353356
354357 # test for symbol table
355- code_analyzer .analysis_level = " symbol_table"
358+ code_analyzer .analysis_level = AnalysisLevel . symbol_table
356359 graph = code_analyzer .get_call_graph ()
357360 assert graph is not None
358361 assert isinstance (graph , DiGraph )
@@ -407,20 +410,20 @@ def test_get_all_callers(test_fixture, analysis_json_fixture):
407410 all_callers = code_analyzer .get_all_callers ("com.ibm.websphere.samples.daytrader.util.Log" , "log(String)" , False )
408411 assert all_callers is not None
409412 assert isinstance (all_callers , Dict )
413+ assert len (all_callers ) > 0
410414 assert "caller_details" in all_callers
411415 assert len (all_callers ["caller_details" ]) == 18
412416 for method in all_callers ["caller_details" ]:
413417 assert isinstance (method ["caller_method" ], JMethodDetail )
414418
419+ # Call using symbol table
420+
415421 # TODO: This currently doesn't work. Code has bad call as seen in this error message:
416422 # TypeError: JavaSitter.get_calling_lines() missing 1 required positional argument: 'is_target_method_a_constructor'
417- # Uncomment when code is fixed.
418-
419- # # Call using symbol table
420- # all_callers = code_analyzer.get_all_callers("com.ibm.websphere.samples.daytrader.util.Log", "log(String)", True)
421- # assert all_callers is not None
422- # assert isinstance(all_callers, Dict)
423- # assert "caller_details" in all_callers
423+ all_callers = code_analyzer .get_all_callers ("com.ibm.websphere.samples.daytrader.util.Log" , "log(String)" , True )
424+ assert all_callers is not None
425+ assert isinstance (all_callers , Dict )
426+ assert "caller_details" in all_callers
424427
425428
426429def test_get_all_callees (test_fixture , analysis_json_fixture ):
@@ -443,20 +446,21 @@ def test_get_all_callees(test_fixture, analysis_json_fixture):
443446 )
444447
445448 # Call without using symbol table
446- all_callees = code_analyzer .get_all_callees ("com.ibm.websphere.samples.daytrader.util.Log" , "log (String)" , False )
449+ all_callees = code_analyzer .get_all_callees ("com.ibm.websphere.samples.daytrader.util.Log" , "printCollection (String, Collection )" , False )
447450 assert all_callees is not None
448451 assert isinstance (all_callees , Dict )
449452 assert "callee_details" in all_callees
450- assert len (all_callees ["callee_details" ]) == 0
453+ assert len (all_callees ["callee_details" ]) == 2
451454
452- # Call using symbol table
453- all_callees = code_analyzer .get_all_callees ("com.ibm.websphere.samples.daytrader.util.Log" , "log(String)" , True )
455+ # Call using the symbol table
456+
457+ # TODO: Throws the following exception
458+ # TypeError: JavaSitter.get_calling_lines() missing 1 required positional argument: 'is_target_method_a_constructor'
459+ all_callees = code_analyzer .get_all_callees ("com.ibm.websphere.samples.daytrader.util.Log" , "printCollection(String, Collection)" , True )
454460 assert all_callees is not None
455461 assert isinstance (all_callees , Dict )
456- # TODO: Bug, the Dict is empty.
457- # need to uncomment when code is fixed
458- # assert "callee_details" in all_callees
459- # assert len(all_callees["callee_details"]) == 0
462+ assert "callee_details" in all_callees
463+ assert len (all_callees ["callee_details" ]) == 2
460464
461465
462466def test_get_all_methods_in_application (test_fixture , analysis_json_fixture ):
@@ -480,6 +484,14 @@ def test_get_all_methods_in_application(test_fixture, analysis_json_fixture):
480484 all_methods = code_analyzer .get_all_methods_in_application ()
481485 assert all_methods is not None
482486 assert isinstance (all_methods , Dict )
487+ assert len (all_methods ) > 0
488+ # Validate structure
489+ for _ , method in all_methods .items ():
490+ assert method is not None
491+ assert isinstance (method , Dict )
492+ for _ , callable in method .items ():
493+ assert callable is not None
494+ assert isinstance (callable , JCallable )
483495
484496
485497def test_get_all_classes (test_fixture , analysis_json_fixture ):
@@ -501,9 +513,14 @@ def test_get_all_classes(test_fixture, analysis_json_fixture):
501513 target_files = None ,
502514 )
503515
504- all_methods = code_analyzer .get_all_classes ()
505- assert all_methods is not None
506- assert isinstance (all_methods , Dict )
516+ all_classes = code_analyzer .get_all_classes ()
517+ assert all_classes is not None
518+ assert isinstance (all_classes , Dict )
519+ assert len (all_classes ) > 0
520+ # Validate structure
521+ for _ , a_class in all_classes .items ():
522+ assert a_class is not None
523+ assert isinstance (a_class , JType )
507524
508525
509526def test_get_class (test_fixture , analysis_json_fixture ):
@@ -608,6 +625,10 @@ def test_get_all_methods_in_class(test_fixture, analysis_json_fixture):
608625 assert all_methods is not None
609626 assert isinstance (all_methods , Dict )
610627 assert len (all_methods ) > 0
628+ # Validate structure
629+ for _ , method in all_methods .items ():
630+ assert method is not None
631+ assert isinstance (method , JCallable )
611632
612633
613634def test_get_all_constructors (test_fixture , analysis_json_fixture ):
@@ -629,10 +650,21 @@ def test_get_all_constructors(test_fixture, analysis_json_fixture):
629650 target_files = None ,
630651 )
631652
653+ # Test if it finds the 3 constructors in AccountDataBean
632654 all_constructors = code_analyzer .get_all_constructors ("com.ibm.websphere.samples.daytrader.entities.AccountDataBean" )
633655 assert all_constructors is not None
634656 assert isinstance (all_constructors , Dict )
635657 assert len (all_constructors ) == 3
658+ # Validate structure
659+ for _ , constructor in all_constructors .items ():
660+ assert constructor is not None
661+ assert isinstance (constructor , JCallable )
662+
663+ # Test class with no constructors
664+ all_constructors = code_analyzer .get_all_constructors ("com.ibm.websphere.samples.daytrader.util.FinancialUtils" )
665+ assert all_constructors is not None
666+ assert isinstance (all_constructors , Dict )
667+ assert len (all_constructors ) == 0
636668
637669
638670def test_get_all_sub_classes (test_fixture , analysis_json_fixture ):
@@ -648,15 +680,17 @@ def test_get_all_sub_classes(test_fixture, analysis_json_fixture):
648680 source_code = None ,
649681 analysis_backend_path = None ,
650682 analysis_json_path = None ,
651- analysis_level = AnalysisLevel .call_graph ,
683+ analysis_level = AnalysisLevel .symbol_table ,
652684 use_graalvm_binary = False ,
653685 eager_analysis = False ,
654686 target_files = None ,
655687 )
656688
657- all_subclasses = code_analyzer .get_all_sub_classes ("com.ibm.websphere.samples.daytrader.TradeAction " )
689+ all_subclasses = code_analyzer .get_all_sub_classes ("javax.ws.rs.core.Application " )
658690 assert all_subclasses is not None
659691 assert isinstance (all_subclasses , Dict )
692+ assert len (all_subclasses ) == 1
693+ assert "com.ibm.websphere.samples.daytrader.jaxrs.JAXRSApplication" in all_subclasses
660694
661695
662696def test_get_all_fields (test_fixture , analysis_json_fixture ):
@@ -709,9 +743,13 @@ def test_get_all_nested_classes(test_fixture, analysis_json_fixture):
709743 target_files = None ,
710744 )
711745
712- all_nested_classes = code_analyzer .get_all_nested_classes ("com.ibm.websphere.samples.daytrader.TradeAction" )
746+ # TODO: This should return 1 but return 0
747+
748+ # Test with a KeyBlock that has nested KeyBlockIterator
749+ all_nested_classes = code_analyzer .get_all_nested_classes ("com.ibm.websphere.samples.daytrader.util.KeyBlock" )
713750 assert all_nested_classes is not None
714751 assert isinstance (all_nested_classes , List )
752+ assert len (all_nested_classes ) == 1
715753
716754 # Handle class not found
717755 all_nested_classes = code_analyzer .get_all_nested_classes ("com.not.Found" )
@@ -739,12 +777,14 @@ def test_get_extended_classes(test_fixture, analysis_json_fixture):
739777 target_files = None ,
740778 )
741779
742- all_extended_classes = code_analyzer .get_extended_classes ("com.ibm.websphere.samples.daytrader.TradeAction " )
780+ all_extended_classes = code_analyzer .get_extended_classes ("com.ibm.websphere.samples.daytrader.util.TradeRunTimeModeLiteral " )
743781 assert all_extended_classes is not None
744782 assert isinstance (all_extended_classes , List )
783+ assert len (all_extended_classes ) == 1
784+ assert "javax.enterprise.util.AnnotationLiteral<com.ibm.websphere.samples.daytrader.interfaces.RuntimeMode>" in all_extended_classes
745785
746- # Handle class not found
747- all_extended_classes = code_analyzer .get_extended_classes ("com.not.Found " )
786+ # Test with class that is not extended
787+ all_extended_classes = code_analyzer .get_extended_classes ("com.ibm.websphere.samples.daytrader.entities.HoldingDataBean " )
748788 assert all_extended_classes is not None
749789 assert isinstance (all_extended_classes , List )
750790 assert len (all_extended_classes ) == 0
@@ -769,13 +809,16 @@ def test_get_implemented_interfaces(test_fixture, analysis_json_fixture):
769809 target_files = None ,
770810 )
771811
772- # Call without using symbol table
773- all_interfaces = code_analyzer .get_implemented_interfaces ("com.ibm.websphere.samples.daytrader.TradeAction " )
812+ # Call class that implements 2 interfaces
813+ all_interfaces = code_analyzer .get_implemented_interfaces ("com.ibm.websphere.samples.daytrader.impl.direct.TradeDirect " )
774814 assert all_interfaces is not None
775815 assert isinstance (all_interfaces , List )
816+ assert len (all_interfaces ) == 2
817+ assert "com.ibm.websphere.samples.daytrader.interfaces.TradeServices" in all_interfaces
818+ assert "java.io.Serializable" in all_interfaces
776819
777- # Handle class not found
778- all_interfaces = code_analyzer .get_implemented_interfaces ("com.not.Found " )
820+ # Call class that implements no interfaces
821+ all_interfaces = code_analyzer .get_implemented_interfaces ("com.ibm.websphere.samples.daytrader.util.TradeConfig " )
779822 assert all_interfaces is not None
780823 assert isinstance (all_interfaces , List )
781824 assert len (all_interfaces ) == 0
@@ -800,16 +843,19 @@ def test_get_class_call_graph_using_symbol_table(test_fixture, analysis_json_fix
800843 target_files = None ,
801844 )
802845
803- # TODO: The code seems to be broken for this case
804- # # Call with method signature
805- # all_call_graph = code_analyzer.get_class_call_graph_using_symbol_table("com.ibm.websphere.samples.daytrader.TradeAction", "getQuote(String)")
806- # assert all_call_graph is not None
807- # assert isinstance(all_call_graph, List)
846+ # TODO: I could be wrong but I think these should not be zero?
847+
848+ # Call with method signature
849+ all_call_graph = code_analyzer .get_class_call_graph_using_symbol_table ("com.ibm.websphere.samples.daytrader.impl.direct.TradeDirect" , "getStatement(Connection, String)" )
850+ assert all_call_graph is not None
851+ assert isinstance (all_call_graph , List )
852+ assert len (all_call_graph ) == 0
808853
809854 # Call without method signature
810- all_call_graph = code_analyzer .get_class_call_graph_using_symbol_table ("com.ibm.websphere.samples.daytrader.TradeAction " , None )
855+ all_call_graph = code_analyzer .get_class_call_graph_using_symbol_table ("com.ibm.websphere.samples.daytrader.impl.direct.TradeDirect " , None )
811856 assert all_call_graph is not None
812857 assert isinstance (all_call_graph , List )
858+ assert len (all_call_graph ) == 0
813859
814860
815861def test_get_class_call_graph (test_fixture , analysis_json_fixture ):
@@ -832,14 +878,22 @@ def test_get_class_call_graph(test_fixture, analysis_json_fixture):
832878 )
833879
834880 # Call with method signature
835- class_call_graph = code_analyzer .get_class_call_graph ("com.ibm.websphere.samples.daytrader.TradeAction" , "getQuote(String)" )
881+ class_call_graph = code_analyzer .get_class_call_graph (
882+ "com.ibm.websphere.samples.daytrader.impl.direct.TradeDirect" , "createHolding(Connection, int, String, double, BigDecimal)"
883+ )
836884 assert class_call_graph is not None
837885 assert isinstance (class_call_graph , List )
886+ assert len (class_call_graph ) == 4
887+ for method in class_call_graph :
888+ assert isinstance (method , Tuple )
889+ assert isinstance (method [0 ], JMethodDetail )
890+ assert isinstance (method [1 ], JMethodDetail )
838891
839892 # Call without method signature
840- class_call_graph = code_analyzer .get_class_call_graph ("com.ibm.websphere.samples.daytrader.TradeAction " , None )
893+ class_call_graph = code_analyzer .get_class_call_graph ("com.ibm.websphere.samples.daytrader.impl.direct.TradeDirect " , None )
841894 assert class_call_graph is not None
842895 assert isinstance (class_call_graph , List )
896+ assert len (class_call_graph ) > 0
843897
844898
845899def test_get_all_entry_point_methods (test_fixture , analysis_json_fixture ):
@@ -866,6 +920,11 @@ def test_get_all_entry_point_methods(test_fixture, analysis_json_fixture):
866920 assert entry_point_methods is not None
867921 assert isinstance (entry_point_methods , Dict )
868922 assert len (entry_point_methods ) > 0
923+ # Validate structure
924+ for _ , entry_point in entry_point_methods .items ():
925+ assert isinstance (entry_point , Dict )
926+ for _ , method in entry_point .items ():
927+ assert isinstance (method , JCallable )
869928
870929
871930def test_get_all_entry_point_classes (test_fixture , analysis_json_fixture ):
@@ -892,3 +951,6 @@ def test_get_all_entry_point_classes(test_fixture, analysis_json_fixture):
892951 assert entry_point_classes is not None
893952 assert isinstance (entry_point_classes , Dict )
894953 assert len (entry_point_classes ) > 0
954+ # Validate structure
955+ for _ , entry_point in entry_point_classes .items ():
956+ assert isinstance (entry_point , JType )
0 commit comments