nanoc 4.7.3 → 4.7.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|