jekyll-minibundle 1.5.1 → 1.6.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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +18 -6
  3. data/README.md +34 -24
  4. data/Rakefile +19 -14
  5. data/jekyll-minibundle.gemspec +5 -4
  6. data/lib/jekyll/minibundle/asset_bundle.rb +24 -4
  7. data/lib/jekyll/minibundle/asset_file_operations.rb +0 -8
  8. data/lib/jekyll/minibundle/asset_file_properties.rb +26 -8
  9. data/lib/jekyll/minibundle/asset_file_registry.rb +57 -21
  10. data/lib/jekyll/minibundle/asset_tag_markup.rb +13 -4
  11. data/lib/jekyll/minibundle/bundle_file.rb +9 -6
  12. data/lib/jekyll/minibundle/compatibility.rb +11 -1
  13. data/lib/jekyll/minibundle/development_file.rb +6 -0
  14. data/lib/jekyll/minibundle/development_file_collection.rb +3 -16
  15. data/lib/jekyll/minibundle/environment.rb +5 -12
  16. data/lib/jekyll/minibundle/files.rb +18 -0
  17. data/lib/jekyll/minibundle/hashes.rb +20 -0
  18. data/lib/jekyll/minibundle/mini_bundle_block.rb +52 -12
  19. data/lib/jekyll/minibundle/mini_stamp_tag.rb +27 -8
  20. data/lib/jekyll/minibundle/stamp_file.rb +9 -6
  21. data/lib/jekyll/minibundle/version.rb +1 -1
  22. data/test/fixture/site/_bin/with_count +6 -5
  23. data/test/integration/known_caveats_test.rb +89 -0
  24. data/test/integration/minibundle_development_mode_test.rb +171 -26
  25. data/test/integration/minibundle_production_mode_test.rb +234 -42
  26. data/test/integration/ministamp_development_mode_test.rb +145 -0
  27. data/test/integration/{ministamp_test.rb → ministamp_production_mode_test.rb} +72 -23
  28. data/test/integration/static_files_as_asset_sources_test.rb +3 -0
  29. data/test/support/assertions.rb +24 -0
  30. data/test/support/fixture_config.rb +13 -10
  31. data/test/support/static_file_api_config.rb +9 -3
  32. data/test/support/test_case.rb +7 -6
  33. data/test/unit/asset_bundle_test.rb +16 -2
  34. data/test/unit/asset_file_registry_test.rb +117 -14
  35. data/test/unit/asset_tag_markup_test.rb +17 -5
  36. data/test/unit/bundle_file_properties_test.rb +32 -8
  37. data/test/unit/bundle_file_writing_test.rb +10 -11
  38. data/test/unit/development_file_collection_properties_test.rb +47 -15
  39. data/test/unit/environment_test.rb +0 -13
  40. data/test/unit/files_test.rb +46 -0
  41. data/test/unit/hashes_test.rb +41 -0
  42. data/test/unit/mini_bundle_block_test.rb +56 -1
  43. data/test/unit/mini_stamp_tag_test.rb +8 -8
  44. data/test/unit/stamp_file_properties_test.rb +32 -13
  45. data/test/unit/stamp_file_writing_test.rb +1 -5
  46. metadata +38 -16
  47. data/test/unit/development_file_collection_writing_test.rb +0 -43
  48. data/test/unit/jekyll_payload_test.rb +0 -64
@@ -9,21 +9,20 @@ module Jekyll::Minibundle
9
9
 
10
10
  attr_reader :asset_source_path, :asset_destination_dir, :stamped_at
11
11
 
12
- def initialize(site, asset_source_path, asset_destination_path, &basenamer)
12
+ def initialize(site, asset_source_path, asset_destination_path)
13
13
  @site = site
14
- @basenamer = basenamer
15
14
  @asset_source_path = File.join(@site.source, asset_source_path)
16
15
  @asset_destination_dir = File.dirname(asset_destination_path)
17
16
  @asset_destination_extension = File.extname(asset_destination_path)
18
- @asset_destination_base_prefix = File.basename(asset_destination_path)[0 .. -(@asset_destination_extension.size + 1)]
17
+ @asset_destination_base_prefix = File.basename(asset_destination_path)[0..-(@asset_destination_extension.size + 1)]
19
18
  @stamped_at = nil
20
19
  @is_modified = false
21
20
  end
22
21
 
23
22
  def destination_path_for_markup
24
23
  # we must regenerate the fingerprint here, if at all, in order
25
- # to make sure the markup and generated file have the same
26
- # fingerprint
24
+ # to make sure markup destination and generated file paths have
25
+ # the same fingerprint
27
26
  if modified?
28
27
  @stamped_at = mtime
29
28
  @is_modified = true
@@ -33,6 +32,10 @@ module Jekyll::Minibundle
33
32
  asset_destination_path
34
33
  end
35
34
 
35
+ def extname
36
+ @asset_destination_extension
37
+ end
38
+
36
39
  # writes destination only after `markup` has been called
37
40
  def write(site_destination_dir)
38
41
  if @is_modified
@@ -47,7 +50,7 @@ module Jekyll::Minibundle
47
50
  private
48
51
 
49
52
  def asset_destination_basename
50
- @basenamer.call(@asset_destination_base_prefix, @asset_destination_extension, -> { asset_stamp })
53
+ "#{@asset_destination_base_prefix}-#{asset_stamp}#{extname}"
51
54
  end
52
55
 
53
56
  def asset_stamp
@@ -1,5 +1,5 @@
1
1
  module Jekyll
2
2
  module Minibundle
3
- VERSION = '1.5.1'
3
+ VERSION = '1.6.0'.freeze
4
4
  end
5
5
  end
@@ -2,11 +2,12 @@
2
2
 
3
3
  filename = ARGV.first
4
4
 
5
- count = if File.exist?(filename)
6
- File.read(filename).strip.to_i
7
- else
8
- 0
9
- end
5
+ count =
6
+ if File.exist?(filename)
7
+ File.read(filename).strip.to_i
8
+ else
9
+ 0
10
+ end
10
11
 
11
12
  File.write(filename, "#{count + 1}\n")
12
13
 
@@ -0,0 +1,89 @@
1
+ require 'support/test_case'
2
+ require 'support/fixture_config'
3
+
4
+ module Jekyll::Minibundle::Test
5
+ # Known software caveats that won't be fixed in the current design
6
+ # of the software.
7
+ class KnownCaveatsTest < TestCase
8
+ include FixtureConfig
9
+
10
+ # In Jekyll's watch (auto-regeneration) mode, changing asset
11
+ # destination path to a new value triggers the plugin to rebundle
12
+ # the assets and writing the bundle file to site output
13
+ # directory. After that, changing the destination path back to the
14
+ # original value should cause the plugin to write the original
15
+ # bundle file to site output directory again. This should happen
16
+ # without rebundling the assets, because the plugin stores the
17
+ # original bundle in a temporary file.
18
+ #
19
+ # The plugin cannot rewrite the original bundle file to site
20
+ # output directory, because it does not get a trigger for doing
21
+ # so. The plugin has a non-expiring cumulative cache for
22
+ # assets. This allows the plugin to avoid rebundling assets in
23
+ # site regeneration if the assets themselves are unchanged. This
24
+ # same mechanism is the cause for this caveat.
25
+ #
26
+ # As a workaround, touching or changing one of the assets in the
27
+ # bundle triggers rebundling and rewriting the bundle file to site
28
+ # output directory.
29
+ #
30
+ # For now, we have decided that the caveat is a minor drawback
31
+ # compared to the benefit of avoiding unnecessary rebundling in
32
+ # site regeneration.
33
+ def test_changing_asset_destination_path_to_new_value_and_back_to_original_does_not_rewrite_destination
34
+ with_site_dir do
35
+ generate_site(:production)
36
+
37
+ assert File.exist?(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
38
+
39
+ ensure_file_mtime_changes do
40
+ change_destination_path('assets/site', 'assets/site2')
41
+ end
42
+
43
+ generate_site(:production, clear_cache: false)
44
+
45
+ refute File.exist?(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
46
+
47
+ new_destination = "assets/site2-#{JS_BUNDLE_FINGERPRINT}.js"
48
+
49
+ assert_equal new_destination, find_js_path_from_index
50
+ assert File.exist?(destination_path(new_destination))
51
+
52
+ ensure_file_mtime_changes do
53
+ change_destination_path('assets/site2', 'assets/site')
54
+
55
+ # CAVEAT: This should not be needed.
56
+ FileUtils.touch(source_path('_assets/scripts/dependency.js'))
57
+ end
58
+
59
+ generate_site(:production, clear_cache: false)
60
+
61
+ assert_equal JS_BUNDLE_DESTINATION_FINGERPRINT_PATH, find_js_path_from_index
62
+ refute File.exist?(destination_path(new_destination))
63
+ assert File.exist?(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
64
+ end
65
+ end
66
+
67
+ private
68
+
69
+ def change_destination_path(from, to)
70
+ match_snippet = <<-END
71
+ {% minibundle js %}
72
+ source_dir: _assets/scripts
73
+ destination_path: #{from}
74
+ END
75
+
76
+ replacement_snippet = <<-END
77
+ {% minibundle js %}
78
+ source_dir: _assets/scripts
79
+ destination_path: #{to}
80
+ END
81
+
82
+ find_and_gsub_in_file(source_path('_layouts/default.html'), match_snippet, replacement_snippet)
83
+ end
84
+
85
+ def find_js_path_from_index
86
+ find_html_element(File.read(destination_path('index.html')), 'body script').first['src']
87
+ end
88
+ end
89
+ end
@@ -51,16 +51,18 @@ module Jekyll::Minibundle::Test
51
51
  end
52
52
 
53
53
  [
54
- {desc: "changing", action: ->(source) { File.write(source, 'h1 {}') }},
55
- {desc: "touching", action: ->(source) { FileUtils.touch(source) }}
54
+ {desc: 'changing', action: ->(source) { File.write(source, '(function() {})()') }},
55
+ {desc: 'touching', action: ->(source) { FileUtils.touch(source) }}
56
56
  ].each do |spec|
57
- define_method :"test_#{spec.fetch(:desc)}_css_asset_source_rewrites_destination" do
57
+ define_method :"test_#{spec.fetch(:desc)}_asset_source_file_rewrites_destination" do
58
58
  with_site_dir do
59
59
  generate_site(:development)
60
- destination = destination_path(CSS_BUNDLE_DESTINATION_PATH, 'common.css')
60
+
61
+ destination = destination_path(JS_BUNDLE_DESTINATION_PATH, 'app.js')
61
62
  org_mtime = mtime_of(destination)
62
- source = source_path(CSS_BUNDLE_SOURCE_DIR, 'common.css')
63
+ source = source_path(JS_BUNDLE_SOURCE_DIR, 'app.js')
63
64
  ensure_file_mtime_changes { spec.fetch(:action).call(source) }
65
+
64
66
  generate_site(:development, clear_cache: false)
65
67
 
66
68
  assert_equal File.read(destination), File.read(source)
@@ -69,46 +71,152 @@ module Jekyll::Minibundle::Test
69
71
  end
70
72
  end
71
73
 
72
- [
73
- {desc: "changing", action: ->(source) { File.write(source, '(function() {})()') }},
74
- {desc: "touching", action: ->(source) { FileUtils.touch(source) }}
75
- ].each do |spec|
76
- define_method :"test_#{spec.fetch(:desc)}_js_asset_source_rewrites_destination" do
77
- with_site_dir do
78
- generate_site(:development)
79
- destination = destination_path(JS_BUNDLE_DESTINATION_PATH, 'app.js')
80
- org_mtime = mtime_of(destination)
81
- source = source_path(JS_BUNDLE_SOURCE_DIR, 'app.js')
82
- ensure_file_mtime_changes { spec.fetch(:action).call(source) }
83
- generate_site(:development, clear_cache: false)
74
+ def test_changing_asset_source_directory_rewrites_destination
75
+ with_site_dir do
76
+ generate_site(:development)
84
77
 
85
- assert_equal File.read(destination), File.read(source)
86
- assert_operator mtime_of(destination), :>, org_mtime
78
+ destination = destination_path(JS_BUNDLE_DESTINATION_PATH, 'app.js')
79
+ org_mtime = mtime_of(destination)
80
+
81
+ match_snippet = <<-END
82
+ {% minibundle js %}
83
+ source_dir: _assets/scripts
84
+ END
85
+
86
+ replacement_snippet = <<-END
87
+ {% minibundle js %}
88
+ source_dir: _assets/scripts2
89
+ END
90
+
91
+ ensure_file_mtime_changes do
92
+ FileUtils.mv(source_path('_assets/scripts'), source_path('_assets/scripts2'))
93
+ find_and_gsub_in_file(source_path('_layouts/default.html'), match_snippet, replacement_snippet)
94
+ end
95
+
96
+ generate_site(:development, clear_cache: false)
97
+
98
+ assert_operator mtime_of(destination), :>, org_mtime
99
+ end
100
+ end
101
+
102
+ def test_changing_asset_source_list_rewrites_destination
103
+ with_site_dir do
104
+ generate_site(:development)
105
+
106
+ org_mtime = mtime_of(destination_path(JS_BUNDLE_DESTINATION_PATH, 'dependency.js'))
107
+
108
+ match_snippet = <<-END
109
+ assets:
110
+ - dependency
111
+ - app
112
+ END
113
+
114
+ replacement_snippet = <<-END
115
+ assets:
116
+ - dependency
117
+ END
118
+
119
+ ensure_file_mtime_changes do
120
+ find_and_gsub_in_file(source_path('_layouts/default.html'), match_snippet, replacement_snippet)
87
121
  end
122
+
123
+ generate_site(:development, clear_cache: false)
124
+
125
+ assert_equal [File.join(JS_BUNDLE_DESTINATION_PATH, 'dependency.js')], find_js_paths_from_index
126
+
127
+ new_mtime = mtime_of(destination_path(JS_BUNDLE_DESTINATION_PATH, 'dependency.js'))
128
+ assert_operator new_mtime, :>, org_mtime
129
+ end
130
+ end
131
+
132
+ def test_changing_asset_destination_path_rewrites_destination
133
+ with_site_dir do
134
+ generate_site(:development)
135
+
136
+ assert File.exist?(destination_path(JS_BUNDLE_DESTINATION_PATH, 'dependency.js'))
137
+ assert File.exist?(destination_path(JS_BUNDLE_DESTINATION_PATH, 'app.js'))
138
+
139
+ match_snippet = <<-END
140
+ {% minibundle js %}
141
+ source_dir: _assets/scripts
142
+ destination_path: assets/site
143
+ END
144
+
145
+ replacement_snippet = <<-END
146
+ {% minibundle js %}
147
+ source_dir: _assets/scripts
148
+ destination_path: assets/site2
149
+ END
150
+
151
+ find_and_gsub_in_file(source_path('_layouts/default.html'), match_snippet, replacement_snippet)
152
+
153
+ generate_site(:development, clear_cache: false)
154
+
155
+ assert_equal ['assets/site2/dependency.js', 'assets/site2/app.js'], find_js_paths_from_index
156
+ assert File.exist?(destination_path('assets/site2/dependency.js'))
157
+ assert File.exist?(destination_path('assets/site2/app.js'))
88
158
  end
89
159
  end
90
160
 
91
161
  def test_supports_relative_and_absolute_destination_paths
92
162
  with_site_dir do
93
- expected_css_path = destination_path(CSS_BUNDLE_DESTINATION_PATH, 'common.css')
94
- expected_js_path = destination_path(JS_BUNDLE_DESTINATION_PATH, 'app.js')
95
163
  generate_site(:development)
96
164
 
97
- assert File.exist?(expected_css_path)
98
- assert File.exist?(expected_js_path)
165
+ assert File.exist?(destination_path(CSS_BUNDLE_DESTINATION_PATH, 'common.css'))
166
+ assert File.exist?(destination_path(JS_BUNDLE_DESTINATION_PATH, 'app.js'))
167
+
99
168
  assert_equal 'assets/site/common.css', find_css_paths_from_index.last
100
169
  assert_equal 'assets/site/app.js', find_js_paths_from_index.last
101
170
 
102
171
  find_and_gsub_in_file(source_path('_layouts/default.html'), 'destination_path: assets/site', 'destination_path: /assets/site')
172
+
103
173
  generate_site(:development, clear_cache: false)
104
174
 
105
- assert File.exist?(expected_css_path)
106
- assert File.exist?(expected_js_path)
107
175
  assert_equal '/assets/site/common.css', find_css_paths_from_index.last
108
176
  assert_equal '/assets/site/app.js', find_js_paths_from_index.last
109
177
  end
110
178
  end
111
179
 
180
+ def test_supports_baseurl
181
+ with_site_dir do
182
+ generate_site(:development)
183
+
184
+ assert File.exist?(destination_path(CSS_BUNDLE_DESTINATION_PATH, 'common.css'))
185
+ assert File.exist?(destination_path(JS_BUNDLE_DESTINATION_PATH, 'app.js'))
186
+
187
+ assert_equal 'assets/site/common.css', find_css_paths_from_index.last
188
+ assert_equal 'assets/site/app.js', find_js_paths_from_index.last
189
+
190
+ find_and_gsub_in_file(source_path('_layouts/default.html'), '{% minibundle css %}', "{% minibundle css %}\n baseurl: /css-root")
191
+ find_and_gsub_in_file(source_path('_layouts/default.html'), '{% minibundle js %}', "{% minibundle js %}\n baseurl: /js-root")
192
+
193
+ generate_site(:development, clear_cache: false)
194
+
195
+ assert_equal '/css-root/assets/site/common.css', find_css_paths_from_index.last
196
+ assert_equal '/js-root/assets/site/app.js', find_js_paths_from_index.last
197
+ end
198
+ end
199
+
200
+ def test_supports_changing_attributes
201
+ with_site_dir do
202
+ generate_site(:development)
203
+
204
+ assert File.exist?(destination_path(CSS_BUNDLE_DESTINATION_PATH, 'common.css'))
205
+ assert File.exist?(destination_path(JS_BUNDLE_DESTINATION_PATH, 'app.js'))
206
+
207
+ find_and_gsub_in_file(source_path('_layouts/default.html'), 'id: my-styles', 'id: my-styles2')
208
+ find_and_gsub_in_file(source_path('_layouts/default.html'), 'id: my-scripts', 'id: my-scripts2')
209
+
210
+ generate_site(:development, clear_cache: false)
211
+
212
+ css_ids = find_css_elements_from_index.map { |el| el['id'] }.uniq
213
+ assert_equal ['my-styles2'], css_ids
214
+
215
+ js_ids = find_js_elements_from_index.map { |el| el['id'] }.uniq
216
+ assert_equal ['my-scripts2'], js_ids
217
+ end
218
+ end
219
+
112
220
  def test_does_not_require_bundling_commands
113
221
  with_site_dir do
114
222
  generate_site(:development, minifier_cmd_css: nil, minifier_cmd_js: nil)
@@ -116,17 +224,54 @@ module Jekyll::Minibundle::Test
116
224
  end
117
225
  end
118
226
 
119
- def test_does_not_rewrite_destination_when_nonsource_files_change
227
+ def test_does_not_rewrite_destination_when_changing_nonsource_files
120
228
  with_site_dir do
121
229
  generate_site(:development)
230
+
122
231
  expected_js_path = destination_path(JS_BUNDLE_DESTINATION_PATH, 'app.js')
123
232
  org_mtime = mtime_of(expected_js_path)
124
233
  ensure_file_mtime_changes { File.write(source_path(JS_BUNDLE_SOURCE_DIR, 'dependency.js'), '(function() {})()') }
234
+
125
235
  generate_site(:development, clear_cache: false)
126
236
 
127
237
  assert_equal org_mtime, mtime_of(expected_js_path)
128
238
 
129
239
  ensure_file_mtime_changes { FileUtils.touch('index.html') }
240
+
241
+ generate_site(:development, clear_cache: false)
242
+
243
+ assert_equal org_mtime, mtime_of(expected_js_path)
244
+ end
245
+ end
246
+
247
+ def test_does_not_rewrite_destination_when_changing_attributes
248
+ with_site_dir do
249
+ generate_site(:development)
250
+
251
+ expected_js_path = destination_path(JS_BUNDLE_DESTINATION_PATH, 'app.js')
252
+ org_mtime = mtime_of(expected_js_path)
253
+
254
+ ensure_file_mtime_changes do
255
+ find_and_gsub_in_file(source_path('_layouts/default.html'), 'id: my-scripts', 'id: my-scripts2')
256
+ end
257
+
258
+ generate_site(:development, clear_cache: false)
259
+
260
+ assert_equal org_mtime, mtime_of(expected_js_path)
261
+ end
262
+ end
263
+
264
+ def test_does_not_rebundle_assets_when_changing_baseurl
265
+ with_site_dir do
266
+ generate_site(:development)
267
+
268
+ expected_js_path = destination_path(JS_BUNDLE_DESTINATION_PATH, 'app.js')
269
+ org_mtime = mtime_of(expected_js_path)
270
+
271
+ ensure_file_mtime_changes do
272
+ find_and_gsub_in_file(source_path('_layouts/default.html'), '{% minibundle js %}', "{% minibundle js %}\n baseurl: /js-root")
273
+ end
274
+
130
275
  generate_site(:development, clear_cache: false)
131
276
 
132
277
  assert_equal org_mtime, mtime_of(expected_js_path)
@@ -61,7 +61,7 @@ module Jekyll::Minibundle::Test
61
61
  def test_inserts_semicolons_between_js_assets
62
62
  with_precompiled_site(:production) do
63
63
  bundle = File.read(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
64
- assert_match(%r|}\)\(window\)\n;\n\(function|, bundle)
64
+ assert_match(/}\)\(window\)\n;\n\(function/, bundle)
65
65
  end
66
66
  end
67
67
 
@@ -81,89 +81,232 @@ module Jekyll::Minibundle::Test
81
81
  end
82
82
  end
83
83
 
84
- def test_changing_css_asset_source_rewrites_destination
84
+ def test_changing_asset_source_file_rewrites_destination
85
85
  with_site_dir do
86
86
  generate_site(:production)
87
- org_mtime = mtime_of(destination_path(CSS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
88
- ensure_file_mtime_changes { File.write(source_path(CSS_BUNDLE_SOURCE_DIR, 'common.css'), 'h1 {}') }
87
+
88
+ ensure_file_mtime_changes { File.write(source_path(JS_BUNDLE_SOURCE_DIR, 'app.js'), '(function() {})()') }
89
+
89
90
  generate_site(:production, clear_cache: false)
90
91
 
91
- refute File.exist?(destination_path(CSS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
92
+ refute File.exist?(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
92
93
 
93
- new_destination = 'assets/site-9fd3995d6f0fce425db81c3691dfe93f.css'
94
+ new_destination = 'assets/site-375a0b430b0c5555d0edd2205d26c04d.js'
94
95
 
95
- assert_equal new_destination, find_css_path_from_index
96
+ assert_equal new_destination, find_js_path_from_index
96
97
  assert File.exist?(destination_path(new_destination))
97
- assert_operator mtime_of(destination_path(new_destination)), :>, org_mtime
98
98
  end
99
99
  end
100
100
 
101
- def test_changing_js_asset_source_rewrites_destination
101
+ def test_touching_asset_source_file_rewrites_destination
102
102
  with_site_dir do
103
103
  generate_site(:production)
104
+
104
105
  org_mtime = mtime_of(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
105
- ensure_file_mtime_changes { File.write(source_path(JS_BUNDLE_SOURCE_DIR, 'app.js'), '(function() {})()') }
106
+ ensure_file_mtime_changes { FileUtils.touch(source_path(JS_BUNDLE_SOURCE_DIR, 'app.js')) }
107
+
108
+ generate_site(:production, clear_cache: false)
109
+
110
+ assert_equal JS_BUNDLE_DESTINATION_FINGERPRINT_PATH, find_js_path_from_index
111
+ assert File.exist?(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
112
+ assert_operator mtime_of(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH)), :>, org_mtime
113
+ end
114
+ end
115
+
116
+ def test_changing_asset_source_directory_rewrites_destination
117
+ with_site_dir do
118
+ generate_site(:production)
119
+
120
+ org_mtime = mtime_of(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
121
+
122
+ match_snippet = <<-END
123
+ {% minibundle js %}
124
+ source_dir: _assets/scripts
125
+ END
126
+
127
+ replacement_snippet = <<-END
128
+ {% minibundle js %}
129
+ source_dir: _assets/scripts2
130
+ END
131
+
132
+ ensure_file_mtime_changes do
133
+ FileUtils.mv(source_path('_assets/scripts'), source_path('_assets/scripts2'))
134
+ find_and_gsub_in_file(source_path('_layouts/default.html'), match_snippet, replacement_snippet)
135
+ end
136
+
137
+ generate_site(:production, clear_cache: false)
138
+
139
+ new_mtime = mtime_of(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
140
+
141
+ assert_operator new_mtime, :>, org_mtime
142
+ end
143
+ end
144
+
145
+ def test_changing_asset_source_list_rewrites_destination
146
+ with_site_dir do
147
+ generate_site(:production)
148
+
149
+ assert File.exist?(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
150
+
151
+ match_snippet = <<-END
152
+ assets:
153
+ - dependency
154
+ - app
155
+ END
156
+
157
+ replacement_snippet = <<-END
158
+ assets:
159
+ - dependency
160
+ END
161
+
162
+ ensure_file_mtime_changes do
163
+ find_and_gsub_in_file(source_path('_layouts/default.html'), match_snippet, replacement_snippet)
164
+ end
165
+
106
166
  generate_site(:production, clear_cache: false)
107
167
 
108
168
  refute File.exist?(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
109
169
 
110
- new_destination = 'assets/site-375a0b430b0c5555d0edd2205d26c04d.js'
170
+ new_destination = 'assets/site-71042d0b7c86c04e015fde694dd9f409.js'
111
171
 
112
172
  assert_equal new_destination, find_js_path_from_index
113
173
  assert File.exist?(destination_path(new_destination))
114
- assert_operator mtime_of(destination_path(new_destination)), :>, org_mtime
115
174
  end
116
175
  end
117
176
 
118
- def test_touching_css_asset_source_rewrites_destination
177
+ def test_changing_asset_destination_path_rewrites_destination
119
178
  with_site_dir do
120
179
  generate_site(:production)
121
- destination = CSS_BUNDLE_DESTINATION_FINGERPRINT_PATH
122
- org_mtime = mtime_of(destination_path(destination))
123
- ensure_file_mtime_changes { FileUtils.touch(source_path(CSS_BUNDLE_SOURCE_DIR, 'common.css')) }
180
+
181
+ assert File.exist?(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
182
+
183
+ match_snippet = <<-END
184
+ {% minibundle js %}
185
+ source_dir: _assets/scripts
186
+ destination_path: assets/site
187
+ END
188
+
189
+ replacement_snippet = <<-END
190
+ {% minibundle js %}
191
+ source_dir: _assets/scripts
192
+ destination_path: assets/site2
193
+ END
194
+
195
+ ensure_file_mtime_changes do
196
+ find_and_gsub_in_file(source_path('_layouts/default.html'), match_snippet, replacement_snippet)
197
+ end
198
+
124
199
  generate_site(:production, clear_cache: false)
125
200
 
126
- assert_equal destination, find_css_path_from_index
127
- assert File.exist?(destination_path(destination))
128
- assert_operator mtime_of(destination_path(destination)), :>, org_mtime
201
+ refute File.exist?(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
202
+
203
+ new_destination = "assets/site2-#{JS_BUNDLE_FINGERPRINT}.js"
204
+
205
+ assert_equal new_destination, find_js_path_from_index
206
+ assert File.exist?(destination_path(new_destination))
129
207
  end
130
208
  end
131
209
 
132
- def test_touching_js_asset_source_rewrites_destination
210
+ def test_changing_minifier_cmd_rewrites_destination
133
211
  with_site_dir do
134
212
  generate_site(:production)
135
- destination = JS_BUNDLE_DESTINATION_FINGERPRINT_PATH
136
- org_mtime = mtime_of(destination_path(destination))
137
- ensure_file_mtime_changes { FileUtils.touch(source_path(JS_BUNDLE_SOURCE_DIR, 'app.js')) }
213
+
214
+ assert_equal 0, get_minifier_cmd_count
215
+ destination = destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH)
216
+ org_mtime = mtime_of(destination)
217
+
218
+ match_snippet = <<-END
219
+ {% minibundle js %}
220
+ END
221
+
222
+ replacement_snippet = <<-END
223
+ {% minibundle js %}
224
+ minifier_cmd: #{minifier_cmd_to_remove_comments_and_count}
225
+ END
226
+
227
+ ensure_file_mtime_changes do
228
+ find_and_gsub_in_file(source_path('_layouts/default.html'), match_snippet, replacement_snippet)
229
+ end
230
+
138
231
  generate_site(:production, clear_cache: false)
139
232
 
140
- assert_equal destination, find_js_path_from_index
141
- assert File.exist?(destination_path(destination))
142
- assert_operator mtime_of(destination_path(destination)), :>, org_mtime
233
+ assert_equal 1, get_minifier_cmd_count
234
+ assert_operator mtime_of(destination), :>, org_mtime
143
235
  end
144
236
  end
145
237
 
146
238
  def test_supports_relative_and_absolute_destination_paths
147
239
  with_site_dir do
148
240
  generate_site(:production)
149
- expected_css_path = destination_path(CSS_BUNDLE_DESTINATION_FINGERPRINT_PATH)
150
- expected_js_path = destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH)
151
241
 
152
- assert File.exist?(expected_css_path)
153
- assert File.exist?(expected_js_path)
242
+ assert File.exist?(destination_path(CSS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
243
+ assert File.exist?(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
244
+
154
245
  assert_equal CSS_BUNDLE_DESTINATION_FINGERPRINT_PATH, find_css_path_from_index
155
246
  assert_equal JS_BUNDLE_DESTINATION_FINGERPRINT_PATH, find_js_path_from_index
156
247
 
157
248
  find_and_gsub_in_file(source_path('_layouts/default.html'), 'destination_path: assets/site', 'destination_path: /assets/site')
249
+
158
250
  generate_site(:production, clear_cache: false)
159
251
 
160
- assert File.exist?(expected_css_path)
161
- assert File.exist?(expected_js_path)
162
252
  assert_equal "/#{CSS_BUNDLE_DESTINATION_FINGERPRINT_PATH}", find_css_path_from_index
163
253
  assert_equal "/#{JS_BUNDLE_DESTINATION_FINGERPRINT_PATH}", find_js_path_from_index
164
254
  end
165
255
  end
166
256
 
257
+ def test_supports_baseurl
258
+ with_site_dir do
259
+ generate_site(:production)
260
+
261
+ assert File.exist?(destination_path(CSS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
262
+ assert File.exist?(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
263
+
264
+ assert_equal CSS_BUNDLE_DESTINATION_FINGERPRINT_PATH, find_css_path_from_index
265
+ assert_equal JS_BUNDLE_DESTINATION_FINGERPRINT_PATH, find_js_path_from_index
266
+
267
+ find_and_gsub_in_file(source_path('_layouts/default.html'), '{% minibundle css %}', "{% minibundle css %}\n baseurl: /css-root")
268
+ find_and_gsub_in_file(source_path('_layouts/default.html'), '{% minibundle js %}', "{% minibundle js %}\n baseurl: /js-root")
269
+
270
+ generate_site(:production, clear_cache: false)
271
+
272
+ assert_equal "/css-root/#{CSS_BUNDLE_DESTINATION_FINGERPRINT_PATH}", find_css_path_from_index
273
+ assert_equal "/js-root/#{JS_BUNDLE_DESTINATION_FINGERPRINT_PATH}", find_js_path_from_index
274
+ end
275
+ end
276
+
277
+ def test_supports_baseurl_via_liquid_variable
278
+ with_site_dir do
279
+ merge_to_yaml_file(source_path('_config.yml'), 'baseurl' => '/')
280
+ find_and_gsub_in_file(source_path('_layouts/default.html'), '{% minibundle css %}', "{% minibundle css %}\n baseurl: {{ site.baseurl }}")
281
+ find_and_gsub_in_file(source_path('_layouts/default.html'), '{% minibundle js %}', "{% minibundle js %}\n baseurl: {{ site.baseurl }}")
282
+
283
+ generate_site(:production)
284
+
285
+ assert File.exist?(destination_path(CSS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
286
+ assert File.exist?(destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH))
287
+
288
+ assert_equal "/#{CSS_BUNDLE_DESTINATION_FINGERPRINT_PATH}", find_css_path_from_index
289
+ assert_equal "/#{JS_BUNDLE_DESTINATION_FINGERPRINT_PATH}", find_js_path_from_index
290
+ end
291
+ end
292
+
293
+ def test_supports_changing_attributes
294
+ with_site_dir do
295
+ generate_site(:production)
296
+
297
+ assert_equal CSS_BUNDLE_DESTINATION_FINGERPRINT_PATH, find_css_path_from_index
298
+ assert_equal JS_BUNDLE_DESTINATION_FINGERPRINT_PATH, find_js_path_from_index
299
+
300
+ find_and_gsub_in_file(source_path('_layouts/default.html'), 'id: my-styles', 'id: my-styles2')
301
+ find_and_gsub_in_file(source_path('_layouts/default.html'), 'id: my-scripts', 'id: my-scripts2')
302
+
303
+ generate_site(:production, clear_cache: false)
304
+
305
+ assert_equal 'my-styles2', find_css_element_from_index['id']
306
+ assert_equal 'my-scripts2', find_js_element_from_index['id']
307
+ end
308
+ end
309
+
167
310
  def test_bundles_assets_only_once_at_startup
168
311
  with_site_dir do
169
312
  generate_site(:production, minifier_cmd_js: minifier_cmd_to_remove_comments_and_count)
@@ -171,31 +314,77 @@ module Jekyll::Minibundle::Test
171
314
  end
172
315
  end
173
316
 
174
- def test_does_not_rebundle_assets_when_nonsource_files_change
317
+ def test_does_not_rebundle_assets_when_changing_nonsource_files
175
318
  with_site_dir do
176
319
  generate_site(:production, minifier_cmd_js: minifier_cmd_to_remove_comments_and_count)
320
+
177
321
  expected_js_path = destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH)
178
- last_mtime = mtime_of(expected_js_path)
322
+ org_mtime = mtime_of(expected_js_path)
179
323
 
180
324
  assert_equal 1, get_minifier_cmd_count
181
325
 
182
326
  ensure_file_mtime_changes { File.write(source_path(CSS_BUNDLE_SOURCE_DIR, 'common.css'), 'h1 {}') }
327
+
183
328
  generate_site(:production, clear_cache: false, minifier_cmd_js: minifier_cmd_to_remove_comments_and_count)
184
329
 
185
- assert_equal last_mtime, mtime_of(expected_js_path)
330
+ assert_equal org_mtime, mtime_of(expected_js_path)
186
331
  assert_equal 1, get_minifier_cmd_count
187
332
 
188
333
  ensure_file_mtime_changes { FileUtils.touch('index.html') }
334
+
335
+ generate_site(:production, clear_cache: false, minifier_cmd_js: minifier_cmd_to_remove_comments_and_count)
336
+
337
+ assert_equal org_mtime, mtime_of(expected_js_path)
338
+ assert_equal 1, get_minifier_cmd_count
339
+ end
340
+ end
341
+
342
+ def test_does_not_rebundle_assets_when_changing_attributes
343
+ with_site_dir do
344
+ generate_site(:production, minifier_cmd_js: minifier_cmd_to_remove_comments_and_count)
345
+
346
+ expected_js_path = destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH)
347
+ org_mtime = mtime_of(expected_js_path)
348
+
349
+ assert_equal 1, get_minifier_cmd_count
350
+
351
+ ensure_file_mtime_changes do
352
+ find_and_gsub_in_file(source_path('_layouts/default.html'), 'id: my-scripts', 'id: my-scripts2')
353
+ end
354
+
355
+ generate_site(:production, clear_cache: false, minifier_cmd_js: minifier_cmd_to_remove_comments_and_count)
356
+
357
+ assert_equal org_mtime, mtime_of(expected_js_path)
358
+ assert_equal 1, get_minifier_cmd_count
359
+ end
360
+ end
361
+
362
+ def test_does_not_rebundle_assets_when_changing_baseurl
363
+ with_site_dir do
364
+ generate_site(:production, minifier_cmd_js: minifier_cmd_to_remove_comments_and_count)
365
+
366
+ expected_js_path = destination_path(JS_BUNDLE_DESTINATION_FINGERPRINT_PATH)
367
+ org_mtime = mtime_of(expected_js_path)
368
+
369
+ assert_equal 1, get_minifier_cmd_count
370
+
371
+ ensure_file_mtime_changes do
372
+ find_and_gsub_in_file(source_path('_layouts/default.html'), '{% minibundle js %}', "{% minibundle js %}\n baseurl: /js-root")
373
+ end
374
+
189
375
  generate_site(:production, clear_cache: false, minifier_cmd_js: minifier_cmd_to_remove_comments_and_count)
190
376
 
191
- assert_equal last_mtime, mtime_of(expected_js_path)
377
+ assert_equal org_mtime, mtime_of(expected_js_path)
192
378
  assert_equal 1, get_minifier_cmd_count
193
379
  end
194
380
  end
195
381
 
196
382
  def test_gets_minifier_command_from_site_configuration
197
383
  with_site_dir do
198
- merge_to_yaml_file('_config.yml', 'minibundle' => {'minifier_commands' => {'js' => minifier_cmd_to_remove_comments_and_count('minifier_cmd_config_count')}})
384
+ merge_to_yaml_file(
385
+ source_path('_config.yml'),
386
+ 'minibundle' => {'minifier_commands' => {'js' => minifier_cmd_to_remove_comments_and_count('minifier_cmd_config_count')}}
387
+ )
199
388
 
200
389
  generate_site(:production, minifier_cmd_js: nil)
201
390
 
@@ -207,7 +396,10 @@ module Jekyll::Minibundle::Test
207
396
 
208
397
  def test_minifier_command_from_environment_overrides_command_from_site_configuration
209
398
  with_site_dir do
210
- merge_to_yaml_file('_config.yml', 'minibundle' => {'minifier_commands' => {'js' => minifier_cmd_to_remove_comments_and_count('minifier_cmd_config_count')}})
399
+ merge_to_yaml_file(
400
+ source_path('_config.yml'),
401
+ 'minibundle' => {'minifier_commands' => {'js' => minifier_cmd_to_remove_comments_and_count('minifier_cmd_config_count')}}
402
+ )
211
403
 
212
404
  generate_site(:production, minifier_cmd_js: minifier_cmd_to_remove_comments_and_count('minifier_cmd_env_count'))
213
405
 
@@ -275,10 +467,10 @@ title: Test
275
467
  end
276
468
 
277
469
  def source_assets_size(source_subdir, assets, type)
278
- assets.
279
- map { |f| File.read(site_fixture_path(source_subdir, "#{f}.#{type}")) }.
280
- join('').
281
- size
470
+ assets
471
+ .map { |f| File.read(site_fixture_path(source_subdir, "#{f}.#{type}")) }
472
+ .join('')
473
+ .size
282
474
  end
283
475
  end
284
476
  end