Skip to content

Commit

Permalink
Merge branch 'release-4.2.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
denisdefreyne committed Jul 3, 2016
2 parents 2984eb5 + 22ee434 commit 249d7c9
Show file tree
Hide file tree
Showing 26 changed files with 250 additions and 28 deletions.
3 changes: 3 additions & 0 deletions lib/nanoc.rb
Expand Up @@ -20,6 +20,9 @@ def self.on_windows?
end
end

# Load external dependencies
require 'hamster'

# Load general requirements
require 'digest'
require 'enumerator'
Expand Down
2 changes: 0 additions & 2 deletions lib/nanoc/base/checksummer.rb
@@ -1,5 +1,3 @@
require 'hamster'

module Nanoc::Int
# Creates checksums for given objects.
#
Expand Down
3 changes: 2 additions & 1 deletion lib/nanoc/base/compilation/compiler.rb
Expand Up @@ -191,7 +191,8 @@ def compile_reps
end

# Find item reps to compile and compile them
selector = Nanoc::Int::ItemRepSelector.new(@reps)
outdated_reps = @reps.select { |r| outdatedness_checker.outdated?(r) }
selector = Nanoc::Int::ItemRepSelector.new(outdated_reps)
selector.each do |rep|
@stack = []
compile_rep(rep)
Expand Down
2 changes: 1 addition & 1 deletion lib/nanoc/base/compilation/outdatedness_checker.rb
Expand Up @@ -136,7 +136,7 @@ def basic_outdatedness_reason_for(obj)
# indefinitely. It should not be necessary to pass this a custom value.
#
# @return [Boolean] true if the object is outdated, false otherwise
def outdated_due_to_dependencies?(obj, processed = Set.new)
def outdated_due_to_dependencies?(obj, processed = Hamster::Set.new)
# Convert from rep to item if necessary
obj = obj.item if obj.is_a?(Nanoc::Int::ItemRep)

Expand Down
18 changes: 16 additions & 2 deletions lib/nanoc/base/memoization.rb
Expand Up @@ -8,6 +8,20 @@ module Nanoc::Int
# @since 3.2.0
module Memoization
class Wrapper
attr_reader :ref

def initialize(ref)
@ref = ref
end

def inspect
@ref.inspect
rescue WeakRef::RefError
'<weak ref collected>'
end
end

class Value
attr_reader :value

def initialize(value)
Expand Down Expand Up @@ -63,15 +77,15 @@ def memoize(method_name)
if method_cache.key?(args)
value =
begin
method_cache[args].value
method_cache[args].ref.value
rescue WeakRef::RefError
NONE
end
end

if value.equal?(NONE)
send(original_method_name, *args).tap do |r|
method_cache[args] = WeakRef.new(Wrapper.new(r))
method_cache[args] = Wrapper.new(WeakRef.new(Value.new(r)))
end
else
value
Expand Down
4 changes: 1 addition & 3 deletions lib/nanoc/base/plugin_registry.rb
Expand Up @@ -196,9 +196,7 @@ def all

def resolve(class_or_name, _klass)
if class_or_name.is_a?(String)
class_or_name.scan(/\w+/).reduce(Kernel) do |memo, part|
memo.const_get(part)
end
Kernel.const_get(class_or_name)
else
class_or_name
end
Expand Down
4 changes: 4 additions & 0 deletions lib/nanoc/base/views/item_rep_view.rb
Expand Up @@ -77,5 +77,9 @@ def raw_path(snapshot: :last)
def binary?
@item_rep.binary?
end

def inspect
"<#{self.class} item.identifier=#{item.identifier} name=#{name}>"
end
end
end
4 changes: 4 additions & 0 deletions lib/nanoc/base/views/mixins/document_view_mixin.rb
Expand Up @@ -76,5 +76,9 @@ def reference
def raw_content
unwrap.content.string
end

def inspect
"<#{self.class} identifier=#{unwrap.identifier}>"
end
end
end
7 changes: 6 additions & 1 deletion lib/nanoc/base/views/post_compile_item_view.rb
@@ -1,7 +1,12 @@
module Nanoc
class PostCompileItemView < Nanoc::ItemWithRepsView
# @deprecated Use {#modified_reps} instead
def modified
reps.select { |rep| rep.unwrap.modified }
modified_reps
end

def modified_reps
reps.select { |rep| rep.unwrap.modified? }
end
end
end
4 changes: 4 additions & 0 deletions lib/nanoc/base/views/view.rb
Expand Up @@ -23,5 +23,9 @@ def unwrap
def frozen?
unwrap.frozen?
end

def inspect
"<#{self.class}>"
end
end
end
5 changes: 5 additions & 0 deletions spec/nanoc/base/views/config_view_spec.rb
Expand Up @@ -88,4 +88,9 @@
expect(res).to eql([[:amount, 9000], [:animal, 'donkey']])
end
end

describe '#inspect' do
subject { view.inspect }
it { is_expected.to eql('<Nanoc::ConfigView>') }
end
end
15 changes: 15 additions & 0 deletions spec/nanoc/base/views/item_collection_view_spec.rb
@@ -1,4 +1,19 @@
# FIXME: fix name
describe Nanoc::ItemCollectionWithRepsView do
let(:view_class) { Nanoc::ItemWithRepsView }
it_behaves_like 'an identifiable collection'

describe '#inspect' do
let(:wrapped) do
Nanoc::Int::IdentifiableCollection.new(config)
end

let(:view) { described_class.new(wrapped, view_context) }
let(:view_context) { double(:view_context) }
let(:config) { { string_pattern_type: 'glob' } }

subject { view.inspect }

it { is_expected.to eql('<Nanoc::ItemCollectionWithRepsView>') }
end
end
6 changes: 6 additions & 0 deletions spec/nanoc/base/views/item_rep_collection_view_spec.rb
Expand Up @@ -129,4 +129,10 @@
end
end
end

describe '#inspect' do
subject { view.inspect }

it { is_expected.to eql('<Nanoc::ItemRepCollectionView>') }
end
end
10 changes: 10 additions & 0 deletions spec/nanoc/base/views/item_rep_view_spec.rb
Expand Up @@ -212,4 +212,14 @@
expect(subject._context).to equal(view_context)
end
end

describe '#inspect' do
let(:item_rep) { Nanoc::Int::ItemRep.new(item, :jacques) }
let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo/') }
let(:view) { described_class.new(item_rep, view_context) }

subject { view.inspect }

it { is_expected.to eql('<Nanoc::ItemRepView item.identifier=/foo/ name=jacques>') }
end
end
9 changes: 9 additions & 0 deletions spec/nanoc/base/views/item_view_spec.rb
Expand Up @@ -331,4 +331,13 @@
describe '#raw_filename' do
# TODO: implement
end

describe '#inspect' do
let(:item) { Nanoc::Int::Item.new('content', {}, '/asdf/') }
let(:view) { described_class.new(item, nil) }

subject { view.inspect }

it { is_expected.to eql('<Nanoc::ItemWithRepsView identifier=/asdf/>') }
end
end
14 changes: 14 additions & 0 deletions spec/nanoc/base/views/layout_collection_view_spec.rb
@@ -1,4 +1,18 @@
describe Nanoc::LayoutCollectionView do
let(:view_class) { Nanoc::LayoutView }
it_behaves_like 'an identifiable collection'

describe '#inspect' do
let(:wrapped) do
Nanoc::Int::IdentifiableCollection.new(config)
end

let(:view) { described_class.new(wrapped, view_context) }
let(:view_context) { double(:view_context) }
let(:config) { { string_pattern_type: 'glob' } }

subject { view.inspect }

it { is_expected.to eql('<Nanoc::LayoutCollectionView>') }
end
end
9 changes: 9 additions & 0 deletions spec/nanoc/base/views/layout_view_spec.rb
Expand Up @@ -2,4 +2,13 @@
let(:entity_class) { Nanoc::Int::Layout }
let(:other_view_class) { Nanoc::ItemWithRepsView }
it_behaves_like 'a document view'

describe '#inspect' do
let(:item) { Nanoc::Int::Layout.new('content', {}, '/asdf/') }
let(:view) { described_class.new(item, nil) }

subject { view.inspect }

it { is_expected.to eql('<Nanoc::LayoutView identifier=/asdf/>') }
end
end
11 changes: 8 additions & 3 deletions spec/nanoc/base/views/mutable_config_view_spec.rb
@@ -1,11 +1,16 @@
describe Nanoc::MutableConfigView do
describe '#[]=' do
let(:config) { {} }
let(:view) { described_class.new(config, nil) }
let(:config) { {} }
let(:view) { described_class.new(config, nil) }

describe '#[]=' do
it 'sets attributes' do
view[:awesomeness] = 'rather high'
expect(config[:awesomeness]).to eq('rather high')
end
end

describe '#inspect' do
subject { view.inspect }
it { is_expected.to eql('<Nanoc::MutableConfigView>') }
end
end
14 changes: 14 additions & 0 deletions spec/nanoc/base/views/mutable_item_collection_view_spec.rb
Expand Up @@ -32,4 +32,18 @@
expect(ret).to equal(view)
end
end

describe '#inspect' do
let(:wrapped) do
Nanoc::Int::IdentifiableCollection.new(config)
end

let(:view) { described_class.new(wrapped, view_context) }
let(:view_context) { double(:view_context) }
let(:config) { { string_pattern_type: 'glob' } }

subject { view.inspect }

it { is_expected.to eql('<Nanoc::MutableItemCollectionView>') }
end
end
9 changes: 9 additions & 0 deletions spec/nanoc/base/views/mutable_item_view_spec.rb
Expand Up @@ -10,4 +10,13 @@
expect(view).not_to respond_to(:path)
expect(view).not_to respond_to(:reps)
end

describe '#inspect' do
let(:item) { Nanoc::Int::Item.new('content', {}, '/asdf/') }
let(:view) { described_class.new(item, nil) }

subject { view.inspect }

it { is_expected.to eql('<Nanoc::MutableItemView identifier=/asdf/>') }
end
end
14 changes: 14 additions & 0 deletions spec/nanoc/base/views/mutable_layout_collection_view_spec.rb
Expand Up @@ -32,4 +32,18 @@
expect(ret).to equal(view)
end
end

describe '#inspect' do
let(:wrapped) do
Nanoc::Int::IdentifiableCollection.new(config)
end

let(:view) { described_class.new(wrapped, view_context) }
let(:view_context) { double(:view_context) }
let(:config) { { string_pattern_type: 'glob' } }

subject { view.inspect }

it { is_expected.to eql('<Nanoc::MutableLayoutCollectionView>') }
end
end
9 changes: 9 additions & 0 deletions spec/nanoc/base/views/mutable_layout_view_spec.rb
@@ -1,4 +1,13 @@
describe Nanoc::MutableLayoutView do
let(:entity_class) { Nanoc::Int::Layout }
it_behaves_like 'a mutable document view'

describe '#inspect' do
let(:item) { Nanoc::Int::Item.new('content', {}, '/asdf/') }
let(:view) { described_class.new(item, nil) }

subject { view.inspect }

it { is_expected.to eql('<Nanoc::MutableLayoutView identifier=/asdf/>') }
end
end
36 changes: 36 additions & 0 deletions spec/nanoc/base/views/post_compile_item_view_spec.rb
@@ -0,0 +1,36 @@
describe Nanoc::PostCompileItemView do
shared_examples 'a method that returns modified reps only' do
let(:item) { Nanoc::Int::Item.new('blah', {}, '/foo.md') }
let(:rep_a) { Nanoc::Int::ItemRep.new(item, :no_mod) }
let(:rep_b) { Nanoc::Int::ItemRep.new(item, :modded).tap { |r| r.modified = true } }

let(:reps) do
Nanoc::Int::ItemRepRepo.new.tap do |reps|
reps << rep_a
reps << rep_b
end
end

let(:view_context) { double(:view_context, reps: reps) }
let(:view) { described_class.new(item, view_context) }

it 'returns only modified items' do
expect(subject.size).to eq(1)
expect(subject.map(&:name)).to eq(%i(modded))
end

it 'returns an array' do
expect(subject.class).to eql(Array)
end
end

describe '#modified_reps' do
subject { view.modified_reps }
it_behaves_like 'a method that returns modified reps only'
end

describe '#modified' do
subject { view.modified }
it_behaves_like 'a method that returns modified reps only'
end
end
29 changes: 29 additions & 0 deletions spec/nanoc/regressions/gh_882_spec.rb
@@ -0,0 +1,29 @@
describe 'GH-882', site: true, stdio: true do
before do
File.write('content/foo.md', 'I am foo!')
File.write('content/bar.md', 'I am bar!')

File.write('Rules', <<EOS)
compile '/**/*' do
write item.identifier.without_ext + '.html'
end
postprocess do
modified_reps = items.flat_map(&:modified)
modified_reps.each do |rep|
puts "Modified: \#{rep.item.identifier} - \#{rep.name}"
end
end
EOS
end

example do
Nanoc::CLI.run(%w(compile))

File.write('content/bar.md', 'I am bar! Modified!')
expect { Nanoc::CLI.run(%w(compile)) }.to output(%r{^Modified: /bar.md - default$}).to_stdout

File.write('content/bar.md', 'I am bar! Modified again!')
expect { Nanoc::CLI.run(%w(compile)) }.not_to output(%r{^Modified: /foo.md - default$}).to_stdout
end
end

0 comments on commit 249d7c9

Please sign in to comment.