nanoc 4.6.4 → 4.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -0
- data/Gemfile.lock +12 -4
- data/NEWS.md +7 -0
- data/README.md +1 -1
- data/lib/nanoc/base/feature.rb +1 -1
- data/lib/nanoc/base/services/compiler.rb +18 -11
- data/lib/nanoc/base/services/compiler/phases.rb +2 -0
- data/lib/nanoc/base/services/compiler/phases/abstract.rb +34 -0
- data/lib/nanoc/base/services/compiler/phases/cache.rb +8 -5
- data/lib/nanoc/base/services/compiler/phases/mark_done.rb +8 -5
- data/lib/nanoc/base/services/compiler/phases/recalculate.rb +6 -2
- data/lib/nanoc/base/services/compiler/phases/resume.rb +9 -7
- data/lib/nanoc/base/services/compiler/phases/write.rb +8 -5
- data/lib/nanoc/base/services/compiler/stages/compile_reps.rb +1 -1
- data/lib/nanoc/cli.rb +8 -0
- data/lib/nanoc/cli/commands/compile.rb +81 -27
- data/lib/nanoc/cli/commands/nanoc.rb +2 -1
- data/lib/nanoc/cli/error_handler.rb +1 -0
- data/lib/nanoc/filters.rb +1 -0
- data/lib/nanoc/filters/erubi.rb +27 -0
- data/lib/nanoc/rule_dsl/rule_context.rb +16 -2
- data/lib/nanoc/telemetry/labelled_counter.rb +9 -9
- data/lib/nanoc/telemetry/labelled_summary.rb +15 -11
- data/lib/nanoc/version.rb +1 -1
- data/spec/nanoc/base/compiler_spec.rb +2 -0
- data/spec/nanoc/base/services/compiler/phases/abstract_spec.rb +49 -0
- data/spec/nanoc/base/services/compiler/phases/cache_spec.rb +13 -9
- data/spec/nanoc/cli/commands/compile/timing_recorder_spec.rb +101 -5
- data/spec/nanoc/rule_dsl/rule_context_spec.rb +63 -13
- data/spec/nanoc/telemetry/labelled_counter_spec.rb +10 -10
- data/spec/nanoc/telemetry/labelled_summary_spec.rb +36 -23
- data/spec/nanoc/telemetry/stopwatch_spec.rb +2 -0
- data/spec/nanoc/telemetry_spec.rb +14 -14
- data/spec/spec_helper.rb +3 -0
- data/test/base/test_compiler.rb +0 -38
- data/test/checking/checks/test_html.rb +0 -4
- data/test/filters/test_erubi.rb +73 -0
- data/test/fixtures/vcr_cassettes/html_run_ok.yml +27 -98
- data/test/helper.rb +3 -0
- metadata +6 -2
@@ -24,8 +24,9 @@ opt :C, :'no-color', 'disable color' do
|
|
24
24
|
$stderr.add_stream_cleaner(Nanoc::CLI::StreamCleaners::ANSIColors)
|
25
25
|
end
|
26
26
|
|
27
|
-
opt :V, :verbose, 'make output more detailed' do
|
27
|
+
opt :V, :verbose, 'make output more detailed', multiple: true do |val|
|
28
28
|
Nanoc::CLI::Logger.instance.level = :low
|
29
|
+
Nanoc::CLI.verbosity = val.size
|
29
30
|
end
|
30
31
|
|
31
32
|
opt :v, :version, 'show version information and quit' do
|
data/lib/nanoc/filters.rb
CHANGED
@@ -7,6 +7,7 @@ require_relative 'filters/bluecloth'
|
|
7
7
|
require_relative 'filters/colorize_syntax'
|
8
8
|
require_relative 'filters/coffeescript'
|
9
9
|
require_relative 'filters/erb'
|
10
|
+
require_relative 'filters/erubi'
|
10
11
|
require_relative 'filters/erubis'
|
11
12
|
require_relative 'filters/haml'
|
12
13
|
require_relative 'filters/handlebars'
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Nanoc::Filters
|
2
|
+
# @api private
|
3
|
+
class Erubi < Nanoc::Filter
|
4
|
+
identifier :erubi
|
5
|
+
|
6
|
+
requires 'erubi'
|
7
|
+
|
8
|
+
# Runs the content through [Erubi](https://github.com/jeremyevans/erubi).
|
9
|
+
# To prevent single quote escaping use :escapefunc => 'Nanoc::Helpers::HTMLEscape.html_escape'
|
10
|
+
# See the Erubi documentation for more options.
|
11
|
+
#
|
12
|
+
# @param [String] content The content to filter
|
13
|
+
#
|
14
|
+
# @return [String] The filtered content
|
15
|
+
def run(content, params = {})
|
16
|
+
# Create context
|
17
|
+
context = ::Nanoc::Int::Context.new(assigns)
|
18
|
+
|
19
|
+
# Get binding
|
20
|
+
proc = assigns[:content] ? -> { assigns[:content] } : nil
|
21
|
+
assigns_binding = context.get_binding(&proc)
|
22
|
+
|
23
|
+
# Get result
|
24
|
+
eval(::Erubi::Engine.new(content, { bufvar: '_erbout', filename: filename }.merge(params)).src, assigns_binding)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -73,11 +73,25 @@ module Nanoc::RuleDSL
|
|
73
73
|
# @param [String] path
|
74
74
|
#
|
75
75
|
# @return [void]
|
76
|
-
def write(
|
76
|
+
def write(arg)
|
77
77
|
@_write_snapshot_counter ||= 0
|
78
78
|
snapshot_name = "_#{@_write_snapshot_counter}".to_sym
|
79
79
|
@_write_snapshot_counter += 1
|
80
|
-
|
80
|
+
|
81
|
+
case arg
|
82
|
+
when String, Nanoc::Identifier
|
83
|
+
snapshot(snapshot_name, path: arg)
|
84
|
+
when Hash
|
85
|
+
if arg.key?(:ext)
|
86
|
+
ext = arg[:ext].sub(/\A\./, '')
|
87
|
+
path = @item.identifier.without_exts + '.' + ext
|
88
|
+
snapshot(snapshot_name, path: path)
|
89
|
+
else
|
90
|
+
raise ArgumentError, 'Cannot call #write this way (need path or :ext)'
|
91
|
+
end
|
92
|
+
else
|
93
|
+
raise ArgumentError, 'Cannot call #write this way (need path or :ext)'
|
94
|
+
end
|
81
95
|
end
|
82
96
|
end
|
83
97
|
end
|
@@ -4,23 +4,23 @@ module Nanoc::Telemetry
|
|
4
4
|
@counters = {}
|
5
5
|
end
|
6
6
|
|
7
|
-
def increment(
|
8
|
-
get(
|
7
|
+
def increment(label)
|
8
|
+
get(label).increment
|
9
9
|
end
|
10
10
|
|
11
|
-
def get(
|
12
|
-
@counters.fetch(
|
11
|
+
def get(label)
|
12
|
+
@counters.fetch(label) { @counters[label] = Counter.new }
|
13
13
|
end
|
14
14
|
|
15
|
-
# TODO: add #
|
15
|
+
# TODO: add #empty?
|
16
16
|
|
17
|
-
def value(
|
18
|
-
get(
|
17
|
+
def value(label)
|
18
|
+
get(label).value
|
19
19
|
end
|
20
20
|
|
21
21
|
def values
|
22
|
-
@counters.each_with_object({}) do |(
|
23
|
-
res[
|
22
|
+
@counters.each_with_object({}) do |(label, counter), res|
|
23
|
+
res[label] = counter.value
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
@@ -4,28 +4,32 @@ module Nanoc::Telemetry
|
|
4
4
|
@summaries = {}
|
5
5
|
end
|
6
6
|
|
7
|
-
def observe(value,
|
8
|
-
get(
|
7
|
+
def observe(value, label)
|
8
|
+
get(label).observe(value)
|
9
9
|
end
|
10
10
|
|
11
|
-
def get(
|
12
|
-
@summaries.fetch(
|
11
|
+
def get(label)
|
12
|
+
@summaries.fetch(label) { @summaries[label] = Summary.new }
|
13
13
|
end
|
14
14
|
|
15
|
-
def
|
16
|
-
@summaries.
|
15
|
+
def empty?
|
16
|
+
@summaries.empty?
|
17
17
|
end
|
18
18
|
|
19
|
-
def quantile(fraction,
|
20
|
-
get(
|
19
|
+
def quantile(fraction, label)
|
20
|
+
get(label).quantile(fraction)
|
21
|
+
end
|
22
|
+
|
23
|
+
def map
|
24
|
+
@summaries.map { |(label, summary)| yield(label, summary) }
|
21
25
|
end
|
22
26
|
|
23
27
|
# TODO: add quantiles(fraction)
|
24
|
-
# TODO: add min(
|
28
|
+
# TODO: add min(label)
|
25
29
|
# TODO: add mins
|
26
|
-
# TODO: add max(
|
30
|
+
# TODO: add max(label)
|
27
31
|
# TODO: add maxs
|
28
|
-
# TODO: add sum(
|
32
|
+
# TODO: add sum(label)
|
29
33
|
# TODO: add sums
|
30
34
|
end
|
31
35
|
end
|
data/lib/nanoc/version.rb
CHANGED
@@ -70,6 +70,8 @@ describe Nanoc::Int::Compiler do
|
|
70
70
|
|
71
71
|
allow(action_provider).to receive(:memory_for).with(rep).and_return(memory)
|
72
72
|
allow(action_provider).to receive(:memory_for).with(other_rep).and_return(memory)
|
73
|
+
|
74
|
+
allow(Nanoc::Int::NotificationCenter).to receive(:post)
|
73
75
|
end
|
74
76
|
|
75
77
|
describe '#compile_rep' do
|
@@ -0,0 +1,49 @@
|
|
1
|
+
describe Nanoc::Int::Compiler::Phases::Abstract do
|
2
|
+
subject(:phase) do
|
3
|
+
described_class.new(wrapped: wrapped, name: 'my_phase')
|
4
|
+
end
|
5
|
+
|
6
|
+
let(:item) { Nanoc::Int::Item.new('foo', {}, '/stuff.md') }
|
7
|
+
let(:rep) { Nanoc::Int::ItemRep.new(item, :default) }
|
8
|
+
|
9
|
+
let(:wrapped) { nil }
|
10
|
+
|
11
|
+
describe '#run' do
|
12
|
+
subject { phase.run(rep, is_outdated: false) {} }
|
13
|
+
|
14
|
+
it 'raises' do
|
15
|
+
expect { subject }.to raise_error(NotImplementedError)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#call' do
|
20
|
+
subject { phase.call(rep, is_outdated: false) }
|
21
|
+
|
22
|
+
let(:phase) do
|
23
|
+
Class.new(described_class) do
|
24
|
+
def run(_rep, is_outdated:) # rubocop:disable Lint/UnusedMethodArgument
|
25
|
+
yield
|
26
|
+
end
|
27
|
+
end.new(wrapped: wrapped, name: 'my_phase')
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:wrapped) do
|
31
|
+
Class.new(described_class) do
|
32
|
+
def run(_rep, is_outdated:); end
|
33
|
+
end.new(wrapped: nil, name: 'wrapped_phase')
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'sends the proper notifications' do
|
37
|
+
expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_started, 'my_phase', rep).ordered
|
38
|
+
expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_yielded, 'my_phase', rep).ordered
|
39
|
+
|
40
|
+
expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_started, 'wrapped_phase', rep).ordered
|
41
|
+
expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_ended, 'wrapped_phase', rep).ordered
|
42
|
+
|
43
|
+
expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_resumed, 'my_phase', rep).ordered
|
44
|
+
expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_ended, 'my_phase', rep).ordered
|
45
|
+
|
46
|
+
subject
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -14,7 +14,7 @@ describe Nanoc::Int::Compiler::Phases::Cache do
|
|
14
14
|
let(:snapshot_repo) { Nanoc::Int::SnapshotRepo.new }
|
15
15
|
|
16
16
|
let(:wrapped_class) do
|
17
|
-
Class.new do
|
17
|
+
Class.new(Nanoc::Int::Compiler::Phases::Abstract) do
|
18
18
|
def initialize(snapshot_repo)
|
19
19
|
@snapshot_repo = snapshot_repo
|
20
20
|
end
|
@@ -31,10 +31,17 @@ describe Nanoc::Int::Compiler::Phases::Cache do
|
|
31
31
|
let(:rep) { Nanoc::Int::ItemRep.new(item, :latex) }
|
32
32
|
|
33
33
|
describe '#run' do
|
34
|
-
subject { phase.
|
34
|
+
subject { phase.call(rep, is_outdated: is_outdated) }
|
35
35
|
|
36
36
|
let(:is_outdated) { raise 'override me' }
|
37
37
|
|
38
|
+
before do
|
39
|
+
allow(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_started, anything, anything)
|
40
|
+
allow(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_yielded, anything, anything)
|
41
|
+
allow(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_resumed, anything, anything)
|
42
|
+
allow(Nanoc::Int::NotificationCenter).to receive(:post).with(:phase_ended, anything, anything)
|
43
|
+
end
|
44
|
+
|
38
45
|
shared_examples 'calls wrapped' do
|
39
46
|
it 'delegates to wrapped' do
|
40
47
|
expect(wrapped).to receive(:run).with(rep, is_outdated: is_outdated)
|
@@ -48,8 +55,7 @@ describe Nanoc::Int::Compiler::Phases::Cache do
|
|
48
55
|
.to(true)
|
49
56
|
end
|
50
57
|
|
51
|
-
it 'sends no notifications' do
|
52
|
-
expect(Nanoc::Int::NotificationCenter).not_to receive(:post)
|
58
|
+
it 'sends no other notifications' do
|
53
59
|
subject
|
54
60
|
end
|
55
61
|
|
@@ -75,6 +81,7 @@ describe Nanoc::Int::Compiler::Phases::Cache do
|
|
75
81
|
end
|
76
82
|
|
77
83
|
it 'writes content to cache' do
|
84
|
+
expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:cached_content_used, rep)
|
78
85
|
expect { subject }
|
79
86
|
.to change { snapshot_repo.get(rep, :last) }
|
80
87
|
.from(nil)
|
@@ -82,6 +89,7 @@ describe Nanoc::Int::Compiler::Phases::Cache do
|
|
82
89
|
end
|
83
90
|
|
84
91
|
it 'marks rep as compiled' do
|
92
|
+
expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:cached_content_used, rep)
|
85
93
|
expect { subject }
|
86
94
|
.to change { rep.compiled? }
|
87
95
|
.from(false)
|
@@ -89,14 +97,10 @@ describe Nanoc::Int::Compiler::Phases::Cache do
|
|
89
97
|
end
|
90
98
|
|
91
99
|
it 'does not change compiled content cache' do
|
100
|
+
expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:cached_content_used, rep)
|
92
101
|
expect { subject }
|
93
102
|
.not_to change { compiled_content_cache[rep] }
|
94
103
|
end
|
95
|
-
|
96
|
-
it 'sends notification' do
|
97
|
-
expect(Nanoc::Int::NotificationCenter).to receive(:post).with(:cached_content_used, rep)
|
98
|
-
subject
|
99
|
-
end
|
100
104
|
end
|
101
105
|
|
102
106
|
context 'binary cached compiled content available' do
|
@@ -4,6 +4,8 @@ describe Nanoc::CLI::Commands::Compile::TimingRecorder, stdio: true do
|
|
4
4
|
before { Timecop.freeze(Time.local(2008, 1, 2, 14, 5, 0)) }
|
5
5
|
after { Timecop.return }
|
6
6
|
|
7
|
+
before { Nanoc::CLI.verbosity = 2 }
|
8
|
+
|
7
9
|
let(:reps) do
|
8
10
|
Nanoc::Int::ItemRepRepo.new.tap do |reps|
|
9
11
|
reps << rep
|
@@ -27,7 +29,7 @@ describe Nanoc::CLI::Commands::Compile::TimingRecorder, stdio: true do
|
|
27
29
|
Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :erb)
|
28
30
|
|
29
31
|
expect { listener.stop }
|
30
|
-
.to output(
|
32
|
+
.to output(/^\s*erb │ 1 1\.00s 1\.00s 1\.00s 1\.00s$/).to_stdout
|
31
33
|
end
|
32
34
|
|
33
35
|
it 'records multiple from filtering_started to filtering_ended' do
|
@@ -43,7 +45,7 @@ describe Nanoc::CLI::Commands::Compile::TimingRecorder, stdio: true do
|
|
43
45
|
Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :erb)
|
44
46
|
|
45
47
|
expect { listener.stop }
|
46
|
-
.to output(
|
48
|
+
.to output(/^\s*erb │ 2 1\.00s 1\.50s 2\.00s 3\.00s$/).to_stdout
|
47
49
|
end
|
48
50
|
|
49
51
|
it 'records inner filters in nested filtering_started/filtering_ended' do
|
@@ -59,7 +61,7 @@ describe Nanoc::CLI::Commands::Compile::TimingRecorder, stdio: true do
|
|
59
61
|
Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :outer)
|
60
62
|
|
61
63
|
expect { listener.stop }
|
62
|
-
.to output(
|
64
|
+
.to output(/^\s*inner │ 1 2\.00s 2\.00s 2\.00s 2\.00s$/).to_stdout
|
63
65
|
end
|
64
66
|
|
65
67
|
it 'records outer filters in nested filtering_started/filtering_ended' do
|
@@ -75,7 +77,27 @@ describe Nanoc::CLI::Commands::Compile::TimingRecorder, stdio: true do
|
|
75
77
|
Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :outer)
|
76
78
|
|
77
79
|
expect { listener.stop }
|
78
|
-
.to output(
|
80
|
+
.to output(/^\s*outer │ 1 6\.00s 6\.00s 6\.00s 6\.00s$/).to_stdout
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'pauses outer stopwatch when suspended' do
|
84
|
+
listener.start
|
85
|
+
|
86
|
+
Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0))
|
87
|
+
Nanoc::Int::NotificationCenter.post(:compilation_started, rep)
|
88
|
+
Nanoc::Int::NotificationCenter.post(:filtering_started, rep, :outer)
|
89
|
+
Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1))
|
90
|
+
Nanoc::Int::NotificationCenter.post(:filtering_started, rep, :inner)
|
91
|
+
Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 3))
|
92
|
+
Nanoc::Int::NotificationCenter.post(:compilation_suspended, rep, :__anything__)
|
93
|
+
Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 6))
|
94
|
+
Nanoc::Int::NotificationCenter.post(:compilation_started, rep)
|
95
|
+
Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 10))
|
96
|
+
Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :inner)
|
97
|
+
Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :outer)
|
98
|
+
|
99
|
+
expect { listener.stop }
|
100
|
+
.to output(/^\s*outer │ 1 7\.00s 7\.00s 7\.00s 7\.00s$/).to_stdout
|
79
101
|
end
|
80
102
|
|
81
103
|
it 'records single from filtering_started over compilation_{suspended,started} to filtering_ended' do
|
@@ -92,6 +114,80 @@ describe Nanoc::CLI::Commands::Compile::TimingRecorder, stdio: true do
|
|
92
114
|
Nanoc::Int::NotificationCenter.post(:filtering_ended, rep, :erb)
|
93
115
|
|
94
116
|
expect { listener.stop }
|
95
|
-
.to output(
|
117
|
+
.to output(/^\s*erb │ 1 5\.00s 5\.00s 5\.00s 5\.00s$/).to_stdout
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'records single phase start+stop' do
|
121
|
+
listener.start
|
122
|
+
|
123
|
+
Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0))
|
124
|
+
Nanoc::Int::NotificationCenter.post(:phase_started, 'donkey', rep)
|
125
|
+
Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1))
|
126
|
+
Nanoc::Int::NotificationCenter.post(:phase_ended, 'donkey', rep)
|
127
|
+
|
128
|
+
expect { listener.stop }
|
129
|
+
.to output(/^\s*donkey │ 1 1\.00s 1\.00s 1\.00s 1\.00s$/).to_stdout
|
130
|
+
end
|
131
|
+
|
132
|
+
it 'records multiple phase start+stop' do
|
133
|
+
listener.start
|
134
|
+
|
135
|
+
Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0))
|
136
|
+
Nanoc::Int::NotificationCenter.post(:phase_started, 'donkey', rep)
|
137
|
+
Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1))
|
138
|
+
Nanoc::Int::NotificationCenter.post(:phase_ended, 'donkey', rep)
|
139
|
+
Timecop.freeze(Time.local(2008, 9, 1, 11, 6, 0))
|
140
|
+
Nanoc::Int::NotificationCenter.post(:phase_started, 'donkey', rep)
|
141
|
+
Timecop.freeze(Time.local(2008, 9, 1, 11, 6, 2))
|
142
|
+
Nanoc::Int::NotificationCenter.post(:phase_ended, 'donkey', rep)
|
143
|
+
|
144
|
+
expect { listener.stop }
|
145
|
+
.to output(/^\s*donkey │ 2 1\.00s 1\.50s 2\.00s 3\.00s$/).to_stdout
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'records single phase start+yield+resume+stop' do
|
149
|
+
listener.start
|
150
|
+
|
151
|
+
Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0))
|
152
|
+
Nanoc::Int::NotificationCenter.post(:phase_started, 'donkey', rep)
|
153
|
+
Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1))
|
154
|
+
Nanoc::Int::NotificationCenter.post(:phase_yielded, 'donkey', rep)
|
155
|
+
Timecop.freeze(Time.local(2008, 9, 1, 11, 6, 0))
|
156
|
+
Nanoc::Int::NotificationCenter.post(:phase_resumed, 'donkey', rep)
|
157
|
+
Timecop.freeze(Time.local(2008, 9, 1, 11, 6, 2))
|
158
|
+
Nanoc::Int::NotificationCenter.post(:phase_ended, 'donkey', rep)
|
159
|
+
|
160
|
+
expect { listener.stop }
|
161
|
+
.to output(/^\s*donkey │ 1 3\.00s 3\.00s 3\.00s 3\.00s$/).to_stdout
|
162
|
+
end
|
163
|
+
|
164
|
+
it 'records single phase start+yield+abort+start+stop' do
|
165
|
+
listener.start
|
166
|
+
|
167
|
+
Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0))
|
168
|
+
Nanoc::Int::NotificationCenter.post(:phase_started, 'donkey', rep)
|
169
|
+
Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1))
|
170
|
+
Nanoc::Int::NotificationCenter.post(:phase_yielded, 'donkey', rep)
|
171
|
+
Timecop.freeze(Time.local(2008, 9, 1, 11, 6, 0))
|
172
|
+
Nanoc::Int::NotificationCenter.post(:phase_aborted, 'donkey', rep)
|
173
|
+
Timecop.freeze(Time.local(2008, 9, 1, 12, 7, 2))
|
174
|
+
Nanoc::Int::NotificationCenter.post(:phase_started, 'donkey', rep)
|
175
|
+
Timecop.freeze(Time.local(2008, 9, 1, 12, 7, 5))
|
176
|
+
Nanoc::Int::NotificationCenter.post(:phase_ended, 'donkey', rep)
|
177
|
+
|
178
|
+
expect { listener.stop }
|
179
|
+
.to output(/^\s*donkey │ 2 1\.00s 2\.00s 3\.00s 4\.00s$/).to_stdout
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'records stage duration' do
|
183
|
+
listener.start
|
184
|
+
|
185
|
+
Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 0))
|
186
|
+
Nanoc::Int::NotificationCenter.post(:stage_started, 'donkey', rep)
|
187
|
+
Timecop.freeze(Time.local(2008, 9, 1, 10, 5, 1))
|
188
|
+
Nanoc::Int::NotificationCenter.post(:stage_ended, 'donkey', rep)
|
189
|
+
|
190
|
+
expect { listener.stop }
|
191
|
+
.to output(/^\s*donkey │ 1\.00s$/).to_stdout
|
96
192
|
end
|
97
193
|
end
|
@@ -162,25 +162,75 @@ describe(Nanoc::RuleDSL::RuleContext) do
|
|
162
162
|
end
|
163
163
|
|
164
164
|
describe '#write' do
|
165
|
-
context '
|
166
|
-
|
165
|
+
context 'with path' do
|
166
|
+
context 'calling once' do
|
167
|
+
subject { rule_context.write('/foo.html') }
|
168
|
+
|
169
|
+
it 'makes a request to the executor' do
|
170
|
+
expect(executor).to receive(:snapshot).with(:_0, path: '/foo.html')
|
171
|
+
subject
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
context 'calling twice' do
|
176
|
+
subject do
|
177
|
+
rule_context.write('/foo.html')
|
178
|
+
rule_context.write('/bar.html')
|
179
|
+
end
|
180
|
+
|
181
|
+
it 'makes two requests to the executor with unique snapshot names' do
|
182
|
+
expect(executor).to receive(:snapshot).with(:_0, path: '/foo.html')
|
183
|
+
expect(executor).to receive(:snapshot).with(:_1, path: '/bar.html')
|
184
|
+
subject
|
185
|
+
end
|
186
|
+
end
|
187
|
+
end
|
167
188
|
|
168
|
-
|
169
|
-
|
170
|
-
subject
|
189
|
+
context 'with :ext, without period' do
|
190
|
+
context 'calling once' do
|
191
|
+
subject { rule_context.write(ext: 'html') }
|
192
|
+
|
193
|
+
it 'makes a request to the executor' do
|
194
|
+
expect(executor).to receive(:snapshot).with(:_0, path: '/foo.html')
|
195
|
+
subject
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
context 'calling twice' do
|
200
|
+
subject do
|
201
|
+
rule_context.write(ext: 'html')
|
202
|
+
rule_context.write(ext: 'htm')
|
203
|
+
end
|
204
|
+
|
205
|
+
it 'makes a request to the executor' do
|
206
|
+
expect(executor).to receive(:snapshot).with(:_0, path: '/foo.html')
|
207
|
+
expect(executor).to receive(:snapshot).with(:_1, path: '/foo.htm')
|
208
|
+
subject
|
209
|
+
end
|
171
210
|
end
|
172
211
|
end
|
173
212
|
|
174
|
-
context '
|
175
|
-
|
176
|
-
rule_context.write('
|
177
|
-
|
213
|
+
context 'with :ext, without period' do
|
214
|
+
context 'calling once' do
|
215
|
+
subject { rule_context.write(ext: '.html') }
|
216
|
+
|
217
|
+
it 'makes a request to the executor' do
|
218
|
+
expect(executor).to receive(:snapshot).with(:_0, path: '/foo.html')
|
219
|
+
subject
|
220
|
+
end
|
178
221
|
end
|
179
222
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
223
|
+
context 'calling twice' do
|
224
|
+
subject do
|
225
|
+
rule_context.write(ext: '.html')
|
226
|
+
rule_context.write(ext: '.htm')
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'makes a request to the executor' do
|
230
|
+
expect(executor).to receive(:snapshot).with(:_0, path: '/foo.html')
|
231
|
+
expect(executor).to receive(:snapshot).with(:_1, path: '/foo.htm')
|
232
|
+
subject
|
233
|
+
end
|
184
234
|
end
|
185
235
|
end
|
186
236
|
end
|