Changed naming from Routes to Controllers; fixed some Sinatra modular layout stuff; added RSpec for testing and some basic tests
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

This commit is contained in:
Gregory Ballantine
2025-08-12 16:15:43 -04:00
parent 260d0d1268
commit 40cfdcc2a3
18 changed files with 105 additions and 83 deletions

View File

@@ -1,4 +1,6 @@
require: rubocop-sequel
plugins:
- rubocop-rspec
- rubocop-sequel
AllCops:
NewCops: enable

View File

@@ -15,6 +15,7 @@ group :development, :test do
# rubocop and extensions for code style
gem 'rubocop'
gem 'rubocop-rspec'
gem 'rubocop-sequel'
end

View File

@@ -78,6 +78,9 @@ GEM
rubocop-ast (1.45.1)
parser (>= 3.3.7.2)
prism (~> 1.4)
rubocop-rspec (3.6.0)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop-sequel (0.4.1)
lint_roller (~> 1.1)
rubocop (>= 1.72.1, < 2)
@@ -132,6 +135,7 @@ DEPENDENCIES
rerun
rspec
rubocop
rubocop-rspec
rubocop-sequel
sequel (~> 5.92)
sinatra (~> 4.1)

View File

@@ -29,7 +29,7 @@ namespace :test do
end
task :rubocop do
system("rubocop src/")
system("rubocop src/ spec/")
end
end

View File

@@ -1,7 +1,5 @@
# Load application config
require_relative 'src/config.rb'
$conf = Config.new(File.join(__dir__, 'config/defaults.yaml'))
root = ::File.dirname(__FILE__)
require ::File.join( root, 'src', 'app' )
require ::File.join( root, 'src', 'server' )
run GameData.new

View File

@@ -0,0 +1,23 @@
# frozen_string_literal: true
require_relative '../spec_helper'
RSpec.describe(IndexController) do
# / route
describe 'Get /' do
it 'Dashboard returns 200.' do
get '/'
expect(last_response).to(be_ok)
end
it "Dashboard contains 'Game Data' on page (nav bar should be loaded)." do
get '/'
expect(last_response.body).to(include('Game Data'))
end
it "Dashboard contains 'Ruby version' on page (footer should be loaded)." do
get '/'
expect(last_response.body).to(include('Ruby version'))
end
end
end

View File

@@ -1,14 +0,0 @@
require_relative '../spec_helper'
RSpec.describe IndexRoutes do
def app
IndexRoutes
end
it "Dashboard returns 200" do
get '/'
expect(last_response).to be_ok
end
end

View File

@@ -1,17 +1,21 @@
# frozen_string_literal: true
ENV['APP_ENV'] = 'test'
require_relative '../src/app'
require_relative '../src/server'
require 'rspec'
require 'rack/test'
module RSpecMixin
include Rack::Test::Methods
def app
GameData
end
end
RSpec.configure do |config|
config.include RSpecMixin
config.include(RSpecMixin)
end

View File

@@ -1,41 +0,0 @@
# frozen_string_literal: true
require 'sinatra/base'
require 'sequel'
require 'sqlite3'
# Load the Sequel timestamps plugin
Sequel::Model.plugin(:timestamps)
# Initialize Sequel gem for database actions
DB = Sequel.connect(adapter: $conf.get('database.adapter'), database: $conf.get('database.database'))
# Load in routes (must happen after Sequel is loaded!)
require_relative 'routes/api1'
require_relative 'routes/benchmark'
require_relative 'routes/hardware'
require_relative 'routes/index'
require_relative 'routes/reports'
require_relative 'routes/result'
require_relative 'routes/test'
# GameData - main app that gets launched
# - inherits from Sinatra::Base to instantiate the server
# - sets up some base app configuration
# - registers route classes with the base app
class GameData < Sinatra::Base
enable :sessions
# Set up static file serving
enable :static
set :public_folder, File.join(__dir__, '/../public')
use IndexRoutes
use HardwareRoutes
use BenchmarkRoutes
use TestRoutes
use ResultRoutes
use ReportsRoutes
use APIv1Routes
end

View File

@@ -2,13 +2,13 @@
require 'sinatra/json'
require_relative '../server'
require_relative 'base_controller'
require_relative '../models/benchmark'
require_relative '../models/test'
require_relative '../models/result'
# /api/v1 routes
class APIv1Routes < Server
class APIv1Controller < BaseController
get '/api/v1/benchmark/details' do
benchmark_id = params[:benchmark_id]

View File

@@ -0,0 +1,15 @@
# frozen_string_literal: true
require 'sinatra/base'
# BaseController - base modular Sinatra app class
class BaseController < Sinatra::Base
# Register view helpers
require_relative '../helpers'
helpers Helpers
# Set up our view engine
set :views, File.join(settings.root, '/../../views')
end

View File

@@ -1,10 +1,10 @@
# frozen_string_literal: true
require_relative '../server'
require_relative 'base_controller'
require_relative '../models/benchmark'
# /benchmark routes
class BenchmarkRoutes < Server
class BenchmarkController < BaseController
get '/benchmark' do
benchmarks = Benchmark.reverse(:updated_at).limit(10).all()

View File

@@ -1,11 +1,11 @@
# frozen_string_literal: true
require_relative '../server'
require_relative 'base_controller'
require_relative '../models/hardware'
require_relative '../models/benchmark'
# /hardware routes
class HardwareRoutes < Server
class HardwareController < BaseController
get '/hardware' do
hardware = Hardware.reverse(:updated_at).limit(10).all()

View File

@@ -1,10 +1,10 @@
# frozen_string_literal: true
require_relative '../server'
require_relative 'base_controller'
require_relative '../models/test'
# / (top-level) routes
class IndexRoutes < Server
class IndexController < BaseController
get '/' do
tests = Test.reverse(:updated_at).limit(10).all()

View File

@@ -2,13 +2,13 @@
require 'sinatra/json'
require_relative '../server'
require_relative 'base_controller'
require_relative '../models/benchmark'
require_relative '../models/result'
require_relative '../models/test'
# /reports routes
class ReportsRoutes < Server
class ReportsController < BaseController
get '/report' do
benchmarks = Benchmark.order(:name).all()

View File

@@ -1,10 +1,10 @@
# frozen_string_literal: true
require_relative '../server'
require_relative 'base_controller'
require_relative '../models/result'
# /result routes
class ResultRoutes < Server
class ResultController < BaseController
post '/result/add' do
result_minimum = params[:result_minimum] if params.key?(:result_minimum)

View File

@@ -1,12 +1,12 @@
# frozen_string_literal: true
require_relative '../server'
require_relative 'base_controller'
require_relative '../models/benchmark'
require_relative '../models/hardware'
require_relative '../models/test'
# /test routes
class TestRoutes < Server
class TestController < BaseController
get '/test' do
tests = Test.reverse(:updated_at).limit(10).all()

44
src/server.rb Executable file → Normal file
View File

@@ -1,15 +1,45 @@
# frozen_string_literal: true
require 'sinatra/base'
require 'sequel'
require 'sqlite3'
# Server - base modular Sinatra app class
class Server < Sinatra::Base
require_relative 'config'
# Register view helpers
require_relative 'helpers'
helpers Helpers
$conf = Config.new(File.join(__dir__, 'config/defaults.yaml'))
# Set up our view engine
set :views, File.join(settings.root, '/../views')
# Load the Sequel timestamps plugin
Sequel::Model.plugin(:timestamps)
# Initialize Sequel gem for database actions
DB = Sequel.connect(adapter: $conf.get('database.adapter'), database: $conf.get('database.database'))
# Load in routes (must happen after Sequel is loaded!)
require_relative 'controllers/api1'
require_relative 'controllers/benchmark'
require_relative 'controllers/hardware'
require_relative 'controllers/index'
require_relative 'controllers/reports'
require_relative 'controllers/result'
require_relative 'controllers/test'
# GameData - main app that gets launched
# - inherits from Sinatra::Base to instantiate the server
# - sets up some base app configuration
# - registers route classes with the base app
class GameData < Sinatra::Base
enable :sessions
# Set up static file serving
enable :static
set :public_folder, File.join(__dir__, '/../public')
use IndexController
use HardwareController
use BenchmarkController
use TestController
use ResultController
use ReportsController
use APIv1Controller
end