hanami 2.0.0.beta4 → 2.0.0.rc1

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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/hanami.gemspec +8 -7
  4. data/lib/hanami/app.rb +47 -36
  5. data/lib/hanami/assets/app_config.rb +7 -15
  6. data/lib/hanami/assets/config.rb +5 -6
  7. data/lib/hanami/config/actions/content_security_policy.rb +1 -1
  8. data/lib/hanami/config/actions/cookies.rb +27 -0
  9. data/lib/hanami/config/actions/sessions.rb +42 -5
  10. data/lib/hanami/config/actions.rb +81 -17
  11. data/lib/hanami/config/logger.rb +112 -23
  12. data/lib/hanami/config/router.rb +0 -1
  13. data/lib/hanami/config/views.rb +6 -10
  14. data/lib/hanami/config.rb +235 -73
  15. data/lib/hanami/constants.rb +4 -0
  16. data/lib/hanami/errors.rb +17 -0
  17. data/lib/hanami/extensions/action/slice_configured_action.rb +9 -5
  18. data/lib/hanami/extensions/action.rb +59 -7
  19. data/lib/hanami/extensions/view/context.rb +3 -4
  20. data/lib/hanami/extensions/view/slice_configured_view.rb +4 -4
  21. data/lib/hanami/extensions/view.rb +7 -5
  22. data/lib/hanami/providers/inflector.rb +6 -0
  23. data/lib/hanami/providers/logger.rb +8 -0
  24. data/lib/hanami/providers/rack.rb +12 -0
  25. data/lib/hanami/providers/routes.rb +14 -4
  26. data/lib/hanami/routes.rb +36 -1
  27. data/lib/hanami/settings/env_store.rb +1 -1
  28. data/lib/hanami/settings.rb +102 -36
  29. data/lib/hanami/slice/router.rb +38 -16
  30. data/lib/hanami/slice/routing/middleware/stack.rb +66 -42
  31. data/lib/hanami/slice/routing/resolver.rb +10 -17
  32. data/lib/hanami/slice/view_name_inferrer.rb +1 -1
  33. data/lib/hanami/slice.rb +553 -14
  34. data/lib/hanami/slice_registrar.rb +20 -15
  35. data/lib/hanami/version.rb +2 -3
  36. data/lib/hanami/web/rack_logger.rb +14 -4
  37. data/lib/hanami.rb +122 -23
  38. data/spec/integration/action/csrf_protection_spec.rb +1 -1
  39. data/spec/integration/container/application_routes_helper_spec.rb +3 -1
  40. data/spec/integration/container/provider_lifecycle_spec.rb +61 -0
  41. data/spec/integration/container/standard_providers/rack_provider_spec.rb +44 -0
  42. data/spec/integration/container/{standard_bootable_components_spec.rb → standard_providers_spec.rb} +3 -3
  43. data/spec/integration/rack_app/body_parser_spec.rb +3 -0
  44. data/spec/integration/rack_app/middleware_spec.rb +427 -3
  45. data/spec/integration/rack_app/non_booted_rack_app_spec.rb +2 -1
  46. data/spec/integration/rack_app/rack_app_spec.rb +39 -11
  47. data/spec/integration/setup_spec.rb +4 -4
  48. data/spec/integration/slices/external_slice_spec.rb +2 -1
  49. data/spec/integration/slices/slice_configuration_spec.rb +3 -1
  50. data/spec/integration/slices/slice_loading_spec.rb +4 -4
  51. data/spec/integration/slices/slice_routing_spec.rb +4 -3
  52. data/spec/integration/slices_spec.rb +100 -0
  53. data/spec/isolation/hanami/boot/success_spec.rb +1 -1
  54. data/spec/support/app_integration.rb +2 -10
  55. data/spec/unit/hanami/config/actions/content_security_policy_spec.rb +7 -7
  56. data/spec/unit/hanami/config/actions/default_values_spec.rb +1 -1
  57. data/spec/unit/hanami/config/actions/sessions_spec.rb +1 -3
  58. data/spec/unit/hanami/config/actions_spec.rb +1 -12
  59. data/spec/unit/hanami/config/logger_spec.rb +38 -55
  60. data/spec/unit/hanami/config/router_spec.rb +1 -1
  61. data/spec/unit/hanami/config/views_spec.rb +3 -13
  62. data/spec/unit/hanami/settings_spec.rb +1 -1
  63. data/spec/unit/hanami/slice_configurable_spec.rb +5 -5
  64. data/spec/unit/hanami/slice_spec.rb +32 -0
  65. data/spec/unit/hanami/version_spec.rb +1 -1
  66. data/spec/unit/hanami/web/rack_logger_spec.rb +13 -2
  67. metadata +54 -45
  68. data/lib/hanami/config/sessions.rb +0 -50
  69. data/spec/unit/hanami/config_spec.rb +0 -43
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rack/test"
4
+ require "stringio"
4
5
 
5
6
  RSpec.describe "Hanami web app", :app_integration do
6
7
  include Rack::Test::Methods
@@ -50,7 +51,7 @@ RSpec.describe "Hanami web app", :app_integration do
50
51
 
51
52
  module TestApp
52
53
  class App < Hanami::App
53
- config.logger.stream = File.new("/dev/null", "w")
54
+ config.logger.stream = StringIO.new
54
55
 
55
56
  config.middleware.use Middlewares::AppendOne
56
57
  config.middleware.use Middlewares::Prepare, before: Middlewares::AppendOne
@@ -101,7 +102,7 @@ RSpec.describe "Hanami web app", :app_integration do
101
102
 
102
103
  module TestApp
103
104
  class App < Hanami::App
104
- config.logger.stream = File.new("/dev/null", "w")
105
+ config.logger.stream = StringIO.new
105
106
  end
106
107
  end
107
108
  RUBY
@@ -164,7 +165,7 @@ RSpec.describe "Hanami web app", :app_integration do
164
165
  end
165
166
 
166
167
  class App < Hanami::App
167
- config.logger.stream = File.new("/dev/null", "w")
168
+ config.logger.stream = StringIO.new
168
169
 
169
170
  config.middleware.use(TestApp::TestMiddleware) { |env| env["tested"] = "yes" }
170
171
  end
@@ -234,4 +235,427 @@ RSpec.describe "Hanami web app", :app_integration do
234
235
  }.to raise_error(Hanami::UnsupportedMiddlewareSpecError)
235
236
  end
236
237
  end
238
+
239
+ context "with simple app" do
240
+ before do
241
+ write "config/app.rb", <<~RUBY
242
+ require "hanami"
243
+
244
+ module TestApp
245
+ class App < Hanami::App
246
+ config.logger.stream = File.new("/dev/null", "w")
247
+ end
248
+ end
249
+ RUBY
250
+
251
+ write "lib/test_app/middleware/authentication.rb", <<~RUBY
252
+ module TestApp
253
+ module Middleware
254
+ class Authentication
255
+ def self.inspect
256
+ "<Middleware::Auth>"
257
+ end
258
+
259
+ def initialize(app)
260
+ @app = app
261
+ end
262
+
263
+ def call(env)
264
+ env["AUTH_USER_ID"] = user_id = "23"
265
+ status, headers, body = @app.call(env)
266
+ headers["X-Auth-User-ID"] = user_id
267
+
268
+ [status, headers, body]
269
+ end
270
+ end
271
+ end
272
+ end
273
+ RUBY
274
+
275
+ write "config/routes.rb", <<~RUBY
276
+ require "test_app/middleware/authentication"
277
+
278
+ module TestApp
279
+ class Routes < Hanami::Routes
280
+ root to: ->(*) { [200, {"Content-Length" => "4"}, ["Home"]] }
281
+
282
+ slice :admin, at: "/admin" do
283
+ use TestApp::Middleware::Authentication
284
+
285
+ root to: "home.show"
286
+ end
287
+ end
288
+ end
289
+ RUBY
290
+
291
+ write "slices/admin/actions/home/show.rb", <<~RUBY
292
+ module Admin
293
+ module Actions
294
+ module Home
295
+ class Show < Hanami::Action
296
+ def handle(req, res)
297
+ res.body = "Hello from admin (User ID " + req.env['AUTH_USER_ID'] + ")"
298
+ end
299
+ end
300
+ end
301
+ end
302
+ end
303
+ RUBY
304
+
305
+ require "hanami/boot"
306
+ end
307
+
308
+ it "excludes root scope" do
309
+ get "/"
310
+
311
+ expect(last_response.status).to eq 200
312
+ expect(last_response.body).to eq "Home"
313
+ expect(last_response.headers).to_not have_key("X-Auth-User-ID")
314
+ end
315
+
316
+ it "excludes not found routes in root scope" do
317
+ get "/foo"
318
+
319
+ expect(last_response.status).to eq 404
320
+ expect(last_response.body).to eq "Not Found"
321
+ expect(last_response.headers).to_not have_key("X-Auth-User-ID")
322
+ end
323
+
324
+ context "within slice" do
325
+ it "uses Rack middleware" do
326
+ get "/admin"
327
+
328
+ expect(last_response.status).to eq 200
329
+ expect(last_response.body).to eq "Hello from admin (User ID 23)"
330
+ expect(last_response.headers).to have_key("X-Auth-User-ID")
331
+ end
332
+
333
+ it "uses Rack middleware for not found paths" do
334
+ get "/admin/users"
335
+
336
+ expect(last_response.status).to be(404)
337
+ expect(last_response.body).to eq "Not Found"
338
+ expect(last_response.headers).to have_key("X-Auth-User-ID")
339
+ end
340
+ end
341
+ end
342
+
343
+ context "with complex app" do
344
+ let(:app_modules) { %i[TestApp Admin APIV1] }
345
+
346
+ before do
347
+ write "config/app.rb", <<~RUBY
348
+ require "hanami"
349
+
350
+ module TestApp
351
+ class App < Hanami::App
352
+ config.logger.stream = File.new("/dev/null", "w")
353
+ end
354
+ end
355
+ RUBY
356
+
357
+ write "lib/test_app/middleware/elapsed.rb", <<~RUBY
358
+ module TestApp
359
+ module Middleware
360
+ class Elapsed
361
+ def self.inspect
362
+ "<Middleware::Elapsed>"
363
+ end
364
+
365
+ def initialize(app)
366
+ @app = app
367
+ end
368
+
369
+ def call(env)
370
+ with_time_instrumentation do
371
+ @app.call(env)
372
+ end
373
+ end
374
+
375
+ private
376
+
377
+ def with_time_instrumentation
378
+ starting = now
379
+ status, headers, body = yield
380
+ ending = now
381
+
382
+ headers["X-Elapsed"] = (ending - starting).round(5).to_s
383
+ [status, headers, body]
384
+ end
385
+
386
+ def now
387
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
388
+ end
389
+ end
390
+ end
391
+ end
392
+ RUBY
393
+
394
+ write "lib/test_app/middleware/authentication.rb", <<~RUBY
395
+ module TestApp
396
+ module Middleware
397
+ class Authentication
398
+ def self.inspect
399
+ "<Middleware::Auth>"
400
+ end
401
+
402
+ def initialize(app)
403
+ @app = app
404
+ end
405
+
406
+ def call(env)
407
+ env["AUTH_USER_ID"] = user_id = "23"
408
+ status, headers, body = @app.call(env)
409
+ headers["X-Auth-User-ID"] = user_id
410
+
411
+ [status, headers, body]
412
+ end
413
+ end
414
+ end
415
+ end
416
+ RUBY
417
+
418
+ write "lib/test_app/middleware/rate_limiter.rb", <<~RUBY
419
+ module TestApp
420
+ module Middleware
421
+ class RateLimiter
422
+ def self.inspect
423
+ "<Middleware::API::Limiter>"
424
+ end
425
+
426
+ def initialize(app)
427
+ @app = app
428
+ end
429
+
430
+ def call(env)
431
+ status, headers, body = @app.call(env)
432
+ headers["X-API-Rate-Limit-Quota"] = "4000"
433
+
434
+ [status, headers, body]
435
+ end
436
+ end
437
+ end
438
+ end
439
+ RUBY
440
+
441
+ write "lib/test_app/middleware/api_version.rb", <<~RUBY
442
+ module TestApp
443
+ module Middleware
444
+ class ApiVersion
445
+ def self.inspect
446
+ "<Middleware::API::Version>"
447
+ end
448
+
449
+ def initialize(app)
450
+ @app = app
451
+ end
452
+
453
+ def call(env)
454
+ status, headers, body = @app.call(env)
455
+ headers["X-API-Version"] = "1"
456
+
457
+ [status, headers, body]
458
+ end
459
+ end
460
+ end
461
+ end
462
+ RUBY
463
+
464
+ write "lib/test_app/middleware/api_deprecation.rb", <<~RUBY
465
+ module TestApp
466
+ module Middleware
467
+ class ApiDeprecation
468
+ def self.inspect
469
+ "<Middleware::API::Deprecation>"
470
+ end
471
+
472
+ def initialize(app)
473
+ @app = app
474
+ end
475
+
476
+ def call(env)
477
+ status, headers, body = @app.call(env)
478
+ headers["X-API-Deprecated"] = "API v1 is deprecated"
479
+
480
+ [status, headers, body]
481
+ end
482
+ end
483
+ end
484
+ end
485
+ RUBY
486
+
487
+ write "lib/test_app/middleware/scope_identifier.rb", <<~RUBY
488
+ module TestApp
489
+ module Middleware
490
+ class ScopeIdentifier
491
+ def self.inspect
492
+ "<Middleware::API::ScopeIdentifier>"
493
+ end
494
+
495
+ def initialize(app, scope)
496
+ @app = app
497
+ @scope = scope
498
+ end
499
+
500
+ def call(env)
501
+ status, header, body = @app.call(env)
502
+ header["X-Identifier-" + @scope] = "true"
503
+ [status, header, body]
504
+ end
505
+
506
+ def inspect
507
+ "Scope identifier: " + @scope.inspect
508
+ end
509
+ end
510
+ end
511
+ end
512
+ RUBY
513
+
514
+ write "config/routes.rb", <<~RUBY
515
+ require "test_app/middleware/elapsed"
516
+ require "test_app/middleware/authentication"
517
+ require "test_app/middleware/rate_limiter"
518
+ require "test_app/middleware/api_version"
519
+ require "test_app/middleware/api_deprecation"
520
+ require "test_app/middleware/scope_identifier"
521
+
522
+ module TestApp
523
+ class Routes < Hanami::Routes
524
+ use TestApp::Middleware::Elapsed
525
+ use TestApp::Middleware::ScopeIdentifier, "Root"
526
+ root to: ->(*) { [200, {"Content-Length" => "4"}, ["Home (complex app)"]] }
527
+
528
+ mount ->(*) { [200, {"Content-Length" => "7"}, ["Mounted"]] }, at: "/mounted"
529
+
530
+ slice :admin, at: "/admin" do
531
+ use TestApp::Middleware::Authentication
532
+ use TestApp::Middleware::ScopeIdentifier, "Admin"
533
+
534
+ root to: "home.show"
535
+ end
536
+
537
+ # Without leading slash
538
+ # See: https://github.com/hanami/api/issues/8
539
+ scope "api" do
540
+ use TestApp::Middleware::RateLimiter
541
+ use TestApp::Middleware::ScopeIdentifier, "API"
542
+
543
+ root to: ->(*) { [200, {"Content-Length" => "3"}, ["API"]] }
544
+
545
+ slice :api_v1, at: "/v1" do
546
+ use TestApp::Middleware::ApiVersion
547
+ use TestApp::Middleware::ApiDeprecation
548
+ use TestApp::Middleware::ScopeIdentifier, "API-V1"
549
+
550
+ root to: "home.show"
551
+ end
552
+ end
553
+ end
554
+ end
555
+ RUBY
556
+
557
+ write "slices/admin/actions/home/show.rb", <<~RUBY
558
+ module Admin
559
+ module Actions
560
+ module Home
561
+ class Show < Hanami::Action
562
+ def handle(req, res)
563
+ res.body = "Hello from admin (User ID " + req.env['AUTH_USER_ID'] + ")"
564
+ end
565
+ end
566
+ end
567
+ end
568
+ end
569
+ RUBY
570
+
571
+ write "slices/api_v1/actions/home/show.rb", <<~RUBY
572
+ module APIV1
573
+ module Actions
574
+ module Home
575
+ class Show < Hanami::Action
576
+ def handle(req, res)
577
+ res.body = "API v1"
578
+ end
579
+ end
580
+ end
581
+ end
582
+ end
583
+ RUBY
584
+
585
+ require "hanami/boot"
586
+ end
587
+
588
+ it "uses Rack middleware" do
589
+ get "/"
590
+
591
+ expect(last_response.status).to be(200)
592
+ expect(last_response.body).to eq("Home (complex app)")
593
+ expect(last_response.headers["X-Identifier-Root"]).to eq("true")
594
+ expect(last_response.headers).to have_key("X-Elapsed")
595
+ expect(last_response.headers).to_not have_key("X-Auth-User-ID")
596
+ expect(last_response.headers).to_not have_key("X-API-Rate-Limit-Quota")
597
+ expect(last_response.headers).to_not have_key("X-API-Version")
598
+ end
599
+
600
+ it "uses Rack middleware for other paths" do
601
+ get "/foo"
602
+
603
+ expect(last_response.status).to be(404)
604
+ expect(last_response.headers["X-Identifier-Root"]).to eq("true")
605
+ expect(last_response.headers).to have_key("X-Elapsed")
606
+ expect(last_response.headers).to_not have_key("X-Auth-User-ID")
607
+ expect(last_response.headers).to_not have_key("X-API-Rate-Limit-Quota")
608
+ expect(last_response.headers).to_not have_key("X-API-Version")
609
+ end
610
+
611
+ context "scoped" do
612
+ it "uses Rack middleware" do
613
+ get "/admin"
614
+
615
+ expect(last_response.status).to be(200)
616
+ expect(last_response.headers["X-Identifier-Admin"]).to eq("true")
617
+ expect(last_response.headers).to have_key("X-Elapsed")
618
+ expect(last_response.headers).to have_key("X-Auth-User-ID")
619
+ expect(last_response.headers).to_not have_key("X-API-Rate-Limit-Quota")
620
+ expect(last_response.headers).to_not have_key("X-API-Version")
621
+ end
622
+
623
+ it "uses Rack middleware for other paths" do
624
+ get "/admin/users"
625
+
626
+ expect(last_response.status).to be(404)
627
+ expect(last_response.headers["X-Identifier-Admin"]).to eq("true")
628
+ expect(last_response.headers).to have_key("X-Elapsed")
629
+ expect(last_response.headers).to have_key("X-Elapsed")
630
+ expect(last_response.headers).to have_key("X-Auth-User-ID")
631
+ expect(last_response.headers).to_not have_key("X-API-Rate-Limit-Quota")
632
+ expect(last_response.headers).to_not have_key("X-API-Version")
633
+ end
634
+
635
+ # See: https://github.com/hanami/api/issues/8
636
+ it "uses Rack middleware for scope w/o leading slash" do
637
+ get "/api"
638
+
639
+ expect(last_response.status).to be(200)
640
+ expect(last_response.headers["X-Identifier-Api"]).to eq("true")
641
+ expect(last_response.headers).to have_key("X-Elapsed")
642
+ expect(last_response.headers).to_not have_key("X-Auth-User-ID")
643
+ expect(last_response.headers).to have_key("X-API-Rate-Limit-Quota")
644
+ expect(last_response.headers).to_not have_key("X-API-Version")
645
+ end
646
+
647
+ # See: https://github.com/hanami/api/issues/8
648
+ it "uses Rack middleware for nested scope w/o leading slash" do
649
+ get "/api/v1"
650
+
651
+ expect(last_response.status).to be(200)
652
+ expect(last_response.headers["X-Identifier-API-V1"]).to eq("true")
653
+ expect(last_response.headers).to have_key("X-Elapsed")
654
+ expect(last_response.headers).to_not have_key("X-Auth-User-ID")
655
+ expect(last_response.headers).to have_key("X-API-Rate-Limit-Quota")
656
+ expect(last_response.headers).to have_key("X-API-Deprecated")
657
+ expect(last_response.headers["X-API-Version"]).to eq("1")
658
+ end
659
+ end
660
+ end
237
661
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rack/test"
4
+ require "stringio"
4
5
 
5
6
  RSpec.describe "Running a Rack app for a non-booted app", :app_integration do
6
7
  include Rack::Test::Methods
@@ -14,7 +15,7 @@ RSpec.describe "Running a Rack app for a non-booted app", :app_integration do
14
15
 
15
16
  module TestApp
16
17
  class App < Hanami::App
17
- config.logger.stream = File.new("/dev/null", "w")
18
+ config.logger.stream = StringIO.new
18
19
  end
19
20
  end
20
21
  RUBY
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rack/test"
4
+ require "stringio"
4
5
 
5
6
  RSpec.describe "Hanami web app", :app_integration do
6
7
  include Rack::Test::Methods
@@ -46,10 +47,25 @@ RSpec.describe "Hanami web app", :app_integration do
46
47
  end
47
48
  RUBY
48
49
 
50
+ write "app/actions/users/index.rb", <<~RUBY
51
+ module TestApp
52
+ module Actions
53
+ module Users
54
+ class Index < Hanami::Action
55
+ def handle(req, _resp)
56
+ raise StandardError, "OH NOEZ"
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ RUBY
63
+
49
64
  write "config/routes.rb", <<~RUBY
50
65
  module TestApp
51
66
  class Routes < Hanami::Routes
52
67
  root to: ->(env) { [200, {}, ["OK"]] }
68
+ get "/users", to: "users.index"
53
69
  end
54
70
  end
55
71
  RUBY
@@ -63,6 +79,14 @@ RSpec.describe "Hanami web app", :app_integration do
63
79
  logs = -> { Pathname(dir).join("test.log").realpath.read }
64
80
 
65
81
  expect(logs.()).to match %r{GET 200 \d+ms 127.0.0.1 /}
82
+
83
+ begin
84
+ get "/users"
85
+ rescue => e # rubocop:disable Style/RescueStandardError
86
+ raise unless e.to_s == "OH NOEZ"
87
+ end
88
+
89
+ expect(logs.()).to match %r{OH NOEZ}
66
90
  end
67
91
  end
68
92
 
@@ -109,7 +133,7 @@ RSpec.describe "Hanami web app", :app_integration do
109
133
 
110
134
  module TestApp
111
135
  class App < Hanami::App
112
- config.logger.stream = File.new("/dev/null", "w")
136
+ config.logger.stream = StringIO.new
113
137
  end
114
138
  end
115
139
  RUBY
@@ -214,7 +238,7 @@ RSpec.describe "Hanami web app", :app_integration do
214
238
 
215
239
  module TestApp
216
240
  class App < Hanami::App
217
- config.logger.stream = File.new("/dev/null", "w")
241
+ config.logger.stream = StringIO.new
218
242
  end
219
243
  end
220
244
  RUBY
@@ -279,7 +303,7 @@ RSpec.describe "Hanami web app", :app_integration do
279
303
 
280
304
  module TestApp
281
305
  class App < Hanami::App
282
- config.logger.stream = File.new("/dev/null", "w")
306
+ config.logger.stream = StringIO.new
283
307
  end
284
308
  end
285
309
  RUBY
@@ -372,8 +396,9 @@ RSpec.describe "Hanami web app", :app_integration do
372
396
  require "hanami/boot"
373
397
 
374
398
  expect { Hanami.app.rack_app }.to raise_error do |exception|
375
- expect(exception).to be_kind_of(Hanami::Slice::Routing::UnknownActionError)
376
- expect(exception.message).to include("missing.action")
399
+ expect(exception).to be_kind_of(Hanami::Routes::MissingActionError)
400
+ expect(exception.message).to include("Could not find action with key \"actions.missing.action\" in TestApp::App")
401
+ expect(exception.message).to match(%r{define the action class TestApp::Actions::Missing::Action.+actions/missing/action.rb})
377
402
  end
378
403
  end
379
404
  end
@@ -403,8 +428,9 @@ RSpec.describe "Hanami web app", :app_integration do
403
428
  require "hanami/boot"
404
429
 
405
430
  expect { Hanami.app.rack_app }.to raise_error do |exception|
406
- expect(exception).to be_kind_of(Hanami::Slice::Routing::UnknownActionError)
407
- expect(exception.message).to include("missing.action")
431
+ expect(exception).to be_kind_of(Hanami::Routes::MissingActionError)
432
+ expect(exception.message).to include("Could not find action with key \"actions.missing.action\" in Admin::Slice")
433
+ expect(exception.message).to match(%r{define the action class Admin::Actions::Missing::Action.+slices/admin/actions/missing/action.rb})
408
434
  end
409
435
  end
410
436
  end
@@ -433,8 +459,9 @@ RSpec.describe "Hanami web app", :app_integration do
433
459
  expect { Hanami.app.rack_app }.not_to raise_error
434
460
 
435
461
  expect { get "/missing" }.to raise_error do |exception|
436
- expect(exception).to be_kind_of(Hanami::Slice::Routing::UnknownActionError)
437
- expect(exception.message).to include("missing.action")
462
+ expect(exception).to be_kind_of(Hanami::Routes::MissingActionError)
463
+ expect(exception.message).to include("Could not find action with key \"actions.missing.action\" in TestApp::App")
464
+ expect(exception.message).to match(%r{define the action class TestApp::Actions::Missing::Action.+actions/missing/action.rb})
438
465
  end
439
466
  end
440
467
  end
@@ -466,8 +493,9 @@ RSpec.describe "Hanami web app", :app_integration do
466
493
  expect { Hanami.app.rack_app }.not_to raise_error
467
494
 
468
495
  expect { get "/admin/missing" }.to raise_error do |exception|
469
- expect(exception).to be_kind_of(Hanami::Slice::Routing::UnknownActionError)
470
- expect(exception.message).to include("missing.action")
496
+ expect(exception).to be_kind_of(Hanami::Routes::MissingActionError)
497
+ expect(exception.message).to include("Could not find action with key \"actions.missing.action\" in Admin::Slice")
498
+ expect(exception.message).to match(%r{define the action class Admin::Actions::Missing::Action.+slices/admin/actions/missing/action.rb})
471
499
  end
472
500
  end
473
501
  end
@@ -63,12 +63,12 @@ RSpec.describe "Hanami setup", :app_integration do
63
63
 
64
64
  with_tmp_directory(Dir.mktmpdir) do
65
65
  write "config/app.rb", <<~RUBY
66
- require "hanami"
66
+ require "hanami"
67
67
 
68
- module TestApp
69
- class App < Hanami::App
68
+ module TestApp
69
+ class App < Hanami::App
70
+ end
70
71
  end
71
- end
72
72
  RUBY
73
73
 
74
74
  expect { setup }.to change { Hanami.app? }.to true
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "rack/test"
4
+ require "stringio"
4
5
 
5
6
  RSpec.describe "Slices / External slices", :app_integration do
6
7
  include Rack::Test::Methods
@@ -14,7 +15,7 @@ RSpec.describe "Slices / External slices", :app_integration do
14
15
 
15
16
  module TestApp
16
17
  class App < Hanami::App
17
- config.logger.stream = File.new("/dev/null", "w")
18
+ config.logger.stream = StringIO.new
18
19
 
19
20
  require "external/slice"
20
21
  register_slice(:external, External::Slice)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "stringio"
4
+
3
5
  RSpec.describe "Slices / Slice configuration", :app_integration do
4
6
  specify "Slices receive a copy of the app configuration, and can make distinct modifications" do
5
7
  with_tmp_directory(Dir.mktmpdir) do
@@ -8,7 +10,7 @@ RSpec.describe "Slices / Slice configuration", :app_integration do
8
10
 
9
11
  module TestApp
10
12
  class App < Hanami::App
11
- config.logger.stream = File.new("/dev/null", "w")
13
+ config.logger.stream = StringIO.new
12
14
 
13
15
  config.no_auto_register_paths << "structs"
14
16
  end
@@ -3,7 +3,7 @@
3
3
  require "rack/test"
4
4
 
5
5
  RSpec.describe "Slices / Slice loading", :app_integration, :aggregate_failures do
6
- let(:app_modules) { %i[TestApp Admin Editorial Main Shop] }
6
+ let(:app_modules) { %i[TestApp Admin Main] }
7
7
 
8
8
  describe "loading specific slices with config.slices" do
9
9
  describe "setup app" do
@@ -48,7 +48,7 @@ RSpec.describe "Slices / Slice loading", :app_integration, :aggregate_failures d
48
48
 
49
49
  expect { Admin::Slice.register_slice :editorial }.not_to(change { Admin::Slice.slices.keys })
50
50
  expect { Admin::Slice.register_slice :shop }.to change { Admin::Slice.slices.keys }.to [:shop]
51
- expect(Shop::Slice).to be
51
+ expect(Admin::Shop::Slice).to be
52
52
  end
53
53
  end
54
54
  end
@@ -123,9 +123,9 @@ RSpec.describe "Slices / Slice loading", :app_integration, :aggregate_failures d
123
123
  expect(Admin::Slice.slices.keys).to eq [:shop]
124
124
 
125
125
  expect(Admin::Slice).to be
126
- expect(Shop::Slice).to be
126
+ expect(Admin::Shop::Slice).to be
127
127
 
128
- expect { Editorial }.to raise_error(NameError)
128
+ expect { Admin::Editorial }.to raise_error(NameError)
129
129
  expect { Main }.to raise_error(NameError)
130
130
  end
131
131
  end