diff --git a/.rubocop.yml b/.rubocop.yml index 5378101..8158bb3 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,4 +1,6 @@ -require: rubocop-sequel +plugins: + - rubocop-rspec + - rubocop-sequel AllCops: NewCops: enable diff --git a/Gemfile b/Gemfile index 0ca0db1..914453f 100644 --- a/Gemfile +++ b/Gemfile @@ -15,6 +15,7 @@ group :development, :test do # rubocop and extensions for code style gem 'rubocop' + gem 'rubocop-rspec' gem 'rubocop-sequel' end diff --git a/Gemfile.lock b/Gemfile.lock index 1d8830a..eff2464 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -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) diff --git a/Rakefile b/Rakefile index eb02513..40a3c9f 100644 --- a/Rakefile +++ b/Rakefile @@ -29,7 +29,7 @@ namespace :test do end task :rubocop do - system("rubocop src/") + system("rubocop src/ spec/") end end diff --git a/config.ru b/config.ru index f85997e..d24c0ba 100644 --- a/config.ru +++ b/config.ru @@ -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 diff --git a/spec/controllers/index_controller_spec.rb b/spec/controllers/index_controller_spec.rb new file mode 100644 index 0000000..ece6ebd --- /dev/null +++ b/spec/controllers/index_controller_spec.rb @@ -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 diff --git a/spec/routes/index_spec.rb b/spec/routes/index_spec.rb deleted file mode 100644 index d750b85..0000000 --- a/spec/routes/index_spec.rb +++ /dev/null @@ -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 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8c4fef3..23da6f9 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -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 diff --git a/src/app.rb b/src/app.rb deleted file mode 100644 index eaf00f9..0000000 --- a/src/app.rb +++ /dev/null @@ -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 diff --git a/src/routes/api1.rb b/src/controllers/api1.rb similarity index 90% rename from src/routes/api1.rb rename to src/controllers/api1.rb index 13a8719..0d851fd 100644 --- a/src/routes/api1.rb +++ b/src/controllers/api1.rb @@ -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] diff --git a/src/controllers/base_controller.rb b/src/controllers/base_controller.rb new file mode 100644 index 0000000..df010ea --- /dev/null +++ b/src/controllers/base_controller.rb @@ -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 diff --git a/src/routes/benchmark.rb b/src/controllers/benchmark.rb similarity index 94% rename from src/routes/benchmark.rb rename to src/controllers/benchmark.rb index 535256f..95bfc2e 100644 --- a/src/routes/benchmark.rb +++ b/src/controllers/benchmark.rb @@ -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() diff --git a/src/routes/hardware.rb b/src/controllers/hardware.rb similarity index 94% rename from src/routes/hardware.rb rename to src/controllers/hardware.rb index 2ba2ec5..bdfdfda 100644 --- a/src/routes/hardware.rb +++ b/src/controllers/hardware.rb @@ -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() diff --git a/src/routes/index.rb b/src/controllers/index.rb similarity index 77% rename from src/routes/index.rb rename to src/controllers/index.rb index 94c3509..15cd3af 100644 --- a/src/routes/index.rb +++ b/src/controllers/index.rb @@ -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() diff --git a/src/routes/reports.rb b/src/controllers/reports.rb similarity index 93% rename from src/routes/reports.rb rename to src/controllers/reports.rb index 529e09e..d7ed309 100644 --- a/src/routes/reports.rb +++ b/src/controllers/reports.rb @@ -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() diff --git a/src/routes/result.rb b/src/controllers/result.rb similarity index 91% rename from src/routes/result.rb rename to src/controllers/result.rb index c3d9ba8..1b3861d 100644 --- a/src/routes/result.rb +++ b/src/controllers/result.rb @@ -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) diff --git a/src/routes/test.rb b/src/controllers/test.rb similarity index 96% rename from src/routes/test.rb rename to src/controllers/test.rb index 79f2002..aaaf08c 100644 --- a/src/routes/test.rb +++ b/src/controllers/test.rb @@ -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() diff --git a/src/server.rb b/src/server.rb old mode 100755 new mode 100644 index 6a439f4..10d196e --- a/src/server.rb +++ b/src/server.rb @@ -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