nanoc 4.8.11 → 4.8.12

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