mirror of
https://github.com/abapGit/abapGit.git
synced 2025-05-02 04:36:49 +08:00
380 lines
11 KiB
ABAP
380 lines
11 KiB
ABAP
**********************************************************************
|
|
* UTIL
|
|
**********************************************************************
|
|
|
|
CLASS lcl_nodes_helper DEFINITION FINAL.
|
|
PUBLIC SECTION.
|
|
|
|
DATA mt_nodes TYPE zif_abapgit_ajson=>ty_nodes_tt READ-ONLY.
|
|
|
|
METHODS add
|
|
IMPORTING
|
|
iv_str TYPE string.
|
|
METHODS sorted
|
|
RETURNING
|
|
VALUE(rt_nodes) TYPE zif_abapgit_ajson=>ty_nodes_ts.
|
|
|
|
ENDCLASS.
|
|
|
|
CLASS lcl_nodes_helper IMPLEMENTATION.
|
|
METHOD add.
|
|
|
|
FIELD-SYMBOLS <n> LIKE LINE OF mt_nodes.
|
|
DATA lv_children TYPE string.
|
|
DATA lv_index TYPE string.
|
|
|
|
APPEND INITIAL LINE TO mt_nodes ASSIGNING <n>.
|
|
|
|
SPLIT iv_str AT '|' INTO
|
|
<n>-path
|
|
<n>-name
|
|
<n>-type
|
|
<n>-value
|
|
lv_index
|
|
lv_children.
|
|
CONDENSE <n>-path.
|
|
CONDENSE <n>-name.
|
|
CONDENSE <n>-type.
|
|
CONDENSE <n>-value.
|
|
<n>-index = lv_index.
|
|
<n>-children = lv_children.
|
|
|
|
ENDMETHOD.
|
|
|
|
METHOD sorted.
|
|
rt_nodes = mt_nodes.
|
|
ENDMETHOD.
|
|
ENDCLASS.
|
|
|
|
**********************************************************************
|
|
* PARSER
|
|
**********************************************************************
|
|
|
|
CLASS ltcl_parser_test DEFINITION FINAL
|
|
FOR TESTING
|
|
RISK LEVEL HARMLESS
|
|
DURATION SHORT.
|
|
|
|
PUBLIC SECTION.
|
|
|
|
CLASS-METHODS sample_json
|
|
IMPORTING
|
|
iv_separator TYPE string OPTIONAL
|
|
RETURNING
|
|
VALUE(rv_json) TYPE string.
|
|
|
|
ENDCLASS.
|
|
|
|
CLASS ltcl_parser_test IMPLEMENTATION.
|
|
|
|
METHOD sample_json.
|
|
|
|
rv_json =
|
|
'{\n' &&
|
|
' "string": "abc",\n' &&
|
|
' "number": 123,\n' &&
|
|
' "float": 123.45,\n' &&
|
|
' "boolean": true,\n' &&
|
|
' "false": false,\n' &&
|
|
' "null": null,\n' &&
|
|
' "date": "2020-03-15",\n' &&
|
|
' "issues": [\n' &&
|
|
' {\n' &&
|
|
' "message": "Indentation problem ...",\n' &&
|
|
' "key": "indentation",\n' &&
|
|
' "start": {\n' &&
|
|
' "row": 4,\n' &&
|
|
' "col": 3\n' &&
|
|
' },\n' &&
|
|
' "end": {\n' &&
|
|
' "row": 4,\n' &&
|
|
' "col": 26\n' &&
|
|
' },\n' &&
|
|
' "filename": "./zxxx.prog.abap"\n' &&
|
|
' },\n' &&
|
|
' {\n' &&
|
|
' "message": "Remove space before XXX",\n' &&
|
|
' "key": "space_before_dot",\n' &&
|
|
' "start": {\n' &&
|
|
' "row": 3,\n' &&
|
|
' "col": 21\n' &&
|
|
' },\n' &&
|
|
' "end": {\n' &&
|
|
' "row": 3,\n' &&
|
|
' "col": 22\n' &&
|
|
' },\n' &&
|
|
' "filename": "./zxxx.prog.abap"\n' &&
|
|
' }\n' &&
|
|
' ]\n' &&
|
|
'}'.
|
|
|
|
REPLACE ALL OCCURRENCES OF '\n' IN rv_json WITH iv_separator.
|
|
|
|
ENDMETHOD.
|
|
|
|
ENDCLASS.
|
|
|
|
**********************************************************************
|
|
* JSON UTILITIES
|
|
**********************************************************************
|
|
|
|
CLASS ltcl_json_utils DEFINITION
|
|
FOR TESTING
|
|
RISK LEVEL HARMLESS
|
|
DURATION SHORT
|
|
FINAL.
|
|
|
|
PRIVATE SECTION.
|
|
|
|
METHODS json_diff FOR TESTING RAISING zcx_abapgit_ajson_error.
|
|
METHODS json_diff_types FOR TESTING RAISING zcx_abapgit_ajson_error.
|
|
METHODS json_sort FOR TESTING RAISING zcx_abapgit_ajson_error.
|
|
|
|
ENDCLASS.
|
|
|
|
CLASS ltcl_json_utils IMPLEMENTATION.
|
|
|
|
METHOD json_diff.
|
|
|
|
DATA:
|
|
lv_json TYPE string,
|
|
lo_util TYPE REF TO zcl_abapgit_ajson_utilities,
|
|
lo_insert TYPE REF TO zif_abapgit_ajson,
|
|
lo_delete TYPE REF TO zif_abapgit_ajson,
|
|
lo_change TYPE REF TO zif_abapgit_ajson,
|
|
lo_insert_exp TYPE REF TO lcl_nodes_helper,
|
|
lo_delete_exp TYPE REF TO lcl_nodes_helper,
|
|
lo_change_exp TYPE REF TO lcl_nodes_helper.
|
|
|
|
lv_json =
|
|
'{\n' &&
|
|
' "string": "abc",\n' && " no changes
|
|
' "number": 789,\n' && " changed value
|
|
' "float": 123.45,\n' &&
|
|
' "boolean": "true",\n' && " changed type
|
|
' "true": true,\n' && " insert
|
|
* ' "false": false,\n' && " delete
|
|
' "null": null,\n' &&
|
|
' "date": "2020-03-15",\n' &&
|
|
' "issues": [\n' &&
|
|
' {\n' &&
|
|
' "message": "Indentation problem ...",\n' &&
|
|
' "key": "indentation",\n' &&
|
|
' "start": {\n' &&
|
|
' "row": 5,\n' && " array change
|
|
' "col": 3\n' &&
|
|
' },\n' &&
|
|
' "end": {\n' &&
|
|
' "new": 1,\n' && " array insert
|
|
* ' "row": 4,\n' && " array delete
|
|
' "col": 26\n' &&
|
|
' },\n' &&
|
|
' "filename": "./zxxx.prog.abap"\n' &&
|
|
' },\n' &&
|
|
' {\n' &&
|
|
' "message": "Remove space before XXX",\n' &&
|
|
' "key": "space_before_dot",\n' &&
|
|
' "start": {\n' &&
|
|
' "row": 3,\n' &&
|
|
' "col": 21\n' &&
|
|
' },\n' &&
|
|
' "end": {\n' &&
|
|
' "row": 3,\n' &&
|
|
' "col": 22\n' &&
|
|
' },\n' &&
|
|
' "filename": "./zxxx.prog.abap"\n' &&
|
|
' }\n' &&
|
|
' ]\n' &&
|
|
'}'.
|
|
|
|
REPLACE ALL OCCURRENCES OF '\n' IN lv_json WITH cl_abap_char_utilities=>newline.
|
|
|
|
CREATE OBJECT lo_insert_exp.
|
|
lo_insert_exp->add( ' | |object | |0|3' ).
|
|
lo_insert_exp->add( '/ |boolean |str |true |0|0' ). " changed type (insert new)
|
|
lo_insert_exp->add( '/ |issues |array | |0|1' ).
|
|
lo_insert_exp->add( '/ |true |bool |true |0|0' ). " insert
|
|
lo_insert_exp->add( '/issues/ |1 |object | |1|1' ).
|
|
lo_insert_exp->add( '/issues/1/ |end |object | |0|1' ).
|
|
lo_insert_exp->add( '/issues/1/end/ |new |num |1 |0|0' ). " array insert
|
|
|
|
CREATE OBJECT lo_delete_exp.
|
|
lo_delete_exp->add( ' | |object | |0|3' ).
|
|
lo_delete_exp->add( '/ |boolean |bool |true |0|0' ). " changed type (delete old)
|
|
lo_delete_exp->add( '/ |false |bool |false |0|0' ). " delete
|
|
lo_delete_exp->add( '/ |issues |array | |0|1' ).
|
|
lo_delete_exp->add( '/issues/ |1 |object | |1|1' ).
|
|
lo_delete_exp->add( '/issues/1/ |end |object | |0|1' ).
|
|
lo_delete_exp->add( '/issues/1/end/ |row |num |4 |0|0' ). " array delete
|
|
|
|
CREATE OBJECT lo_change_exp.
|
|
lo_change_exp->add( ' | |object | |0|2' ).
|
|
lo_change_exp->add( '/ |issues |array | |0|1' ).
|
|
lo_change_exp->add( '/ |number |num |789 |0|0' ). " changed value
|
|
lo_change_exp->add( '/issues/ |1 |object | |1|1' ).
|
|
lo_change_exp->add( '/issues/1/ |start |object | |0|1' ).
|
|
lo_change_exp->add( '/issues/1/start/|row |num |5 |0|0' ). " array change
|
|
|
|
CREATE OBJECT lo_util.
|
|
|
|
lo_util->diff(
|
|
EXPORTING
|
|
iv_json_a = ltcl_parser_test=>sample_json( )
|
|
iv_json_b = lv_json
|
|
IMPORTING
|
|
eo_insert = lo_insert
|
|
eo_delete = lo_delete
|
|
eo_change = lo_change ).
|
|
|
|
cl_abap_unit_assert=>assert_equals(
|
|
act = lo_insert->mt_json_tree
|
|
exp = lo_insert_exp->mt_nodes ).
|
|
|
|
cl_abap_unit_assert=>assert_equals(
|
|
act = lo_delete->mt_json_tree
|
|
exp = lo_delete_exp->mt_nodes ).
|
|
|
|
cl_abap_unit_assert=>assert_equals(
|
|
act = lo_change->mt_json_tree
|
|
exp = lo_change_exp->mt_nodes ).
|
|
|
|
ENDMETHOD.
|
|
|
|
METHOD json_diff_types.
|
|
|
|
DATA:
|
|
lv_json_a TYPE string,
|
|
lv_json_b TYPE string,
|
|
lo_util TYPE REF TO zcl_abapgit_ajson_utilities,
|
|
lo_insert TYPE REF TO zif_abapgit_ajson,
|
|
lo_delete TYPE REF TO zif_abapgit_ajson,
|
|
lo_change TYPE REF TO zif_abapgit_ajson,
|
|
lo_insert_exp TYPE REF TO lcl_nodes_helper,
|
|
lo_delete_exp TYPE REF TO lcl_nodes_helper.
|
|
|
|
" Change single value to array
|
|
lv_json_a =
|
|
'{\n' &&
|
|
' "string": "abc",\n' &&
|
|
' "number": 123\n' &&
|
|
'}'.
|
|
|
|
lv_json_b =
|
|
'{\n' &&
|
|
' "string": [\n' &&
|
|
' "a",\n' &&
|
|
' "b",\n' &&
|
|
' "c"\n' &&
|
|
' ],\n' &&
|
|
' "number": 123\n' &&
|
|
'}'.
|
|
|
|
REPLACE ALL OCCURRENCES OF '\n' IN lv_json_a WITH cl_abap_char_utilities=>newline.
|
|
REPLACE ALL OCCURRENCES OF '\n' IN lv_json_b WITH cl_abap_char_utilities=>newline.
|
|
|
|
CREATE OBJECT lo_insert_exp.
|
|
lo_insert_exp->add( ' | |object | |0|1' ).
|
|
lo_insert_exp->add( '/ |string |array | |0|3' ).
|
|
lo_insert_exp->add( '/string/ |1 |str |a |1|0' ).
|
|
lo_insert_exp->add( '/string/ |2 |str |b |2|0' ).
|
|
lo_insert_exp->add( '/string/ |3 |str |c |3|0' ).
|
|
|
|
CREATE OBJECT lo_delete_exp.
|
|
lo_delete_exp->add( ' | |object | |0|1' ).
|
|
lo_delete_exp->add( '/ |string |str |abc |0|0' ).
|
|
|
|
CREATE OBJECT lo_util.
|
|
|
|
lo_util->diff(
|
|
EXPORTING
|
|
iv_json_a = lv_json_a
|
|
iv_json_b = lv_json_b
|
|
IMPORTING
|
|
eo_insert = lo_insert
|
|
eo_delete = lo_delete
|
|
eo_change = lo_change ).
|
|
|
|
cl_abap_unit_assert=>assert_equals(
|
|
act = lo_insert->mt_json_tree
|
|
exp = lo_insert_exp->mt_nodes ).
|
|
|
|
cl_abap_unit_assert=>assert_equals(
|
|
act = lo_delete->mt_json_tree
|
|
exp = lo_delete_exp->mt_nodes ).
|
|
|
|
cl_abap_unit_assert=>assert_equals(
|
|
act = lines( lo_change->mt_json_tree )
|
|
exp = 0 ).
|
|
|
|
" Change array to single value
|
|
lo_util->diff(
|
|
EXPORTING
|
|
iv_json_a = lv_json_b
|
|
iv_json_b = lv_json_a
|
|
IMPORTING
|
|
eo_insert = lo_insert
|
|
eo_delete = lo_delete
|
|
eo_change = lo_change ).
|
|
|
|
cl_abap_unit_assert=>assert_equals(
|
|
act = lo_insert->mt_json_tree
|
|
exp = lo_delete_exp->mt_nodes ).
|
|
|
|
cl_abap_unit_assert=>assert_equals(
|
|
act = lo_delete->mt_json_tree
|
|
exp = lo_insert_exp->mt_nodes ).
|
|
|
|
cl_abap_unit_assert=>assert_equals(
|
|
act = lines( lo_change->mt_json_tree )
|
|
exp = 0 ).
|
|
|
|
ENDMETHOD.
|
|
|
|
METHOD json_sort.
|
|
|
|
DATA:
|
|
lv_json TYPE string,
|
|
lo_util TYPE REF TO zcl_abapgit_ajson_utilities,
|
|
lv_sorted TYPE string,
|
|
lv_sorted_exp TYPE string.
|
|
|
|
lv_json =
|
|
'{\n' &&
|
|
' "string": "abc",\n' &&
|
|
' "number": 789,\n' &&
|
|
' "float": 123.45,\n' &&
|
|
' "boolean": "true",\n' &&
|
|
' "true": true,\n' &&
|
|
' "false": false,\n' &&
|
|
' "null": null,\n' &&
|
|
' "date": "2020-03-15"\n' &&
|
|
'}'.
|
|
|
|
REPLACE ALL OCCURRENCES OF '\n' IN lv_json WITH cl_abap_char_utilities=>newline.
|
|
|
|
lv_sorted_exp =
|
|
'{\n' &&
|
|
' "boolean": "true",\n' &&
|
|
' "date": "2020-03-15",\n' &&
|
|
' "false": false,\n' &&
|
|
' "float": 123.45,\n' &&
|
|
' "null": null,\n' &&
|
|
' "number": 789,\n' &&
|
|
' "string": "abc",\n' &&
|
|
' "true": true\n' &&
|
|
'}'.
|
|
|
|
REPLACE ALL OCCURRENCES OF '\n' IN lv_sorted_exp WITH cl_abap_char_utilities=>newline.
|
|
|
|
CREATE OBJECT lo_util.
|
|
|
|
lv_sorted = lo_util->sort( iv_json = lv_json ).
|
|
|
|
cl_abap_unit_assert=>assert_equals(
|
|
act = lv_sorted
|
|
exp = lv_sorted_exp ).
|
|
|
|
ENDMETHOD.
|
|
|
|
ENDCLASS.
|