├── .abapgit.xml ├── LICENSE ├── README.md ├── docu ├── zcl_ci_test_comp_procs_docu.md ├── zcl_ci_test_dsag_pretty_print_docu.md ├── zcl_ci_test_header_comment_docu.md └── zcl_ci_test_translations_docu.md ├── snippets ├── Z_SCI_VARIANT_701.txt └── Z_SCI_VARIANT_740.txt └── src ├── package.devc.xml ├── zcl_ci_category_dsag_samples.clas.abap ├── zcl_ci_category_dsag_samples.clas.xml ├── zcl_ci_test_comp_procs.clas.abap ├── zcl_ci_test_comp_procs.clas.xml ├── zcl_ci_test_dsag_pretty_print.clas.abap ├── zcl_ci_test_dsag_pretty_print.clas.testclasses.abap ├── zcl_ci_test_dsag_pretty_print.clas.xml ├── zcl_ci_test_header_comment.clas.abap ├── zcl_ci_test_header_comment.clas.xml ├── zcl_ci_test_translations.clas.abap ├── zcl_ci_test_translations.clas.xml ├── zverif_pretty_printer=========vc.prog.abap ├── zverif_pretty_printer=========vc.prog.xml ├── zverif_pretty_printer_n=======vc.prog.abap └── zverif_pretty_printer_n=======vc.prog.xml /.abapgit.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | E 6 | /src/ 7 | PREFIX 8 | 9 | /.gitignore 10 | /LICENSE 11 | /README.md 12 | /package.json 13 | /.travis.yml 14 | /.gitlab-ci.yml 15 | /abaplint.json 16 | /azure-pipelines.yml 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 DSAG 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ABAP Test Cockpit Best Practice Guide 2 | 3 | Dieses Repository beinhaltet Beispielcode als Begleitmaterial zum ABAP Test Cockpit (ATC) Leitfaden der [DSAG](https://dsag.de/). 4 | 5 | ## Folder "src" 6 | Der Folder beinhaltet Codebeispiele für Prüfklassen. Die Kategorie aller Prüfklassen ist `ZCL_CI_CATEGORY_DSAG`. 7 | 8 | ### ZCL_CI_TEST_DSAG_PRETTY_PRINT 9 | Klasse zur Überprüfung ob auf den Source Code Pretty Print angewendet wurde. 10 | 11 | ### ZCL_CI_TEST_COMP_PROCS 12 | Klasse zur Ausführung verschiedener Code-basierter Prüfungen (Details siehe docu). 13 | 14 | ### ZCL_CI_TEST_HEADER_COMMENT 15 | Klasse zur Überprüfung, ob Kopfkommentare in Programmen, Funktionsgruppen, globalen Klassen und globalen Interfaces existieren. 16 | 17 | ### ZCL_CI_TEST_TRANSLATIONS 18 | Klasse zur Überprüfung ob für die wichtigsten Objektarten alle Texte sowohl in Deutsch als auch in Englisch vorliegen. 19 | 20 | ## Folder "snippets" 21 | Der Folder "snippets" beinhaltet Code Snippets, die Sie bei Ihrer Arbeit mit dem ATC unterstützen. 22 | 23 | ### Z_SCI_VARIANT_* 24 | Sourcen zur Erstellen eines Reports für die übersichtliche Anzeige von Prüfvarianten. 25 | 26 | ## Folder "docu" 27 | Der Folder "docu" beinhaltet zusätzliche Dokumentation zu den Prüfklassen, die nicht über den Mechanismus von abapGit übertragen werden kann. Sie können die Dokumentation manuell in das System übertragen. Die Namenskonvention für die Dokumentation ist: 28 | _docu.MD -------------------------------------------------------------------------------- /docu/zcl_ci_test_comp_procs_docu.md: -------------------------------------------------------------------------------- 1 | # Dokumentation der Prüfklasse ZCL_CI_TEST_COMP_PROCS 2 | 3 | ## English Version 4 | 5 | ### MEANING 6 | Various Code-based checks 7 | 8 | ### HINTS 9 | * `CALL TRANSACTION` 10 | ** always with explicit `WITH` or `WITHOUT AUTHORITY-CHECK` 11 | ** `WITHOUT CHECK` only in combination with `USING bdc` (or via exemption) 12 | ** `WITH AUTH` requires `CATCH` in following lines of procedure 13 | * Obsolete or unwanted language elements: 14 | ** `DEFINE *` 15 | ** `BEGIN OF COMMON PART *` 16 | * `FORMs` not allowed in new includes (new: as specified in constant `con_forms_allowed_until`) 17 | 18 | ## Deutsche Version 19 | ### MEANING 20 | Verschiedene Code-basierte Prüfungen. 21 | 22 | ### HINTS 23 | * `CALL TRANSACTION` 24 | ** immer mit explizitem `WITH` oder `WITHOUT AUTHORITY-CHECK` 25 | ** `WITHOUT CHECK` nur bei Verwendung mit `USING bdc` (oder Befreiung) 26 | ** `WITH AUTH` benötigt `CATCH` in den Folgezeilen 27 | * Obsolete oder unerwünschte Sprachelemente: 28 | ** `DEFINE *` 29 | ** `BEGIN OF COMMON PART *` 30 | * `FORMs` in neuen Includes nicht erlaubt (neu: gemäß der Konstanten `con_forms_allowed_until`) 31 | -------------------------------------------------------------------------------- /docu/zcl_ci_test_dsag_pretty_print_docu.md: -------------------------------------------------------------------------------- 1 | # Dokumentation der Prüfklasse ZCL_CI_TEST_DSAG_PRETTY_PRINT 2 | 3 | ## English Version 4 | 5 | ### MEANING 6 | This class checks if the pretty print was applied to the source code. 7 | 8 | ## Deutsche Version 9 | 10 | ### MEANING 11 | Die Klasse prüft, ob der Pretty Printer auf dne Source Code angewendet wurde. 12 | 13 | -------------------------------------------------------------------------------- /docu/zcl_ci_test_header_comment_docu.md: -------------------------------------------------------------------------------- 1 | # Dokumentation der Prüfklasse ZCL_CI_TEST_HEADER_COMMENT 2 | 3 | ## English Version 4 | 5 | ### MEANING 6 | Check existence of a header comment in every 7 | * program 8 | * function group 9 | * global class 10 | * global interface 11 | ### HINTS 12 | Because the content can not be checked by the system, it is only checked that there are five consecutive comment lines, beginning with an asterisk. These lines have to be at the following positions: 13 | * For normal programs, first line of frame program (before the statement `REPORT`) 14 | * For global classes, in the constructor method of the class, after the line `METHOD constructor`. 15 | In many cases, you will have to define a constructor just for this purpose. If you are in a subclass, you have to call `super->constructor( )`. at the end of the method. 16 | * For global exception classes, the `CLASS_CONSTRUCTOR` has to be used 17 | * For global interfaces, in the line directly after the `INTERFACE` statement 18 | * For function pools, in TOP-include, starting in the first line (i.e. in front of the `FUNCTION-POOL` statement) 19 | 20 | ## Deutsche Version 21 | ### MEANING 22 | Es wird geprüft, ob 23 | * jedes Programm 24 | * jede Funktionsgruppe 25 | * jede globale Klasse 26 | * jedes globale Interface 27 | 28 | einen Kopfkommentar hat. 29 | 30 | ### HINTS 31 | Da keine automatische inhaltliche Prüfung erfolgen kann, wird lediglich geprüft, dass es fünf aufeinander folgende Kommentarzeilen gibt, die mit einem Sternchen beginnen. Diese fünf Zeilen müssen an folgenden Positionen stehen: 32 | * Bei normalen Programmen, ab der ersten Zeile des Rahmenprogramms (vor der Anweisung `REPORT`). 33 | * Bei globalen Klassen, im Konstruktor hinter der Zeile `METHOD constructor`. 34 | In vielen Fällen muss der Konstruktor nur zu diesem Zweck deklariert werden. 35 | * Falls es sich um eine abgeleitete Klasse handelt, muss am Ende der Methode `super->constructor( ).` aufgerufen werden. 36 | * Bei globalen Ausnahmeklassen muss entsprechend der `CLASS_CONSTRUCTOR` verwendet werden 37 | * Bei globalen Schnittstellen, in der Zeile hinter der `INTERFACE` Anweisung 38 | * Bei Funktionsgruppen, im TOP-Include, beginnend mit der ersten Zeile (also direkt vor der `FUNCTION-POOL` Anweisung) -------------------------------------------------------------------------------- /docu/zcl_ci_test_translations_docu.md: -------------------------------------------------------------------------------- 1 | # Dokumentation der Prüfklasse ZCL_CI_TEST_TRANSLATIONS 2 | 3 | ## English Version 4 | 5 | ### MEANING 6 | Checks whether texts (most important text types only) exist in German as well as English. 7 | ### HINTS 8 | The following text types are supported: 9 | * Program texts (selection texts and text symbols) 10 | * Program title 11 | * Transaction title 12 | * Texts from GUI-Title and GUI-Status (CUA texts) 13 | * Screen texts (title and field descriptions) 14 | * Messages including long texts 15 | * Data element texts 16 | * Texts for domain fixed values 17 | * Texts for GET/SET parameters 18 | * OTR texts 19 | * Development Packages (descriptions) 20 | 21 | ### NOTES 22 | The following applies for the check 10 'GUI text ... missing in language...'. 23 | Meaning of the first character in the name: 24 | * M Menu 25 | * F Function 26 | * T Title 27 | * A Menu Bar 28 | * P Function Key Setting 29 | * B Pushbutton settings 30 | * C Status 31 | and the second character in the name: 32 | * M Object text 33 | * I Icontext 34 | * Q Quick info 35 | * T Technical Information 36 | 37 | ## Deutsche Version 38 | ### MEANING 39 | Prüft für die wichtigsten Objektarten, ob alle Texte sowohl in Deutsch als auch in Englisch vorliegen. 40 | 41 | ### HINTS 42 | Folgende Objektarten werden getestet: 43 | * Programmtexte (Selektionstexte und Textsymbole) 44 | * Programmtitel 45 | * Transaktionstitel 46 | * Texte aus GUI-Titel und GUI-Status 47 | * Dynpro-Texte (Titel und Feldnamen) 48 | * Nachrichten inklusive Langtexten 49 | * Datenelement-Texte 50 | * Texte zu Domänen-Festwerten 51 | * Texte zu GET/SET-Parameter 52 | * OTR-Texte 53 | * Pakete (Kurzbeschreibung) 54 | 55 | ### NOTES 56 | Folgende zusätzliche Informationen für die Prüfung 10 'GUI text ... fehlt in Sprache...'. 57 | Bedeutung der ersten Position im Namen: 58 | * M Menü 59 | * F Funktion 60 | * T Titel 61 | * A Menüleiste 62 | * P Funktionstastenbelegung 63 | * B Drucktastenbelegung 64 | * C Status 65 | und der zweiten Position im Namen: 66 | * M Objekttext 67 | * I Icontext 68 | * Q Quickinfo 69 | * T Technische Info -------------------------------------------------------------------------------- /snippets/Z_SCI_VARIANT_701.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1DSAG/ATC-Best-Practice-Guide/29e81461a43f6ddd01b5fcf5bc6dea7912801016/snippets/Z_SCI_VARIANT_701.txt -------------------------------------------------------------------------------- /snippets/Z_SCI_VARIANT_740.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/1DSAG/ATC-Best-Practice-Guide/29e81461a43f6ddd01b5fcf5bc6dea7912801016/snippets/Z_SCI_VARIANT_740.txt -------------------------------------------------------------------------------- /src/package.devc.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Beispiele für DSAG ATC Leitfaden 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/zcl_ci_category_dsag_samples.clas.abap: -------------------------------------------------------------------------------- 1 | class ZCL_CI_CATEGORY_DSAG_SAMPLES definition 2 | public 3 | inheriting from CL_CI_CATEGORY_ROOT 4 | final 5 | create public . 6 | 7 | public section. 8 | 9 | methods CONSTRUCTOR . 10 | protected section. 11 | private section. 12 | ENDCLASS. 13 | 14 | 15 | 16 | CLASS ZCL_CI_CATEGORY_DSAG_SAMPLES IMPLEMENTATION. 17 | 18 | 19 | METHOD CONSTRUCTOR. 20 | ************************************************************************ 21 | * ATC/Code Inspector Check Category 22 | * Corresponds to a "folder" in the view 23 | * for setting up check variants. 24 | ************************************************************************ 25 | 26 | super->constructor( ). 27 | description = 'DSAG Beispiele'(001). 28 | category = 'CL_CI_CATEGORY_TOP' ##NO_TEXT. 29 | position = '010'. 30 | 31 | ENDMETHOD. 32 | ENDCLASS. 33 | -------------------------------------------------------------------------------- /src/zcl_ci_category_dsag_samples.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_CI_CATEGORY_DSAG_SAMPLES 7 | D 8 | Code Inspector: Kategorie DSAG Beispiele 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | I 17 | 001 18 | DSAG Samples 19 | 14 20 | 21 | 22 | 23 | 24 | ZCL_CI_CATEGORY_DSAG_SAMPLES 25 | CONSTRUCTOR 26 | D 27 | CONSTRUCTOR 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/zcl_ci_test_comp_procs.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_ci_test_comp_procs DEFINITION 2 | PUBLIC 3 | INHERITING FROM cl_ci_test_abap_comp_procs 4 | FINAL 5 | CREATE PUBLIC . 6 | 7 | PUBLIC SECTION. 8 | METHODS constructor . 9 | METHODS run 10 | REDEFINITION . 11 | PROTECTED SECTION. 12 | METHODS analyze_proc REDEFINITION. 13 | 14 | PRIVATE SECTION. 15 | METHODS: 16 | check_call_transaction IMPORTING i_stmt TYPE cl_abap_comp_procs=>t_stmt, 17 | check_unwanted_statement IMPORTING i_stmt TYPE cl_abap_comp_procs=>t_stmt, 18 | check_auth_exception IMPORTING i_stmt TYPE cl_abap_comp_procs=>t_stmt, 19 | check_new_subroutines IMPORTING i_stmt TYPE cl_abap_comp_procs=>t_stmt, 20 | is_catch IMPORTING i_stmt TYPE cl_abap_comp_procs=>t_stmt 21 | RETURNING VALUE(r) TYPE abap_bool, 22 | report_missing_catch. 23 | CONSTANTS: con_forms_allowed_until TYPE endda VALUE '20190101'. 24 | DATA: m_call_ta_with_auth_check_stmt TYPE cl_abap_comp_procs=>t_stmt 25 | . 26 | ENDCLASS. 27 | 28 | 29 | 30 | CLASS zcl_ci_test_comp_procs IMPLEMENTATION. 31 | 32 | 33 | METHOD analyze_proc. 34 | TRY. 35 | LOOP AT p_proc-stmts REFERENCE INTO DATA(stmt). 36 | IF m_call_ta_with_auth_check_stmt IS NOT INITIAL. 37 | IF is_catch( stmt->* ). 38 | CLEAR m_call_ta_with_auth_check_stmt. 39 | ENDIF. 40 | ENDIF. 41 | CASE stmt->keyword. 42 | WHEN 'CALL'. 43 | check_call_transaction( stmt->* ). 44 | WHEN 'DEFINE' OR 'DATA'. 45 | check_unwanted_statement( stmt->* ). 46 | WHEN 'FORM'. 47 | check_new_subroutines( stmt->* ). 48 | WHEN 'ENDFORM' OR 'ENDFUNCTION' OR 'ENDMETHOD'. 49 | IF m_call_ta_with_auth_check_stmt IS NOT INITIAL. 50 | report_missing_catch( ). 51 | CLEAR m_call_ta_with_auth_check_stmt. 52 | ENDIF. 53 | ENDCASE. 54 | ENDLOOP. 55 | CATCH cx_sy_itab_line_not_found. 56 | LOG-POINT ID zlog_p FIELDS stmt->include stmt->line. " unexpected statement pattern 57 | ENDTRY. 58 | ENDMETHOD. 59 | 60 | 61 | METHOD check_auth_exception. 62 | IF i_stmt-keyword <> 'CATCH' OR i_stmt-tokens[ 2 ]-str <> |CX_SY_AUTHORIZATION_ERROR|. 63 | add_info( p_include = m_call_ta_with_auth_check_stmt-include 64 | p_line = m_call_ta_with_auth_check_stmt-line 65 | p_column = m_call_ta_with_auth_check_stmt-column 66 | p_kind = '0004' ). 67 | ENDIF. 68 | ENDMETHOD. 69 | 70 | METHOD is_catch. 71 | r = xsdbool( i_stmt-keyword = 'CATCH' AND i_stmt-tokens[ 2 ]-str CP |CX_*| ). 72 | ENDMETHOD. 73 | 74 | METHOD report_missing_catch. 75 | add_info( p_include = m_call_ta_with_auth_check_stmt-include 76 | p_line = m_call_ta_with_auth_check_stmt-line 77 | p_column = m_call_ta_with_auth_check_stmt-column 78 | p_kind = '0004' 79 | p_comments = m_call_ta_with_auth_check_stmt-comments ). 80 | ENDMETHOD. 81 | 82 | METHOD check_call_transaction. 83 | IF i_stmt-tokens[ 2 ]-str = |TRANSACTION|. 84 | IF lines( i_stmt-tokens ) < 5 OR i_stmt-tokens[ 4 ]-str NP |WITH*| OR i_stmt-tokens[ 5 ]-str <> |AUTHORITY-CHECK|. 85 | add_info( p_include = i_stmt-include 86 | p_line = i_stmt-line 87 | p_column = i_stmt-column 88 | p_kind = '0001' ). 89 | RETURN. 90 | ENDIF. 91 | IF i_stmt-tokens[ 4 ]-str = |WITH|. 92 | m_call_ta_with_auth_check_stmt = i_stmt. " check whether there is a catch CX_SY_AUTHORIZATION_ERROR statement in the following lines 93 | ELSE. 94 | ASSERT ID zlog_p FIELDS i_stmt-include i_stmt-line CONDITION i_stmt-tokens[ 4 ]-str = |WITHOUT|. " unexpected statement pattern (neither WITH nor WITHOUT) 95 | IF lines( i_stmt-tokens ) < 6 OR i_stmt-tokens[ 6 ]-str <> |USING|. " WITHOUT AUTH-CHECK USING bdc is allowed 96 | add_info( p_include = i_stmt-include 97 | p_line = i_stmt-line 98 | p_column = i_stmt-column 99 | p_kind = '0002' ). 100 | RETURN. 101 | ENDIF. 102 | ENDIF. 103 | ENDIF. 104 | ENDMETHOD. 105 | 106 | 107 | METHOD check_new_subroutines. 108 | SELECT SINGLE @abap_true FROM reposrc 109 | WHERE progname = @i_stmt-include 110 | AND cdat > @con_forms_allowed_until 111 | INTO @data(dummy). 112 | CHECK sy-subrc = 0. 113 | add_info( p_include = i_stmt-include 114 | p_line = i_stmt-line 115 | p_column = i_stmt-column 116 | p_kind = '0005' ). 117 | ENDMETHOD. 118 | 119 | 120 | METHOD check_unwanted_statement. 121 | IF i_stmt-keyword = 'DEFINE'. 122 | DATA(param1) = 'DEFINE macro'. 123 | ENDIF. 124 | IF i_stmt-keyword = 'DATA' AND lines( i_stmt-tokens ) >= 5 125 | AND i_stmt-tokens[ 2 ]-str = |BEGIN| 126 | AND i_stmt-tokens[ 3 ]-str = |OF| 127 | AND i_stmt-tokens[ 4 ]-str = |COMMON| 128 | AND i_stmt-tokens[ 5 ]-str = |PART|. 129 | param1 = 'COMMON PART'. 130 | ENDIF. 131 | IF param1 IS NOT INITIAL. 132 | add_info( p_include = i_stmt-include 133 | p_line = i_stmt-line 134 | p_column = i_stmt-column 135 | p_kind = '0003' 136 | p_name = param1 ). 137 | ENDIF. 138 | ENDMETHOD. 139 | 140 | 141 | METHOD constructor. 142 | ************************************************************************ 143 | * ATC/Code Inspector Test for various topics, based on code 144 | * (where inheritance from cl_ci_test_abap_comp_procs is useful). 145 | * Author: Edo von Glan, www.draeger.com 146 | * 147 | * - CALL TRANSACTION: 148 | * - always with WITH/WITHOUT AUTH-CHECK 149 | * (is possible with standard ATC check, but has no helpful text info) 150 | * - WITHOUT CHECK only with USING bdc or via exemption 151 | * - WITH AUTH needs CATCH in following lines 152 | * - Obsolete and unwanted Language features 153 | * DEFINE * 154 | * BEGIN OF COMMON PART * 155 | * (is possible in standard, but has no helpful text info) 156 | * - FORMs not allowed in new includes (after con_forms_allowed_until), 157 | * no pragma possible 158 | * 159 | ************************************************************************ 160 | * MIT License 161 | * 162 | * Copyright (c) 2019 DSAG 163 | * 164 | * Permission is hereby granted, free of charge, to any person obtaining a copy 165 | * of this software and associated documentation files (the "Software"), to deal 166 | * in the Software without restriction, including without limitation the rights 167 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 168 | * copies of the Software, and to permit persons to whom the Software is 169 | * furnished to do so, subject to the following conditions: 170 | * 171 | * The above copyright notice and this permission notice shall be included in all 172 | * copies or substantial portions of the Software. 173 | * 174 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 175 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 176 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 177 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 178 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 179 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 180 | * SOFTWARE. 181 | ************************************************************************ 182 | super->constructor( ). 183 | 184 | description = 'Verschiedene Prüfungen (Code)'(000). 185 | myname = 'ZCL_CI_TEST_COMP_PROCS'. 186 | category = 'ZCL_CI_CATEGORY_DSAG' ##NO_TEXT. 187 | position = 2. 188 | has_attributes = abap_false. 189 | attributes_ok = abap_false. 190 | has_documentation = abap_true. 191 | remote_enabled = abap_false. 192 | remote_rfc_enabled = abap_false. 193 | 194 | INSERT VALUE scimessage( test = myname 195 | code = '0001' 196 | kind = c_error 197 | text = 'CALL TRANSACTION ohne AUTHORITY-CHECK Angabe'(001) ) INTO TABLE scimessages . 198 | INSERT VALUE scimessage( test = myname 199 | code = '0002' 200 | kind = c_error 201 | text = 'CALL TA WITHOUT AUTH-CHECK - benötigt Genehmigung'(002) ) INTO TABLE scimessages . 202 | INSERT VALUE scimessage( test = myname 203 | code = '0003' 204 | kind = c_error 205 | text = 'Obsoleter und nicht erwünschter Befehl &1'(003) ) INTO TABLE scimessages . 206 | INSERT VALUE scimessage( test = myname 207 | code = '0004' 208 | kind = c_error 209 | text = 'Fehlendes CATCH CX_SY_AUTHORIZATION_ERROR (Dump wenn unberechtigt)'(004) 210 | " does not work pcom = 'CI_NOCATCH' 211 | ) INTO TABLE scimessages . 212 | INSERT VALUE scimessage( test = myname 213 | code = '0005' 214 | kind = c_error 215 | text = 'Subroutinen (FORMs) sind obsolet'(005) ) INTO TABLE scimessages . 216 | ENDMETHOD. 217 | 218 | 219 | METHOD run. 220 | CHECK get( ). 221 | analyze_start( ref_check ). 222 | LOOP AT infos REFERENCE INTO DATA(info). " TODO SAP Docu: include this part 223 | inform( p_sub_obj_type = c_type_include 224 | p_sub_obj_name = info->include 225 | p_line = info->line 226 | p_column = info->column 227 | p_test = myname 228 | p_code = info->kind 229 | p_param_1 = info->name ). 230 | ENDLOOP. 231 | ENDMETHOD. 232 | ENDCLASS. 233 | -------------------------------------------------------------------------------- /src/zcl_ci_test_comp_procs.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_CI_TEST_COMP_PROCS 7 | D 8 | Code Inspector: Kleinere Prüfungen auf Basis COMP_PROCS 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | I 17 | 000 18 | Verschiedene Prüfungen (Code) 19 | 82 20 | 21 | 22 | I 23 | 001 24 | CALL TRANSACTION ohne AUTHORITY-CHECK Angabe 25 | 88 26 | 27 | 28 | I 29 | 002 30 | CALL TA WITHOUT AUTH-CHECK - benötigt Befreiung 31 | 98 32 | 33 | 34 | I 35 | 003 36 | Obsoleter und nicht erwünschter Befehl &1 37 | 50 38 | 39 | 40 | I 41 | 004 42 | Fehlendes CATCH CX_SY_AUTHORIZATION_ERROR (Dump wenn Benutzer unberechtigt) 43 | 108 44 | 45 | 46 | I 47 | 005 48 | Subroutinen (FORMs) sind obsolet 49 | 64 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /src/zcl_ci_test_dsag_pretty_print.clas.abap: -------------------------------------------------------------------------------- 1 | class ZCL_CI_TEST_DSAG_PRETTY_PRINT definition 2 | public 3 | inheriting from CL_CI_TEST_SCAN 4 | final 5 | create public . 6 | 7 | public section. 8 | 9 | methods CONSTRUCTOR . 10 | 11 | methods GET_ATTRIBUTES 12 | redefinition . 13 | methods IF_CI_TEST~QUERY_ATTRIBUTES 14 | redefinition . 15 | methods PUT_ATTRIBUTES 16 | redefinition . 17 | methods RUN 18 | redefinition . 19 | protected section. 20 | 21 | types: 22 | BEGIN OF ty_pp_settings, 23 | lower TYPE flag, 24 | upper TYPE flag, 25 | key_upper TYPE flag, 26 | key_lower TYPE flag, 27 | END OF ty_pp_settings . 28 | 29 | data MS_PP_SETTINGS type TY_PP_SETTINGS . 30 | data MV_ONE_FINDING type FLAG . 31 | 32 | methods FILL_MESSAGE . 33 | methods SET_DEFAULTS . 34 | methods GET_MODE 35 | returning 36 | value(RV_MODE) type CHAR5 . 37 | private section. 38 | 39 | constants C_PP_ERROR type SCI_ERRC value '001'. "#EC NOTEXT 40 | ENDCLASS. 41 | 42 | 43 | 44 | CLASS ZCL_CI_TEST_DSAG_PRETTY_PRINT IMPLEMENTATION. 45 | 46 | 47 | METHOD constructor. 48 | 49 | super->constructor( ). 50 | 51 | description = 'Überprüfung ob Pretty Printer benutzt wurde'(001). 52 | category = 'ZCL_CI_CATEGORY_DSAG' ##NO_TEXT. 53 | 54 | has_documentation = abap_true. "Es existiert eine Dokumentation dazu 55 | has_attributes = abap_true. "Gibt an, dass Attribute vorhanden sind 56 | attributes_ok = abap_true. "Angegebene Attribute sind ok 57 | 58 | fill_message( ). "mögliche Meldungen füllen, die bei einem Fund 59 | * "ausgegeben werden können 60 | 61 | set_defaults( ). "Default-Werte für Attribut-Popup setzen 62 | 63 | ENDMETHOD. 64 | 65 | 66 | METHOD fill_message. 67 | 68 | DATA: ls_scimessage TYPE scimessage. 69 | 70 | 71 | * Inkorrekter Pretty-Print-Zustand 72 | ls_scimessage-test = myname. 73 | ls_scimessage-code = c_pp_error. "pro Fehler eigenen Code definieren 74 | ls_scimessage-kind = c_warning. 75 | ls_scimessage-text = 'Inkorrekter Pretty-Print-Zustand'(002). 76 | ls_scimessage-pcom = space. 77 | ls_scimessage-pcom_alt = space. 78 | INSERT ls_scimessage INTO TABLE scimessages. 79 | 80 | * hier ggf. weitere Meldungen nach o.a. Muster hinzufügen... 81 | 82 | ENDMETHOD. 83 | 84 | 85 | METHOD get_attributes. 86 | 87 | EXPORT ms_pp_settings = ms_pp_settings 88 | mv_one_finding = mv_one_finding 89 | TO DATA BUFFER p_attributes. 90 | 91 | ENDMETHOD. 92 | 93 | 94 | METHOD get_mode. 95 | 96 | IF ms_pp_settings-lower EQ abap_true. 97 | rv_mode = 'LOWER'. 98 | ELSEIF ms_pp_settings-upper EQ abap_true. 99 | rv_mode = 'UPPER'. 100 | ELSEIF ms_pp_settings-key_upper EQ abap_true. 101 | rv_mode = 'HIKEY'. 102 | ELSE. "KEY_LOWER 103 | rv_mode = 'LOKEY'. 104 | ENDIF. 105 | 106 | ENDMETHOD. 107 | 108 | 109 | METHOD if_ci_test~query_attributes. 110 | 111 | DATA: lt_attributes TYPE sci_atttab, 112 | ls_attribute LIKE LINE OF lt_attributes. 113 | 114 | 115 | DEFINE fill_att. 116 | CLEAR: ls_attribute. 117 | GET REFERENCE OF &1 INTO ls_attribute-ref. 118 | ls_attribute-text = &2. 119 | ls_attribute-kind = &3. 120 | APPEND ls_attribute TO lt_attributes. 121 | END-OF-DEFINITION. 122 | 123 | 124 | DEFINE fill_att_rb. 125 | CLEAR: ls_attribute. 126 | GET REFERENCE OF &1 INTO ls_attribute-ref. 127 | ls_attribute-text = &2. 128 | ls_attribute-kind = &3. 129 | ls_attribute-button_group = &4. 130 | APPEND ls_attribute TO lt_attributes. 131 | END-OF-DEFINITION. 132 | 133 | *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 134 | * Kind: 135 | * G = Gruppe / Selection-Screen Block 136 | * R = Radio-Button 137 | * C = Checkbox 138 | * L = Listbox 139 | * S = Select-Option 140 | * space = Parameter 141 | *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 142 | 143 | fill_att mv_one_finding 'Nur 1 Befund pro Incl. melden'(007) 'C'. 144 | 145 | fill_att sy-index 'Groß/Kleinkonvertierung'(008) 'G'. 146 | fill_att_rb ms_pp_settings-lower 'Kleinschreibung'(003) 'R' 'PP1'. 147 | fill_att_rb ms_pp_settings-upper 'Großschreibung'(004) 'R' 'PP1'. 148 | fill_att_rb ms_pp_settings-key_upper 'Schlüsselwort groß'(005) 'R' 'PP1'. 149 | fill_att_rb ms_pp_settings-key_lower 'Schlüsselwort klein'(006) 'R' 'PP1'. 150 | 151 | cl_ci_query_attributes=>generic( p_name = myname 152 | p_title = 'Einstellungen der Prüfung'(009) 153 | p_attributes = lt_attributes 154 | p_display = p_display ). 155 | 156 | ENDMETHOD. 157 | 158 | 159 | METHOD put_attributes. 160 | 161 | IMPORT ms_pp_settings = ms_pp_settings 162 | mv_one_finding = mv_one_finding 163 | FROM DATA BUFFER p_attributes. 164 | 165 | ASSERT sy-subrc = 0. 166 | 167 | ENDMETHOD. 168 | 169 | 170 | METHOD run. 171 | 172 | DATA: lt_includes TYPE STANDARD TABLE OF program, 173 | lt_source_in TYPE swbse_max_line_tab, 174 | lt_pretty TYPE rswsourcet, 175 | lv_tabix TYPE sy-tabix. 176 | 177 | FIELD-SYMBOLS: TYPE slevel, 178 | TYPE program, 179 | TYPE swbse_max_line, 180 | TYPE string. 181 | 182 | 183 | IF get( ) <> 'X'. 184 | RETURN. 185 | ENDIF. 186 | 187 | LOOP AT ref_scan->levels ASSIGNING WHERE type = 'P'. "#EC CI_STDSEQ 188 | CHECK -name+30(2) <> 'CP'. 189 | CHECK -name+30(2) <> 'CU'. 190 | CHECK -name+30(2) <> 'CO'. 191 | CHECK -name+30(2) <> 'CI'. 192 | CHECK -name+30(2) <> 'IP'. 193 | CHECK -name+30(2) <> 'IU'. 194 | CHECK -name NP 'L*UXX'. 195 | INSERT -name INTO TABLE lt_includes. 196 | ENDLOOP. 197 | 198 | SORT lt_includes. 199 | DELETE ADJACENT DUPLICATES FROM lt_includes. 200 | 201 | LOOP AT lt_includes ASSIGNING . 202 | CLEAR: lt_source_in. 203 | READ REPORT INTO lt_source_in. 204 | 205 | lt_pretty = lt_source_in. 206 | 207 | CALL FUNCTION 'CREATE_PRETTY_PRINT_FORMAT' 208 | EXPORTING 209 | mode = get_mode( ) 210 | TABLES 211 | source = lt_pretty 212 | EXCEPTIONS 213 | syntax_errors = 1 214 | OTHERS = 2. 215 | 216 | IF sy-subrc NE 0. 217 | RETURN. 218 | ENDIF. 219 | 220 | IF lt_source_in <> lt_pretty. 221 | LOOP AT lt_source_in ASSIGNING . 222 | lv_tabix = sy-tabix. 223 | READ TABLE lt_pretty INDEX lv_tabix ASSIGNING . 224 | 225 | IF sy-subrc NE 0. 226 | CONTINUE. 227 | ENDIF. 228 | 229 | IF <> . 230 | 231 | inform( p_sub_obj_type = 'PROG' 232 | p_sub_obj_name = 233 | p_line = lv_tabix 234 | p_column = 0 235 | p_kind = c_warning 236 | p_test = myname 237 | p_code = c_pp_error ). 238 | 239 | IF mv_one_finding EQ abap_true. 240 | EXIT. 241 | ENDIF. 242 | 243 | ENDIF. 244 | ENDLOOP. 245 | ENDIF. 246 | 247 | ENDLOOP. 248 | 249 | ENDMETHOD. 250 | 251 | 252 | METHOD set_defaults. 253 | 254 | ms_pp_settings-key_upper = abap_true. 255 | mv_one_finding = abap_true. 256 | 257 | ENDMETHOD. 258 | ENDCLASS. 259 | -------------------------------------------------------------------------------- /src/zcl_ci_test_dsag_pretty_print.clas.testclasses.abap: -------------------------------------------------------------------------------- 1 | CLASS lth_verif_pp DEFINITION FINAL. 2 | PUBLIC SECTION. 3 | 4 | METHODS: ci_check_single IMPORTING iv_variant TYPE sci_chkv 5 | iv_obj_type TYPE trobjtype 6 | iv_obj_name TYPE sobj_name 7 | RETURNING VALUE(rt_result_list) TYPE scit_rest 8 | RAISING cx_ci_invalid_variant 9 | cx_ci_invalid_object 10 | cx_ci_check_error. 11 | 12 | ENDCLASS. 13 | 14 | 15 | CLASS lth_verif_pp IMPLEMENTATION. 16 | 17 | METHOD ci_check_single. 18 | 19 | DATA: lo_result TYPE REF TO cl_ci_check_result, 20 | lv_ok TYPE sychar01. 21 | 22 | 23 | cl_ci_check=>single( EXPORTING p_variant_user = ' ' 24 | p_variant = iv_variant 25 | p_obj_type = iv_obj_type 26 | p_obj_name = iv_obj_name 27 | IMPORTING p_ok = lv_ok 28 | p_result = lo_result ). 29 | 30 | lo_result->get_result( IMPORTING p_result = rt_result_list ). 31 | 32 | ENDMETHOD. 33 | 34 | ENDCLASS. 35 | 36 | 37 | CLASS ltc_test DEFINITION FINAL FOR TESTING RISK LEVEL HARMLESS DURATION SHORT. 38 | 39 | PUBLIC SECTION. 40 | METHODS pp_ok FOR TESTING. 41 | METHODS pp_nok FOR TESTING. 42 | 43 | PRIVATE SECTION. 44 | METHODS setup. 45 | DATA: mo_helper TYPE REF TO lth_verif_pp. 46 | 47 | ENDCLASS. 48 | 49 | CLASS ltc_test IMPLEMENTATION. 50 | 51 | METHOD setup. 52 | CREATE OBJECT mo_helper. 53 | ENDMETHOD. 54 | 55 | METHOD pp_ok. 56 | 57 | DATA: lt_result_list TYPE scit_rest, 58 | lv_lines TYPE sy-index. 59 | 60 | TRY. 61 | lt_result_list = mo_helper->ci_check_single( EXPORTING iv_variant = 'ZVERIF_PRETTY_PRINTER' 62 | iv_obj_type = 'CLAS' 63 | iv_obj_name = 'ZCL_CI_TEST_DSAG_PRETTY_PRINT' ). 64 | CATCH cx_ci_invalid_variant. 65 | cl_abap_unit_assert=>fail( 'Exception CX_CI_INVALID_VARIANT' ). "#EC NOTEXT 66 | CATCH cx_ci_invalid_object. 67 | cl_abap_unit_assert=>fail( 'Exception CX_CI_INVALID_OBJECT' ). "#EC NOTEXT 68 | CATCH cx_ci_check_error. 69 | cl_abap_unit_assert=>fail( 'Exception CX_CI_CHECK_ERROR' ). "#EC NOTEXT 70 | ENDTRY. 71 | 72 | DESCRIBE TABLE lt_result_list LINES lv_lines. 73 | 74 | cl_abap_unit_assert=>assert_equals( act = lv_lines 75 | exp = 0 76 | msg = 'Falsche Anzahl von Meldungen' ). 77 | 78 | ENDMETHOD. 79 | 80 | METHOD pp_nok. 81 | 82 | DATA: lt_result_list TYPE scit_rest, 83 | lv_lines TYPE sy-index. 84 | 85 | 86 | TRY. 87 | lt_result_list = mo_helper->ci_check_single( EXPORTING iv_variant = 'ZVERIF_PRETTY_PRINTER_N' 88 | iv_obj_type = 'CLAS' 89 | iv_obj_name = 'ZCL_CI_TEST_DSAG_PRETTY_PRINT' ). 90 | CATCH cx_ci_invalid_variant. 91 | cl_abap_unit_assert=>fail( 'Exception CX_CI_INVALID_VARIANT' ). "#EC NOTEXT 92 | CATCH cx_ci_invalid_object. 93 | cl_abap_unit_assert=>fail( 'Exception CX_CI_INVALID_OBJECT' ). "#EC NOTEXT 94 | CATCH cx_ci_check_error. 95 | cl_abap_unit_assert=>fail( 'Exception CX_CI_CHECK_ERROR' ). "#EC NOTEXT 96 | ENDTRY. 97 | 98 | DESCRIBE TABLE lt_result_list LINES lv_lines. 99 | 100 | cl_abap_unit_assert=>assert_equals( act = lv_lines 101 | exp = 9 102 | msg = 'Falsche Anzahl von Meldungen' ). 103 | 104 | ENDMETHOD. 105 | 106 | ENDCLASS. 107 | -------------------------------------------------------------------------------- /src/zcl_ci_test_dsag_pretty_print.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_CI_TEST_DSAG_PRETTY_PRINT 7 | D 8 | DSAG-Beispiel-Prüfung: Pretty Printer 9 | 1 10 | X 11 | X 12 | X 13 | X 14 | 15 | 16 | 17 | I 18 | 001 19 | Check Pretty Printer state 20 | 43 21 | 22 | 23 | I 24 | 002 25 | Incorrect Pretty Print State 26 | 32 27 | 28 | 29 | I 30 | 003 31 | Lowercase 32 | 15 33 | 34 | 35 | I 36 | 004 37 | Uppercase 38 | 14 39 | 40 | 41 | I 42 | 005 43 | Uppercase keyword 44 | 18 45 | 46 | 47 | I 48 | 006 49 | Lowercase keyword 50 | 19 51 | 52 | 53 | I 54 | 007 55 | Report one finding per include 56 | 35 57 | 58 | 59 | I 60 | 008 61 | Case conversion 62 | 23 63 | 64 | 65 | I 66 | 009 67 | Check Settings 68 | 25 69 | 70 | 71 | 72 | 73 | ZCL_CI_TEST_DSAG_PRETTY_PRINT 74 | CONSTRUCTOR 75 | D 76 | CONSTRUCTOR 77 | 78 | 79 | ZCL_CI_TEST_DSAG_PRETTY_PRINT 80 | C_PP_ERROR 81 | D 82 | Code Inspector: Kennung für Meldungscode 83 | 84 | 85 | ZCL_CI_TEST_DSAG_PRETTY_PRINT 86 | FILL_MESSAGE 87 | D 88 | scimessages füllen 89 | 90 | 91 | ZCL_CI_TEST_DSAG_PRETTY_PRINT 92 | GET_MODE 93 | D 94 | Pretty Printer Mode zurückliefern 95 | 96 | 97 | ZCL_CI_TEST_DSAG_PRETTY_PRINT 98 | MV_ONE_FINDING 99 | D 100 | allgemeines flag 101 | 102 | 103 | ZCL_CI_TEST_DSAG_PRETTY_PRINT 104 | SET_DEFAULTS 105 | D 106 | Default-Werte setzen 107 | 108 | 109 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /src/zcl_ci_test_header_comment.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_ci_test_header_comment DEFINITION 2 | PUBLIC 3 | INHERITING FROM cl_ci_test_scan 4 | FINAL 5 | CREATE PUBLIC . 6 | 7 | PUBLIC SECTION. 8 | METHODS constructor . 9 | METHODS run REDEFINITION. 10 | PROTECTED SECTION. 11 | 12 | PRIVATE SECTION. 13 | CONSTANTS: con_my_name TYPE seoclsname VALUE 'ZCL_CI_TEST_HEADER_COMMENT' ##NO_TEXT 14 | . 15 | METHODS: 16 | failed 17 | , get_nonclass_1st_relevt_token 18 | RETURNING VALUE(r_token_index) TYPE sytabix. 19 | 20 | ENDCLASS. 21 | 22 | 23 | 24 | CLASS ZCL_CI_TEST_HEADER_COMMENT IMPLEMENTATION. 25 | 26 | 27 | METHOD constructor . 28 | ************************************************************************ 29 | * ATC/Code Inspector Test for header comments. 30 | * Checks for PROG, FUGR, CLAS and INTF, that a header comment was created. 31 | * Author: Edo von Glan, www.draeger.com 32 | * 33 | * Required position of the comment: 34 | * - For normal programs, first line of frame program 35 | * - Header comments for global classes have to be placed in the constructor 36 | * method of the class, after the line 37 | * METHOD constructor. 38 | * (in most cases, you will have to define a constructor just for this purpose. 39 | * If you are in a subclass, you have to call 40 | * super->constructor( ). 41 | * at the end of the method.). 42 | * - For global exception classes, the CLASS_CONSTRUCTOR has to be used 43 | * - For global interfaces, in the line directly after the INTERFACE statement 44 | * - For function pools, in TOP-include, starting in the first line (i.e. in front of the FUNCTION-POOL statement) 45 | * 46 | ************************************************************************ 47 | * MIT License 48 | * 49 | * Copyright (c) 2019 DSAG 50 | * 51 | * Permission is hereby granted, free of charge, to any person obtaining a copy 52 | * of this software and associated documentation files (the "Software"), to deal 53 | * in the Software without restriction, including without limitation the rights 54 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 55 | * copies of the Software, and to permit persons to whom the Software is 56 | * furnished to do so, subject to the following conditions: 57 | * 58 | * The above copyright notice and this permission notice shall be included in all 59 | * copies or substantial portions of the Software. 60 | * 61 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 62 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 63 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 64 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 65 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 66 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 67 | * SOFTWARE. 68 | ************************************************************************ 69 | super->constructor( ). 70 | 71 | description = TEXT-000. 72 | category = |ZCL_CI_CATEGORY_DSAG|. 73 | position = 2. 74 | has_attributes = abap_false. 75 | attributes_ok = abap_false. 76 | has_documentation = abap_true. 77 | 78 | add_obj_type( 'PROG' ). 79 | add_obj_type( 'FUGR' ). 80 | add_obj_type( 'CLAS' ). 81 | add_obj_type( 'INTF' ). 82 | " enhancement implementations cannot be tested here - this class is not called by the framework even if ENHO is added as relevant object type 83 | " (ZCL_CI_TEST_TRANSLATIONS is called, presumably because it only inherits from CL_CI_TEST_ROOT) 84 | 85 | scimessages = VALUE #( ( test = con_my_name code = '0001' kind = c_warning text = TEXT-001 pcom = c_exceptn_imposibl ) ). " Kopfkommentar fehlt in &1 &2 86 | 87 | ENDMETHOD. 88 | 89 | 90 | METHOD failed. 91 | inform( p_sub_obj_type = object_type 92 | p_sub_obj_name = object_name 93 | p_test = con_my_name 94 | p_code = '0001' 95 | p_param_1 = object_type 96 | p_param_2 = object_name ). 97 | ENDMETHOD. 98 | 99 | 100 | METHOD get_nonclass_1st_relevt_token. 101 | CASE object_type. 102 | WHEN 'PROG'. 103 | r_token_index = 1. 104 | WHEN 'FUGR'. 105 | DATA(top_include) = ref_scan->levels[ 2 ]. 106 | ASSERT ID zlog FIELDS object_name CONDITION top_include-name CP 'L*TOP'. " FUGR TOP include should always be in second line of scanned levels 107 | r_token_index = ref_scan->statements[ top_include-from ]-from. 108 | WHEN 'INTF'. 109 | LOOP AT ref_scan->statements REFERENCE INTO DATA(stmt) WHERE type = 'K'. 110 | IF ref_scan->tokens[ stmt->from ]-str = 'INTERFACE'. 111 | r_token_index = stmt->to + 1. 112 | RETURN. 113 | ENDIF. 114 | ENDLOOP. 115 | ASSERT ID zlog FIELDS object_name CONDITION lines( ref_scan->levels ) = 2. " INTF should contain an INTERFACE statement 116 | ENDCASE. 117 | ENDMETHOD. 118 | 119 | 120 | METHOD run. 121 | CHECK object_type IN typelist. 122 | CHECK get( ). 123 | 124 | IF object_type = 'CLAS'. 125 | DATA(parse_status) = |0 CLAS Init|. 126 | ELSE. 127 | DATA(nonclass_first_relevant_token) = get_nonclass_1st_relevt_token( ). " first relevant token, for objects other than CLAS 128 | ENDIF. 129 | DATA(lines) = lines( ref_scan->tokens ). 130 | DATA(comment_lines_found) = 0. 131 | 132 | LOOP AT ref_scan->tokens FROM nonclass_first_relevant_token REFERENCE INTO DATA(token). 133 | DATA(index) = sy-tabix. 134 | " If the current token is a potential comment 135 | IF parse_status = '2 CLAS Constr Impl' 136 | OR object_type <> 'CLAS' AND index >= nonclass_first_relevant_token. 137 | " Check that the first five lines are comments (for comments, one token = one line) 138 | FIND REGEX '^\*' IN token->str. " alternativ: token->type = 'C' 139 | IF sy-subrc <> 0. 140 | parse_status = '- No Comment Found'. 141 | EXIT. 142 | ELSE. 143 | ADD 1 TO comment_lines_found. 144 | IF comment_lines_found >= 5. 145 | parse_status = '+ Comment Found'. 146 | EXIT. 147 | ENDIF. 148 | ENDIF. 149 | ENDIF. 150 | IF object_type = 'CLAS'. 151 | " Check whether we have progressed to a new position/status 152 | CASE token->str. 153 | WHEN 'CLASS'. 154 | IF parse_status = '0 CLAS Init' AND lines >= index + 2 155 | AND ref_scan->tokens[ index + 1 ]-str = object_name 156 | AND ref_scan->tokens[ index + 2 ]-str = 'IMPLEMENTATION'. 157 | parse_status = '1 CLAS Impl'. 158 | ENDIF. 159 | WHEN 'CONSTRUCTOR'. 160 | IF object_name CP 'ZCL*' 161 | AND parse_status = '1 CLAS Impl' AND index > 1 162 | AND ref_scan->tokens[ index - 1 ]-str = 'METHOD'. 163 | parse_status = '2 CLAS Constr Impl'. 164 | ENDIF. 165 | WHEN 'CLASS_CONSTRUCTOR'. 166 | IF object_name CP 'ZCX*' " for exception classes, the constructor is generated and cannot be modified 167 | AND parse_status = '1 CLAS Impl' AND index > 1 168 | AND ref_scan->tokens[ index - 1 ]-str = 'METHOD'. 169 | parse_status = '2 CLAS Constr Impl'. 170 | ENDIF. 171 | WHEN 'ENDMETHOD'. 172 | IF parse_status = '2 CLAS Constr Impl'. 173 | parse_status = '- No Comment Found'. 174 | EXIT. 175 | ENDIF. 176 | ENDCASE. 177 | ENDIF. 178 | ENDLOOP. 179 | IF parse_status <> '+ Comment Found'. 180 | failed( ). 181 | ENDIF. 182 | ENDMETHOD. 183 | ENDCLASS. 184 | -------------------------------------------------------------------------------- /src/zcl_ci_test_header_comment.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_CI_TEST_HEADER_COMMENT 7 | D 8 | Code Inspector: Prüfung Existenz von Kopfkommentaren 9 | 1 10 | X 11 | X 12 | X 13 | K 14 | ZS_DEV_TOOLS 15 | 16 | 17 | 18 | I 19 | 000 20 | Fehlende Kopfkommentare 21 | 64 22 | 23 | 24 | I 25 | 001 26 | Kopfkommentar fehlt in &1 &2 27 | 74 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/zcl_ci_test_translations.clas.abap: -------------------------------------------------------------------------------- 1 | CLASS zcl_ci_test_translations DEFINITION 2 | PUBLIC 3 | INHERITING FROM cl_ci_test_root 4 | FINAL 5 | CREATE PUBLIC . 6 | 7 | PUBLIC SECTION. 8 | METHODS constructor . 9 | METHODS run REDEFINITION . 10 | PROTECTED SECTION. 11 | 12 | PRIVATE SECTION. 13 | CONSTANTS c_my_name TYPE seoclsname VALUE 'ZCL_CI_TEST_TRANSLATIONS' ##NO_TEXT. 14 | TYPES: BEGIN OF tp 15 | , key TYPE syst_msgv " 50 characters. We run into problems with MESSAGE if we use more than that 16 | , END OF tp 17 | , ttp TYPE SORTED TABLE OF tp WITH UNIQUE KEY key 18 | . 19 | DATA: m_spras TYPE spras " 1 character 20 | , m_laiso TYPE t002-laiso " ISO language (2 characters) 21 | . 22 | 23 | METHODS: check_program_texts 24 | , check_screen_texts 25 | , check_single_generic 26 | IMPORTING i_check_code TYPE sci_errc 27 | i_screen TYPE d020s-dnum OPTIONAL " only to be filled for screen checks 28 | , check_list_generic 29 | IMPORTING i_check_code TYPE sci_errc 30 | i_screen TYPE d020s-dnum OPTIONAL " only to be filled for screen checks 31 | , set_language_from_index 32 | IMPORTING i_index TYPE sy-index 33 | , is_master_language_missing 34 | RETURNING VALUE(r) TYPE abap_bool, 35 | remove_screen_ddic_fields 36 | IMPORTING i_program_name TYPE progname 37 | i_screen TYPE d020s-dnum 38 | CHANGING c_fields TYPE zcl_ci_test_translations=>ttp. 39 | 40 | ENDCLASS. 41 | 42 | 43 | 44 | CLASS zcl_ci_test_translations IMPLEMENTATION. 45 | 46 | 47 | METHOD check_list_generic. 48 | DATA: it_key TYPE ttp 49 | , it_key_de TYPE ttp 50 | , it_key_en LIKE it_key_de 51 | , it_key_missing LIKE it_key_de 52 | , pattern TYPE char40 53 | . 54 | 55 | DO 2 TIMES. 56 | set_language_from_index( sy-index ). 57 | CASE i_check_code. 58 | WHEN '0004'. 59 | SELECT msgnr FROM t100 60 | WHERE arbgb = @object_name "#ec ci_conv_ok 61 | AND sprsl = @m_spras 62 | INTO TABLE @it_key. "#EC CI_SUBRC 63 | WHEN '0008'. 64 | SELECT domvalue_l FROM dd07t 65 | WHERE domname = @object_name "#ec ci_conv_ok 66 | AND ddlanguage = @m_spras 67 | AND as4local = 'A' 68 | AND ddtext <> '' 69 | INTO TABLE @it_key. "#EC CI_SUBRC 70 | WHEN '0009'. 71 | pattern = |{ object_name }___|. " followed by 3 digits 72 | SELECT object FROM doktl 73 | WHERE id = 'NA' " message 74 | AND object LIKE @pattern "#ec ci_conv_ok 75 | AND langu = @m_spras "#EC CI_NOORDER 76 | INTO TABLE @DATA(it_key_duplicates). "#EC CI_SUBRC 77 | SORT it_key_duplicates BY table_line. "#EC CI_SORTLOOP . Cannot use DISTINCT because doktl is a cluster table 78 | DELETE ADJACENT DUPLICATES FROM it_key_duplicates COMPARING table_line. 79 | it_key = it_key_duplicates. 80 | WHEN '0010'. 81 | SELECT SINGLE @abap_true 82 | FROM d342l 83 | WHERE progname = @program_name 84 | INTO @data(dummy). 85 | IF sy-subrc = 0. " if all GUI status have been deleted (no entry in table d342l), the texts still remain as zombies, but we do not want to check them. 86 | " However, the entry in d342l also sometimes remains, even though the GUI status has been deleted. So in some cases there will still be false (zombie) findings 87 | DATA(separator) = '|'. 88 | SELECT DISTINCT obj_type && @separator && texttype && @separator && obj_code FROM rsmptexts 89 | WHERE progname = @program_name "#ec ci_conv_ok 90 | " do not check technical texts: 91 | AND ( texttype <> 'T' " various texts of GUI-Status 92 | OR obj_type = 'T' ) " GUI-Title 93 | AND sprsl = @m_spras " #EC CI_CMPLX_WHERE 94 | INTO TABLE @it_key. "#EC CI_SUBRC 95 | ENDIF. 96 | WHEN '0012'. 97 | SELECT fldn FROM d021t 98 | WHERE prog = @program_name "#ec ci_conv_ok 99 | AND dynr = @i_screen 100 | AND lang = @m_spras 101 | INTO TABLE @it_key. "#EC CI_SUBRC 102 | WHEN '0014'. 103 | pattern = |{ object_name WIDTH = 30 }%|. " first 30 chars = componentname + spaces (followed by viewname from pos 31) 104 | SELECT CASE sotr_head~alias_name 105 | WHEN ' ' THEN sotr_head~concept 106 | ELSE sotr_head~alias_name 107 | END AS key 108 | FROM sotr_use INNER JOIN sotr_head ON sotr_use~concept = sotr_head~concept 109 | INNER JOIN sotr_text ON sotr_use~concept = sotr_text~concept 110 | WHERE sotr_use~pgmid = 'LIMU' 111 | AND sotr_use~object = 'WDYV' 112 | AND sotr_use~obj_name LIKE @pattern 113 | AND sotr_text~langu = @m_spras 114 | INTO TABLE @it_key. "#EC CI_SUBRC 115 | WHEN OTHERS. 116 | ASSERT 1 = 0. 117 | ENDCASE. 118 | 119 | CASE sy-index. 120 | WHEN 1. MOVE-CORRESPONDING it_key TO it_key_de. 121 | WHEN 2. MOVE-CORRESPONDING it_key TO it_key_en. 122 | ENDCASE. 123 | ENDDO. 124 | 125 | " need to synchronize at this point, otherwise the filtering cannot be done both ways 126 | DO 2 TIMES. 127 | set_language_from_index( sy-index ). 128 | CASE sy-index. 129 | WHEN 1. it_key_missing = FILTER #( it_key_en EXCEPT IN it_key_de WHERE key = key ). 130 | WHEN 2. it_key_missing = FILTER #( it_key_de EXCEPT IN it_key_en WHERE key = key ). 131 | ENDCASE. 132 | IF i_check_code = '0012'. 133 | remove_screen_ddic_fields( EXPORTING i_program_name = program_name 134 | i_screen = i_screen 135 | CHANGING c_fields = it_key_missing ). 136 | ENDIF. 137 | LOOP AT it_key_missing ASSIGNING FIELD-SYMBOL(). 138 | inform( p_sub_obj_type = object_type 139 | p_sub_obj_name = object_name 140 | p_test = c_my_name 141 | p_code = i_check_code 142 | " in case 0012 (Screen [dynpro] field), 143 | " if the master language entry is missing (i.e. field has been deleted, but translation was not deleted), 144 | " ignore, because of very low risk 145 | " (I also verified that the Autotext numbers are not reused - EvG) 146 | " This case still occurs after I implemented the remove_screen_ddic_fields() method - 08.05.2019 with SAPMZE32 / 9090 147 | p_kind = COND #( WHEN i_check_code = '0012' AND is_master_language_missing( ) THEN c_note 148 | ELSE c_warning ) 149 | p_param_1 = COND #( WHEN i_check_code = '0012' THEN i_screen && '|' && -key 150 | ELSE -key ) 151 | p_param_2 = m_laiso ). 152 | ENDLOOP. 153 | ENDDO. 154 | ENDMETHOD. 155 | 156 | 157 | METHOD check_program_texts. 158 | DATA: it_tpool TYPE textpool_table 159 | , it_de TYPE SORTED TABLE OF textpool WITH UNIQUE KEY id key 160 | , it_en LIKE it_de 161 | , it_missing LIKE it_de 162 | , check_code TYPE sci_errc 163 | . 164 | CHECK program_name IS NOT INITIAL. 165 | DO 2 TIMES. 166 | set_language_from_index( sy-index ). 167 | CLEAR it_tpool. 168 | READ TEXTPOOL program_name LANGUAGE m_spras INTO it_tpool. 169 | SORT it_tpool BY id key. "#EC CI_SORTLOOP 170 | DELETE ADJACENT DUPLICATES FROM it_tpool COMPARING id key. " we do not want to crash because of inconsistent data (e.g. report ZKFVBMTASNEU) 171 | 172 | CASE sy-index. 173 | WHEN 1. MOVE-CORRESPONDING it_tpool TO it_de. 174 | WHEN 2. MOVE-CORRESPONDING it_tpool TO it_en. 175 | ENDCASE. 176 | ENDDO. 177 | 178 | " need to synchronize at this point, otherwise the filtering cannot be done both ways 179 | DO 2 TIMES. 180 | " first iteration: m_spras = D. it_missing = texts missing in DE (i.e. existing only in EN) 181 | set_language_from_index( sy-index ). 182 | CASE sy-index. 183 | WHEN 1. it_missing = FILTER #( it_en EXCEPT IN it_de WHERE id = id AND key = key ). 184 | WHEN 2. it_missing = FILTER #( it_de EXCEPT IN it_en WHERE id = id AND key = key ). 185 | ENDCASE. 186 | 187 | " We observed once there was an ID=R Length=0 entry for a function group. Therefore: 188 | DELETE it_missing WHERE length = 0. "#EC CI_SORTSEQ 189 | 190 | LOOP AT it_missing ASSIGNING FIELD-SYMBOL(). 191 | CASE -id. 192 | WHEN 'S'. 193 | check_code = '0001'. 194 | IF -entry(1) = 'D'. 195 | " if the DDIC-Flag is set in the original language, texts are taken from DDIC. 196 | " But a "dummy" translation "." to other languages is required for technical reasons 197 | " see note https://launchpad.support.sap.com/#/notes/2287306 198 | " ATTENTION: the logic here has to be checked when we add a further languages (besides DE and EN) 199 | check_code = '0016'. " Dummy-Text "." missing --- Note that in this case there only p_param_2 / &2 is used 200 | ENDIF. 201 | " in case 0001 (Parameters), 202 | " if the master language entry is missing (i.e. parameter has been removed, but translation was not deleted), 203 | " ignore, because of very low risk 204 | IF is_master_language_missing( ). 205 | DATA(prio3_only) = abap_true. 206 | ENDIF. 207 | WHEN 'I'. check_code = '0002'. 208 | WHEN 'R'. check_code = '0003'. 209 | WHEN OTHERS. " check for list headings not supported 210 | ENDCASE. 211 | CHECK check_code IS NOT INITIAL. " correction EvG 20180509 after Upgrade 212 | inform( p_sub_obj_type = object_type 213 | p_sub_obj_name = object_name 214 | p_test = c_my_name 215 | p_code = check_code 216 | p_kind = COND #( WHEN prio3_only = abap_false THEN c_warning 217 | ELSE c_note ) 218 | p_param_1 = -key 219 | p_param_2 = m_laiso ). 220 | ENDLOOP. 221 | ENDDO. 222 | 223 | DATA(it_both) = FILTER #( it_en IN it_de WHERE id = id AND key = key ). 224 | LOOP AT it_both ASSIGNING WHERE id = 'S'. 225 | DATA(wa_de) = it_de[ id = -id key = -key ]. 226 | DATA(wa_en) = it_en[ id = -id key = -key ]. 227 | IF ( wa_de-entry(1) = 'D' AND wa_en-entry(1) = ' ' ) 228 | OR ( wa_de-entry(1) = ' ' AND wa_en-entry(1) = 'D' ). 229 | inform( p_sub_obj_type = object_type 230 | p_sub_obj_name = object_name 231 | p_test = c_my_name 232 | p_code = '0006' 233 | p_param_1 = -key ). 234 | ENDIF. 235 | ENDLOOP. 236 | 237 | ENDMETHOD. 238 | 239 | 240 | METHOD check_screen_texts. 241 | SELECT dnum FROM d020s 242 | WHERE type = '' " exclude generated screens 243 | AND prog = @program_name 244 | INTO TABLE @DATA(screens). "#EC CI_SUBRC 245 | LOOP AT screens ASSIGNING FIELD-SYMBOL(). 246 | check_single_generic( i_check_code = '0011' 247 | i_screen = CONV #( ) ). 248 | check_list_generic( i_check_code = '0012' 249 | i_screen = CONV #( ) ). 250 | ENDLOOP. 251 | ENDMETHOD. 252 | 253 | 254 | METHOD check_single_generic. 255 | DATA: missing TYPE abap_bool 256 | , exists TYPE abap_bool 257 | . 258 | 259 | DO 2 TIMES. 260 | set_language_from_index( sy-index ). 261 | exists = abap_false. 262 | CASE i_check_code. 263 | WHEN '0005'. 264 | SELECT SINGLE @abap_true FROM dd04t 265 | WHERE rollname = @object_name "#ec ci_conv_ok 266 | AND ddlanguage = @m_spras 267 | INTO @exists. "#EC CI_SUBRC 268 | WHEN '0007'. 269 | SELECT SINGLE @abap_true FROM tstct 270 | WHERE tcode = @object_name "#ec ci_conv_ok 271 | AND sprsl = @m_spras 272 | INTO @exists. "#EC CI_SUBRC 273 | WHEN '0011'. 274 | SELECT SINGLE @abap_true FROM d020t 275 | WHERE prog = @program_name "#ec ci_conv_ok 276 | AND dynr = @i_screen 277 | AND lang = @m_spras 278 | INTO @exists. "#EC CI_SUBRC 279 | WHEN '0013'. 280 | SELECT SINGLE @abap_true FROM tparat 281 | WHERE paramid = @object_name "#ec ci_conv_ok 282 | AND sprache = @m_spras 283 | INTO @exists. "#EC CI_SUBRC 284 | WHEN '0015'. 285 | SELECT SINGLE @abap_true FROM tdevct 286 | WHERE devclass = @object_name "#ec ci_conv_ok 287 | AND spras = @m_spras 288 | INTO @exists. "#EC CI_SUBRC 289 | WHEN OTHERS. 290 | ASSERT 1 = 0. 291 | ENDCASE. 292 | CASE sy-index. 293 | WHEN 1. DATA(de_exists) = exists. 294 | WHEN 2. DATA(en_exists) = exists. 295 | ENDCASE. 296 | ENDDO. 297 | 298 | " need to synchronize at this point, otherwise the filtering cannot be done both ways 299 | DO 2 TIMES. 300 | set_language_from_index( sy-index ). 301 | CASE sy-index. 302 | WHEN 1. missing = xsdbool( de_exists = abap_false AND en_exists = abap_true ). 303 | WHEN 2. missing = xsdbool( de_exists = abap_true AND en_exists = abap_false ). 304 | ENDCASE. 305 | IF missing = abap_true. 306 | inform( p_sub_obj_type = object_type 307 | p_sub_obj_name = object_name 308 | p_test = c_my_name 309 | p_code = i_check_code 310 | " in case 0005 (Data Element), 311 | " if the master language entry is missing (i.e. Data element has been deleted, but translation was not deleted), 312 | " ignore, because of very low risk 313 | p_kind = COND #( WHEN i_check_code = '0005' AND is_master_language_missing( ) THEN c_note 314 | ELSE c_warning ) 315 | p_param_1 = i_screen " this is only filled for check 0011. All other texts here should not make use of &1 316 | p_param_2 = m_laiso ). " PARAM1 should be something key-like, for the filtering of Z_DELTA check variant 317 | ENDIF. 318 | ENDDO. 319 | 320 | ENDMETHOD. 321 | 322 | 323 | METHOD constructor . 324 | ************************************************************************ 325 | * ATC/Code Inspector Test for missing translations. 326 | * Checks for various object types, that texts are maintained in DE and EN. 327 | * Author: Edo von Glan, www.draeger.com 328 | * 329 | * Known limitations of this check 330 | * - Navigation to objects (translated texts) is not possible 331 | * - If there are several GUI status for one program, the message does not reveal 332 | * in which status the text is missing (because info is not directly available in 333 | * RSMPTEXTS, would need to evaluate output of function RS_CUA_INTERNAL_FETCH 334 | * for various object types) 335 | * 336 | * Possible additional object types / checks 337 | * DD01T R/3 DD: domain texts - not sure if this is ever visible for the user 338 | * DD02T SAP DD: SAP Table Texts - not sure if this is ever visible for the user 339 | * DD30T Search help texts - not sure if this is ever visible for the user 340 | * SE61-Texts in general 341 | * 342 | * Note concerning other languages: 343 | * Currently, DE and EN are checked. 344 | * It would be difficult to check more than 2 languages (big change of logic / code necessary). 345 | * However, it would be easily possible to replace EN with a different language as second language, maybe dependent 346 | * on the check variant (e.g. Z_TRANSLATION_FR might replace EN with FR) 347 | ************************************************************************ 348 | * MIT License 349 | * 350 | * Copyright (c) 2019 DSAG 351 | * 352 | * Permission is hereby granted, free of charge, to any person obtaining a copy 353 | * of this software and associated documentation files (the "Software"), to deal 354 | * in the Software without restriction, including without limitation the rights 355 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 356 | * copies of the Software, and to permit persons to whom the Software is 357 | * furnished to do so, subject to the following conditions: 358 | * 359 | * The above copyright notice and this permission notice shall be included in all 360 | * copies or substantial portions of the Software. 361 | * 362 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 363 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 364 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 365 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 366 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 367 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 368 | * SOFTWARE. 369 | ************************************************************************ 370 | 371 | DEFINE fill_message. 372 | CLEAR smsg. 373 | smsg-test = c_my_name. 374 | smsg-code = &1. "message code 375 | smsg-kind = &2. "message priority 376 | smsg-text = &3. "message text 377 | smsg-pcom = &4. "pseudocomment 378 | INSERT smsg INTO TABLE scimessages. 379 | END-OF-DEFINITION. 380 | 381 | super->constructor( ). 382 | 383 | description = TEXT-000. 384 | category = 'ZCL_CI_CATEGORY_DSAG' ##NO_TEXT. 385 | position = 1. 386 | has_attributes = abap_false. 387 | attributes_ok = abap_false. 388 | has_documentation = abap_true. 389 | 390 | add_obj_type( 'PROG' ). 391 | add_obj_type( 'FUGR' ). 392 | add_obj_type( 'CLAS' ). 393 | add_obj_type( 'INTF' ). 394 | add_obj_type( 'MSAG' ). 395 | add_obj_type( 'DOMA' ). 396 | add_obj_type( 'DTEL' ). 397 | add_obj_type( 'TRAN' ). 398 | add_obj_type( 'PARA' ). 399 | add_obj_type( 'WDYN' ). 400 | add_obj_type( 'DEVC' ). 401 | 402 | fill_message '0001' c_warning TEXT-001 c_exceptn_imposibl . " Selektionstext &1 fehlt in Sprache &2 (TEXTPOOL-ID = S) 403 | fill_message '0002' c_warning TEXT-002 c_exceptn_imposibl . " Textsymbol &1 fehlt in Sprache &2 (TEXTPOOL-ID = I) 404 | fill_message '0003' c_warning TEXT-003 c_exceptn_imposibl . " Programmtitel fehlt in Sprache &2 (TEXTPOOL-ID = R) 405 | fill_message '0004' c_warning TEXT-004 c_exceptn_imposibl . " Nachricht &1 fehlt in Sprache &2 406 | fill_message '0005' c_warning TEXT-005 c_exceptn_imposibl . " Text zu Datenelement fehlt in Sprache &2 407 | fill_message '0006' c_note TEXT-006 c_exceptn_imposibl . " Selektionstext &1 hat inkonsistenten DDIC-Bezug (DE/EN) 408 | fill_message '0007' c_warning TEXT-007 c_exceptn_imposibl . " Text zu Transaktion fehlt in Sprache &2 409 | fill_message '0008' c_warning TEXT-008 c_exceptn_imposibl . " Text zu Festwert &1 fehlt in Sprache &2 410 | fill_message '0009' c_warning TEXT-009 c_exceptn_imposibl . " Langtext zu Nachricht &1 fehlt in Sprache &2 411 | fill_message '0010' c_warning TEXT-010 c_exceptn_imposibl . " GUI-Text &1 fehlt in Sprache &2 412 | fill_message '0011' c_warning TEXT-011 c_exceptn_imposibl . " Text zu Dynpro &1 fehlt in Sprache &2 413 | fill_message '0012' c_warning TEXT-012 c_exceptn_imposibl . " Text zu Dynpro-Feld &1 fehlt in Sprache &2 414 | fill_message '0013' c_warning TEXT-013 c_exceptn_imposibl . " Text zu GET/SET-Parameter fehlt in Sprache &2 415 | fill_message '0014' c_warning TEXT-014 c_exceptn_imposibl . " OTR-Text zu Konzept &1 fehlt in Sprache &2 416 | fill_message '0015' c_warning TEXT-015 c_exceptn_imposibl . " Kurzbeschreibung zu Paket &1 fehlt in Sprache &2 417 | fill_message '0016' c_warning TEXT-016 c_exceptn_imposibl . " Dummy-Text "." zu DDIC-Selektionsparameter &1 fehlt in Sprache &2 418 | 419 | ENDMETHOD. 420 | 421 | 422 | METHOD is_master_language_missing. 423 | SELECT SINGLE masterlang 424 | FROM tadir 425 | WHERE pgmid = 'R3TR' 426 | AND object = @object_type 427 | AND obj_name = @object_name 428 | INTO @DATA(master_language). 429 | IF sy-subrc <> 0 OR master_language IS INITIAL. 430 | SELECT SINGLE rload 431 | FROM reposrc 432 | WHERE progname = @program_name 433 | AND r3state = 'A' 434 | INTO @master_language. 435 | IF sy-subrc <> 0 OR master_language IS INITIAL. 436 | LOG-POINT ID zlog FIELDS object_type object_name program_name. 437 | r = abap_false. " like this, there may be an error on the side of giving too many warnings (which we prefer to too few) 438 | RETURN. 439 | ENDIF. 440 | ENDIF. 441 | 442 | r = xsdbool( m_spras = master_language ). 443 | 444 | ENDMETHOD. 445 | 446 | 447 | METHOD run. 448 | CHECK object_type IN typelist. 449 | check_program_texts( ). 450 | check_screen_texts( ). 451 | CASE object_type. 452 | WHEN 'DTEL'. 453 | check_single_generic( '0005' ). 454 | WHEN 'DOMA'. 455 | check_list_generic( '0008' ). 456 | WHEN 'MSAG'. 457 | check_list_generic( '0004' ). 458 | check_list_generic( '0009' ). 459 | WHEN 'PROG' OR 'FUGR'. 460 | check_list_generic( '0010' ). 461 | WHEN 'TRAN'. 462 | check_single_generic( '0007' ). 463 | WHEN 'PARA'. 464 | check_single_generic( '0013' ). 465 | WHEN 'WDYN'. " R3TR WDYN --> LIMU WDYV --> OTR text 466 | check_list_generic( '0014' ). 467 | WHEN 'DEVC'. 468 | check_single_generic( '0015' ). 469 | ENDCASE. 470 | 471 | ENDMETHOD. 472 | 473 | 474 | METHOD set_language_from_index. 475 | CASE i_index. 476 | WHEN 1. m_spras = 'D'. 477 | WHEN 2. m_spras = 'E'. 478 | ENDCASE. 479 | SELECT SINGLE laiso FROM t002 480 | WHERE spras = @m_spras 481 | INTO @m_laiso. 482 | ASSERT sy-subrc = 0. 483 | ENDMETHOD. 484 | 485 | METHOD remove_screen_ddic_fields. 486 | DATA: screen_fields TYPE dyfatc_tab. 487 | CHECK c_fields IS NOT INITIAL. 488 | CALL FUNCTION 'RPY_DYNPRO_READ' 489 | EXPORTING 490 | progname = i_program_name 491 | dynnr = i_screen 492 | suppress_exist_checks = 'X' " Unterdrücken Existenzcheck des Dynpros 493 | suppress_corr_checks = 'X' " Unterdrücken Verprobung Anzeigeberechtigung 494 | TABLES 495 | fields_to_containers = screen_fields 496 | EXCEPTIONS 497 | cancelled = 1 " Abbruch durch Nutzer im Korrektur-popup 498 | not_found = 2 " Dynpro nicht gefunden 499 | permission_error = 3 " keine Berechtigung im Importieren (Lesen) 500 | OTHERS = 4. 501 | ASSERT ID zlog FIELDS i_program_name i_screen CONDITION sy-subrc = 0. 502 | LOOP AT c_fields REFERENCE INTO DATA(check_field). 503 | 504 | IF NOT line_exists( screen_fields[ name = check_field->key type = 'TEXT' ] ) 505 | OR screen_fields[ name = check_field->key type = 'TEXT' ]-from_dict = 'X'. 506 | DELETE c_fields USING KEY loop_key. 507 | ENDIF. 508 | ENDLOOP. 509 | " Alternative implementation: 510 | " function DYNPRO_IMPORT, then 511 | " data FLG1DDF type X length 1 value '20'. 512 | " from_dict = -FLG1 BIT_AND FLG1DDF (in SAP code, the obsolete operator 'o' is used) 513 | ENDMETHOD. 514 | 515 | ENDCLASS. 516 | -------------------------------------------------------------------------------- /src/zcl_ci_test_translations.clas.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZCL_CI_TEST_TRANSLATIONS 7 | D 8 | Code Inspector: Prüfung bezüglich Übersetzung von Texten 9 | 1 10 | X 11 | X 12 | X 13 | 14 | 15 | 16 | I 17 | 000 18 | Fehlende Übersetzungen zu Texten 19 | 64 20 | 21 | 22 | I 23 | 001 24 | Selektionstext &1 fehlt in Sprache &2 25 | 74 26 | 27 | 28 | I 29 | 002 30 | Textsymbol &1 fehlt in Sprache &2 31 | 66 32 | 33 | 34 | I 35 | 003 36 | Programmtitel fehlt in Sprache &2 37 | 66 38 | 39 | 40 | I 41 | 004 42 | Nachricht &1 fehlt in Sprache &2 43 | 64 44 | 45 | 46 | I 47 | 005 48 | Texte zu Datenelement fehlen in Sprache &2 49 | 80 50 | 51 | 52 | I 53 | 006 54 | Selektionstext &1 hat inkonsistenten DDIC-Bezug (DE/EN verschieden) 55 | 132 56 | 57 | 58 | I 59 | 007 60 | Text zu Transaktion fehlt in Sprache &2 61 | 84 62 | 63 | 64 | I 65 | 008 66 | Text zu Festwert &1 fehlt in Sprache &2 67 | 68 68 | 69 | 70 | I 71 | 009 72 | Langtext zu Nachricht &1 fehlt in Sprache &2 73 | 80 74 | 75 | 76 | I 77 | 010 78 | GUI-Text &1 fehlt in Sprache &2 79 | 62 80 | 81 | 82 | I 83 | 011 84 | Text zu Dynpro &1 fehlt in Sprache &2 85 | 74 86 | 87 | 88 | I 89 | 012 90 | Text zu Dynpro-Feld &1 fehlt in Sprache &2 91 | 84 92 | 93 | 94 | I 95 | 013 96 | Text zu GET/SET-Parameter fehlt in Sprache &2 97 | 80 98 | 99 | 100 | I 101 | 014 102 | OTR-Text zu Alias/Konzept &1 fehlt in Sprache &2 103 | 88 104 | 105 | 106 | I 107 | 015 108 | Kurzbeschreibung zu Paket fehlt in Sprache &2 109 | 96 110 | 111 | 112 | I 113 | 016 114 | Dummy-Text "." zu DDIC-Selektionsparametern fehlt in Sprache &2 (Hinweis 2652089) 115 | 130 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /src/zverif_pretty_printer=========vc.prog.abap: -------------------------------------------------------------------------------- 1 | 20190925 C_MLICHTINGER 2 | DSAG-Beispiel: für U-Test Pretty Printer Prüfklasse - ok 3 | ZCL_CI_TEST_DSAG_PRETTY_PRINT 201 000 4 | FF060201010280003431303300000000020E0000000008000000740E00000000 5 | 000000000000000000000000000000004D0053005F00500050005F0053004500 6 | 5400540049004E0047005300AB0E0000000008AA000000000002AA0000000000 7 | 02AA000000000002AA000000000002AC0E0000000008BC000000082000200058 8 | 002000BD01000000000002000000440E00000000000000000000000000000000 9 | 000000004D0056005F004F004E0045005F00460049004E00440049004E004700 10 | BC000000025800BD04 11 | -------------------------------------------------------------------------------- /src/zverif_pretty_printer=========vc.prog.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZVERIF_PRETTY_PRINTER=========VC 7 | I 8 | S 9 | D 10 | X 11 | 12 | 13 | 14 | D 15 | 16 | 17 | R 18 | SCI Validierungsvariante Pretty Printer - OK 19 | 44 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/zverif_pretty_printer_n=======vc.prog.abap: -------------------------------------------------------------------------------- 1 | 20190925 C_MLICHTINGER 2 | DSAG-Beispiel: für U-Test Pretty Printer Prüfklasse - nok 3 | ZCL_CI_TEST_DSAG_PRETTY_PRINT 201 000 4 | FF060201010280003431303300000000020E0000000008000000740E00000000 5 | 000000000000000000000000000000004D0053005F00500050005F0053004500 6 | 5400540049004E0047005300AB0E0000000008AA000000000002AA0000000000 7 | 02AA000000000002AA000000000002AC0E0000000008BC000000085800200020 8 | 002000BD01000000000002000000440E00000000000000000000000000000000 9 | 000000004D0056005F004F004E0045005F00460049004E00440049004E004700 10 | BC000000025800BD04 11 | -------------------------------------------------------------------------------- /src/zverif_pretty_printer_n=======vc.prog.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | ZVERIF_PRETTY_PRINTER_N=======VC 7 | I 8 | S 9 | D 10 | X 11 | 12 | 13 | 14 | D 15 | 16 | 17 | R 18 | SCI Validierungsvariante Pretty Printer - NOK 19 | 45 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | --------------------------------------------------------------------------------