hanami 2.1.0.rc2 → 2.1.0.rc3
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 +15 -1
- data/hanami.gemspec +1 -1
- data/lib/hanami/app.rb +0 -5
- data/lib/hanami/config.rb +1 -5
- data/lib/hanami/extensions/view/context.rb +12 -3
- data/lib/hanami/helpers/assets_helper.rb +30 -29
- data/lib/hanami/helpers/form_helper/form_builder.rb +54 -54
- data/lib/hanami/helpers/form_helper/values.rb +8 -8
- data/lib/hanami/helpers/form_helper.rb +9 -9
- data/lib/hanami/providers/assets.rb +4 -1
- data/lib/hanami/rake_tasks.rb +1 -9
- data/lib/hanami/slice.rb +10 -0
- data/lib/hanami/version.rb +1 -1
- data/spec/integration/assets/assets_spec.rb +67 -24
- data/spec/integration/assets/cross_slice_assets_helpers_spec.rb +130 -0
- data/spec/integration/view/context/assets_spec.rb +57 -31
- data/spec/support/app_integration.rb +12 -6
- data/spec/unit/hanami/helpers/assets_helper/asset_url_spec.rb +11 -0
- data/spec/unit/hanami/version_spec.rb +1 -1
- metadata +11 -9
@@ -18,39 +18,17 @@ RSpec.describe "Assets", :app_integration do
|
|
18
18
|
end
|
19
19
|
RUBY
|
20
20
|
|
21
|
-
write "config/assets.
|
21
|
+
write "config/assets.js", <<~JS
|
22
22
|
import * as assets from "hanami-assets";
|
23
23
|
await assets.run();
|
24
24
|
JS
|
25
25
|
|
26
26
|
write "package.json", <<~JSON
|
27
27
|
{
|
28
|
-
"
|
29
|
-
"assets": "node config/assets.mjs"
|
30
|
-
}
|
28
|
+
"type": "module"
|
31
29
|
}
|
32
30
|
JSON
|
33
31
|
|
34
|
-
write "config/routes.rb", <<~RUBY
|
35
|
-
module TestApp
|
36
|
-
class Routes < Hanami::Routes
|
37
|
-
get "posts/:id/edit", to: "posts.edit"
|
38
|
-
put "posts/:id", to: "posts.update"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
RUBY
|
42
|
-
|
43
|
-
write "app/action.rb", <<~RUBY
|
44
|
-
# auto_register: false
|
45
|
-
|
46
|
-
require "hanami/action"
|
47
|
-
|
48
|
-
module TestApp
|
49
|
-
class Action < Hanami::Action
|
50
|
-
end
|
51
|
-
end
|
52
|
-
RUBY
|
53
|
-
|
54
32
|
write "app/view.rb", <<~RUBY
|
55
33
|
# auto_register: false
|
56
34
|
|
@@ -109,4 +87,69 @@ RSpec.describe "Assets", :app_integration do
|
|
109
87
|
expect(assets["app.css"].to_s).to match(%r{/assets/app-[A-Z0-9]{8}.css})
|
110
88
|
expect(assets["app.js"].to_s).to match(%r{/assets/app-[A-Z0-9]{8}.js})
|
111
89
|
end
|
90
|
+
|
91
|
+
describe "slice with assets" do
|
92
|
+
def before_prepare
|
93
|
+
write "slices/main/view.rb", <<~RUBY
|
94
|
+
# auto_register: false
|
95
|
+
|
96
|
+
module Main
|
97
|
+
class View < TestApp::View
|
98
|
+
end
|
99
|
+
end
|
100
|
+
RUBY
|
101
|
+
|
102
|
+
write "slices/main/views/posts/show.rb", <<~RUBY
|
103
|
+
module Main
|
104
|
+
module Views
|
105
|
+
module Posts
|
106
|
+
class Show < Main::View
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
RUBY
|
112
|
+
|
113
|
+
write "slices/main/templates/posts/show.html.erb", <<~ERB
|
114
|
+
<%= stylesheet_tag("app") %>
|
115
|
+
<%= javascript_tag("app") %>
|
116
|
+
ERB
|
117
|
+
|
118
|
+
write "slices/main/assets/js/app.ts", <<~TS
|
119
|
+
import "../css/app.css";
|
120
|
+
|
121
|
+
console.log("Hello from main slice index.ts");
|
122
|
+
TS
|
123
|
+
|
124
|
+
write "slices/main/assets/css/app.css", <<~CSS
|
125
|
+
.btn {
|
126
|
+
background: #f00;
|
127
|
+
}
|
128
|
+
CSS
|
129
|
+
end
|
130
|
+
|
131
|
+
specify "the slice's assets are available in its own and distinct `assets` component" do
|
132
|
+
compile_assets!
|
133
|
+
|
134
|
+
output = Main::Slice["views.posts.show"].call.to_s
|
135
|
+
|
136
|
+
expect(output).to match(%r{<link href="/assets/main/app-[A-Z0-9]{8}.css" type="text/css" rel="stylesheet">})
|
137
|
+
expect(output).to match(%r{<script src="/assets/main/app-[A-Z0-9]{8}.js" type="text/javascript"></script>})
|
138
|
+
|
139
|
+
assets = Main::Slice["assets"]
|
140
|
+
|
141
|
+
expect(assets["app.css"].to_s).to match(%r{/assets/main/app-[A-Z0-9]{8}.css})
|
142
|
+
expect(assets["app.js"].to_s).to match(%r{/assets/main/app-[A-Z0-9]{8}.js})
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
describe "slice without assets" do
|
147
|
+
def before_prepare
|
148
|
+
write "slices/main/.keep", ""
|
149
|
+
end
|
150
|
+
|
151
|
+
it "does not have an assets component" do
|
152
|
+
expect(Main::Slice.key?("assets")).to be false
|
153
|
+
end
|
154
|
+
end
|
112
155
|
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rack/test"
|
4
|
+
require "stringio"
|
5
|
+
|
6
|
+
RSpec.describe "Cross-slice assets via helpers", :app_integration do
|
7
|
+
include Rack::Test::Methods
|
8
|
+
let(:app) { Hanami.app }
|
9
|
+
let(:root) { make_tmp_directory }
|
10
|
+
|
11
|
+
before do
|
12
|
+
with_directory(root) do
|
13
|
+
write "config/app.rb", <<~RUBY
|
14
|
+
module TestApp
|
15
|
+
class App < Hanami::App
|
16
|
+
config.logger.stream = StringIO.new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
RUBY
|
20
|
+
|
21
|
+
write "config/slices/admin.rb", <<~RUBY
|
22
|
+
module Admin
|
23
|
+
class Slice < Hanami::Slice
|
24
|
+
# TODO: we should update `import` to make importing from the app nicer
|
25
|
+
# TODO: this test failed when I tried doing `as: "app"` (string instead of symbol); fix this in dry-system
|
26
|
+
import keys: ["assets"], from: Hanami.app.container, as: :app
|
27
|
+
end
|
28
|
+
end
|
29
|
+
RUBY
|
30
|
+
|
31
|
+
write "config/assets.js", <<~JS
|
32
|
+
import * as assets from "hanami-assets";
|
33
|
+
await assets.run();
|
34
|
+
JS
|
35
|
+
|
36
|
+
write "package.json", <<~JSON
|
37
|
+
{
|
38
|
+
"type": "module"
|
39
|
+
}
|
40
|
+
JSON
|
41
|
+
|
42
|
+
write "app/view.rb", <<~RUBY
|
43
|
+
# auto_register: false
|
44
|
+
|
45
|
+
require "hanami/view"
|
46
|
+
|
47
|
+
module TestApp
|
48
|
+
class View < Hanami::View
|
49
|
+
config.layout = nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
RUBY
|
53
|
+
|
54
|
+
write "app/assets/js/app.ts", <<~TS
|
55
|
+
import "../css/app.css";
|
56
|
+
|
57
|
+
console.log("Hello from index.ts");
|
58
|
+
TS
|
59
|
+
|
60
|
+
write "app/assets/css/app.css", <<~CSS
|
61
|
+
.btn {
|
62
|
+
background: #f00;
|
63
|
+
}
|
64
|
+
CSS
|
65
|
+
|
66
|
+
write "slices/admin/assets/js/app.ts", <<~TS
|
67
|
+
import "../css/app.css";
|
68
|
+
|
69
|
+
console.log("Hello from admin's index.ts");
|
70
|
+
TS
|
71
|
+
|
72
|
+
write "slices/admin/assets/css/app.css", <<~CSS
|
73
|
+
.btn {
|
74
|
+
background: #f00;
|
75
|
+
}
|
76
|
+
CSS
|
77
|
+
|
78
|
+
write "slices/admin/view.rb", <<~RUBY
|
79
|
+
# auto_register: false
|
80
|
+
|
81
|
+
module Admin
|
82
|
+
class View < TestApp::View
|
83
|
+
end
|
84
|
+
end
|
85
|
+
RUBY
|
86
|
+
|
87
|
+
write "slices/admin/views/posts/show.rb", <<~RUBY
|
88
|
+
module Admin
|
89
|
+
module Views
|
90
|
+
module Posts
|
91
|
+
class Show < Admin::View
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
RUBY
|
97
|
+
|
98
|
+
write "slices/admin/views/context.rb", <<~RUBY
|
99
|
+
# auto_register: false
|
100
|
+
|
101
|
+
require "hanami/view"
|
102
|
+
|
103
|
+
module Admin
|
104
|
+
module Views
|
105
|
+
class Context < Hanami::View::Context
|
106
|
+
include Deps[app_assets: "app.assets"]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
RUBY
|
111
|
+
|
112
|
+
write "slices/admin/templates/posts/show.html.erb", <<~ERB
|
113
|
+
<%= stylesheet_tag(app_assets["app.css"]) %>
|
114
|
+
<%= javascript_tag(app_assets["app.js"]) %>
|
115
|
+
ERB
|
116
|
+
|
117
|
+
before_prepare if respond_to?(:before_prepare)
|
118
|
+
require "hanami/prepare"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
specify "assets are available in helpers and in `assets` component" do
|
123
|
+
compile_assets!
|
124
|
+
|
125
|
+
output = Admin::Slice["views.posts.show"].call.to_s
|
126
|
+
|
127
|
+
expect(output).to match(%r{<link href="/assets/app-[A-Z0-9]{8}.css" type="text/css" rel="stylesheet">})
|
128
|
+
expect(output).to match(%r{<script src="/assets/app-[A-Z0-9]{8}.js" type="text/javascript"></script>})
|
129
|
+
end
|
130
|
+
end
|
@@ -3,51 +3,77 @@
|
|
3
3
|
require "hanami"
|
4
4
|
|
5
5
|
RSpec.describe "App view / Context / Assets", :app_integration do
|
6
|
+
subject(:context) { context_class.new }
|
7
|
+
let(:context_class) { TestApp::Views::Context }
|
8
|
+
|
6
9
|
before do
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
with_directory(make_tmp_directory) do
|
11
|
+
write "config/app.rb", <<~RUBY
|
12
|
+
module TestApp
|
13
|
+
class App < Hanami::App
|
14
|
+
config.logger.stream = File::NULL
|
15
|
+
end
|
16
|
+
end
|
17
|
+
RUBY
|
11
18
|
|
12
|
-
|
19
|
+
write "app/views/context.rb", <<~RUBY
|
20
|
+
# auto_register: false
|
13
21
|
|
14
|
-
|
15
|
-
|
16
|
-
|
22
|
+
require "hanami/view/context"
|
23
|
+
|
24
|
+
module TestApp
|
25
|
+
module Views
|
26
|
+
class Context < Hanami::View::Context
|
27
|
+
end
|
28
|
+
end
|
17
29
|
end
|
18
|
-
|
30
|
+
RUBY
|
31
|
+
|
32
|
+
before_prepare if respond_to?(:before_prepare)
|
33
|
+
require "hanami/prepare"
|
19
34
|
end
|
20
35
|
end
|
21
36
|
|
22
|
-
|
23
|
-
|
37
|
+
context "assets present and hanami-assets bundled" do
|
38
|
+
def before_prepare
|
39
|
+
write "app/assets/.keep", ""
|
40
|
+
end
|
24
41
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
42
|
+
it "is the app assets by default" do
|
43
|
+
expect(context.assets).to be TestApp::App[:assets]
|
44
|
+
end
|
45
|
+
end
|
29
46
|
|
30
|
-
|
31
|
-
|
32
|
-
|
47
|
+
context "assets not present" do
|
48
|
+
it "raises error" do
|
49
|
+
expect { context.assets }.to raise_error(Hanami::ComponentLoadError, /assets directory\?/)
|
33
50
|
end
|
51
|
+
end
|
34
52
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
53
|
+
context "hanami-assets not bundled" do
|
54
|
+
def before_prepare
|
55
|
+
# These must be here instead of an ordinary before hook because the Hanami.bundled? check for
|
56
|
+
# assets is done as part of requiring "hanami/prepare" above.
|
57
|
+
allow(Hanami).to receive(:bundled?).and_call_original
|
58
|
+
allow(Hanami).to receive(:bundled?).with("hanami-assets").and_return(false)
|
39
59
|
|
40
|
-
|
41
|
-
|
42
|
-
context_class.new(assets: assets)
|
43
|
-
}
|
60
|
+
write "app/assets/.keep", ""
|
61
|
+
end
|
44
62
|
|
45
|
-
|
63
|
+
it "raises error" do
|
64
|
+
expect { context.assets }.to raise_error(Hanami::ComponentLoadError, /hanami-assets gem/)
|
65
|
+
end
|
66
|
+
end
|
46
67
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
68
|
+
context "injected assets" do
|
69
|
+
subject(:context) {
|
70
|
+
context_class.new(assets: assets)
|
71
|
+
}
|
72
|
+
|
73
|
+
let(:assets) { double(:assets) }
|
74
|
+
|
75
|
+
it "is the injected assets" do
|
76
|
+
expect(context.assets).to be assets
|
51
77
|
end
|
52
78
|
end
|
53
79
|
end
|
@@ -29,12 +29,16 @@ module RSpec
|
|
29
29
|
|
30
30
|
private
|
31
31
|
|
32
|
+
# TODO: make slice-aware
|
32
33
|
def stub_assets(*assets)
|
33
34
|
manifest_hash = assets.each_with_object({}) { |source_path, hsh|
|
34
35
|
hsh[source_path] = {url: File.join("/assets", source_path)}
|
35
36
|
}
|
36
37
|
|
37
|
-
write "public/assets.json", JSON.generate(manifest_hash)
|
38
|
+
write "public/assets/assets.json", JSON.generate(manifest_hash)
|
39
|
+
|
40
|
+
# An assets dir isrequired to load the assets provider
|
41
|
+
write "app/assets/.keep", ""
|
38
42
|
end
|
39
43
|
|
40
44
|
def compile_assets!
|
@@ -44,7 +48,11 @@ module RSpec
|
|
44
48
|
require "hanami/cli/command"
|
45
49
|
require "hanami/cli/commands/app/command"
|
46
50
|
require "hanami/cli/commands/app/assets/compile"
|
47
|
-
assets_compile = Hanami::CLI::Commands::App::Assets::Compile.new(
|
51
|
+
assets_compile = Hanami::CLI::Commands::App::Assets::Compile.new(
|
52
|
+
config: Hanami.app.config.assets,
|
53
|
+
out: File.new(File::NULL, "w"),
|
54
|
+
err: File.new(File::NULL, "w"),
|
55
|
+
)
|
48
56
|
|
49
57
|
with_directory(Hanami.app.root) { assets_compile.call }
|
50
58
|
end
|
@@ -62,16 +70,14 @@ module RSpec
|
|
62
70
|
root = Hanami.app.root
|
63
71
|
|
64
72
|
with_directory(root) do
|
65
|
-
write("config/assets.
|
73
|
+
write("config/assets.js", <<~JS) unless root.join("config", "assets.js").exist?
|
66
74
|
import * as assets from "hanami-assets";
|
67
75
|
await assets.run();
|
68
76
|
JS
|
69
77
|
|
70
78
|
write("package.json", <<~JSON) unless root.join("package.json").exist?
|
71
79
|
{
|
72
|
-
"
|
73
|
-
"assets": "node config/assets.mjs"
|
74
|
-
}
|
80
|
+
"type": "module"
|
75
81
|
}
|
76
82
|
JSON
|
77
83
|
end
|
@@ -106,4 +106,15 @@ RSpec.describe Hanami::Helpers::AssetsHelper, "#asset_url", :app_integration do
|
|
106
106
|
end
|
107
107
|
end
|
108
108
|
end
|
109
|
+
|
110
|
+
context "given an asset object" do
|
111
|
+
it "returns the URL for the asset" do
|
112
|
+
asset = Hanami::Assets::Asset.new(
|
113
|
+
path: "/foo/bar.js",
|
114
|
+
base_url: Hanami.app.config.assets.base_url
|
115
|
+
)
|
116
|
+
|
117
|
+
expect(asset_url(asset)).to eq "/foo/bar.js"
|
118
|
+
end
|
119
|
+
end
|
109
120
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hanami
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.0.
|
4
|
+
version: 2.1.0.rc3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-02-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -160,16 +160,16 @@ dependencies:
|
|
160
160
|
name: hanami-cli
|
161
161
|
requirement: !ruby/object:Gem::Requirement
|
162
162
|
requirements:
|
163
|
-
- -
|
163
|
+
- - '='
|
164
164
|
- !ruby/object:Gem::Version
|
165
|
-
version: 2.1.
|
165
|
+
version: 2.1.0.rc3
|
166
166
|
type: :runtime
|
167
167
|
prerelease: false
|
168
168
|
version_requirements: !ruby/object:Gem::Requirement
|
169
169
|
requirements:
|
170
|
-
- -
|
170
|
+
- - '='
|
171
171
|
- !ruby/object:Gem::Version
|
172
|
-
version: 2.1.
|
172
|
+
version: 2.1.0.rc3
|
173
173
|
- !ruby/object:Gem::Dependency
|
174
174
|
name: hanami-utils
|
175
175
|
requirement: !ruby/object:Gem::Requirement
|
@@ -325,6 +325,7 @@ files:
|
|
325
325
|
- spec/integration/action/view_rendering/view_context_spec.rb
|
326
326
|
- spec/integration/action/view_rendering_spec.rb
|
327
327
|
- spec/integration/assets/assets_spec.rb
|
328
|
+
- spec/integration/assets/cross_slice_assets_helpers_spec.rb
|
328
329
|
- spec/integration/assets/serve_static_assets_spec.rb
|
329
330
|
- spec/integration/code_loading/loading_from_app_spec.rb
|
330
331
|
- spec/integration/code_loading/loading_from_lib_spec.rb
|
@@ -446,11 +447,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
446
447
|
version: '3.0'
|
447
448
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
448
449
|
requirements:
|
449
|
-
- - "
|
450
|
+
- - ">="
|
450
451
|
- !ruby/object:Gem::Version
|
451
|
-
version:
|
452
|
+
version: '0'
|
452
453
|
requirements: []
|
453
|
-
rubygems_version: 3.
|
454
|
+
rubygems_version: 3.5.6
|
454
455
|
signing_key:
|
455
456
|
specification_version: 4
|
456
457
|
summary: The web, with simplicity
|
@@ -466,6 +467,7 @@ test_files:
|
|
466
467
|
- spec/integration/action/view_rendering/view_context_spec.rb
|
467
468
|
- spec/integration/action/view_rendering_spec.rb
|
468
469
|
- spec/integration/assets/assets_spec.rb
|
470
|
+
- spec/integration/assets/cross_slice_assets_helpers_spec.rb
|
469
471
|
- spec/integration/assets/serve_static_assets_spec.rb
|
470
472
|
- spec/integration/code_loading/loading_from_app_spec.rb
|
471
473
|
- spec/integration/code_loading/loading_from_lib_spec.rb
|