nanoc 4.8.11 → 4.8.12

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 +5 -5
  2. data/NEWS.md +10 -0
  3. data/README.md +1 -0
  4. data/lib/nanoc/base/entities/pattern.rb +2 -0
  5. data/lib/nanoc/base/entities/site.rb +1 -1
  6. data/lib/nanoc/base/repos/action_sequence_store.rb +4 -1
  7. data/lib/nanoc/base/repos/compiled_content_cache.rb +2 -2
  8. data/lib/nanoc/base/services/compiler.rb +4 -1
  9. data/lib/nanoc/base/services/compiler/stages/cleanup.rb +3 -3
  10. data/lib/nanoc/filters/colorize_syntax/colorizers.rb +2 -3
  11. data/lib/nanoc/filters/pandoc.rb +1 -1
  12. data/lib/nanoc/version.rb +1 -1
  13. data/nanoc.manifest +4 -6
  14. data/spec/gem_spec.rb +21 -0
  15. data/spec/manifest_spec.rb +2 -2
  16. data/spec/nanoc/base/compiler_spec.rb +7 -2
  17. data/spec/nanoc/base/entities/pattern_spec.rb +6 -0
  18. data/spec/nanoc/base/repos/compiled_content_cache_spec.rb +9 -1
  19. data/spec/nanoc/base/repos/dependency_store_spec.rb +116 -9
  20. data/spec/nanoc/base/repos/store_spec.rb +34 -0
  21. data/spec/nanoc/base/services/compiler/phases/cache_spec.rb +9 -1
  22. data/spec/nanoc/base/services/compiler/stages/cleanup_spec.rb +1 -1
  23. data/spec/nanoc/base/services/compiler/stages/compile_reps_spec.rb +1 -1
  24. data/spec/nanoc/base/services/notification_center_spec.rb +25 -0
  25. data/spec/nanoc/base/services/outdatedness_checker_spec.rb +3 -3
  26. data/spec/nanoc/base/services/outdatedness_rules_spec.rb +2 -2
  27. data/spec/nanoc/base/views/post_compile_item_rep_view_spec.rb +10 -2
  28. data/spec/nanoc/filters/colorize_syntax/rouge_spec.rb +66 -108
  29. data/spec/nanoc/regressions/gh_1248_spec.rb +24 -0
  30. data/spec/nanoc/rule_dsl/rule_spec.rb +111 -0
  31. data/spec/spec_helper.rb +0 -6
  32. data/test/base/test_compiler.rb +0 -54
  33. data/test/filters/test_pandoc.rb +2 -2
  34. data/test/helper.rb +0 -36
  35. metadata +7 -9
  36. data/Appraisals +0 -13
  37. data/test/base/test_dependency_tracker.rb +0 -265
  38. data/test/base/test_notification_center.rb +0 -32
  39. data/test/base/test_store.rb +0 -39
  40. data/test/rule_dsl/test_rule.rb +0 -27
  41. data/test/test_gem.rb +0 -30
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 686e6a239ceae1d59678f267f4aa4c5dfc46b45e
4
- data.tar.gz: e80de3bfc0c9475292ad4f9f4fa886f87bd272a8
2
+ SHA256:
3
+ metadata.gz: e5cc17f8346af531417d26173e8610348080326f2f9faceb6485e19d9fc9c194
4
+ data.tar.gz: 2e9ebdd0c7da3bb1d4119b4dc8ca51dc840b66ff191af0336a88da006b5af8f4
5
5
  SHA512:
6
- metadata.gz: b476ce18ea4cdd880de849b64bc5c8bbe1287a1b3cbd67a7a54a0fa079812107d9448f839785b391ae192147f331facb47e89d828a65c896aae5dad8b40a5c08
7
- data.tar.gz: 8ffcb7d57ea237b0fef6490828d960247fd618c814990e14f0f707a55831f8288b2666cc21693792452f3d9d1e475aa9c33cbebc6807405d7749cda3022fedc9
6
+ metadata.gz: d3674db085f03b8a75de0c39c202c69769b77317a830eb3ffb8164e14959842270e16c8cc153f1e8de75ba1e35a6c23e6c410a35a459873173664a71829b9373
7
+ data.tar.gz: 650b49e7c74857d1d2dfd3fe16edd60005a0a47cd06799cc894813896edf406560f8712063959f94993d40bdaf7bf308a382f5c165a12d9d96a1759b9b7ea3fa
data/NEWS.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Nanoc news
2
2
 
3
+ ## 4.8.12 (2017-11-16)
4
+
5
+ Fixes:
6
+
7
+ * Fixed issue where changing `:output_dir` during preprocessing would prevent Nanoc from performing incremental compilation (#1248, #1249)
8
+
9
+ Enhancements:
10
+
11
+ * Allowed creation of pattern from symbols, not just strings (#1247) [Gregory Pakosz]
12
+
3
13
  ## 4.8.11 (2017-10-28)
4
14
 
5
15
  Enhancements:
data/README.md CHANGED
@@ -3,6 +3,7 @@
3
3
  [![Build status](http://img.shields.io/travis/nanoc/nanoc.svg)](https://travis-ci.org/nanoc/nanoc)
4
4
  [![Code Climate](http://img.shields.io/codeclimate/github/nanoc/nanoc.svg)](https://codeclimate.com/github/nanoc/nanoc)
5
5
  [![Code Coverage](https://img.shields.io/codecov/c/github/nanoc/nanoc.svg)](https://codecov.io/gh/nanoc/nanoc)
6
+ [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fnanoc%2Fnanoc.svg?type=shield)](https://app.fossa.io/projects/git%2Bgithub.com%2Fnanoc%2Fnanoc?ref=badge_shield)
6
7
 
7
8
  ![Nanoc logo](https://avatars1.githubusercontent.com/u/3260163?s=140)
8
9
 
@@ -14,6 +14,8 @@ module Nanoc::Int
14
14
  Nanoc::Int::StringPattern.new(obj)
15
15
  when Regexp
16
16
  Nanoc::Int::RegexpPattern.new(obj)
17
+ when Symbol
18
+ Nanoc::Int::StringPattern.new(obj.to_s)
17
19
  else
18
20
  raise ArgumentError, "Do not know how to convert `#{obj.inspect}` into a Nanoc::Pattern"
19
21
  end
@@ -9,7 +9,7 @@ module Nanoc::Int
9
9
  attr_reader :config
10
10
  attr_accessor :data_source
11
11
 
12
- contract C::KeywordArgs[config: Nanoc::Int::Configuration, code_snippets: C::IterOf[Nanoc::Int::CodeSnippet], data_source: C::Maybe[C::Named['Nanoc::DataSource']]] => C::Any
12
+ contract C::KeywordArgs[config: Nanoc::Int::Configuration, code_snippets: C::IterOf[Nanoc::Int::CodeSnippet], data_source: C::Named['Nanoc::DataSource']] => C::Any
13
13
  def initialize(config:, code_snippets:, data_source:)
14
14
  @config = config
15
15
  @code_snippets = code_snippets
@@ -6,7 +6,10 @@ module Nanoc::Int
6
6
  #
7
7
  # @api private
8
8
  class ActionSequenceStore < ::Nanoc::Int::Store
9
- def initialize(site: nil)
9
+ include Nanoc::Int::ContractsSupport
10
+
11
+ contract C::KeywordArgs[site: Nanoc::Int::Site] => C::Any
12
+ def initialize(site:)
10
13
  super(Nanoc::Int::Store.tmp_path_for(site: site, store_name: 'rule_memory'), 1)
11
14
 
12
15
  @action_sequences = {}
@@ -8,8 +8,8 @@ module Nanoc::Int
8
8
  class CompiledContentCache < ::Nanoc::Int::Store
9
9
  include Nanoc::Int::ContractsSupport
10
10
 
11
- contract C::KeywordArgs[site: C::Maybe[Nanoc::Int::Site], items: C::IterOf[Nanoc::Int::Item]] => C::Any
12
- def initialize(site: nil, items:)
11
+ contract C::KeywordArgs[site: Nanoc::Int::Site, items: C::IterOf[Nanoc::Int::Item]] => C::Any
12
+ def initialize(site:, items:)
13
13
  super(Nanoc::Int::Store.tmp_path_for(site: site, store_name: 'compiled_content'), 2)
14
14
 
15
15
  @items = items
@@ -7,6 +7,9 @@ module Nanoc::Int
7
7
  def initialize(site, compiled_content_cache:, checksum_store:, action_sequence_store:, action_provider:, dependency_store:, outdatedness_store:)
8
8
  @site = site
9
9
 
10
+ # Needed because configuration is mutable :(
11
+ @output_dirs = @site.config.output_dirs
12
+
10
13
  @compiled_content_cache = compiled_content_cache
11
14
  @checksum_store = checksum_store
12
15
  @action_sequence_store = action_sequence_store
@@ -199,7 +202,7 @@ module Nanoc::Int
199
202
  end
200
203
 
201
204
  def cleanup_stage
202
- @_cleanup_stage ||= Stages::Cleanup.new(@site.config)
205
+ @_cleanup_stage ||= Stages::Cleanup.new(@output_dirs)
203
206
  end
204
207
 
205
208
  def forget_outdated_dependencies_stage
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Nanoc::Int::Compiler::Stages
4
4
  class Cleanup
5
- def initialize(config)
6
- @config = config
5
+ def initialize(output_dirs)
6
+ @output_dirs = output_dirs
7
7
  end
8
8
 
9
9
  def run
@@ -20,7 +20,7 @@ module Nanoc::Int::Compiler::Stages
20
20
  end
21
21
 
22
22
  def cleanup_unused_stores
23
- used_paths = @config.output_dirs.map { |d| Nanoc::Int::Store.tmp_path_prefix(d) }
23
+ used_paths = @output_dirs.map { |d| Nanoc::Int::Store.tmp_path_prefix(d) }
24
24
  all_paths = Dir.glob('tmp/nanoc/*')
25
25
  (all_paths - used_paths).each do |obsolete_path|
26
26
  FileUtils.rm_rf(obsolete_path)
@@ -131,8 +131,7 @@ module Nanoc::Filters::ColorizeSyntax::Colorizers
131
131
  def process(code, language, params = {})
132
132
  require 'rouge'
133
133
 
134
- if Rouge.version < '2' || params.fetch(:legacy, false)
135
- # Rouge 1.x or Rouge 2.x legacy options
134
+ if params.fetch(:legacy, false)
136
135
  formatter_options = {
137
136
  css_class: params.fetch(:css_class, 'highlight'),
138
137
  inline_theme: params.fetch(:inline_theme, nil),
@@ -140,7 +139,7 @@ module Nanoc::Filters::ColorizeSyntax::Colorizers
140
139
  start_line: params.fetch(:start_line, 1),
141
140
  wrap: params.fetch(:wrap, false),
142
141
  }
143
- formatter_cls = Rouge::Formatters.const_get(Rouge.version < '2' ? 'HTML' : 'HTMLLegacy')
142
+ formatter_cls = Rouge::Formatters::HTMLLegacy
144
143
  formatter = formatter_cls.new(formatter_options)
145
144
  else
146
145
  formatter = params.fetch(:formatter, Rouge::Formatters::HTML.new)
@@ -22,7 +22,7 @@ module Nanoc::Filters
22
22
  #
23
23
  # @example Passing arguments using `:arg`
24
24
  #
25
- # filter :pandoc, args: [:s, {:f => :markdown, :to => :html}, 'no-wrap', :toc]
25
+ # filter :pandoc, args: [:s, {:f => :markdown, :to => :html}, 'wrap=none', :toc]
26
26
  #
27
27
  # @example Passing arguments not using `:arg`
28
28
  #
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Nanoc
4
4
  # The current Nanoc version.
5
- VERSION = '4.8.11'
5
+ VERSION = '4.8.12'
6
6
  end
@@ -1,6 +1,5 @@
1
1
  .rspec
2
2
  .rubocop.yml
3
- Appraisals
4
3
  CODE_OF_CONDUCT.md
5
4
  LICENSE
6
5
  nanoc.gemspec
@@ -271,6 +270,7 @@ lib/nanoc/version.rb
271
270
 
272
271
  spec/contributors_spec.rb
273
272
  spec/manifest_spec.rb
273
+ spec/gem_spec.rb
274
274
  spec/nanoc/base/changes_stream_spec.rb
275
275
  spec/nanoc/base/checksummer_spec.rb
276
276
  spec/nanoc/base/compiler_spec.rb
@@ -326,6 +326,7 @@ spec/nanoc/base/services/dependency_tracker_spec.rb
326
326
  spec/nanoc/base/services/executor_spec.rb
327
327
  spec/nanoc/base/services/item_rep_router_spec.rb
328
328
  spec/nanoc/base/services/item_rep_selector_spec.rb
329
+ spec/nanoc/base/services/notification_center_spec.rb
329
330
  spec/nanoc/base/services/outdatedness_checker_spec.rb
330
331
  spec/nanoc/base/services/outdatedness_rules_spec.rb
331
332
  spec/nanoc/base/services/pruner_spec.rb
@@ -419,6 +420,7 @@ spec/nanoc/regressions/gh_1145_spec.rb
419
420
  spec/nanoc/regressions/gh_1171_spec.rb
420
421
  spec/nanoc/regressions/gh_1185_spec.rb
421
422
  spec/nanoc/regressions/gh_1216_spec.rb
423
+ spec/nanoc/regressions/gh_1248_spec.rb
422
424
  spec/nanoc/regressions/gh_761_spec.rb
423
425
  spec/nanoc/regressions/gh_767_spec.rb
424
426
  spec/nanoc/regressions/gh_769_spec.rb
@@ -454,6 +456,7 @@ spec/nanoc/rule_dsl/action_sequence_calculator_spec.rb
454
456
  spec/nanoc/rule_dsl/recording_executor_spec.rb
455
457
  spec/nanoc/rule_dsl/rule_context_spec.rb
456
458
  spec/nanoc/rule_dsl/rules_collection_spec.rb
459
+ spec/nanoc/rule_dsl/rule_spec.rb
457
460
  spec/nanoc/spec_spec.rb
458
461
  spec/nanoc/telemetry_spec.rb
459
462
  spec/nanoc/telemetry/counter_spec.rb
@@ -466,11 +469,8 @@ spec/regression_filenames_spec.rb
466
469
  spec/spec_helper.rb
467
470
 
468
471
  test/base/test_compiler.rb
469
- test/base/test_dependency_tracker.rb
470
472
  test/base/test_filter.rb
471
- test/base/test_notification_center.rb
472
473
  test/base/test_site.rb
473
- test/base/test_store.rb
474
474
  test/checking/checks/test_css.rb
475
475
  test/checking/checks/test_external_links.rb
476
476
  test/checking/checks/test_html.rb
@@ -540,6 +540,4 @@ test/helpers/test_link_to.rb
540
540
  test/helpers/test_xml_sitemap.rb
541
541
  test/rule_dsl/test_action_provider.rb
542
542
  test/rule_dsl/test_compiler_dsl.rb
543
- test/rule_dsl/test_rule.rb
544
543
  test/rule_dsl/test_rules_collection.rb
545
- test/test_gem.rb
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe 'nanoc.gem', chdir: false, stdio: true do
4
+ around do |ex|
5
+ Dir['*.gem'].each { |f| FileUtils.rm(f) }
6
+ ex.run
7
+ Dir['*.gem'].each { |f| FileUtils.rm(f) }
8
+ end
9
+
10
+ subject do
11
+ piper = Nanoc::Extra::Piper.new(stdout: $stdout, stderr: $stderr)
12
+ piper.run(%w[gem build nanoc.gemspec], nil)
13
+ end
14
+
15
+ it 'builds gem' do
16
+ expect { subject }
17
+ .to change { Dir['*.gem'] }
18
+ .from([])
19
+ .to(include(match(/^nanoc-.*\.gem$/)))
20
+ end
21
+ end
@@ -12,11 +12,11 @@ describe 'manifest', chdir: false do
12
12
 
13
13
  it 'contains all files in gemspec' do
14
14
  missing_from_manifest = gemspec_lines - manifest_lines
15
- expect(missing_from_manifest).to be_empty
15
+ expect(missing_from_manifest).to be_empty, "Found files that appear in the gemspec, but not in the manifest: #{missing_from_manifest.join(', ')}"
16
16
  end
17
17
 
18
18
  it 'contains no files not in gemspec' do
19
19
  extra_in_manifest = manifest_lines - gemspec_lines
20
- expect(extra_in_manifest).to be_empty
20
+ expect(extra_in_manifest).to be_empty, "Found files that appear in the manifest, but not in the gemspec: #{extra_in_manifest.join(', ')}"
21
21
  end
22
22
  end
@@ -14,14 +14,19 @@ describe Nanoc::Int::Compiler do
14
14
  end
15
15
 
16
16
  let(:checksum_store) { Nanoc::Int::ChecksumStore.new(objects: items) }
17
- let(:action_sequence_store) { Nanoc::Int::ActionSequenceStore.new }
17
+ let(:action_sequence_store) { Nanoc::Int::ActionSequenceStore.new(site: site) }
18
18
 
19
19
  let(:dependency_store) { Nanoc::Int::DependencyStore.new(items, layouts, config) }
20
20
 
21
21
  let(:outdatedness_store) { Nanoc::Int::OutdatednessStore.new(site: site) }
22
22
  let(:action_provider) { double(:action_provider) }
23
23
 
24
- let(:compiled_content_cache) { Nanoc::Int::CompiledContentCache.new(items: items) }
24
+ let(:compiled_content_cache) do
25
+ Nanoc::Int::CompiledContentCache.new(
26
+ site: site,
27
+ items: items,
28
+ )
29
+ end
25
30
 
26
31
  let(:rep) { Nanoc::Int::ItemRep.new(item, :default) }
27
32
  let(:item) { Nanoc::Int::Item.new('<%= 1 + 2 %>', {}, '/hi.md') }
@@ -21,6 +21,12 @@ describe Nanoc::Int::Pattern do
21
21
  expect(pattern.match?('/foo/xyz/bar.html')).to eql(false)
22
22
  end
23
23
 
24
+ it 'converts from symbol' do
25
+ pattern = described_class.from(:'/foo/x[ab]z/bar.*')
26
+ expect(pattern.match?('/foo/xaz/bar.html')).to eql(true)
27
+ expect(pattern.match?('/foo/xyz/bar.html')).to eql(false)
28
+ end
29
+
24
30
  it 'errors on other inputs' do
25
31
  expect { described_class.from(123) }.to raise_error(ArgumentError)
26
32
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  describe Nanoc::Int::CompiledContentCache do
4
- let(:cache) { described_class.new(items: items) }
4
+ let(:cache) { described_class.new(items: items, site: site) }
5
5
 
6
6
  let(:items) { [item] }
7
7
 
@@ -13,6 +13,14 @@ describe Nanoc::Int::CompiledContentCache do
13
13
 
14
14
  let(:content) { Nanoc::Int::Content.create('omg') }
15
15
 
16
+ let(:site) do
17
+ Nanoc::Int::Site.new(
18
+ config: Nanoc::Int::Configuration.new.with_defaults,
19
+ code_snippets: [],
20
+ data_source: Nanoc::Int::InMemDataSource.new(items, []),
21
+ )
22
+ end
23
+
16
24
  it 'has no content by default' do
17
25
  expect(cache[item_rep]).to be_nil
18
26
  end
@@ -14,6 +14,14 @@ describe Nanoc::Int::DependencyStore do
14
14
  let(:layouts) { Nanoc::Int::LayoutCollection.new(config, [layout_a, layout_b]) }
15
15
  let(:config) { Nanoc::Int::Configuration.new }
16
16
 
17
+ it 'is empty by default' do
18
+ expect(store.objects_causing_outdatedness_of(item_a)).to be_empty
19
+ expect(store.objects_causing_outdatedness_of(item_b)).to be_empty
20
+ expect(store.objects_causing_outdatedness_of(item_c)).to be_empty
21
+ expect(store.objects_causing_outdatedness_of(layout_a)).to be_empty
22
+ expect(store.objects_causing_outdatedness_of(layout_b)).to be_empty
23
+ end
24
+
17
25
  describe '#dependencies_causing_outdatedness_of' do
18
26
  context 'no dependencies' do
19
27
  it 'returns nothing for each' do
@@ -208,15 +216,17 @@ describe Nanoc::Int::DependencyStore do
208
216
  store.record_dependency(item_a, item_b, attributes: true)
209
217
 
210
218
  store.store
211
- store.items = items_after
212
- store.load
219
+ end
220
+
221
+ let(:reloaded_store) do
222
+ described_class.new(items_after, layouts, config).tap(&:load)
213
223
  end
214
224
 
215
225
  context 'no new items' do
216
226
  let(:items_after) { items }
217
227
 
218
228
  it 'has the right dependencies for item A' do
219
- deps = store.dependencies_causing_outdatedness_of(item_a)
229
+ deps = reloaded_store.dependencies_causing_outdatedness_of(item_a)
220
230
  expect(deps.size).to eql(1)
221
231
 
222
232
  expect(deps[0].from).to eql(item_b)
@@ -229,12 +239,12 @@ describe Nanoc::Int::DependencyStore do
229
239
  end
230
240
 
231
241
  it 'has the right dependencies for item B' do
232
- deps = store.dependencies_causing_outdatedness_of(item_b)
242
+ deps = reloaded_store.dependencies_causing_outdatedness_of(item_b)
233
243
  expect(deps).to be_empty
234
244
  end
235
245
 
236
246
  it 'has the right dependencies for item C' do
237
- deps = store.dependencies_causing_outdatedness_of(item_c)
247
+ deps = reloaded_store.dependencies_causing_outdatedness_of(item_c)
238
248
  expect(deps).to be_empty
239
249
  end
240
250
  end
@@ -247,10 +257,34 @@ describe Nanoc::Int::DependencyStore do
247
257
  let(:item_d) { Nanoc::Int::Item.new('d', {}, '/d.md') }
248
258
 
249
259
  it 'does not mark items as outdated' do
250
- expect(store.objects_causing_outdatedness_of(item_a)).not_to include(item_d)
251
- expect(store.objects_causing_outdatedness_of(item_b)).not_to include(item_d)
252
- expect(store.objects_causing_outdatedness_of(item_c)).not_to include(item_d)
253
- expect(store.objects_causing_outdatedness_of(item_d)).not_to include(item_d)
260
+ expect(reloaded_store.objects_causing_outdatedness_of(item_a)).not_to include(item_d)
261
+ expect(reloaded_store.objects_causing_outdatedness_of(item_b)).not_to include(item_d)
262
+ expect(reloaded_store.objects_causing_outdatedness_of(item_c)).not_to include(item_d)
263
+ expect(reloaded_store.objects_causing_outdatedness_of(item_d)).not_to include(item_d)
264
+ end
265
+ end
266
+
267
+ context 'unrelated item removed' do
268
+ let(:items_after) do
269
+ Nanoc::Int::ItemCollection.new(config, [item_a, item_b])
270
+ end
271
+
272
+ it 'does not mark items as outdated' do
273
+ expect(reloaded_store.objects_causing_outdatedness_of(item_a)).to eq([item_b])
274
+ expect(reloaded_store.objects_causing_outdatedness_of(item_b)).to be_empty
275
+ expect(reloaded_store.objects_causing_outdatedness_of(item_c)).to be_empty
276
+ end
277
+ end
278
+
279
+ context 'related item removed' do
280
+ let(:items_after) do
281
+ Nanoc::Int::ItemCollection.new(config, [item_a, item_c])
282
+ end
283
+
284
+ it 'does not mark items as outdated' do
285
+ expect(reloaded_store.objects_causing_outdatedness_of(item_a)).to eq([nil])
286
+ expect(reloaded_store.objects_causing_outdatedness_of(item_b)).to be_empty
287
+ expect(reloaded_store.objects_causing_outdatedness_of(item_c)).to be_empty
254
288
  end
255
289
  end
256
290
  end
@@ -303,6 +337,49 @@ describe Nanoc::Int::DependencyStore do
303
337
  subject
304
338
  expect(other_items).to all(satisfy { |o| store.dependencies_causing_outdatedness_of(o).empty? })
305
339
  end
340
+
341
+ context 'dependency on self' do
342
+ subject { store.record_dependency(source_obj, item_a) }
343
+
344
+ it 'does not create dependency on self' do
345
+ expect { subject }
346
+ .not_to change { store.objects_causing_outdatedness_of(source_obj) }
347
+ end
348
+ end
349
+
350
+ context 'two dependencies' do
351
+ subject do
352
+ store.record_dependency(source_obj, item_b)
353
+ store.record_dependency(source_obj, item_b)
354
+ end
355
+
356
+ it 'does not create duplicate dependencies' do
357
+ expect { subject }
358
+ .to change { store.objects_causing_outdatedness_of(source_obj) }
359
+ .from([])
360
+ .to([item_b])
361
+ end
362
+ end
363
+
364
+ context 'dependency to nil' do
365
+ subject { store.record_dependency(source_obj, nil) }
366
+
367
+ it 'creates a dependency to nil' do
368
+ expect { subject }
369
+ .to change { store.objects_causing_outdatedness_of(source_obj) }
370
+ .from([])
371
+ .to([nil])
372
+ end
373
+ end
374
+
375
+ context 'dependency from nil' do
376
+ subject { store.record_dependency(nil, item_b) }
377
+
378
+ it 'does not create a dependency from nil' do
379
+ expect { subject }
380
+ .not_to change { store.objects_causing_outdatedness_of(item_b) }
381
+ end
382
+ end
306
383
  end
307
384
 
308
385
  context 'compiled content prop' do
@@ -405,4 +482,34 @@ describe Nanoc::Int::DependencyStore do
405
482
  include_examples 'records dependencies'
406
483
  end
407
484
  end
485
+
486
+ describe '#forget_dependencies_for' do
487
+ before do
488
+ store.record_dependency(item_a, item_b)
489
+ store.record_dependency(item_a, item_c)
490
+ store.record_dependency(item_b, item_a)
491
+ store.record_dependency(item_b, item_c)
492
+ store.record_dependency(item_c, item_a)
493
+ store.record_dependency(item_c, item_b)
494
+ end
495
+
496
+ subject { store.forget_dependencies_for(item_b) }
497
+
498
+ it 'removes dependencies from item_a' do
499
+ expect { subject }
500
+ .not_to change { store.objects_causing_outdatedness_of(item_a) }
501
+ end
502
+
503
+ it 'removes dependencies from item_b' do
504
+ expect { subject }
505
+ .to change { store.objects_causing_outdatedness_of(item_b) }
506
+ .from(match_array([item_a, item_c]))
507
+ .to(be_empty)
508
+ end
509
+
510
+ it 'removes dependencies from item_c' do
511
+ expect { subject }
512
+ .not_to change { store.objects_causing_outdatedness_of(item_c) }
513
+ end
514
+ end
408
515
  end