Establish standard Ruby project structure
Moves app to lib/pro_tacts/ so tests can require without relative
paths via Minitest::TestTask's load path.
Assisted-by: Claude Opus 4.5 via Claude Code
diff --git a/Gemfile b/Gemfile
index 4ced7cb..d502359 100644
--- a/Gemfile
+++ b/Gemfile
@@ -12,4 +12,5 @@ gem "sentry-ruby"
group :development do
gem "irb"
gem "minitest"
+ gem "rack-test"
end
diff --git a/Gemfile.lock b/Gemfile.lock
index ef389f9..7a2252e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -24,6 +24,8 @@ GEM
puma (7.1.0)
nio4r (~> 2.0)
rack (3.2.4)
+ rack-test (2.2.0)
+ rack (>= 1.3)
rackup (2.3.1)
rack (>= 3)
rake (13.3.1)
@@ -50,6 +52,7 @@ DEPENDENCIES
logger
minitest
puma
+ rack-test
rackup
rake
roda
@@ -71,6 +74,7 @@ CHECKSUMS
psych (5.3.1) sha256=eb7a57cef10c9d70173ff74e739d843ac3b2c019a003de48447b2963d81b1974
puma (7.1.0) sha256=e45c10cb124f224d448c98db653a75499794edbecadc440ad616cf50f2fd49dd
rack (3.2.4) sha256=5d74b6f75082a643f43c1e76b419c40f0e5527fcfee1e669ac1e6b73c0ccb6f6
+ rack-test (2.2.0) sha256=005a36692c306ac0b4a9350355ee080fd09ddef1148a5f8b2ac636c720f5c463
rackup (2.3.1) sha256=6c79c26753778e90983761d677a48937ee3192b3ffef6bc963c0950f94688868
rake (13.3.1) sha256=8c9e89d09f66a26a01264e7e3480ec0607f0c497a861ef16063604b1b08eb19c
rdoc (7.0.3) sha256=dfe3d0981d19b7bba71d9dbaeb57c9f4e3a7a4103162148a559c4fc687ea81f9
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..cc4ae53
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+require "minitest/test_task"
+
+Minitest::TestTask.create
+
+task default: :test
diff --git a/config.ru b/config.ru
index c588f40..21df719 100644
--- a/config.ru
+++ b/config.ru
@@ -1,61 +1,5 @@
-require "roda"
-require "sentry-ruby"
+# frozen_string_literal: true
-Sentry.init do |config|
- # TODO: Consolidate configuration
- config.dsn = ENV.fetch("SENTRY_DSN")
+require_relative "lib/pro_tacts/web"
- # Get breadcrumbs from logs
- config.breadcrumbs_logger = [:sentry_logger, :http_logger]
-
- # Add data like request headers and IP for users, if applicable;
- # see https://docs.sentry.io/platforms/ruby/data-management/data-collected/ for more info
- config.send_default_pii = true
-
- # Trace all the things!
- config.traces_sample_rate = 1.0
-end
-
-class App < Roda
- plugin :not_found do
- Sentry.capture_message("404 Not Found", level: :warning, extra: {
- path: request.path,
- method: request.request_method
- })
- "Not Found"
- end
-
- route do |r|
- # GET / request
- r.root do
- r.redirect "/hello"
- end
-
- # /hello branch
- r.on "hello" do
- # Set variable for all routes in /hello branch
- @greeting = "Hello"
-
- # GET /hello/world request
- r.get "world" do
- "#{@greeting} world!"
- end
-
- # /hello request
- r.is do
- # GET /hello request
- r.get do
- "#{@greeting}!"
- end
-
- # POST /hello request
- r.post do
- puts "Someone said #{@greeting}!"
- r.redirect
- end
- end
- end
- end
-end
-
-run App.freeze.app
+run ProTacts::Web.freeze.app
diff --git a/lib/pro_tacts/web.rb b/lib/pro_tacts/web.rb
new file mode 100644
index 0000000..1622e54
--- /dev/null
+++ b/lib/pro_tacts/web.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require "roda"
+require "sentry-ruby"
+
+Sentry.init do |config|
+ # TODO: Consolidate configuration
+ config.dsn = ENV.fetch("SENTRY_DSN")
+
+ # Get breadcrumbs from logs
+ config.breadcrumbs_logger = [:sentry_logger, :http_logger]
+
+ # Add data like request headers and IP for users, if applicable;
+ # see https://docs.sentry.io/platforms/ruby/data-management/data-collected/ for more info
+ config.send_default_pii = true
+
+ # Trace all the things!
+ config.traces_sample_rate = 1.0
+end
+
+module ProTacts
+ class Web < Roda
+ plugin :not_found do
+ Sentry.capture_message("404 Not Found", level: :warning, extra: {
+ path: request.path,
+ method: request.request_method
+ })
+ "Not Found"
+ end
+
+ route do |r|
+ # GET / request
+ r.root do
+ r.redirect "/hello"
+ end
+
+ # /hello branch
+ r.on "hello" do
+ # Set variable for all routes in /hello branch
+ @greeting = "Hello"
+
+ # GET /hello/world request
+ r.get "world" do
+ "#{@greeting} world!"
+ end
+
+ # /hello request
+ r.is do
+ # GET /hello request
+ r.get do
+ "#{@greeting}!"
+ end
+
+ # POST /hello request
+ r.post do
+ puts "Someone said #{@greeting}!"
+ r.redirect
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/test/pro_tacts/test_web.rb b/test/pro_tacts/test_web.rb
new file mode 100644
index 0000000..abfad25
--- /dev/null
+++ b/test/pro_tacts/test_web.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require "minitest/autorun"
+require "rack/test"
+
+require "pro_tacts/web"
+
+class WebTest < Minitest::Test
+ include Rack::Test::Methods
+
+ def app
+ ProTacts::Web
+ end
+
+ def test_hello
+ get "/hello"
+
+ assert_equal 200, last_response.status
+ assert_equal "Hello!", last_response.body
+ end
+end