class ZCL_CALCULATOR definition public create public . *"* public components of class ZCL_CALCULATOR *"* do not include other source files here!!! public section. constants PLUS type CHAR1 value '+'. "#EC NOTEXT constants SUBTRACTION type CHAR1 value '-'. "#EC NOTEXT constants MULTIPLICATION type CHAR1 value '*'. "#EC NOTEXT constants DIVISION type CHAR1 value '/'. "#EC NOTEXT constants EQUAL type CHAR1 value '='. "#EC NOTEXT constants DIGIT_1 type CHAR1 value '1'. "#EC NOTEXT constants DIGIT_2 type CHAR1 value '2'. "#EC NOTEXT constants DIGIT_3 type CHAR1 value '3'. "#EC NOTEXT constants DIGIT_4 type CHAR1 value '4'. "#EC NOTEXT constants DIGIT_5 type CHAR1 value '5'. "#EC NOTEXT constants DIGIT_6 type CHAR1 value '6'. "#EC NOTEXT constants DIGIT_7 type CHAR1 value '7'. "#EC NOTEXT constants DIGIT_8 type CHAR1 value '8'. "#EC NOTEXT constants DIGIT_9 type CHAR1 value '9'. "#EC NOTEXT constants DIGIT_0 type CHAR1 value '0'. "#EC NOTEXT constants ERROR type CHAR1 value 'E'. "#EC NOTEXT methods CONSTRUCTOR . methods ENTER_OPERATION importing !IM_OPERAND type CHAR1 raising ZCX_INVALID_OPERATION . methods ENTER_DIGIT importing !IM_DIGIT type CHAR1 . methods GET_DISPLAY returning value(RE_DISPLAY) type STRING . methods CLEAR_DISPLAY . methods EXECUTE raising CX_SY_ZERODIVIDE . *"* protected components of class ZCL_CALCULATOR *"* do not include other source files here!!! protected section. *"* private components of class ZCL_CALCULATOR *"* do not include other source files here!!! private section. data OPERAND type CHAR1 . data DISPLAY type STRING . data PREVIOUS_VALUE type P . *"* local class implementation for public class *"* use this source file for the implementation part of *"* local helper classes *"* use this source file for any type declarations (class *"* definitions, interfaces or data types) you need for method *"* implementation or private method's signature *"* use this source file for any macro definitions you need *"* in the implementation part of the class * ---------------------------------------------------------------------- CLASS abap_unit_testclass DEFINITION FOR TESTING "#AU Duration Medium "#AU Risk_Level Harmless . * ---------------------------------------------------------------------- * =============== PUBLIC SECTION. * =============== * ================== PROTECTED SECTION. * ================== * ================ PRIVATE SECTION. * ================ TYPE-POOLS: abap. DATA: m_ref TYPE REF TO zcl_calculator. "#EC NOTEXT DATA: is_exception TYPE abap_bool, error_message TYPE string. METHODS: setup. METHODS: teardown. METHODS: clear_display FOR TESTING. METHODS: enter_digit FOR TESTING. METHODS: enter_operation FOR TESTING. METHODS: execute FOR TESTING. METHODS: get_display FOR TESTING. ENDCLASS. "Abap_Unit_Testclass * ---------------------------------------------------------------------- CLASS abap_unit_testclass IMPLEMENTATION. * ---------------------------------------------------------------------- * ---------------------------------------------------------------------- METHOD setup. * ---------------------------------------------------------------------- CREATE OBJECT m_ref. ENDMETHOD. "Setup * ---------------------------------------------------------------------- METHOD teardown. * ---------------------------------------------------------------------- ENDMETHOD. "Teardown * ---------------------------------------------------------------------- METHOD clear_display. * ---------------------------------------------------------------------- DATA re_display TYPE string. m_ref->clear_display( ). re_display = m_ref->get_display( ). cl_aunit_assert=>assert_equals( act = re_display exp = zcl_calculator=>digit_0 msg = 'Error clearing display.' ). ENDMETHOD. "Clear_Display * ---------------------------------------------------------------------- METHOD enter_digit. * ---------------------------------------------------------------------- DATA im_digit TYPE char1. DATA re_display TYPE string. m_ref->clear_display( ). im_digit = zcl_calculator=>digit_0. m_ref->enter_digit( im_digit ). re_display = m_ref->get_display( ). CONCATENATE 'Error entering digit:' im_digit 'expected:' '0' 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = '0' msg = error_message ). * ---------------------------------------- im_digit = zcl_calculator=>digit_1. m_ref->enter_digit( im_digit ). re_display = m_ref->get_display( ). CONCATENATE 'Error entering digit:' im_digit 'expected:' '1' 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = '1' msg = error_message ). * ---------------------------------------- im_digit = zcl_calculator=>digit_2. m_ref->enter_digit( im_digit ). re_display = m_ref->get_display( ). CONCATENATE 'Error entering digit:' im_digit 'expected:' '12' 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = '12' msg = error_message ). * ---------------------------------------- im_digit = zcl_calculator=>digit_3. m_ref->enter_digit( im_digit ). re_display = m_ref->get_display( ). CONCATENATE 'Error entering digit:' im_digit 'expected:' '123' 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = '123' msg = error_message ). * ---------------------------------------- im_digit = zcl_calculator=>digit_4. m_ref->enter_digit( im_digit ). re_display = m_ref->get_display( ). CONCATENATE 'Error entering digit:' im_digit 'expected:' '1234' 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = '1234' msg = error_message ). * ---------------------------------------- im_digit = zcl_calculator=>digit_5. m_ref->enter_digit( im_digit ). re_display = m_ref->get_display( ). CONCATENATE 'Error entering digit:' im_digit 'expected:' '12345' 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = '12345' msg = error_message ). * ---------------------------------------- im_digit = zcl_calculator=>digit_6. m_ref->enter_digit( im_digit ). re_display = m_ref->get_display( ). CONCATENATE 'Error entering digit:' im_digit 'expected:' '123456' 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = '123456' msg = error_message ). * ---------------------------------------- im_digit = zcl_calculator=>digit_7. m_ref->enter_digit( im_digit ). re_display = m_ref->get_display( ). CONCATENATE 'Error entering digit:' im_digit 'expected:' '1234567' 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = '1234567' msg = error_message ). * ---------------------------------------- im_digit = zcl_calculator=>digit_8. m_ref->enter_digit( im_digit ). re_display = m_ref->get_display( ). CONCATENATE 'Error entering digit:' im_digit 'expected:' '12345678' 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = '12345678' msg = error_message ). * ---------------------------------------- im_digit = zcl_calculator=>digit_9. m_ref->enter_digit( im_digit ). re_display = m_ref->get_display( ). CONCATENATE 'Error entering digit:' im_digit 'expected:' '123456789' 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = '123456789' msg = error_message ). * ---------------------------------------- im_digit = zcl_calculator=>digit_0. m_ref->enter_digit( im_digit ). re_display = m_ref->get_display( ). CONCATENATE 'Error entering digit:' im_digit 'expected:' '1234567890' 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = '1234567890' msg = error_message ). * ---------------------------------------- im_digit = zcl_calculator=>digit_1. m_ref->enter_digit( im_digit ). re_display = m_ref->get_display( ). CONCATENATE 'Error entering digit:' im_digit 'expected:' '12345678901' INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = '12345678901' msg = error_message ). * ---------------------------------------- im_digit = zcl_calculator=>digit_2. m_ref->enter_digit( im_digit ). re_display = m_ref->get_display( ). CONCATENATE 'Error entering digit:' im_digit 'expected:' '123456789012' 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = '123456789012' msg = error_message ). * ---------------------------------------- im_digit = zcl_calculator=>digit_3. m_ref->enter_digit( im_digit ). re_display = m_ref->get_display( ). CONCATENATE 'Enter more than 12 digits.' 'Expected:' '123456789012' 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = '123456789012' msg = error_message ). ENDMETHOD. "Enter_Digit * ---------------------------------------------------------------------- METHOD enter_operation. * ---------------------------------------------------------------------- DATA: is_exception TYPE char1. "...SUM CLEAR is_exception. TRY . m_ref->enter_operation( zcl_calculator=>plus ). CATCH zcx_invalid_operation. is_exception = abap_true. ENDTRY. cl_aunit_assert=>assert_equals( act = is_exception exp = abap_false msg = 'Error on operation sum.' ). "...SUBTRATION CLEAR is_exception. TRY . m_ref->enter_operation( zcl_calculator=>subtraction ). CATCH zcx_invalid_operation. is_exception = abap_true. ENDTRY. cl_aunit_assert=>assert_equals( act = is_exception exp = abap_false msg = 'Error on operation subtration.' ). "...DIVISION CLEAR is_exception. TRY . m_ref->enter_operation( zcl_calculator=>division ). CATCH zcx_invalid_operation. is_exception = abap_true. ENDTRY. cl_aunit_assert=>assert_equals( act = is_exception exp = abap_false msg = 'Error on operation division.' ). "...MULTIPLICATION CLEAR is_exception. TRY . m_ref->enter_operation( zcl_calculator=>multiplication ). CATCH zcx_invalid_operation. is_exception = abap_true. ENDTRY. cl_aunit_assert=>assert_equals( act = is_exception exp = abap_false msg = 'Error on operation multiplication.' ). "...WRONG OPERATION CLEAR is_exception. TRY . m_ref->enter_operation( '@' ). CATCH zcx_invalid_operation. is_exception = abap_true. ENDTRY. cl_aunit_assert=>assert_equals( act = is_exception exp = abap_true msg = 'Error on operation: wrong operation.' ). ENDMETHOD. "Enter_Operation * ---------------------------------------------------------------------- METHOD execute. * ---------------------------------------------------------------------- DATA: re_display TYPE string, lv_expected TYPE string, is_exception TYPE char1. "...SUM m_ref->clear_display( ). m_ref->enter_digit( zcl_calculator=>digit_2 ). m_ref->enter_digit( zcl_calculator=>digit_5 ). m_ref->enter_operation( zcl_calculator=>plus ). m_ref->enter_digit( zcl_calculator=>digit_1 ). m_ref->enter_digit( zcl_calculator=>digit_6 ). m_ref->execute( ). re_display = m_ref->get_display( ). lv_expected = '41.00'. CONCATENATE 'Error 25 + 16' 'Expected:' lv_expected 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = lv_expected msg = error_message ). "...SUBTRATION m_ref->clear_display( ). m_ref->enter_digit( zcl_calculator=>digit_2 ). m_ref->enter_digit( zcl_calculator=>digit_5 ). m_ref->enter_operation( zcl_calculator=>subtraction ). m_ref->enter_digit( zcl_calculator=>digit_1 ). m_ref->enter_digit( zcl_calculator=>digit_6 ). m_ref->execute( ). re_display = m_ref->get_display( ). lv_expected = '9.00'. CONCATENATE 'Error 25 - 16' 'Expected:' lv_expected 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = lv_expected msg = error_message ). "...MULTIPLICATION m_ref->clear_display( ). m_ref->enter_digit( zcl_calculator=>digit_2 ). m_ref->enter_digit( zcl_calculator=>digit_5 ). m_ref->enter_operation( zcl_calculator=>multiplication ). m_ref->enter_digit( zcl_calculator=>digit_1 ). m_ref->enter_digit( zcl_calculator=>digit_6 ). m_ref->execute( ). re_display = m_ref->get_display( ). lv_expected = '400.00'. CONCATENATE 'Error 25 * 16' 'Expected:' lv_expected 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = lv_expected msg = error_message ). "...DIVISION m_ref->clear_display( ). m_ref->enter_digit( zcl_calculator=>digit_2 ). m_ref->enter_digit( zcl_calculator=>digit_5 ). m_ref->enter_operation( zcl_calculator=>division ). m_ref->enter_digit( zcl_calculator=>digit_1 ). m_ref->enter_digit( zcl_calculator=>digit_6 ). m_ref->execute( ). re_display = m_ref->get_display( ). lv_expected = '1.56'. CONCATENATE 'Error 25 / 16' 'Expected:' lv_expected 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = lv_expected msg = error_message ). "...DIVISION BY ZERO m_ref->clear_display( ). m_ref->enter_digit( zcl_calculator=>digit_2 ). m_ref->enter_digit( zcl_calculator=>digit_5 ). m_ref->enter_operation( zcl_calculator=>division ). m_ref->enter_digit( zcl_calculator=>digit_0 ). TRY . m_ref->execute( ). CATCH cx_sy_zerodivide. is_exception = abap_true. ENDTRY. cl_aunit_assert=>assert_equals( act = is_exception exp = abap_true msg = 'Error on operation division - zero divide.' ). lv_expected = zcl_calculator=>error. re_display = m_ref->get_display( ). CONCATENATE 'Error display after zero divide' 'Expected:' lv_expected 'actual:' re_display INTO error_message SEPARATED BY space. cl_aunit_assert=>assert_equals( act = re_display exp = lv_expected msg = error_message ). ENDMETHOD. "Execute * ---------------------------------------------------------------------- METHOD get_display. * ---------------------------------------------------------------------- DATA: re_display TYPE string. m_ref->clear_display( ). m_ref->enter_digit( zcl_calculator=>digit_1 ). re_display = m_ref->get_display( ). cl_aunit_assert=>assert_equals( act = re_display exp = zcl_calculator=>digit_1 msg = 'Returning wrong value.' ). * ---------------------------------------- m_ref->clear_display( ). m_ref->enter_digit( zcl_calculator=>digit_0 ). re_display = m_ref->get_display( ). cl_aunit_assert=>assert_equals( act = re_display exp = zcl_calculator=>digit_0 msg = 'Returning wrong value on clear display.' ). ENDMETHOD. "Get_Display ENDCLASS. "Abap_Unit_Testclass METHOD clear_display. display = digit_0. ENDMETHOD. method CONSTRUCTOR. display = '0'. endmethod. METHOD enter_digit. DATA: vl_lenght TYPE i. CHECK NOT ( display EQ digit_0 AND im_digit EQ digit_0 ). IF display EQ digit_0. display = im_digit. EXIT. ENDIF. vl_lenght = STRLEN( display ). CHECK vl_lenght < 12. CONCATENATE display im_digit INTO display. ENDMETHOD. METHOD enter_operation. IF NOT im_operand CA '+-/*'. RAISE EXCEPTION TYPE zcx_invalid_operation. ENDIF. operand = im_operand. previous_value = display. clear_display( ). ENDMETHOD. METHOD execute. DATA: vl_result TYPE p LENGTH 9 DECIMALS 2, vl_actual TYPE p LENGTH 9 DECIMALS 2. vl_actual = display. CASE operand. WHEN plus. vl_result = previous_value + vl_actual. WHEN subtraction. vl_result = previous_value - vl_actual. WHEN division. TRY . vl_result = previous_value / vl_actual. CLEANUP. display = error. ENDTRY. WHEN multiplication. vl_result = previous_value * vl_actual. ENDCASE. display = vl_result. ENDMETHOD. METHOD get_display. CONDENSE display. re_display = display. ENDMETHOD. class ZCX_INVALID_OPERATION definition public inheriting from CX_STATIC_CHECK final create public . *"* public components of class ZCX_INVALID_OPERATION *"* do not include other source files here!!! public section. constants ZCX_INVALID_OPERATION type SOTR_CONC value 'E06ADC24135AF4F1A6A000E081B02C77'. "#EC NOTEXT methods CONSTRUCTOR importing !TEXTID like TEXTID optional !PREVIOUS like PREVIOUS optional . *"* protected components of class ZCX_INVALID_OPERATION *"* do not include other source files here!!! protected section. *"* private components of class ZCX_INVALID_OPERATION *"* do not include other source files here!!! private section. *"* local class implementation for public class *"* use this source file for the implementation part of *"* local helper classes *"* use this source file for any type declarations (class *"* definitions, interfaces or data types) you need for method *"* implementation or private method's signature *"* use this source file for any macro definitions you need *"* in the implementation part of the class method CONSTRUCTOR. CALL METHOD SUPER->CONSTRUCTOR EXPORTING TEXTID = TEXTID PREVIOUS = PREVIOUS . IF textid IS INITIAL. me->textid = ZCX_INVALID_OPERATION . ENDIF. endmethod.