From 087b8f55c988507caf59facbac1153a878883559 Mon Sep 17 00:00:00 2001 From: Frank Hunleth Date: Sat, 9 May 2026 22:10:30 -0500 Subject: [PATCH 1/5] Simplify size_and_list to buffer empty, partial, exact, and over states --- test/circular_buffer_test.exs | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/test/circular_buffer_test.exs b/test/circular_buffer_test.exs index 82d5563..f407756 100644 --- a/test/circular_buffer_test.exs +++ b/test/circular_buffer_test.exs @@ -108,11 +108,7 @@ defmodule CircularBufferTest do buffer = Enum.reduce(iis, CB.new(size), fn i, cb -> CB.insert(cb, i) end) - oldest = - iis - |> Enum.reverse() - |> Enum.drop(size - 1) - |> Enum.at(0) + oldest = iis |> Enum.take(-size) |> List.first() CB.oldest(buffer) == oldest end @@ -156,17 +152,11 @@ defmodule CircularBufferTest do def size_and_list do let size <- pos_integer() do - let is <- ints(size * 2 + 1, []) do - {size, is} + let n <- range(0, size * 2 + 1) do + let is <- vector(n, integer()) do + {size, is} + end end end end - - defp ints(0, acc), do: acc - - defp ints(size, acc) do - let i <- integer() do - ints(size - 1, [i | acc]) - end - end end From de349605f2dcbdbd9dab5049ad343a1a6ef75c95 Mon Sep 17 00:00:00 2001 From: Frank Hunleth Date: Sat, 9 May 2026 22:19:47 -0500 Subject: [PATCH 2/5] Expand proptest coverage of Enumerable tests --- test/circular_buffer_test.exs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/test/circular_buffer_test.exs b/test/circular_buffer_test.exs index f407756..0fa77c0 100644 --- a/test/circular_buffer_test.exs +++ b/test/circular_buffer_test.exs @@ -44,20 +44,26 @@ defmodule CircularBufferTest do end end - property "member?/1" do - items = such_that({a, b} <- {pos_integer(), pos_integer()}, when: a != b) + property "member?/2 reflects buffer contents" do + forall {size, is} <- size_and_list() do + iis = Enum.with_index(is) + buffer = Enum.reduce(iis, CB.new(size), fn i, cb -> CB.insert(cb, i) end) - forall {a, b} <- items do - cb = CB.new(1) |> CB.insert(a) - !Enum.member?(cb, b) && Enum.member?(cb, a) + kept = Enum.take(iis, -size) + evicted = Enum.drop(iis, -size) + + Enum.all?(kept, &Enum.member?(buffer, &1)) and + Enum.all?(evicted, fn x -> not Enum.member?(buffer, x) end) and + not Enum.member?(buffer, :never_inserted) end end property "implements Enumerable" do - forall is <- list(integer()) do - buffer = Enum.reduce(is, CB.new(length(is) + 1), fn i, cb -> CB.insert(cb, i) end) + forall {size, is} <- size_and_list() do + buffer = Enum.reduce(is, CB.new(size), fn i, cb -> CB.insert(cb, i) end) - Enum.reduce(buffer, 0, fn acc, i -> acc + i end) == Enum.sum(is) + Enum.reduce(buffer, 0, fn elem, acc -> acc + elem end) == + Enum.sum(Enum.take(is, -size)) end end From c49b406470f212120966ec455995da003b458206 Mon Sep 17 00:00:00 2001 From: Frank Hunleth Date: Sat, 9 May 2026 22:26:51 -0500 Subject: [PATCH 3/5] Split the new/1 prop test --- test/circular_buffer_test.exs | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/test/circular_buffer_test.exs b/test/circular_buffer_test.exs index 0fa77c0..4bf8647 100644 --- a/test/circular_buffer_test.exs +++ b/test/circular_buffer_test.exs @@ -11,17 +11,25 @@ defmodule CircularBufferTest do alias CircularBuffer, as: CB - property "new/1 accepts a max size" do - forall i <- integer() do + property "new/1 returns an empty buffer for positive sizes" do + forall size <- pos_integer() do + cb = CB.new(size) + + cb.max_size == size and + cb.count == 0 and + cb.a == [] and + cb.b == [] and + CB.empty?(cb) + end + end + + property "new/1 raises for non-positive sizes" do + forall n <- non_neg_integer() do try do - buffer = CB.new(i) - buffer.max_size == i + CB.new(-n) + false rescue - FunctionClauseError -> - i <= 0 - - _ -> - false + FunctionClauseError -> true end end end From 76cf2a18565b62606b3ed4af86d0e42b5f18073b Mon Sep 17 00:00:00 2001 From: Frank Hunleth Date: Sat, 9 May 2026 22:43:04 -0500 Subject: [PATCH 4/5] Run more proptests since they're fast --- test/circular_buffer_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/circular_buffer_test.exs b/test/circular_buffer_test.exs index 4bf8647..acf5d29 100644 --- a/test/circular_buffer_test.exs +++ b/test/circular_buffer_test.exs @@ -6,7 +6,7 @@ # defmodule CircularBufferTest do use ExUnit.Case, async: false - use PropCheck + use PropCheck, default_opts: [:quiet, {:numtests, 10_000}] doctest CircularBuffer alias CircularBuffer, as: CB From 910843d04c1b545b94b2ab512e99a1027bf14b56 Mon Sep 17 00:00:00 2001 From: Frank Hunleth Date: Sat, 9 May 2026 22:47:32 -0500 Subject: [PATCH 5/5] Fix GHA Node.js 20 warnings --- .github/workflows/elixir.yml | 12 ++++++------ .github/workflows/reuse.yaml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/elixir.yml b/.github/workflows/elixir.yml index b5d6393..7374b9c 100644 --- a/.github/workflows/elixir.yml +++ b/.github/workflows/elixir.yml @@ -23,7 +23,7 @@ jobs: otp: '28' steps: - name: checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 - name: setup @@ -32,7 +32,7 @@ jobs: elixir-version: ${{ matrix.pair.elixir }} otp-version: ${{ matrix.pair.otp }} - name: Retrieve Cached Dependencies - uses: actions/cache@v4 + uses: actions/cache@v5 id: mix-cache with: path: | @@ -62,7 +62,7 @@ jobs: - elixir: '1.19.5' otp: '28' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: fetch-depth: 0 - name: Setup elixir @@ -71,7 +71,7 @@ jobs: elixir-version: ${{ matrix.pair.elixir }} otp-version: ${{ matrix.pair.otp }} - name: Retrieve Cached Dependencies - uses: actions/cache@v4 + uses: actions/cache@v5 id: mix-cache with: path: | @@ -96,7 +96,7 @@ jobs: - elixir: '1.19.5' otp: '28' steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 with: fetch-depth: 0 - uses: erlef/setup-beam@v1 @@ -104,7 +104,7 @@ jobs: elixir-version: ${{ matrix.pair.elixir }} otp-version: ${{ matrix.pair.otp }} - name: Retrieve Cached Dependencies - uses: actions/cache@v4 + uses: actions/cache@v5 id: mix-cache with: path: | diff --git a/.github/workflows/reuse.yaml b/.github/workflows/reuse.yaml index f55ba90..6e9750f 100644 --- a/.github/workflows/reuse.yaml +++ b/.github/workflows/reuse.yaml @@ -8,6 +8,6 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + - uses: actions/checkout@v6 - name: REUSE Compliance Check uses: fsfe/reuse-action@v4