test: cover CacheStoreTest, test_write_then_read_round_trips
This commit is contained in:
1 parent
730c66caf0
commit
9d3d74ae61
2 files changed
+174
No files matched your search
@@ -0,0 +1,116 @@
|
|||||||
|
require 'minitest/autorun'
|
||||||
|
require 'prism'
|
||||||
|
|
||||||
|
class CacheStoreTest < Minitest::Test
|
||||||
|
def setup
|
||||||
|
@store = Prism::Cache::MemoryStore.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_write_then_read_round_trips
|
||||||
|
@store.write('key', 'value')
|
||||||
|
assert_equal 'value', @store.read('key')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_read_of_missing_key_is_nil
|
||||||
|
assert_nil @store.read('missing')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_keys_are_coerced_to_string
|
||||||
|
@store.write(:sym_key, 'value')
|
||||||
|
assert_equal 'value', @store.read('sym_key')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_fetch_computes_and_stores_on_miss
|
||||||
|
calls = 0
|
||||||
|
3.times { @store.fetch('k') { calls += 1; 'computed' } }
|
||||||
|
assert_equal 1, calls
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_fetch_returns_existing_value_without_yielding_on_hit
|
||||||
|
@store.write('k', 'preset')
|
||||||
|
result = @store.fetch('k') { raise 'must not be called' }
|
||||||
|
assert_equal 'preset', result
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_delete_removes_the_entry
|
||||||
|
@store.write('k', 'v')
|
||||||
|
assert @store.delete('k')
|
||||||
|
assert_nil @store.read('k')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_delete_of_missing_key_returns_falsey
|
||||||
|
refute @store.delete('missing')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_exist_reflects_presence
|
||||||
|
refute @store.exist?('k')
|
||||||
|
@store.write('k', 'v')
|
||||||
|
assert @store.exist?('k')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_clear_empties_the_store
|
||||||
|
@store.write('a', 1)
|
||||||
|
@store.write('b', 2)
|
||||||
|
@store.clear
|
||||||
|
assert_equal 0, @store.size
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_expires_in_makes_the_entry_unreadable_afterwards
|
||||||
|
@store.write('k', 'v', expires_in: 0)
|
||||||
|
sleep 0.01
|
||||||
|
assert_nil @store.read('k')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_delete_matched_removes_keys_matching_a_regexp
|
||||||
|
@store.write('posts/1', 'a')
|
||||||
|
@store.write('posts/2', 'b')
|
||||||
|
@store.write('users/1', 'c')
|
||||||
|
@store.delete_matched(/\Aposts\//)
|
||||||
|
assert_nil @store.read('posts/1')
|
||||||
|
assert_nil @store.read('posts/2')
|
||||||
|
assert_equal 'c', @store.read('users/1')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_default_store_is_a_memory_store_singleton
|
||||||
|
assert_same Prism::Cache.store, Prism::Cache.store
|
||||||
|
assert_instance_of Prism::Cache::MemoryStore, Prism::Cache.store
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_unbounded_store_never_evicts
|
||||||
|
store = Prism::Cache::MemoryStore.new
|
||||||
|
50.times { |i| store.write("k#{i}", i) }
|
||||||
|
assert_equal 50, store.size
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_max_size_evicts_the_least_recently_used_entry_on_write
|
||||||
|
store = Prism::Cache::MemoryStore.new(max_size: 2)
|
||||||
|
store.write('a', 1)
|
||||||
|
store.write('b', 2)
|
||||||
|
store.write('c', 3)
|
||||||
|
assert_equal 2, store.size
|
||||||
|
assert_nil store.read('a')
|
||||||
|
assert_equal 2, store.read('b')
|
||||||
|
assert_equal 3, store.read('c')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_reading_a_key_protects_it_from_eviction
|
||||||
|
store = Prism::Cache::MemoryStore.new(max_size: 2)
|
||||||
|
store.write('a', 1)
|
||||||
|
store.write('b', 2)
|
||||||
|
store.read('a') # bump 'a' to most-recently-used, 'b' is now the LRU one
|
||||||
|
store.write('c', 3)
|
||||||
|
assert_equal 1, store.read('a')
|
||||||
|
assert_nil store.read('b')
|
||||||
|
assert_equal 3, store.read('c')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_rewriting_an_existing_key_does_not_grow_the_store
|
||||||
|
store = Prism::Cache::MemoryStore.new(max_size: 2)
|
||||||
|
store.write('a', 1)
|
||||||
|
store.write('b', 2)
|
||||||
|
store.write('a', 'updated')
|
||||||
|
assert_equal 2, store.size
|
||||||
|
assert_equal 'updated', store.read('a')
|
||||||
|
assert_equal 2, store.read('b')
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
require 'minitest/autorun'
|
||||||
|
require 'prism'
|
||||||
|
require 'tmpdir'
|
||||||
|
require 'fileutils'
|
||||||
|
require 'stringio'
|
||||||
|
|
||||||
|
class CliAssetsPrecompileTest < Minitest::Test
|
||||||
|
def setup
|
||||||
|
@dir = Dir.mktmpdir('prism-cli-assets')
|
||||||
|
@cli = Prism::Cli.new(@dir)
|
||||||
|
@source = File.join(@dir, 'app', 'assets')
|
||||||
|
@output = File.join(@dir, 'public', 'assets')
|
||||||
|
FileUtils.mkdir_p(File.join(@source, 'stylesheets'))
|
||||||
|
File.write(File.join(@source, 'stylesheets', 'application.css'), 'body { color: red; }')
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
FileUtils.remove_entry(@dir)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_precompiles_without_booting_an_application
|
||||||
|
manifest = @cli.assets_precompile(['--source=app/assets', '--output=public/assets'], out: StringIO.new)
|
||||||
|
logical = manifest.to_h.keys
|
||||||
|
assert_equal ['stylesheets/application.css'], logical
|
||||||
|
fingerprinted = manifest.lookup('stylesheets/application.css')
|
||||||
|
assert_match(/\Astylesheets\/application-[0-9a-f]{8}\.css\z/, fingerprinted)
|
||||||
|
assert File.exist?(File.join(@output, fingerprinted))
|
||||||
|
assert File.exist?(File.join(@output, 'manifest.json'))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_prints_a_summary_to_the_given_output
|
||||||
|
out = StringIO.new
|
||||||
|
@cli.assets_precompile(['--source=app/assets', '--output=public/assets'], out: out)
|
||||||
|
assert_match(/compiled 1 file\(s\) into/, out.string)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_recompiling_unchanged_content_reproduces_the_same_fingerprint_and_removes_nothing_stale
|
||||||
|
first = @cli.assets_precompile(['--source=app/assets', '--output=public/assets'], out: StringIO.new)
|
||||||
|
second = @cli.assets_precompile(['--source=app/assets', '--output=public/assets'], out: StringIO.new)
|
||||||
|
assert_equal first.to_h, second.to_h
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_raises_usage_error_without_required_options
|
||||||
|
assert_raises(Prism::Cli::UsageError) { @cli.assets_precompile([]) }
|
||||||
|
assert_raises(Prism::Cli::UsageError) { @cli.assets_precompile(['--source=app/assets']) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_run_dispatches_the_assets_colon_precompile_command
|
||||||
|
original_stdout = $stdout
|
||||||
|
captured = StringIO.new
|
||||||
|
$stdout = captured
|
||||||
|
@cli.run(['assets:precompile', '--source=app/assets', '--output=public/assets'])
|
||||||
|
ensure
|
||||||
|
$stdout = original_stdout
|
||||||
|
assert_match(/compiled 1 file\(s\)/, captured.string)
|
||||||
|
assert File.exist?(File.join(@output, 'manifest.json'))
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in new issue
Block a user