jekyll 3.8.7 → 4.1.0

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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +71 -62
  3. data/LICENSE +1 -1
  4. data/README.markdown +46 -17
  5. data/lib/blank_template/_config.yml +3 -0
  6. data/lib/blank_template/_layouts/default.html +12 -0
  7. data/lib/blank_template/_sass/main.scss +9 -0
  8. data/lib/blank_template/assets/css/main.scss +4 -0
  9. data/lib/blank_template/index.md +8 -0
  10. data/lib/jekyll.rb +10 -1
  11. data/lib/jekyll/cache.rb +190 -0
  12. data/lib/jekyll/cleaner.rb +5 -4
  13. data/lib/jekyll/collection.rb +82 -10
  14. data/lib/jekyll/command.rb +33 -6
  15. data/lib/jekyll/commands/build.rb +11 -20
  16. data/lib/jekyll/commands/clean.rb +2 -0
  17. data/lib/jekyll/commands/doctor.rb +15 -8
  18. data/lib/jekyll/commands/help.rb +1 -1
  19. data/lib/jekyll/commands/new.rb +37 -35
  20. data/lib/jekyll/commands/new_theme.rb +30 -28
  21. data/lib/jekyll/commands/serve.rb +55 -81
  22. data/lib/jekyll/commands/serve/live_reload_reactor.rb +6 -10
  23. data/lib/jekyll/commands/serve/servlet.rb +22 -25
  24. data/lib/jekyll/commands/serve/websockets.rb +1 -1
  25. data/lib/jekyll/configuration.rb +61 -149
  26. data/lib/jekyll/converters/identity.rb +18 -0
  27. data/lib/jekyll/converters/markdown.rb +49 -40
  28. data/lib/jekyll/converters/markdown/kramdown_parser.rb +84 -11
  29. data/lib/jekyll/converters/smartypants.rb +34 -14
  30. data/lib/jekyll/convertible.rb +30 -31
  31. data/lib/jekyll/deprecator.rb +1 -3
  32. data/lib/jekyll/document.rb +89 -61
  33. data/lib/jekyll/drops/collection_drop.rb +2 -3
  34. data/lib/jekyll/drops/document_drop.rb +14 -1
  35. data/lib/jekyll/drops/drop.rb +17 -14
  36. data/lib/jekyll/drops/excerpt_drop.rb +4 -0
  37. data/lib/jekyll/drops/page_drop.rb +18 -0
  38. data/lib/jekyll/drops/site_drop.rb +6 -5
  39. data/lib/jekyll/drops/unified_payload_drop.rb +1 -0
  40. data/lib/jekyll/drops/url_drop.rb +53 -1
  41. data/lib/jekyll/entry_filter.rb +42 -45
  42. data/lib/jekyll/excerpt.rb +45 -34
  43. data/lib/jekyll/external.rb +10 -5
  44. data/lib/jekyll/filters.rb +200 -40
  45. data/lib/jekyll/filters/date_filters.rb +6 -3
  46. data/lib/jekyll/filters/grouping_filters.rb +1 -2
  47. data/lib/jekyll/filters/url_filters.rb +46 -14
  48. data/lib/jekyll/frontmatter_defaults.rb +46 -35
  49. data/lib/jekyll/hooks.rb +4 -8
  50. data/lib/jekyll/inclusion.rb +32 -0
  51. data/lib/jekyll/liquid_extensions.rb +0 -2
  52. data/lib/jekyll/liquid_renderer.rb +31 -16
  53. data/lib/jekyll/liquid_renderer/file.rb +24 -3
  54. data/lib/jekyll/liquid_renderer/table.rb +36 -77
  55. data/lib/jekyll/log_adapter.rb +5 -1
  56. data/lib/jekyll/mime.types +53 -11
  57. data/lib/jekyll/page.rb +54 -12
  58. data/lib/jekyll/page_excerpt.rb +26 -0
  59. data/lib/jekyll/page_without_a_file.rb +0 -4
  60. data/lib/jekyll/path_manager.rb +31 -0
  61. data/lib/jekyll/plugin.rb +5 -11
  62. data/lib/jekyll/plugin_manager.rb +2 -0
  63. data/lib/jekyll/profiler.rb +58 -0
  64. data/lib/jekyll/reader.rb +42 -9
  65. data/lib/jekyll/readers/collection_reader.rb +1 -0
  66. data/lib/jekyll/readers/data_reader.rb +8 -9
  67. data/lib/jekyll/readers/layout_reader.rb +3 -12
  68. data/lib/jekyll/readers/page_reader.rb +5 -5
  69. data/lib/jekyll/readers/post_reader.rb +31 -18
  70. data/lib/jekyll/readers/static_file_reader.rb +4 -4
  71. data/lib/jekyll/readers/theme_assets_reader.rb +8 -5
  72. data/lib/jekyll/regenerator.rb +4 -12
  73. data/lib/jekyll/renderer.rb +23 -40
  74. data/lib/jekyll/site.rb +91 -38
  75. data/lib/jekyll/static_file.rb +62 -21
  76. data/lib/jekyll/stevenson.rb +2 -3
  77. data/lib/jekyll/tags/highlight.rb +19 -51
  78. data/lib/jekyll/tags/include.rb +82 -42
  79. data/lib/jekyll/tags/link.rb +11 -7
  80. data/lib/jekyll/tags/post_url.rb +25 -21
  81. data/lib/jekyll/theme.rb +16 -18
  82. data/lib/jekyll/theme_builder.rb +91 -89
  83. data/lib/jekyll/url.rb +10 -5
  84. data/lib/jekyll/utils.rb +18 -21
  85. data/lib/jekyll/utils/ansi.rb +1 -1
  86. data/lib/jekyll/utils/exec.rb +0 -1
  87. data/lib/jekyll/utils/internet.rb +2 -4
  88. data/lib/jekyll/utils/platforms.rb +8 -8
  89. data/lib/jekyll/utils/thread_event.rb +1 -5
  90. data/lib/jekyll/utils/win_tz.rb +2 -2
  91. data/lib/jekyll/version.rb +1 -1
  92. data/lib/site_template/.gitignore +2 -0
  93. data/lib/site_template/404.html +1 -0
  94. data/lib/site_template/_config.yml +17 -5
  95. data/lib/site_template/_posts/0000-00-00-welcome-to-jekyll.markdown.erb +5 -1
  96. data/lib/site_template/{about.md → about.markdown} +0 -0
  97. data/lib/site_template/{index.md → index.markdown} +0 -0
  98. data/lib/theme_template/gitignore.erb +1 -0
  99. data/lib/theme_template/theme.gemspec.erb +1 -4
  100. data/rubocop/jekyll/assert_equal_literal_actual.rb +149 -0
  101. metadata +69 -31
  102. data/lib/jekyll/converters/markdown/rdiscount_parser.rb +0 -37
  103. data/lib/jekyll/converters/markdown/redcarpet_parser.rb +0 -112
  104. data/lib/jekyll/utils/rouge.rb +0 -22
@@ -7,25 +7,17 @@ module Jekyll
7
7
  autoload :Exec, "jekyll/utils/exec"
8
8
  autoload :Internet, "jekyll/utils/internet"
9
9
  autoload :Platforms, "jekyll/utils/platforms"
10
- autoload :Rouge, "jekyll/utils/rouge"
11
10
  autoload :ThreadEvent, "jekyll/utils/thread_event"
12
11
  autoload :WinTZ, "jekyll/utils/win_tz"
13
12
 
14
13
  # Constants for use in #slugify
15
14
  SLUGIFY_MODES = %w(raw default pretty ascii latin).freeze
16
15
  SLUGIFY_RAW_REGEXP = Regexp.new('\\s+').freeze
17
- SLUGIFY_DEFAULT_REGEXP = Regexp.new("[^[:alnum:]]+").freeze
18
- SLUGIFY_PRETTY_REGEXP = Regexp.new("[^[:alnum:]._~!$&'()+,;=@]+").freeze
16
+ SLUGIFY_DEFAULT_REGEXP = Regexp.new("[^\\p{M}\\p{L}\\p{Nd}]+").freeze
17
+ SLUGIFY_PRETTY_REGEXP = Regexp.new("[^\\p{M}\\p{L}\\p{Nd}._~!$&'()+,;=@]+").freeze
19
18
  SLUGIFY_ASCII_REGEXP = Regexp.new("[^[A-Za-z0-9]]+").freeze
20
19
 
21
- # Takes an indented string and removes the preceding spaces on each line
22
-
23
- def strip_heredoc(str)
24
- str.gsub(%r!^[ \t]{#{(str.scan(%r!^[ \t]*(?=\S)!).min || "").size}}!, "")
25
- end
26
-
27
20
  # Takes a slug and turns it into a simple title.
28
-
29
21
  def titleize_slug(slug)
30
22
  slug.split("-").map!(&:capitalize).join(" ")
31
23
  end
@@ -76,11 +68,14 @@ module Jekyll
76
68
  #
77
69
  # Returns an array
78
70
  def pluralized_array_from_hash(hash, singular_key, plural_key)
79
- [].tap do |array|
80
- value = value_from_singular_key(hash, singular_key)
81
- value ||= value_from_plural_key(hash, plural_key)
82
- array << value
83
- end.flatten.compact
71
+ array = []
72
+ value = value_from_singular_key(hash, singular_key)
73
+ value ||= value_from_plural_key(hash, plural_key)
74
+
75
+ array << value
76
+ array.flatten!
77
+ array.compact!
78
+ array
84
79
  end
85
80
 
86
81
  def value_from_singular_key(hash, key)
@@ -141,9 +136,9 @@ module Jekyll
141
136
  # Determines whether a given file has
142
137
  #
143
138
  # Returns true if the YAML front matter is present.
144
- # rubocop: disable PredicateName
139
+ # rubocop: disable Naming/PredicateName
145
140
  def has_yaml_header?(file)
146
- !!(File.open(file, "rb", &:readline) =~ %r!\A---\s*\r?\n!)
141
+ File.open(file, "rb", &:readline).match? %r!\A---\s*\r?\n!
147
142
  rescue EOFError
148
143
  false
149
144
  end
@@ -153,9 +148,10 @@ module Jekyll
153
148
  # Returns true is the string contains sequences of `{%` or `{{`
154
149
  def has_liquid_construct?(content)
155
150
  return false if content.nil? || content.empty?
151
+
156
152
  content.include?("{%") || content.include?("{{")
157
153
  end
158
- # rubocop: enable PredicateName
154
+ # rubocop: enable Naming/PredicateName
159
155
 
160
156
  # Slugify a filename or title.
161
157
  #
@@ -222,6 +218,7 @@ module Jekyll
222
218
  slug.gsub!(%r!^\-|\-$!i, "")
223
219
 
224
220
  slug.downcase! unless cased
221
+ Jekyll.logger.warn("Warning:", "Empty `slug` generated for '#{string}'.") if slug.empty?
225
222
  slug
226
223
  end
227
224
 
@@ -293,8 +290,10 @@ module Jekyll
293
290
  # Returns matched pathes
294
291
  def safe_glob(dir, patterns, flags = 0)
295
292
  return [] unless Dir.exist?(dir)
293
+
296
294
  pattern = File.join(Array(patterns))
297
295
  return [dir] if pattern.empty?
296
+
298
297
  Dir.chdir(dir) do
299
298
  Dir.glob(pattern, flags).map { |f| File.join(dir, f) }
300
299
  end
@@ -314,6 +313,7 @@ module Jekyll
314
313
  end
315
314
 
316
315
  private
316
+
317
317
  def merge_values(target, overwrite)
318
318
  target.merge!(overwrite) do |_key, old_val, new_val|
319
319
  if new_val.nil?
@@ -326,14 +326,12 @@ module Jekyll
326
326
  end
327
327
  end
328
328
 
329
- private
330
329
  def merge_default_proc(target, overwrite)
331
330
  if target.is_a?(Hash) && overwrite.is_a?(Hash) && target.default_proc.nil?
332
331
  target.default_proc = overwrite.default_proc
333
332
  end
334
333
  end
335
334
 
336
- private
337
335
  def duplicate_frozen_values(target)
338
336
  target.each do |key, val|
339
337
  target[key] = val.dup if val.frozen? && duplicable?(val)
@@ -344,7 +342,6 @@ module Jekyll
344
342
  #
345
343
  # See Utils#slugify for a description of the character sequence specified
346
344
  # by each mode.
347
- private
348
345
  def replace_character_sequence_with_hyphen(string, mode: "default")
349
346
  replaceable_char =
350
347
  case mode
@@ -6,7 +6,7 @@ module Jekyll
6
6
  extend self
7
7
 
8
8
  ESCAPE = format("%c", 27)
9
- MATCH = %r!#{ESCAPE}\[(?:\d+)(?:;\d+)*(j|k|m|s|u|A|B|G)|\e\(B\e\[m!ix
9
+ MATCH = %r!#{ESCAPE}\[(?:\d+)(?:;\d+)*(j|k|m|s|u|A|B|G)|\e\(B\e\[m!ix.freeze
10
10
  COLORS = {
11
11
  :red => 31,
12
12
  :green => 32,
@@ -21,7 +21,6 @@ module Jekyll
21
21
  [stdin, stdout, stderr].each(&:close)
22
22
  [process.value, out + err]
23
23
  end
24
-
25
24
  end
26
25
  end
27
26
  end
@@ -3,7 +3,6 @@
3
3
  module Jekyll
4
4
  module Utils
5
5
  module Internet
6
-
7
6
  # Public: Determine whether the present device has a connection to
8
7
  # the Internet. This allows plugin writers which require the outside
9
8
  # world to have a neat fallback mechanism for offline building.
@@ -18,13 +17,13 @@ module Jekyll
18
17
  # end
19
18
  #
20
19
  # Returns true if a DNS call can successfully be made, or false if not.
20
+
21
21
  module_function
22
+
22
23
  def connected?
23
24
  !dns("example.com").nil?
24
25
  end
25
26
 
26
- private
27
- module_function
28
27
  def dns(domain)
29
28
  require "resolv"
30
29
  Resolv::DNS.open do |resolver|
@@ -33,7 +32,6 @@ module Jekyll
33
32
  rescue Resolv::ResolvError, Resolv::ResolvTimeout
34
33
  nil
35
34
  end
36
-
37
35
  end
38
36
  end
39
37
  end
@@ -31,7 +31,7 @@ module Jekyll
31
31
  # --
32
32
 
33
33
  alias_method :really_windows?, \
34
- :vanilla_windows?
34
+ :vanilla_windows?
35
35
 
36
36
  #
37
37
 
@@ -68,14 +68,14 @@ module Jekyll
68
68
  #
69
69
 
70
70
  private
71
+
71
72
  def proc_version
72
- @proc_version ||= begin
73
- Pathutil.new(
74
- "/proc/version"
75
- ).read
76
- rescue Errno::ENOENT
77
- nil
78
- end
73
+ @proc_version ||=
74
+ begin
75
+ File.read("/proc/version")
76
+ rescue Errno::ENOENT, Errno::EACCES
77
+ nil
78
+ end
79
79
  end
80
80
  end
81
81
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "thread"
4
-
5
3
  module Jekyll
6
4
  module Utils
7
5
  # Based on the pattern and code from
@@ -25,9 +23,7 @@ module Jekyll
25
23
 
26
24
  def wait
27
25
  @lock.synchronize do
28
- unless @flag
29
- @cond.wait(@lock)
30
- end
26
+ @cond.wait(@lock) unless @flag
31
27
  end
32
28
  end
33
29
  end
@@ -21,7 +21,7 @@ module Jekyll
21
21
  # is denoted as:
22
22
  # EST+5 (or) EST+05:00
23
23
  # Reference: http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html
24
- sign = difference < 0 ? "-" : "+"
24
+ sign = difference.negative? ? "-" : "+"
25
25
  offset = sign == "-" ? "+" : "-" unless difference.zero?
26
26
  #
27
27
  # convert the difference (in seconds) to hours, as a rational number, and perform
@@ -30,7 +30,7 @@ module Jekyll
30
30
  #
31
31
  # Format the hour as a two-digit number.
32
32
  # Establish the minutes based on modulo expression.
33
- hh = format("%02d", absolute_hour(difference).ceil)
33
+ hh = format("%<hour>02d", :hour => absolute_hour(difference).ceil)
34
34
  mm = modulo.zero? ? "00" : "30"
35
35
 
36
36
  Jekyll.logger.debug "Timezone:", "#{timezone} #{offset}#{hh}:#{mm}"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Jekyll
4
- VERSION = "3.8.7".freeze
4
+ VERSION = "4.1.0"
5
5
  end
@@ -1,3 +1,5 @@
1
1
  _site
2
2
  .sass-cache
3
+ .jekyll-cache
3
4
  .jekyll-metadata
5
+ vendor
@@ -1,4 +1,5 @@
1
1
  ---
2
+ permalink: /404.html
2
3
  layout: default
3
4
  ---
4
5
 
@@ -7,12 +7,17 @@
7
7
  #
8
8
  # For technical reasons, this file is *NOT* reloaded automatically when you use
9
9
  # 'bundle exec jekyll serve'. If you change this file, please restart the server process.
10
-
10
+ #
11
+ # If you need help with YAML syntax, here are some quick references for you:
12
+ # https://learn-the-web.algonquindesign.ca/topics/markdown-yaml-cheat-sheet/#yaml
13
+ # https://learnxinyminutes.com/docs/yaml/
14
+ #
11
15
  # Site settings
12
16
  # These are used to personalize your new site. If you look in the HTML files,
13
17
  # you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
14
18
  # You can create any custom variable you would like, and they will be accessible
15
19
  # in the templates via {{ site.myvariable }}.
20
+
16
21
  title: Your awesome title
17
22
  email: your-email@example.com
18
23
  description: >- # this means to ignore newlines until "baseurl:"
@@ -25,18 +30,25 @@ twitter_username: jekyllrb
25
30
  github_username: jekyll
26
31
 
27
32
  # Build settings
28
- markdown: kramdown
29
33
  theme: minima
30
34
  plugins:
31
35
  - jekyll-feed
32
36
 
33
37
  # Exclude from processing.
34
- # The following items will not be processed, by default. Create a custom list
35
- # to override the default setting.
38
+ # The following items will not be processed, by default.
39
+ # Any item listed under the `exclude:` key here will be automatically added to
40
+ # the internal "default list".
41
+ #
42
+ # Excluded items can be processed by explicitly listing the directories or
43
+ # their entries' file path in the `include:` list.
44
+ #
36
45
  # exclude:
46
+ # - .sass-cache/
47
+ # - .jekyll-cache/
48
+ # - gemfiles/
37
49
  # - Gemfile
38
50
  # - Gemfile.lock
39
- # - node_modules
51
+ # - node_modules/
40
52
  # - vendor/bundle/
41
53
  # - vendor/cache/
42
54
  # - vendor/gems/
@@ -6,7 +6,11 @@ categories: jekyll update
6
6
  ---
7
7
  You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated.
8
8
 
9
- To add new posts, simply add a file in the `_posts` directory that follows the convention `YYYY-MM-DD-name-of-post.ext` and includes the necessary front matter. Take a look at the source for this post to get an idea about how it works.
9
+ Jekyll requires blog post files to be named according to the following format:
10
+
11
+ `YEAR-MONTH-DAY-title.MARKUP`
12
+
13
+ Where `YEAR` is a four-digit number, `MONTH` and `DAY` are both two-digit numbers, and `MARKUP` is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works.
10
14
 
11
15
  Jekyll also offers powerful support for code snippets:
12
16
 
@@ -1,5 +1,6 @@
1
1
  *.gem
2
2
  .bundle
3
+ .jekyll-cache
3
4
  .sass-cache
4
5
  _site
5
6
  Gemfile.lock
@@ -10,10 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.homepage = "TODO: Put your gem's website or public repo URL here."
11
11
  spec.license = "MIT"
12
12
 
13
- spec.files = `git ls-files -z`.split("\x0").select { |f| f.match(%r!^(<%= theme_directories.join("|") %>|LICENSE|README)!i) }
13
+ spec.files = `git ls-files -z`.split("\x0").select { |f| f.match(%r!^(<%= theme_directories.join("|") %>|LICENSE|README|_config\.yml)!i) }
14
14
 
15
15
  spec.add_runtime_dependency "jekyll", "~> <%= jekyll_version_with_minor %>"
16
-
17
- spec.add_development_dependency "bundler", "~> 1.16"
18
- spec.add_development_dependency "rake", "~> 12.0"
19
16
  end
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module Jekyll
6
+ # Checks for `assert_equal(exp, act, msg = nil)` calls containing literal values as
7
+ # second argument. The second argument should ideally be a method called on the tested
8
+ # instance.
9
+ #
10
+ # @example
11
+ # # bad
12
+ # assert_equal @foo.bar, "foobar"
13
+ # assert_equal @alpha.beta, { "foo" => "bar", "lorem" => "ipsum" }
14
+ # assert_equal @alpha.omega, ["foobar", "lipsum"]
15
+ #
16
+ # # good
17
+ # assert_equal "foobar", @foo.bar
18
+ #
19
+ # assert_equal(
20
+ # { "foo" => "bar", "lorem" => "ipsum" },
21
+ # @alpha.beta
22
+ # )
23
+ #
24
+ # assert_equal(
25
+ # ["foobar", "lipsum"],
26
+ # @alpha.omega
27
+ # )
28
+ #
29
+ class AssertEqualLiteralActual < Cop
30
+ MSG = "Provide the 'expected value' as the first argument to `assert_equal`.".freeze
31
+
32
+ SIMPLE_LITERALS = %i(
33
+ true
34
+ false
35
+ nil
36
+ int
37
+ float
38
+ str
39
+ sym
40
+ complex
41
+ rational
42
+ regopt
43
+ ).freeze
44
+
45
+ COMPLEX_LITERALS = %i(
46
+ array
47
+ hash
48
+ pair
49
+ irange
50
+ erange
51
+ regexp
52
+ ).freeze
53
+
54
+ def_node_matcher :literal_actual?, <<-PATTERN
55
+ (send nil? :assert_equal $(send ...) $#literal?)
56
+ PATTERN
57
+
58
+ def_node_matcher :literal_actual_with_msg?, <<-PATTERN
59
+ (send nil? :assert_equal $(send ...) $#literal? $#opt_msg?)
60
+ PATTERN
61
+
62
+ def on_send(node)
63
+ return unless literal_actual?(node) || literal_actual_with_msg?(node)
64
+ add_offense(node, location: :expression)
65
+ end
66
+
67
+ def autocorrect(node)
68
+ lambda do |corrector|
69
+ corrector.replace(node.loc.expression, replacement(node))
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ def opt_msg?(node)
76
+ node&.source
77
+ end
78
+
79
+ # This is not implement using a NodePattern because it seems
80
+ # to not be able to match against an explicit (nil) sexp
81
+ def literal?(node)
82
+ node && (simple_literal?(node) || complex_literal?(node))
83
+ end
84
+
85
+ def simple_literal?(node)
86
+ SIMPLE_LITERALS.include?(node.type)
87
+ end
88
+
89
+ def complex_literal?(node)
90
+ COMPLEX_LITERALS.include?(node.type) &&
91
+ node.each_child_node.all?(&method(:literal?))
92
+ end
93
+
94
+ def replacement(node)
95
+ _, _, first_param, second_param, optional_param = *node
96
+
97
+ replaced_text = \
98
+ if second_param.type == :hash
99
+ replace_hash_with_variable(first_param.source, second_param.source)
100
+ elsif second_param.type == :array && second_param.source != "[]"
101
+ replace_array_with_variable(first_param.source, second_param.source)
102
+ else
103
+ replace_based_on_line_length(first_param.source, second_param.source)
104
+ end
105
+
106
+ return "#{replaced_text}, #{optional_param.source}" if optional_param
107
+ replaced_text
108
+ end
109
+
110
+ def replace_based_on_line_length(first_expression, second_expression)
111
+ result = "assert_equal #{second_expression}, #{first_expression}"
112
+ return result if result.length < 80
113
+
114
+ # fold long lines independent of Rubocop configuration for better readability
115
+ <<~TEXT
116
+ assert_equal(
117
+ #{second_expression},
118
+ #{first_expression}
119
+ )
120
+ TEXT
121
+ end
122
+
123
+ def replace_hash_with_variable(first_expression, second_expression)
124
+ expect_expression = if second_expression.start_with?("{")
125
+ second_expression
126
+ else
127
+ "{#{second_expression}}"
128
+ end
129
+ <<~TEXT
130
+ expected = #{expect_expression}
131
+ assert_equal expected, #{first_expression}
132
+ TEXT
133
+ end
134
+
135
+ def replace_array_with_variable(first_expression, second_expression)
136
+ expect_expression = if second_expression.start_with?("%")
137
+ second_expression
138
+ else
139
+ Array(second_expression)
140
+ end
141
+ <<~TEXT
142
+ expected = #{expect_expression}
143
+ assert_equal expected, #{first_expression}
144
+ TEXT
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end