Skip to content

Handle functional operand in assert check #462

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Sep 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
------------------
Expand Down
23 changes: 16 additions & 7 deletions src/checks/y_check_unit_test_assert.clas.abap
Original file line number Diff line number Diff line change
Expand Up @@ -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.

Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -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 ].
Expand Down
128 changes: 91 additions & 37 deletions src/checks/y_check_unit_test_assert.clas.testclasses.abap
Original file line number Diff line number Diff line change
Expand Up @@ -491,41 +491,53 @@ 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. ' )
( ' ENDCLASS. ' )

( ' 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. ' )
).
Expand All @@ -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 #(
Expand All @@ -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. ' )
).
Expand All @@ -562,56 +576,96 @@ 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 #(
( ' 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. ' )
( | 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. ' )
).
Expand Down