From 92ef52cc518b5428f051ced36d95dae49d925fb3 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Fri, 20 Feb 2026 18:27:53 +0100 Subject: [PATCH 1/3] test: Add GitHub Actions workflow for coverage and enhance test cases --- .github/workflows/coverage.yml | 34 ++++ Cargo.lock | 337 ++++++++++++++++++++++++++------ deny.toml | 4 - src/tests/integration_test.rs | 4 +- src/tests/main_test.rs | 346 ++++++--------------------------- src/tests/printer_test.rs | 50 ++++- 6 files changed, 415 insertions(+), 360 deletions(-) create mode 100644 .github/workflows/coverage.yml diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml new file mode 100644 index 0000000..af04d6e --- /dev/null +++ b/.github/workflows/coverage.yml @@ -0,0 +1,34 @@ +name: Coverage + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + tarpaulin: + name: Tarpaulin + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + with: + lfs: true + + - uses: dtolnay/rust-toolchain@stable + + - uses: Swatinem/rust-cache@v2 + + - name: Set up git user for tests + run: | + git config --global user.email "ci@example.com" + git config --global user.name "CI User" + + - name: Install cargo-tarpaulin + uses: taiki-e/install-action@cargo-tarpaulin + + - name: Run coverage check + run: cargo tarpaulin --workspace --all-features --fail-under 90 --out Xml --out Stdout diff --git a/Cargo.lock b/Cargo.lock index f15a7d2..cfe22b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -54,21 +54,21 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.100" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" [[package]] name = "cc" -version = "1.2.51" +version = "1.2.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" +checksum = "aebf35691d1bfb0ac386a69bac2fde4dd276fb618cf8bf4f5318fe285e821bb2" dependencies = [ "find-msvc-tools", "jobserver", @@ -84,9 +84,9 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "clap" -version = "4.5.53" +version = "4.5.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" +checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a" dependencies = [ "clap_builder", "clap_derive", @@ -94,9 +94,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.53" +version = "4.5.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" +checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876" dependencies = [ "anstream", "anstyle", @@ -106,18 +106,18 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.64" +version = "4.5.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c0da80818b2d95eca9aa614a30783e42f62bf5fdfee24e68cfb960b071ba8d1" +checksum = "c757a3b7e39161a4e56f9365141ada2a6c915a8622c408ab6bb4b5d047371031" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.49" +version = "4.5.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" dependencies = [ "heck", "proc-macro2", @@ -127,9 +127,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.6" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" [[package]] name = "colorchoice" @@ -139,9 +139,9 @@ checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "comfy-table" -version = "7.2.1" +version = "7.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03b7db8e0b4b2fdad6c551e634134e99ec000e5c8c3b6856c65e8bbaded7a3b" +checksum = "958c5d6ecf1f214b4c2bbbbf6ab9523a864bd136dcf71a7e8904799acfe1ad47" dependencies = [ "crossterm", "unicode-segmentation", @@ -210,9 +210,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.5.5" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ "powerfmt", ] @@ -249,6 +249,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "errno" version = "0.3.14" @@ -267,9 +273,15 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "find-msvc-tools" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "form_urlencoded" @@ -292,6 +304,19 @@ dependencies = [ "wasip2", ] +[[package]] +name = "getrandom" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", + "wasip3", +] + [[package]] name = "git-statuses" version = "0.8.0" @@ -316,9 +341,9 @@ dependencies = [ [[package]] name = "git2" -version = "0.20.3" +version = "0.20.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e2b37e2f62729cdada11f0e6b3b6fe383c69c29fc619e391223e12856af308c" +checksum = "7b88256088d75a56f8ecfa070513a775dd9107f6530ef14919dac831af9cfe2b" dependencies = [ "bitflags", "libc", @@ -329,6 +354,21 @@ dependencies = [ "url", ] +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + [[package]] name = "heck" version = "0.5.0" @@ -416,6 +456,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "idna" version = "1.1.0" @@ -437,11 +483,23 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", + "serde", + "serde_core", +] + [[package]] name = "insta" -version = "1.45.1" +version = "1.46.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "983e3b24350c84ab8a65151f537d67afbbf7153bb9f1110e03e9fa9b07f67a5c" +checksum = "e82db8c87c7f1ccecb34ce0c24399b8a73081427f3c7c50a5d597925356115e4" dependencies = [ "console", "once_cell", @@ -468,15 +526,21 @@ version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom", + "getrandom 0.3.4", "libc", ] +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "libc" -version = "0.2.178" +version = "0.2.182" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" +checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" [[package]] name = "libgit2-sys" @@ -553,15 +617,15 @@ checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "memchr" -version = "2.7.6" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "num-conv" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" [[package]] name = "num_threads" @@ -592,9 +656,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-src" -version = "300.5.4+3.5.4" +version = "300.5.5+3.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507b3792995dae9b0df8a1c1e3771e8418b7c2d9f0baeba32e6fe8b06c7cb72" +checksum = "3f1787d533e03597a7934fd0a765f0d28e94ecc5fb7789f8053b1e699a56f709" dependencies = [ "cc", ] @@ -662,20 +726,30 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + [[package]] name = "proc-macro2" -version = "1.0.104" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.42" +version = "1.0.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" dependencies = [ "proc-macro2", ] @@ -743,6 +817,12 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + [[package]] name = "serde" version = "1.0.228" @@ -775,9 +855,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.148" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", @@ -850,9 +930,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.111" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -872,12 +952,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.24.0" +version = "3.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1" dependencies = [ "fastrand", - "getrandom", + "getrandom 0.4.1", "once_cell", "rustix", "windows-sys 0.61.2", @@ -894,9 +974,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.44" +version = "0.3.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" dependencies = [ "deranged", "itoa", @@ -904,22 +984,22 @@ dependencies = [ "num-conv", "num_threads", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" [[package]] name = "time-macros" -version = "0.2.24" +version = "0.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" dependencies = [ "num-conv", "time-core", @@ -937,9 +1017,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.22" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-segmentation" @@ -953,11 +1033,17 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + [[package]] name = "url" -version = "2.5.7" +version = "2.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" dependencies = [ "form_urlencoded", "idna", @@ -995,13 +1081,56 @@ dependencies = [ [[package]] name = "wasip2" -version = "1.0.1+wasi-0.2.4" +version = "1.0.2+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" dependencies = [ "wit-bindgen", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags", + "hashbrown 0.15.5", + "indexmap", + "semver", +] + [[package]] name = "winapi" version = "0.3.9" @@ -1123,9 +1252,91 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "wit-bindgen" -version = "0.46.0" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] [[package]] name = "writeable" @@ -1212,6 +1423,6 @@ dependencies = [ [[package]] name = "zmij" -version = "1.0.3" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9747e91771f56fd7893e1164abd78febd14a670ceec257caad15e051de35f06" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/deny.toml b/deny.toml index 6623647..e1ce0e8 100644 --- a/deny.toml +++ b/deny.toml @@ -6,12 +6,8 @@ allow = [ "Apache-2.0", "MIT", "Unicode-3.0", - "Zlib" ] exceptions = [] [bans] multiple-versions = "allow" - -[advisories] -ignore = ["RUSTSEC-2024-0436"] # Ignore because ratatui uses it \ No newline at end of file diff --git a/src/tests/integration_test.rs b/src/tests/integration_test.rs index b82e0ee..056355c 100644 --- a/src/tests/integration_test.rs +++ b/src/tests/integration_test.rs @@ -268,14 +268,14 @@ fn test_integration_repository_fast_forward() { let remote_repo_name = "remote-repo"; let remote_repo_path = remote_temp_dir.path().join(remote_repo_name); - let remote_url = format!("file://{}", remote_repo_path.display()); + let remote_path = remote_repo_path.to_string_lossy().to_string(); // Create repository faking remote let remote_repo = create_git_repo_with_commit(remote_temp_dir.path(), remote_repo_name); // Create git repository, clone from remote let _local_repo = - Repository::clone(&remote_url, local_temp_dir.path().join("local-repo")).unwrap(); + Repository::clone(&remote_path, local_temp_dir.path().join("local-repo")).unwrap(); // Test that the clone was NOT fast-forwarded let args = Args { diff --git a/src/tests/main_test.rs b/src/tests/main_test.rs index 0443e17..64fb413 100644 --- a/src/tests/main_test.rs +++ b/src/tests/main_test.rs @@ -1,309 +1,75 @@ -use std::fs; -use std::process::{Command, Stdio}; -use tempfile::TempDir; - -/// Test the main binary execution with various flags -/// These are more like end-to-end tests - -#[test] -fn test_help_flag() { - let output = Command::new("cargo") - .args(["run", "--", "--help"]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output() - .unwrap(); - - assert!(output.status.success()); - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("A tool to display git repository statuses")); - assert!(stdout.contains("--depth")); - assert!(stdout.contains("--remote")); -} - -#[test] -fn test_version_flag() { - let output = Command::new("cargo") - .args(["run", "--", "--version"]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output() - .unwrap(); - - assert!(output.status.success()); - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("git-statuses")); -} - -#[test] -fn test_legend_flag() { - let output = Command::new("cargo") - .args(["run", "--", "--legend"]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output() - .unwrap(); - - assert!(output.status.success()); - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("Status")); - assert!(stdout.contains("Description")); - assert!(stdout.contains("Clean")); - assert!(stdout.contains("Dirty")); -} - -#[test] -fn test_legend_condensed() { - let output = Command::new("cargo") - .args(["run", "--", "--legend", "--condensed"]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output() - .unwrap(); - - assert!(output.status.success()); - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("Status")); - assert!(stdout.contains("Clean")); - // Should be in condensed format -} - -#[test] -fn test_completions_bash() { - let output = Command::new("cargo") - .args(["run", "--", "--completions", "bash"]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output() - .unwrap(); - - assert!(output.status.success()); - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("_git-statuses")); - assert!(stdout.contains("complete")); -} - -#[test] -fn test_empty_directory() { - let temp_dir = TempDir::new().unwrap(); - - let output = Command::new("cargo") - .args(["run", "--", temp_dir.path().to_str().unwrap()]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output() - .unwrap(); - - assert!(output.status.success()); - // Should complete without error even with no repos -} - -#[test] -fn test_nonexistent_directory() { - let output = Command::new("cargo") - .args(["run", "--", "/path/that/does/not/exist"]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output() - .unwrap(); - - // Should handle nonexistent directory gracefully - let _stderr = String::from_utf8_lossy(&output.stderr); - // May contain error message about directory not existing - // but shouldn't crash +use std::path::PathBuf; + +use clap::Parser; + +use crate::{ + cli::Args, + gitinfo::{repoinfo::RepoInfo, status::Status}, +}; + +fn repo_info_with_status(status: Status, stash_count: usize, fast_forwarded: bool) -> RepoInfo { + RepoInfo { + name: "repo".to_owned(), + branch: "main".to_owned(), + ahead: 3, + behind: 1, + commits: 42, + status, + has_unpushed: true, + remote_url: Some("https://example.com/repo.git".to_owned()), + path: PathBuf::from("/tmp/repo"), + stash_count, + is_local_only: false, + fast_forwarded, + repo_path: "repo".to_owned(), + is_worktree: false, + } } #[test] -fn test_with_actual_git_repo() { - let temp_dir = TempDir::new().unwrap(); - - // Create a git repository - let repo_path = temp_dir.path().join("test-repo"); - fs::create_dir_all(&repo_path).unwrap(); - - // Initialize git repo - Command::new("git") - .args(["init"]) - .current_dir(&repo_path) - .output() - .unwrap(); - - // Configure git - Command::new("git") - .args(["config", "user.name", "Test User"]) - .current_dir(&repo_path) - .output() - .unwrap(); - - Command::new("git") - .args(["config", "user.email", "test@example.com"]) - .current_dir(&repo_path) - .output() - .unwrap(); - - // Create and commit a file - fs::write(repo_path.join("README.md"), "# Test Repo").unwrap(); - Command::new("git") - .args(["add", "README.md"]) - .current_dir(&repo_path) - .output() - .unwrap(); - - Command::new("git") - .args(["commit", "-m", "Initial commit"]) - .current_dir(&repo_path) - .output() - .unwrap(); - - // Run git-statuses on the directory - let output = Command::new("cargo") - .args(["run", "--", temp_dir.path().to_str().unwrap()]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output() - .unwrap(); - - assert!(output.status.success()); - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("test-repo")); - assert!(stdout.contains("main") || stdout.contains("master")); // branch name +fn test_repo_info_format_local_status_local_only() { + let mut repo = repo_info_with_status(Status::Clean, 0, false); + repo.is_local_only = true; + assert_eq!(repo.format_local_status(), "local-only"); } #[test] -fn test_with_summary_flag() { - let temp_dir = TempDir::new().unwrap(); - - let output = Command::new("cargo") - .args(["run", "--", "--summary", temp_dir.path().to_str().unwrap()]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output() - .unwrap(); - - assert!(output.status.success()); - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("Summary:")); - assert!(stdout.contains("Total repositories:")); +fn test_repo_info_format_local_status_with_upstream_counts() { + let repo = repo_info_with_status(Status::Clean, 0, false); + assert_eq!(repo.format_local_status(), "↑3 ↓1"); } #[test] -fn test_depth_flag_integration() { - let temp_dir = TempDir::new().unwrap(); - - // Create nested structure - let level1 = temp_dir.path().join("level1"); - let level2 = level1.join("level2"); - fs::create_dir_all(&level2).unwrap(); - - let output = Command::new("cargo") - .args([ - "run", - "--", - "--depth", - "3", - temp_dir.path().to_str().unwrap(), - ]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output() - .unwrap(); - - assert!(output.status.success()); - // Should scan deeper directories +fn test_repo_info_format_status_with_stash_only() { + let repo = repo_info_with_status(Status::Dirty(2), 4, false); + assert_eq!(repo.format_status_with_stash_and_ff(), "Dirty (2) (4*)"); } #[test] -fn test_remote_flag_integration() { - let temp_dir = TempDir::new().unwrap(); - - let output = Command::new("cargo") - .args(["run", "--", "--remote", temp_dir.path().to_str().unwrap()]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output() - .unwrap(); - - assert!(output.status.success()); - // Should include remote column in output (even if empty) +fn test_repo_info_format_status_with_fast_forward_only() { + let repo = repo_info_with_status(Status::Clean, 0, true); + assert_eq!(repo.format_status_with_stash_and_ff(), "Clean ↑↑"); } #[test] -fn test_condensed_flag_integration() { - let temp_dir = TempDir::new().unwrap(); - - let output = Command::new("cargo") - .args([ - "run", - "--", - "--condensed", - temp_dir.path().to_str().unwrap(), - ]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output() - .unwrap(); - - assert!(output.status.success()); - // Should use condensed table format -} - -#[test] -fn test_multiple_flags_combination() { - let temp_dir = TempDir::new().unwrap(); - - let output = Command::new("cargo") - .args([ - "run", - "--", - "--remote", - "--condensed", - "--summary", - "--depth", - "2", - temp_dir.path().to_str().unwrap(), - ]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output() - .unwrap(); - - assert!(output.status.success()); - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("Summary:")); - // Multiple flags should work together +fn test_repo_info_format_status_with_stash_and_fast_forward() { + let repo = repo_info_with_status(Status::Unpushed, 2, true); + assert_eq!(repo.format_status_with_stash_and_ff(), "Unpushed (2*) ↑↑"); } #[test] -fn test_path_flag_integration() { - let temp_dir = TempDir::new().unwrap(); - - let output = Command::new("cargo") - .args(["run", "--", "--path", temp_dir.path().to_str().unwrap()]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output() - .unwrap(); - - assert!(output.status.success()); - // Should include path column in output -} - -#[test] -fn test_non_clean_flag_integration() { - let temp_dir = TempDir::new().unwrap(); - - let output = Command::new("cargo") - .args([ - "run", - "--", - "--non-clean", - temp_dir.path().to_str().unwrap(), - ]) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .output() - .unwrap(); - - assert!(output.status.success()); - // Should only show non-clean repositories +fn test_args_parse_json_fast_forward_and_subdir() { + let args = Args::parse_from([ + "git-statuses", + "--json", + "--ff", + "--subdir", + "checkout", + "--depth=-1", + ".", + ]); + assert!(args.json); + assert!(args.fast_forward); + assert_eq!(args.subdir.as_deref(), Some("checkout")); + assert_eq!(args.depth, -1); } diff --git a/src/tests/printer_test.rs b/src/tests/printer_test.rs index c786f8f..b833ab2 100644 --- a/src/tests/printer_test.rs +++ b/src/tests/printer_test.rs @@ -3,7 +3,7 @@ use std::path::PathBuf; use crate::cli::Args; use crate::gitinfo::repoinfo::RepoInfo; use crate::gitinfo::status::Status; -use crate::printer::{failed_summary, legend, repositories_table, summary}; +use crate::printer::{failed_summary, json_output, legend, repositories_table, summary}; #[test] fn test_repositories_table_empty() { @@ -442,3 +442,51 @@ fn test_summary_edge_cases() { }]; summary(&edge_repos, 0); } + +#[test] +fn test_repositories_table_marks_worktree_rows() { + let mut repos = vec![RepoInfo { + name: "worktree-repo".to_owned(), + branch: "feature".to_owned(), + ahead: 0, + behind: 0, + commits: 3, + status: Status::Clean, + has_unpushed: false, + remote_url: None, + path: PathBuf::from("/path/to/worktree-repo"), + stash_count: 0, + is_local_only: false, + fast_forwarded: false, + repo_path: "worktree-repo".to_owned(), + is_worktree: true, + }]; + let args = Args { + dir: ".".into(), + depth: 1, + ..Default::default() + }; + repositories_table(&mut repos, &args); +} + +#[test] +fn test_json_output_smoke() { + let repos = vec![RepoInfo { + name: "json-repo".to_owned(), + branch: "main".to_owned(), + ahead: 0, + behind: 0, + commits: 1, + status: Status::Clean, + has_unpushed: false, + remote_url: None, + path: PathBuf::from("/path/to/json-repo"), + stash_count: 0, + is_local_only: false, + fast_forwarded: false, + repo_path: "json-repo".to_owned(), + is_worktree: false, + }]; + let failed = vec!["broken-repo".to_owned()]; + json_output(&repos, &failed); +} From 8ac3962251ac08a3b22dc15d7b28e01a1b80a389 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Sun, 22 Feb 2026 10:53:14 +0100 Subject: [PATCH 2/3] fixup! test: Add GitHub Actions workflow for coverage and enhance test cases --- .github/workflows/ci.yml | 85 ++++++++++++++++++++-------- .github/workflows/coverage.yml | 34 ----------- .github/workflows/publish_checks.yml | 2 +- 3 files changed, 61 insertions(+), 60 deletions(-) delete mode 100644 .github/workflows/coverage.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e98d2bb..de9fbc7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,18 +11,57 @@ on: - main jobs: + + typos: + name: Typos + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + lfs: true + - uses: crate-ci/typos@master + + cargo-shear: + runs-on: ubuntu-latest + needs: typos + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + lfs: true + + - name: Install cargo-binstall + uses: cargo-bins/cargo-binstall@main + + - name: Install cargo-shear + run: cargo binstall --no-confirm cargo-shear + + - run: cargo shear + + cargo-deny: + runs-on: ubuntu-latest + needs: typos + steps: + - uses: actions/checkout@v6 + with: + lfs: true + - uses: EmbarkStudios/cargo-deny-action@v2 + build: name: Build runs-on: ubuntu-latest + needs: [cargo-shear, cargo-deny] steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: lfs: true - uses: dtolnay/rust-toolchain@master with: toolchain: stable - uses: Swatinem/rust-cache@v2 + with: + shared-key: ${{ github.ref_name }} - name: cargo build run: cargo build @@ -30,15 +69,18 @@ jobs: check: name: Check runs-on: ubuntu-latest + needs: build steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: lfs: true - uses: dtolnay/rust-toolchain@master with: toolchain: stable - uses: Swatinem/rust-cache@v2 + with: + shared-key: ${{ github.ref_name }} - name: Set up git user for testing purposes run: | git config --global user.email "ci@example.com" @@ -53,35 +95,28 @@ jobs: - name: cargo test run: cargo test - typos: - name: Typos + tarpaulin: + name: Tarpaulin runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - lfs: true - - uses: crate-ci/typos@master - cargo-shear: - runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: lfs: true - - name: Install cargo-binstall - uses: cargo-bins/cargo-binstall@main + - uses: dtolnay/rust-toolchain@stable - - name: Install cargo-shear - run: cargo binstall --no-confirm cargo-shear + - uses: Swatinem/rust-cache@v2 + with: + shared-key: ${{ github.ref_name }} - - run: cargo shear + - name: Set up git user for tests + run: | + git config --global user.email "ci@example.com" + git config --global user.name "CI User" - cargo-deny: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - lfs: true - - uses: EmbarkStudios/cargo-deny-action@v2 + - name: Install cargo-tarpaulin + uses: taiki-e/install-action@cargo-tarpaulin + + - name: Run coverage check + run: cargo tarpaulin --workspace --all-features --fail-under 90 --out Xml --out Stdout diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml deleted file mode 100644 index af04d6e..0000000 --- a/.github/workflows/coverage.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Coverage - -on: - push: - branches: - - main - pull_request: - branches: - - main - -jobs: - tarpaulin: - name: Tarpaulin - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - with: - lfs: true - - - uses: dtolnay/rust-toolchain@stable - - - uses: Swatinem/rust-cache@v2 - - - name: Set up git user for tests - run: | - git config --global user.email "ci@example.com" - git config --global user.name "CI User" - - - name: Install cargo-tarpaulin - uses: taiki-e/install-action@cargo-tarpaulin - - - name: Run coverage check - run: cargo tarpaulin --workspace --all-features --fail-under 90 --out Xml --out Stdout diff --git a/.github/workflows/publish_checks.yml b/.github/workflows/publish_checks.yml index c68fffd..96e8fcc 100644 --- a/.github/workflows/publish_checks.yml +++ b/.github/workflows/publish_checks.yml @@ -13,7 +13,7 @@ jobs: - uses: dtolnay/rust-toolchain@master with: toolchain: stable - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: lfs: true - uses: Swatinem/rust-cache@v2 From cffeab7e36259d8d918bc98e0200ca1719188d73 Mon Sep 17 00:00:00 2001 From: Nicolas Date: Sun, 22 Feb 2026 11:01:50 +0100 Subject: [PATCH 3/3] fixup! test: Add GitHub Actions workflow for coverage and enhance test cases --- .github/workflows/ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index de9fbc7..3ea949f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -98,6 +98,7 @@ jobs: tarpaulin: name: Tarpaulin runs-on: ubuntu-latest + needs: check steps: - uses: actions/checkout@v6