nanoc 4.1.0a1 → 4.1.0b1

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.
Files changed (41) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +4 -4
  3. data/NEWS.md +10 -0
  4. data/lib/nanoc/base/checksummer.rb +2 -1
  5. data/lib/nanoc/base/compilation/compiler.rb +33 -43
  6. data/lib/nanoc/base/compilation/outdatedness_checker.rb +4 -8
  7. data/lib/nanoc/base/entities/rule_memory.rb +5 -1
  8. data/lib/nanoc/base/entities.rb +0 -1
  9. data/lib/nanoc/base/services/action_provider.rb +22 -0
  10. data/lib/nanoc/base/services/compiler_loader.rb +5 -14
  11. data/lib/nanoc/base/services/executor.rb +1 -1
  12. data/lib/nanoc/base/services/item_rep_builder.rb +4 -12
  13. data/lib/nanoc/base/services/item_rep_router.rb +3 -4
  14. data/lib/nanoc/base/services.rb +1 -5
  15. data/lib/nanoc/base.rb +0 -3
  16. data/lib/nanoc/cli/commands/create-site.rb +2 -5
  17. data/lib/nanoc/cli/commands/show-rules.rb +9 -1
  18. data/lib/nanoc/helpers/rendering.rb +1 -1
  19. data/lib/nanoc/rule_dsl/action_provider.rb +76 -0
  20. data/lib/nanoc/{base/compilation → rule_dsl}/compiler_dsl.rb +9 -9
  21. data/lib/nanoc/{base/services → rule_dsl}/recording_executor.rb +6 -11
  22. data/lib/nanoc/{base/compilation → rule_dsl}/rule.rb +3 -3
  23. data/lib/nanoc/{base/compilation → rule_dsl}/rule_context.rb +2 -2
  24. data/lib/nanoc/{base/services → rule_dsl}/rule_memory_calculator.rb +16 -11
  25. data/lib/nanoc/{base/entities → rule_dsl}/rules_collection.rb +1 -1
  26. data/lib/nanoc/{base/services → rule_dsl}/rules_loader.rb +2 -2
  27. data/lib/nanoc/rule_dsl.rb +8 -0
  28. data/lib/nanoc/version.rb +1 -1
  29. data/lib/nanoc.rb +1 -0
  30. data/test/base/test_compiler.rb +45 -147
  31. data/test/filters/test_erb.rb +1 -1
  32. data/test/helper.rb +2 -2
  33. data/test/rule_dsl/test_action_provider.rb +70 -0
  34. data/test/{base → rule_dsl}/test_compiler_dsl.rb +25 -86
  35. data/test/{base → rule_dsl}/test_rule.rb +1 -1
  36. data/test/rule_dsl/test_rules_collection.rb +89 -0
  37. metadata +17 -16
  38. data/lib/nanoc/base/services/postprocessor.rb +0 -26
  39. data/lib/nanoc/base/services/preprocessor.rb +0 -26
  40. data/nanoc-4.0.2.gem +0 -0
  41. data/tags +0 -1175
@@ -1,12 +1,6 @@
1
1
  module Nanoc
2
- module Int
2
+ module RuleDSL
3
3
  class RecordingExecutor
4
- class NonFinalSnapshotWithPathError < ::Nanoc::Error
5
- def initialize
6
- super('This call to #snapshot specifies `final: false`, but it also specifies a path, which is an impossible combination.')
7
- end
8
- end
9
-
10
4
  class PathWithoutInitialSlashError < ::Nanoc::Error
11
5
  def initialize(rep, basic_path)
12
6
  super("The path returned for the #{rep.inspect} item representation, “#{basic_path}”, does not start with a slash. Please ensure that all routing rules return a path that starts with a slash.")
@@ -28,14 +22,15 @@ module Nanoc
28
22
  end
29
23
 
30
24
  def layout(_rep, layout_identifier, extra_filter_args = {})
25
+ unless @rule_memory.any_layouts?
26
+ @rule_memory.add_snapshot(:pre, true, nil)
27
+ end
28
+
31
29
  @rule_memory.add_layout(layout_identifier, extra_filter_args)
32
30
  end
33
31
 
34
32
  def snapshot(rep, snapshot_name, final: true, path: nil)
35
- actual_path = path || basic_path_from_rules_for(rep, snapshot_name)
36
- if !final && actual_path
37
- raise NonFinalSnapshotWithPathError
38
- end
33
+ actual_path = final ? (path || basic_path_from_rules_for(rep, snapshot_name)) : nil
39
34
  @rule_memory.add_snapshot(snapshot_name, final, actual_path)
40
35
  end
41
36
 
@@ -1,4 +1,4 @@
1
- module Nanoc::Int
1
+ module Nanoc::RuleDSL
2
2
  # Contains the processing information for a item.
3
3
  #
4
4
  # @api private
@@ -48,12 +48,12 @@ module Nanoc::Int
48
48
  #
49
49
  # @param [Nanoc::Int::ItemRep] rep
50
50
  # @param [Nanoc::Int::Site] site
51
- # @param [Nanoc::Int::Executor, Nanoc::Int::RecordingExecutor] executor
51
+ # @param [Nanoc::Int::Executor, Nanoc::RuleDSL::RecordingExecutor] executor
52
52
  # @param [Nanoc::ViewContext] view_context
53
53
  #
54
54
  # @return [void]
55
55
  def apply_to(rep, site:, executor:, view_context:)
56
- context = Nanoc::Int::RuleContext.new(
56
+ context = Nanoc::RuleDSL::RuleContext.new(
57
57
  rep: rep, executor: executor, site: site, view_context: view_context)
58
58
  context.instance_exec(matches(rep.item.identifier), &@block)
59
59
  end
@@ -1,4 +1,4 @@
1
- module Nanoc::Int
1
+ module Nanoc::RuleDSL
2
2
  # Provides a context in which compilation and routing rules can be executed.
3
3
  # It provides access to the item representation that is being compiled or
4
4
  # routed.
@@ -7,7 +7,7 @@ module Nanoc::Int
7
7
  class RuleContext < Nanoc::Int::Context
8
8
  # @param [Nanoc::Int::ItemRep] rep
9
9
  # @param [Nanoc::Int::Site] site
10
- # @param [Nanoc::Int::Executor, Nanoc::Int::RecordingExecutor] executor
10
+ # @param [Nanoc::Int::Executor, Nanoc::RuleDSL::RecordingExecutor] executor
11
11
  # @param [Nanoc::ViewContext] view_context
12
12
  def initialize(rep:, site:, executor:, view_context:)
13
13
  @_executor = executor
@@ -1,4 +1,4 @@
1
- module Nanoc::Int
1
+ module Nanoc::RuleDSL
2
2
  # Calculates rule memories for objects that can be run through a rule (item
3
3
  # representations and layouts).
4
4
  #
@@ -16,7 +16,7 @@ module Nanoc::Int
16
16
  attr_accessor :rules_collection
17
17
 
18
18
  # @param [Nanoc::Int::Site] site
19
- # @param [Nanoc::Int::RulesCollection] rules_collection
19
+ # @param [Nanoc::RuleDSL::RulesCollection] rules_collection
20
20
  def initialize(site:, rules_collection:)
21
21
  @site = site
22
22
  @rules_collection = rules_collection
@@ -26,6 +26,9 @@ module Nanoc::Int
26
26
  #
27
27
  # @return [Nanoc::Int::RuleMemory]
28
28
  def [](obj)
29
+ # FIXME: Remove this
30
+ obj = obj.unwrap if obj.respond_to?(:unwrap)
31
+
29
32
  case obj
30
33
  when Nanoc::Int::ItemRep
31
34
  new_rule_memory_for_rep(obj)
@@ -54,19 +57,21 @@ module Nanoc::Int
54
57
  #
55
58
  # @return [Nanoc::Int::RuleMemory]
56
59
  def new_rule_memory_for_rep(rep)
57
- # FIXME: This is more-or-less duplicated from Compiler#recalculate_content_for_rep.
58
- # Letting the compiler use the rule memory would fix this.
59
-
60
60
  # FIXME: What if #compilation_rule_for returns nil?
61
61
 
62
- executor = Nanoc::Int::RecordingExecutor.new(rep, @rules_collection, @site)
62
+ executor = Nanoc::RuleDSL::RecordingExecutor.new(rep, @rules_collection, @site)
63
+ rule = @rules_collection.compilation_rule_for(rep)
64
+
63
65
  executor.snapshot(rep, :raw)
64
66
  executor.snapshot(rep, :pre, final: false)
65
- @rules_collection
66
- .compilation_rule_for(rep)
67
- .apply_to(rep, executor: executor, site: @site, view_context: nil)
68
- executor.snapshot(rep, :post) if rep.has_snapshot?(:post)
69
- executor.snapshot(rep, :last) unless executor.rule_memory.snapshot_actions.any? { |sa| sa.snapshot_name == :last }
67
+ rule.apply_to(rep, executor: executor, site: @site, view_context: nil)
68
+ if executor.rule_memory.any_layouts?
69
+ executor.snapshot(rep, :post)
70
+ end
71
+ unless executor.rule_memory.snapshot_actions.any? { |sa| sa.snapshot_name == :last }
72
+ executor.snapshot(rep, :last)
73
+ end
74
+
70
75
  executor.rule_memory
71
76
  end
72
77
 
@@ -1,4 +1,4 @@
1
- module Nanoc::Int
1
+ module Nanoc::RuleDSL
2
2
  # Keeps track of the rules in a site.
3
3
  #
4
4
  # @api private
@@ -1,8 +1,8 @@
1
- module Nanoc::Int
1
+ module Nanoc::RuleDSL
2
2
  # @api private
3
3
  class RulesLoader
4
4
  def initialize(config, rules_collection)
5
- @dsl = Nanoc::Int::CompilerDSL.new(rules_collection, config)
5
+ @dsl = Nanoc::RuleDSL::CompilerDSL.new(rules_collection, config)
6
6
  end
7
7
 
8
8
  def load
@@ -0,0 +1,8 @@
1
+ require_relative 'rule_dsl/compiler_dsl'
2
+ require_relative 'rule_dsl/action_provider'
3
+ require_relative 'rule_dsl/recording_executor'
4
+ require_relative 'rule_dsl/rule_context'
5
+ require_relative 'rule_dsl/rule_memory_calculator'
6
+ require_relative 'rule_dsl/rule'
7
+ require_relative 'rule_dsl/rules_collection'
8
+ require_relative 'rule_dsl/rules_loader'
data/lib/nanoc/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Nanoc
2
2
  # The current Nanoc version.
3
- VERSION = '4.1.0a1'
3
+ VERSION = '4.1.0b1'
4
4
  end
data/lib/nanoc.rb CHANGED
@@ -41,3 +41,4 @@ require 'nanoc/extra'
41
41
  require 'nanoc/data_sources'
42
42
  require 'nanoc/filters'
43
43
  require 'nanoc/helpers'
44
+ require 'nanoc/rule_dsl'
@@ -7,20 +7,17 @@ class Nanoc::Int::CompilerTest < Nanoc::TestCase
7
7
  layouts: [],
8
8
  )
9
9
 
10
- rules_collection = Nanoc::Int::RulesCollection.new
11
-
12
10
  reps = Nanoc::Int::ItemRepRepo.new
13
11
 
12
+ action_provider = Nanoc::Int::ActionProvider.named(:rule_dsl).for(site)
13
+
14
14
  params = {
15
15
  compiled_content_cache: Nanoc::Int::CompiledContentCache.new,
16
16
  checksum_store: Nanoc::Int::ChecksumStore.new(site: site),
17
17
  rule_memory_store: Nanoc::Int::RuleMemoryStore.new,
18
- rule_memory_calculator: Nanoc::Int::RuleMemoryCalculator.new(
19
- rules_collection: rules_collection,
20
- site: site,
21
- ),
22
18
  dependency_store: Nanoc::Int::DependencyStore.new(
23
19
  site.items.to_a + site.layouts.to_a),
20
+ action_provider: action_provider,
24
21
  reps: reps,
25
22
  }
26
23
 
@@ -29,157 +26,58 @@ class Nanoc::Int::CompilerTest < Nanoc::TestCase
29
26
  site: site,
30
27
  checksum_store: params[:checksum_store],
31
28
  dependency_store: params[:dependency_store],
32
- rules_collection: params[:rules_collection],
33
29
  rule_memory_store: params[:rule_memory_store],
34
- rule_memory_calculator: params[:rule_memory_calculator],
30
+ action_provider: action_provider,
35
31
  reps: reps,
36
32
  )
37
33
 
38
- Nanoc::Int::Compiler.new(site, rules_collection, params)
39
- end
40
-
41
- def test_compilation_rule_for
42
- # Mock rules
43
- rules = [mock, mock, mock]
44
- rules[0].expects(:applicable_to?).returns(false)
45
- rules[1].expects(:applicable_to?).returns(true)
46
- rules[1].expects(:rep_name).returns('wrong')
47
- rules[2].expects(:applicable_to?).returns(true)
48
- rules[2].expects(:rep_name).returns('right')
49
-
50
- # Create compiler
51
- compiler = new_compiler
52
- compiler.rules_collection.instance_eval { @item_compilation_rules = rules }
53
-
54
- # Mock rep
55
- rep = mock
56
- rep.stubs(:name).returns('right')
57
- item = mock
58
- rep.stubs(:item).returns(item)
59
-
60
- # Test
61
- assert_equal rules[2], compiler.rules_collection.compilation_rule_for(rep)
62
- end
63
-
64
- def test_filter_for_layout_with_existant_layout
65
- # Create compiler
66
- compiler = new_compiler
67
- compiler.rules_collection.layout_filter_mapping[Nanoc::Int::Pattern.from(/.*/)] = [:erb, { foo: 'bar' }]
68
-
69
- # Mock layout
70
- layout = MiniTest::Mock.new
71
- layout.expect(:identifier, '/some_layout/')
72
-
73
- # Check
74
- assert_equal([:erb, { foo: 'bar' }], compiler.rules_collection.filter_for_layout(layout))
34
+ Nanoc::Int::Compiler.new(site, params)
75
35
  end
76
36
 
77
- def test_filter_for_layout_with_existant_layout_and_unknown_filter
78
- # Create compiler
79
- compiler = new_compiler
80
- compiler.rules_collection.layout_filter_mapping[Nanoc::Int::Pattern.from(/.*/)] = [:some_unknown_filter, { foo: 'bar' }]
81
-
82
- # Mock layout
83
- layout = MiniTest::Mock.new
84
- layout.expect(:identifier, '/some_layout/')
85
-
86
- # Check
87
- assert_equal([:some_unknown_filter, { foo: 'bar' }], compiler.rules_collection.filter_for_layout(layout))
88
- end
89
-
90
- def test_filter_for_layout_with_nonexistant_layout
91
- # Create compiler
92
- compiler = new_compiler
93
- compiler.rules_collection.layout_filter_mapping[Nanoc::Int::Pattern.from(%r{^/foo/$})] = [:erb, { foo: 'bar' }]
94
-
95
- # Mock layout
96
- layout = MiniTest::Mock.new
97
- layout.expect(:identifier, '/bar/')
98
-
99
- # Check
100
- assert_equal(nil, compiler.rules_collection.filter_for_layout(layout))
101
- end
102
-
103
- def test_filter_for_layout_with_many_layouts
104
- # Create compiler
105
- compiler = new_compiler
106
- compiler.rules_collection.layout_filter_mapping[Nanoc::Int::Pattern.from(%r{^/a/b/c/.*/$})] = [:erb, { char: 'd' }]
107
- compiler.rules_collection.layout_filter_mapping[Nanoc::Int::Pattern.from(%r{^/a/.*/$})] = [:erb, { char: 'b' }]
108
- compiler.rules_collection.layout_filter_mapping[Nanoc::Int::Pattern.from(%r{^/a/b/.*/$})] = [:erb, { char: 'c' }] # never used!
109
- compiler.rules_collection.layout_filter_mapping[Nanoc::Int::Pattern.from(%r{^/.*/$})] = [:erb, { char: 'a' }]
110
-
111
- # Mock layout
112
- layouts = [mock, mock, mock, mock]
113
- layouts[0].stubs(:identifier).returns('/a/b/c/d/')
114
- layouts[1].stubs(:identifier).returns('/a/b/c/')
115
- layouts[2].stubs(:identifier).returns('/a/b/')
116
- layouts[3].stubs(:identifier).returns('/a/')
117
-
118
- # Get expectations
119
- expectations = {
120
- 0 => 'd',
121
- 1 => 'b', # never used! not c, because b takes priority
122
- 2 => 'b',
123
- 3 => 'a',
124
- }
37
+ def test_compile_rep_should_write_proper_snapshots_real
38
+ with_site do |site|
39
+ File.write('content/moo.txt', '<%= 1 %> <%%= 2 %> <%%%= 3 %>')
40
+ File.write('layouts/default.erb', 'head <%= yield %> foot')
125
41
 
126
- # Check
127
- expectations.each_pair do |num, char|
128
- filter_and_args = compiler.rules_collection.filter_for_layout(layouts[num])
129
- refute_nil(filter_and_args)
130
- assert_equal(char, filter_and_args[1][:char])
131
- end
132
- end
42
+ File.open('Rules', 'w') do |io|
43
+ io.write "compile '/**/*' do\n"
44
+ io.write " filter :erb\n"
45
+ io.write " filter :erb\n"
46
+ io.write " layout 'default'\n"
47
+ io.write " filter :erb\n"
48
+ io.write "end\n"
49
+ io.write "\n"
50
+ io.write "route '/**/*', snapshot: :raw do\n"
51
+ io.write " '/moo-raw.txt'\n"
52
+ io.write "end\n"
53
+ io.write "\n"
54
+ io.write "route '/**/*', snapshot: :pre do\n"
55
+ io.write " '/moo-pre.txt'\n"
56
+ io.write "end\n"
57
+ io.write "\n"
58
+ io.write "route '/**/*', snapshot: :post do\n"
59
+ io.write " '/moo-post.txt'\n"
60
+ io.write "end\n"
61
+ io.write "\n"
62
+ io.write "route '/**/*' do\n"
63
+ io.write " '/moo-last.txt'\n"
64
+ io.write "end\n"
65
+ io.write "\n"
66
+ io.write "layout '/**/*', :erb\n"
67
+ end
133
68
 
134
- def test_compile_rep_should_write_proper_snapshots
135
- # Mock rep
136
- item = Nanoc::Int::Item.new('<%= 1 %> <%%= 2 %> <%%%= 3 %>', {}, '/moo/')
137
- rep = Nanoc::Int::ItemRep.new(item, :blah)
138
-
139
- # Set snapshot filenames
140
- rep.raw_paths = {
141
- raw: 'raw.txt',
142
- pre: 'pre.txt',
143
- post: 'post.txt',
144
- last: 'last.txt',
145
- }
69
+ site = Nanoc::Int::SiteLoader.new.new_from_cwd
70
+ site.compile
146
71
 
147
- # Create rule
148
- rule_block = proc do
149
- filter :erb
150
- filter :erb
151
- layout '/blah/'
152
- filter :erb
72
+ assert File.file?('output/moo-raw.txt')
73
+ # assert File.file?('output/moo-pre.txt')
74
+ assert File.file?('output/moo-post.txt')
75
+ assert File.file?('output/moo-last.txt')
76
+ assert_equal '<%= 1 %> <%%= 2 %> <%%%= 3 %>', File.read('output/moo-raw.txt')
77
+ # assert_equal '1 2 <%= 3 %>', File.read('output/moo-pre.txt')
78
+ assert_equal 'head 1 2 3 foot', File.read('output/moo-post.txt')
79
+ assert_equal 'head 1 2 3 foot', File.read('output/moo-last.txt')
153
80
  end
154
- rule = Nanoc::Int::Rule.new(Nanoc::Int::Pattern.from(/blah/), :meh, rule_block)
155
-
156
- # Create layout
157
- layout = Nanoc::Int::Layout.new('head <%= yield %> foot', {}, '/blah/')
158
-
159
- # Create site
160
- site = mock
161
- site.stubs(:config).returns({})
162
- site.stubs(:items).returns([])
163
- site.stubs(:layouts).returns([layout])
164
-
165
- # Create compiler
166
- compiler = new_compiler(site)
167
- compiler.rules_collection.expects(:compilation_rule_for).times(2).with(rep).returns(rule)
168
- compiler.rules_collection.layout_filter_mapping[Nanoc::Int::Pattern.from(%r{^/blah/$})] = [:erb, {}]
169
- site.stubs(:compiler).returns(compiler)
170
-
171
- # Compile
172
- compiler.send(:compile_rep, rep)
173
-
174
- # Test
175
- assert File.file?('raw.txt')
176
- assert File.file?('pre.txt')
177
- assert File.file?('post.txt')
178
- assert File.file?('last.txt')
179
- assert_equal '<%= 1 %> <%%= 2 %> <%%%= 3 %>', File.read('raw.txt')
180
- assert_equal '1 2 <%= 3 %>', File.read('pre.txt')
181
- assert_equal 'head 1 2 3 foot', File.read('post.txt')
182
- assert_equal 'head 1 2 3 foot', File.read('last.txt')
183
81
  end
184
82
 
185
83
  def test_compile_with_no_reps
@@ -77,7 +77,7 @@ class Nanoc::Filters::ERBTest < Nanoc::TestCase
77
77
 
78
78
  # With
79
79
  assert_raises(SecurityError) do
80
- res = filter.setup_and_run('<%= File.read("moo") %>', safe_level: 3)
80
+ res = filter.setup_and_run('<%= eval File.read("moo") %>', safe_level: 1)
81
81
  end
82
82
  end
83
83
 
data/test/helper.rb CHANGED
@@ -95,11 +95,11 @@ EOS
95
95
  end
96
96
 
97
97
  File.open('nanoc.yaml', 'w') do |io|
98
- io << 'string_pattern_type: legacy' << "\n"
98
+ io << 'string_pattern_type: legacy' << "\n" if params.fetch(:legacy, true)
99
99
  io << 'data_sources:' << "\n"
100
100
  io << ' -' << "\n"
101
101
  io << ' type: filesystem' << "\n"
102
- io << ' identifier_type: legacy' << "\n"
102
+ io << ' identifier_type: legacy' << "\n" if params.fetch(:legacy, true)
103
103
  end
104
104
 
105
105
  File.open('Rules', 'w') { |io| io.write(rules_content) }
@@ -0,0 +1,70 @@
1
+ class Nanoc::RuleDSL::ActionProviderTest < Nanoc::TestCase
2
+ def new_action_provider(site)
3
+ rules_collection = Nanoc::RuleDSL::RulesCollection.new
4
+
5
+ rule_memory_calculator =
6
+ Nanoc::RuleDSL::RuleMemoryCalculator.new(
7
+ rules_collection: rules_collection, site: site)
8
+
9
+ action_provider = Nanoc::RuleDSL::ActionProvider.new(
10
+ rules_collection, rule_memory_calculator)
11
+
12
+ Nanoc::RuleDSL::RulesLoader.new(site.config, rules_collection).load
13
+
14
+ action_provider
15
+ end
16
+
17
+ def test_per_rules_file_preprocessor
18
+ # Create site
19
+ Nanoc::CLI.run %w( create_site foo )
20
+ FileUtils.cd('foo') do
21
+ # Create a bonus rules file
22
+ File.write(
23
+ 'more_rules.rb',
24
+ "preprocess { @items['/index.*'][:preprocessed] = true }")
25
+
26
+ # Adjust normal rules file
27
+ File.write(
28
+ 'Rules',
29
+ "include_rules 'more_rules'\n\npreprocess {}\n\n" + File.read('Rules'))
30
+
31
+ # Create site and compiler
32
+ site = Nanoc::Int::SiteLoader.new.new_from_cwd
33
+ action_provider = new_action_provider(site)
34
+
35
+ # Check that the two preprocess blocks have been added
36
+ assert_equal 2, action_provider.rules_collection.preprocessors.size
37
+ refute_nil action_provider.rules_collection.preprocessors.first
38
+ refute_nil action_provider.rules_collection.preprocessors.to_a.last
39
+
40
+ # Apply preprocess blocks
41
+ action_provider.preprocess(site)
42
+ assert site.items['/index.*'].attributes[:preprocessed]
43
+ end
44
+ end
45
+
46
+ def test_per_rules_file_postprocessor
47
+ # Create site
48
+ Nanoc::CLI.run %w( create_site foo )
49
+ FileUtils.cd('foo') do
50
+ # Create a bonus rules file
51
+ File.write(
52
+ 'more_rules.rb',
53
+ 'postprocess {}')
54
+
55
+ # Adjust normal rules file
56
+ File.write(
57
+ 'Rules',
58
+ "include_rules 'more_rules'\n\npostprocess {}\n\n" + File.read('Rules'))
59
+
60
+ # Create site and compiler
61
+ site = Nanoc::Int::SiteLoader.new.new_from_cwd
62
+ action_provider = new_action_provider(site)
63
+
64
+ # Check that the two postprocess blocks have been added
65
+ assert_equal 2, action_provider.rules_collection.postprocessors.size
66
+ refute_nil action_provider.rules_collection.postprocessors.first
67
+ refute_nil action_provider.rules_collection.postprocessors.to_a.last
68
+ end
69
+ end
70
+ end