CLASS {{p}}t02_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC FOR TESTING DURATION SHORT RISK LEVEL HARMLESS. PRIVATE SECTION. TYPES ty_cost TYPE p LENGTH 15 DECIMALS 2. TYPES ty_currency TYPE c LENGTH 5. TYPES ty_zone_code TYPE c LENGTH 4. TYPES ty_weight TYPE p LENGTH 15 DECIMALS 3. DATA mo_cut TYPE REF TO {{p}}freight_calc. METHODS setup. METHODS calculate_result IMPORTING iv_zone_code TYPE ty_zone_code iv_weight_kg TYPE ty_weight iv_express TYPE abap_bool DEFAULT abap_false RETURNING VALUE(rs_result) TYPE {{p}}freight_calc=>ty_result. METHODS assert_cost IMPORTING iv_cost TYPE ty_cost iv_currency TYPE ty_currency is_result TYPE {{p}}freight_calc=>ty_result. METHODS assert_weight IMPORTING iv_expected TYPE ty_weight iv_actual TYPE ty_weight iv_msg TYPE string. METHODS standard_cost FOR TESTING. METHODS express_surcharge FOR TESTING. METHODS express_no_early_rounding FOR TESTING. METHODS minimum_charge FOR TESTING. METHODS rounding FOR TESTING. METHODS zone_code_normalized FOR TESTING. METHODS weight_at_limit FOR TESTING. METHODS unknown_zone FOR TESTING. METHODS invalid_weight FOR TESTING. METHODS weight_limit FOR TESTING. METHODS weight_check_before_zone_lookup FOR TESTING. ENDCLASS. CLASS {{p}}t02_hidden IMPLEMENTATION. METHOD setup. mo_cut = NEW {{p}}freight_calc( ). ENDMETHOD. METHOD calculate_result. TRY. rs_result = mo_cut->calculate( iv_zone_code = iv_zone_code iv_weight_kg = iv_weight_kg iv_express = iv_express ). CATCH {{p}}cx_freight_error INTO DATA(lo_error). cl_abap_unit_assert=>fail( msg = lo_error->get_reason_text( ) ). ENDTRY. ENDMETHOD. METHOD assert_cost. cl_abap_unit_assert=>assert_equals( exp = iv_cost act = is_result-cost msg = 'cost' ). cl_abap_unit_assert=>assert_equals( exp = iv_currency act = is_result-currency msg = 'currency' ). ENDMETHOD. METHOD assert_weight. cl_abap_unit_assert=>assert_equals( exp = iv_expected act = iv_actual msg = iv_msg ). ENDMETHOD. METHOD standard_cost. DATA(ls_result) = calculate_result( iv_zone_code = 'DE01' iv_weight_kg = '10.000' ). assert_cost( iv_cost = '17.00' iv_currency = 'EUR' is_result = ls_result ). ENDMETHOD. METHOD express_surcharge. DATA(ls_result) = calculate_result( iv_zone_code = 'DE01' iv_weight_kg = '10.000' iv_express = abap_true ). assert_cost( iv_cost = '25.50' iv_currency = 'EUR' is_result = ls_result ). ENDMETHOD. METHOD express_no_early_rounding. DATA(ls_result) = calculate_result( iv_zone_code = 'DE01' iv_weight_kg = '10.004' iv_express = abap_true ). assert_cost( iv_cost = '25.51' iv_currency = 'EUR' is_result = ls_result ). ENDMETHOD. METHOD minimum_charge. DATA(ls_result) = calculate_result( iv_zone_code = 'DE01' iv_weight_kg = '0.500' ). assert_cost( iv_cost = '6.00' iv_currency = 'EUR' is_result = ls_result ). ENDMETHOD. METHOD rounding. DATA(ls_result) = calculate_result( iv_zone_code = 'FR01' iv_weight_kg = '1.234' ). assert_cost( iv_cost = '12.09' iv_currency = 'EUR' is_result = ls_result ). ENDMETHOD. METHOD zone_code_normalized. DATA(ls_result) = calculate_result( iv_zone_code = 'de01' iv_weight_kg = '10.000' ). assert_cost( iv_cost = '17.00' iv_currency = 'EUR' is_result = ls_result ). ENDMETHOD. METHOD weight_at_limit. DATA(ls_result) = calculate_result( iv_zone_code = 'CN01' iv_weight_kg = '20.000' ). assert_cost( iv_cost = '103.00' iv_currency = 'CNY' is_result = ls_result ). ENDMETHOD. METHOD unknown_zone. TRY. mo_cut->calculate( iv_zone_code = 'xx99' iv_weight_kg = '1.000' ). cl_abap_unit_assert=>fail( msg = 'CX_UNKNOWN_ZONE expected' ). CATCH {{p}}cx_unknown_zone INTO DATA(lo_unknown). cl_abap_unit_assert=>assert_equals( exp = 'XX99' act = lo_unknown->mv_zone_code ). cl_abap_unit_assert=>assert_equals( exp = `Zone XX99 is not known` act = lo_unknown->get_reason_text( ) ). CATCH {{p}}cx_freight_error INTO DATA(lo_other). cl_abap_unit_assert=>fail( msg = |Wrong exception class: { lo_other->get_reason_text( ) }| ). ENDTRY. ENDMETHOD. METHOD invalid_weight. TRY. mo_cut->calculate( iv_zone_code = 'DE01' iv_weight_kg = '0.000' ). cl_abap_unit_assert=>fail( msg = 'CX_INVALID_WEIGHT expected' ). CATCH {{p}}cx_invalid_weight INTO DATA(lo_invalid). assert_weight( iv_expected = '0.000' iv_actual = lo_invalid->mv_weight_kg iv_msg = 'weight' ). cl_abap_unit_assert=>assert_equals( exp = 'DE01' act = lo_invalid->mv_zone_code ). cl_abap_unit_assert=>assert_equals( exp = `Weight must be greater than zero` act = lo_invalid->get_reason_text( ) ). CATCH {{p}}cx_freight_error INTO DATA(lo_other). cl_abap_unit_assert=>fail( msg = |Wrong exception class: { lo_other->get_reason_text( ) }| ). ENDTRY. ENDMETHOD. METHOD weight_limit. TRY. mo_cut->calculate( iv_zone_code = 'CN01' iv_weight_kg = '20.001' ). cl_abap_unit_assert=>fail( msg = 'CX_WEIGHT_LIMIT expected' ). CATCH {{p}}cx_weight_limit INTO DATA(lo_limit). assert_weight( iv_expected = '20.001' iv_actual = lo_limit->mv_weight_kg iv_msg = 'weight' ). cl_abap_unit_assert=>assert_equals( exp = 20 act = lo_limit->mv_max_weight_kg msg = 'max weight' ). cl_abap_unit_assert=>assert_equals( exp = 'CN01' act = lo_limit->mv_zone_code ). cl_abap_unit_assert=>assert_equals( exp = `Weight exceeds the zone limit` act = lo_limit->get_reason_text( ) ). CATCH {{p}}cx_freight_error INTO DATA(lo_other). cl_abap_unit_assert=>fail( msg = |Wrong exception class: { lo_other->get_reason_text( ) }| ). ENDTRY. ENDMETHOD. METHOD weight_check_before_zone_lookup. TRY. mo_cut->calculate( iv_zone_code = 'ZZZZ' iv_weight_kg = '0.000' ). cl_abap_unit_assert=>fail( msg = 'CX_INVALID_WEIGHT expected' ). CATCH {{p}}cx_invalid_weight INTO DATA(lo_invalid). cl_abap_unit_assert=>assert_equals( exp = 'ZZZZ' act = lo_invalid->mv_zone_code ). CATCH {{p}}cx_freight_error INTO DATA(lo_other). cl_abap_unit_assert=>fail( msg = |Wrong exception class: { lo_other->get_reason_text( ) }| ). ENDTRY. ENDMETHOD. ENDCLASS.