nanoc 4.7.10 → 4.7.11

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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CONTRIBUTING.md +17 -0
  3. data/.github/ISSUE_TEMPLATE.md +23 -0
  4. data/.github/PULL_REQUEST_TEMPLATE.md +18 -0
  5. data/.gitignore +8 -0
  6. data/.rspec +3 -0
  7. data/.rubocop.yml +174 -0
  8. data/.travis.yml +27 -0
  9. data/Gemfile +4 -3
  10. data/NEWS.md +11 -0
  11. data/Rakefile +5 -2
  12. data/lib/nanoc/base/entities/dependency.rb +5 -3
  13. data/lib/nanoc/base/entities/layout.rb +1 -1
  14. data/lib/nanoc/base/repos/dependency_store.rb +64 -28
  15. data/lib/nanoc/base/services/dependency_tracker.rb +1 -1
  16. data/lib/nanoc/base/views/config_view.rb +4 -0
  17. data/lib/nanoc/checking/checks/external_links.rb +3 -6
  18. data/lib/nanoc/cli.rb +0 -2
  19. data/lib/nanoc/cli/commands/shell.rb +2 -3
  20. data/lib/nanoc/filters/colorize_syntax/colorizers.rb +4 -1
  21. data/lib/nanoc/telemetry/table.rb +1 -1
  22. data/lib/nanoc/version.rb +1 -1
  23. data/nanoc.gemspec +1 -5
  24. data/scripts/release +95 -0
  25. data/{test → spec/nanoc}/base/core_ext/array_spec.rb +5 -14
  26. data/{test → spec/nanoc}/base/core_ext/hash_spec.rb +6 -15
  27. data/{test → spec/nanoc}/base/core_ext/pathname_spec.rb +0 -0
  28. data/spec/nanoc/base/core_ext/string_spec.rb +23 -0
  29. data/spec/nanoc/base/directed_graph_spec.rb +291 -0
  30. data/spec/nanoc/base/entities/identifiable_collection_spec.rb +56 -0
  31. data/spec/nanoc/base/entities/item_spec.rb +8 -0
  32. data/spec/nanoc/base/entities/layout_spec.rb +8 -0
  33. data/spec/nanoc/base/repos/dependency_store_spec.rb +166 -21
  34. data/spec/nanoc/base/views/config_view_spec.rb +29 -1
  35. data/spec/nanoc/cli/commands/shell_spec.rb +23 -8
  36. data/spec/nanoc/filters/less_spec.rb +1 -1
  37. data/spec/nanoc/regressions/gh_1185_spec.rb +22 -0
  38. data/spec/nanoc/telemetry/table_spec.rb +22 -0
  39. data/spec/spec_helper.rb +5 -6
  40. data/test/base/test_item_array.rb +0 -35
  41. data/test/checking/checks/test_external_links.rb +0 -14
  42. data/test/filters/test_coffeescript.rb +0 -2
  43. data/test/filters/test_handlebars.rb +0 -4
  44. data/test/filters/test_uglify_js.rb +0 -4
  45. data/test/helper.rb +0 -6
  46. data/test/helpers/test_blogging.rb +66 -26
  47. data/test/helpers/test_xml_sitemap.rb +23 -7
  48. metadata +16 -9
  49. data/Gemfile.lock +0 -433
  50. data/test/base/core_ext/string_spec.rb +0 -25
  51. data/test/base/test_item.rb +0 -40
  52. data/test/base/test_layout.rb +0 -16
@@ -5,7 +5,7 @@ module Nanoc::Int
5
5
  class DependencyTracker
6
6
  include Nanoc::Int::ContractsSupport
7
7
 
8
- C_OBJ = C::Or[Nanoc::Int::Item, Nanoc::Int::Layout]
8
+ C_OBJ = C::Or[Nanoc::Int::Item, Nanoc::Int::Layout, Nanoc::Int::Configuration]
9
9
  C_ATTR = C::Or[C::IterOf[Symbol], C::Bool]
10
10
  C_ARGS = C::KeywordArgs[raw_content: C::Optional[C::Bool], attributes: C::Optional[C_ATTR], compiled_content: C::Optional[C::Bool], path: C::Optional[C::Bool]]
11
11
 
@@ -18,6 +18,7 @@ module Nanoc
18
18
 
19
19
  # @see Hash#fetch
20
20
  def fetch(key, fallback = NONE, &_block)
21
+ @context.dependency_tracker.bounce(unwrap, attributes: [key])
21
22
  @config.fetch(key) do
22
23
  if !fallback.equal?(NONE)
23
24
  fallback
@@ -31,16 +32,19 @@ module Nanoc
31
32
 
32
33
  # @see Hash#key?
33
34
  def key?(key)
35
+ @context.dependency_tracker.bounce(unwrap, attributes: [key])
34
36
  @config.key?(key)
35
37
  end
36
38
 
37
39
  # @see Hash#[]
38
40
  def [](key)
41
+ @context.dependency_tracker.bounce(unwrap, attributes: [key])
39
42
  @config[key]
40
43
  end
41
44
 
42
45
  # @see Hash#each
43
46
  def each(&block)
47
+ @context.dependency_tracker.bounce(unwrap, attributes: true)
44
48
  @config.each(&block)
45
49
  end
46
50
  end
@@ -69,13 +69,10 @@ module ::Nanoc::Checking::Checks
69
69
  begin
70
70
  Timeout.timeout(timeouts[i]) do
71
71
  res = request_url_once(url)
72
- if res.code == '405'
73
- res = request_url_once(url, Net::HTTP::Get)
74
- end
75
72
  end
76
73
  rescue => e
77
74
  last_err = e
78
- next # can not allow
75
+ next
79
76
  end
80
77
 
81
78
  if res.code =~ /^3..$/
@@ -122,8 +119,8 @@ module ::Nanoc::Checking::Checks
122
119
  path
123
120
  end
124
121
 
125
- def request_url_once(url, req_method = Net::HTTP::Head)
126
- req = req_method.new(path_for_url(url))
122
+ def request_url_once(url)
123
+ req = Net::HTTP::Get.new(path_for_url(url))
127
124
  http = Net::HTTP.new(url.host, url.port)
128
125
  if url.instance_of? URI::HTTPS
129
126
  http.use_ssl = true
data/lib/nanoc/cli.rb CHANGED
@@ -78,8 +78,6 @@ module Nanoc::CLI
78
78
  add_after_setup_proc(block)
79
79
  end
80
80
 
81
- protected
82
-
83
81
  # Makes the command-line interface ready for use.
84
82
  #
85
83
  # @return [void]
@@ -6,19 +6,18 @@ aliases 'console'
6
6
  description "
7
7
  Open an IRB shell on a context that contains @items, @layouts, and @config.
8
8
  "
9
+ flag :p, :preprocess, 'run preprocessor'
9
10
 
10
11
  module Nanoc::CLI::Commands
11
12
  class Shell < ::Nanoc::CLI::CommandRunner
12
13
  def run
13
14
  require 'pry'
14
15
 
15
- load_site
16
+ load_site(preprocess: options[:preprocess])
16
17
 
17
18
  Nanoc::Int::Context.new(env).pry
18
19
  end
19
20
 
20
- protected
21
-
22
21
  def env
23
22
  self.class.env_for_site(site)
24
23
  end
@@ -166,7 +166,10 @@ module Nanoc::Filters::ColorizeSyntax::Colorizers
166
166
  code1 = element.xpath('code').first
167
167
  return if code1.nil?
168
168
 
169
- pre = code1.xpath('pre').first
169
+ div = code1.xpath('div').first
170
+
171
+ # For Rouge 2.x and 1.x, respectively
172
+ pre = (div || code1).xpath('pre').first
170
173
  return if pre.nil?
171
174
 
172
175
  code2 = pre.xpath('code').first
@@ -13,7 +13,7 @@ module Nanoc::Telemetry
13
13
  [].tap do |lines|
14
14
  lines << row_to_s(@rows[0], column_lengths)
15
15
  lines << separator(column_lengths)
16
- lines.concat(@rows.map { |r| row_to_s(r, column_lengths) })
16
+ lines.concat(@rows.drop(1).map { |r| row_to_s(r, column_lengths) })
17
17
  end.join("\n")
18
18
  end
19
19
 
data/lib/nanoc/version.rb CHANGED
@@ -2,5 +2,5 @@
2
2
 
3
3
  module Nanoc
4
4
  # The current Nanoc version.
5
- VERSION = '4.7.10'
5
+ VERSION = '4.7.11'
6
6
  end
data/nanoc.gemspec CHANGED
@@ -13,11 +13,7 @@ Gem::Specification.new do |s|
13
13
  s.email = 'denis.defreyne@stoneship.org'
14
14
  s.license = 'MIT'
15
15
 
16
- s.files =
17
- Dir['[A-Z]*'] +
18
- Dir['doc/yardoc_{templates,handlers}/**/*'] +
19
- Dir['{bin,lib,tasks,test,spec}/**/*'] +
20
- ['nanoc.gemspec']
16
+ s.files = `git ls-files -z`.split("\x0")
21
17
  s.executables = ['nanoc']
22
18
  s.require_paths = ['lib']
23
19
 
data/scripts/release ADDED
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'fileutils'
5
+ require 'octokit'
6
+
7
+ def run(*args)
8
+ puts 'I will execute the following:'
9
+ puts ' ' + args.map { |a| a =~ /\s/ ? a.inspect : a }.join(' ')
10
+ print 'Is this correct? [y/N] '
11
+ res = gets
12
+ unless res.strip.casecmp('y').zero?
13
+ $stderr.puts 'Answer was not Y; release aborted.'
14
+ exit 1
15
+ end
16
+
17
+ system('echo', *args)
18
+ system(*args)
19
+
20
+ print 'Continue? [y/N] '
21
+ res = gets
22
+ unless res.strip.casecmp('y').zero?
23
+ $stderr.puts 'Answer was not Y; release aborted.'
24
+ exit 1
25
+ end
26
+ end
27
+
28
+ puts '=== Logging in to GitHub’s API…'
29
+ client = Octokit::Client.new(netrc: true)
30
+ puts
31
+
32
+ puts '=== Deleting old *.gem files…'
33
+ Dir['*.gem'].each do |fn|
34
+ puts " #{fn}…"
35
+ FileUtils.rm_f(fn)
36
+ end
37
+ puts
38
+
39
+ puts '=== Verifying presence of release date…'
40
+ unless File.readlines('NEWS.md').drop(2).first =~ / \(\d{4}-\d{2}-\d{2}\)$/
41
+ $stderr.puts 'No proper release date found!'
42
+ exit 1
43
+ end
44
+ puts
45
+
46
+ puts '=== Building new gem…'
47
+ run('gem', 'build', 'nanoc.gemspec')
48
+ puts
49
+
50
+ puts '=== Reading version…'
51
+ require './lib/nanoc/version'
52
+ puts "Version = #{Nanoc::VERSION}"
53
+ puts
54
+
55
+ puts '=== Verifying that release does not yet exist…'
56
+ releases = client.releases('nanoc/nanoc')
57
+ release = releases.find { |r| r.tag_name == Nanoc::VERSION }
58
+ if release
59
+ $stderr.puts 'Release already exists!'
60
+ $stderr.puts 'ABORTED!'
61
+ exit 1
62
+ end
63
+ puts
64
+
65
+ puts '=== Creating Git tag…'
66
+ run('git', 'tag', '--sign', '--annotate', Nanoc::VERSION, '--message', "Version #{Nanoc::VERSION}")
67
+ puts
68
+
69
+ puts '=== Pushing Git data…'
70
+ run('git', 'push', 'origin', '--tags')
71
+ puts
72
+
73
+ puts '=== Pushing gem…'
74
+ run('gem', 'push', "nanoc-#{Nanoc::VERSION}.gem")
75
+ puts
76
+
77
+ puts '=== Reading release notes…'
78
+ release_notes =
79
+ File.readlines('NEWS.md')
80
+ .drop(4)
81
+ .take_while { |l| l !~ /^## / }
82
+ .join
83
+ puts
84
+
85
+ puts '=== Creating release on GitHub…'
86
+ sleep 3 # Give GitHub some time to detect the new tag
87
+ is_prerelease = Nanoc::VERSION =~ /a|b|rc/ || Nanoc::VERSION =~ /^0/
88
+ client.create_release(
89
+ 'nanoc/nanoc', Nanoc::VERSION,
90
+ prerelease: !is_prerelease.nil?,
91
+ body: release_notes
92
+ )
93
+ puts
94
+
95
+ puts 'DONE!'
@@ -1,34 +1,26 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'helper'
4
-
5
3
  describe 'Array#__nanoc_symbolize_keys_recursively' do
6
4
  it 'should convert keys to symbols' do
7
5
  array_old = [:abc, 'xyz', { 'foo' => 'bar', :baz => :qux }]
8
6
  array_new = [:abc, 'xyz', { foo: 'bar', baz: :qux }]
9
- array_old.__nanoc_symbolize_keys_recursively.must_equal array_new
7
+ expect(array_old.__nanoc_symbolize_keys_recursively).to eql(array_new)
10
8
  end
11
9
  end
12
10
 
13
11
  describe 'Array#__nanoc_freeze_recursively' do
14
- include Nanoc::TestHelpers
15
-
16
12
  it 'should prevent first-level elements from being modified' do
17
13
  array = [:a, %i[b c], :d]
18
14
  array.__nanoc_freeze_recursively
19
15
 
20
- assert_raises_frozen_error do
21
- array[0] = 123
22
- end
16
+ expect { array[0] = 123 }.to raise_frozen_error
23
17
  end
24
18
 
25
19
  it 'should prevent second-level elements from being modified' do
26
20
  array = [:a, %i[b c], :d]
27
21
  array.__nanoc_freeze_recursively
28
22
 
29
- assert_raises_frozen_error do
30
- array[1][0] = 123
31
- end
23
+ expect { array[1][0] = 123 }.to raise_frozen_error
32
24
  end
33
25
 
34
26
  it 'should not freeze infinitely' do
@@ -37,8 +29,7 @@ describe 'Array#__nanoc_freeze_recursively' do
37
29
 
38
30
  a.__nanoc_freeze_recursively
39
31
 
40
- assert a.frozen?
41
- assert a[0].frozen?
42
- assert_equal a, a[0]
32
+ expect(a).to be_frozen
33
+ expect(a[0]).to be_frozen
43
34
  end
44
35
  end
@@ -1,40 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'helper'
4
-
5
3
  describe 'Hash#__nanoc_symbolize_keys_recursively' do
6
4
  it 'should convert keys to symbols' do
7
5
  hash_old = { 'foo' => 'bar' }
8
6
  hash_new = { foo: 'bar' }
9
- hash_old.__nanoc_symbolize_keys_recursively.must_equal hash_new
7
+ expect(hash_old.__nanoc_symbolize_keys_recursively).to eql(hash_new)
10
8
  end
11
9
 
12
10
  it 'should not require string keys' do
13
11
  hash_old = { Time.now => 'abc' }
14
12
  hash_new = hash_old
15
- hash_old.__nanoc_symbolize_keys_recursively.must_equal hash_new
13
+ expect(hash_old.__nanoc_symbolize_keys_recursively).to eql(hash_new)
16
14
  end
17
15
  end
18
16
 
19
17
  describe 'Hash#__nanoc_freeze_recursively' do
20
- include Nanoc::TestHelpers
21
-
22
18
  it 'should prevent first-level elements from being modified' do
23
19
  hash = { a: { b: :c } }
24
20
  hash.__nanoc_freeze_recursively
25
21
 
26
- assert_raises_frozen_error do
27
- hash[:a] = 123
28
- end
22
+ expect { hash[:a] = 123 }.to raise_frozen_error
29
23
  end
30
24
 
31
25
  it 'should prevent second-level elements from being modified' do
32
26
  hash = { a: { b: :c } }
33
27
  hash.__nanoc_freeze_recursively
34
28
 
35
- assert_raises_frozen_error do
36
- hash[:a][:b] = 123
37
- end
29
+ expect { hash[:a][:b] = 123 }.to raise_frozen_error
38
30
  end
39
31
 
40
32
  it 'should not freeze infinitely' do
@@ -43,8 +35,7 @@ describe 'Hash#__nanoc_freeze_recursively' do
43
35
 
44
36
  a.__nanoc_freeze_recursively
45
37
 
46
- assert a.frozen?
47
- assert a[:x].frozen?
48
- assert_equal a, a[:x]
38
+ expect(a).to be_frozen
39
+ expect(a[0]).to be_frozen
49
40
  end
50
41
  end
File without changes
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe 'String#__nanoc_cleaned_identifier' do
4
+ it 'should not convert already clean paths' do
5
+ expect('/foo/bar/'.__nanoc_cleaned_identifier).to eql('/foo/bar/')
6
+ end
7
+
8
+ it 'should prepend slash if necessary' do
9
+ expect('foo/bar/'.__nanoc_cleaned_identifier).to eql('/foo/bar/')
10
+ end
11
+
12
+ it 'should append slash if necessary' do
13
+ expect('/foo/bar'.__nanoc_cleaned_identifier).to eql('/foo/bar/')
14
+ end
15
+
16
+ it 'should remove double slashes at start' do
17
+ expect('//foo/bar/'.__nanoc_cleaned_identifier).to eql('/foo/bar/')
18
+ end
19
+
20
+ it 'should remove double slashes at end' do
21
+ expect('/foo/bar//'.__nanoc_cleaned_identifier).to eql('/foo/bar/')
22
+ end
23
+ end
@@ -65,4 +65,295 @@ describe Nanoc::Int::DirectedGraph do
65
65
  it { is_expected.to eq([2, 3, 4, 5]) }
66
66
  end
67
67
  end
68
+
69
+ describe '#all_paths' do
70
+ subject { graph.all_paths.to_a }
71
+
72
+ context 'no cycles' do
73
+ example do
74
+ expect(subject).to contain_exactly(
75
+ [1],
76
+ [2],
77
+ [3],
78
+ )
79
+ end
80
+ end
81
+
82
+ context 'one cycle without head' do
83
+ before do
84
+ graph.add_edge(1, 2)
85
+ graph.add_edge(2, 1)
86
+ end
87
+
88
+ example do
89
+ expect(subject).to contain_exactly(
90
+ [1],
91
+ [1, 2],
92
+ [1, 2, 1],
93
+ [2],
94
+ [2, 1],
95
+ [2, 1, 2],
96
+ [3],
97
+ )
98
+ end
99
+ end
100
+
101
+ context 'one cycle with head' do
102
+ before do
103
+ graph.add_edge(1, 2)
104
+ graph.add_edge(2, 3)
105
+ graph.add_edge(3, 2)
106
+ end
107
+
108
+ example do
109
+ expect(subject).to contain_exactly(
110
+ [1],
111
+ [1, 2],
112
+ [1, 2, 3],
113
+ [1, 2, 3, 2],
114
+ [2],
115
+ [2, 3],
116
+ [2, 3, 2],
117
+ [3],
118
+ [3, 2],
119
+ [3, 2, 3],
120
+ )
121
+ end
122
+ end
123
+
124
+ context 'one cycle with tail' do
125
+ before do
126
+ graph.add_edge(1, 2)
127
+ graph.add_edge(2, 20)
128
+ graph.add_edge(20, 21)
129
+ graph.add_edge(2, 3)
130
+ graph.add_edge(3, 1)
131
+ end
132
+
133
+ example do
134
+ expect(subject).to contain_exactly(
135
+ [1],
136
+ [1, 2],
137
+ [1, 2, 20],
138
+ [1, 2, 20, 21],
139
+ [1, 2, 3],
140
+ [1, 2, 3, 1],
141
+ [2],
142
+ [2, 20],
143
+ [2, 20, 21],
144
+ [2, 3],
145
+ [2, 3, 1],
146
+ [2, 3, 1, 2],
147
+ [3],
148
+ [3, 1],
149
+ [3, 1, 2],
150
+ [3, 1, 2, 20],
151
+ [3, 1, 2, 20, 21],
152
+ [3, 1, 2, 3],
153
+ [20],
154
+ [20, 21],
155
+ [21],
156
+ )
157
+ end
158
+ end
159
+
160
+ context 'large cycle' do
161
+ before do
162
+ graph.add_edge(1, 2)
163
+ graph.add_edge(2, 3)
164
+ graph.add_edge(3, 4)
165
+ graph.add_edge(4, 5)
166
+ graph.add_edge(5, 1)
167
+ end
168
+
169
+ example do
170
+ expect(subject).to contain_exactly(
171
+ [1],
172
+ [1, 2],
173
+ [1, 2, 3],
174
+ [1, 2, 3, 4],
175
+ [1, 2, 3, 4, 5],
176
+ [1, 2, 3, 4, 5, 1],
177
+ [2],
178
+ [2, 3],
179
+ [2, 3, 4],
180
+ [2, 3, 4, 5],
181
+ [2, 3, 4, 5, 1],
182
+ [2, 3, 4, 5, 1, 2],
183
+ [3],
184
+ [3, 4],
185
+ [3, 4, 5],
186
+ [3, 4, 5, 1],
187
+ [3, 4, 5, 1, 2],
188
+ [3, 4, 5, 1, 2, 3],
189
+ [4],
190
+ [4, 5],
191
+ [4, 5, 1],
192
+ [4, 5, 1, 2],
193
+ [4, 5, 1, 2, 3],
194
+ [4, 5, 1, 2, 3, 4],
195
+ [5],
196
+ [5, 1],
197
+ [5, 1, 2],
198
+ [5, 1, 2, 3],
199
+ [5, 1, 2, 3, 4],
200
+ [5, 1, 2, 3, 4, 5],
201
+ )
202
+ end
203
+ end
204
+
205
+ context 'large cycle with head' do
206
+ before do
207
+ graph.add_edge(1, 2)
208
+ graph.add_edge(2, 3)
209
+ graph.add_edge(3, 4)
210
+ graph.add_edge(4, 5)
211
+ graph.add_edge(5, 2)
212
+ end
213
+
214
+ example do
215
+ expect(subject).to contain_exactly(
216
+ [1],
217
+ [1, 2],
218
+ [1, 2, 3],
219
+ [1, 2, 3, 4],
220
+ [1, 2, 3, 4, 5],
221
+ [1, 2, 3, 4, 5, 2],
222
+ [2],
223
+ [2, 3],
224
+ [2, 3, 4],
225
+ [2, 3, 4, 5],
226
+ [2, 3, 4, 5, 2],
227
+ [3],
228
+ [3, 4],
229
+ [3, 4, 5],
230
+ [3, 4, 5, 2],
231
+ [3, 4, 5, 2, 3],
232
+ [4],
233
+ [4, 5],
234
+ [4, 5, 2],
235
+ [4, 5, 2, 3],
236
+ [4, 5, 2, 3, 4],
237
+ [5],
238
+ [5, 2],
239
+ [5, 2, 3],
240
+ [5, 2, 3, 4],
241
+ [5, 2, 3, 4, 5],
242
+ )
243
+ end
244
+ end
245
+ end
246
+
247
+ describe '#dfs_from' do
248
+ subject do
249
+ [].tap do |ps|
250
+ graph.dfs_from(1) do |p|
251
+ ps << p
252
+ end
253
+ end
254
+ end
255
+
256
+ context 'no cycles' do
257
+ example do
258
+ expect(subject).to contain_exactly(
259
+ [1],
260
+ )
261
+ end
262
+ end
263
+
264
+ context 'one cycle without head' do
265
+ before do
266
+ graph.add_edge(1, 2)
267
+ graph.add_edge(2, 1)
268
+ end
269
+
270
+ example do
271
+ expect(subject).to contain_exactly(
272
+ [1],
273
+ [1, 2],
274
+ [1, 2, 1],
275
+ )
276
+ end
277
+ end
278
+
279
+ context 'one cycle with head' do
280
+ before do
281
+ graph.add_edge(1, 2)
282
+ graph.add_edge(2, 3)
283
+ graph.add_edge(3, 2)
284
+ end
285
+
286
+ example do
287
+ expect(subject).to contain_exactly(
288
+ [1],
289
+ [1, 2],
290
+ [1, 2, 3],
291
+ [1, 2, 3, 2],
292
+ )
293
+ end
294
+ end
295
+
296
+ context 'one cycle with tail' do
297
+ before do
298
+ graph.add_edge(1, 2)
299
+ graph.add_edge(2, 20)
300
+ graph.add_edge(20, 21)
301
+ graph.add_edge(2, 3)
302
+ graph.add_edge(3, 1)
303
+ end
304
+
305
+ example do
306
+ expect(subject).to contain_exactly(
307
+ [1],
308
+ [1, 2],
309
+ [1, 2, 20],
310
+ [1, 2, 20, 21],
311
+ [1, 2, 3],
312
+ [1, 2, 3, 1],
313
+ )
314
+ end
315
+ end
316
+
317
+ context 'large cycle' do
318
+ before do
319
+ graph.add_edge(1, 2)
320
+ graph.add_edge(2, 3)
321
+ graph.add_edge(3, 4)
322
+ graph.add_edge(4, 5)
323
+ graph.add_edge(5, 1)
324
+ end
325
+
326
+ example do
327
+ expect(subject).to contain_exactly(
328
+ [1],
329
+ [1, 2],
330
+ [1, 2, 3],
331
+ [1, 2, 3, 4],
332
+ [1, 2, 3, 4, 5],
333
+ [1, 2, 3, 4, 5, 1],
334
+ )
335
+ end
336
+ end
337
+
338
+ context 'large cycle with head' do
339
+ before do
340
+ graph.add_edge(1, 2)
341
+ graph.add_edge(2, 3)
342
+ graph.add_edge(3, 4)
343
+ graph.add_edge(4, 5)
344
+ graph.add_edge(5, 2)
345
+ end
346
+
347
+ example do
348
+ expect(subject).to contain_exactly(
349
+ [1],
350
+ [1, 2],
351
+ [1, 2, 3],
352
+ [1, 2, 3, 4],
353
+ [1, 2, 3, 4, 5],
354
+ [1, 2, 3, 4, 5, 2],
355
+ )
356
+ end
357
+ end
358
+ end
68
359
  end