Compare commits

...

12 commits

10 changed files with 178 additions and 49 deletions

View file

@ -0,0 +1,24 @@
---
name: Roda Project
description: describes this project for AI to better understand
alwaysApply: true
---
# Project Architecture
This is a Roda application using:
- Roda web framework
- Bundler for dependency management
- Puma for the application server
- systemd for process management
## Coding Standards
- Use Context7
- Follow the existing naming conventions.
- Testing should use minitest.
- Tests should be unit tests, not spec tests.
- Any database access should use sequel, never use raw sql.
- Prioritize **simplicity, clarity, and performance** over cleverness.
- Ask clarifying questions if the goal is ambiguous (e.g., “Are you building a REST API or a full web app?”).

15
Gemfile
View file

@ -1,15 +1,20 @@
source "https://rubygems.org" # frozen_string_literal: true
gem "roda" source 'https://rubygems.org'
gem 'rake'
gem 'roda'
# change to gunicorn or passenger if you prefer: # change to gunicorn or passenger if you prefer:
gem "puma" gem 'puma'
group :development, :test do group :development do
gem "rerun" gem 'rerun'
gem 'rubocop'
end end
group :test do group :test do
gem 'capybara' gem 'capybara'
gem 'minitest' gem 'minitest'
gem 'minitest-reporters'
end end

View file

@ -3,6 +3,9 @@ GEM
specs: specs:
addressable (2.8.7) addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0) public_suffix (>= 2.0.2, < 7.0)
ansi (1.5.0)
ast (2.4.3)
builder (3.3.0)
capybara (3.40.0) capybara (3.40.0)
addressable addressable
matrix matrix
@ -15,51 +18,85 @@ GEM
ffi (1.17.2) ffi (1.17.2)
ffi (1.17.2-arm64-darwin) ffi (1.17.2-arm64-darwin)
ffi (1.17.2-x86_64-darwin) ffi (1.17.2-x86_64-darwin)
ffi (1.17.2-x86_64-linux-gnu)
json (2.15.1)
language_server-protocol (3.17.0.5)
lint_roller (1.1.0)
listen (3.9.0) listen (3.9.0)
rb-fsevent (~> 0.10, >= 0.10.3) rb-fsevent (~> 0.10, >= 0.10.3)
rb-inotify (~> 0.9, >= 0.9.10) rb-inotify (~> 0.9, >= 0.9.10)
matrix (0.4.3) matrix (0.4.3)
mini_mime (1.1.5) mini_mime (1.1.5)
mini_portile2 (2.8.9) minitest (5.26.0)
minitest (5.25.5) minitest-reporters (1.7.1)
ansi
builder
minitest (>= 5.0)
ruby-progressbar
nio4r (2.7.4) nio4r (2.7.4)
nokogiri (1.18.8) nokogiri (1.18.10-arm64-darwin)
mini_portile2 (~> 2.8.2)
racc (~> 1.4) racc (~> 1.4)
nokogiri (1.18.8-arm64-darwin) nokogiri (1.18.10-x86_64-darwin)
racc (~> 1.4) racc (~> 1.4)
nokogiri (1.18.8-x86_64-darwin) nokogiri (1.18.10-x86_64-linux-gnu)
racc (~> 1.4) racc (~> 1.4)
parallel (1.27.0)
parser (3.3.9.0)
ast (~> 2.4.1)
racc
prism (1.6.0)
public_suffix (6.0.2) public_suffix (6.0.2)
puma (6.6.0) puma (7.1.0)
nio4r (~> 2.0) nio4r (~> 2.0)
racc (1.8.1) racc (1.8.1)
rack (3.1.16) rack (3.2.3)
rack-test (2.2.0) rack-test (2.2.0)
rack (>= 1.3) rack (>= 1.3)
rainbow (3.1.1)
rake (13.3.0)
rb-fsevent (0.11.2) rb-fsevent (0.11.2)
rb-inotify (0.11.1) rb-inotify (0.11.1)
ffi (~> 1.0) ffi (~> 1.0)
regexp_parser (2.10.0) regexp_parser (2.11.3)
rerun (0.14.0) rerun (0.14.0)
listen (~> 3.0) listen (~> 3.0)
roda (3.93.0) roda (3.97.0)
rack rack
rubocop (1.81.1)
json (~> 2.3)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
parallel (~> 1.10)
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.9.3, < 3.0)
rubocop-ast (>= 1.47.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.47.1)
parser (>= 3.3.7.2)
prism (~> 1.4)
ruby-progressbar (1.13.0)
unicode-display_width (3.2.0)
unicode-emoji (~> 4.1)
unicode-emoji (4.1.0)
xpath (3.2.0) xpath (3.2.0)
nokogiri (~> 1.8) nokogiri (~> 1.8)
PLATFORMS PLATFORMS
arm64-darwin arm64-darwin
ruby
x86_64-darwin x86_64-darwin
x86_64-linux x86_64-linux
DEPENDENCIES DEPENDENCIES
capybara capybara
minitest minitest
minitest-reporters
puma puma
rake
rerun rerun
roda roda
rubocop
BUNDLED WITH BUNDLED WITH
2.6.9 2.7.1

View file

@ -1,3 +1,22 @@
# Roda step 1 - Single File app (sort of) # Roda step 1 - Single File app (sort of)
Example single file Roda web app. There are extra files for launching the server, running tests, the license, etc, but the app itself is all in app.rb. Example single file Roda web app. There are extra files for launching the server, running tests, the license, etc, but the app itself is all in app.rb.
Prepare the environment with:
```bash
bundle install
# could do "bundle update" instead if you want to fetch new versions of packages
```
Run tests with:
```bash
bundle exec rake test
```
Run the app with:
```bash
bundle exec puma
```

7
Rakefile Normal file
View file

@ -0,0 +1,7 @@
# frozen_string_literal: true
require 'rake/testtask'
Rake::TestTask.new do |task|
task.pattern = '*_test.rb'
end

13
app.rb
View file

@ -1,11 +1,16 @@
require "roda" # frozen_string_literal: true
require 'roda'
# A simple Roda app all in one file.
class App < Roda class App < Roda
route do |r| route do |r|
r.root do
r.on do 'My Homepage'
"Hello World!"
end end
r.get 'about' do
'About This Site'
end
end end
end end

51
app_test.rb Normal file
View file

@ -0,0 +1,51 @@
# frozen_string_literal: true
require 'minitest/autorun'
require 'capybara/minitest'
require_relative 'app'
# make test report prettier
require 'minitest/reporters'
Minitest::Reporters.use!
Capybara.app = App
# Run tests for my simple Roda app.
class AppTest < Minitest::Test
include Capybara::DSL
include Capybara::Minitest::Assertions
def teardown
Capybara.reset_sessions!
Capybara.use_default_driver
end
# always passes, just to make sure tests are running
def test_the_truth
assert true
end
# Make sure not just responding to every path
def test_random_page_does_not__exist
visit '/skdjflksjdflkzxbjslkdjqweooiumnbvjslkdjflk'
refute_equal 200, page.status_code
end
def test_home_page_exists
visit '/'
assert_equal 200, page.status_code
end
# Can change the checked content as your site evolves:
def test_home_page_has_content
visit '/'
assert_content 'My Homepage'
end
def test_about_page_exists_and_has_content
visit '/about'
assert_equal 200, page.status_code
assert_content 'About This Site'
end
end

View file

@ -1,3 +1,5 @@
require "./app" # frozen_string_literal: true
require './app'
run App.freeze.app run App.freeze.app

View file

@ -8,10 +8,15 @@ Group=myapp
WorkingDirectory=/opt/myapp WorkingDirectory=/opt/myapp
Environment=RACK_ENV=production Environment=RACK_ENV=production
ExecStart=/usr/bin/puma ExecStart=/opt/myapp/bin/puma
TimeoutStopSec=300 TimeoutStopSec=300
KillMode=mixed KillMode=mixed
Restart=on-failure Restart=on-failure
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
# Can copy this unit file into /etc/systemd/system/
# then edit for your installation details (user, group, directory, exec, app name)
# run "sudo systemctl daemon-reload",
# then "sudo systemctl enable --now -q myapp.service"

View file

@ -1,26 +0,0 @@
require 'minitest/autorun'
require 'capybara/minitest'
require_relative 'app'
Capybara.app = App
class AppTest < Minitest::Test
include Capybara::DSL
include Capybara::Minitest::Assertions
def teardown
Capybara.reset_sessions!
Capybara.use_default_driver
end
# always passes, just to make sure tests are running
def test_the_truth
assert true
end
def test_home_page_exists
visit '/'
assert_equal 200, page.status_code
end
end