Code Monkey home page Code Monkey logo

supermarketreceipt-refactoring-kata's Introduction

Support this and all my katas via Patreon

The Supermarket Receipt Refactoring Kata

Watch the "Detangle Bad Code Challenge" introduction to this exercise.

This is a variation of a popular kata described in http://codekata.com/kata/kata01-supermarket-pricing/. The aim of the exercise is to build automated tests for this code, refactor it, and add a new feature.

The supermarket has a catalog with different types of products (rice, apples, milk, toothbrushes,...). Each product has a price, and the total price of the shopping cart is the total of all the prices of the items. You get a receipt that details the items you've bought, the total price and any discounts that were applied.

The supermarket runs special deals, e.g.

  • Buy two toothbrushes, get one free. Normal toothbrush price is €0.99
  • 20% discount on apples, normal price €1.99 per kilo.
  • 10% discount on rice, normal price €2.49 per bag
  • Five tubes of toothpaste for €7.49, normal price €1.79
  • Two boxes of cherry tomatoes for €0.99, normal price €0.69 per box.

These are just examples: the actual special deals change each week.

Create some test cases and aim to get good enough code coverage that you feel confident to do some refactoring.

When you have good test cases, identify code smells such as Long Method, Feature Envy. Apply relevant refactorings.

When you're confident you can handle this code, implement the new feature described below

New feature: discounted bundles

The owner of the system has a new feature request. They want to introduce a new kind of special offer - bundles. When you buy all the items in a product bundle you get 10% off the total for those items. For example you could make a bundle offer of one toothbrush and one toothpaste. If you then you buy one toothbrush and one toothpaste, the discount will be 10% of €0.99 + €1.79. If you instead buy two toothbrushes and one toothpaste, you get the same discount as if you'd bought only one of each - ie only complete bundles are discounted.

New feature: HTML receipt

Currently we print a traditional ticket receipt. Now being a modern business we'd like to be able to print or send a HTML version of the same receipt. All the data and number formatting should be the same. However the layout should be html. You don't have to worry about the HTML template - a designer will care of that - but we do need someone to keep duplication between the reports to a bare minimum.

Start with the refactoring

If you would like to just do the refactoring part of this exercise, you can instead check out the 'with_tests' branch. Those tests have reasonably good coverage and should support most kinds of refactorings you'd like to do.

Use this exercise in a Learning Hour

You can use the Supermarket Receipt Kata in learning hours if you are using the Samman coaching method.

supermarketreceipt-refactoring-kata's People

Contributors

alex-thiessen-for-siemens avatar caichinger avatar codecop avatar daddyshortlegs avatar dependabot[bot] avatar dertseha avatar drlc avatar emilybache avatar grigory-rechistov-intel avatar heidererkatrin avatar kerryb avatar martinsson avatar neil-vass avatar nicoolas25 avatar pen-y-fan avatar riggs333 avatar sandordargo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

supermarketreceipt-refactoring-kata's Issues

Questions regarding Python examples

I really like this kata - thank you for all the effort that went into it and sharing it publicly!

I have a few questions regarding the Python examples.

What is the intended difference between python/ and python_pytest/?

To me, the distinction is not clear.

For me, python_pytest/ suggest that this version uses pytest whereas the other uses unittest.
However, both examples use pytest.

The code base is almost identical in both cases, except for the difference in the README and the additional textest_fixture.py in the python_pytest/ version.

Data Files for texttest_fixture.py missing?

texttest_fixture.py loads catalog.csv (and other files).

Is a user intended to create these file by themselves or were they maybe forgotten?

How to run tests in python_pytest/?

With the current layout/configuration, the tests in python_pytest/ cannot be run by simply invoking $ pytest, since the required modules cannot be imported.

At the moment, the README suggests use pytest to run tests but it may no be immediately clear how to do that.

There are different ways to address this issue:

  1. Change layout by moving tests/ into src/ (mimicking the layout currently used in python/)
  2. Add a pytest.ini to python_pytest/ where we add src/ to the pythonpath.
  3. Add a conftest.py to python_pytest/

If you share your intention with me, I am happy to provide a PR.

Personally, I would kind of merge the two folders.

Test coverage using Combination Approvals (csharp-ms)

Hi Emily,

I forked your kata and created a branch providing 100% coverage with one simple approval test that is utilizing combination approvals. As one cannot create a pull request for adding a new branch I wanted to ask you if you want to include this branch into your kata. It's implemented for csharp-ms only for now, but we could add the tests for more languages (where available), such as Java.

The branch can be found here:
https://github.com/afhswe/SupermarketReceipt-Refactoring-Kata/tree/with_combination_approval_tests

Please simply close the issue if you this does not make sense for your kata setup.

Best,
Andi

Cannot build the C++ part out of the box on Ubuntu/Debian

Cannot build the C++ part out of the box on Ubuntu/Debian. Either the CMake version is too old or the C++ standard library is too new.

Repro steps:

  1. install Docker
  2. create a Dockerfile:
ARG base

FROM "${base}"

ENV DEBIAN_FRONTEND=noninteractive

RUN \
        apt-get update \
        && apt-get --assume-yes install eatmydata \
        && eatmydata apt-get --assume-yes upgrade

RUN eatmydata apt-get --assume-yes install \
                build-essential

RUN eatmydata apt-get --assume-yes install \
                cmake \
                git \
        ;
  1. Build the image (e.g. based on Ubuntu 20.04):
docker build --build-arg base=ubuntu:20.04 --tag sw-excellence:ubuntu-20.04 .
  1. Try to build and test in a container using the image:
docker run --tty --interactive sw-excellence:ubuntu-20.04 sh -c 'git clone https://github.com/emilybache/SupermarketReceipt-Refactoring-Kata.git && cd SupermarketReceipt-Refactoring-Kata/cpp && cmake -S . -B build && cd build && cmake --build . && ctest'
  1. Observe a build error:
CMake Error at CMakeLists.txt:1 (cmake_minimum_required):
  CMake 3.20.2 or higher is required.  You are running version 3.16.3


-- Configuring incomplete, errors occurred!
  1. Try using a newer OS version, e.g. Ubuntu 22.04, observe this build error:
[ 82%] Built target ApprovalTests
[ 83%] Building CXX object test-catch2/CMakeFiles/sample_test_catch2.dir/main.cpp.o
In file included from /usr/include/signal.h:328,
                 from /SupermarketReceipt-Refactoring-Kata/cpp/build/_deps/catch2-src/single_include/catch2/catch.hpp:8042,
                 from /SupermarketReceipt-Refactoring-Kata/cpp/build/_deps/approvaltests-src/ApprovalTests/../ApprovalTests/integrations/catch/Catch2Approvals.h:18,
                 from /SupermarketReceipt-Refactoring-Kata/cpp/build/_deps/approvaltests-src/ApprovalTests/ApprovalTests.hpp:70,
                 from /SupermarketReceipt-Refactoring-Kata/cpp/test-catch2/main.cpp:2:
/SupermarketReceipt-Refactoring-Kata/cpp/build/_deps/catch2-src/single_include/catch2/catch.hpp:10830:58: error: call to non-'constexpr' function 'long int sysconf(int)'
10830 |     static constexpr std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ;
      |                                                          ^~~~~~~~~~~
In file included from /usr/include/c++/11/bits/atomic_wait.h:44,
                 from /usr/include/c++/11/bits/atomic_base.h:41,
                 from /usr/include/c++/11/bits/shared_ptr_atomic.h:33,
                 from /usr/include/c++/11/memory:78,
                 from /SupermarketReceipt-Refactoring-Kata/cpp/build/_deps/approvaltests-src/ApprovalTests/../ApprovalTests/reporters/ReporterFactory.h:7,
                 from /SupermarketReceipt-Refactoring-Kata/cpp/build/_deps/approvaltests-src/ApprovalTests/ApprovalTests.hpp:8,
                 from /SupermarketReceipt-Refactoring-Kata/cpp/test-catch2/main.cpp:2:
/usr/include/unistd.h:640:17: note: 'long int sysconf(int)' declared here
  640 | extern long int sysconf (int __name) __THROW;
      |                 ^~~~~~~
In file included from /SupermarketReceipt-Refactoring-Kata/cpp/build/_deps/approvaltests-src/ApprovalTests/../ApprovalTests/integrations/catch/Catch2Approvals.h:18,
                 from /SupermarketReceipt-Refactoring-Kata/cpp/build/_deps/approvaltests-src/ApprovalTests/ApprovalTests.hpp:70,
                 from /SupermarketReceipt-Refactoring-Kata/cpp/test-catch2/main.cpp:2:
/SupermarketReceipt-Refactoring-Kata/cpp/build/_deps/catch2-src/single_include/catch2/catch.hpp:10889:45: error: size of array 'altStackMem' is not an integral constant-expression
10889 |     char FatalConditionHandler::altStackMem[sigStackSize] = {};
      |                                             ^~~~~~~~~~~~
gmake[2]: *** [test-catch2/CMakeFiles/sample_test_catch2.dir/build.make:76: test-catch2/CMakeFiles/sample_test_catch2.dir/main.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:317: test-catch2/CMakeFiles/sample_test_catch2.dir/all] Error 2
gmake: *** [Makefile:146: all] Error 2

which stems from Catch2 being used per default and hitting this bug: catchorg/Catch2#2421.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.