diff --git a/changelog.txt b/changelog.txt index 06dc0557..e820d693 100644 --- a/changelog.txt +++ b/changelog.txt @@ -20,6 +20,7 @@ Whenever you upgrade code pal for ABAP, it is highly recommended to execute the + Prefer Pragmas to Pseudo Comments (#421) + COLLECT restriction (#441) * RAP needs CREATE OBJECT ... FOR TESTING (#444) +* Filter functional operands in "Unit Test Assert" check (#460) 2021-08-12 v.1.15.0 ------------------ diff --git a/src/checks/y_check_unit_test_assert.clas.abap b/src/checks/y_check_unit_test_assert.clas.abap index 04323a62..c6552fa2 100644 --- a/src/checks/y_check_unit_test_assert.clas.abap +++ b/src/checks/y_check_unit_test_assert.clas.abap @@ -6,14 +6,17 @@ CLASS y_check_unit_test_assert DEFINITION PUBLIC INHERITING FROM y_check_base CR METHODS inspect_tokens REDEFINITION. PRIVATE SECTION. - METHODS get_parameter_reference IMPORTING statement TYPE sstmnt - parameter TYPE string + METHODS get_parameter_reference IMPORTING statement TYPE sstmnt + parameter TYPE string RETURNING VALUE(result) TYPE string - RAISING cx_sy_itab_line_not_found. + RAISING cx_sy_itab_line_not_found. - METHODS is_variable IMPORTING token TYPE stokesx + METHODS is_variable IMPORTING token TYPE stokesx RETURNING VALUE(result) TYPE abap_bool. + METHODS contains_functional_operand IMPORTING expression TYPE string + RETURNING VALUE(result) TYPE abap_bool. + METHODS is_internal_table IMPORTING position TYPE i RETURNING VALUE(result) TYPE abap_bool. @@ -64,7 +67,7 @@ CLASS y_check_unit_test_assert IMPLEMENTATION. RETURN. ENDIF. - IF act <> exp. + IF act <> exp OR contains_functional_operand( act ). RETURN. ENDIF. @@ -110,9 +113,9 @@ CLASS y_check_unit_test_assert IMPLEMENTATION. CONTINUE. ENDIF. - IF token-str CP '*(*'. + IF token-str CP '*( *'. depth = depth + 1. - ELSEIF token-str CP '*)*'. + ELSEIF token-str CP '* )*'. depth = depth - 1. ENDIF. @@ -144,6 +147,12 @@ CLASS y_check_unit_test_assert IMPLEMENTATION. ENDMETHOD. + METHOD contains_functional_operand. + FIND REGEX `[A-Z_][A-Z0-9_]*\(` IN expression. + result = xsdbool( sy-subrc = 0 ). + ENDMETHOD. + + METHOD is_internal_table. TRY. DATA(previous_token) = ref_scan_manager->tokens[ position - 1 ]. diff --git a/src/checks/y_check_unit_test_assert.clas.testclasses.abap b/src/checks/y_check_unit_test_assert.clas.testclasses.abap index 701c34d4..66b824cf 100644 --- a/src/checks/y_check_unit_test_assert.clas.testclasses.abap +++ b/src/checks/y_check_unit_test_assert.clas.testclasses.abap @@ -491,31 +491,45 @@ ENDCLASS. -CLASS ltc_call_static DEFINITION INHERITING FROM ltc_hardcoded_string FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. +CLASS ltc_assert_fail DEFINITION INHERITING FROM ltc_hardcoded_string FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. PROTECTED SECTION. - METHODS get_code_with_issue REDEFINITION. + METHODS get_code_without_issue REDEFINITION. ENDCLASS. -CLASS ltc_call_static IMPLEMENTATION. +CLASS ltc_assert_fail IMPLEMENTATION. - METHOD get_code_with_issue. + METHOD get_code_without_issue. result = VALUE #( ( ' REPORT y_example. ' ) - ( ' CLASS y_fake DEFINITION. ' ) + ( ' CLASS y_example DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. ' ) ( ' PUBLIC SECTION. ' ) - ( ' CLASS-METHODS get_fullname IMPORTING name TYPE string ' ) - ( ' surname TYPE string ' ) - ( ' RETURNING VALUE(result) TYPE string. ' ) + ( ' METHODS example FOR TESTING. ' ) ( ' ENDCLASS. ' ) - ( ' CLASS y_fake IMPLEMENTATION. ' ) - ( ' METHOD get_fullname. ' ) - ( ' result = |{ name } { surname }|. ' ) + ( ' CLASS y_example IMPLEMENTATION. ' ) + ( ' METHOD example. ' ) + ( | cl_aunit_assert=>fail( 'Not Allowed' ). | ) ( ' ENDMETHOD. ' ) ( ' ENDCLASS. ' ) + ). + ENDMETHOD. + +ENDCLASS. + +CLASS ltc_assert_empty DEFINITION INHERITING FROM ltc_hardcoded_string FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. + PROTECTED SECTION. + METHODS get_code_with_issue REDEFINITION. +ENDCLASS. + +CLASS ltc_assert_empty IMPLEMENTATION. + + METHOD get_code_with_issue. + result = VALUE #( + ( ' REPORT y_example. ' ) + ( ' CLASS y_example DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. ' ) ( ' PUBLIC SECTION. ' ) ( ' METHODS example FOR TESTING. ' ) @@ -523,9 +537,7 @@ CLASS ltc_call_static IMPLEMENTATION. ( ' CLASS y_example IMPLEMENTATION. ' ) ( ' METHOD example. ' ) - ( | cl_aunit_assert=>assert_equals( act = y_fake=>get_fullname( name = 'code pal' surname = 'for ABAP' ) | ) - ( | exp = y_fake=>get_fullname( name = 'code pal' | ) - ( | surname = 'for ABAP' ) ). | ) + ( | cl_aunit_assert=>assert_equals( act = '' exp = '' ). | ) ( ' ENDMETHOD. ' ) ( ' ENDCLASS. ' ) ). @@ -535,12 +547,12 @@ ENDCLASS. -CLASS ltc_assert_fail DEFINITION INHERITING FROM ltc_hardcoded_string FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. +CLASS ltc_internal_table DEFINITION INHERITING FROM ltc_hardcoded_string FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. PROTECTED SECTION. METHODS get_code_without_issue REDEFINITION. ENDCLASS. -CLASS ltc_assert_fail IMPLEMENTATION. +CLASS ltc_internal_table IMPLEMENTATION. METHOD get_code_without_issue. result = VALUE #( @@ -553,7 +565,9 @@ CLASS ltc_assert_fail IMPLEMENTATION. ( ' CLASS y_example IMPLEMENTATION. ' ) ( ' METHOD example. ' ) - ( | cl_aunit_assert=>fail( 'Not Allowed' ). | ) + ( ' DATA itab TYPE TABLE OF tadir. ' ) + ( ' cl_abap_unit_assert=>assert_equals( exp = itab[ 5 ]-devclass act = itab[ 6 ]-devclass ). ' ) + ( ' cl_abap_unit_assert=>assert_equals( exp = itab[ 7 ]-devclass act = itab[ 8 ]-devclass ). ' ) ( ' ENDMETHOD. ' ) ( ' ENDCLASS. ' ) ). @@ -562,13 +576,19 @@ CLASS ltc_assert_fail IMPLEMENTATION. ENDCLASS. - -CLASS ltc_assert_empty DEFINITION INHERITING FROM ltc_hardcoded_string FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. +CLASS ltc_functional_operand DEFINITION INHERITING FROM y_unit_test_base FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. PROTECTED SECTION. + METHODS get_cut REDEFINITION. METHODS get_code_with_issue REDEFINITION. + METHODS get_code_without_issue REDEFINITION. + methods get_code_with_exemption REDEFINITION. ENDCLASS. -CLASS ltc_assert_empty IMPLEMENTATION. +CLASS ltc_functional_operand IMPLEMENTATION. + + METHOD get_cut. + result ?= NEW y_check_unit_test_assert( ). + ENDMETHOD. METHOD get_code_with_issue. result = VALUE #( @@ -576,42 +596,76 @@ CLASS ltc_assert_empty IMPLEMENTATION. ( ' CLASS y_example DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. ' ) ( ' PUBLIC SECTION. ' ) - ( ' METHODS example FOR TESTING. ' ) + ( ' METHODS test FOR TESTING. ' ) + ( ' PRIVATE SECTION.' ) + ( ' METHODS get_val RETURNING VALUE(result) type string.' ) ( ' ENDCLASS. ' ) ( ' CLASS y_example IMPLEMENTATION. ' ) - ( ' METHOD example. ' ) - ( | cl_aunit_assert=>assert_equals( act = '' exp = '' ). | ) + ( ' METHOD test. ' ) + ( ' DATA(first) = `abc`.' ) + ( ' DATA(second) = `def`.' ) + ( ' cl_abap_unit_assert=>assert_equals( act = first && second+2(1)' ) + ( ' exp = first && second+2(1) ).' ) + ( ' ENDMETHOD. ' ) + ( ' METHOD get_val.' ) + ( ' result = `Foo`.' ) ( ' ENDMETHOD. ' ) ( ' ENDCLASS. ' ) ). ENDMETHOD. -ENDCLASS. - - + METHOD get_code_without_issue. + result = VALUE #( + ( ' REPORT y_example. ' ) -CLASS ltc_internal_table DEFINITION INHERITING FROM ltc_hardcoded_string FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. - PROTECTED SECTION. - METHODS get_code_without_issue REDEFINITION. -ENDCLASS. + ( ' CLASS y_example DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. ' ) + ( ' PUBLIC SECTION. ' ) + ( ' METHODS test FOR TESTING. ' ) + ( ' PRIVATE SECTION.' ) + ( ' METHODS get_val RETURNING VALUE(result) type string.' ) + ( ' ENDCLASS. ' ) -CLASS ltc_internal_table IMPLEMENTATION. + ( ' CLASS y_example IMPLEMENTATION. ' ) + ( ' METHOD test. ' ) + ( ' DATA(first) = `abc`.' ) + ( ' DATA(second) = `def`.' ) + ( ' cl_abap_unit_assert=>assert_equals( act = first && get_val( ) && second+2(1)' ) + ( ' exp = first && get_val( ) && second+2(1) ).' ) + ( ' cl_abap_unit_assert=>assert_equals( act = first && get_val( ) && second+2(1)' ) + ( ' exp = first && second+2(1) ).' ) + ( ' cl_abap_unit_assert=>assert_equals( act = first && second+2(1)' ) + ( ' exp = first && get_val( ) && second+2(1) ).' ) + ( ' cl_abap_unit_assert=>assert_equals( act = get_val( )' ) + ( ' exp = get_val( ) ).' ) + ( ' ENDMETHOD. ' ) + ( ' METHOD get_val.' ) + ( ' result = `Foo`.' ) + ( ' ENDMETHOD. ' ) + ( ' ENDCLASS. ' ) + ). + ENDMETHOD. - METHOD get_code_without_issue. + METHOD get_code_with_exemption. result = VALUE #( ( ' REPORT y_example. ' ) ( ' CLASS y_example DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. ' ) ( ' PUBLIC SECTION. ' ) - ( ' METHODS example FOR TESTING. ' ) + ( ' METHODS test FOR TESTING. ' ) + ( ' PRIVATE SECTION.' ) + ( ' METHODS get_val RETURNING VALUE(result) type string.' ) ( ' ENDCLASS. ' ) ( ' CLASS y_example IMPLEMENTATION. ' ) - ( ' METHOD example. ' ) - ( ' DATA itab TYPE TABLE OF tadir. ' ) - ( ' cl_abap_unit_assert=>assert_equals( exp = itab[ 5 ]-devclass act = itab[ 6 ]-devclass ). ' ) - ( ' cl_abap_unit_assert=>assert_equals( exp = itab[ 7 ]-devclass act = itab[ 8 ]-devclass ). ' ) + ( ' METHOD test. ' ) + ( ' DATA(first) = `abc`.' ) + ( ' DATA(second) = `def`.' ) + ( ' cl_abap_unit_assert=>assert_equals( act = first && second+2(1)' ) + ( ' exp = first && second+2(1) ). "#EC UT_ASSERT' ) + ( ' ENDMETHOD. ' ) + ( ' METHOD get_val.' ) + ( ' result = `Foo`.' ) ( ' ENDMETHOD. ' ) ( ' ENDCLASS. ' ) ).