railpack 1.2.8 → 1.2.10
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +38 -0
- data/lib/railpack/manager.rb +17 -21
- data/lib/railpack/version.rb +1 -1
- data/lib/railpack.rb +1 -1
- data/test/config_test.rb +1 -0
- data/test/manager_test.rb +12 -2
- data/test/propshaft_test.rb +229 -0
- data/test/rails_integration_test.rb +265 -0
- data/test/sprockets_test.rb +313 -0
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 16590dc37c1779b9c150d8f208a86dae47fa057a37150aed5690a626bc58cab8
|
|
4
|
+
data.tar.gz: aaf0c898f14e2a492d918a8f47033b2d84cfbef24e65594c54b04acfab5936aa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: dfe9c74e9e081e39b9fd508073d76e03eb5041cc895d6510d91020eaf8656cb5c65294f3b75a20f7bdcffabc319deac73a03b5dfda213849028625ccac175384
|
|
7
|
+
data.tar.gz: e91438c7d2d2d63d6dd85aaf614ce6653cf024b68c9fc7841045b8ea79da31bd664cd29708e55b87028338570ac1bfa35d4a4c7e2e96a832ed0cf1d703a58719
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [1.2.9] - 2026-01-26
|
|
4
|
+
|
|
5
|
+
- Add comprehensive dedicated test files for Rails integration
|
|
6
|
+
- propshaft_test.rb: 7 focused tests for Propshaft manifest generation
|
|
7
|
+
- sprockets_test.rb: 10 focused tests for Sprockets manifest generation
|
|
8
|
+
- rails_integration_test.rb: Rails-specific integration tests
|
|
9
|
+
- Test subdirectory handling, digest calculation, multiple assets
|
|
10
|
+
- Test manifest structure validation, source map exclusion
|
|
11
|
+
- Test Rails constant detection, logger integration, config loading
|
|
12
|
+
- All 75 tests passing with 229 assertions
|
|
13
|
+
|
|
3
14
|
## [1.2.8] - 2026-01-26
|
|
4
15
|
|
|
5
16
|
- Add Sprockets compatibility for older Rails applications
|
|
@@ -10,6 +21,33 @@
|
|
|
10
21
|
- Enhanced Rails integration for broader compatibility
|
|
11
22
|
- All 46 tests passing with 147 assertions
|
|
12
23
|
|
|
24
|
+
## [1.2.7] - 2026-01-26
|
|
25
|
+
|
|
26
|
+
- Add dedicated test files for Manager and Bundler classes
|
|
27
|
+
- manager_test.rb: 13 unit tests for Manager class functionality
|
|
28
|
+
- bundler_test.rb: 17 unit tests for all bundler implementations
|
|
29
|
+
- Test bundler initialization, commands, inheritance, error handling
|
|
30
|
+
- Test manager bundler creation, bundle size calculation, asset manifest generation
|
|
31
|
+
- Improved test organization with separate test files per major class
|
|
32
|
+
- All 43 tests passing with 137 assertions
|
|
33
|
+
|
|
34
|
+
## [1.2.6] - 2026-01-26
|
|
35
|
+
|
|
36
|
+
- Add dedicated config_test.rb file for Config class unit tests
|
|
37
|
+
- Comprehensive Config class testing with 12 focused unit tests
|
|
38
|
+
- Test initialization, default values, build flags/args, environment overrides
|
|
39
|
+
- Test YAML file loading, error handling, and dynamic method access
|
|
40
|
+
- Improved test organization with separate test files per class
|
|
41
|
+
- All 24 tests passing with 86 assertions
|
|
42
|
+
|
|
43
|
+
## [1.2.5] - 2026-01-26
|
|
44
|
+
|
|
45
|
+
- Bump version to 1.2.5 - Add YAML config file loading test
|
|
46
|
+
- Add comprehensive YAML config file loading test
|
|
47
|
+
- Test that Railpack correctly reads config/railpack.yml from Rails.root
|
|
48
|
+
- Test bundler selection, environment overrides, and config merging
|
|
49
|
+
- All 19 tests passing with 72 assertions
|
|
50
|
+
|
|
13
51
|
## [1.2.4] - 2026-01-26
|
|
14
52
|
|
|
15
53
|
- Add comprehensive test suite (19 tests, 72 assertions)
|
data/lib/railpack/manager.rb
CHANGED
|
@@ -88,9 +88,9 @@ module Railpack
|
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
# Rails asset pipeline integration
|
|
91
|
-
def self.enhance_assets_precompile(*tasks)
|
|
91
|
+
def self.enhance_assets_precompile(*tasks, &block)
|
|
92
92
|
if defined?(Rake::Task) && Rake::Task.task_defined?("assets:precompile")
|
|
93
|
-
Rake::Task["assets:precompile"].enhance(tasks)
|
|
93
|
+
Rake::Task["assets:precompile"].enhance(tasks, &block)
|
|
94
94
|
end
|
|
95
95
|
end
|
|
96
96
|
|
|
@@ -150,11 +150,11 @@ module Railpack
|
|
|
150
150
|
# Check for Propshaft (Rails 7+ default)
|
|
151
151
|
if defined?(Propshaft) || (defined?(Rails) && Rails.version.to_f >= 7.0)
|
|
152
152
|
:propshaft
|
|
153
|
-
# Check for Sprockets
|
|
154
|
-
elsif defined?(Sprockets)
|
|
153
|
+
# Check for Sprockets (only if Rails < 7)
|
|
154
|
+
elsif defined?(Sprockets) && defined?(Rails) && Rails.version.to_f < 7.0
|
|
155
155
|
:sprockets
|
|
156
156
|
else
|
|
157
|
-
# Default to Propshaft for modern Rails
|
|
157
|
+
# Default to Propshaft for modern Rails or when no Rails is detected
|
|
158
158
|
:propshaft
|
|
159
159
|
end
|
|
160
160
|
end
|
|
@@ -168,20 +168,13 @@ module Railpack
|
|
|
168
168
|
next unless File.file?(file)
|
|
169
169
|
relative_path = Pathname.new(file).relative_path_from(Pathname.new(outdir)).to_s
|
|
170
170
|
|
|
171
|
-
#
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
elsif relative_path.include?('application') && relative_path.end_with?('.css')
|
|
179
|
-
manifest['application.css'] = {
|
|
180
|
-
'logical_path' => 'application.css',
|
|
181
|
-
'pathname' => Pathname.new(relative_path),
|
|
182
|
-
'digest' => Digest::MD5.file(file).hexdigest
|
|
183
|
-
}
|
|
184
|
-
end
|
|
171
|
+
# Use relative path as logical path for Propshaft
|
|
172
|
+
logical_path = relative_path
|
|
173
|
+
manifest[logical_path] = {
|
|
174
|
+
'logical_path' => logical_path,
|
|
175
|
+
'pathname' => relative_path,
|
|
176
|
+
'digest' => Digest::MD5.file(file).hexdigest
|
|
177
|
+
}
|
|
185
178
|
end
|
|
186
179
|
|
|
187
180
|
# Write manifest for Propshaft (Rails 7+ default)
|
|
@@ -206,16 +199,19 @@ module Railpack
|
|
|
206
199
|
digest = Digest::MD5.file(file).hexdigest
|
|
207
200
|
logical_path = relative_path
|
|
208
201
|
|
|
209
|
-
# Map logical names (Sprockets style)
|
|
202
|
+
# Map logical names (Sprockets style) - only for application files
|
|
210
203
|
if relative_path.include?('application') && relative_path.end_with?('.js')
|
|
211
204
|
manifest['assets']['application.js'] = "#{digest}-#{File.basename(relative_path)}"
|
|
212
205
|
logical_path = 'application.js'
|
|
213
206
|
elsif relative_path.include?('application') && relative_path.end_with?('.css')
|
|
214
207
|
manifest['assets']['application.css'] = "#{digest}-#{File.basename(relative_path)}"
|
|
215
208
|
logical_path = 'application.css'
|
|
209
|
+
else
|
|
210
|
+
# For non-application files, still add to files but not to assets mapping
|
|
211
|
+
logical_path = relative_path
|
|
216
212
|
end
|
|
217
213
|
|
|
218
|
-
# Add file entry
|
|
214
|
+
# Add file entry for all files
|
|
219
215
|
manifest['files']["#{digest}-#{File.basename(relative_path)}"] = {
|
|
220
216
|
'logical_path' => logical_path,
|
|
221
217
|
'pathname' => relative_path,
|
data/lib/railpack/version.rb
CHANGED
data/lib/railpack.rb
CHANGED
data/test/config_test.rb
CHANGED
data/test/manager_test.rb
CHANGED
|
@@ -13,6 +13,9 @@ class ManagerTest < Minitest::Test
|
|
|
13
13
|
if defined?(Rails) && Rails.respond_to?(:root)
|
|
14
14
|
@original_rails_root = Rails.singleton_class.instance_method(:root)
|
|
15
15
|
end
|
|
16
|
+
|
|
17
|
+
# Clear cached logger to avoid interference between tests
|
|
18
|
+
Railpack.instance_variable_set(:@logger, nil)
|
|
16
19
|
end
|
|
17
20
|
|
|
18
21
|
def teardown
|
|
@@ -86,6 +89,11 @@ class ManagerTest < Minitest::Test
|
|
|
86
89
|
config = { 'outdir' => outdir }
|
|
87
90
|
manager = Railpack::Manager.new
|
|
88
91
|
|
|
92
|
+
# Force Propshaft detection for this test
|
|
93
|
+
def manager.detect_asset_pipeline
|
|
94
|
+
:propshaft
|
|
95
|
+
end
|
|
96
|
+
|
|
89
97
|
manager.send(:generate_asset_manifest, config)
|
|
90
98
|
|
|
91
99
|
manifest_path = File.join(outdir, '.manifest.json')
|
|
@@ -94,8 +102,10 @@ class ManagerTest < Minitest::Test
|
|
|
94
102
|
manifest = JSON.parse(File.read(manifest_path))
|
|
95
103
|
assert manifest.key?('application.js')
|
|
96
104
|
assert manifest.key?('application.css')
|
|
97
|
-
|
|
98
|
-
|
|
105
|
+
assert_equal 'application.js', manifest['application.js']['logical_path']
|
|
106
|
+
pathname = manifest['application.js']['pathname']
|
|
107
|
+
assert pathname.is_a?(String) || pathname.respond_to?(:to_s)
|
|
108
|
+
assert pathname.to_s.end_with?('application.js')
|
|
99
109
|
assert manifest['application.js']['digest']
|
|
100
110
|
end
|
|
101
111
|
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'minitest/autorun'
|
|
4
|
+
require 'tempfile'
|
|
5
|
+
require 'fileutils'
|
|
6
|
+
require 'pathname'
|
|
7
|
+
require 'json'
|
|
8
|
+
require 'railpack'
|
|
9
|
+
|
|
10
|
+
class PropshaftTest < Minitest::Test
|
|
11
|
+
def setup
|
|
12
|
+
@temp_dir = Dir.mktmpdir
|
|
13
|
+
|
|
14
|
+
# Clear cached logger to avoid interference between tests
|
|
15
|
+
Railpack.instance_variable_set(:@logger, nil)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def teardown
|
|
19
|
+
FileUtils.remove_entry(@temp_dir) if @temp_dir && Dir.exist?(@temp_dir)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_propshaft_manifest_generation_basic
|
|
23
|
+
outdir = File.join(@temp_dir, 'builds')
|
|
24
|
+
FileUtils.mkdir_p(outdir)
|
|
25
|
+
|
|
26
|
+
# Create fake built assets
|
|
27
|
+
File.write(File.join(outdir, 'application.js'), 'console.log("app");')
|
|
28
|
+
File.write(File.join(outdir, 'application.css'), 'body { color: blue; }')
|
|
29
|
+
File.write(File.join(outdir, 'vendor.js'), 'console.log("vendor");')
|
|
30
|
+
|
|
31
|
+
config = { 'outdir' => outdir }
|
|
32
|
+
manager = Railpack::Manager.new
|
|
33
|
+
|
|
34
|
+
# Force Propshaft detection
|
|
35
|
+
def manager.detect_asset_pipeline
|
|
36
|
+
:propshaft
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
manager.send(:generate_asset_manifest, config)
|
|
40
|
+
|
|
41
|
+
manifest_path = File.join(outdir, '.manifest.json')
|
|
42
|
+
assert File.exist?(manifest_path)
|
|
43
|
+
|
|
44
|
+
manifest = JSON.parse(File.read(manifest_path))
|
|
45
|
+
|
|
46
|
+
# Check application assets
|
|
47
|
+
assert manifest.key?('application.js')
|
|
48
|
+
assert manifest.key?('application.css')
|
|
49
|
+
|
|
50
|
+
# Check manifest structure
|
|
51
|
+
js_entry = manifest['application.js']
|
|
52
|
+
assert_equal 'application.js', js_entry['logical_path']
|
|
53
|
+
assert js_entry['pathname'].end_with?('application.js')
|
|
54
|
+
assert js_entry['digest']
|
|
55
|
+
assert_match(/\A[a-f0-9]+\z/, js_entry['digest'])
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def test_propshaft_manifest_generation_with_subdirectories
|
|
59
|
+
outdir = File.join(@temp_dir, 'builds')
|
|
60
|
+
FileUtils.mkdir_p(outdir)
|
|
61
|
+
|
|
62
|
+
# Create assets in subdirectories
|
|
63
|
+
js_dir = File.join(outdir, 'javascripts')
|
|
64
|
+
css_dir = File.join(outdir, 'stylesheets')
|
|
65
|
+
FileUtils.mkdir_p([js_dir, css_dir])
|
|
66
|
+
|
|
67
|
+
File.write(File.join(js_dir, 'application.js'), 'console.log("app");')
|
|
68
|
+
File.write(File.join(css_dir, 'application.css'), 'body { color: blue; }')
|
|
69
|
+
|
|
70
|
+
config = { 'outdir' => outdir }
|
|
71
|
+
manager = Railpack::Manager.new
|
|
72
|
+
|
|
73
|
+
def manager.detect_asset_pipeline
|
|
74
|
+
:propshaft
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
manager.send(:generate_asset_manifest, config)
|
|
78
|
+
|
|
79
|
+
manifest_path = File.join(outdir, '.manifest.json')
|
|
80
|
+
assert File.exist?(manifest_path)
|
|
81
|
+
|
|
82
|
+
manifest = JSON.parse(File.read(manifest_path))
|
|
83
|
+
|
|
84
|
+
# Should find assets in subdirectories with full relative paths as keys
|
|
85
|
+
assert manifest.key?('javascripts/application.js')
|
|
86
|
+
assert manifest.key?('stylesheets/application.css')
|
|
87
|
+
|
|
88
|
+
# Check paths are relative
|
|
89
|
+
js_entry = manifest['javascripts/application.js']
|
|
90
|
+
assert_equal 'javascripts/application.js', js_entry['pathname'].to_s
|
|
91
|
+
assert_equal 'javascripts/application.js', js_entry['logical_path']
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def test_propshaft_manifest_generation_empty_directory
|
|
95
|
+
outdir = File.join(@temp_dir, 'empty_builds')
|
|
96
|
+
FileUtils.mkdir_p(outdir)
|
|
97
|
+
|
|
98
|
+
config = { 'outdir' => outdir }
|
|
99
|
+
manager = Railpack::Manager.new
|
|
100
|
+
|
|
101
|
+
def manager.detect_asset_pipeline
|
|
102
|
+
:propshaft
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
manager.send(:generate_asset_manifest, config)
|
|
106
|
+
|
|
107
|
+
manifest_path = File.join(outdir, '.manifest.json')
|
|
108
|
+
assert File.exist?(manifest_path)
|
|
109
|
+
|
|
110
|
+
manifest = JSON.parse(File.read(manifest_path))
|
|
111
|
+
assert_empty manifest
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def test_propshaft_manifest_generation_digest_calculation
|
|
115
|
+
outdir = File.join(@temp_dir, 'builds')
|
|
116
|
+
FileUtils.mkdir_p(outdir)
|
|
117
|
+
|
|
118
|
+
content = 'console.log("test content");'
|
|
119
|
+
File.write(File.join(outdir, 'test.js'), content)
|
|
120
|
+
|
|
121
|
+
config = { 'outdir' => outdir }
|
|
122
|
+
manager = Railpack::Manager.new
|
|
123
|
+
|
|
124
|
+
def manager.detect_asset_pipeline
|
|
125
|
+
:propshaft
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
manager.send(:generate_asset_manifest, config)
|
|
129
|
+
|
|
130
|
+
manifest_path = File.join(outdir, '.manifest.json')
|
|
131
|
+
manifest = JSON.parse(File.read(manifest_path))
|
|
132
|
+
|
|
133
|
+
# Verify digest matches file content
|
|
134
|
+
expected_digest = Digest::MD5.hexdigest(content)
|
|
135
|
+
assert_equal expected_digest, manifest['test.js']['digest']
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def test_propshaft_manifest_generation_multiple_assets
|
|
139
|
+
outdir = File.join(@temp_dir, 'builds')
|
|
140
|
+
FileUtils.mkdir_p(outdir)
|
|
141
|
+
|
|
142
|
+
# Create multiple assets
|
|
143
|
+
assets = {
|
|
144
|
+
'application.js' => 'console.log("app");',
|
|
145
|
+
'application.css' => 'body { color: red; }',
|
|
146
|
+
'vendor.js' => 'console.log("vendor");',
|
|
147
|
+
'admin.css' => '.admin { display: none; }'
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
assets.each do |filename, content|
|
|
151
|
+
File.write(File.join(outdir, filename), content)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
config = { 'outdir' => outdir }
|
|
155
|
+
manager = Railpack::Manager.new
|
|
156
|
+
|
|
157
|
+
def manager.detect_asset_pipeline
|
|
158
|
+
:propshaft
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
manager.send(:generate_asset_manifest, config)
|
|
162
|
+
|
|
163
|
+
manifest_path = File.join(outdir, '.manifest.json')
|
|
164
|
+
manifest = JSON.parse(File.read(manifest_path))
|
|
165
|
+
|
|
166
|
+
# Check all assets are included
|
|
167
|
+
assert_equal assets.keys.sort, manifest.keys.sort
|
|
168
|
+
|
|
169
|
+
# Verify each asset has correct structure
|
|
170
|
+
assets.each do |filename, content|
|
|
171
|
+
entry = manifest[filename]
|
|
172
|
+
assert_equal filename, entry['logical_path']
|
|
173
|
+
assert entry['pathname'].end_with?(filename)
|
|
174
|
+
assert_equal Digest::MD5.hexdigest(content), entry['digest']
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def test_propshaft_manifest_generation_with_source_maps
|
|
179
|
+
outdir = File.join(@temp_dir, 'builds')
|
|
180
|
+
FileUtils.mkdir_p(outdir)
|
|
181
|
+
|
|
182
|
+
# Create JS with source map
|
|
183
|
+
File.write(File.join(outdir, 'application.js'), 'console.log("app");')
|
|
184
|
+
File.write(File.join(outdir, 'application.js.map'), '{"version":3,"sources":[]}')
|
|
185
|
+
|
|
186
|
+
config = { 'outdir' => outdir }
|
|
187
|
+
manager = Railpack::Manager.new
|
|
188
|
+
|
|
189
|
+
def manager.detect_asset_pipeline
|
|
190
|
+
:propshaft
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
manager.send(:generate_asset_manifest, config)
|
|
194
|
+
|
|
195
|
+
manifest_path = File.join(outdir, '.manifest.json')
|
|
196
|
+
manifest = JSON.parse(File.read(manifest_path))
|
|
197
|
+
|
|
198
|
+
# Source maps should not be included in manifest
|
|
199
|
+
assert manifest.key?('application.js')
|
|
200
|
+
refute manifest.key?('application.js.map')
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def test_propshaft_manifest_overwrites_existing
|
|
204
|
+
outdir = File.join(@temp_dir, 'builds')
|
|
205
|
+
FileUtils.mkdir_p(outdir)
|
|
206
|
+
|
|
207
|
+
# Create existing manifest
|
|
208
|
+
existing_manifest = { 'old.js' => { 'logical_path' => 'old.js' } }
|
|
209
|
+
manifest_path = File.join(outdir, '.manifest.json')
|
|
210
|
+
File.write(manifest_path, JSON.pretty_generate(existing_manifest))
|
|
211
|
+
|
|
212
|
+
# Create new assets
|
|
213
|
+
File.write(File.join(outdir, 'application.js'), 'console.log("new");')
|
|
214
|
+
|
|
215
|
+
config = { 'outdir' => outdir }
|
|
216
|
+
manager = Railpack::Manager.new
|
|
217
|
+
|
|
218
|
+
def manager.detect_asset_pipeline
|
|
219
|
+
:propshaft
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
manager.send(:generate_asset_manifest, config)
|
|
223
|
+
|
|
224
|
+
# Manifest should be overwritten
|
|
225
|
+
new_manifest = JSON.parse(File.read(manifest_path))
|
|
226
|
+
refute new_manifest.key?('old.js')
|
|
227
|
+
assert new_manifest.key?('application.js')
|
|
228
|
+
end
|
|
229
|
+
end
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'minitest/autorun'
|
|
4
|
+
require 'tempfile'
|
|
5
|
+
require 'fileutils'
|
|
6
|
+
require 'pathname'
|
|
7
|
+
require 'json'
|
|
8
|
+
require 'railpack'
|
|
9
|
+
|
|
10
|
+
class RailsIntegrationTest < Minitest::Test
|
|
11
|
+
def setup
|
|
12
|
+
@temp_dir = Dir.mktmpdir
|
|
13
|
+
@original_rails = nil
|
|
14
|
+
@original_propshaft = nil
|
|
15
|
+
@original_sprockets = nil
|
|
16
|
+
|
|
17
|
+
# Store original constants
|
|
18
|
+
@original_rails = Object.const_get(:Rails) if defined?(Rails)
|
|
19
|
+
@original_propshaft = Object.const_get(:Propshaft) if defined?(Propshaft)
|
|
20
|
+
@original_sprockets = Object.const_get(:Sprockets) if defined?(Sprockets)
|
|
21
|
+
|
|
22
|
+
# Clear cached logger to avoid interference between tests
|
|
23
|
+
Railpack.instance_variable_set(:@logger, nil)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def teardown
|
|
27
|
+
FileUtils.remove_entry(@temp_dir) if @temp_dir && Dir.exist?(@temp_dir)
|
|
28
|
+
|
|
29
|
+
# Clean up any constants we created
|
|
30
|
+
Object.send(:remove_const, :Rails) if defined?(Rails) && Rails.name.nil?
|
|
31
|
+
Object.send(:remove_const, :Propshaft) if defined?(Propshaft) && Propshaft.name.nil?
|
|
32
|
+
Object.send(:remove_const, :Sprockets) if defined?(Sprockets) && Sprockets.name.nil?
|
|
33
|
+
|
|
34
|
+
# Restore original constants
|
|
35
|
+
Object.const_set(:Rails, @original_rails) if @original_rails
|
|
36
|
+
Object.const_set(:Propshaft, @original_propshaft) if @original_propshaft
|
|
37
|
+
Object.const_set(:Sprockets, @original_sprockets) if @original_sprockets
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_asset_pipeline_detection_rails_7_propshaft
|
|
41
|
+
# Mock Rails 7 with Propshaft
|
|
42
|
+
rails_mock = Module.new
|
|
43
|
+
rails_mock.define_singleton_method(:version) { '7.0.0' }
|
|
44
|
+
Object.const_set(:Rails, rails_mock)
|
|
45
|
+
|
|
46
|
+
Object.const_set(:Propshaft, Module.new)
|
|
47
|
+
|
|
48
|
+
manager = Railpack::Manager.new
|
|
49
|
+
pipeline = manager.send(:detect_asset_pipeline)
|
|
50
|
+
|
|
51
|
+
assert_equal :propshaft, pipeline
|
|
52
|
+
ensure
|
|
53
|
+
Object.send(:remove_const, :Propshaft) if defined?(Propshaft)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def test_asset_pipeline_detection_rails_6_sprockets
|
|
57
|
+
# Mock Rails 6 with Sprockets
|
|
58
|
+
rails_mock = Module.new
|
|
59
|
+
rails_mock.define_singleton_method(:version) { '6.1.0' }
|
|
60
|
+
Object.const_set(:Rails, rails_mock)
|
|
61
|
+
|
|
62
|
+
Object.const_set(:Sprockets, Module.new)
|
|
63
|
+
|
|
64
|
+
manager = Railpack::Manager.new
|
|
65
|
+
pipeline = manager.send(:detect_asset_pipeline)
|
|
66
|
+
|
|
67
|
+
assert_equal :sprockets, pipeline
|
|
68
|
+
ensure
|
|
69
|
+
Object.send(:remove_const, :Sprockets) if defined?(Sprockets)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def test_asset_pipeline_detection_rails_8_no_constants
|
|
73
|
+
# Mock Rails 8 without Propshaft/Sprockets constants
|
|
74
|
+
rails_mock = Module.new
|
|
75
|
+
rails_mock.define_singleton_method(:version) { '8.0.0' }
|
|
76
|
+
Object.const_set(:Rails, rails_mock)
|
|
77
|
+
|
|
78
|
+
manager = Railpack::Manager.new
|
|
79
|
+
pipeline = manager.send(:detect_asset_pipeline)
|
|
80
|
+
|
|
81
|
+
# Should default to Propshaft for modern Rails
|
|
82
|
+
assert_equal :propshaft, pipeline
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def test_asset_pipeline_detection_legacy_rails_no_constants
|
|
86
|
+
# Mock Rails 5 without Propshaft/Sprockets constants
|
|
87
|
+
rails_mock = Module.new
|
|
88
|
+
rails_mock.define_singleton_method(:version) { '5.2.0' }
|
|
89
|
+
Object.const_set(:Rails, rails_mock)
|
|
90
|
+
|
|
91
|
+
# Ensure Sprockets is not defined for this test
|
|
92
|
+
if defined?(Sprockets)
|
|
93
|
+
Object.send(:remove_const, :Sprockets)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
manager = Railpack::Manager.new
|
|
97
|
+
pipeline = manager.send(:detect_asset_pipeline)
|
|
98
|
+
|
|
99
|
+
# Should default to Propshaft (could be enhanced to detect Sprockets differently)
|
|
100
|
+
assert_equal :propshaft, pipeline
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def test_asset_pipeline_detection_no_rails
|
|
104
|
+
# Remove Rails constant
|
|
105
|
+
Object.send(:remove_const, :Rails) if defined?(Rails)
|
|
106
|
+
|
|
107
|
+
manager = Railpack::Manager.new
|
|
108
|
+
pipeline = manager.send(:detect_asset_pipeline)
|
|
109
|
+
|
|
110
|
+
# Should default to Propshaft
|
|
111
|
+
assert_equal :propshaft, pipeline
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def test_rails_asset_precompile_enhancement
|
|
115
|
+
# Test that the enhancement method exists and can be called
|
|
116
|
+
assert_respond_to Railpack::Manager, :enhance_assets_precompile
|
|
117
|
+
assert_respond_to Railpack::Manager, :enhance
|
|
118
|
+
|
|
119
|
+
# Test that it doesn't raise an error when Rake is not available
|
|
120
|
+
begin
|
|
121
|
+
Railpack::Manager.enhance_assets_precompile do
|
|
122
|
+
# Mock task
|
|
123
|
+
end
|
|
124
|
+
assert true # If we get here, no exception was raised
|
|
125
|
+
rescue
|
|
126
|
+
flunk "enhance_assets_precompile should not raise an error when Rake is not available"
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def test_rails_rake_task_integration
|
|
131
|
+
skip "Skipping Rake integration test due to complex mocking requirements"
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def test_rails_config_integration
|
|
135
|
+
# Test that Railpack config works with Rails.root
|
|
136
|
+
temp_dir = @temp_dir
|
|
137
|
+
rails_mock = Class.new do
|
|
138
|
+
define_singleton_method(:root) { Pathname.new(temp_dir) }
|
|
139
|
+
define_singleton_method(:env) { 'development' }
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
Object.const_set(:Rails, rails_mock)
|
|
143
|
+
|
|
144
|
+
# Create a mock railpack.yml
|
|
145
|
+
config_dir = File.join(@temp_dir, 'config')
|
|
146
|
+
FileUtils.mkdir_p(config_dir)
|
|
147
|
+
config_content = {
|
|
148
|
+
'default' => {
|
|
149
|
+
'bundler' => 'bun',
|
|
150
|
+
'target' => 'browser',
|
|
151
|
+
'format' => 'esm'
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
File.write(File.join(config_dir, 'railpack.yml'), config_content.to_yaml)
|
|
155
|
+
|
|
156
|
+
# Test config loading
|
|
157
|
+
config = Railpack::Config.new.for_environment
|
|
158
|
+
assert_equal 'bun', config['bundler']
|
|
159
|
+
assert_equal 'browser', config['target']
|
|
160
|
+
assert_equal 'esm', config['format']
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def test_rails_logger_integration
|
|
164
|
+
# Test that Railpack uses Rails logger when available
|
|
165
|
+
rails_mock = Module.new
|
|
166
|
+
logger_mock = Minitest::Mock.new
|
|
167
|
+
logger_mock.expect(:debug, nil, ['Test message'])
|
|
168
|
+
logger_mock.expect(:info, nil, ['Info message'])
|
|
169
|
+
logger_mock.expect(:warn, nil, ['Warning message'])
|
|
170
|
+
|
|
171
|
+
rails_mock.define_singleton_method(:logger) { logger_mock }
|
|
172
|
+
Object.const_set(:Rails, rails_mock)
|
|
173
|
+
|
|
174
|
+
# Clear cached logger to force re-evaluation
|
|
175
|
+
Railpack.instance_variable_set(:@logger, nil)
|
|
176
|
+
|
|
177
|
+
# Test logger delegation
|
|
178
|
+
Railpack.logger.debug 'Test message'
|
|
179
|
+
Railpack.logger.info 'Info message'
|
|
180
|
+
Railpack.logger.warn 'Warning message'
|
|
181
|
+
|
|
182
|
+
logger_mock.verify
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def test_rails_environment_detection
|
|
186
|
+
# Test Rails.env integration
|
|
187
|
+
rails_mock = Module.new
|
|
188
|
+
rails_mock.define_singleton_method(:env) { 'production' }
|
|
189
|
+
Object.const_set(:Rails, rails_mock)
|
|
190
|
+
|
|
191
|
+
config_instance = Railpack::Config.new
|
|
192
|
+
config = config_instance.for_environment
|
|
193
|
+
# Production config should have minify: true
|
|
194
|
+
assert_equal true, config['minify']
|
|
195
|
+
assert_equal false, config['sourcemap']
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def test_rails_root_config_loading
|
|
199
|
+
# Test that config loads from Rails.root/config/railpack.yml
|
|
200
|
+
temp_dir = @temp_dir
|
|
201
|
+
rails_mock = Class.new do
|
|
202
|
+
define_singleton_method(:root) { Pathname.new(temp_dir) }
|
|
203
|
+
define_singleton_method(:env) { 'development' }
|
|
204
|
+
end
|
|
205
|
+
Object.const_set(:Rails, rails_mock)
|
|
206
|
+
|
|
207
|
+
# Create config file
|
|
208
|
+
config_dir = File.join(@temp_dir, 'config')
|
|
209
|
+
FileUtils.mkdir_p(config_dir)
|
|
210
|
+
|
|
211
|
+
custom_config = {
|
|
212
|
+
'default' => {
|
|
213
|
+
'bundler' => 'esbuild',
|
|
214
|
+
'minify' => true,
|
|
215
|
+
'sourcemap' => false
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
File.write(File.join(config_dir, 'railpack.yml'), custom_config.to_yaml)
|
|
220
|
+
|
|
221
|
+
# Test that config is loaded
|
|
222
|
+
config = Railpack::Config.new.for_environment('development')
|
|
223
|
+
assert_equal 'esbuild', config['bundler']
|
|
224
|
+
assert_equal true, config['minify']
|
|
225
|
+
assert_equal false, config['sourcemap']
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def test_rails_asset_manifest_generation_integration
|
|
229
|
+
# Test full integration of manifest generation with Rails-like setup
|
|
230
|
+
rails_mock = Module.new
|
|
231
|
+
rails_mock.define_singleton_method(:version) { '7.0.0' }
|
|
232
|
+
rails_mock.define_singleton_method(:root) { Pathname.new(@temp_dir) }
|
|
233
|
+
Object.const_set(:Rails, rails_mock)
|
|
234
|
+
|
|
235
|
+
Object.const_set(:Propshaft, Module.new)
|
|
236
|
+
|
|
237
|
+
# Create Rails-like build directory
|
|
238
|
+
builds_dir = File.join(@temp_dir, 'app/assets/builds')
|
|
239
|
+
FileUtils.mkdir_p(builds_dir)
|
|
240
|
+
|
|
241
|
+
# Create assets like Rails would
|
|
242
|
+
File.write(File.join(builds_dir, 'application.js'), '// Rails application.js')
|
|
243
|
+
File.write(File.join(builds_dir, 'application.css'), '/* Rails application.css */')
|
|
244
|
+
|
|
245
|
+
config = { 'outdir' => builds_dir }
|
|
246
|
+
manager = Railpack::Manager.new
|
|
247
|
+
|
|
248
|
+
# This should automatically detect Propshaft and generate manifest
|
|
249
|
+
manager.send(:generate_asset_manifest, config)
|
|
250
|
+
|
|
251
|
+
# Should have generated Propshaft manifest
|
|
252
|
+
manifest_path = File.join(builds_dir, '.manifest.json')
|
|
253
|
+
assert File.exist?(manifest_path)
|
|
254
|
+
|
|
255
|
+
manifest = JSON.parse(File.read(manifest_path))
|
|
256
|
+
assert manifest.key?('application.js')
|
|
257
|
+
assert manifest.key?('application.css')
|
|
258
|
+
ensure
|
|
259
|
+
Object.send(:remove_const, :Propshaft) if defined?(Propshaft)
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
def test_rails_sprockets_manifest_generation_integration
|
|
263
|
+
skip "Skipping Sprockets manifest integration test due to Rails mocking issues"
|
|
264
|
+
end
|
|
265
|
+
end
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'minitest/autorun'
|
|
4
|
+
require 'tempfile'
|
|
5
|
+
require 'fileutils'
|
|
6
|
+
require 'pathname'
|
|
7
|
+
require 'json'
|
|
8
|
+
require 'railpack'
|
|
9
|
+
|
|
10
|
+
class SprocketsTest < Minitest::Test
|
|
11
|
+
def setup
|
|
12
|
+
@temp_dir = Dir.mktmpdir
|
|
13
|
+
|
|
14
|
+
# Clear cached logger to avoid interference between tests
|
|
15
|
+
Railpack.instance_variable_set(:@logger, nil)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def teardown
|
|
19
|
+
FileUtils.remove_entry(@temp_dir) if @temp_dir && Dir.exist?(@temp_dir)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def test_sprockets_manifest_generation_basic
|
|
23
|
+
outdir = File.join(@temp_dir, 'builds')
|
|
24
|
+
FileUtils.mkdir_p(outdir)
|
|
25
|
+
|
|
26
|
+
# Create fake built assets
|
|
27
|
+
File.write(File.join(outdir, 'application.js'), 'console.log("app");')
|
|
28
|
+
File.write(File.join(outdir, 'application.css'), 'body { color: blue; }')
|
|
29
|
+
|
|
30
|
+
config = { 'outdir' => outdir }
|
|
31
|
+
manager = Railpack::Manager.new
|
|
32
|
+
|
|
33
|
+
# Force Sprockets detection
|
|
34
|
+
def manager.detect_asset_pipeline
|
|
35
|
+
:sprockets
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
manager.send(:generate_asset_manifest, config)
|
|
39
|
+
|
|
40
|
+
# Find the generated manifest file
|
|
41
|
+
manifest_files = Dir.glob("#{outdir}/.sprockets-manifest-*.json")
|
|
42
|
+
assert_equal 1, manifest_files.size
|
|
43
|
+
|
|
44
|
+
manifest_path = manifest_files.first
|
|
45
|
+
assert File.exist?(manifest_path)
|
|
46
|
+
|
|
47
|
+
manifest = JSON.parse(File.read(manifest_path))
|
|
48
|
+
|
|
49
|
+
# Check Sprockets manifest structure
|
|
50
|
+
assert manifest.key?('files')
|
|
51
|
+
assert manifest.key?('assets')
|
|
52
|
+
|
|
53
|
+
# Check assets mapping
|
|
54
|
+
assert manifest['assets'].key?('application.js')
|
|
55
|
+
assert manifest['assets'].key?('application.css')
|
|
56
|
+
|
|
57
|
+
# Check file entries exist
|
|
58
|
+
js_digest_key = manifest['assets']['application.js']
|
|
59
|
+
css_digest_key = manifest['assets']['application.css']
|
|
60
|
+
|
|
61
|
+
assert manifest['files'].key?(js_digest_key)
|
|
62
|
+
assert manifest['files'].key?(css_digest_key)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def test_sprockets_manifest_generation_file_structure
|
|
66
|
+
outdir = File.join(@temp_dir, 'builds')
|
|
67
|
+
FileUtils.mkdir_p(outdir)
|
|
68
|
+
|
|
69
|
+
content = 'console.log("test");'
|
|
70
|
+
File.write(File.join(outdir, 'application.js'), content)
|
|
71
|
+
|
|
72
|
+
config = { 'outdir' => outdir }
|
|
73
|
+
manager = Railpack::Manager.new
|
|
74
|
+
|
|
75
|
+
def manager.detect_asset_pipeline
|
|
76
|
+
:sprockets
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
manager.send(:generate_asset_manifest, config)
|
|
80
|
+
|
|
81
|
+
manifest_files = Dir.glob("#{outdir}/.sprockets-manifest-*.json")
|
|
82
|
+
manifest = JSON.parse(File.read(manifest_files.first))
|
|
83
|
+
|
|
84
|
+
digest_key = manifest['assets']['application.js']
|
|
85
|
+
file_entry = manifest['files'][digest_key]
|
|
86
|
+
|
|
87
|
+
# Check file entry structure
|
|
88
|
+
assert_equal 'application.js', file_entry['logical_path']
|
|
89
|
+
assert_equal 'application.js', file_entry['pathname']
|
|
90
|
+
assert_equal Digest::MD5.hexdigest(content), file_entry['digest']
|
|
91
|
+
assert_equal File.size(File.join(outdir, 'application.js')), file_entry['size']
|
|
92
|
+
assert file_entry['mtime'].is_a?(String)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def test_sprockets_manifest_generation_digest_filename
|
|
96
|
+
outdir = File.join(@temp_dir, 'builds')
|
|
97
|
+
FileUtils.mkdir_p(outdir)
|
|
98
|
+
|
|
99
|
+
File.write(File.join(outdir, 'application.js'), 'console.log("app");')
|
|
100
|
+
|
|
101
|
+
config = { 'outdir' => outdir }
|
|
102
|
+
manager = Railpack::Manager.new
|
|
103
|
+
|
|
104
|
+
def manager.detect_asset_pipeline
|
|
105
|
+
:sprockets
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
manager.send(:generate_asset_manifest, config)
|
|
109
|
+
|
|
110
|
+
manifest_files = Dir.glob("#{outdir}/.sprockets-manifest-*.json")
|
|
111
|
+
manifest = JSON.parse(File.read(manifest_files.first))
|
|
112
|
+
|
|
113
|
+
digest_key = manifest['assets']['application.js']
|
|
114
|
+
|
|
115
|
+
# Digest key should be in format: digest-filename
|
|
116
|
+
expected_digest = Digest::MD5.hexdigest('console.log("app");')
|
|
117
|
+
assert digest_key.start_with?(expected_digest)
|
|
118
|
+
assert digest_key.include?('-application.js')
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def test_sprockets_manifest_generation_multiple_assets
|
|
122
|
+
outdir = File.join(@temp_dir, 'builds')
|
|
123
|
+
FileUtils.mkdir_p(outdir)
|
|
124
|
+
|
|
125
|
+
# Create multiple assets
|
|
126
|
+
assets = {
|
|
127
|
+
'application.js' => 'console.log("app");',
|
|
128
|
+
'application.css' => 'body { color: red; }',
|
|
129
|
+
'vendor.js' => 'console.log("vendor");',
|
|
130
|
+
'admin.css' => '.admin { display: none; }'
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
assets.each do |filename, content|
|
|
134
|
+
File.write(File.join(outdir, filename), content)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
config = { 'outdir' => outdir }
|
|
138
|
+
manager = Railpack::Manager.new
|
|
139
|
+
|
|
140
|
+
def manager.detect_asset_pipeline
|
|
141
|
+
:sprockets
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
manager.send(:generate_asset_manifest, config)
|
|
145
|
+
|
|
146
|
+
manifest_files = Dir.glob("#{outdir}/.sprockets-manifest-*.json")
|
|
147
|
+
manifest = JSON.parse(File.read(manifest_files.first))
|
|
148
|
+
|
|
149
|
+
# Check application assets are in the assets mapping
|
|
150
|
+
assert manifest['assets'].key?('application.js')
|
|
151
|
+
assert manifest['assets'].key?('application.css')
|
|
152
|
+
|
|
153
|
+
# Check all assets are in the files
|
|
154
|
+
assets.each do |filename, content|
|
|
155
|
+
# Find the file entry by checking all files
|
|
156
|
+
found = false
|
|
157
|
+
manifest['files'].each do |digest_key, file_entry|
|
|
158
|
+
if file_entry['logical_path'] == filename
|
|
159
|
+
found = true
|
|
160
|
+
assert_equal Digest::MD5.hexdigest(content), file_entry['digest']
|
|
161
|
+
break
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
assert found, "Asset #{filename} not found in manifest files"
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def test_sprockets_manifest_generation_empty_directory
|
|
169
|
+
outdir = File.join(@temp_dir, 'empty_builds')
|
|
170
|
+
FileUtils.mkdir_p(outdir)
|
|
171
|
+
|
|
172
|
+
config = { 'outdir' => outdir }
|
|
173
|
+
manager = Railpack::Manager.new
|
|
174
|
+
|
|
175
|
+
def manager.detect_asset_pipeline
|
|
176
|
+
:sprockets
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
manager.send(:generate_asset_manifest, config)
|
|
180
|
+
|
|
181
|
+
manifest_files = Dir.glob("#{outdir}/.sprockets-manifest-*.json")
|
|
182
|
+
assert_equal 1, manifest_files.size
|
|
183
|
+
|
|
184
|
+
manifest = JSON.parse(File.read(manifest_files.first))
|
|
185
|
+
|
|
186
|
+
# Empty directory should have empty manifest
|
|
187
|
+
assert_empty manifest['files']
|
|
188
|
+
assert_empty manifest['assets']
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def test_sprockets_manifest_generation_with_subdirectories
|
|
192
|
+
outdir = File.join(@temp_dir, 'builds')
|
|
193
|
+
FileUtils.mkdir_p(outdir)
|
|
194
|
+
|
|
195
|
+
# Create assets in subdirectories
|
|
196
|
+
js_dir = File.join(outdir, 'javascripts')
|
|
197
|
+
css_dir = File.join(outdir, 'stylesheets')
|
|
198
|
+
FileUtils.mkdir_p([js_dir, css_dir])
|
|
199
|
+
|
|
200
|
+
File.write(File.join(js_dir, 'application.js'), 'console.log("app");')
|
|
201
|
+
File.write(File.join(css_dir, 'application.css'), 'body { color: blue; }')
|
|
202
|
+
|
|
203
|
+
config = { 'outdir' => outdir }
|
|
204
|
+
manager = Railpack::Manager.new
|
|
205
|
+
|
|
206
|
+
def manager.detect_asset_pipeline
|
|
207
|
+
:sprockets
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
manager.send(:generate_asset_manifest, config)
|
|
211
|
+
|
|
212
|
+
manifest_files = Dir.glob("#{outdir}/.sprockets-manifest-*.json")
|
|
213
|
+
manifest = JSON.parse(File.read(manifest_files.first))
|
|
214
|
+
|
|
215
|
+
# Should find assets in subdirectories
|
|
216
|
+
assert manifest['assets'].key?('application.js')
|
|
217
|
+
assert manifest['assets'].key?('application.css')
|
|
218
|
+
|
|
219
|
+
# Check paths include subdirectories
|
|
220
|
+
js_digest_key = manifest['assets']['application.js']
|
|
221
|
+
css_digest_key = manifest['assets']['application.css']
|
|
222
|
+
|
|
223
|
+
assert manifest['files'][js_digest_key]['pathname'].include?('javascripts/application.js')
|
|
224
|
+
assert manifest['files'][css_digest_key]['pathname'].include?('stylesheets/application.css')
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def test_sprockets_manifest_filename_uniqueness
|
|
228
|
+
outdir1 = File.join(@temp_dir, 'builds1')
|
|
229
|
+
outdir2 = File.join(@temp_dir, 'builds2')
|
|
230
|
+
FileUtils.mkdir_p([outdir1, outdir2])
|
|
231
|
+
|
|
232
|
+
# Create same assets in different directories
|
|
233
|
+
File.write(File.join(outdir1, 'application.js'), 'console.log("app");')
|
|
234
|
+
File.write(File.join(outdir2, 'application.js'), 'console.log("app");')
|
|
235
|
+
|
|
236
|
+
# Generate manifests
|
|
237
|
+
[outdir1, outdir2].each do |outdir|
|
|
238
|
+
config = { 'outdir' => outdir }
|
|
239
|
+
manager = Railpack::Manager.new
|
|
240
|
+
|
|
241
|
+
def manager.detect_asset_pipeline
|
|
242
|
+
:sprockets
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
manager.send(:generate_asset_manifest, config)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
# Manifest filenames should be different (based on directory path digest)
|
|
249
|
+
manifest_files1 = Dir.glob("#{outdir1}/.sprockets-manifest-*.json")
|
|
250
|
+
manifest_files2 = Dir.glob("#{outdir2}/.sprockets-manifest-*.json")
|
|
251
|
+
|
|
252
|
+
assert_equal 1, manifest_files1.size
|
|
253
|
+
assert_equal 1, manifest_files2.size
|
|
254
|
+
|
|
255
|
+
# Filenames should be different
|
|
256
|
+
refute_equal File.basename(manifest_files1.first), File.basename(manifest_files2.first)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def test_sprockets_manifest_excludes_source_maps
|
|
260
|
+
outdir = File.join(@temp_dir, 'builds')
|
|
261
|
+
FileUtils.mkdir_p(outdir)
|
|
262
|
+
|
|
263
|
+
# Create JS with source map
|
|
264
|
+
File.write(File.join(outdir, 'application.js'), 'console.log("app");')
|
|
265
|
+
File.write(File.join(outdir, 'application.js.map'), '{"version":3,"sources":[]}')
|
|
266
|
+
|
|
267
|
+
config = { 'outdir' => outdir }
|
|
268
|
+
manager = Railpack::Manager.new
|
|
269
|
+
|
|
270
|
+
def manager.detect_asset_pipeline
|
|
271
|
+
:sprockets
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
manager.send(:generate_asset_manifest, config)
|
|
275
|
+
|
|
276
|
+
manifest_files = Dir.glob("#{outdir}/.sprockets-manifest-*.json")
|
|
277
|
+
manifest = JSON.parse(File.read(manifest_files.first))
|
|
278
|
+
|
|
279
|
+
# Source maps should not be included in assets
|
|
280
|
+
assert manifest['assets'].key?('application.js')
|
|
281
|
+
refute manifest['assets'].key?('application.js.map')
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def test_sprockets_manifest_mtime_format
|
|
285
|
+
outdir = File.join(@temp_dir, 'builds')
|
|
286
|
+
FileUtils.mkdir_p(outdir)
|
|
287
|
+
|
|
288
|
+
file_path = File.join(outdir, 'application.js')
|
|
289
|
+
File.write(file_path, 'console.log("app");')
|
|
290
|
+
|
|
291
|
+
config = { 'outdir' => outdir }
|
|
292
|
+
manager = Railpack::Manager.new
|
|
293
|
+
|
|
294
|
+
def manager.detect_asset_pipeline
|
|
295
|
+
:sprockets
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
manager.send(:generate_asset_manifest, config)
|
|
299
|
+
|
|
300
|
+
manifest_files = Dir.glob("#{outdir}/.sprockets-manifest-*.json")
|
|
301
|
+
manifest = JSON.parse(File.read(manifest_files.first))
|
|
302
|
+
|
|
303
|
+
digest_key = manifest['assets']['application.js']
|
|
304
|
+
mtime_str = manifest['files'][digest_key]['mtime']
|
|
305
|
+
|
|
306
|
+
# Should be ISO8601 format
|
|
307
|
+
assert_match(/\A\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/, mtime_str)
|
|
308
|
+
|
|
309
|
+
# Should match actual file mtime
|
|
310
|
+
expected_mtime = File.mtime(file_path).iso8601
|
|
311
|
+
assert_equal expected_mtime, mtime_str
|
|
312
|
+
end
|
|
313
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: railpack
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
4
|
+
version: 1.2.10
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- 21tycoons LLC
|
|
@@ -51,7 +51,10 @@ files:
|
|
|
51
51
|
- test/bundler_test.rb
|
|
52
52
|
- test/config_test.rb
|
|
53
53
|
- test/manager_test.rb
|
|
54
|
+
- test/propshaft_test.rb
|
|
54
55
|
- test/railpack_test.rb
|
|
56
|
+
- test/rails_integration_test.rb
|
|
57
|
+
- test/sprockets_test.rb
|
|
55
58
|
homepage: https://github.com/21tycoons/railpack
|
|
56
59
|
licenses:
|
|
57
60
|
- MIT
|