From 3ea6a030bfd3f67a8b247e128a028c7ee5514709 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 24 Nov 2025 18:51:24 +0000 Subject: [PATCH 1/5] Initial plan From e62b1d6e13597306769d9d8fc8dd648c1f5edb94 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 24 Nov 2025 18:57:15 +0000 Subject: [PATCH 2/5] Add committed cache specs and populate initial cache files Co-authored-by: nhorton <204146+nhorton@users.noreply.github.com> --- spec/committed_cache_spec.rb | 164 ++++++++++++++++++ .../39cc398b810ada504bc9d10624575cf9.key | 1 + .../39cc398b810ada504bc9d10624575cf9.value | Bin 0 -> 45 bytes .../39d971627e43c9bf240a49201b62f115.key | 1 + .../39d971627e43c9bf240a49201b62f115.value | Bin 0 -> 59 bytes spec/fixtures/committed_cache/README.md | 20 +++ .../ca63624a99ad3e461af0d7c8a2d5a520.key | 1 + .../ca63624a99ad3e461af0d7c8a2d5a520.value | Bin 0 -> 61 bytes 8 files changed, 187 insertions(+) create mode 100644 spec/committed_cache_spec.rb create mode 100644 spec/fixtures/committed_cache/39cc398b810ada504bc9d10624575cf9.key create mode 100644 spec/fixtures/committed_cache/39cc398b810ada504bc9d10624575cf9.value create mode 100644 spec/fixtures/committed_cache/39d971627e43c9bf240a49201b62f115.key create mode 100644 spec/fixtures/committed_cache/39d971627e43c9bf240a49201b62f115.value create mode 100644 spec/fixtures/committed_cache/README.md create mode 100644 spec/fixtures/committed_cache/ca63624a99ad3e461af0d7c8a2d5a520.key create mode 100644 spec/fixtures/committed_cache/ca63624a99ad3e461af0d7c8a2d5a520.value diff --git a/spec/committed_cache_spec.rb b/spec/committed_cache_spec.rb new file mode 100644 index 0000000..48876eb --- /dev/null +++ b/spec/committed_cache_spec.rb @@ -0,0 +1,164 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe "Committed Cache Directory" do + # Use a non-git-ignored directory for cache storage + let(:committed_cache_path) { File.join(__dir__, "fixtures", "committed_cache") } + let(:store) { ActiveSupport::Cache::SourceControlCacheStore.new(cache_path: committed_cache_path) } + + # Track files that exist at the start of the test suite + let(:initial_files) do + if File.directory?(committed_cache_path) + Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) + .reject { |f| File.directory?(f) } + .sort + else + [] + end + end + + describe "initial cache population" do + it "creates the cache directory if it doesn't exist" do + expect(File.directory?(committed_cache_path)).to be true + end + + it "populates cache with predefined entries" do + # Write predefined cache entries that will be committed + store.write("user:123:profile", { name: "John Doe", email: "john@example.com" }) + store.write("user:456:profile", { name: "Jane Smith", email: "jane@example.com" }) + store.write("config:app:settings", { theme: "dark", language: "en" }) + + # Verify the entries were written + expect(store.read("user:123:profile")).to eq({ name: "John Doe", email: "john@example.com" }) + expect(store.read("user:456:profile")).to eq({ name: "Jane Smith", email: "jane@example.com" }) + expect(store.read("config:app:settings")).to eq({ theme: "dark", language: "en" }) + end + + it "creates .key and .value files for each entry" do + # Ensure files exist + cache_files = Dir.glob(File.join(committed_cache_path, "*")) + + # We expect at least 6 files (3 entries × 2 files each) + expect(cache_files.length).to be >= 6 + + # Check that we have both .key and .value files + key_files = cache_files.select { |f| f.end_with?(".key") } + value_files = cache_files.select { |f| f.end_with?(".value") } + + expect(key_files.length).to be >= 3 + expect(value_files.length).to be >= 3 + end + end + + describe "cache stability verification" do + before(:all) do + # Capture the state of files before any tests run + committed_cache_path = File.join(__dir__, "fixtures", "committed_cache") + store = ActiveSupport::Cache::SourceControlCacheStore.new(cache_path: committed_cache_path) + + # Ensure initial cache entries exist + store.write("user:123:profile", { name: "John Doe", email: "john@example.com" }) + store.write("user:456:profile", { name: "Jane Smith", email: "jane@example.com" }) + store.write("config:app:settings", { theme: "dark", language: "en" }) + + @initial_file_list = Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) + .reject { |f| File.directory?(f) } + .sort + end + + it "does not create new files when reading existing entries" do + # Read existing entries + store.read("user:123:profile") + store.read("user:456:profile") + store.read("config:app:settings") + + # Get current file list + current_files = Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) + .reject { |f| File.directory?(f) } + .sort + + # Verify no new files were created + expect(current_files).to eq(@initial_file_list) + end + + it "does not create new files when writing to existing keys with same values" do + # Write same values to existing keys + store.write("user:123:profile", { name: "John Doe", email: "john@example.com" }) + store.write("user:456:profile", { name: "Jane Smith", email: "jane@example.com" }) + store.write("config:app:settings", { theme: "dark", language: "en" }) + + # Get current file list + current_files = Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) + .reject { |f| File.directory?(f) } + .sort + + # Verify no new files were created (same files should exist) + expect(current_files).to eq(@initial_file_list) + end + + it "has all expected cache files present" do + # Verify that all expected keys exist + expect(store.read("user:123:profile")).to eq({ name: "John Doe", email: "john@example.com" }) + expect(store.read("user:456:profile")).to eq({ name: "Jane Smith", email: "jane@example.com" }) + expect(store.read("config:app:settings")).to eq({ theme: "dark", language: "en" }) + end + + it "maintains the exact file count" do + current_files = Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) + .reject { |f| File.directory?(f) } + .sort + + # Should have exactly 7 files (3 entries × 2 files each + 1 README.md) + expect(current_files.length).to eq(7) + end + + it "does not create new files during multiple read operations" do + # Perform multiple read operations + 10.times do + store.read("user:123:profile") + store.read("user:456:profile") + store.read("config:app:settings") + end + + # Get current file list + current_files = Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) + .reject { |f| File.directory?(f) } + .sort + + # Verify no new files were created + expect(current_files).to eq(@initial_file_list) + end + end + + describe "file content verification" do + it "preserves original keys in .key files" do + key_files = Dir.glob(File.join(committed_cache_path, "*.key")) + expect(key_files.length).to eq(3) + + # Read all key files and verify they contain expected keys + key_contents = key_files.map { |f| File.read(f) }.sort + expect(key_contents).to contain_exactly( + "config:app:settings", + "user:123:profile", + "user:456:profile" + ) + end + + it "has valid value files that can be deserialized" do + value_files = Dir.glob(File.join(committed_cache_path, "*.value")) + expect(value_files.length).to eq(3) + + # All value files should be readable and deserializable + value_files.each do |value_file| + expect(File.read(value_file).length).to be > 0 + end + end + + it "includes README.md documentation" do + readme_path = File.join(committed_cache_path, "README.md") + expect(File.exist?(readme_path)).to be true + expect(File.read(readme_path)).to include("Committed Cache Directory") + end + end +end diff --git a/spec/fixtures/committed_cache/39cc398b810ada504bc9d10624575cf9.key b/spec/fixtures/committed_cache/39cc398b810ada504bc9d10624575cf9.key new file mode 100644 index 0000000..3c82369 --- /dev/null +++ b/spec/fixtures/committed_cache/39cc398b810ada504bc9d10624575cf9.key @@ -0,0 +1 @@ +config:app:settings \ No newline at end of file diff --git a/spec/fixtures/committed_cache/39cc398b810ada504bc9d10624575cf9.value b/spec/fixtures/committed_cache/39cc398b810ada504bc9d10624575cf9.value new file mode 100644 index 0000000000000000000000000000000000000000..8a65748439d52d8069e9c112f9126db9f4aaf65b GIT binary patch literal 45 zcmZQz;fQ9dX1C%h$wLusrvRSi*0075$5TO77 literal 0 HcmV?d00001 diff --git a/spec/fixtures/committed_cache/README.md b/spec/fixtures/committed_cache/README.md new file mode 100644 index 0000000..2fc4b84 --- /dev/null +++ b/spec/fixtures/committed_cache/README.md @@ -0,0 +1,20 @@ +# Committed Cache Directory + +This directory contains cache files that are intentionally committed to source control for testing purposes. + +## Purpose + +This directory is used by the `committed_cache_spec.rb` test suite to verify that: +1. Cache files can be stored in a non-git-ignored directory +2. Once populated, no new files are created on subsequent runs +3. The cache remains stable across different environments and PRs + +## Files + +The cache files in this directory are generated by the test suite and should not be manually modified. +They represent a stable set of cache entries used for validation testing. + +## Do Not Ignore + +**Important:** This directory and its contents should NOT be added to `.gitignore`. +The cache files are intentionally version-controlled to ensure test stability. diff --git a/spec/fixtures/committed_cache/ca63624a99ad3e461af0d7c8a2d5a520.key b/spec/fixtures/committed_cache/ca63624a99ad3e461af0d7c8a2d5a520.key new file mode 100644 index 0000000..e45287e --- /dev/null +++ b/spec/fixtures/committed_cache/ca63624a99ad3e461af0d7c8a2d5a520.key @@ -0,0 +1 @@ +user:456:profile \ No newline at end of file diff --git a/spec/fixtures/committed_cache/ca63624a99ad3e461af0d7c8a2d5a520.value b/spec/fixtures/committed_cache/ca63624a99ad3e461af0d7c8a2d5a520.value new file mode 100644 index 0000000000000000000000000000000000000000..ff45501dc27d91eb4923d88d4b4f743d72829c6c GIT binary patch literal 61 zcmZQz;fQ9dX1C(ZOUzC6RO0ta%u7`W&dn^zV6$R#4YA@%%}vbA@l+Dc0!lcfRwU*Y P Date: Mon, 24 Nov 2025 19:00:51 +0000 Subject: [PATCH 3/5] Refactor committed cache specs based on code review feedback Co-authored-by: nhorton <204146+nhorton@users.noreply.github.com> --- spec/committed_cache_spec.rb | 45 +++++++++++++++++------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/spec/committed_cache_spec.rb b/spec/committed_cache_spec.rb index 48876eb..e05e038 100644 --- a/spec/committed_cache_spec.rb +++ b/spec/committed_cache_spec.rb @@ -7,17 +7,6 @@ let(:committed_cache_path) { File.join(__dir__, "fixtures", "committed_cache") } let(:store) { ActiveSupport::Cache::SourceControlCacheStore.new(cache_path: committed_cache_path) } - # Track files that exist at the start of the test suite - let(:initial_files) do - if File.directory?(committed_cache_path) - Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) - .reject { |f| File.directory?(f) } - .sort - else - [] - end - end - describe "initial cache population" do it "creates the cache directory if it doesn't exist" do expect(File.directory?(committed_cache_path)).to be true @@ -52,22 +41,24 @@ end describe "cache stability verification" do - before(:all) do - # Capture the state of files before any tests run - committed_cache_path = File.join(__dir__, "fixtures", "committed_cache") - store = ActiveSupport::Cache::SourceControlCacheStore.new(cache_path: committed_cache_path) - - # Ensure initial cache entries exist + # Capture initial state for comparison + let(:initial_file_list) do + Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) + .reject { |f| File.directory?(f) } + .sort + end + + before(:each) do + # Ensure cache entries exist before each test store.write("user:123:profile", { name: "John Doe", email: "john@example.com" }) store.write("user:456:profile", { name: "Jane Smith", email: "jane@example.com" }) store.write("config:app:settings", { theme: "dark", language: "en" }) - - @initial_file_list = Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) - .reject { |f| File.directory?(f) } - .sort end it "does not create new files when reading existing entries" do + # Capture state before reading + files_before = initial_file_list + # Read existing entries store.read("user:123:profile") store.read("user:456:profile") @@ -79,10 +70,13 @@ .sort # Verify no new files were created - expect(current_files).to eq(@initial_file_list) + expect(current_files).to eq(files_before) end it "does not create new files when writing to existing keys with same values" do + # Capture state before writing + files_before = initial_file_list + # Write same values to existing keys store.write("user:123:profile", { name: "John Doe", email: "john@example.com" }) store.write("user:456:profile", { name: "Jane Smith", email: "jane@example.com" }) @@ -94,7 +88,7 @@ .sort # Verify no new files were created (same files should exist) - expect(current_files).to eq(@initial_file_list) + expect(current_files).to eq(files_before) end it "has all expected cache files present" do @@ -114,6 +108,9 @@ end it "does not create new files during multiple read operations" do + # Capture state before reading + files_before = initial_file_list + # Perform multiple read operations 10.times do store.read("user:123:profile") @@ -127,7 +124,7 @@ .sort # Verify no new files were created - expect(current_files).to eq(@initial_file_list) + expect(current_files).to eq(files_before) end end From 0eec3e50be1f92aaa0ae5573635bbad68ae9f7be Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 24 Nov 2025 19:18:12 +0000 Subject: [PATCH 4/5] Refactor committed cache specs based on PR feedback - Remove initial cache population block (files now exist) - Add shared examples for cache validation - Move cache entries to top-level let blocks - Configure store with compress: false and raw: true - Use JSON for readable value files - Regenerate value files with readable JSON format Co-authored-by: nhorton <204146+nhorton@users.noreply.github.com> --- spec/committed_cache_spec.rb | 145 ++++++++---------- .../39cc398b810ada504bc9d10624575cf9.value | Bin 45 -> 45 bytes .../39d971627e43c9bf240a49201b62f115.value | Bin 59 -> 59 bytes .../ca63624a99ad3e461af0d7c8a2d5a520.value | Bin 61 -> 61 bytes 4 files changed, 65 insertions(+), 80 deletions(-) diff --git a/spec/committed_cache_spec.rb b/spec/committed_cache_spec.rb index e05e038..bf99c05 100644 --- a/spec/committed_cache_spec.rb +++ b/spec/committed_cache_spec.rb @@ -1,42 +1,55 @@ # frozen_string_literal: true require "spec_helper" +require "json" RSpec.describe "Committed Cache Directory" do # Use a non-git-ignored directory for cache storage let(:committed_cache_path) { File.join(__dir__, "fixtures", "committed_cache") } - let(:store) { ActiveSupport::Cache::SourceControlCacheStore.new(cache_path: committed_cache_path) } - - describe "initial cache population" do - it "creates the cache directory if it doesn't exist" do - expect(File.directory?(committed_cache_path)).to be true + # Configure store with raw mode to avoid compression + let(:store) { ActiveSupport::Cache::SourceControlCacheStore.new(cache_path: committed_cache_path, compress: false) } + + # Predefined cache entries (keys and values as JSON strings for readability) + let(:cache_entries) do + { + "user:123:profile" => { name: "John Doe", email: "john@example.com" }.to_json, + "user:456:profile" => { name: "Jane Smith", email: "jane@example.com" }.to_json, + "config:app:settings" => { theme: "dark", language: "en" }.to_json + } + end + + # Shared examples for validating cache state + shared_examples "validates committed cache files" do + it "has the expected number of key files" do + key_files = Dir.glob(File.join(committed_cache_path, "*.key")) + expect(key_files.length).to eq(3) end - - it "populates cache with predefined entries" do - # Write predefined cache entries that will be committed - store.write("user:123:profile", { name: "John Doe", email: "john@example.com" }) - store.write("user:456:profile", { name: "Jane Smith", email: "jane@example.com" }) - store.write("config:app:settings", { theme: "dark", language: "en" }) - - # Verify the entries were written - expect(store.read("user:123:profile")).to eq({ name: "John Doe", email: "john@example.com" }) - expect(store.read("user:456:profile")).to eq({ name: "Jane Smith", email: "jane@example.com" }) - expect(store.read("config:app:settings")).to eq({ theme: "dark", language: "en" }) + + it "has the expected number of value files" do + value_files = Dir.glob(File.join(committed_cache_path, "*.value")) + expect(value_files.length).to eq(3) end - - it "creates .key and .value files for each entry" do - # Ensure files exist - cache_files = Dir.glob(File.join(committed_cache_path, "*")) - - # We expect at least 6 files (3 entries × 2 files each) - expect(cache_files.length).to be >= 6 - - # Check that we have both .key and .value files - key_files = cache_files.select { |f| f.end_with?(".key") } - value_files = cache_files.select { |f| f.end_with?(".value") } - - expect(key_files.length).to be >= 3 - expect(value_files.length).to be >= 3 + + it "preserves original keys in .key files" do + key_files = Dir.glob(File.join(committed_cache_path, "*.key")) + key_contents = key_files.map { |f| File.read(f) }.sort + expect(key_contents).to contain_exactly(*cache_entries.keys.sort) + end + + it "has valid value files that can be deserialized" do + value_files = Dir.glob(File.join(committed_cache_path, "*.value")) + # All value files should be readable + value_files.each do |value_file| + expect(File.read(value_file).length).to be > 0 + end + end + + it "maintains the exact file count" do + current_files = Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) + .reject { |f| File.directory?(f) } + .sort + # Should have exactly 7 files (3 entries × 2 files each + 1 README.md) + expect(current_files.length).to eq(7) end end @@ -49,20 +62,20 @@ end before(:each) do - # Ensure cache entries exist before each test - store.write("user:123:profile", { name: "John Doe", email: "john@example.com" }) - store.write("user:456:profile", { name: "Jane Smith", email: "jane@example.com" }) - store.write("config:app:settings", { theme: "dark", language: "en" }) + # Ensure cache entries exist before each test using raw mode + cache_entries.each do |key, value| + store.write(key, value, raw: true) + end end it "does not create new files when reading existing entries" do # Capture state before reading files_before = initial_file_list - # Read existing entries - store.read("user:123:profile") - store.read("user:456:profile") - store.read("config:app:settings") + # Read existing entries with raw mode + cache_entries.keys.each do |key| + store.read(key, raw: true) + end # Get current file list current_files = Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) @@ -77,10 +90,10 @@ # Capture state before writing files_before = initial_file_list - # Write same values to existing keys - store.write("user:123:profile", { name: "John Doe", email: "john@example.com" }) - store.write("user:456:profile", { name: "Jane Smith", email: "jane@example.com" }) - store.write("config:app:settings", { theme: "dark", language: "en" }) + # Write same values to existing keys with raw mode + cache_entries.each do |key, value| + store.write(key, value, raw: true) + end # Get current file list current_files = Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) @@ -93,18 +106,9 @@ it "has all expected cache files present" do # Verify that all expected keys exist - expect(store.read("user:123:profile")).to eq({ name: "John Doe", email: "john@example.com" }) - expect(store.read("user:456:profile")).to eq({ name: "Jane Smith", email: "jane@example.com" }) - expect(store.read("config:app:settings")).to eq({ theme: "dark", language: "en" }) - end - - it "maintains the exact file count" do - current_files = Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) - .reject { |f| File.directory?(f) } - .sort - - # Should have exactly 7 files (3 entries × 2 files each + 1 README.md) - expect(current_files.length).to eq(7) + cache_entries.each do |key, expected_value| + expect(store.read(key, raw: true)).to eq(expected_value) + end end it "does not create new files during multiple read operations" do @@ -113,9 +117,9 @@ # Perform multiple read operations 10.times do - store.read("user:123:profile") - store.read("user:456:profile") - store.read("config:app:settings") + cache_entries.keys.each do |key| + store.read(key, raw: true) + end end # Get current file list @@ -126,32 +130,13 @@ # Verify no new files were created expect(current_files).to eq(files_before) end + + include_examples "validates committed cache files" end describe "file content verification" do - it "preserves original keys in .key files" do - key_files = Dir.glob(File.join(committed_cache_path, "*.key")) - expect(key_files.length).to eq(3) - - # Read all key files and verify they contain expected keys - key_contents = key_files.map { |f| File.read(f) }.sort - expect(key_contents).to contain_exactly( - "config:app:settings", - "user:123:profile", - "user:456:profile" - ) - end - - it "has valid value files that can be deserialized" do - value_files = Dir.glob(File.join(committed_cache_path, "*.value")) - expect(value_files.length).to eq(3) - - # All value files should be readable and deserializable - value_files.each do |value_file| - expect(File.read(value_file).length).to be > 0 - end - end - + include_examples "validates committed cache files" + it "includes README.md documentation" do readme_path = File.join(committed_cache_path, "README.md") expect(File.exist?(readme_path)).to be true diff --git a/spec/fixtures/committed_cache/39cc398b810ada504bc9d10624575cf9.value b/spec/fixtures/committed_cache/39cc398b810ada504bc9d10624575cf9.value index 8a65748439d52d8069e9c112f9126db9f4aaf65b..91157f85d3820cdfb6ae7a50d9896d669e2c9353 100644 GIT binary patch literal 45 ycmZQz;fQAQR8p;0D#=LAO;xf|N=YorR?<<*Nz6+xO-u)gq~98xP1a|?1(^^)^* Lm1^0n*jz&Z<9ZQG literal 59 zcmZQz;fQ9dX1C(ZOUzC6RO0o@&&X47$xmgoVsj0#;!4d;%*^pr63qe%JET@5<`(3n N>LusrvRSi*0075$5TO77 diff --git a/spec/fixtures/committed_cache/ca63624a99ad3e461af0d7c8a2d5a520.value b/spec/fixtures/committed_cache/ca63624a99ad3e461af0d7c8a2d5a520.value index ff45501dc27d91eb4923d88d4b4f743d72829c6c..e7edfdba9a12d4a74653e0ce6bc70024a41d0c91 100644 GIT binary patch literal 61 zcmZQz;fQAQR5Gnr%1g{mRkBj@O3X`D2+qwc$xzZ!O3h8o%mE5!0R Date: Mon, 24 Nov 2025 20:55:12 +0000 Subject: [PATCH 5/5] DRY up spec with let statements for file lists - Extract Dir.glob calls to top-level let statements - Add key_files, value_files, all_files, and key_contents helpers - Simplify shared examples to use let helpers - Simplify test assertions by reusing all_files instead of inline Dir.glob - Reduces code duplication and improves readability Co-authored-by: nhorton <204146+nhorton@users.noreply.github.com> --- spec/committed_cache_spec.rb | 47 ++++++++++++------------------------ 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/spec/committed_cache_spec.rb b/spec/committed_cache_spec.rb index bf99c05..a28b0a5 100644 --- a/spec/committed_cache_spec.rb +++ b/spec/committed_cache_spec.rb @@ -18,26 +18,31 @@ } end + # File list helpers + let(:key_files) { Dir.glob(File.join(committed_cache_path, "*.key")) } + let(:value_files) { Dir.glob(File.join(committed_cache_path, "*.value")) } + let(:all_files) do + Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) + .reject { |f| File.directory?(f) } + .sort + end + let(:key_contents) { key_files.map { |f| File.read(f) }.sort } + # Shared examples for validating cache state shared_examples "validates committed cache files" do it "has the expected number of key files" do - key_files = Dir.glob(File.join(committed_cache_path, "*.key")) expect(key_files.length).to eq(3) end it "has the expected number of value files" do - value_files = Dir.glob(File.join(committed_cache_path, "*.value")) expect(value_files.length).to eq(3) end it "preserves original keys in .key files" do - key_files = Dir.glob(File.join(committed_cache_path, "*.key")) - key_contents = key_files.map { |f| File.read(f) }.sort expect(key_contents).to contain_exactly(*cache_entries.keys.sort) end it "has valid value files that can be deserialized" do - value_files = Dir.glob(File.join(committed_cache_path, "*.value")) # All value files should be readable value_files.each do |value_file| expect(File.read(value_file).length).to be > 0 @@ -45,21 +50,14 @@ end it "maintains the exact file count" do - current_files = Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) - .reject { |f| File.directory?(f) } - .sort # Should have exactly 7 files (3 entries × 2 files each + 1 README.md) - expect(current_files.length).to eq(7) + expect(all_files.length).to eq(7) end end describe "cache stability verification" do # Capture initial state for comparison - let(:initial_file_list) do - Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) - .reject { |f| File.directory?(f) } - .sort - end + let(:initial_file_list) { all_files } before(:each) do # Ensure cache entries exist before each test using raw mode @@ -77,13 +75,8 @@ store.read(key, raw: true) end - # Get current file list - current_files = Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) - .reject { |f| File.directory?(f) } - .sort - # Verify no new files were created - expect(current_files).to eq(files_before) + expect(all_files).to eq(files_before) end it "does not create new files when writing to existing keys with same values" do @@ -95,13 +88,8 @@ store.write(key, value, raw: true) end - # Get current file list - current_files = Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) - .reject { |f| File.directory?(f) } - .sort - # Verify no new files were created (same files should exist) - expect(current_files).to eq(files_before) + expect(all_files).to eq(files_before) end it "has all expected cache files present" do @@ -122,13 +110,8 @@ end end - # Get current file list - current_files = Dir.glob(File.join(committed_cache_path, "**", "*"), File::FNM_DOTMATCH) - .reject { |f| File.directory?(f) } - .sort - # Verify no new files were created - expect(current_files).to eq(files_before) + expect(all_files).to eq(files_before) end include_examples "validates committed cache files"