nanoc 4.7.3 → 4.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -5
- data/NEWS.md +7 -0
- data/lib/nanoc/base/entities.rb +1 -1
- data/lib/nanoc/base/entities/{rule_memory.rb → action_sequence.rb} +19 -1
- data/lib/nanoc/base/entities/outdatedness_reasons.rb +12 -4
- data/lib/nanoc/base/entities/outdatedness_status.rb +1 -1
- data/lib/nanoc/base/repos.rb +1 -1
- data/lib/nanoc/base/repos/{rule_memory_store.rb → action_sequence_store.rb} +12 -12
- data/lib/nanoc/base/repos/checksum_store.rb +3 -3
- data/lib/nanoc/base/services/action_provider.rb +1 -9
- data/lib/nanoc/base/services/checksummer.rb +4 -2
- data/lib/nanoc/base/services/compiler.rb +11 -11
- data/lib/nanoc/base/services/compiler/phases/recalculate.rb +3 -3
- data/lib/nanoc/base/services/compiler/stages/cleanup.rb +1 -1
- data/lib/nanoc/base/services/compiler/stages/compile_reps.rb +3 -3
- data/lib/nanoc/base/services/compiler/stages/determine_outdatedness.rb +7 -2
- data/lib/nanoc/base/services/compiler_loader.rb +3 -3
- data/lib/nanoc/base/services/item_rep_builder.rb +4 -2
- data/lib/nanoc/base/services/item_rep_router.rb +7 -2
- data/lib/nanoc/base/services/outdatedness_checker.rb +30 -7
- data/lib/nanoc/base/services/outdatedness_rule.rb +7 -4
- data/lib/nanoc/base/services/outdatedness_rules.rb +9 -161
- data/lib/nanoc/base/services/outdatedness_rules/attributes_modified.rb +34 -0
- data/lib/nanoc/base/services/outdatedness_rules/code_snippets_modified.rb +26 -0
- data/lib/nanoc/base/services/outdatedness_rules/configuration_modified.rb +23 -0
- data/lib/nanoc/base/services/outdatedness_rules/content_modified.rb +15 -0
- data/lib/nanoc/base/services/outdatedness_rules/not_written.rb +11 -0
- data/lib/nanoc/base/services/outdatedness_rules/paths_modified.rb +20 -0
- data/lib/nanoc/base/services/outdatedness_rules/rules_modified.rb +13 -0
- data/lib/nanoc/base/services/outdatedness_rules/uses_always_outdated_filter.rb +20 -0
- data/lib/nanoc/rule_dsl.rb +1 -1
- data/lib/nanoc/rule_dsl/action_provider.rb +7 -11
- data/lib/nanoc/rule_dsl/{rule_memory_calculator.rb → action_sequence_calculator.rb} +21 -39
- data/lib/nanoc/rule_dsl/recording_executor.rb +7 -7
- data/lib/nanoc/spec.rb +7 -7
- data/lib/nanoc/version.rb +1 -1
- data/spec/nanoc/base/checksummer_spec.rb +20 -0
- data/spec/nanoc/base/compiler_spec.rb +7 -10
- data/spec/nanoc/base/entities/action_sequence_spec.rb +278 -0
- data/spec/nanoc/base/repos/checksum_store_spec.rb +22 -2
- data/spec/nanoc/base/services/compiler/stages/cleanup_spec.rb +2 -2
- data/spec/nanoc/base/services/compiler/stages/compile_reps_spec.rb +5 -9
- data/spec/nanoc/base/services/executor_spec.rb +5 -5
- data/spec/nanoc/base/services/item_rep_router_spec.rb +36 -18
- data/spec/nanoc/base/services/outdatedness_checker_spec.rb +74 -30
- data/spec/nanoc/base/services/outdatedness_rules_spec.rb +78 -18
- data/spec/nanoc/helpers/rendering_spec.rb +4 -4
- data/spec/nanoc/rule_dsl/{rule_memory_calculator_spec.rb → action_sequence_calculator_spec.rb} +6 -61
- data/spec/nanoc/rule_dsl/recording_executor_spec.rb +45 -45
- data/test/base/test_outdatedness_checker.rb +1 -1
- data/test/rule_dsl/test_action_provider.rb +3 -3
- metadata +15 -7
- data/spec/nanoc/base/entities/rule_memory_spec.rb +0 -167
@@ -0,0 +1,13 @@
|
|
1
|
+
module Nanoc::Int::OutdatednessRules
|
2
|
+
class RulesModified < Nanoc::Int::OutdatednessRule
|
3
|
+
affects_props :compiled_content, :path
|
4
|
+
|
5
|
+
def apply(obj, outdatedness_checker)
|
6
|
+
mem_old = outdatedness_checker.action_sequence_store[obj]
|
7
|
+
mem_new = outdatedness_checker.action_sequence_for(obj).serialize
|
8
|
+
unless mem_old.eql?(mem_new)
|
9
|
+
Nanoc::Int::OutdatednessReasons::RulesModified
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Nanoc::Int::OutdatednessRules
|
2
|
+
class UsesAlwaysOutdatedFilter < Nanoc::Int::OutdatednessRule
|
3
|
+
affects_props :raw_content, :attributes, :path
|
4
|
+
|
5
|
+
def apply(obj, outdatedness_checker)
|
6
|
+
mem = outdatedness_checker.action_sequence_for(obj)
|
7
|
+
if any_always_outdated?(mem)
|
8
|
+
Nanoc::Int::OutdatednessReasons::UsesAlwaysOutdatedFilter
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def any_always_outdated?(mem)
|
13
|
+
mem
|
14
|
+
.select { |a| a.is_a?(Nanoc::Int::ProcessingActions::Filter) }
|
15
|
+
.map { |a| Nanoc::Filter.named(a.filter_name) }
|
16
|
+
.compact
|
17
|
+
.any?(&:always_outdated?)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/nanoc/rule_dsl.rb
CHANGED
@@ -2,7 +2,7 @@ require_relative 'rule_dsl/compiler_dsl'
|
|
2
2
|
require_relative 'rule_dsl/action_provider'
|
3
3
|
require_relative 'rule_dsl/recording_executor'
|
4
4
|
require_relative 'rule_dsl/rule_context'
|
5
|
-
require_relative 'rule_dsl/
|
5
|
+
require_relative 'rule_dsl/action_sequence_calculator'
|
6
6
|
require_relative 'rule_dsl/rule'
|
7
7
|
require_relative 'rule_dsl/rules_collection'
|
8
8
|
require_relative 'rule_dsl/rules_loader'
|
@@ -8,21 +8,21 @@ module Nanoc::RuleDSL
|
|
8
8
|
def self.for(site)
|
9
9
|
rules_collection = Nanoc::RuleDSL::RulesCollection.new
|
10
10
|
|
11
|
-
|
12
|
-
Nanoc::RuleDSL::
|
11
|
+
action_sequence_calculator =
|
12
|
+
Nanoc::RuleDSL::ActionSequenceCalculator.new(
|
13
13
|
rules_collection: rules_collection, site: site,
|
14
14
|
)
|
15
15
|
|
16
|
-
action_provider = new(rules_collection,
|
16
|
+
action_provider = new(rules_collection, action_sequence_calculator)
|
17
17
|
|
18
18
|
Nanoc::RuleDSL::RulesLoader.new(site.config, rules_collection).load
|
19
19
|
|
20
20
|
action_provider
|
21
21
|
end
|
22
22
|
|
23
|
-
def initialize(rules_collection,
|
23
|
+
def initialize(rules_collection, action_sequence_calculator)
|
24
24
|
@rules_collection = rules_collection
|
25
|
-
@
|
25
|
+
@action_sequence_calculator = action_sequence_calculator
|
26
26
|
end
|
27
27
|
|
28
28
|
def rep_names_for(item)
|
@@ -32,12 +32,8 @@ module Nanoc::RuleDSL
|
|
32
32
|
matching_rules.map(&:rep_name).uniq
|
33
33
|
end
|
34
34
|
|
35
|
-
def
|
36
|
-
@
|
37
|
-
end
|
38
|
-
|
39
|
-
def snapshots_defs_for(rep)
|
40
|
-
@rule_memory_calculator.snapshots_defs_for(rep)
|
35
|
+
def action_sequence_for(rep)
|
36
|
+
@action_sequence_calculator[rep]
|
41
37
|
end
|
42
38
|
|
43
39
|
def need_preprocessing?
|
@@ -1,24 +1,24 @@
|
|
1
1
|
module Nanoc::RuleDSL
|
2
|
-
# Calculates
|
2
|
+
# Calculates action sequences for objects that can be run through a rule (item
|
3
3
|
# representations and layouts).
|
4
4
|
#
|
5
5
|
# @api private
|
6
|
-
class
|
6
|
+
class ActionSequenceCalculator
|
7
7
|
extend Nanoc::Int::Memoization
|
8
8
|
|
9
9
|
class UnsupportedObjectTypeException < ::Nanoc::Error
|
10
10
|
def initialize(obj)
|
11
|
-
super("Do not know how to calculate the
|
11
|
+
super("Do not know how to calculate the action sequence for #{obj.inspect}")
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
class
|
15
|
+
class NoActionSequenceForLayoutException < ::Nanoc::Error
|
16
16
|
def initialize(layout)
|
17
17
|
super("There is no layout rule specified for #{layout.inspect}")
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
class
|
21
|
+
class NoActionSequenceForItemRepException < ::Nanoc::Error
|
22
22
|
def initialize(item)
|
23
23
|
super("There is no compilation rule specified for #{item.inspect}")
|
24
24
|
end
|
@@ -42,78 +42,60 @@ module Nanoc::RuleDSL
|
|
42
42
|
|
43
43
|
# @param [#reference] obj
|
44
44
|
#
|
45
|
-
# @return [Nanoc::Int::
|
45
|
+
# @return [Nanoc::Int::ActionSequence]
|
46
46
|
def [](obj)
|
47
47
|
case obj
|
48
48
|
when Nanoc::Int::ItemRep
|
49
|
-
|
49
|
+
new_action_sequence_for_rep(obj)
|
50
50
|
when Nanoc::Int::Layout
|
51
|
-
|
51
|
+
new_action_sequence_for_layout(obj)
|
52
52
|
else
|
53
53
|
raise UnsupportedObjectTypeException.new(obj)
|
54
54
|
end
|
55
55
|
end
|
56
56
|
|
57
|
-
def snapshots_defs_for(rep)
|
58
|
-
is_binary = rep.item.content.binary?
|
59
|
-
snapshot_defs = []
|
60
|
-
|
61
|
-
self[rep].each do |action|
|
62
|
-
case action
|
63
|
-
when Nanoc::Int::ProcessingActions::Snapshot
|
64
|
-
action.snapshot_names.each do |snapshot_name|
|
65
|
-
snapshot_defs << Nanoc::Int::SnapshotDef.new(snapshot_name, binary: is_binary)
|
66
|
-
end
|
67
|
-
when Nanoc::Int::ProcessingActions::Filter
|
68
|
-
is_binary = Nanoc::Filter.named!(action.filter_name).to_binary?
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
snapshot_defs
|
73
|
-
end
|
74
|
-
|
75
57
|
# @param [Nanoc::Int::ItemRep] rep The item representation to get the rule
|
76
58
|
# memory for
|
77
59
|
#
|
78
|
-
# @return [Nanoc::Int::
|
79
|
-
def
|
60
|
+
# @return [Nanoc::Int::ActionSequence]
|
61
|
+
def new_action_sequence_for_rep(rep)
|
80
62
|
dependency_tracker = Nanoc::Int::DependencyTracker::Null.new
|
81
63
|
view_context = @site.compiler.compilation_context.create_view_context(dependency_tracker)
|
82
64
|
|
83
|
-
|
84
|
-
executor = Nanoc::RuleDSL::RecordingExecutor.new(
|
65
|
+
action_sequence = Nanoc::Int::ActionSequence.new(rep)
|
66
|
+
executor = Nanoc::RuleDSL::RecordingExecutor.new(action_sequence)
|
85
67
|
rule = @rules_collection.compilation_rule_for(rep)
|
86
68
|
|
87
69
|
unless rule
|
88
|
-
raise
|
70
|
+
raise NoActionSequenceForItemRepException.new(rep)
|
89
71
|
end
|
90
72
|
|
91
73
|
executor.snapshot(:raw)
|
92
74
|
rule.apply_to(rep, executor: executor, site: @site, view_context: view_context)
|
93
|
-
if
|
75
|
+
if action_sequence.any_layouts?
|
94
76
|
executor.snapshot(:post)
|
95
77
|
end
|
96
|
-
unless
|
78
|
+
unless action_sequence.snapshot_actions.any? { |sa| sa.snapshot_names.include?(:last) }
|
97
79
|
executor.snapshot(:last)
|
98
80
|
end
|
99
|
-
unless
|
81
|
+
unless action_sequence.snapshot_actions.any? { |sa| sa.snapshot_names.include?(:pre) }
|
100
82
|
executor.snapshot(:pre)
|
101
83
|
end
|
102
84
|
|
103
|
-
copy_paths_from_routing_rules(
|
85
|
+
copy_paths_from_routing_rules(action_sequence.compact_snapshots, rep: rep)
|
104
86
|
end
|
105
87
|
|
106
88
|
# @param [Nanoc::Int::Layout] layout
|
107
89
|
#
|
108
|
-
# @return [Nanoc::Int::
|
109
|
-
def
|
90
|
+
# @return [Nanoc::Int::ActionSequence]
|
91
|
+
def new_action_sequence_for_layout(layout)
|
110
92
|
res = @rules_collection.filter_for_layout(layout)
|
111
93
|
|
112
94
|
unless res
|
113
|
-
raise
|
95
|
+
raise NoActionSequenceForLayoutException.new(layout)
|
114
96
|
end
|
115
97
|
|
116
|
-
Nanoc::Int::
|
98
|
+
Nanoc::Int::ActionSequence.new(layout).tap do |rm|
|
117
99
|
rm.add_filter(res[0], res[1])
|
118
100
|
end
|
119
101
|
end
|
@@ -3,12 +3,12 @@ module Nanoc
|
|
3
3
|
class RecordingExecutor
|
4
4
|
include Nanoc::Int::ContractsSupport
|
5
5
|
|
6
|
-
def initialize(
|
7
|
-
@
|
6
|
+
def initialize(action_sequence)
|
7
|
+
@action_sequence = action_sequence
|
8
8
|
end
|
9
9
|
|
10
10
|
def filter(filter_name, filter_args = {})
|
11
|
-
@
|
11
|
+
@action_sequence.add_filter(filter_name, filter_args)
|
12
12
|
end
|
13
13
|
|
14
14
|
def layout(layout_identifier, extra_filter_args = {})
|
@@ -16,17 +16,17 @@ module Nanoc
|
|
16
16
|
raise ArgumentError.new('The layout passed to #layout must be a string')
|
17
17
|
end
|
18
18
|
|
19
|
-
unless @
|
20
|
-
@
|
19
|
+
unless @action_sequence.any_layouts?
|
20
|
+
@action_sequence.add_snapshot(:pre, nil)
|
21
21
|
end
|
22
22
|
|
23
|
-
@
|
23
|
+
@action_sequence.add_layout(layout_identifier, extra_filter_args)
|
24
24
|
end
|
25
25
|
|
26
26
|
Pathlike = C::Maybe[C::Or[String, Nanoc::Identifier]]
|
27
27
|
contract Symbol, C::KeywordArgs[path: C::Optional[Pathlike]] => nil
|
28
28
|
def snapshot(snapshot_name, path: nil)
|
29
|
-
@
|
29
|
+
@action_sequence.add_snapshot(snapshot_name, path && path.to_s)
|
30
30
|
nil
|
31
31
|
end
|
32
32
|
end
|
data/lib/nanoc/spec.rb
CHANGED
@@ -12,7 +12,7 @@ module Nanoc
|
|
12
12
|
@mod = mod
|
13
13
|
|
14
14
|
@erbout = ''
|
15
|
-
@
|
15
|
+
@action_sequence = {}
|
16
16
|
@config = Nanoc::Int::Configuration.new.with_defaults
|
17
17
|
@reps = Nanoc::Int::ItemRepRepo.new
|
18
18
|
@items = Nanoc::Int::IdentifiableCollection.new(@config)
|
@@ -103,12 +103,12 @@ module Nanoc
|
|
103
103
|
assigns[:layouts]
|
104
104
|
end
|
105
105
|
|
106
|
-
def
|
107
|
-
@
|
106
|
+
def action_sequence_for(obj)
|
107
|
+
@action_sequence.fetch(obj, [])
|
108
108
|
end
|
109
109
|
|
110
|
-
def
|
111
|
-
@
|
110
|
+
def update_action_sequence(obj, memory)
|
111
|
+
@action_sequence[obj] = memory
|
112
112
|
end
|
113
113
|
|
114
114
|
def snapshot_repo
|
@@ -141,8 +141,8 @@ module Nanoc
|
|
141
141
|
[:default]
|
142
142
|
end
|
143
143
|
|
144
|
-
def
|
145
|
-
@context.
|
144
|
+
def action_sequence_for(obj)
|
145
|
+
@context.action_sequence_for(obj)
|
146
146
|
end
|
147
147
|
|
148
148
|
def snapshots_defs_for(_rep)
|
data/lib/nanoc/version.rb
CHANGED
@@ -23,6 +23,26 @@ end
|
|
23
23
|
describe Nanoc::Int::Checksummer do
|
24
24
|
subject { described_class.calc(obj, Nanoc::Int::Checksummer::VerboseDigest) }
|
25
25
|
|
26
|
+
describe '.calc_for_each_attribute_of' do
|
27
|
+
let(:obj) { Nanoc::Int::Item.new('asdf', { 'foo' => 'bar' }, '/foo.md') }
|
28
|
+
|
29
|
+
context 'compact' do
|
30
|
+
subject do
|
31
|
+
described_class.calc_for_each_attribute_of(obj)
|
32
|
+
end
|
33
|
+
|
34
|
+
it { is_expected.to have_key(:foo) }
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'verbose' do
|
38
|
+
subject do
|
39
|
+
described_class.calc_for_each_attribute_of(obj, Nanoc::Int::Checksummer::VerboseDigest)
|
40
|
+
end
|
41
|
+
|
42
|
+
it { is_expected.to eq(foo: 'String<bar>') }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
26
46
|
context 'String' do
|
27
47
|
let(:obj) { 'hello' }
|
28
48
|
it { is_expected.to eql('String<hello>') }
|
@@ -4,7 +4,7 @@ describe Nanoc::Int::Compiler do
|
|
4
4
|
site,
|
5
5
|
compiled_content_cache: compiled_content_cache,
|
6
6
|
checksum_store: checksum_store,
|
7
|
-
|
7
|
+
action_sequence_store: action_sequence_store,
|
8
8
|
action_provider: action_provider,
|
9
9
|
dependency_store: dependency_store,
|
10
10
|
outdatedness_checker: outdatedness_checker,
|
@@ -13,8 +13,8 @@ describe Nanoc::Int::Compiler do
|
|
13
13
|
)
|
14
14
|
end
|
15
15
|
|
16
|
-
let(:checksum_store)
|
17
|
-
let(:
|
16
|
+
let(:checksum_store) { Nanoc::Int::ChecksumStore.new(objects: items) }
|
17
|
+
let(:action_sequence_store) { Nanoc::Int::ActionSequenceStore.new }
|
18
18
|
|
19
19
|
let(:dependency_store) { Nanoc::Int::DependencyStore.new(items.to_a) }
|
20
20
|
let(:reps) { Nanoc::Int::ItemRepRepo.new }
|
@@ -54,7 +54,7 @@ describe Nanoc::Int::Compiler do
|
|
54
54
|
Nanoc::Int::ProcessingActions::Snapshot.new([:last], []),
|
55
55
|
]
|
56
56
|
|
57
|
-
Nanoc::Int::
|
57
|
+
Nanoc::Int::ActionSequence.new(nil, actions: actions)
|
58
58
|
end
|
59
59
|
|
60
60
|
before do
|
@@ -68,8 +68,9 @@ describe Nanoc::Int::Compiler do
|
|
68
68
|
allow(outdatedness_checker).to receive(:outdated?).with(rep).and_return(true)
|
69
69
|
allow(outdatedness_checker).to receive(:outdated?).with(other_rep).and_return(true)
|
70
70
|
|
71
|
-
|
72
|
-
|
71
|
+
# FIXME: eww
|
72
|
+
action_sequences = { rep => memory, other_rep => memory }
|
73
|
+
compiler.instance_variable_set(:@action_sequences, action_sequences)
|
73
74
|
|
74
75
|
allow(Nanoc::Int::NotificationCenter).to receive(:post)
|
75
76
|
end
|
@@ -100,10 +101,6 @@ describe Nanoc::Int::Compiler do
|
|
100
101
|
context 'interrupted compilation' do
|
101
102
|
let(:item) { Nanoc::Int::Item.new('other=<%= @items["/other.*"].compiled_content %>', {}, '/hi.md') }
|
102
103
|
|
103
|
-
before do
|
104
|
-
expect(action_provider).to receive(:memory_for).with(other_rep).and_return(memory)
|
105
|
-
end
|
106
|
-
|
107
104
|
it 'generates expected output' do
|
108
105
|
expect(compiler.snapshot_repo.get(rep, :last)).to be_nil
|
109
106
|
|
@@ -0,0 +1,278 @@
|
|
1
|
+
describe Nanoc::Int::ActionSequence do
|
2
|
+
let(:action_sequence) { described_class.new(rep) }
|
3
|
+
let(:rep) { double(:rep) }
|
4
|
+
|
5
|
+
describe '#size' do
|
6
|
+
subject { action_sequence.size }
|
7
|
+
|
8
|
+
context 'no actions' do
|
9
|
+
it { is_expected.to eql(0) }
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'some actions' do
|
13
|
+
before do
|
14
|
+
action_sequence.add_filter(:foo, {})
|
15
|
+
end
|
16
|
+
|
17
|
+
it { is_expected.to eql(1) }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#[]' do
|
22
|
+
subject { action_sequence[index] }
|
23
|
+
let(:index) { 0 }
|
24
|
+
|
25
|
+
context 'no actions' do
|
26
|
+
it { is_expected.to be_nil }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'some actions' do
|
30
|
+
before do
|
31
|
+
action_sequence.add_filter(:foo, {})
|
32
|
+
end
|
33
|
+
|
34
|
+
it { is_expected.to be_a(Nanoc::Int::ProcessingActions::Filter) }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe '#add_filter' do
|
39
|
+
example do
|
40
|
+
action_sequence.add_filter(:foo, donkey: 123)
|
41
|
+
|
42
|
+
expect(action_sequence.size).to eql(1)
|
43
|
+
expect(action_sequence[0]).to be_a(Nanoc::Int::ProcessingActions::Filter)
|
44
|
+
expect(action_sequence[0].filter_name).to eql(:foo)
|
45
|
+
expect(action_sequence[0].params).to eql(donkey: 123)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe '#add_layout' do
|
50
|
+
example do
|
51
|
+
action_sequence.add_layout('/foo.*', donkey: 123)
|
52
|
+
|
53
|
+
expect(action_sequence.size).to eql(1)
|
54
|
+
expect(action_sequence[0]).to be_a(Nanoc::Int::ProcessingActions::Layout)
|
55
|
+
expect(action_sequence[0].layout_identifier).to eql('/foo.*')
|
56
|
+
expect(action_sequence[0].params).to eql(donkey: 123)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '#add_snapshot' do
|
61
|
+
context 'snapshot does not yet exist' do
|
62
|
+
example do
|
63
|
+
action_sequence.add_snapshot(:before_layout, '/foo.md')
|
64
|
+
|
65
|
+
expect(action_sequence.size).to eql(1)
|
66
|
+
expect(action_sequence[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
|
67
|
+
expect(action_sequence[0].snapshot_names).to eql([:before_layout])
|
68
|
+
expect(action_sequence[0].paths).to eql(['/foo.md'])
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'snapshot already exist' do
|
73
|
+
before do
|
74
|
+
action_sequence.add_snapshot(:before_layout, '/bar.md')
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'raises' do
|
78
|
+
expect { action_sequence.add_snapshot(:before_layout, '/foo.md') }
|
79
|
+
.to raise_error(Nanoc::Int::Errors::CannotCreateMultipleSnapshotsWithSameName)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#each' do
|
85
|
+
before do
|
86
|
+
action_sequence.add_filter(:erb, awesomeness: 'high')
|
87
|
+
action_sequence.add_snapshot(:bar, '/foo.md')
|
88
|
+
action_sequence.add_layout('/default.erb', somelayoutparam: 'yes')
|
89
|
+
end
|
90
|
+
|
91
|
+
example do
|
92
|
+
actions = []
|
93
|
+
action_sequence.each { |a| actions << a }
|
94
|
+
expect(actions.size).to eq(3)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '#map' do
|
99
|
+
before do
|
100
|
+
action_sequence.add_filter(:erb, awesomeness: 'high')
|
101
|
+
action_sequence.add_snapshot(:bar, '/foo.md')
|
102
|
+
action_sequence.add_layout('/default.erb', somelayoutparam: 'yes')
|
103
|
+
end
|
104
|
+
|
105
|
+
example do
|
106
|
+
res = action_sequence.map { Nanoc::Int::ProcessingActions::Filter.new(:donkey, {}) }
|
107
|
+
expect(res.to_a.size).to eq(3)
|
108
|
+
expect(res.to_a).to all(be_a(Nanoc::Int::ProcessingActions::Filter))
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe '#serialize' do
|
113
|
+
subject { action_sequence.serialize }
|
114
|
+
|
115
|
+
before do
|
116
|
+
action_sequence.add_filter(:erb, awesomeness: 'high')
|
117
|
+
action_sequence.add_snapshot(:bar, '/foo.md')
|
118
|
+
action_sequence.add_layout('/default.erb', somelayoutparam: 'yes')
|
119
|
+
end
|
120
|
+
|
121
|
+
example do
|
122
|
+
expect(subject).to eql(
|
123
|
+
[
|
124
|
+
[:filter, :erb, 'PeWUm2PtXYtqeHJdTqnY7kkwAow='],
|
125
|
+
[:snapshot, [:bar], true, ['/foo.md']],
|
126
|
+
[:layout, '/default.erb', '97LAe1pYTLKczxBsu+x4MmvqdkU='],
|
127
|
+
],
|
128
|
+
)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe '#compact_snapshots' do
|
133
|
+
subject { action_sequence.compact_snapshots }
|
134
|
+
|
135
|
+
before do
|
136
|
+
action_sequence.add_snapshot(:a1, nil)
|
137
|
+
action_sequence.add_snapshot(:a2, '/a2.md')
|
138
|
+
action_sequence.add_snapshot(:a3, nil)
|
139
|
+
action_sequence.add_filter(:erb, awesomeness: 'high')
|
140
|
+
action_sequence.add_snapshot(:b1, '/b1.md')
|
141
|
+
action_sequence.add_snapshot(:b2, nil)
|
142
|
+
action_sequence.add_snapshot(:b3, '/b3.md')
|
143
|
+
action_sequence.add_filter(:erb, awesomeness: 'high')
|
144
|
+
action_sequence.add_snapshot(:c, nil)
|
145
|
+
end
|
146
|
+
|
147
|
+
example do
|
148
|
+
expect(subject[0]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
|
149
|
+
expect(subject[0].snapshot_names).to eql(%i(a1 a2 a3))
|
150
|
+
expect(subject[0].paths).to eql(['/a2.md'])
|
151
|
+
|
152
|
+
expect(subject[1]).to be_a(Nanoc::Int::ProcessingActions::Filter)
|
153
|
+
|
154
|
+
expect(subject[2]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
|
155
|
+
expect(subject[2].snapshot_names).to eql(%i(b1 b2 b3))
|
156
|
+
expect(subject[2].paths).to eql(['/b1.md', '/b3.md'])
|
157
|
+
|
158
|
+
expect(subject[3]).to be_a(Nanoc::Int::ProcessingActions::Filter)
|
159
|
+
|
160
|
+
expect(subject[4]).to be_a(Nanoc::Int::ProcessingActions::Snapshot)
|
161
|
+
expect(subject[4].snapshot_names).to eql([:c])
|
162
|
+
expect(subject[4].paths).to be_empty
|
163
|
+
|
164
|
+
expect(subject.size).to eql(5)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
describe '#snapshots_defs' do
|
169
|
+
subject { action_sequence.snapshots_defs }
|
170
|
+
|
171
|
+
let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo.md') }
|
172
|
+
let(:rep) { Nanoc::Int::ItemRep.new(item, :default) }
|
173
|
+
|
174
|
+
Class.new(Nanoc::Filter) do
|
175
|
+
identifier :RuleMemSpec_filter_b2b
|
176
|
+
type :binary => :binary # rubocop:disable Style/HashSyntax
|
177
|
+
|
178
|
+
def run(content, params = {}); end
|
179
|
+
end
|
180
|
+
|
181
|
+
Class.new(Nanoc::Filter) do
|
182
|
+
identifier :RuleMemSpec_filter_b2t
|
183
|
+
type :binary => :text # rubocop:disable Style/HashSyntax
|
184
|
+
|
185
|
+
def run(content, params = {}); end
|
186
|
+
end
|
187
|
+
|
188
|
+
Class.new(Nanoc::Filter) do
|
189
|
+
identifier :RuleMemSpec_filter_t2t
|
190
|
+
type :text => :text # rubocop:disable Style/HashSyntax
|
191
|
+
|
192
|
+
def run(content, params = {}); end
|
193
|
+
end
|
194
|
+
|
195
|
+
Class.new(Nanoc::Filter) do
|
196
|
+
identifier :RuleMemSpec_filter_t2b
|
197
|
+
type :text => :binary # rubocop:disable Style/HashSyntax
|
198
|
+
|
199
|
+
def run(content, params = {}); end
|
200
|
+
end
|
201
|
+
|
202
|
+
it 'has no snapshot defs by default' do
|
203
|
+
expect(subject).to be_empty
|
204
|
+
end
|
205
|
+
|
206
|
+
context 'textual item' do
|
207
|
+
let(:item) { Nanoc::Int::Item.new('asdf', {}, '/foo.md') }
|
208
|
+
|
209
|
+
it 'generates initial textual snapshot def' do
|
210
|
+
action_sequence.add_snapshot(:giraffe, nil)
|
211
|
+
|
212
|
+
expect(subject.size).to eq(1)
|
213
|
+
expect(subject[0].name).to eq(:giraffe)
|
214
|
+
expect(subject[0]).not_to be_binary
|
215
|
+
end
|
216
|
+
|
217
|
+
it 'generated follow-up textual snapshot def if previous filter is textual' do
|
218
|
+
action_sequence.add_snapshot(:giraffe, nil)
|
219
|
+
action_sequence.add_filter(:RuleMemSpec_filter_t2t, arguments: 'irrelevant')
|
220
|
+
action_sequence.add_snapshot(:zebra, nil)
|
221
|
+
|
222
|
+
expect(subject.size).to eq(2)
|
223
|
+
expect(subject[0].name).to eq(:giraffe)
|
224
|
+
expect(subject[0]).not_to be_binary
|
225
|
+
expect(subject[1].name).to eq(:zebra)
|
226
|
+
expect(subject[1]).not_to be_binary
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'generated follow-up binary snapshot def if previous filter is text-to-bianry' do
|
230
|
+
action_sequence.add_snapshot(:giraffe, nil)
|
231
|
+
action_sequence.add_filter(:RuleMemSpec_filter_t2b, arguments: 'irrelevant')
|
232
|
+
action_sequence.add_snapshot(:zebra, nil)
|
233
|
+
|
234
|
+
expect(subject.size).to eq(2)
|
235
|
+
expect(subject[0].name).to eq(:giraffe)
|
236
|
+
expect(subject[0]).not_to be_binary
|
237
|
+
expect(subject[1].name).to eq(:zebra)
|
238
|
+
expect(subject[1]).to be_binary
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
context 'binary item' do
|
243
|
+
let(:item) { Nanoc::Int::Item.new(Nanoc::Int::BinaryContent.new('/asdf.dat'), {}, '/foo.md') }
|
244
|
+
|
245
|
+
it 'generates initial binary snapshot def' do
|
246
|
+
action_sequence.add_snapshot(:giraffe, nil)
|
247
|
+
|
248
|
+
expect(subject.size).to eq(1)
|
249
|
+
expect(subject[0].name).to eq(:giraffe)
|
250
|
+
expect(subject[0]).to be_binary
|
251
|
+
end
|
252
|
+
|
253
|
+
it 'generated follow-up binary snapshot def if previous filter is binary' do
|
254
|
+
action_sequence.add_snapshot(:giraffe, nil)
|
255
|
+
action_sequence.add_filter(:RuleMemSpec_filter_b2b, arguments: 'irrelevant')
|
256
|
+
action_sequence.add_snapshot(:zebra, nil)
|
257
|
+
|
258
|
+
expect(subject.size).to eq(2)
|
259
|
+
expect(subject[0].name).to eq(:giraffe)
|
260
|
+
expect(subject[0]).to be_binary
|
261
|
+
expect(subject[1].name).to eq(:zebra)
|
262
|
+
expect(subject[1]).to be_binary
|
263
|
+
end
|
264
|
+
|
265
|
+
it 'generated follow-up textual snapshot def if previous filter is binary-to-text' do
|
266
|
+
action_sequence.add_snapshot(:giraffe, nil)
|
267
|
+
action_sequence.add_filter(:RuleMemSpec_filter_b2t, arguments: 'irrelevant')
|
268
|
+
action_sequence.add_snapshot(:zebra, nil)
|
269
|
+
|
270
|
+
expect(subject.size).to eq(2)
|
271
|
+
expect(subject[0].name).to eq(:giraffe)
|
272
|
+
expect(subject[0]).to be_binary
|
273
|
+
expect(subject[1].name).to eq(:zebra)
|
274
|
+
expect(subject[1]).not_to be_binary
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|