From 7e2cdf3c8e5812baa100e5aa3f85f1bec2b7b39e Mon Sep 17 00:00:00 2001 From: LoricAndre <57358788+LoricAndre@users.noreply.github.com> Date: Thu, 25 Jun 2026 21:12:49 +0200 Subject: [PATCH] tests: improve coverage to 90% (#1099) * tests: improve coverage to 90% * feat: improve coverage * remove most unix-only tests * Update src/skim_tests.rs Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * fixes * chore: misc --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .github/workflows/test.yml | 161 +- AGENTS.md | 4 +- ARCHITECTURE.md | 16 +- justfile | 5 +- src/bin/main.rs | 138 +- src/binds.rs | 134 +- src/binds_tests.rs | 179 ++ src/engine/all.rs | 27 + src/engine/andor.rs | 4 + src/engine/andor_tests.rs | 101 ++ src/engine/exact.rs | 4 + src/engine/exact_tests.rs | 113 ++ src/engine/factory.rs | 12 + src/engine/fuzzy.rs | 65 + src/engine/normalized.rs | 102 ++ src/engine/regexp.rs | 58 + src/engine/split.rs | 85 + src/engine/util.rs | 47 + src/field.rs | 237 +-- src/field_tests.rs | 255 +++ src/fuzzy_matcher/arinae/atom.rs | 67 + src/fuzzy_matcher/arinae/banding.rs | 10 +- src/fuzzy_matcher/arinae/helpers.rs | 10 +- src/fuzzy_matcher/arinae/matrix.rs | 53 + src/fuzzy_matcher/arinae/tests.rs | 90 + src/fuzzy_matcher/clangd.rs | 40 + src/fuzzy_matcher/frizbee.rs | 66 + src/fuzzy_matcher/fzy.rs | 248 +-- src/fuzzy_matcher/fzy_tests.rs | 339 ++++ src/fuzzy_matcher/mod.rs | 40 + src/fuzzy_matcher/skim.rs | 175 +- src/fuzzy_matcher/skim_tests.rs | 204 +++ src/fuzzy_matcher/util.rs | 58 + src/helper/item.rs | 393 +--- src/helper/item_reader.rs | 4 + src/helper/item_reader_tests.rs | 166 ++ src/helper/item_tests.rs | 489 +++++ src/helper/selector.rs | 13 + src/item.rs | 5 + src/item_tests.rs | 218 +++ src/lib.rs | 7 +- src/lib_tests.rs | 99 ++ src/manpage.rs | 1 + src/matcher.rs | 93 + src/options.rs | 72 +- src/options_tests.rs | 289 +++ src/output.rs | 304 ++++ src/popup/mod.rs | 110 +- src/popup/mod_tests.rs | 100 ++ src/popup/tmux.rs | 155 +- src/popup/tmux_tests.rs | 125 ++ src/popup/zellij.rs | 168 +- src/popup/zellij_tests.rs | 181 ++ src/reader.rs | 112 ++ src/shell.rs | 113 +- src/shell_tests.rs | 109 ++ src/skim.rs | 6 +- src/skim_item.rs | 25 + src/skim_tests.rs | 215 +++ src/spinlock.rs | 1 + src/theme.rs | 300 +--- src/theme_tests.rs | 429 +++++ src/thread_pool.rs | 198 +-- src/thread_pool_tests.rs | 202 +++ src/tui/app.rs | 41 +- src/tui/app_tests.rs | 1573 +++++++++++++++++ src/tui/backend.rs | 45 + src/tui/event.rs | 4 + src/tui/event_tests.rs | 190 ++ src/tui/header.rs | 92 + src/tui/input.rs | 8 +- src/tui/input_tests.rs | 238 +++ src/tui/item_list.rs | 4 + src/tui/item_list_tests.rs | 291 +++ src/tui/item_renderer.rs | 219 +-- src/tui/item_renderer_tests.rs | 277 +++ src/tui/layout.rs | 539 +----- src/tui/layout_tests.rs | 535 ++++++ src/tui/mod.rs | 35 + src/tui/options.rs | 85 +- src/tui/options_tests.rs | 106 ++ src/tui/preview.rs | 45 +- src/tui/preview_tests.rs | 171 ++ src/tui/statusline.rs | 59 + src/tui/util.rs | 280 +-- src/tui/util_tests.rs | 414 +++++ src/util.rs | 136 +- src/util_tests.rs | 278 +++ tests/ansi.rs | 83 +- tests/cli.rs | 249 +++ tests/common/insta.rs | 97 + tests/common/mod.rs | 24 +- tests/common/tmux.rs | 5 +- tests/highlighting.rs | 61 +- tests/history.rs | 95 - tests/listen.rs | 12 +- tests/options.rs | 116 +- tests/popup.rs | 9 +- .../ansi__ansi_flag_disabled@001.snap | 29 + .../ansi__ansi_flag_disabled@color002.snap | 12 + .../ansi__ansi_flag_enabled@001.snap | 29 + .../ansi__ansi_flag_enabled@color002.snap | 11 + .../ansi__ansi_flag_no_strip@001.snap | 29 + .../ansi__ansi_flag_no_strip@color002.snap | 11 + ...i__ansi_matching_on_stripped_text@001.snap | 29 + ...i__ansi_matching_on_stripped_text@003.snap | 29 + ...si_matching_on_stripped_text@color002.snap | 19 + .../snapshots/ansi__prompt_ansi@color002.snap | 11 + .../highlighting__highlight_match@001.snap | 29 + ...ighlighting__highlight_match@color002.snap | 12 + ...ghlighting__highlight_split_match@001.snap | 29 + ...hting__highlight_split_match@color002.snap | 15 + .../options__opt_null_delimiter_nth@001.snap | 29 + .../options__opt_null_delimiter_nth@002.snap | 29 + .../options__opt_null_delimiter_nth@003.snap | 29 + ...ions__opt_null_delimiter_with_nth@001.snap | 29 + .../options__opt_pre_select_file.snap | 29 + tests/snapshots/options__opt_read0@001.snap | 29 + .../snapshots/options__vanilla_basic@001.snap | 29 + tests/unix.rs | 331 +--- 120 files changed, 10801 insertions(+), 4292 deletions(-) create mode 100644 src/binds_tests.rs create mode 100644 src/engine/andor_tests.rs create mode 100644 src/engine/exact_tests.rs create mode 100644 src/field_tests.rs create mode 100644 src/fuzzy_matcher/fzy_tests.rs create mode 100644 src/fuzzy_matcher/skim_tests.rs create mode 100644 src/helper/item_reader_tests.rs create mode 100644 src/helper/item_tests.rs create mode 100644 src/item_tests.rs create mode 100644 src/lib_tests.rs create mode 100644 src/options_tests.rs create mode 100644 src/popup/mod_tests.rs create mode 100644 src/popup/tmux_tests.rs create mode 100644 src/popup/zellij_tests.rs create mode 100644 src/shell_tests.rs create mode 100644 src/skim_tests.rs create mode 100644 src/theme_tests.rs create mode 100644 src/thread_pool_tests.rs create mode 100644 src/tui/app_tests.rs create mode 100644 src/tui/event_tests.rs create mode 100644 src/tui/input_tests.rs create mode 100644 src/tui/item_list_tests.rs create mode 100644 src/tui/item_renderer_tests.rs create mode 100644 src/tui/layout_tests.rs create mode 100644 src/tui/options_tests.rs create mode 100644 src/tui/preview_tests.rs create mode 100644 src/tui/util_tests.rs create mode 100644 src/util_tests.rs create mode 100644 tests/cli.rs delete mode 100644 tests/history.rs create mode 100644 tests/snapshots/ansi__ansi_flag_disabled@001.snap create mode 100644 tests/snapshots/ansi__ansi_flag_disabled@color002.snap create mode 100644 tests/snapshots/ansi__ansi_flag_enabled@001.snap create mode 100644 tests/snapshots/ansi__ansi_flag_enabled@color002.snap create mode 100644 tests/snapshots/ansi__ansi_flag_no_strip@001.snap create mode 100644 tests/snapshots/ansi__ansi_flag_no_strip@color002.snap create mode 100644 tests/snapshots/ansi__ansi_matching_on_stripped_text@001.snap create mode 100644 tests/snapshots/ansi__ansi_matching_on_stripped_text@003.snap create mode 100644 tests/snapshots/ansi__ansi_matching_on_stripped_text@color002.snap create mode 100644 tests/snapshots/ansi__prompt_ansi@color002.snap create mode 100644 tests/snapshots/highlighting__highlight_match@001.snap create mode 100644 tests/snapshots/highlighting__highlight_match@color002.snap create mode 100644 tests/snapshots/highlighting__highlight_split_match@001.snap create mode 100644 tests/snapshots/highlighting__highlight_split_match@color002.snap create mode 100644 tests/snapshots/options__opt_null_delimiter_nth@001.snap create mode 100644 tests/snapshots/options__opt_null_delimiter_nth@002.snap create mode 100644 tests/snapshots/options__opt_null_delimiter_nth@003.snap create mode 100644 tests/snapshots/options__opt_null_delimiter_with_nth@001.snap create mode 100644 tests/snapshots/options__opt_pre_select_file.snap create mode 100644 tests/snapshots/options__opt_read0@001.snap create mode 100644 tests/snapshots/options__vanilla_basic@001.snap diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f2564aee..c33436e9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,7 @@ jobs: nextest: runs-on: ${{matrix.os}} strategy: - matrix: + matrix: &matrix build: [linux, macos, windows] include: - build: linux @@ -34,9 +34,9 @@ jobs: target: x86_64-pc-windows-msvc permissions: contents: read - code-quality: write steps: - - name: "[linux] Install dependencies" + - &linux-deps + name: "[linux] Install dependencies" run: | sudo apt-get install tmux tmux -V @@ -51,42 +51,25 @@ jobs: env: HOMEBREW_NO_AUTO_UPDATE: 1 - - name: Checkout repository + - &checkout + name: Checkout repository uses: actions/checkout@v6 with: fetch-depth: 1 - - run: rustup toolchain install - - uses: taiki-e/install-action@v2 + - &toolchain + name: Install rust toolchain + run: rustup toolchain install + - &nextest-install + name: Install nextest + uses: taiki-e/install-action@v2 with: tool: nextest@0.9 - - uses: taiki-e/install-action@v2 - with: - tool: cargo-llvm-cov@0.8 - - name: Cache + - &cache + name: Setup cargo cache uses: Swatinem/rust-cache@v2 - with: &cache-with - key: ${{ runner.os }} - add-job-id-key: "false" - add-rust-environment-hash-key: "false" - env-vars: "____" - cache-on-failure: "true" - cache-all-crates: "true" - - name: Run doctests run: cargo test --doc - - name: "[linux] Run tests with coverage" - if: runner.os == 'Linux' - # Do not use `--all-targets` to avoid running benches - run: | - cargo llvm-cov nextest --release --profile ci --bins --lib --examples --tests --no-report - cargo llvm-cov report --release --cobertura --output-path coverage.xml - cargo llvm-cov report --release --html - echo "COVERAGE_PERCENT=$(cargo llvm-cov report --release | tail -n1 | awk '{ print $4 }')" | tee --append $GITHUB_ENV - env: - LC_ALL: en_US.UTF-8 - TERM: xterm-256color - - name: "[macos/windows] Run tests" - if: runner.os != 'Linux' + - name: "Run tests" # Do not use `--all-targets` to avoid running benches run: cargo nextest run --release --profile ci --bins --lib --examples --tests env: @@ -107,89 +90,86 @@ jobs: fi done shell: bash - - name: "[linux] Upload coverage report" - if: runner.os == 'Linux' && (github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository) + + coverage: + runs-on: ubuntu-latest + permissions: + code-quality: write + steps: + - *linux-deps + - *checkout + - *toolchain + - *nextest-install + - uses: taiki-e/install-action@v2 + with: + tool: cargo-llvm-cov@0.8 + - *cache + - name: "Run tests with coverage" + # Do not use `--all-targets` to avoid running benches + run: | + cargo +nightly llvm-cov nextest --release --profile ci --branch --bins --lib --examples --tests --no-report + cargo +nightly llvm-cov report --release --cobertura --output-path coverage.xml + cargo +nightly llvm-cov report --release --html + echo "COVERAGE_PERCENT=$(cargo +nightly llvm-cov report --release | tail -n1 | awk '{ print $13 }')" | tee --append $GITHUB_ENV + env: + LC_ALL: en_US.UTF-8 + TERM: xterm-256color + - name: "Upload coverage report" + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository continue-on-error: true uses: actions/upload-code-coverage@v1 with: file: coverage.xml language: Rust label: ${{ runner.os }} - - name: "[linux] Generate coverage badge" - if: &if-linux-master runner.os == 'Linux' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) + + - name: "Generate coverage badge" + if: &if-master github.ref == format('refs/heads/{0}', github.event.repository.default_branch) uses: emibcn/badge-action@v2.0.2 with: label: 'Coverage' status: ${{ env.COVERAGE_PERCENT }} color: 'blue' path: 'target/llvm-cov/html/coverage.svg' - - name: "[linux] Upload default branch results to gh pages" - if: *if-linux-master + - name: "Upload default branch results to gh pages" + if: *if-master uses: actions/upload-pages-artifact@v3 with: path: target/llvm-cov/html deploy-coverage-page: - needs: nextest + needs: coverage + runs-on: ubuntu-latest permissions: pages: write id-token: write environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest steps: - - name: "[linux] Deploy gh pages" + - name: "Deploy gh pages" id: deployment - if: *if-linux-master + if: *if-master uses: actions/deploy-pages@v4 clippy: runs-on: ${{matrix.os}} strategy: - matrix: - build: [linux, macos, windows] - include: - - build: linux - os: ubuntu-latest - target: x86_64-unknown-linux-musl - - build: macos - os: macos-latest - target: x86_64-apple-darwin - - build: windows - os: windows-latest - target: x86_64-pc-windows-msvc + matrix: *matrix steps: - - name: Checkout repository - uses: actions/checkout@v6 - with: - fetch-depth: 1 - - run: rustup toolchain install - - name: Cache - uses: Swatinem/rust-cache@v2 - with: *cache-with + - *checkout + - *toolchain + - *cache - name: Clippy run: cargo clippy rustfmt: runs-on: ${{matrix.os}} strategy: - matrix: - build: [linux, macos, windows] - include: - - build: linux - os: ubuntu-latest - target: x86_64-unknown-linux-musl - - build: macos - os: macos-latest - target: x86_64-apple-darwin - - build: windows - os: windows-latest - target: x86_64-pc-windows-msvc + matrix: *matrix steps: - - name: Checkout repository - uses: actions/checkout@v6 - - run: rustup toolchain install + - *checkout + - *toolchain - name: Check formatting run: | cargo fmt --all -- --check @@ -197,25 +177,11 @@ jobs: build-no-default-features: runs-on: ${{matrix.os}} strategy: - matrix: - build: [linux, macos, windows] - include: - - build: linux - os: ubuntu-latest - target: x86_64-unknown-linux-musl - - build: macos - os: macos-latest - target: x86_64-apple-darwin - - build: windows - os: windows-latest - target: x86_64-pc-windows-msvc + matrix: *matrix steps: - - name: Checkout repository - uses: actions/checkout@v6 - - run: rustup toolchain install - - name: Cache - uses: Swatinem/rust-cache@v2 - with: *cache-with + - *checkout + - *toolchain + - *cache - name: Build without any feature run: | cargo build --no-default-features @@ -224,11 +190,8 @@ jobs: msrv: runs-on: ubuntu-latest steps: - - name: Checkout repository - uses: actions/checkout@v6 - with: - fetch-depth: 1 - - run: rustup toolchain install + - *checkout + - *toolchain - uses: taiki-e/install-action@v2 with: tool: cargo-msrv@0.19 diff --git a/AGENTS.md b/AGENTS.md index 819a3cec..c0a87c5d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -62,7 +62,8 @@ insta_test!(my_test, @interactive, &["-i", "--cmd", "echo {q}"]); **DSL variant** (multiple snapshots with interaction between them): ```rust insta_test!(my_test, ["a", "b", "c"], &["--multi"], { - @snap; // take a snapshot + @snap; // take a snapshot (cell text only) + @snap_color; // snapshot cell styling (fg/bg/modifier) instead @key Up; // send a named key (Enter, Down, Tab, …) @char 'f'; // send a single character @type "foo"; // type a string @@ -83,6 +84,7 @@ insta_test!(my_test, ["a", "b", "c"], &["--multi"], { |---|---|---| | Simple variant | `{file}__{test}.snap` | `options__opt_wrap.snap` | | DSL variant — Nth `@snap` | `{file}__{test}@{NNN}.snap` | `options__opt_cycle@002.snap` | +| DSL variant — Nth `@snap_color` | `{file}__{test}@color{NNN}.snap` | `ansi__ansi_flag_enabled@color002.snap` | DSL snapshots use a zero-padded three-digit suffix (`@001`, `@002`, …) so that `cargo insta review` presents them in the order they were taken. diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index c779e011..e215d576 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -94,7 +94,7 @@ skim/ ← workspace root │ ├── lib.rs ← library root; re-exports public types │ ├── skim.rs ← Skim orchestrator │ ├── options.rs ← SkimOptions (all CLI / library options) -│ ├── output.rs ← SkimOutput (returned to callers) +│ ├── output.rs ← SkimOutput (returned to callers) + BinOptions/write_output (CLI serialization) │ ├── reader.rs ← Reader + ReaderControl + CommandCollector trait │ ├── matcher.rs ← Matcher + MatcherControl (parallel worker dispatcher) │ ├── item.rs ← ItemPool, MatchedItem, Rank, RankBuilder @@ -981,14 +981,14 @@ pub struct SkimOutput { } ``` -In the CLI binary, the output phase (`sk_main` after `Skim::run_with`): -1. Prints `query` if `--print-query` -2. Prints `cmd` if `--print-cmd` -3. Prints `header` if `--print-header` -4. Prints current item text if `--print-current` -5. Prints `accept_key` if `--expect` matched +The output phase is `SkimOutput::write_output(&mut out, &BinOptions)` (`src/output.rs`), called by the CLI binary with a buffered stdout. `BinOptions` (also in `src/output.rs`, built via `BinOptions::from_opts`) captures the output-related flags. Keeping the serialization independent of stdout lets it be unit-tested by passing a `Vec`. It writes, in order: +1. `query` if `--print-query` +2. `cmd` if `--print-cmd` +3. `header` if `--print-header` +4. current item text if `--print-current` +5. `accept_key` if `--expect` matched 6. For each selected item: strips ANSI if `--ansi && !--no-strip-ansi`, prints text + score if `--print-score` -7. If `--output-format