mirror of
https://github.com/abapGit/abapGit.git
synced 2025-05-01 12:20:51 +08:00
Merge remote-tracking branch 'origin/news_announcement' into news2
This commit is contained in:
commit
30f89dc9b5
|
@ -55,6 +55,7 @@ INCLUDE zabapgit_authorizations.
|
||||||
INCLUDE zabapgit_stage.
|
INCLUDE zabapgit_stage.
|
||||||
INCLUDE zabapgit_git_helpers.
|
INCLUDE zabapgit_git_helpers.
|
||||||
INCLUDE zabapgit_repo.
|
INCLUDE zabapgit_repo.
|
||||||
|
INCLUDE zabapgit_news.
|
||||||
INCLUDE zabapgit_stage_logic.
|
INCLUDE zabapgit_stage_logic.
|
||||||
INCLUDE zabapgit_2fa.
|
INCLUDE zabapgit_2fa.
|
||||||
INCLUDE zabapgit_http.
|
INCLUDE zabapgit_http.
|
||||||
|
|
|
@ -742,3 +742,49 @@ div.tutorial h2 {
|
||||||
}
|
}
|
||||||
.nav-container ul ul li.separator:first-child { border-top: none; }
|
.nav-container ul ul li.separator:first-child { border-top: none; }
|
||||||
.nav-container ul ul li.separator:hover { background-color: inherit; }
|
.nav-container ul ul li.separator:hover { background-color: inherit; }
|
||||||
|
|
||||||
|
/* News Announcement */
|
||||||
|
.news {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 99;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 40em;
|
||||||
|
margin-top: -12em;
|
||||||
|
margin-left: -20em;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
background-color: white;
|
||||||
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news .title {
|
||||||
|
color: #888888;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 16px;
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news .attention {
|
||||||
|
background-color: #ff9800;
|
||||||
|
color: white;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news li {
|
||||||
|
margin: 4px;
|
||||||
|
padding-left: 10px;
|
||||||
|
font-size: 15px;
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.news p.versionHeader {
|
||||||
|
font-size: 16px;
|
||||||
|
color: #888888;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: left;
|
||||||
|
padding-top: 8px;
|
||||||
|
padding-bottom: 8px;
|
||||||
|
border-bottom: 1px #ddd solid;
|
||||||
|
margin: 4px;
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ CLASS lcl_gui_chunk_lib DEFINITION FINAL.
|
||||||
iv_show_branch TYPE abap_bool DEFAULT abap_true
|
iv_show_branch TYPE abap_bool DEFAULT abap_true
|
||||||
iv_interactive_branch TYPE abap_bool DEFAULT abap_false
|
iv_interactive_branch TYPE abap_bool DEFAULT abap_false
|
||||||
iv_branch TYPE string OPTIONAL
|
iv_branch TYPE string OPTIONAL
|
||||||
|
io_news TYPE REF TO lcl_news OPTIONAL
|
||||||
RETURNING VALUE(ro_html) TYPE REF TO lcl_html
|
RETURNING VALUE(ro_html) TYPE REF TO lcl_html
|
||||||
RAISING lcx_exception.
|
RAISING lcx_exception.
|
||||||
|
|
||||||
|
@ -36,6 +37,12 @@ CLASS lcl_gui_chunk_lib DEFINITION FINAL.
|
||||||
RETURNING VALUE(ro_html) TYPE REF TO lcl_html
|
RETURNING VALUE(ro_html) TYPE REF TO lcl_html
|
||||||
RAISING lcx_exception.
|
RAISING lcx_exception.
|
||||||
|
|
||||||
|
CLASS-METHODS render_news
|
||||||
|
IMPORTING
|
||||||
|
io_news TYPE REF TO lcl_news
|
||||||
|
RETURNING VALUE(ro_html) TYPE REF TO lcl_html
|
||||||
|
RAISING lcx_exception.
|
||||||
|
|
||||||
ENDCLASS. "lcl_gui_chunk_lib
|
ENDCLASS. "lcl_gui_chunk_lib
|
||||||
|
|
||||||
CLASS lcl_gui_chunk_lib IMPLEMENTATION.
|
CLASS lcl_gui_chunk_lib IMPLEMENTATION.
|
||||||
|
@ -72,6 +79,12 @@ CLASS lcl_gui_chunk_lib IMPLEMENTATION.
|
||||||
|
|
||||||
ro_html->add( '<td class="repo_attr right">' ).
|
ro_html->add( '<td class="repo_attr right">' ).
|
||||||
|
|
||||||
|
IF io_news IS BOUND AND io_news->has_news( ) = abap_true.
|
||||||
|
ro_html->add_a( iv_act = 'displayNews()'
|
||||||
|
iv_typ = gc_action_type-onclick
|
||||||
|
iv_txt = lcl_html=>icon( iv_name = 'history/dark' ) ).
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
IF abap_true = lcl_app=>user( )->is_favorite_repo( io_repo->get_key( ) ).
|
IF abap_true = lcl_app=>user( )->is_favorite_repo( io_repo->get_key( ) ).
|
||||||
lv_icon = 'star/blue' ##NO_TEXT.
|
lv_icon = 'star/blue' ##NO_TEXT.
|
||||||
ELSE.
|
ELSE.
|
||||||
|
@ -215,4 +228,50 @@ CLASS lcl_gui_chunk_lib IMPLEMENTATION.
|
||||||
ro_html->add( '</div>' ).
|
ro_html->add( '</div>' ).
|
||||||
ENDMETHOD. "render_js_error_stub
|
ENDMETHOD. "render_js_error_stub
|
||||||
|
|
||||||
|
METHOD render_news.
|
||||||
|
|
||||||
|
DATA lt_log TYPE lcl_news=>tt_log.
|
||||||
|
|
||||||
|
CREATE OBJECT ro_html.
|
||||||
|
|
||||||
|
IF io_news IS NOT BOUND.
|
||||||
|
RETURN.
|
||||||
|
ELSEIF io_news->has_news( ) = abap_true.
|
||||||
|
lt_log = io_news->get_log( ).
|
||||||
|
ELSE.
|
||||||
|
RETURN.
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
FIELD-SYMBOLS: <line> LIKE LINE OF lt_log.
|
||||||
|
|
||||||
|
ro_html->add( '<div id="news" class="news">' ).
|
||||||
|
|
||||||
|
ro_html->add( '<table class="w100"><tr>' ).
|
||||||
|
ro_html->add( '<td class="title">' ).
|
||||||
|
ro_html->add( 'Announcement of the latest changes' ).
|
||||||
|
ro_html->add( '</td>' ).
|
||||||
|
ro_html->add( '<td class="right">' ).
|
||||||
|
ro_html->add( '<a onclick="displayNews()">close</a>' ).
|
||||||
|
ro_html->add( '</td>' ).
|
||||||
|
ro_html->add( '</tr></table>' ).
|
||||||
|
|
||||||
|
IF io_news->has_important_news( ) = abap_true.
|
||||||
|
ro_html->add( '<div class="attention">'
|
||||||
|
&& 'Some changes mentioned in this announcement might be critical !'
|
||||||
|
&& '</div>' ).
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
" Generate news
|
||||||
|
LOOP AT lt_log ASSIGNING <line>.
|
||||||
|
IF <line>-header = 'X'.
|
||||||
|
ro_html->add( |<p class="versionHeader"> { <line>-text } </p>| ).
|
||||||
|
ELSE.
|
||||||
|
ro_html->add( |<li> { <line>-text } </li>| ).
|
||||||
|
ENDIF.
|
||||||
|
ENDLOOP.
|
||||||
|
|
||||||
|
ro_html->add( '</div>' ).
|
||||||
|
|
||||||
|
ENDMETHOD. "render_news
|
||||||
|
|
||||||
ENDCLASS. "lcl_gui_chunk_lib
|
ENDCLASS. "lcl_gui_chunk_lib
|
||||||
|
|
|
@ -499,3 +499,13 @@ DiffHelper.prototype.highlightButton = function(state) {
|
||||||
this.dom.filterButton.classList.remove("bgorange");
|
this.dom.filterButton.classList.remove("bgorange");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**********************************************************
|
||||||
|
* Other functions
|
||||||
|
**********************************************************/
|
||||||
|
|
||||||
|
// News announcement
|
||||||
|
function displayNews() {
|
||||||
|
var div = document.getElementById("news");
|
||||||
|
div.style.display = (div.style.display)?'':'none';
|
||||||
|
}
|
||||||
|
|
400
src/zabapgit_news.prog.abap
Normal file
400
src/zabapgit_news.prog.abap
Normal file
|
@ -0,0 +1,400 @@
|
||||||
|
*&---------------------------------------------------------------------*
|
||||||
|
*& Include ZABAPGIT_NEWS
|
||||||
|
*&---------------------------------------------------------------------*
|
||||||
|
CLASS ltcl_news DEFINITION DEFERRED.
|
||||||
|
|
||||||
|
*&---------------------------------------------------------------------*
|
||||||
|
*& Class lcl_news
|
||||||
|
*&---------------------------------------------------------------------*
|
||||||
|
* Class responsible for preparation of data for news announcements
|
||||||
|
*----------------------------------------------------------------------*
|
||||||
|
CLASS lcl_news DEFINITION FRIENDS ltcl_news.
|
||||||
|
|
||||||
|
PUBLIC SECTION.
|
||||||
|
TYPES:
|
||||||
|
BEGIN OF ty_log,
|
||||||
|
version TYPE string,
|
||||||
|
header TYPE abap_bool,
|
||||||
|
important TYPE abap_bool,
|
||||||
|
text TYPE string,
|
||||||
|
END OF ty_log,
|
||||||
|
tt_log TYPE STANDARD TABLE OF ty_log WITH DEFAULT KEY.
|
||||||
|
|
||||||
|
CONSTANTS:
|
||||||
|
c_log_filename TYPE string VALUE '/',
|
||||||
|
c_log_path TYPE string VALUE 'changelog.txt'.
|
||||||
|
|
||||||
|
CLASS-METHODS create
|
||||||
|
IMPORTING io_repo TYPE REF TO lcl_repo
|
||||||
|
RETURNING VALUE(ro_instance) TYPE REF TO lcl_news.
|
||||||
|
|
||||||
|
METHODS:
|
||||||
|
constructor
|
||||||
|
IMPORTING iv_rawdata TYPE xstring
|
||||||
|
iv_version TYPE string,
|
||||||
|
has_news
|
||||||
|
RETURNING value(rv_boolean) TYPE abap_bool,
|
||||||
|
get_log
|
||||||
|
RETURNING value(rt_log) TYPE tt_log,
|
||||||
|
has_important_news
|
||||||
|
RETURNING value(rv_boolean) TYPE abap_bool.
|
||||||
|
|
||||||
|
PRIVATE SECTION.
|
||||||
|
DATA mt_log TYPE tt_log.
|
||||||
|
|
||||||
|
CLASS-METHODS:
|
||||||
|
split_string
|
||||||
|
IMPORTING iv_string TYPE string
|
||||||
|
RETURNING value(rt_lines) TYPE string_table,
|
||||||
|
|
||||||
|
convert_version_to_numeric
|
||||||
|
IMPORTING iv_version TYPE string
|
||||||
|
RETURNING value(rv_version) TYPE i,
|
||||||
|
|
||||||
|
parse_data
|
||||||
|
IMPORTING it_lines TYPE string_table
|
||||||
|
iv_version TYPE string
|
||||||
|
RETURNING value(rt_log) TYPE tt_log,
|
||||||
|
|
||||||
|
compare_versions
|
||||||
|
IMPORTING iv_a TYPE string
|
||||||
|
iv_b TYPE string
|
||||||
|
RETURNING value(rv_result) TYPE i.
|
||||||
|
|
||||||
|
ENDCLASS. "lcl_news
|
||||||
|
|
||||||
|
*----------------------------------------------------------------------*
|
||||||
|
* CLASS lcl_news IMPLEMENTATION
|
||||||
|
*----------------------------------------------------------------------*
|
||||||
|
*
|
||||||
|
*----------------------------------------------------------------------*
|
||||||
|
CLASS lcl_news IMPLEMENTATION.
|
||||||
|
|
||||||
|
METHOD constructor.
|
||||||
|
DATA:
|
||||||
|
lt_lines TYPE string_table,
|
||||||
|
lv_string TYPE string.
|
||||||
|
|
||||||
|
lv_string = lcl_convert=>xstring_to_string_utf8( iv_rawdata ).
|
||||||
|
lt_lines = lcl_news=>split_string( lv_string ).
|
||||||
|
mt_log = lcl_news=>parse_data( it_lines = lt_lines iv_version = iv_version ).
|
||||||
|
|
||||||
|
ENDMETHOD. "constructor
|
||||||
|
|
||||||
|
METHOD create.
|
||||||
|
|
||||||
|
DATA:
|
||||||
|
lt_remote TYPE ty_files_tt,
|
||||||
|
lo_repo_online TYPE REF TO lcl_repo_online.
|
||||||
|
|
||||||
|
FIELD-SYMBOLS <file> LIKE LINE OF lt_remote.
|
||||||
|
|
||||||
|
IF io_repo->is_offline( ) = abap_false.
|
||||||
|
lo_repo_online ?= io_repo.
|
||||||
|
|
||||||
|
" News announcement temporary restricted to abapGit only
|
||||||
|
IF lo_repo_online->get_url( ) CS '/abapGit.git'.
|
||||||
|
lt_remote = io_repo->get_files_remote( ).
|
||||||
|
|
||||||
|
READ TABLE lt_remote ASSIGNING <file> WITH KEY path = c_log_filename
|
||||||
|
filename = c_log_path.
|
||||||
|
IF sy-subrc = 0.
|
||||||
|
CREATE OBJECT ro_instance EXPORTING
|
||||||
|
iv_rawdata = <file>-data
|
||||||
|
iv_version = gc_abap_version.
|
||||||
|
ENDIF.
|
||||||
|
ENDIF.
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
ENDMETHOD. "create
|
||||||
|
|
||||||
|
METHOD split_string.
|
||||||
|
|
||||||
|
DATA ls_line LIKE LINE OF rt_lines.
|
||||||
|
|
||||||
|
FIND FIRST OCCURRENCE OF cl_abap_char_utilities=>cr_lf IN iv_string.
|
||||||
|
|
||||||
|
" Convert string into table depending on separator type CR_LF vs. LF
|
||||||
|
IF sy-subrc = 0.
|
||||||
|
SPLIT iv_string AT cl_abap_char_utilities=>cr_lf INTO TABLE rt_lines.
|
||||||
|
ELSE.
|
||||||
|
SPLIT iv_string AT cl_abap_char_utilities=>newline INTO TABLE rt_lines.
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
ENDMETHOD. "split_string
|
||||||
|
|
||||||
|
METHOD parse_data.
|
||||||
|
|
||||||
|
CONSTANTS:
|
||||||
|
lc_changelog_version TYPE string
|
||||||
|
VALUE '^\d{4}-\d{2}-\d{2}\s+v(\d{1,3}\.\d{1,3}\.\d{1,3})\s*$',
|
||||||
|
lc_internal_version TYPE string
|
||||||
|
VALUE '^v?(\d{1,3}\.\d{1,3}\.\d{1,3})\s*$'.
|
||||||
|
|
||||||
|
DATA:
|
||||||
|
lv_first_version_found TYPE abap_bool,
|
||||||
|
lv_version TYPE string,
|
||||||
|
lv_current_version TYPE string,
|
||||||
|
ls_log LIKE LINE OF rt_log.
|
||||||
|
|
||||||
|
FIELD-SYMBOLS: <line> LIKE LINE OF it_lines.
|
||||||
|
|
||||||
|
" Internal program version should be in format "vXXX.XXX.XXX"
|
||||||
|
FIND FIRST OCCURRENCE OF REGEX lc_internal_version IN iv_version SUBMATCHES lv_current_version.
|
||||||
|
|
||||||
|
IF sy-subrc IS NOT INITIAL.
|
||||||
|
RETURN. " Internal format of program version is not correct. TODO implement error message
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
LOOP AT it_lines ASSIGNING <line>.
|
||||||
|
CLEAR: lv_version, ls_log-text, ls_log-important, ls_log-header.
|
||||||
|
|
||||||
|
IF <line> IS INITIAL OR <line> CO ' -='. " Skip empty and technical lines
|
||||||
|
CONTINUE.
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
" Check if line is a header line
|
||||||
|
FIND FIRST OCCURRENCE OF REGEX lc_changelog_version IN <line> SUBMATCHES lv_version.
|
||||||
|
|
||||||
|
" Skip entries before first version found
|
||||||
|
IF lv_first_version_found = abap_false.
|
||||||
|
IF sy-subrc IS NOT INITIAL.
|
||||||
|
CONTINUE.
|
||||||
|
ELSE.
|
||||||
|
lv_first_version_found = abap_true.
|
||||||
|
ENDIF.
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
"Skip everything below current version
|
||||||
|
IF lv_version IS NOT INITIAL
|
||||||
|
AND lcl_news=>compare_versions( iv_a = lv_version iv_b = lv_current_version ) < 1.
|
||||||
|
EXIT.
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
" Populate log
|
||||||
|
IF lv_version IS NOT INITIAL. " Version header
|
||||||
|
ls_log-version = lv_version. " ... stays for all subsequent non-version lines
|
||||||
|
ls_log-header = abap_true.
|
||||||
|
ELSE. " Version line item
|
||||||
|
FIND FIRST OCCURRENCE OF REGEX '^\s*!' IN <line>.
|
||||||
|
IF sy-subrc IS INITIAL.
|
||||||
|
ls_log-important = abap_true. " Change is important
|
||||||
|
ENDIF.
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
ls_log-text = <line>.
|
||||||
|
|
||||||
|
APPEND ls_log TO rt_log.
|
||||||
|
ENDLOOP.
|
||||||
|
|
||||||
|
ENDMETHOD. "parse_data
|
||||||
|
|
||||||
|
METHOD has_news.
|
||||||
|
|
||||||
|
rv_boolean = boolc( lines( mt_log ) > 0 ).
|
||||||
|
|
||||||
|
ENDMETHOD. "has_news
|
||||||
|
|
||||||
|
METHOD get_log.
|
||||||
|
|
||||||
|
rt_log = me->mt_log.
|
||||||
|
|
||||||
|
ENDMETHOD. "get_log
|
||||||
|
|
||||||
|
METHOD has_important_news.
|
||||||
|
|
||||||
|
READ TABLE mt_log WITH KEY important = abap_true TRANSPORTING NO FIELDS.
|
||||||
|
|
||||||
|
rv_boolean = boolc( sy-subrc IS INITIAL ).
|
||||||
|
|
||||||
|
ENDMETHOD. "has_important_news
|
||||||
|
|
||||||
|
METHOD compare_versions.
|
||||||
|
|
||||||
|
DATA:
|
||||||
|
lv_version_a TYPE i,
|
||||||
|
lv_version_b TYPE i.
|
||||||
|
|
||||||
|
" Convert versions to numeric
|
||||||
|
lv_version_a = lcl_news=>convert_version_to_numeric( iv_a ).
|
||||||
|
lv_version_b = lcl_news=>convert_version_to_numeric( iv_b ).
|
||||||
|
|
||||||
|
" Compare versions
|
||||||
|
IF lv_version_a > lv_version_b.
|
||||||
|
rv_result = 1.
|
||||||
|
ELSEIF lv_version_a < lv_version_b.
|
||||||
|
rv_result = -1.
|
||||||
|
ELSE.
|
||||||
|
rv_result = 0.
|
||||||
|
ENDIF.
|
||||||
|
|
||||||
|
ENDMETHOD. "compare_versions
|
||||||
|
|
||||||
|
METHOD convert_version_to_numeric.
|
||||||
|
|
||||||
|
DATA: lv_major TYPE numc4,
|
||||||
|
lv_minor TYPE numc4,
|
||||||
|
lv_release TYPE numc4.
|
||||||
|
|
||||||
|
SPLIT iv_version AT '.' INTO lv_major lv_minor lv_release.
|
||||||
|
|
||||||
|
" Calculated value of version number
|
||||||
|
rv_version = lv_major * 1000000 + lv_minor * 1000 + lv_release.
|
||||||
|
|
||||||
|
ENDMETHOD. "convert_version_to_numeric
|
||||||
|
|
||||||
|
ENDCLASS. "lcl_news
|
||||||
|
|
||||||
|
*----------------------------------------------------------------------*
|
||||||
|
* CLASS ltcl_news DEFINITION
|
||||||
|
*----------------------------------------------------------------------*
|
||||||
|
* Definition of test class for news announcement
|
||||||
|
*----------------------------------------------------------------------*
|
||||||
|
CLASS ltcl_news DEFINITION FINAL
|
||||||
|
FOR TESTING RISK LEVEL HARMLESS DURATION SHORT.
|
||||||
|
|
||||||
|
PRIVATE SECTION.
|
||||||
|
|
||||||
|
METHODS:
|
||||||
|
split_string FOR TESTING,
|
||||||
|
convert_version_to_numeric FOR TESTING,
|
||||||
|
compare_versions FOR TESTING,
|
||||||
|
parse_data FOR TESTING.
|
||||||
|
|
||||||
|
ENDCLASS. "ltcl_news DEFINITION
|
||||||
|
|
||||||
|
*----------------------------------------------------------------------*
|
||||||
|
* CLASS ltcl_news IMPLEMENTATION
|
||||||
|
*----------------------------------------------------------------------*
|
||||||
|
* Implementation of test class for news announcement
|
||||||
|
*----------------------------------------------------------------------*
|
||||||
|
CLASS ltcl_news IMPLEMENTATION.
|
||||||
|
|
||||||
|
METHOD split_string.
|
||||||
|
|
||||||
|
DATA: lt_act TYPE string_table,
|
||||||
|
lt_exp TYPE string_table.
|
||||||
|
|
||||||
|
APPEND 'ABC' TO lt_exp.
|
||||||
|
APPEND '123' TO lt_exp.
|
||||||
|
|
||||||
|
" Case 1. String separated by CRLF
|
||||||
|
lt_act = lcl_news=>split_string( 'ABC' && cl_abap_char_utilities=>cr_lf && '123' ).
|
||||||
|
|
||||||
|
cl_abap_unit_assert=>assert_equals( exp = lt_exp
|
||||||
|
act = lt_act
|
||||||
|
msg = ' Error during string split: CRLF' ).
|
||||||
|
|
||||||
|
CLEAR: lt_act.
|
||||||
|
|
||||||
|
" Case 2. String separated by LF
|
||||||
|
lt_act = lcl_news=>split_string( 'ABC' && cl_abap_char_utilities=>newline && '123' ).
|
||||||
|
|
||||||
|
cl_abap_unit_assert=>assert_equals( exp = lt_exp
|
||||||
|
act = lt_act
|
||||||
|
msg = ' Error during string split: LF' ).
|
||||||
|
|
||||||
|
ENDMETHOD. "split_string.
|
||||||
|
|
||||||
|
METHOD convert_version_to_numeric.
|
||||||
|
|
||||||
|
DATA: lv_version_exp TYPE i VALUE 1023010,
|
||||||
|
lv_version_act TYPE i.
|
||||||
|
|
||||||
|
lv_version_act = lcl_news=>convert_version_to_numeric( '1.23.10' ).
|
||||||
|
|
||||||
|
cl_abap_unit_assert=>assert_equals( exp = lv_version_exp
|
||||||
|
act = lv_version_act
|
||||||
|
msg = ' Error during conversion of version to numeric value' ).
|
||||||
|
|
||||||
|
ENDMETHOD. "convert_version_to_numeric
|
||||||
|
|
||||||
|
METHOD compare_versions.
|
||||||
|
|
||||||
|
DATA lv_result TYPE i.
|
||||||
|
|
||||||
|
" Case 1: version A > version B
|
||||||
|
lv_result = lcl_news=>compare_versions( iv_a = '1.28.10' iv_b = '1.23.10' ).
|
||||||
|
|
||||||
|
cl_abap_unit_assert=>assert_equals( exp = 1
|
||||||
|
act = lv_result
|
||||||
|
msg = ' Error during comparison of versions. Case: A > B' ).
|
||||||
|
|
||||||
|
CLEAR: lv_result.
|
||||||
|
|
||||||
|
" Case 2: version A < version B
|
||||||
|
lv_result = lcl_news=>compare_versions( iv_a = '1.28.10' iv_b = '2.23.10' ).
|
||||||
|
|
||||||
|
cl_abap_unit_assert=>assert_equals( exp = -1
|
||||||
|
act = lv_result
|
||||||
|
msg = ' Error during comparison of versions. Case: A < B' ).
|
||||||
|
|
||||||
|
CLEAR: lv_result.
|
||||||
|
|
||||||
|
" Case 3: version A = version B
|
||||||
|
lv_result = lcl_news=>compare_versions( iv_a = '1.28.10' iv_b = '1.28.10' ).
|
||||||
|
|
||||||
|
cl_abap_unit_assert=>assert_equals( exp = 0
|
||||||
|
act = lv_result
|
||||||
|
msg = ' Error during comparison of versions. Case: A = B' ).
|
||||||
|
|
||||||
|
ENDMETHOD. "compare_versions
|
||||||
|
|
||||||
|
DEFINE _add_news_log_entry.
|
||||||
|
CLEAR: ls_log.
|
||||||
|
ls_log-version = &1.
|
||||||
|
ls_log-header = &2.
|
||||||
|
ls_log-important = &3.
|
||||||
|
ls_log-text = &4.
|
||||||
|
APPEND ls_log TO lt_log_exp.
|
||||||
|
END-OF-DEFINITION.
|
||||||
|
|
||||||
|
METHOD parse_data.
|
||||||
|
|
||||||
|
DATA:
|
||||||
|
lt_log_exp TYPE lcl_news=>tt_log,
|
||||||
|
lt_log_act TYPE lcl_news=>tt_log,
|
||||||
|
ls_log LIKE LINE OF lt_log_exp,
|
||||||
|
lt_lines TYPE string_table.
|
||||||
|
|
||||||
|
" Generate test data
|
||||||
|
APPEND '======' TO lt_lines.
|
||||||
|
APPEND '------' TO lt_lines.
|
||||||
|
APPEND ' ' TO lt_lines.
|
||||||
|
APPEND 'abapGit changelog' TO lt_lines.
|
||||||
|
APPEND '2017-02-13 v1.28.0' TO lt_lines.
|
||||||
|
APPEND '------------------' TO lt_lines.
|
||||||
|
APPEND '+ Staging page redesigned' TO lt_lines.
|
||||||
|
APPEND '! Support for core data services' TO lt_lines.
|
||||||
|
APPEND ' ' TO lt_lines.
|
||||||
|
APPEND '2017-01-25 v1.27.0' TO lt_lines.
|
||||||
|
APPEND '------------------' TO lt_lines.
|
||||||
|
APPEND '+ Two factor authentication with github.com' TO lt_lines.
|
||||||
|
APPEND '2017-01-25 v1.26.0' TO lt_lines.
|
||||||
|
|
||||||
|
" Generate expected results
|
||||||
|
_add_news_log_entry '1.28.0' 'X' '' '2017-02-13 v1.28.0'.
|
||||||
|
_add_news_log_entry '1.28.0' '' '' '+ Staging page redesigned'.
|
||||||
|
_add_news_log_entry '1.28.0' '' 'X' '! Support for core data services'.
|
||||||
|
_add_news_log_entry '1.27.0' 'X' '' '2017-01-25 v1.27.0'.
|
||||||
|
_add_news_log_entry '1.27.0' '' '' '+ Two factor authentication with github.com'.
|
||||||
|
|
||||||
|
" Case 1. Test parsing of data
|
||||||
|
lt_log_act = lcl_news=>parse_data( it_lines = lt_lines iv_version = '1.26.01' ).
|
||||||
|
|
||||||
|
cl_abap_unit_assert=>assert_equals( exp = lt_log_exp
|
||||||
|
act = lt_log_act
|
||||||
|
msg = ' Error during parsing: Case 1.' ).
|
||||||
|
|
||||||
|
CLEAR: lt_log_act, lt_log_exp.
|
||||||
|
|
||||||
|
" Case 2. Negative test - format of version is not correct
|
||||||
|
lt_log_act = lcl_news=>parse_data( it_lines = lt_lines iv_version = 'version.1.27.00' ).
|
||||||
|
|
||||||
|
cl_abap_unit_assert=>assert_equals( exp = lt_log_exp
|
||||||
|
act = lt_log_act
|
||||||
|
msg = ' Error during parsing: Case 2.' ).
|
||||||
|
|
||||||
|
ENDMETHOD. "parse_data
|
||||||
|
|
||||||
|
ENDCLASS. "ltcl_news IMPLEMENTATION
|
23
src/zabapgit_news.prog.xml
Normal file
23
src/zabapgit_news.prog.xml
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<abapGit version="v1.0.0" serializer="LCL_OBJECT_PROG" serializer_version="v1.0.0">
|
||||||
|
<asx:abap xmlns:asx="http://www.sap.com/abapxml" version="1.0">
|
||||||
|
<asx:values>
|
||||||
|
<PROGDIR>
|
||||||
|
<NAME>ZABAPGIT_NEWS</NAME>
|
||||||
|
<STATE>A</STATE>
|
||||||
|
<VARCL>X</VARCL>
|
||||||
|
<SUBC>I</SUBC>
|
||||||
|
<RSTAT>K</RSTAT>
|
||||||
|
<RLOAD>E</RLOAD>
|
||||||
|
<UCCHECK>X</UCCHECK>
|
||||||
|
</PROGDIR>
|
||||||
|
<TPOOL>
|
||||||
|
<item>
|
||||||
|
<ID>R</ID>
|
||||||
|
<ENTRY>Include ZABAPGIT_NEWS</ENTRY>
|
||||||
|
<LENGTH>21</LENGTH>
|
||||||
|
</item>
|
||||||
|
</TPOOL>
|
||||||
|
</asx:values>
|
||||||
|
</asx:abap>
|
||||||
|
</abapGit>
|
|
@ -303,11 +303,19 @@ CLASS lcl_gui_page_main IMPLEMENTATION.
|
||||||
|
|
||||||
METHOD render_repo.
|
METHOD render_repo.
|
||||||
|
|
||||||
|
DATA lo_news TYPE REF TO lcl_news.
|
||||||
|
|
||||||
CREATE OBJECT ro_html.
|
CREATE OBJECT ro_html.
|
||||||
|
|
||||||
|
lo_news = lcl_news=>create( io_repo ).
|
||||||
|
|
||||||
ro_html->add( |<div class="repo" id="repo{ io_repo->get_key( ) }">| ).
|
ro_html->add( |<div class="repo" id="repo{ io_repo->get_key( ) }">| ).
|
||||||
ro_html->add( lcl_gui_chunk_lib=>render_repo_top( io_repo = io_repo
|
ro_html->add( lcl_gui_chunk_lib=>render_repo_top( io_repo = io_repo
|
||||||
|
io_news = lo_news
|
||||||
iv_interactive_branch = abap_true ) ).
|
iv_interactive_branch = abap_true ) ).
|
||||||
|
|
||||||
|
ro_html->add( lcl_gui_chunk_lib=>render_news( io_news = lo_news ) ).
|
||||||
|
|
||||||
ro_html->add( mo_repo_content->render( ) ).
|
ro_html->add( mo_repo_content->render( ) ).
|
||||||
ro_html->add( '</div>' ).
|
ro_html->add( '</div>' ).
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user