Extract DB setup into an injectable app container
DB connected at require time, coupling tests to DATABASE_URL.
Domus::App makes the connection injectable.
Assisted-by: Claude Sonnet 4.6 via Claude Code
diff --git a/Rakefile b/Rakefile
index f3575f0..85686fc 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,8 +1,11 @@
# frozen_string_literal: true
require "minitest/test_task"
+require_relative "lib/app"
+require "sequel/extensions/migration"
-require_relative "lib/db"
+DOMUS_APP = Domus::App.new
+DB = DOMUS_APP.db
BUNDLE_INSTALL_MARKER = Pathname.new(".bundle/installed")
@@ -19,10 +22,8 @@ Minitest::TestTask.create(:test)
task default: :test
-desc "Start dev server with pre-seeded in-memory database"
+desc "Start dev server"
task :dev do
- Sequel::Migrator.run(Domus::DB, "db/migrate") unless Dir.empty?("db/migrate")
-
require "rack"
Rack::Server.start(config: "config.ru", Port: 9292)
end
@@ -33,19 +34,24 @@ namespace :db do
if Dir.empty?("db/migrate")
puts "No migrations."
else
- Sequel::Migrator.run(Domus::DB, "db/migrate")
+ Sequel::Migrator.run(DB, "db/migrate")
puts "Migrated."
end
end
desc "Rollback the last migration"
task :rollback do
- version = Domus::DB[:schema_migrations].order(Sequel.desc(:filename)).limit(1).get(:filename)
+ version = DB[:schema_migrations].order(Sequel.desc(:filename)).limit(1).get(:filename)
if version
- Sequel::Migrator.run(Domus::DB, "db/migrate", target: 0, current: version.sub(/\.rb$/, ""))
+ Sequel::Migrator.run(DB, "db/migrate", target: 0, current: version.sub(/\.rb$/, ""))
puts "Rolled back #{version}."
else
puts "Nothing to rollback."
end
end
+
+ desc "Seed the database with development data"
+ task :seed do
+ # Add seed data here
+ end
end
diff --git a/config.ru b/config.ru
index 2f617a8..e3b802c 100644
--- a/config.ru
+++ b/config.ru
@@ -1,5 +1,10 @@
# frozen_string_literal: true
require_relative "lib/app"
+require_relative "lib/web"
+require "sequel/extensions/migration"
-run Domus::App
+app = Domus::App.new
+Sequel::Migrator.run(app.db, "db/migrate") unless Dir.empty?("db/migrate")
+Domus::Web.opts[:app] = app
+run Domus::Web
diff --git a/db/migrate/.gitkeep b/db/migrate/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/lib/app.rb b/lib/app.rb
index 6306b52..268a48c 100644
--- a/lib/app.rb
+++ b/lib/app.rb
@@ -1,20 +1,15 @@
# frozen_string_literal: true
-require "roda"
-require_relative "views/layout"
+require "sequel"
+require_relative "config"
module Domus
- class App < Roda
- route do |r|
- r.root do
- render_with_layout { "ok" }
- end
- end
-
- private
+ class App
+ attr_reader :config, :db
- def render_with_layout(&block)
- Views::Layout.new(&block).call
+ def initialize(config = Config.env)
+ @config = config
+ @db = Sequel.sqlite(config.database_url)
end
end
end
diff --git a/lib/config.rb b/lib/config.rb
index a2d12b4..a454210 100644
--- a/lib/config.rb
+++ b/lib/config.rb
@@ -2,8 +2,6 @@
module Domus
class Config < Data.define(:database_url)
- def self.from_env
- new(database_url: ENV.fetch("DATABASE_URL"))
- end
+ def self.env = new(database_url: ENV.fetch("DATABASE_URL") { "db/domus.db" })
end
end
diff --git a/lib/db.rb b/lib/db.rb
deleted file mode 100644
index 362481f..0000000
--- a/lib/db.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-# frozen_string_literal: true
-
-require "sequel"
-require "sequel/extensions/migration"
-
-require_relative "config"
-
-module Domus
- DB = Sequel.sqlite(Config.from_env.database_url)
-end
diff --git a/lib/web.rb b/lib/web.rb
new file mode 100644
index 0000000..d4d1f86
--- /dev/null
+++ b/lib/web.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+require "roda"
+require_relative "views/layout"
+
+module Domus
+ class Web < Roda
+ route do |r|
+ r.root do
+ render_with_layout { "ok" }
+ end
+ end
+
+ private
+
+ def db = opts[:db] || opts[:app].db
+
+ def render_with_layout(&block)
+ Views::Layout.new(&block).call
+ end
+ end
+end
diff --git a/test/test_app.rb b/test/test_app.rb
index bc36c87..4359efc 100644
--- a/test/test_app.rb
+++ b/test/test_app.rb
@@ -2,13 +2,12 @@
require_relative "test_helper"
require "rack/test"
-require_relative "../lib/app"
class TestApp < Minitest::Test
include Rack::Test::Methods
def app
- Domus::App
+ Domus::Web
end
def test_root
diff --git a/test/test_helper.rb b/test/test_helper.rb
index a93651f..cb093a3 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -1,3 +1,11 @@
# frozen_string_literal: true
require "minitest/autorun"
+
+require_relative "../lib/app"
+require_relative "../lib/web"
+
+app = Domus::App.new(Domus::Config.new(database_url: ":memory:"))
+migrate_dir = File.expand_path("../db/migrate", __dir__)
+Sequel::Migrator.run(app.db, migrate_dir) unless Dir.empty?(migrate_dir)
+Domus::Web.opts[:app] = app