Skip to content
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

Do not reuse cached binary content #1109

Merged
merged 1 commit into from Mar 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 6 additions & 1 deletion lib/nanoc/base/services/compiler/phases/cache.rb
Expand Up @@ -26,7 +26,12 @@ def run(rep, is_outdated:)

contract Nanoc::Int::ItemRep, C::KeywordArgs[is_outdated: C::Bool] => C::Bool
def can_reuse_content_for_rep?(rep, is_outdated:)
!is_outdated && !@compiled_content_cache[rep].nil?
if is_outdated
false
else
cache = @compiled_content_cache[rep]
cache ? cache.none? { |_snapshot_name, content| content.binary? } : false
end
end
end
end
39 changes: 37 additions & 2 deletions spec/nanoc/base/services/compiler/phases/cache_spec.rb
Expand Up @@ -69,12 +69,12 @@ def run(rep, is_outdated:) # rubocop:disable Lint/UnusedMethodArgument
context 'not outdated' do
let(:is_outdated) { false }

context 'cached compiled content available' do
context 'textual cached compiled content available' do
before do
compiled_content_cache[rep] = { last: Nanoc::Int::TextualContent.new('cached') }
end

it 'reuses content from cache' do
it 'writes content to cache' do
expect { subject }
.to change { snapshot_repo.get(rep, :last) }
.from(nil)
Expand All @@ -99,6 +99,41 @@ def run(rep, is_outdated:) # rubocop:disable Lint/UnusedMethodArgument
end
end

context 'binary cached compiled content available' do
let(:binary_content) { 'b1n4ry' }
let(:binary_filename) { Tempfile.open('test') { |fn| fn << binary_content }.path }

before do
compiled_content_cache[rep] = { last: Nanoc::Int::BinaryContent.new(binary_filename) }
end

it 'writes content to cache' do
expect { subject }
.to change { snapshot_repo.get(rep, :last) }
.from(nil)
.to(some_textual_content('wrapped content'))
end

it 'marks rep as compiled' do
expect { subject }
.to change { rep.compiled? }
.from(false)
.to(true)
end

it 'changes compiled content cache' do
expect { subject }
.to change { compiled_content_cache[rep] }
.from(last: some_binary_content(binary_content))
.to(last: some_textual_content('wrapped content'))
end

it 'does not send notification' do
expect(Nanoc::Int::NotificationCenter).not_to receive(:post).with(:cached_content_used, rep)
subject
end
end

context 'no cached compiled content available' do
include_examples 'calls wrapped'
end
Expand Down
22 changes: 22 additions & 0 deletions spec/nanoc/regressions/gh_1094_spec.rb
@@ -0,0 +1,22 @@
describe 'GH-1094', site: true, stdio: true do
before do
File.write('content/a.dat', 'foo')
File.write('content/index.html', '<%= @items["/*.dat"].compiled_content %>')

File.write('Rules', <<EOS)
compile '/**/*.html' do
filter :erb
write item.identifier.to_s
end

passthrough '/**/*.dat'
EOS
end

it 'raises CannotGetCompiledContentOfBinaryItem twice' do
2.times do
expect { Nanoc::CLI.run(%w(compile)) }
.to raise_wrapped_error(an_instance_of(Nanoc::Int::Errors::CannotGetCompiledContentOfBinaryItem))
end
end
end
26 changes: 26 additions & 0 deletions spec/spec_helper.rb
Expand Up @@ -174,6 +174,32 @@ def sort(x)
end
end

RSpec::Matchers.define :raise_wrapped_error do |expected|
supports_block_expectations

include RSpec::Matchers::Composable

match do |actual|
begin
actual.call
rescue Nanoc::Int::Errors::CompilationError => e
values_match?(expected, e.unwrap)
end
end

description do
"raise wrapped error #{expected.inspect}"
end

failure_message do |_actual|
"expected that proc would raise wrapped error #{expected.inspect}"
end

failure_message_when_negated do |_actual|
"expected that proc would not raise wrapped error #{expected.inspect}"
end
end

RSpec::Matchers.define :be_some_textual_content do |expected|
include RSpec::Matchers::Composable

Expand Down