hanami 2.1.1 → 2.2.0.beta2
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 +33 -0
- data/README.md +7 -7
- data/hanami.gemspec +6 -6
- data/lib/hanami/app.rb +5 -1
- data/lib/hanami/config/db.rb +33 -0
- data/lib/hanami/config.rb +36 -9
- data/lib/hanami/constants.rb +4 -0
- data/lib/hanami/extensions/db/repo.rb +103 -0
- data/lib/hanami/extensions.rb +4 -0
- data/lib/hanami/helpers/form_helper/form_builder.rb +4 -6
- data/lib/hanami/provider/source.rb +16 -0
- data/lib/hanami/provider_registrar.rb +28 -0
- data/lib/hanami/providers/assets.rb +2 -20
- data/lib/hanami/providers/db/adapter.rb +75 -0
- data/lib/hanami/providers/db/adapters.rb +50 -0
- data/lib/hanami/providers/db/config.rb +62 -0
- data/lib/hanami/providers/db/gateway.rb +70 -0
- data/lib/hanami/providers/db/sql_adapter.rb +100 -0
- data/lib/hanami/providers/db.rb +298 -0
- data/lib/hanami/providers/db_logging.rb +22 -0
- data/lib/hanami/providers/inflector.rb +1 -1
- data/lib/hanami/providers/logger.rb +1 -1
- data/lib/hanami/providers/rack.rb +3 -3
- data/lib/hanami/providers/relations.rb +31 -0
- data/lib/hanami/providers/routes.rb +2 -14
- data/lib/hanami/rake_tasks.rb +8 -7
- data/lib/hanami/slice.rb +84 -4
- data/lib/hanami/version.rb +1 -1
- data/lib/hanami.rb +3 -0
- data/spec/integration/container/provider_environment_spec.rb +52 -0
- data/spec/integration/db/auto_registration_spec.rb +39 -0
- data/spec/integration/db/commands_spec.rb +80 -0
- data/spec/integration/db/db_inflector_spec.rb +57 -0
- data/spec/integration/db/db_slices_spec.rb +332 -0
- data/spec/integration/db/db_spec.rb +245 -0
- data/spec/integration/db/gateways_spec.rb +320 -0
- data/spec/integration/db/logging_spec.rb +238 -0
- data/spec/integration/db/mappers_spec.rb +84 -0
- data/spec/integration/db/provider_config_spec.rb +88 -0
- data/spec/integration/db/provider_spec.rb +35 -0
- data/spec/integration/db/relations_spec.rb +60 -0
- data/spec/integration/db/repo_spec.rb +215 -0
- data/spec/integration/db/slices_importing_from_parent.rb +130 -0
- data/spec/integration/slices/slice_configuration_spec.rb +4 -4
- data/spec/support/app_integration.rb +3 -0
- data/spec/unit/hanami/config/db_spec.rb +38 -0
- data/spec/unit/hanami/config/router_spec.rb +1 -1
- data/spec/unit/hanami/helpers/form_helper_spec.rb +35 -4
- data/spec/unit/hanami/providers/db/config/default_config_spec.rb +100 -0
- data/spec/unit/hanami/providers/db/config_spec.rb +156 -0
- data/spec/unit/hanami/slice_spec.rb +32 -0
- data/spec/unit/hanami/version_spec.rb +1 -1
- metadata +72 -20
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe "DB / Provider / Config", :app_integration do
|
4
|
+
before do
|
5
|
+
@env = ENV.to_h
|
6
|
+
allow(Hanami::Env).to receive(:loaded?).and_return(false)
|
7
|
+
end
|
8
|
+
|
9
|
+
after do
|
10
|
+
ENV.replace(@env)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "default config" do
|
14
|
+
it "provides default plugins and extensions" do
|
15
|
+
with_tmp_directory(Dir.mktmpdir) do
|
16
|
+
write "config/app.rb", <<~RUBY
|
17
|
+
require "hanami"
|
18
|
+
|
19
|
+
module TestApp
|
20
|
+
class App < Hanami::App
|
21
|
+
end
|
22
|
+
end
|
23
|
+
RUBY
|
24
|
+
|
25
|
+
write "config/db/.keep", ""
|
26
|
+
|
27
|
+
ENV["DATABASE_URL"] = "sqlite::memory"
|
28
|
+
|
29
|
+
require "hanami/prepare"
|
30
|
+
|
31
|
+
Hanami.app.prepare :db
|
32
|
+
|
33
|
+
plugins = Hanami.app["db.config"].setup.plugins
|
34
|
+
expect(plugins).to match [
|
35
|
+
an_object_satisfying {
|
36
|
+
_1.name == :instrumentation && _1.type == :relation &&
|
37
|
+
_1.config.notifications == Hanami.app["notifications"]
|
38
|
+
},
|
39
|
+
an_object_satisfying { _1.name == :auto_restrictions && _1.type == :relation }
|
40
|
+
]
|
41
|
+
|
42
|
+
extensions = Hanami.app["db.gateway"].options[:extensions]
|
43
|
+
expect(extensions).to eq [:caller_logging, :error_sql, :sql_comments]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "evaluates plugin config blocks in the context of the provider" do
|
49
|
+
with_tmp_directory(Dir.mktmpdir) do
|
50
|
+
write "config/app.rb", <<~RUBY
|
51
|
+
require "hanami"
|
52
|
+
|
53
|
+
module TestApp
|
54
|
+
class App < Hanami::App
|
55
|
+
end
|
56
|
+
end
|
57
|
+
RUBY
|
58
|
+
|
59
|
+
write "config/providers/db.rb", <<~RUBY
|
60
|
+
Hanami.app.configure_provider :db do
|
61
|
+
config.adapter :sql do |a|
|
62
|
+
a.skip_defaults :plugins
|
63
|
+
|
64
|
+
a.plugin relations: :instrumentation do |plugin|
|
65
|
+
plugin.notifications = target["custom_notifications"]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
RUBY
|
70
|
+
|
71
|
+
write "app/custom_notifications.rb", <<~RUBY
|
72
|
+
module TestApp
|
73
|
+
class CustomNotifications
|
74
|
+
end
|
75
|
+
end
|
76
|
+
RUBY
|
77
|
+
|
78
|
+
ENV["DATABASE_URL"] = "sqlite::memory"
|
79
|
+
|
80
|
+
require "hanami/prepare"
|
81
|
+
|
82
|
+
Hanami.app.prepare :db
|
83
|
+
|
84
|
+
plugin = Hanami.app["db.config"].setup.plugins.find { _1.name == :instrumentation }
|
85
|
+
expect(plugin.config.notifications).to be_an_instance_of TestApp::CustomNotifications
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe "DB / Provider", :app_integration do
|
4
|
+
before do
|
5
|
+
@env = ENV.to_h
|
6
|
+
allow(Hanami::Env).to receive(:loaded?).and_return(false)
|
7
|
+
end
|
8
|
+
|
9
|
+
after do
|
10
|
+
ENV.replace(@env)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "is registered when only a config/db/ dir exists" do
|
14
|
+
with_tmp_directory(Dir.mktmpdir) do
|
15
|
+
write "config/app.rb", <<~RUBY
|
16
|
+
require "hanami"
|
17
|
+
|
18
|
+
module TestApp
|
19
|
+
class App < Hanami::App
|
20
|
+
end
|
21
|
+
end
|
22
|
+
RUBY
|
23
|
+
|
24
|
+
write "config/db/.keep", ""
|
25
|
+
|
26
|
+
ENV["DATABASE_URL"] = "sqlite::memory"
|
27
|
+
|
28
|
+
require "hanami/prepare"
|
29
|
+
|
30
|
+
Hanami.app.prepare :db
|
31
|
+
|
32
|
+
expect(Hanami.app["db.gateway"]).to be
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe "DB / Relations", :app_integration do
|
4
|
+
before do
|
5
|
+
@env = ENV.to_h
|
6
|
+
allow(Hanami::Env).to receive(:loaded?).and_return(false)
|
7
|
+
end
|
8
|
+
|
9
|
+
after do
|
10
|
+
ENV.replace(@env)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "registers nested relations" do
|
14
|
+
with_tmp_directory(@dir = Dir.mktmpdir) do
|
15
|
+
write "config/app.rb", <<~RUBY
|
16
|
+
require "hanami"
|
17
|
+
|
18
|
+
module TestApp
|
19
|
+
class App < Hanami::App
|
20
|
+
config.logger.stream = File::NULL
|
21
|
+
end
|
22
|
+
end
|
23
|
+
RUBY
|
24
|
+
|
25
|
+
write "app/relations/nested/posts.rb", <<~RUBY
|
26
|
+
module TestApp
|
27
|
+
module Relations
|
28
|
+
module Nested
|
29
|
+
class Posts < Hanami::DB::Relation
|
30
|
+
schema :posts, infer: true
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
RUBY
|
36
|
+
|
37
|
+
ENV["DATABASE_URL"] = "sqlite::memory"
|
38
|
+
|
39
|
+
require "hanami/prepare"
|
40
|
+
|
41
|
+
Hanami.app.prepare :db
|
42
|
+
|
43
|
+
# Manually run a migration and add a test record
|
44
|
+
gateway = TestApp::App["db.gateway"]
|
45
|
+
migration = gateway.migration do
|
46
|
+
change do
|
47
|
+
create_table :posts do
|
48
|
+
primary_key :id
|
49
|
+
column :title, :text
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
migration.apply(gateway, :up)
|
54
|
+
gateway.connection.execute("INSERT INTO posts (title) VALUES ('Hi from nested relation')")
|
55
|
+
|
56
|
+
post = TestApp::App["relations.posts"].to_a[0]
|
57
|
+
expect(post[:title]).to eq "Hi from nested relation"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,215 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe "DB / Repo", :app_integration do
|
4
|
+
before do
|
5
|
+
@env = ENV.to_h
|
6
|
+
allow(Hanami::Env).to receive(:loaded?).and_return(false)
|
7
|
+
end
|
8
|
+
|
9
|
+
after do
|
10
|
+
ENV.replace(@env)
|
11
|
+
end
|
12
|
+
|
13
|
+
specify "repos have a root inferred from their name, or can set their own" do
|
14
|
+
with_tmp_directory(Dir.mktmpdir) do
|
15
|
+
write "config/app.rb", <<~RUBY
|
16
|
+
require "hanami"
|
17
|
+
|
18
|
+
module TestApp
|
19
|
+
class App < Hanami::App
|
20
|
+
end
|
21
|
+
end
|
22
|
+
RUBY
|
23
|
+
|
24
|
+
write "app/repo.rb", <<~RUBY
|
25
|
+
module TestApp
|
26
|
+
class Repo < Hanami::DB::Repo
|
27
|
+
end
|
28
|
+
end
|
29
|
+
RUBY
|
30
|
+
|
31
|
+
write "app/relations/posts.rb", <<~RUBY
|
32
|
+
module TestApp
|
33
|
+
module Relations
|
34
|
+
class Posts < Hanami::DB::Relation
|
35
|
+
schema :posts, infer: true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
RUBY
|
40
|
+
|
41
|
+
write "app/repos/post_repo.rb", <<~RUBY
|
42
|
+
module TestApp
|
43
|
+
module Repos
|
44
|
+
class PostRepo < Repo
|
45
|
+
def get(id)
|
46
|
+
posts.by_pk(id).one!
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
RUBY
|
52
|
+
|
53
|
+
write "app/repos/no_implicit_root_relation_repo.rb", <<~RUBY
|
54
|
+
module TestApp
|
55
|
+
module Repos
|
56
|
+
class NoImplicitRootRelationRepo < Repo
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
RUBY
|
61
|
+
|
62
|
+
write "app/repos/explicit_root_relation_repo.rb", <<~RUBY
|
63
|
+
module TestApp
|
64
|
+
module Repos
|
65
|
+
class ExplicitRootRelationRepo < Repo[:posts]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
RUBY
|
70
|
+
|
71
|
+
ENV["DATABASE_URL"] = "sqlite::memory"
|
72
|
+
|
73
|
+
require "hanami/prepare"
|
74
|
+
|
75
|
+
Hanami.app.prepare :db
|
76
|
+
|
77
|
+
# Manually run a migration and add a test record
|
78
|
+
gateway = Hanami.app["db.gateway"]
|
79
|
+
migration = gateway.migration do
|
80
|
+
change do
|
81
|
+
# drop_table? :posts
|
82
|
+
create_table :posts do
|
83
|
+
primary_key :id
|
84
|
+
column :title, :text, null: false
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
migration.apply(gateway, :up)
|
89
|
+
gateway.connection.execute("INSERT INTO posts (title) VALUES ('Together breakfast')")
|
90
|
+
|
91
|
+
# Repos use a matching root relation automatically
|
92
|
+
repo = Hanami.app["repos.post_repo"]
|
93
|
+
expect(repo.get(1).title).to eq "Together breakfast"
|
94
|
+
expect(repo.root).to eql Hanami.app["relations.posts"]
|
95
|
+
|
96
|
+
# Non-matching repos still work, just with no root relation
|
97
|
+
repo = Hanami.app["repos.no_implicit_root_relation_repo"]
|
98
|
+
expect(repo.root).to be nil
|
99
|
+
|
100
|
+
# Repos can provide an explicit root relation
|
101
|
+
repo = Hanami.app["repos.explicit_root_relation_repo"]
|
102
|
+
expect(repo.root).to eql Hanami.app["relations.posts"]
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
specify "repos use relations and structs only from their own slice" do
|
107
|
+
with_tmp_directory(Dir.mktmpdir) do
|
108
|
+
write "config/app.rb", <<~RUBY
|
109
|
+
require "hanami"
|
110
|
+
|
111
|
+
module TestApp
|
112
|
+
class App < Hanami::App
|
113
|
+
end
|
114
|
+
end
|
115
|
+
RUBY
|
116
|
+
|
117
|
+
ENV["DATABASE_URL"] = "sqlite::memory"
|
118
|
+
|
119
|
+
write "slices/admin/db/struct.rb", <<~RUBY
|
120
|
+
module Admin
|
121
|
+
module DB
|
122
|
+
class Struct < Hanami::DB::Struct
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
RUBY
|
127
|
+
|
128
|
+
write "slices/admin/relations/posts.rb", <<~RUBY
|
129
|
+
module Admin
|
130
|
+
module Relations
|
131
|
+
class Posts < Hanami::DB::Relation
|
132
|
+
schema :posts, infer: true
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
RUBY
|
137
|
+
|
138
|
+
write "slices/admin/repo.rb", <<~RUBY
|
139
|
+
module Admin
|
140
|
+
class Repo < Hanami::DB::Repo
|
141
|
+
end
|
142
|
+
end
|
143
|
+
RUBY
|
144
|
+
|
145
|
+
write "slices/admin/repos/post_repo.rb", <<~RUBY
|
146
|
+
module Admin
|
147
|
+
module Repos
|
148
|
+
class PostRepo < Repo
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
RUBY
|
153
|
+
|
154
|
+
write "slices/admin/structs/post.rb", <<~RUBY
|
155
|
+
module Admin
|
156
|
+
module Structs
|
157
|
+
class Post < DB::Struct
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
RUBY
|
162
|
+
|
163
|
+
write "slices/main/relations/posts.rb", <<~RUBY
|
164
|
+
module Main
|
165
|
+
module Relations
|
166
|
+
class Posts < Hanami::DB::Relation
|
167
|
+
schema :posts, infer: true
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
RUBY
|
172
|
+
|
173
|
+
write "slices/main/repo.rb", <<~RUBY
|
174
|
+
module Main
|
175
|
+
class Repo < Hanami::DB::Repo
|
176
|
+
end
|
177
|
+
end
|
178
|
+
RUBY
|
179
|
+
|
180
|
+
write "slices/main/repos/post_repo.rb", <<~RUBY
|
181
|
+
module Main
|
182
|
+
module Repos
|
183
|
+
class PostRepo < Repo
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
RUBY
|
188
|
+
|
189
|
+
require "hanami/prepare"
|
190
|
+
|
191
|
+
Admin::Slice.prepare :db
|
192
|
+
|
193
|
+
# Manually run a migration
|
194
|
+
gateway = Admin::Slice["db.gateway"]
|
195
|
+
migration = gateway.migration do
|
196
|
+
change do
|
197
|
+
# drop_table? :posts
|
198
|
+
create_table :posts do
|
199
|
+
primary_key :id
|
200
|
+
column :title, :text, null: false
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
migration.apply(gateway, :up)
|
205
|
+
gateway.connection.execute("INSERT INTO posts (title) VALUES ('Together breakfast')")
|
206
|
+
|
207
|
+
expect(Admin::Slice["repos.post_repo"].posts).to eql Admin::Slice["relations.posts"]
|
208
|
+
expect(Admin::Slice["repos.post_repo"].posts.by_pk(1).one!.class).to be < Admin::Structs::Post
|
209
|
+
|
210
|
+
expect(Main::Slice["repos.post_repo"].posts).to eql Main::Slice["relations.posts"]
|
211
|
+
# Slice struct namespace used even when no concrete struct classes are defined
|
212
|
+
expect(Main::Slice["repos.post_repo"].posts.by_pk(1).one!.class).to be < Main::Structs::Post
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe "DB / Slices / Importing from app", :app_integration do
|
4
|
+
before do
|
5
|
+
@env = ENV.to_h
|
6
|
+
allow(Hanami::Env).to receive(:loaded?).and_return(false)
|
7
|
+
end
|
8
|
+
|
9
|
+
after do
|
10
|
+
ENV.replace(@env)
|
11
|
+
end
|
12
|
+
|
13
|
+
specify "app DB components do not import into slices by default" do
|
14
|
+
with_tmp_directory(Dir.mktmpdir) do
|
15
|
+
write "config/app.rb", <<~RUBY
|
16
|
+
require "hanami"
|
17
|
+
|
18
|
+
module TestApp
|
19
|
+
class App < Hanami::App
|
20
|
+
end
|
21
|
+
end
|
22
|
+
RUBY
|
23
|
+
|
24
|
+
write "app/relations/posts.rb", <<~RUBY
|
25
|
+
module TestApp
|
26
|
+
module Relations
|
27
|
+
class Posts < Hanami::DB::Relation
|
28
|
+
schema :posts, infer: true
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
RUBY
|
33
|
+
|
34
|
+
write "slices/admin/.keep", ""
|
35
|
+
|
36
|
+
require "hanami/prepare"
|
37
|
+
|
38
|
+
expect { Admin::Slice.start :db }.to raise_error Dry::System::ProviderNotFoundError
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
specify "importing app DB components into slices via config.db.import_from_parent = true" do
|
43
|
+
with_tmp_directory(Dir.mktmpdir) do
|
44
|
+
write "config/app.rb", <<~RUBY
|
45
|
+
require "hanami"
|
46
|
+
|
47
|
+
module TestApp
|
48
|
+
class App < Hanami::App
|
49
|
+
config.db.import_from_parent = true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
RUBY
|
53
|
+
|
54
|
+
write "app/relations/posts.rb", <<~RUBY
|
55
|
+
module TestApp
|
56
|
+
module Relations
|
57
|
+
class Posts < Hanami::DB::Relation
|
58
|
+
schema :posts, infer: true
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
RUBY
|
63
|
+
|
64
|
+
write "slices/admin/.keep", ""
|
65
|
+
|
66
|
+
ENV["DATABASE_URL"] = "sqlite::memory"
|
67
|
+
|
68
|
+
require "hanami/prepare"
|
69
|
+
|
70
|
+
Hanami.app.prepare :db
|
71
|
+
|
72
|
+
# Manually run a migration and add a test record
|
73
|
+
gateway = Hanami.app["db.gateway"]
|
74
|
+
migration = gateway.migration do
|
75
|
+
change do
|
76
|
+
# drop_table? :posts
|
77
|
+
create_table :posts do
|
78
|
+
primary_key :id
|
79
|
+
column :title, :text, null: false
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
migration.apply(gateway, :up)
|
84
|
+
gateway.connection.execute("INSERT INTO posts (title) VALUES ('Together breakfast')")
|
85
|
+
|
86
|
+
Admin::Slice.start :db
|
87
|
+
|
88
|
+
expect(Admin::Slice["db.rom"]).to be(Hanami.app["db.rom"])
|
89
|
+
expect(Admin::Slice["relations.posts"]).to be(Hanami.app["relations.posts"])
|
90
|
+
|
91
|
+
expect(Admin::Slice["relations.posts"].to_a).to eq [{id: 1, title: "Together breakfast"}]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
specify "disabling import of the DB components within a specific slice" do
|
96
|
+
with_tmp_directory(Dir.mktmpdir) do
|
97
|
+
write "config/app.rb", <<~RUBY
|
98
|
+
require "hanami"
|
99
|
+
|
100
|
+
module TestApp
|
101
|
+
class App < Hanami::App
|
102
|
+
config.db.import_from_parent = true
|
103
|
+
end
|
104
|
+
end
|
105
|
+
RUBY
|
106
|
+
|
107
|
+
write "config/slices/admin.rb", <<~RUBY
|
108
|
+
module Admin
|
109
|
+
class Slice < Hanami::Slice
|
110
|
+
config.db.import_from_parent = false
|
111
|
+
end
|
112
|
+
end
|
113
|
+
RUBY
|
114
|
+
|
115
|
+
write "app/relations/posts.rb", <<~RUBY
|
116
|
+
module TestApp
|
117
|
+
module Relations
|
118
|
+
class Posts < Hanami::DB::Relation
|
119
|
+
schema :posts, infer: true
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
RUBY
|
124
|
+
|
125
|
+
require "hanami/prepare"
|
126
|
+
|
127
|
+
expect { Admin::Slice.start :db }.to raise_error Dry::System::ProviderNotFoundError
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -12,7 +12,7 @@ RSpec.describe "Slices / Slice configuration", :app_integration do
|
|
12
12
|
class App < Hanami::App
|
13
13
|
config.logger.stream = StringIO.new
|
14
14
|
|
15
|
-
config.no_auto_register_paths
|
15
|
+
config.no_auto_register_paths = ["structs"]
|
16
16
|
end
|
17
17
|
end
|
18
18
|
RUBY
|
@@ -34,9 +34,9 @@ RSpec.describe "Slices / Slice configuration", :app_integration do
|
|
34
34
|
|
35
35
|
require "hanami/prepare"
|
36
36
|
|
37
|
-
expect(TestApp::App.config.no_auto_register_paths).to eq %w[
|
38
|
-
expect(Main::Slice.config.no_auto_register_paths).to eq %w[
|
39
|
-
expect(Search::Slice.config.no_auto_register_paths).to eq %w[
|
37
|
+
expect(TestApp::App.config.no_auto_register_paths).to eq %w[structs]
|
38
|
+
expect(Main::Slice.config.no_auto_register_paths).to eq %w[structs schemas]
|
39
|
+
expect(Search::Slice.config.no_auto_register_paths).to eq %w[structs]
|
40
40
|
end
|
41
41
|
end
|
42
42
|
end
|
@@ -118,6 +118,9 @@ RSpec.configure do |config|
|
|
118
118
|
Hanami.instance_variable_set(:@_bundled, {})
|
119
119
|
Hanami.remove_instance_variable(:@_app) if Hanami.instance_variable_defined?(:@_app)
|
120
120
|
|
121
|
+
# Clear cached DB gateways across slices
|
122
|
+
Hanami::Providers::DB.cache.clear
|
123
|
+
|
121
124
|
$LOAD_PATH.replace(@load_paths)
|
122
125
|
|
123
126
|
# Remove example-specific LOADED_FEATURES added when running each example
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "hanami/config"
|
4
|
+
|
5
|
+
RSpec.describe Hanami::Config, "#db" do
|
6
|
+
let(:config) { described_class.new(app_name: app_name, env: :development) }
|
7
|
+
let(:app_name) { "MyApp::App" }
|
8
|
+
|
9
|
+
subject(:db) { config.db }
|
10
|
+
|
11
|
+
context "hanami-router is bundled" do
|
12
|
+
it "is a full router configuration" do
|
13
|
+
is_expected.to be_an_instance_of(Hanami::Config::DB)
|
14
|
+
|
15
|
+
is_expected.to respond_to(:import_from_parent)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "can be finalized" do
|
19
|
+
is_expected.to respond_to(:finalize!)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "hanami-db is not bundled" do
|
24
|
+
before do
|
25
|
+
allow(Hanami).to receive(:bundled?).and_call_original
|
26
|
+
allow(Hanami).to receive(:bundled?).with("hanami-db").and_return(false)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "does not expose any settings" do
|
30
|
+
is_expected.to be_an_instance_of(Hanami::Config::NullConfig)
|
31
|
+
is_expected.not_to respond_to(:import_from_parent)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "can be finalized" do
|
35
|
+
is_expected.to respond_to(:finalize!)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -29,7 +29,7 @@ RSpec.describe Hanami::Config, "#router" do
|
|
29
29
|
context "hanami-router is not bundled" do
|
30
30
|
before do
|
31
31
|
allow(Hanami).to receive(:bundled?).and_call_original
|
32
|
-
|
32
|
+
allow(Hanami).to receive(:bundled?).with("hanami-router").and_return(false)
|
33
33
|
end
|
34
34
|
|
35
35
|
it "does not expose any settings" do
|
@@ -393,6 +393,29 @@ RSpec.describe Hanami::Helpers::FormHelper do
|
|
393
393
|
|
394
394
|
expect(html).to eq_html(expected)
|
395
395
|
end
|
396
|
+
|
397
|
+
context "with base name" do
|
398
|
+
let(:params) { {book: {categories: [{name: "foo"}, {name: "bar"}]}} }
|
399
|
+
|
400
|
+
it "renders" do
|
401
|
+
html = render(<<~ERB)
|
402
|
+
<%= form_for("book", "/books") do |f| %>
|
403
|
+
<% f.fields_for_collection "categories" do |fa| %>
|
404
|
+
<%= fa.text_field :name %>
|
405
|
+
<% end %>
|
406
|
+
<% end %>
|
407
|
+
ERB
|
408
|
+
|
409
|
+
expected = <<~HTML
|
410
|
+
<form action="/books" accept-charset="utf-8" method="POST">
|
411
|
+
<input type="text" name="book[categories][][name]" id="book-categories-0-name" value="foo">
|
412
|
+
<input type="text" name="book[categories][][name]" id="book-categories-1-name" value="bar">
|
413
|
+
</form>
|
414
|
+
HTML
|
415
|
+
|
416
|
+
expect(html).to eq_html(expected)
|
417
|
+
end
|
418
|
+
end
|
396
419
|
end
|
397
420
|
|
398
421
|
describe "#label" do
|
@@ -404,6 +427,14 @@ RSpec.describe Hanami::Helpers::FormHelper do
|
|
404
427
|
expect(html).to include %(<label for="book-free-shipping">Free shipping</label>)
|
405
428
|
end
|
406
429
|
|
430
|
+
it "accepts a symbol" do
|
431
|
+
html = form_for("/books") do |f|
|
432
|
+
f.label :free_shipping
|
433
|
+
end
|
434
|
+
|
435
|
+
expect(html).to include %(<label for="free-shipping">Free shipping</label>)
|
436
|
+
end
|
437
|
+
|
407
438
|
it "accepts a string as custom content" do
|
408
439
|
html = form_for("/books") do |f|
|
409
440
|
f.label "Free Shipping!", for: "book.free_shipping"
|
@@ -2628,7 +2659,7 @@ RSpec.describe Hanami::Helpers::FormHelper do
|
|
2628
2659
|
f.select "book.store", option_values, options: {prompt: "Select a store"}
|
2629
2660
|
end
|
2630
2661
|
|
2631
|
-
expect(html).to include %(<select name="book[store]" id="book-store"><option
|
2662
|
+
expect(html).to include %(<select name="book[store]" id="book-store"><option>Select a store</option><option value="it">Italy</option><option value="us">United States</option></select>)
|
2632
2663
|
end
|
2633
2664
|
|
2634
2665
|
it "allows blank string" do
|
@@ -2636,7 +2667,7 @@ RSpec.describe Hanami::Helpers::FormHelper do
|
|
2636
2667
|
f.select "book.store", option_values, options: {prompt: ""}
|
2637
2668
|
end
|
2638
2669
|
|
2639
|
-
expect(html).to include %(<select name="book[store]" id="book-store"><option
|
2670
|
+
expect(html).to include %(<select name="book[store]" id="book-store"><option></option><option value="it">Italy</option><option value="us">United States</option></select>)
|
2640
2671
|
end
|
2641
2672
|
|
2642
2673
|
context "with values" do
|
@@ -2648,7 +2679,7 @@ RSpec.describe Hanami::Helpers::FormHelper do
|
|
2648
2679
|
f.select "book.store", option_values, options: {prompt: "Select a store"}
|
2649
2680
|
end
|
2650
2681
|
|
2651
|
-
expect(html).to include %(<select name="book[store]" id="book-store"><option
|
2682
|
+
expect(html).to include %(<select name="book[store]" id="book-store"><option>Select a store</option><option value="it" selected="selected">Italy</option><option value="us">United States</option></select>)
|
2652
2683
|
end
|
2653
2684
|
end
|
2654
2685
|
|
@@ -2662,7 +2693,7 @@ RSpec.describe Hanami::Helpers::FormHelper do
|
|
2662
2693
|
f.select "book.store", option_values, options: {prompt: "Select a store"}
|
2663
2694
|
end
|
2664
2695
|
|
2665
|
-
expect(html).to include %(<select name="book[store]" id="book-store"><option
|
2696
|
+
expect(html).to include %(<select name="book[store]" id="book-store"><option>Select a store</option><option value="it" selected="selected">Italy</option><option value="us">United States</option></select>)
|
2666
2697
|
end
|
2667
2698
|
end
|
2668
2699
|
|