Giter VIP home page Giter VIP logo

refactoring-kata-lift-pass-pricing's Introduction

Lift pass pricing

Image logo

This application solves the problem of calculating the pricing for ski lift passes. There's some intricate logic linked to what kind of lift pass you want, your age and the specific date at which you'd like to ski. There's a new feature request, be able to get the price for several lift passes, not just one. Currently the pricing for a single lift pass is implemented, unfortunately the code as it is designed is not reusable. You could put some high level tests in place in order to do preparatory refactoring so that the new feature requires minimum effort to implement.

This kata models a common problem - code that makes no sense to unit test due to bad design.

You can find a video pitch here

When am I done?

There are a few steps, you could do any of them.

  1. Cover with high level tests.
  2. Refactor the code to maximize unit testability and reuse for the new feature
  3. Pull down most of the high level tests
  4. Implement the new feature using unit tests and 1 or 2 high level tests.

Installation

Set up a MySQL database on localhost 3306 with user root and password mysql. If you have Docker installed the easiest thing is to use this script, that will initialize a MariaDB.

./runLocalDatabase.sh

Inject the data with

mysql -u root -p mysql < ./database/initDatabase.sql

Then head on to the language of your choice and follow the Readme in there. Some of the languages have a failing test that you could finish writing.

Tips

There's a good chance you could find a design that is both easier to test, faster to work with and that solves the problem with minimum amount of code. One such design would be to rid the bulk of the logic from it's adherence to the http/rest framework and from the sql specificities. This is sometimes called hexagonal architecture and it facilitates respecting the Testing Pyramid which is not currently possible - there can be only top-level tests

The typical workflow would be

  1. Cover everything from the http layer, use a real DB
  2. Separate request data extraction and sending the response from the logic
  3. Extract a method with the pure logic, move that method to an object (ex PricingLogic)
  4. Now extract the sql stuff from PricingLogic, first to some method with a signature that has nothing to do with sql, then move these methods to a new class (ex PricingDao)
  5. There should be ~3/4 elements, the http layer should have the PricingLogic as an injected dependency and the PricingLogic should have the PricingDao as an injected dependency.
  6. Move the bulk of the high level tests down onto PricingLogic using a fake dao, write some focused integration tests for the PricingDao using a real DB, there should be only a handful.

Now the HTTP layer and the integration of the parts can be tested with very few (one or two) high-level tests.

CONTRIBUTING

There are two branches, the master branch and the with_tests branch. The master is always merged into the with_tests branch. So typically if you want to contribute a new language or a simple version of a language you typically change the master branch, then switch to the with_tests branch and merge with master, then add tests.

Note that there are github actions for most of the with_tests versions, please do provide one if you add a language. This allows anyone having trouble running the tests with a baseline for getting the tests to work

When you're ready please submit one pull request for each branch

Thanks for contributing!

refactoring-kata-lift-pass-pricing's People

Contributors

codecop avatar dependabot[bot] avatar emilybache avatar gaetanmaisse avatar martinsson avatar nilhcem avatar rolger avatar sebcanonica avatar seblm 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

refactoring-kata-lift-pass-pricing's Issues

Differences in Scala port

There are two little differences in the Scala version compared to all other solutions:

  1. PUT does not return content-type JSON.
  2. cost for nightly without an age is 8 instead of 0 like in TS.

Also maybe log level could be turned to Warn when running the application.

ping @seblm

Java version

@codecop I updated the master branch, so it's ready for being adapted to your java port

Setup CI for checking sanity of with_tests branch

It'd be great to have a CI (travis, circleci, ..) to avoid systematically testing all PRs to the with_tests branch by hand.

Note: Possibly one could imagine to do the same for the master branch, but that'd require the tests to actually pass whereas now they fail in order for people to see where to start. Either way let's start with configuring a CI on the with_tests branch

Slight inconsistency in the python version

There is a small inconsistency to the other projects - because also typescript version has it.

  1. There is a main entry point (class, whatever) which calls createApp and then gets the connection and the application. It will print a message with a test URL and proper port (look into index.ts in the Typescript) and then starts the app by listening. So please instead of having the run of app in the main method of Prices, please create a separate file.

  2. The createApp is also returning the connection, so tests can close it after running. I do not see the tests closing the connection, maybe a method provided to shutdown of process? I think it's OK to get the values app and importing by running the module like it is now, connection is just available globally then?

Originally posted by @codecop in #61 (comment)

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.