hanami 2.1.0 → 2.2.0.beta1
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 +30 -6
 - data/FEATURES.md +1 -1
 - data/README.md +7 -7
 - data/hanami.gemspec +6 -6
 - data/lib/hanami/app.rb +6 -2
 - data/lib/hanami/config/actions.rb +1 -1
 - data/lib/hanami/config/assets.rb +1 -1
 - data/lib/hanami/config/db.rb +33 -0
 - data/lib/hanami/config/logger.rb +2 -2
 - data/lib/hanami/config.rb +37 -10
 - data/lib/hanami/extensions/db/repo.rb +103 -0
 - data/lib/hanami/extensions/view/context.rb +1 -1
 - data/lib/hanami/extensions/view/part.rb +1 -1
 - data/lib/hanami/extensions/view/slice_configured_helpers.rb +1 -1
 - data/lib/hanami/extensions.rb +4 -0
 - data/lib/hanami/helpers/assets_helper.rb +5 -5
 - data/lib/hanami/helpers/form_helper/form_builder.rb +4 -6
 - data/lib/hanami/middleware/public_errors_app.rb +2 -2
 - data/lib/hanami/provider_registrar.rb +26 -0
 - data/lib/hanami/providers/assets.rb +2 -20
 - data/lib/hanami/providers/db/adapter.rb +68 -0
 - data/lib/hanami/providers/db/adapters.rb +44 -0
 - data/lib/hanami/providers/db/config.rb +66 -0
 - data/lib/hanami/providers/db/sql_adapter.rb +80 -0
 - data/lib/hanami/providers/db.rb +203 -0
 - data/lib/hanami/providers/db_logging.rb +22 -0
 - data/lib/hanami/providers/rack.rb +3 -3
 - data/lib/hanami/providers/relations.rb +31 -0
 - data/lib/hanami/providers/routes.rb +1 -13
 - data/lib/hanami/rake_tasks.rb +9 -8
 - data/lib/hanami/settings.rb +3 -3
 - data/lib/hanami/slice.rb +90 -10
 - data/lib/hanami/version.rb +1 -1
 - data/lib/hanami/web/rack_logger.rb +3 -3
 - 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/db_inflector_spec.rb +57 -0
 - data/spec/integration/db/db_slices_spec.rb +327 -0
 - data/spec/integration/db/db_spec.rb +220 -0
 - data/spec/integration/db/logging_spec.rb +238 -0
 - data/spec/integration/db/provider_config_spec.rb +88 -0
 - data/spec/integration/db/provider_spec.rb +35 -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/integration/view/config/template_spec.rb +1 -1
 - data/spec/integration/view/context/request_spec.rb +1 -1
 - 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 +33 -2
 - data/spec/unit/hanami/providers/db/config/default_config_spec.rb +107 -0
 - data/spec/unit/hanami/providers/db/config_spec.rb +206 -0
 - data/spec/unit/hanami/slice_spec.rb +33 -1
 - data/spec/unit/hanami/version_spec.rb +1 -1
 - metadata +62 -20
 
| 
         @@ -0,0 +1,238 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            RSpec.describe "DB / Logging", :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 "logs SQL queries" 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 
     | 
    
         
            +
                  ENV["DATABASE_URL"] = "sqlite::memory"
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                  require "hanami/setup"
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  logger_stream = StringIO.new
         
     | 
| 
      
 39 
     | 
    
         
            +
                  Hanami.app.config.logger.stream = logger_stream
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                  require "hanami/prepare"
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                  Hanami.app.prepare :db
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                  # Manually run a migration and add a test record
         
     | 
| 
      
 46 
     | 
    
         
            +
                  gateway = Hanami.app["db.gateway"]
         
     | 
| 
      
 47 
     | 
    
         
            +
                  migration = gateway.migration do
         
     | 
| 
      
 48 
     | 
    
         
            +
                    change do
         
     | 
| 
      
 49 
     | 
    
         
            +
                      create_table :posts do
         
     | 
| 
      
 50 
     | 
    
         
            +
                        primary_key :id
         
     | 
| 
      
 51 
     | 
    
         
            +
                        column :title, :text, null: false
         
     | 
| 
      
 52 
     | 
    
         
            +
                      end
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                      create_table :authors do
         
     | 
| 
      
 55 
     | 
    
         
            +
                        primary_key :id
         
     | 
| 
      
 56 
     | 
    
         
            +
                      end
         
     | 
| 
      
 57 
     | 
    
         
            +
                    end
         
     | 
| 
      
 58 
     | 
    
         
            +
                  end
         
     | 
| 
      
 59 
     | 
    
         
            +
                  migration.apply(gateway, :up)
         
     | 
| 
      
 60 
     | 
    
         
            +
                  gateway.connection.execute("INSERT INTO posts (title) VALUES ('Together breakfast')")
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                  relation = Hanami.app["relations.posts"]
         
     | 
| 
      
 63 
     | 
    
         
            +
                  expect(relation.select(:title).to_a).to eq [{:title=>"Together breakfast"}]
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
                  logger_stream.rewind
         
     | 
| 
      
 66 
     | 
    
         
            +
                  log_lines = logger_stream.read.split("\n")
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                  expect(log_lines.length).to eq 1
         
     | 
| 
      
 69 
     | 
    
         
            +
                  expect(log_lines.first).to match /Loaded :sqlite in \d+ms SELECT `posts`.`title` FROM `posts` ORDER BY `posts`.`id`/
         
     | 
| 
      
 70 
     | 
    
         
            +
                end
         
     | 
| 
      
 71 
     | 
    
         
            +
              end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
              describe "slices sharing app db config" do
         
     | 
| 
      
 74 
     | 
    
         
            +
                it "logs SQL queries" do
         
     | 
| 
      
 75 
     | 
    
         
            +
                  with_tmp_directory(Dir.mktmpdir) do
         
     | 
| 
      
 76 
     | 
    
         
            +
                    write "config/app.rb", <<~RUBY
         
     | 
| 
      
 77 
     | 
    
         
            +
                      require "hanami"
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                      module TestApp
         
     | 
| 
      
 80 
     | 
    
         
            +
                        class App < Hanami::App
         
     | 
| 
      
 81 
     | 
    
         
            +
                        end
         
     | 
| 
      
 82 
     | 
    
         
            +
                      end
         
     | 
| 
      
 83 
     | 
    
         
            +
                    RUBY
         
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
                    write "config/providers/db.rb", <<~RUBY
         
     | 
| 
      
 86 
     | 
    
         
            +
                      Hanami.app.configure_provider :db do
         
     | 
| 
      
 87 
     | 
    
         
            +
                      end
         
     | 
| 
      
 88 
     | 
    
         
            +
                    RUBY
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                    ENV["DATABASE_URL"] = "sqlite::memory"
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                    write "slices/admin/relations/posts.rb", <<~RUBY
         
     | 
| 
      
 93 
     | 
    
         
            +
                      module Admin
         
     | 
| 
      
 94 
     | 
    
         
            +
                        module Relations
         
     | 
| 
      
 95 
     | 
    
         
            +
                          class Posts < Hanami::DB::Relation
         
     | 
| 
      
 96 
     | 
    
         
            +
                            schema :posts, infer: true
         
     | 
| 
      
 97 
     | 
    
         
            +
                          end
         
     | 
| 
      
 98 
     | 
    
         
            +
                        end
         
     | 
| 
      
 99 
     | 
    
         
            +
                      end
         
     | 
| 
      
 100 
     | 
    
         
            +
                    RUBY
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
                    write "slices/main/relations/posts.rb", <<~RUBY
         
     | 
| 
      
 103 
     | 
    
         
            +
                      module Main
         
     | 
| 
      
 104 
     | 
    
         
            +
                        module Relations
         
     | 
| 
      
 105 
     | 
    
         
            +
                          class Posts < Hanami::DB::Relation
         
     | 
| 
      
 106 
     | 
    
         
            +
                            schema :posts, infer: true
         
     | 
| 
      
 107 
     | 
    
         
            +
                          end
         
     | 
| 
      
 108 
     | 
    
         
            +
                        end
         
     | 
| 
      
 109 
     | 
    
         
            +
                      end
         
     | 
| 
      
 110 
     | 
    
         
            +
                    RUBY
         
     | 
| 
      
 111 
     | 
    
         
            +
             
     | 
| 
      
 112 
     | 
    
         
            +
                    require "hanami/setup"
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                    logger_stream = StringIO.new
         
     | 
| 
      
 115 
     | 
    
         
            +
                    Hanami.app.config.logger.stream = logger_stream
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
                    require "hanami/prepare"
         
     | 
| 
      
 118 
     | 
    
         
            +
             
     | 
| 
      
 119 
     | 
    
         
            +
                    Admin::Slice.prepare :db
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                    # Manually run a migration
         
     | 
| 
      
 122 
     | 
    
         
            +
                    gateway = Admin::Slice["db.gateway"]
         
     | 
| 
      
 123 
     | 
    
         
            +
                    migration = gateway.migration do
         
     | 
| 
      
 124 
     | 
    
         
            +
                      change do
         
     | 
| 
      
 125 
     | 
    
         
            +
                        create_table :posts do
         
     | 
| 
      
 126 
     | 
    
         
            +
                          primary_key :id
         
     | 
| 
      
 127 
     | 
    
         
            +
                          column :title, :text, null: false
         
     | 
| 
      
 128 
     | 
    
         
            +
                        end
         
     | 
| 
      
 129 
     | 
    
         
            +
                      end
         
     | 
| 
      
 130 
     | 
    
         
            +
                    end
         
     | 
| 
      
 131 
     | 
    
         
            +
                    migration.apply(gateway, :up)
         
     | 
| 
      
 132 
     | 
    
         
            +
                    gateway.connection.execute("INSERT INTO posts (title) VALUES ('Together breakfast')")
         
     | 
| 
      
 133 
     | 
    
         
            +
             
     | 
| 
      
 134 
     | 
    
         
            +
                    Hanami.app.boot
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                    # Booting the app will have the ROM schemas infer themself via some `PRAGMA` queries to the
         
     | 
| 
      
 137 
     | 
    
         
            +
                    # database, which themselves will emit logs. Clear those logs, since we want to focus on
         
     | 
| 
      
 138 
     | 
    
         
            +
                    # individual query logging in this test.
         
     | 
| 
      
 139 
     | 
    
         
            +
                    logger_stream.truncate(0)
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
                    relation = Admin::Slice["relations.posts"]
         
     | 
| 
      
 142 
     | 
    
         
            +
                    relation.select(:title).to_a
         
     | 
| 
      
 143 
     | 
    
         
            +
             
     | 
| 
      
 144 
     | 
    
         
            +
                    log_lines = logger_stream.string.split("\n")
         
     | 
| 
      
 145 
     | 
    
         
            +
                    expect(log_lines.length).to eq 1
         
     | 
| 
      
 146 
     | 
    
         
            +
                    expect(log_lines.last).to match /Loaded :sqlite in \d+ms SELECT `posts`.`title` FROM `posts` ORDER BY `posts`.`id`/
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
                    relation = Main::Slice["relations.posts"]
         
     | 
| 
      
 149 
     | 
    
         
            +
                    relation.select(:id).to_a
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                    log_lines = logger_stream.string.split("\n")
         
     | 
| 
      
 152 
     | 
    
         
            +
                    expect(log_lines.length).to eq 2
         
     | 
| 
      
 153 
     | 
    
         
            +
                    expect(log_lines.last).to match /Loaded :sqlite in \d+ms SELECT `posts`.`id` FROM `posts` ORDER BY `posts`.`id`/
         
     | 
| 
      
 154 
     | 
    
         
            +
                  end
         
     | 
| 
      
 155 
     | 
    
         
            +
                end
         
     | 
| 
      
 156 
     | 
    
         
            +
              end
         
     | 
| 
      
 157 
     | 
    
         
            +
             
     | 
| 
      
 158 
     | 
    
         
            +
              describe "slices with independent db config" do
         
     | 
| 
      
 159 
     | 
    
         
            +
                # This is the same test as above, except without the config/providers/db.rb file.
         
     | 
| 
      
 160 
     | 
    
         
            +
                it "logs SQL queries" do
         
     | 
| 
      
 161 
     | 
    
         
            +
                  with_tmp_directory(Dir.mktmpdir) do
         
     | 
| 
      
 162 
     | 
    
         
            +
                    write "config/app.rb", <<~RUBY
         
     | 
| 
      
 163 
     | 
    
         
            +
                      require "hanami"
         
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
      
 165 
     | 
    
         
            +
                      module TestApp
         
     | 
| 
      
 166 
     | 
    
         
            +
                        class App < Hanami::App
         
     | 
| 
      
 167 
     | 
    
         
            +
                        end
         
     | 
| 
      
 168 
     | 
    
         
            +
                      end
         
     | 
| 
      
 169 
     | 
    
         
            +
                    RUBY
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
                    ENV["DATABASE_URL"] = "sqlite::memory"
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
                    write "slices/admin/relations/posts.rb", <<~RUBY
         
     | 
| 
      
 174 
     | 
    
         
            +
                      module Admin
         
     | 
| 
      
 175 
     | 
    
         
            +
                        module Relations
         
     | 
| 
      
 176 
     | 
    
         
            +
                          class Posts < Hanami::DB::Relation
         
     | 
| 
      
 177 
     | 
    
         
            +
                            schema :posts, infer: true
         
     | 
| 
      
 178 
     | 
    
         
            +
                          end
         
     | 
| 
      
 179 
     | 
    
         
            +
                        end
         
     | 
| 
      
 180 
     | 
    
         
            +
                      end
         
     | 
| 
      
 181 
     | 
    
         
            +
                    RUBY
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
                    write "slices/main/relations/posts.rb", <<~RUBY
         
     | 
| 
      
 184 
     | 
    
         
            +
                      module Main
         
     | 
| 
      
 185 
     | 
    
         
            +
                        module Relations
         
     | 
| 
      
 186 
     | 
    
         
            +
                          class Posts < Hanami::DB::Relation
         
     | 
| 
      
 187 
     | 
    
         
            +
                            schema :posts, infer: true
         
     | 
| 
      
 188 
     | 
    
         
            +
                          end
         
     | 
| 
      
 189 
     | 
    
         
            +
                        end
         
     | 
| 
      
 190 
     | 
    
         
            +
                      end
         
     | 
| 
      
 191 
     | 
    
         
            +
                    RUBY
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
                    require "hanami/setup"
         
     | 
| 
      
 194 
     | 
    
         
            +
             
     | 
| 
      
 195 
     | 
    
         
            +
                    logger_stream = StringIO.new
         
     | 
| 
      
 196 
     | 
    
         
            +
                    Hanami.app.config.logger.stream = logger_stream
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
                    require "hanami/prepare"
         
     | 
| 
      
 199 
     | 
    
         
            +
             
     | 
| 
      
 200 
     | 
    
         
            +
                    Admin::Slice.prepare :db
         
     | 
| 
      
 201 
     | 
    
         
            +
             
     | 
| 
      
 202 
     | 
    
         
            +
                    # Manually run a migration
         
     | 
| 
      
 203 
     | 
    
         
            +
                    gateway = Admin::Slice["db.gateway"]
         
     | 
| 
      
 204 
     | 
    
         
            +
                    migration = gateway.migration do
         
     | 
| 
      
 205 
     | 
    
         
            +
                      change do
         
     | 
| 
      
 206 
     | 
    
         
            +
                        create_table :posts do
         
     | 
| 
      
 207 
     | 
    
         
            +
                          primary_key :id
         
     | 
| 
      
 208 
     | 
    
         
            +
                          column :title, :text, null: false
         
     | 
| 
      
 209 
     | 
    
         
            +
                        end
         
     | 
| 
      
 210 
     | 
    
         
            +
                      end
         
     | 
| 
      
 211 
     | 
    
         
            +
                    end
         
     | 
| 
      
 212 
     | 
    
         
            +
                    migration.apply(gateway, :up)
         
     | 
| 
      
 213 
     | 
    
         
            +
                    gateway.connection.execute("INSERT INTO posts (title) VALUES ('Together breakfast')")
         
     | 
| 
      
 214 
     | 
    
         
            +
             
     | 
| 
      
 215 
     | 
    
         
            +
                    Hanami.app.boot
         
     | 
| 
      
 216 
     | 
    
         
            +
             
     | 
| 
      
 217 
     | 
    
         
            +
                    # Booting the app will have the ROM schemas infer themself via some `PRAGMA` queries to the
         
     | 
| 
      
 218 
     | 
    
         
            +
                    # database, which themselves will emit logs. Clear those logs, since we want to focus on
         
     | 
| 
      
 219 
     | 
    
         
            +
                    # individual query logging in this test.
         
     | 
| 
      
 220 
     | 
    
         
            +
                    logger_stream.truncate(0)
         
     | 
| 
      
 221 
     | 
    
         
            +
             
     | 
| 
      
 222 
     | 
    
         
            +
                    relation = Admin::Slice["relations.posts"]
         
     | 
| 
      
 223 
     | 
    
         
            +
                    relation.select(:title).to_a
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
                    log_lines = logger_stream.string.split("\n")
         
     | 
| 
      
 226 
     | 
    
         
            +
                    expect(log_lines.length).to eq 1
         
     | 
| 
      
 227 
     | 
    
         
            +
                    expect(log_lines.last).to match /Loaded :sqlite in \d+ms SELECT `posts`.`title` FROM `posts` ORDER BY `posts`.`id`/
         
     | 
| 
      
 228 
     | 
    
         
            +
             
     | 
| 
      
 229 
     | 
    
         
            +
                    relation = Main::Slice["relations.posts"]
         
     | 
| 
      
 230 
     | 
    
         
            +
                    relation.select(:id).to_a
         
     | 
| 
      
 231 
     | 
    
         
            +
             
     | 
| 
      
 232 
     | 
    
         
            +
                    log_lines = logger_stream.string.split("\n")
         
     | 
| 
      
 233 
     | 
    
         
            +
                    expect(log_lines.length).to eq 2
         
     | 
| 
      
 234 
     | 
    
         
            +
                    expect(log_lines.last).to match /Loaded :sqlite in \d+ms SELECT `posts`.`id` FROM `posts` ORDER BY `posts`.`id`/
         
     | 
| 
      
 235 
     | 
    
         
            +
                  end
         
     | 
| 
      
 236 
     | 
    
         
            +
                end
         
     | 
| 
      
 237 
     | 
    
         
            +
              end
         
     | 
| 
      
 238 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -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,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
         
     |