-
Notifications
You must be signed in to change notification settings - Fork 0
Add specs for committed cache store to prevent file creep #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 3 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
3ea6a03
Initial plan
Copilot e62b1d6
Add committed cache specs and populate initial cache files
Copilot 3cc89fc
Refactor committed cache specs based on code review feedback
Copilot 0eec3e5
Refactor committed cache specs based on PR feedback
Copilot f4e2f2c
DRY up spec with let statements for file lists
Copilot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,161 @@ | ||
| # 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) } | ||
|
|
||
| describe "initial cache population" do | ||
nhorton marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 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: "[email protected]" }) | ||
| store.write("user:456:profile", { name: "Jane Smith", email: "[email protected]" }) | ||
| 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: "[email protected]" }) | ||
| expect(store.read("user:456:profile")).to eq({ name: "Jane Smith", email: "[email protected]" }) | ||
| 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 | ||
nhorton marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 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 | ||
|
|
||
| before(:each) do | ||
| # Ensure cache entries exist before each test | ||
| store.write("user:123:profile", { name: "John Doe", email: "[email protected]" }) | ||
| store.write("user:456:profile", { name: "Jane Smith", email: "[email protected]" }) | ||
| store.write("config:app:settings", { theme: "dark", language: "en" }) | ||
| 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") | ||
|
|
||
| # 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) | ||
| 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: "[email protected]" }) | ||
| store.write("user:456:profile", { name: "Jane Smith", email: "[email protected]" }) | ||
| 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(files_before) | ||
| 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: "[email protected]" }) | ||
| expect(store.read("user:456:profile")).to eq({ name: "Jane Smith", email: "[email protected]" }) | ||
| 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 | ||
| # Capture state before reading | ||
| files_before = initial_file_list | ||
|
|
||
| # 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(files_before) | ||
| 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 | ||
1 change: 1 addition & 0 deletions
1
spec/fixtures/committed_cache/39cc398b810ada504bc9d10624575cf9.key
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| config:app:settings |
Binary file added
BIN
+45 Bytes
spec/fixtures/committed_cache/39cc398b810ada504bc9d10624575cf9.value
Binary file not shown.
1 change: 1 addition & 0 deletions
1
spec/fixtures/committed_cache/39d971627e43c9bf240a49201b62f115.key
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| user:123:profile |
Binary file added
BIN
+59 Bytes
spec/fixtures/committed_cache/39d971627e43c9bf240a49201b62f115.value
Binary file not shown.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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. |
1 change: 1 addition & 0 deletions
1
spec/fixtures/committed_cache/ca63624a99ad3e461af0d7c8a2d5a520.key
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| user:456:profile |
Binary file added
BIN
+61 Bytes
spec/fixtures/committed_cache/ca63624a99ad3e461af0d7c8a2d5a520.value
Binary file not shown.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Set this to not compress, and either set
raw: truehere if you can, or in all theread&writecalls elsewhere so that the value files are in text.Also remove the bad value files since the raw versions would be different.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Configured in commit 0eec3e5:
compress: falseraw: true{"name":"John Doe","email":"[email protected]"}