{"id":13392728,"url":"https://github.com/christianhujer/expensereport","last_synced_at":"2026-01-27T11:13:38.320Z","repository":{"id":37699689,"uuid":"395977021","full_name":"christianhujer/expensereport","owner":"christianhujer","description":"The ExpenseReport legacy code refactoring kata in \u003e50 programming languages (Ada to Zig)","archived":false,"fork":false,"pushed_at":"2024-10-04T20:17:49.000Z","size":390,"stargazers_count":150,"open_issues_count":12,"forks_count":99,"subscribers_count":3,"default_branch":"trunk","last_synced_at":"2025-03-13T18:40:25.303Z","etag":null,"topics":["kata","refactoring","refactoring-exercise","refactoring-kata"],"latest_commit_sha":null,"homepage":"","language":"Assembly","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/christianhujer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-08-14T10:44:05.000Z","updated_at":"2025-01-24T09:12:04.000Z","dependencies_parsed_at":"2024-01-15T09:02:58.718Z","dependency_job_id":"7690bf57-5353-4440-ba89-e25dcd70c1d7","html_url":"https://github.com/christianhujer/expensereport","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/christianhujer/expensereport","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christianhujer%2Fexpensereport","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christianhujer%2Fexpensereport/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christianhujer%2Fexpensereport/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christianhujer%2Fexpensereport/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/christianhujer","download_url":"https://codeload.github.com/christianhujer/expensereport/tar.gz/refs/heads/trunk","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/christianhujer%2Fexpensereport/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28812372,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T07:41:26.337Z","status":"ssl_error","status_checked_at":"2026-01-27T07:41:08.776Z","response_time":168,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kata","refactoring","refactoring-exercise","refactoring-kata"],"created_at":"2024-07-30T17:00:36.134Z","updated_at":"2026-01-27T11:13:38.302Z","avatar_url":"https://github.com/christianhujer.png","language":"Assembly","funding_links":[],"categories":["Assembly","Coding Katas (many languages)"],"sub_categories":["CSharp"],"readme":"# ExpenseReport\n![License: CC-BY-SA](by-sa.svg)\nThe ExpenseReport legacy code refactoring kata in various languages.\n\nThis is an example of a piece of legacy code with lots of code smells.\nThe goal is to support the following new feature as best as you can:\n* Add Lunch with an expense limit of 2000.\n\n## Process\n1. 📚 Read the code to understand what it does and how it works.\n2. 🦨 Read the code and check for design and code smells. Make a list of all code and design smells that you find.\n3. 🧑‍🔬 Analyze what you would have to change to implement the new requirement without refactoring the code.\n4. 🧪 Write a characterization test. Expand your list of code and design smells. Add those smells that you missed earlier and discovered now because they made your life writing a test miserable.\n5. 🔧 Refactor the code.\n6. 🔧 Refactor the test.\n7. 👼 Test-drive the new feature.\n\n## Supported Languages\nThe ExpenseReport example currently exists in the following languages:\n- [Ada](expensereport-ada/)\n- [Assembler](expensereport-asm-68k-masm/) (Motorola 68020, Amiga OS, MaxonASM)\n- [Assembler](expensereport-asm-aarch64-linux-gasm/) (AArch64, Linux, GNU Assembler)\n- [Assembler](expensereport-asm-amd64-linux-gasm/) (AMD64/Intel x86-64, Linux, GNU Assembler)\n- [bash](expensereport-bash/)\n- [BASIC](expensereport-basic-amiga/) (Amiga BASIC, Commodore Amiga) ⇐ Quite amazing! First BASIC without line numbers!\n- [BASIC](expensereport-basic-bywater/) (Bywater BASIC, Linux) (very similar to Commodore BASIC)\n- [BASIC](expensereport-basic-c64/) (Commodore BASIC, Commodore 64)\n- [BASIC](expensereport-basic-locomotive/) (Locomotive BASIC, Amstrad CPC)\n- [BASIC](expensereport-basic-yabasic/) (Yabasic)\n- [C](expensereport-c/)\n- [C#](expensereport-csharp/)\n- [C++](expensereport-cxx/)\n- [Clojure](expensereport-clojure/) ⇐ This one was particularly painful to intentionally write poorly, I almost cried.\n- [COBOL](expensereport-cobol/)\n- [D](expensereport-d/)\n- [Dart](expensereport-dart/)\n- [Elixir](expensereport-elixir/)\n- [F#](expensereport-fsharp/)\n- [Fortran](expensereport-fortran/)\n- [Go](expensereport-go/)\n- [Groovy](expensereport-groovy-script/)\n- [Haskell](expensereport-haskell/)\n- [Java](expensereport-java/)\n- [JavaScript](expensereport-javascript/)\n- [Julia](expensereport-julia/)\n- [Kotlin](expensereport-kotlin/)\n- [Lisp](expensereport-lisp/) (Common Lisp)\n- [Lua](expensereport-lua/)\n- [Nim](expense-report-nim/)\n- [Objective-C](expensereport-objc/)\n- [Pascal](expensereport-pascal/)\n- [Perl](expensereport-perl/)\n- [PHP](expensereport-php/)\n- [PostScript](expensereport-postscript/)\n- [Prolog](expensereport-prolog/)\n- [Python](expensereport-python/)\n- [Raku](expensereport-raku/) (Perl6)\n- [Rexx](expensereport-rexx/) (tested with Regina Rexx and ARexx)\n- [Ruby](expensereport-ruby/)\n- [Rust](expensereport-rust/)\n- [Scala](expensereport-scala/)\n- [Scheme](expensereport-scheme/)\n- [Smalltalk](expensereport-smalltalk/)\n- [SQL](expensereport-sql/) (Using SQLite3)\n- [Swift](expensereport-swift/)\n- [TcL](expensereport-tcl/)\n- [TypeScript](expensereport-typescript/)\n- [Visual BASIC](expensereport-vb/)\n- [XML/XSLT](expensereport-xslt/)\n- [Zig](expensereport-zig/)\n- [zsh](expensereport-zsh/)\n\n## Planned languages\n(in no particular order and with no guarantee)\n\n- ABAP\n- Amiga E\n- AMOS BASIC\n- APL\n- More Assembler implementations (arm, aarch64, i686, powerpc, powerpc64, mpis, mips64, sparc, sparc64, risc-v, etc, usually on Linux)\n- Carbon\n- CLIPS\n- Cluster\n- Concurnas\n- Curry\n- Dark\n- Eiffel\n- Elm\n- Erlang\n- Flix\n- Forth\n- Gleam\n- Gosu\n- Hack\n- Hare\n- Java Byte Code / JVM Assembler\n- Lobster\n- Logo\n- Mercury\n- Modula-2 (once the linker starts working again)\n- Mojo\n- Oberon\n- OCaml\n- Pony\n- PureScript\n- R\n- Reason\n- REBOL\n- Scratch\n- SNOBOL\n- Solidity (maybe)\n- Strongtalk\n- TeX\n- Unison\n- WebAssembly\n\n## Languages explicitly not planned\n- Brainfuck\n- False\n- Malbolge\n- Whitespace\n\n## Undecided Languages\nThere are many more programming languages than in the list above.\nFind a more complete list on [Wikipedia](https://en.wikipedia.org/wiki/List_of_programming_languages).\n\n## Other plans\n- Make sure that all languages are providing the identical challenge.\n  To be practical, this will require the removal of the timestamp side-effect.\n- Provide the time-stamp side-effect on a separate branch.\n- Provide a test setup (without test) on a separate branch so that folks can choose whether they want to include the setup work in the kata or not.\n- Provide a level 2 challenge for creating an HTML report besides the Plain Text report.\n\n## Solutions\nTo see solutions, switch to the [solutions branch](https://github.com/christianhujer/expensereport/tree/solutions#solutions).\n\n**Warning** The solutions branch will be rebased!\n\n## Credits and License\nI first encountered the ExpenseReport example during a bootcamp at Equal Experts.\nI also have seen the [ExpenseReport example](https://github.com/unclebob/Episode-10-ExpenseReport) being used by Robert \"Uncle Bob\" C. Martin.\nHowever, he seems to not be the original author (https://twitter.com/unclebobmartin/status/1537063143326855176?s=20\u0026t=lh_vVb9jUQmY6PYG50974w)\nI have tried to research its origins but so far I have failed.\nIf you know who has first come up with this example, please get in touch with me.\n\nAs I was asked for the license conditions, I have decided to put this under CC-BY-SA, with the following considerations:\n- Please credit me, last but not least to retain the opportunity for people to experience this exercise in as many programming languages as they are interested in.\n- Share it under the same license.\n- Using this as training material should be allowed, even if the trainer is charging money for their time.\n\nDisclaimer: As stated above, I did not come up with the original version.\nThe original author is unknown to me.\nThe CC-BY-SA license thus can only cover my contribution: Recreating the Java version from memory, creating the versions in other programming languages than Java, and keeping them consistent.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristianhujer%2Fexpensereport","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchristianhujer%2Fexpensereport","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchristianhujer%2Fexpensereport/lists"}