Skip to content

Commit 11bab84

Browse files
committed
Improve coverage of Propshaft::Manifest
Also do some edits in the other files to make the code look better.
1 parent 68d4ae0 commit 11bab84

File tree

15 files changed

+171
-109
lines changed

15 files changed

+171
-109
lines changed

lib/propshaft/assembly.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ def initialize(config)
1717
end
1818

1919
def load_path
20-
2120
@load_path ||= Propshaft::LoadPath.new(
2221
config.paths,
2322
compilers: compilers,

lib/propshaft/asset.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ def digest
3434
@digest ||= Digest::SHA1.hexdigest("#{content_with_compile_references}#{load_path.version}").first(8)
3535
end
3636

37-
# Following the Subresource Integrity spec draft
38-
# https://w3c.github.io/webappsec-subresource-integrity/
39-
# allowing only sha256, sha384, and sha512
4037
def integrity(hash_algorithm:)
38+
# Following the Subresource Integrity spec draft
39+
# https://w3c.github.io/webappsec-subresource-integrity/
40+
# allowing only sha256, sha384, and sha512
4141
bitlen = case hash_algorithm
4242
when "sha256"
4343
256

lib/propshaft/load_path.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def asset_paths_by_glob(glob)
4242
end
4343

4444
def manifest
45-
Propshaft::Manifest.new(integrity_hash_algorithm:).tap do |manifest|
45+
Propshaft::Manifest.new(integrity_hash_algorithm: integrity_hash_algorithm).tap do |manifest|
4646
assets.each { |asset| manifest.push_asset(asset) }
4747
end
4848
end

lib/propshaft/manifest.rb

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,41 @@ module Propshaft
22
class Manifest
33
class ManifestEntry
44
attr_reader :logical_path, :digested_path, :integrity
5+
56
def initialize(logical_path:, digested_path:, integrity:)
67
@logical_path = logical_path
78
@digested_path = digested_path
89
@integrity = integrity
910
end
1011

1112
def to_h
12-
{ digested_path:, integrity: }
13+
{ digested_path: digested_path, integrity: integrity}
14+
end
15+
end
16+
17+
class << self
18+
def from_path(manifest_path)
19+
manifest = Manifest.new
20+
21+
serialized_manifest = JSON.parse(manifest_path.read, symbolize_names: false)
22+
23+
serialized_manifest.each_pair do |key, value|
24+
# Compatibility mode to be able to
25+
# read the old "simple manifest" format
26+
digested_path, integrity = if value.is_a?(String)
27+
[value, nil]
28+
else
29+
[value["digested_path"], value["integrity"]]
30+
end
31+
32+
entry = ManifestEntry.new(
33+
logical_path: key, digested_path: digested_path, integrity: integrity
34+
)
35+
36+
manifest.push(entry)
37+
end
38+
39+
manifest
1340
end
1441
end
1542

@@ -22,7 +49,7 @@ def push_asset(asset)
2249
entry = ManifestEntry.new(
2350
logical_path: asset.logical_path.to_s,
2451
digested_path: asset.digested_path.to_s,
25-
integrity: @integrity_hash_algorithm && asset.integrity(hash_algorithm: @integrity_hash_algorithm)
52+
integrity: integrity_hash_algorithm && asset.integrity(hash_algorithm: integrity_hash_algorithm)
2653
)
2754

2855
push(entry)
@@ -31,45 +58,19 @@ def push_asset(asset)
3158
def push(entry)
3259
@entries[entry.logical_path] = entry
3360
end
34-
35-
def <<(asset)
36-
push(asset)
37-
end
61+
alias_method :<<, :push
3862

3963
def [](logical_path)
4064
@entries[logical_path]
4165
end
4266

4367
def to_json
44-
Hash.new.tap do |serialized_manifest|
45-
@entries.values.each do |manifest_entry|
46-
serialized_manifest[manifest_entry.logical_path] = manifest_entry.to_h
47-
end
68+
@entries.transform_values do |manifest_entry|
69+
manifest_entry.to_h
4870
end.to_json
4971
end
5072

51-
class << self
52-
def from_path(manifest_path)
53-
Manifest.new.tap do |manifest|
54-
JSON.parse(manifest_path.read, symbolize_names: false).tap do |serialized_manifest|
55-
serialized_manifest.each_pair do |key, value|
56-
# Compatibility mode to be able to
57-
# read the old "simple manifest" format
58-
digested_path, integrity = if value.is_a?(String)
59-
[value, nil]
60-
else
61-
[value["digested_path"], value["integrity"]]
62-
end
63-
64-
entry = ManifestEntry.new(
65-
logical_path: key, digested_path:, integrity:
66-
)
67-
68-
manifest.push(entry)
69-
end
70-
end
71-
end
72-
end
73-
end
73+
private
74+
attr_reader :integrity_hash_algorithm
7475
end
7576
end

lib/propshaft/resolver/dynamic.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ def initialize(load_path:, prefix:)
77
end
88

99
def resolve(logical_path)
10-
if asset = load_path.find(logical_path)
10+
if asset = find_asset(logical_path)
1111
File.join prefix, asset.digested_path
1212
end
1313
end
1414

1515
def integrity(logical_path)
1616
hash_algorithm = load_path.integrity_hash_algorithm
17-
if (asset = load_path.find(logical_path)) && hash_algorithm
17+
18+
if hash_algorithm && (asset = find_asset(logical_path))
1819
asset.integrity(hash_algorithm:)
1920
end
2021
end
@@ -24,5 +25,10 @@ def read(logical_path, options = {})
2425
asset.content(**options)
2526
end
2627
end
28+
29+
private
30+
def find_asset(logical_path)
31+
load_path.find(logical_path)
32+
end
2733
end
2834
end
File renamed without changes.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
One from first path
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
One from first path map

test/propshaft/assembly_test.rb

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
class Propshaft::AssemblyTest < ActiveSupport::TestCase
66
test "uses static resolver when manifest is present" do
7-
assembly = Propshaft::Assembly.new(ActiveSupport::OrderedOptions.new.tap { |config|
7+
assembly = Propshaft::Assembly.new(ActiveSupport::OrderedOptions.new.tap { |config|
88
config.output_path = Pathname.new("#{__dir__}/../fixtures/output")
99
config.manifest_path = config.output_path.join(".manifest.json")
1010
config.prefix = "/assets"
@@ -14,7 +14,7 @@ class Propshaft::AssemblyTest < ActiveSupport::TestCase
1414
end
1515

1616
test "uses dynamic resolver when manifest is missing" do
17-
assembly = Propshaft::Assembly.new(ActiveSupport::OrderedOptions.new.tap { |config|
17+
assembly = Propshaft::Assembly.new(ActiveSupport::OrderedOptions.new.tap { |config|
1818
config.output_path = Pathname.new("#{__dir__}/../fixtures/assets")
1919
config.manifest_path = config.output_path.join(".manifest.json")
2020
config.prefix = "/assets"
@@ -43,30 +43,4 @@ class Propshaft::AssemblyTest < ActiveSupport::TestCase
4343

4444
assert assembly.processor.is_a?(Propshaft::Processor)
4545
end
46-
47-
class Propshaft::AssemblyTest::WithExtensibleManifest < ActiveSupport::TestCase
48-
test "uses static resolver when manifest is present" do
49-
assembly = Propshaft::Assembly.new(ActiveSupport::OrderedOptions.new.tap { |config|
50-
config.output_path = Pathname.new("#{__dir__}/../fixtures/output")
51-
config.manifest_path = config.output_path.join(".extensible_manifest.json")
52-
config.prefix = "/assets"
53-
54-
config.integrity_hash_algorithm = "sha384"
55-
})
56-
57-
assert assembly.resolver.is_a?(Propshaft::Resolver::Static)
58-
end
59-
60-
test "uses dynamic resolver when manifest is missing" do
61-
assembly = Propshaft::Assembly.new(ActiveSupport::OrderedOptions.new.tap { |config|
62-
config.output_path = Pathname.new("#{__dir__}/../fixtures/assets")
63-
config.manifest_path = config.output_path.join(".extensible_manifest.json")
64-
config.prefix = "/assets"
65-
66-
config.integrity_hash_algorithm = "sha384"
67-
})
68-
69-
assert assembly.resolver.is_a?(Propshaft::Resolver::Dynamic)
70-
end
71-
end
7246
end

test/propshaft/asset_test.rb

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ class Propshaft::AssetTest < ActiveSupport::TestCase
6464
exception = assert_raises StandardError do
6565
find_asset("one.txt").integrity(hash_algorithm: "md5")
6666
end
67-
6867
assert_equal "Subresource Integrity hash algorithm must be one of SHA2 family (sha256, sha384, sha512)", exception.message
6968
end
7069

0 commit comments

Comments
 (0)