#git #tdd #unit-testing #test #tcr

deprecated app git-tcrdd

this project has been renamed to git-gamble ; blend TCR + TDD to make sure to develop the right thing, babystep by babystep

5 releases

0.1.0-beta.8 Mar 25, 2020
0.1.0-beta.7 Mar 22, 2020
0.1.0-beta.4 Jan 11, 2020
0.1.0-beta.2 Jan 7, 2020

#36 in #tdd

ISC license

18KB
199 lines

Git-TCRDD

Crate pipeline status License

This project has been renamed to git-gamble




TCRDD = TCR (test && commit || revert) + TDD (Test Driven Development)

Original idea by Xavier Detant

Theory

TCR

TCR is cool! It encourages doing baby steps, reducing the waste when we are wrong

But it doesn't allow us to see the tests failing

So:

  • Maybe we test nothing (assert forgotten)

    def test_should_be_Buzz_given_5():
        input = 5
        actual = fizz_buzz(input)
        # Oops! Assert has been forgotten
    
  • Maybe we are testing something that is not the thing we should be testing

    it("should be Fizz given 3", () => {
      const input = 3;
      const actual = fizzBuzz(input);
      expect(input).toBe("Fizz");
      // Oops! Asserts on the input value instead of the actual value
    });
    

TDD

TDD is cool! It makes sure we develop the right thing, step by step

TCRDD

TCRDD = TCR + TDD

TCRDD blends the constraints of the two methods to benefit from their advantages

Therefore, TCRDD makes sure we develop the right thing, step by step, and we are encouraged to do so by baby steps, reducing the waste when we are wrong

@startuml
skinparam ArrowColor black

start
repeat
	partition "red" #Coral {
		repeat
			:Write a test]
			:Gamble that the tests fail/
			if (Actually run tests) then (Fail)
				-[#Red]->
				:Commit;
				break
			else (Pass)
				-[#Green]->
				:Revert;
			endif
		repeat while (Write another test)
	}
	partition "green" #Lime {
		repeat
			:Write the minimum code]
			:Gamble that the tests pass/
			if (Actually run tests) then (Pass)
				-[#Green]->
				:Commit;
				break
			else (Fail)
				-[#Red]->
				:Revert;
			endif
		repeat while (Try something else)
	}
	partition "refactor" #668cff {
		repeat
			repeat
				:Write code
				without changing the behavior]
				:Gamble that the tests pass/
				if (Actually run tests) then (Pass)
					-[#Green]->
					:Commit;
					break
				else (Fail)
					-[#Tomato]->
					:Revert;
				endif
			repeat while (Change something else)
		repeat while (Another things to refactor ?)
	}
repeat while (Another feature to add ?)
stop
@enduml

How to install

This will be improved

Install Cargo

cargo install --git https://gitlab.com/pinage404/git-tcrdd

Add ~/.cargo/bin to your $PATH

Fish:

set --export --append PATH ~/.cargo/bin

Bash / ZSH:

export PATH=$PATH:~/.cargo/bin

Check if all have been well settled

git tcrdd

If it has been well settled, it should output this :

error: The following required arguments were not provided:
    <test-command>...
    <--pass|--fail>

USAGE:
    git-tcrdd --repository-path <repository-path> <--pass|--fail>

For more information try --help

If it has been badly settled, it should output this :

git : 'tcrdd' is not a git command. See 'git --help'.

How to use

# To see all available flags and options
git-tcrdd --help # dash is only needed for --help

# Write a failing test in your codebase

# Then
git tcrdd --fail -- $YOUR_TEST_COMMAND

# Write the minimum code to make tests pass

# Then
git tcrdd --pass -- $YOUR_TEST_COMMAND

# Refactor your code

# Then
git tcrdd --pass -- $YOUR_TEST_COMMAND

# It's a bit tedious to always repeat the test command
# So you can set an environment variable with the test command to avoid repeating it all the time
export TCRDD_TEST_COMMAND="sh -c 'cargo fix --allow-dirty ; cargo clippy --all-targets ; cargo check --all-targets ; cargo fmt ; cargo test'"
git tcrdd --pass

Test command must exit with a 0 status when there are 0 failing tests, anything else is considered as a failure

Backlog

@startmindmap "backlog"
* Backlog
left side
	* Done
		* MVP
			* base
				* run tests
				* `git commit`
				* `git revert`
				* test it
			* TCR
				* option --pass
			* TRC
				* option --fail
		* give path in option
		* improve test command
			* test command with arguments
			* script
		* dry run flag
		* help option
			* -h
			* --help
		* exclusive flag
		* required flag
		* option colors
			* -g
			* --green
			* -r
			* --red
		* merge commits
			* `git update-ref`
			* `git commit --amend`
		* should fail without test command
		* test command from envirronement variable
		* display when committed or reverted
		* how to use
		* test in isolated and reproductible envirronement
			* container
			* CI
			* [[https://doc.rust-lang.org/cargo/guide/continuous-integration.html Cargo's Documentation about CI]]
		* choose a licence
		* complete metadata
		* publish it ?
			* [[https://doc.rust-lang.org/cargo/reference/publishing.html publishing]]
	* WIP
		* how to install
			* Simple binary
				* cargo build ?
					* cargo build --target "$TARGET" --release
				* cargo install ?
right side
	* TODO
		* when revert `git clean`
		* `git workspace` support
			* `git update-ref` should contain an unique identifier to the workspace
				* branche name ?
				* folder path ?
		* message option
			* -m
			* --message
			* amend should keep message
				* `"--reuse-message=@",`
		* shell completion
		* tcrdd hooks
			* branch based developement
				* `git commit --fixup`
				* `git rebase --autosquash`
			* trunk based developement
				* `git pull`
				* `git push`
		* rename project?
			* simpler to say and understand and remember when not familiar with `TCR` or `TDD`
			* from `git-tcrdd` to `git-...`?
				* [[https://www.wordreference.com/fren/jouer jouer?]]
				* [[https://www.wordreference.com/fren/parier parier?]]
				* [[https://www.wordreference.com/enfr/bet bet?]]
				* [[https://www.wordreference.com/enfr/expect expect?]]
				* [[https://www.wordreference.com/enfr/gamble gamble?]]
				* [[https://www.wordreference.com/enfr/should should?]]
				* Quick save development (qsd)
		* like git, flags & options & arguments should be retrieved from CLI or environment variable or config's file
			* re-use `git config` to store in file ?
		* OS distribution
			* Linux
				* Tar GZipped
					* cargo package ?
				* Nix
					* [[https://crates.io/crates/crate2nix crate2nix]]
					* [[https://github.com/tenx-tech/cargo2nix cargo2nix]]
				* Debian
					* [[https://crates.io/crates/cargo-deb cargo-deb]]
				* RPM
					* [[https://crates.io/crates/cargo-rpm cargo-rpm]]
				* AppImage ?
				* SnapCraft ?
				* FlatPak ?
				* Alpine ?
					* MUSL
				* Cross compilation ?
					* rust-cross
					* [[https://crates.io/crates/release-manager release-manager]]
					* Raspberry Pi ?
						* ARMv6
						* ARMv7
						* ARMv8
						* ARMx64
			* Container Image (Docker) ?
			* Mac OS X / HomeBrew
			* Windows / Chocolatey
			* [[https://github.com/rust-unofficial/awesome-rust#deployment Awesome Rust Deployment]]
			* [[https://github.com/rust-unofficial/awesome-rust#platform-specific Awesome Rust Platform Specific]]
		* URL to download latest version
			* symlinks to URL containing the version name ?
			* using GitLab Pages ?
		* [[https://rachelcarmena.github.io/2018/11/13/test-driven-programming-workflows.html#my-proposal-of-tcr-variant stash instead of revert ?]]
@endmindmap

Technical improvement opportunities

  • licence check
    • cargo license
    • cargo deny
  • code coverage
    • tarpaulin
    • kcov
  • smaller binary
    • cargo bloat
    • cargo deps

Reinvent the wheel

Why reinvent the wheel?

This script already works well

Because i would like to learn Rust ¯\_()_/¯

Contributing

To contribute, install this crates

Deployment

Dependencies

~6–15MB
~170K SLoC