michelchenrich

ABAP Restaurant Kata - Use-Case-Driven

Mar 5th, 2014
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ABAP 7.69 KB | None | 0 0
  1. PROGRAM zkata_restaurant.
  2.  
  3. CLASS restaurant DEFINITION.
  4.   PUBLIC SECTION.
  5.     METHODS:
  6.       constructor IMPORTING id   TYPE string
  7.                             name TYPE string,
  8.       id          RETURNING value(return) TYPE string,
  9.       name        RETURNING value(return) TYPE string.
  10.   PRIVATE SECTION.
  11.     DATA:
  12.       _id   TYPE string,
  13.       _name TYPE string.
  14. ENDCLASS.
  15. CLASS restaurant IMPLEMENTATION.
  16.   METHOD constructor.
  17.     _id   = id.
  18.     _name = name.
  19.   ENDMETHOD.
  20.   METHOD id.
  21.     return = _id.
  22.   ENDMETHOD.
  23.   METHOD name.
  24.     return = _name.
  25.   ENDMETHOD.
  26. ENDCLASS.
  27.  
  28. INTERFACE restaurant_builder.
  29.   METHODS:
  30.     with_name IMPORTING name TYPE string
  31.               RETURNING value(return) TYPE REF TO restaurant_builder,
  32.     build     RETURNING value(return) TYPE REF TO restaurant.
  33. ENDINTERFACE.
  34.  
  35. CLASS in_memory_restaurant_builder DEFINITION FOR TESTING.
  36.   PUBLIC SECTION.
  37.     INTERFACES:
  38.       restaurant_builder.
  39.     METHODS:
  40.       constructor IMPORTING id TYPE string.
  41.   PRIVATE SECTION.
  42.     DATA:
  43.       id   TYPE string,
  44.       name TYPE string.
  45. ENDCLASS.
  46. CLASS in_memory_restaurant_builder IMPLEMENTATION.
  47.   METHOD constructor.
  48.     me->id = id.
  49.   ENDMETHOD.
  50.   METHOD restaurant_builder~build.
  51.     CREATE OBJECT return
  52.       EXPORTING
  53.         id   = id
  54.         name = name.
  55.   ENDMETHOD.
  56.   METHOD restaurant_builder~with_name.
  57.     me->name = name.
  58.     return   = me.
  59.   ENDMETHOD.
  60. ENDCLASS.
  61.  
  62. INTERFACE restaurant_store.
  63.   METHODS:
  64.     create     RETURNING value(return) TYPE REF TO restaurant_builder,
  65.     save       IMPORTING restaurant    TYPE REF TO restaurant,
  66.     find_by_id IMPORTING id            TYPE string
  67.                RETURNING value(return) TYPE REF TO restaurant.
  68. ENDINTERFACE.
  69.  
  70. CLASS in_memory_restaurant_store DEFINITION FOR TESTING.
  71.   PUBLIC SECTION.
  72.     INTERFACES:
  73.       restaurant_store.
  74.   PRIVATE SECTION.
  75.     TYPES:
  76.       BEGIN OF map_entry_type,
  77.         id     TYPE string,
  78.         object TYPE REF TO restaurant,
  79.       END OF map_entry_type,
  80.       map_type TYPE HASHED TABLE OF map_entry_type WITH UNIQUE KEY id.
  81.     DATA:
  82.       incremental_id TYPE i,
  83.       map            TYPE map_type.
  84. ENDCLASS.
  85. CLASS in_memory_restaurant_store IMPLEMENTATION.
  86.   METHOD restaurant_store~create.
  87.     ADD 1 TO incremental_id.
  88.     CREATE OBJECT return TYPE in_memory_restaurant_builder
  89.       EXPORTING
  90.         id = |{ incremental_id }|.
  91.   ENDMETHOD.
  92.   METHOD restaurant_store~find_by_id.
  93.     DATA entry LIKE LINE OF map.
  94.     READ TABLE map INTO entry WITH KEY id = id.
  95.     return = entry-object.
  96.   ENDMETHOD.
  97.   METHOD restaurant_store~save.
  98.     DATA entry LIKE LINE OF map.
  99.     entry-id = restaurant->id( ).
  100.     entry-object = restaurant.
  101.     DELETE map WHERE id = entry-id.
  102.     INSERT entry INTO TABLE map.
  103.   ENDMETHOD.
  104. ENDCLASS.
  105.  
  106. INTERFACE create_restaurant_request.
  107.   METHODS:
  108.     name RETURNING value(return) TYPE string.
  109. ENDINTERFACE.
  110.  
  111. CLASS create_restaurant_request_stub DEFINITION FOR TESTING.
  112.   PUBLIC SECTION.
  113.     INTERFACES:
  114.       create_restaurant_request.
  115.     METHODS:
  116.       with_name IMPORTING name TYPE string.
  117.   PRIVATE SECTION.
  118.     DATA:
  119.       name TYPE string.
  120. ENDCLASS.
  121. CLASS create_restaurant_request_stub IMPLEMENTATION.
  122.   METHOD create_restaurant_request~name.
  123.     return = name.
  124.   ENDMETHOD.
  125.   METHOD with_name.
  126.     me->name = name.
  127.   ENDMETHOD.
  128. ENDCLASS.
  129.  
  130. INTERFACE create_restaurant_receiver.
  131.   METHODS:
  132.     created_with_id IMPORTING id TYPE string,
  133.     send_message    IMPORTING id TYPE string.
  134. ENDINTERFACE.
  135.  
  136. CLASS create_restaurant_receiver_spy DEFINITION FOR TESTING.
  137.   PUBLIC SECTION.
  138.     INTERFACES:
  139.       create_restaurant_receiver.
  140.     METHODS:
  141.       id                    RETURNING value(return) TYPE string,
  142.       has_received_messages IMPORTING message_ids   TYPE string_table OPTIONAL
  143.                             RETURNING value(return) TYPE abap_bool.
  144.   PRIVATE SECTION.
  145.     DATA:
  146.       restaurant_id TYPE string,
  147.       message_ids   TYPE string_table.
  148. ENDCLASS.
  149. CLASS create_restaurant_receiver_spy IMPLEMENTATION.
  150.   METHOD create_restaurant_receiver~created_with_id.
  151.     restaurant_id = id.
  152.   ENDMETHOD.
  153.   METHOD create_restaurant_receiver~send_message.
  154.     APPEND id TO message_ids.
  155.   ENDMETHOD.
  156.   METHOD id.
  157.     return = restaurant_id.
  158.   ENDMETHOD.
  159.   METHOD has_received_messages.
  160.     IF message_ids IS SUPPLIED.
  161.       return = boolc( message_ids = me->message_ids ).
  162.     ELSE.
  163.       return = boolc( lines( me->message_ids ) > 0 ).
  164.     ENDIF.
  165.   ENDMETHOD.
  166. ENDCLASS.
  167.  
  168. INTERFACE command.
  169.   METHODS:
  170.     execute.
  171. ENDINTERFACE.
  172.  
  173. CLASS create_restaurant_command DEFINITION.
  174.   PUBLIC SECTION.
  175.     INTERFACES:
  176.       command.
  177.     METHODS:
  178.       constructor IMPORTING store    TYPE REF TO restaurant_store
  179.                             request  TYPE REF TO create_restaurant_request
  180.                             receiver TYPE REF TO create_restaurant_receiver.
  181.   PRIVATE SECTION.
  182.     DATA:
  183.       store    TYPE REF TO restaurant_store,
  184.       request  TYPE REF TO create_restaurant_request,
  185.       receiver TYPE REF TO create_restaurant_receiver.
  186. ENDCLASS.
  187. CLASS create_restaurant_command IMPLEMENTATION.
  188.   METHOD constructor.
  189.     me->store = store.
  190.     me->request = request.
  191.     me->receiver = receiver.
  192.   ENDMETHOD.
  193.   METHOD command~execute.
  194.     IF request->name( ) IS INITIAL.
  195.       receiver->send_message( 'EMPTY_NAME' ).
  196.     ELSE.
  197.       DATA restaurant TYPE REF TO restaurant.
  198.       restaurant = store->create( )->with_name( request->name( ) )->build( ).
  199.       store->save( restaurant ).
  200.       receiver->created_with_id( restaurant->id( ) ).
  201.     ENDIF.
  202.   ENDMETHOD.
  203. ENDCLASS.
  204.  
  205. CLASS restaurant_test DEFINITION FOR TESTING RISK LEVEL HARMLESS DURATION SHORT CREATE PRIVATE FINAL.
  206.   PRIVATE SECTION.
  207.     DATA:
  208.       store        TYPE REF TO restaurant_store,
  209.       request_stub TYPE REF TO create_restaurant_request_stub,
  210.       receiver_spy TYPE REF TO create_restaurant_receiver_spy,
  211.       command      TYPE REF TO command.
  212.     METHODS:
  213.       setup,
  214.       simple_creation          FOR TESTING,
  215.       creating_mutiple         FOR TESTING,
  216.       creating_with_empty_name FOR TESTING.
  217. ENDCLASS.
  218.  
  219. CLASS restaurant_test IMPLEMENTATION.
  220.   METHOD setup.
  221.     CREATE OBJECT:
  222.       store TYPE in_memory_restaurant_store,
  223.       request_stub,
  224.       receiver_spy,
  225.       command TYPE create_restaurant_command
  226.         EXPORTING
  227.           store    = store
  228.           request  = request_stub
  229.           receiver = receiver_spy.
  230.   ENDMETHOD.
  231.   METHOD simple_creation.
  232.     request_stub->with_name( 'Restaurant name' ).
  233.     command->execute( ).
  234.  
  235.     cl_abap_unit_assert=>assert_equals( exp = 'Restaurant name'
  236.                                         act = store->find_by_id( receiver_spy->id( ) )->name( ) ).
  237.     cl_abap_unit_assert=>assert_false( receiver_spy->has_received_messages( ) ).
  238.   ENDMETHOD.
  239.   METHOD creating_mutiple.
  240.     request_stub->with_name( 'First name' ).
  241.     command->execute( ).
  242.  
  243.     request_stub->with_name( 'Restaurant name' ).
  244.     command->execute( ).
  245.     DATA restaurant_id TYPE string.
  246.     restaurant_id = receiver_spy->id( ).
  247.  
  248.     request_stub->with_name( 'Second name' ).
  249.     command->execute( ).
  250.  
  251.     cl_abap_unit_assert=>assert_equals( exp = 'Restaurant name'
  252.                                         act = store->find_by_id( restaurant_id )->name( ) ).
  253.  
  254.   ENDMETHOD.
  255.   METHOD creating_with_empty_name.
  256.     request_stub->with_name( '' ).
  257.     command->execute( ).
  258.  
  259.     cl_abap_unit_assert=>assert_not_bound( store->find_by_id( receiver_spy->id( ) ) ).
  260.  
  261.     DATA message_ids TYPE string_table.
  262.     APPEND 'EMPTY_NAME' TO message_ids.
  263.     cl_abap_unit_assert=>assert_true( receiver_spy->has_received_messages( message_ids ) ).
  264.   ENDMETHOD.
  265. ENDCLASS.
Advertisement
Add Comment
Please, Sign In to add comment