From e149594dae534e135bc6336560a9ac30b7a80a42 Mon Sep 17 00:00:00 2001 From: Marc Bernard <59966492+mbtools@users.noreply.github.com> Date: Sun, 29 May 2022 09:47:39 +0200 Subject: [PATCH] Refactor: `is_active` logic (#5557) - Move `is_active` from `zcl_abapgit_objects_super` to `zcl_abapgit_objects_activation` - Consolidate `is_ddic_type` logic - Add unit tests for `zcl_abapgit_objects_activation` --- .../zcl_abapgit_objects_activation.clas.abap | 204 +++++++++++++++--- ...t_objects_activation.clas.testclasses.abap | 149 +++++++++++++ .../zcl_abapgit_objects_activation.clas.xml | 1 + .../zcl_abapgit_objects_super.clas.abap | 74 +------ 4 files changed, 323 insertions(+), 105 deletions(-) create mode 100644 src/objects/core/zcl_abapgit_objects_activation.clas.testclasses.abap diff --git a/src/objects/core/zcl_abapgit_objects_activation.clas.abap b/src/objects/core/zcl_abapgit_objects_activation.clas.abap index 1af1d936a..4630b623c 100644 --- a/src/objects/core/zcl_abapgit_objects_activation.clas.abap +++ b/src/objects/core/zcl_abapgit_objects_activation.clas.abap @@ -28,6 +28,13 @@ CLASS zcl_abapgit_objects_activation DEFINITION !iv_obj_type TYPE trobjtype RETURNING VALUE(rv_result) TYPE abap_bool . + CLASS-METHODS is_active + IMPORTING + !is_item TYPE zif_abapgit_definitions=>ty_item + RETURNING + VALUE(rv_active) TYPE abap_bool + RAISING + zcx_abapgit_exception. PROTECTED SECTION. PRIVATE SECTION. @@ -37,6 +44,20 @@ CLASS zcl_abapgit_objects_activation DEFINITION clsname TYPE seoclsname, END OF ty_classes. + CONSTANTS: + c_domain TYPE c LENGTH 9 VALUE 'DOMA DOMD', + c_types TYPE c LENGTH 50 VALUE 'DTEL DTED TABL TABD SQLT SQLD TTYP TTYD VIEW VIED', + c_technset TYPE c LENGTH 24 VALUE 'TABT VIET SQTT INDX XINX', + c_f4_objects TYPE c LENGTH 35 VALUE 'SHLP SHLD MCOB MCOD MACO MACD MCID', + c_enqueue TYPE c LENGTH 9 VALUE 'ENQU ENQD', + c_sqsc TYPE c LENGTH 4 VALUE 'SQSC', + c_stob TYPE c LENGTH 4 VALUE 'STOB', + c_ntab TYPE c LENGTH 14 VALUE 'NTTT NTTB NTDT', + c_ddls TYPE c LENGTH 14 VALUE 'DDLS DRUL DTDC', + c_switches TYPE c LENGTH 24 VALUE 'SF01 SF02 SFSW SFBS SFBF', + c_para TYPE c LENGTH 4 VALUE 'PARA', " can be referenced by DTEL + c_enhd TYPE c LENGTH 4 VALUE 'ENHD'. + CLASS-DATA: gt_classes TYPE STANDARD TABLE OF ty_classes WITH DEFAULT KEY . CLASS-DATA: @@ -79,7 +100,30 @@ CLASS zcl_abapgit_objects_activation DEFINITION VALUE(rv_try_again) TYPE abap_bool RAISING zcx_abapgit_exception . - + CLASS-METHODS is_non_ddic_active + IMPORTING + !is_item TYPE zif_abapgit_definitions=>ty_item + RETURNING + VALUE(rv_active) TYPE abap_bool + RAISING + zcx_abapgit_exception . + CLASS-METHODS is_ddic_active + IMPORTING + !is_item TYPE zif_abapgit_definitions=>ty_item + RETURNING + VALUE(rv_active) TYPE abap_bool + RAISING + zcx_abapgit_exception . + CLASS-METHODS get_ddic_type + IMPORTING + !iv_obj_type TYPE clike + !iv_obj_name TYPE clike + EXPORTING + !ev_type TYPE ddobjtyp + !ev_name TYPE ddobjname + !ev_id TYPE ddobjectid + RAISING + zcx_abapgit_exception. ENDCLASS. @@ -125,17 +169,16 @@ CLASS zcl_abapgit_objects_activation IMPLEMENTATION. CONTINUE. ENDIF. ls_gentab-tabix = sy-tabix. - ls_gentab-type = -object. - ls_gentab-name = -obj_name. - IF ls_gentab-type = 'INDX' OR ls_gentab-type = 'XINX' OR ls_gentab-type = 'MCID'. - CALL FUNCTION 'DD_E071_TO_DD' - EXPORTING - object = -object - obj_name = -obj_name - IMPORTING - name = ls_gentab-name - id = ls_gentab-indx. - ENDIF. + + get_ddic_type( + EXPORTING + iv_obj_type = -object + iv_obj_name = -obj_name + IMPORTING + ev_type = ls_gentab-type + ev_name = ls_gentab-name + ev_id = ls_gentab-indx ). + INSERT ls_gentab INTO TABLE lt_gentab. ENDLOOP. @@ -393,37 +436,134 @@ CLASS zcl_abapgit_objects_activation IMPLEMENTATION. ENDMETHOD. + METHOD get_ddic_type. + + DATA lv_obj_name TYPE e071-obj_name. + + ev_type = iv_obj_type. + + IF ev_type = 'INDX' OR ev_type = 'XINX' OR ev_type = 'MCID'. + lv_obj_name = iv_obj_name. "cast + + CALL FUNCTION 'DD_E071_TO_DD' + EXPORTING + object = ev_type + obj_name = lv_obj_name + IMPORTING + name = ev_name + id = ev_id + EXCEPTIONS + illegal_input = 1 + OTHERS = 2. + IF sy-subrc <> 0. + zcx_abapgit_exception=>raise_t100( ). + ENDIF. + ELSE. + ev_name = iv_obj_name. + ENDIF. + + ENDMETHOD. + + + METHOD is_active. + + " Checks if object is active or not + " + " Note: If object does not exist, this method returns true + " is_not_inactive might be a better name but we avoid the double negative + + IF is_ddic_type( is_item-obj_type ) = abap_true + AND c_para NS is_item-obj_type + AND c_switches NS is_item-obj_type. + rv_active = is_ddic_active( is_item ). + ELSE. + rv_active = is_non_ddic_active( is_item ). + ENDIF. + + ENDMETHOD. + + + METHOD is_ddic_active. + + DATA: + lv_type TYPE ddobjtyp, + lv_name TYPE ddobjname, + lv_id TYPE ddobjectid, + lv_state TYPE ddgotstate. + + get_ddic_type( + EXPORTING + iv_obj_type = is_item-obj_type + iv_obj_name = is_item-obj_name + IMPORTING + ev_type = lv_type + ev_name = lv_name + ev_id = lv_id ). + + " Check if an inactive version of the DDIC object exists + " state = 'A' checks if an active version exists but does not detect new or modified objects + " state = 'M' checks for all possible versions so we can find out if an inactive one exists + " See documentation of the function module + CALL FUNCTION 'DDIF_STATE_GET' + EXPORTING + type = lv_type + name = lv_name + id = lv_id + state = 'M' + IMPORTING + gotstate = lv_state + EXCEPTIONS + illegal_input = 1 + OTHERS = 2. + + rv_active = boolc( sy-subrc = 0 AND ( lv_state = '' OR lv_state = 'A' ) ). + + ENDMETHOD. + + METHOD is_ddic_type. " Determine if object can be handled by mass activation (see RADMASUTC form ma_tab_check) - CONSTANTS: - lc_domain TYPE c LENGTH 9 VALUE 'DOMA DOMD', - lc_types TYPE c LENGTH 50 VALUE 'DTEL DTED TABL TABD SQLT SQLD TTYP TTYD VIEW VIED', - lc_technset TYPE c LENGTH 24 VALUE 'TABT VIET SQTT INDX XINX', - lc_f4_objects TYPE c LENGTH 35 VALUE 'SHLP SHLD MCOB MCOD MACO MACD MCID', - lc_enqueue TYPE c LENGTH 9 VALUE 'ENQU ENQD', - lc_sqsc TYPE c LENGTH 4 VALUE 'SQSC', - lc_stob TYPE c LENGTH 4 VALUE 'STOB', - lc_ntab TYPE c LENGTH 14 VALUE 'NTTT NTTB NTDT', - lc_ddls TYPE c LENGTH 14 VALUE 'DDLS DRUL DTDC', - lc_switches TYPE c LENGTH 24 VALUE 'SF01 SF02 SFSW SFBS SFBF', - lc_para TYPE c LENGTH 4 VALUE 'PARA', " can be referenced by DTEL - lc_enhd TYPE c LENGTH 4 VALUE 'ENHD'. - rv_result = abap_true. - IF lc_domain NS iv_obj_type AND lc_types NS iv_obj_type AND - lc_technset NS iv_obj_type AND lc_f4_objects NS iv_obj_type AND - lc_enqueue NS iv_obj_type AND lc_sqsc NS iv_obj_type AND - lc_stob NS iv_obj_type AND lc_ntab NS iv_obj_type AND - lc_ddls NS iv_obj_type AND lc_para NS iv_obj_type AND - lc_switches NS iv_obj_type AND iv_obj_type <> lc_enhd. + + IF c_domain NS iv_obj_type AND c_types NS iv_obj_type AND + c_technset NS iv_obj_type AND c_f4_objects NS iv_obj_type AND + c_enqueue NS iv_obj_type AND c_sqsc NS iv_obj_type AND + c_stob NS iv_obj_type AND c_ntab NS iv_obj_type AND + c_ddls NS iv_obj_type AND c_para NS iv_obj_type AND + c_switches NS iv_obj_type AND iv_obj_type <> c_enhd. rv_result = abap_false. ENDIF. ENDMETHOD. + METHOD is_non_ddic_active. + + DATA: + lt_messages TYPE STANDARD TABLE OF sprot_u WITH DEFAULT KEY, + ls_e071 TYPE e071, + lt_e071 TYPE STANDARD TABLE OF e071 WITH DEFAULT KEY. + + ls_e071-object = is_item-obj_type. + ls_e071-obj_name = is_item-obj_name. + INSERT ls_e071 INTO TABLE lt_e071. + + CALL FUNCTION 'RS_INACTIVE_OBJECTS_WARNING' + EXPORTING + suppress_protocol = abap_false + with_program_includes = abap_false + suppress_dictionary_check = abap_false + TABLES + p_e071 = lt_e071 + p_xmsg = lt_messages. + + rv_active = boolc( lt_messages IS INITIAL ). + + ENDMETHOD. + + METHOD update_where_used. DATA: ls_class LIKE LINE OF gt_classes, diff --git a/src/objects/core/zcl_abapgit_objects_activation.clas.testclasses.abap b/src/objects/core/zcl_abapgit_objects_activation.clas.testclasses.abap new file mode 100644 index 000000000..ff6d29118 --- /dev/null +++ b/src/objects/core/zcl_abapgit_objects_activation.clas.testclasses.abap @@ -0,0 +1,149 @@ +CLASS ltcl_tests DEFINITION DEFERRED. +CLASS zcl_abapgit_objects_activation DEFINITION LOCAL FRIENDS ltcl_tests. + +CLASS ltcl_tests DEFINITION FOR TESTING RISK LEVEL HARMLESS + DURATION SHORT FINAL. + + PRIVATE SECTION. + DATA mo_cut TYPE REF TO zcl_abapgit_objects_activation. + + METHODS: + setup, + is_active FOR TESTING RAISING zcx_abapgit_exception, + is_ddic_type FOR TESTING, + get_ddic_type FOR TESTING RAISING zcx_abapgit_exception. + +ENDCLASS. + +CLASS ltcl_tests IMPLEMENTATION. + + METHOD setup. + CREATE OBJECT mo_cut. + ENDMETHOD. + + METHOD is_active. + + DATA ls_item TYPE zif_abapgit_definitions=>ty_item. + + " DDIC, exists + ls_item-obj_type = 'TABL'. + ls_item-obj_name = 'T000'. + + cl_abap_unit_assert=>assert_equals( + act = mo_cut->is_active( ls_item ) + exp = abap_true ). + + " DDIC, does not exist + ls_item-obj_type = 'TABL'. + ls_item-obj_name = 'TABL_ABAPGIT'. + + cl_abap_unit_assert=>assert_equals( + act = mo_cut->is_active( ls_item ) + exp = abap_true ). + + " non-DDIC, exists + ls_item-obj_type = 'PROG'. + ls_item-obj_name = 'SAPMSYST'. + + cl_abap_unit_assert=>assert_equals( + act = mo_cut->is_active( ls_item ) + exp = abap_true ). + + ls_item-obj_type = 'SFSW'. + ls_item-obj_name = 'SRIS_SWITCH_SOURCE_SEARCH'. + + cl_abap_unit_assert=>assert_equals( + act = mo_cut->is_active( ls_item ) + exp = abap_true ). + + " non-DDIC, does not exist + ls_item-obj_type = 'FUGR'. + ls_item-obj_name = 'FUGR_ABAPGIT'. + + cl_abap_unit_assert=>assert_equals( + act = mo_cut->is_active( ls_item ) + exp = abap_true ). + + ENDMETHOD. + + METHOD is_ddic_type. + + cl_abap_unit_assert=>assert_equals( + act = mo_cut->is_ddic_type( 'TABL' ) + exp = abap_true ). + + cl_abap_unit_assert=>assert_equals( + act = mo_cut->is_ddic_type( 'PROG' ) + exp = abap_false ). + + ENDMETHOD. + + METHOD get_ddic_type. + + DATA: + lv_type TYPE ddobjtyp, + lv_name TYPE ddobjname, + lv_id TYPE ddobjectid. + + mo_cut->get_ddic_type( + EXPORTING + iv_obj_type = 'TABL' + iv_obj_name = 'T005' + IMPORTING + ev_type = lv_type + ev_name = lv_name + ev_id = lv_id ). + + cl_abap_unit_assert=>assert_equals( + act = lv_type + exp = 'TABL' ). + cl_abap_unit_assert=>assert_equals( + act = lv_name + exp = 'T005' ). + cl_abap_unit_assert=>assert_equals( + act = lv_id + exp = '' ). + + " index id at +10 + mo_cut->get_ddic_type( + EXPORTING + iv_obj_type = 'XINX' + iv_obj_name = 'T005 Z00' + IMPORTING + ev_type = lv_type + ev_name = lv_name + ev_id = lv_id ). + + cl_abap_unit_assert=>assert_equals( + act = lv_type + exp = 'XINX' ). + cl_abap_unit_assert=>assert_equals( + act = lv_name + exp = 'T005' ). + cl_abap_unit_assert=>assert_equals( + act = lv_id + exp = 'Z00' ). + + " index id at +30 + mo_cut->get_ddic_type( + EXPORTING + iv_obj_type = 'XINX' + iv_obj_name = 'ZLONG_TABLE_NAME Z99' + IMPORTING + ev_type = lv_type + ev_name = lv_name + ev_id = lv_id ). + + cl_abap_unit_assert=>assert_equals( + act = lv_type + exp = 'XINX' ). + cl_abap_unit_assert=>assert_equals( + act = lv_name + exp = 'ZLONG_TABLE_NAME' ). + cl_abap_unit_assert=>assert_equals( + act = lv_id + exp = 'Z99' ). + + ENDMETHOD. + +ENDCLASS. diff --git a/src/objects/core/zcl_abapgit_objects_activation.clas.xml b/src/objects/core/zcl_abapgit_objects_activation.clas.xml index 053bb2f4a..11ae90896 100644 --- a/src/objects/core/zcl_abapgit_objects_activation.clas.xml +++ b/src/objects/core/zcl_abapgit_objects_activation.clas.xml @@ -10,6 +10,7 @@ X X X + X diff --git a/src/objects/zcl_abapgit_objects_super.clas.abap b/src/objects/zcl_abapgit_objects_super.clas.abap index 9545ff944..9688495e1 100644 --- a/src/objects/zcl_abapgit_objects_super.clas.abap +++ b/src/objects/zcl_abapgit_objects_super.clas.abap @@ -86,11 +86,6 @@ CLASS zcl_abapgit_objects_super DEFINITION RAISING zcx_abapgit_exception . PRIVATE SECTION. - METHODS is_active_ddic - RETURNING - VALUE(rv_active) TYPE abap_bool - RAISING - zcx_abapgit_exception . ENDCLASS. @@ -282,75 +277,8 @@ CLASS zcl_abapgit_objects_super IMPLEMENTATION. METHOD is_active. - " DDIC types (see LSINTF01, FORM det_dtabname) - CONSTANTS lc_ddic_type TYPE string - VALUE 'DDLS,DOMA,DTEL,ENQU,INDX,MCID,MCOB,SHLP,SQLT,SQSC,STOB,TABL,TTYP,VIEW,XINX'. + rv_active = zcl_abapgit_objects_activation=>is_active( ms_item ). - DATA: lt_messages TYPE STANDARD TABLE OF sprot_u WITH DEFAULT KEY, - lt_e071_tadirs TYPE STANDARD TABLE OF e071 WITH DEFAULT KEY, - ls_e071_tadir LIKE LINE OF lt_e071_tadirs. - - " For DDIC types, use more accurate method - IF lc_ddic_type CS ms_item-obj_type. - rv_active = is_active_ddic( ). - RETURN. - ENDIF. - - ms_item-inactive = abap_false. - - ls_e071_tadir-object = ms_item-obj_type. - ls_e071_tadir-obj_name = ms_item-obj_name. - INSERT ls_e071_tadir INTO TABLE lt_e071_tadirs. - - CALL FUNCTION 'RS_INACTIVE_OBJECTS_WARNING' - EXPORTING - suppress_protocol = abap_false - with_program_includes = abap_false - suppress_dictionary_check = abap_false - TABLES - p_e071 = lt_e071_tadirs - p_xmsg = lt_messages. - - IF lt_messages IS NOT INITIAL. - ms_item-inactive = abap_true. - ENDIF. - - rv_active = boolc( ms_item-inactive = abap_false ). - - ENDMETHOD. - - - METHOD is_active_ddic. - - DATA: - lv_type TYPE ddobjtyp, - lv_name TYPE ddobjname, - lv_state TYPE ddgotstate. - - ms_item-inactive = abap_false. - - lv_type = ms_item-obj_type. - lv_name = ms_item-obj_name. - - " Check if an inactive version of the DDIC object exists - " state = 'A' checks if an active version exists but does not detect new or modified objects - " state = 'M' checks for all possible versions so we can find out if an inactive one exists - " See documentation of the function module - CALL FUNCTION 'DDIF_STATE_GET' - EXPORTING - type = lv_type - name = lv_name - state = 'M' - IMPORTING - gotstate = lv_state - EXCEPTIONS - illegal_input = 1 - OTHERS = 2. - IF sy-subrc <> 0 OR lv_state <> 'A'. - ms_item-inactive = abap_true. - ENDIF. - - rv_active = boolc( ms_item-inactive = abap_false ). ENDMETHOD.