Added Test class to track benchmark groups

This commit is contained in:
Gregory Ballantine 2022-11-25 19:39:51 -05:00
parent 9a65b5f27a
commit ca62be49b6
12 changed files with 245 additions and 4 deletions

View File

@ -20,7 +20,7 @@ final class AddResultsTable extends AbstractMigration
{ {
$table = $this->table('results'); $table = $this->table('results');
$table->addColumn('component', 'string', ['null' => false]) $table->addColumn('component', 'string', ['null' => false])
->addColumn('benchmark', 'text', ['null' => false]) ->addColumn('benchmark', 'string', ['null' => false])
->addColumn('type', 'string', ['null' => false, 'default' => 'fps']) ->addColumn('type', 'string', ['null' => false, 'default' => 'fps'])
->addColumn('average', 'integer', ['null' => false]) ->addColumn('average', 'integer', ['null' => false])
->addColumn('minimum', 'integer') ->addColumn('minimum', 'integer')

View File

@ -0,0 +1,33 @@
<?php
declare(strict_types=1);
use Phinx\Migration\AbstractMigration;
final class AddTestsTable extends AbstractMigration
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
$table = $this->table('tests');
$table->addColumn('name', 'string', ['null' => false])
->addColumn('description', 'text', ['null' => false])
->addTimestamps()
->addIndex(['name'])
->create();
$results = $this->table('results');
$results->addColumn('test_id', 'integer', ['null' => false])
->addForeignKey('test_id', 'tests', 'id', ['delete'=> 'CASCADE', 'update'=> 'CASCADE'])
->update();
}
}

View File

@ -7,6 +7,7 @@ use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Routing\RouteContext; use Slim\Routing\RouteContext;
use Slim\Views\Twig; use Slim\Views\Twig;
use BitGoblin\Colossus\Models\Result; use BitGoblin\Colossus\Models\Result;
use BitGoblin\Colossus\Models\Test;
class ResultController extends Controller { class ResultController extends Controller {
@ -20,14 +21,19 @@ class ResultController extends Controller {
} }
public function getAdd(Request $request, Response $response): Response { public function getAdd(Request $request, Response $response): Response {
$tests = Test::all();
$view = Twig::fromRequest($request); $view = Twig::fromRequest($request);
return $view->render($response, 'result/add.twig'); return $view->render($response, 'result/add.twig', [
'tests' => $tests,
]);
} }
public function postAdd(Request $request, Response $response): Response { public function postAdd(Request $request, Response $response): Response {
$params = (array)$request->getParsedBody(); $params = (array)$request->getParsedBody();
$result = new Result; $result = new Result;
$result->test_id = $params['result_test'];
$result->component = $params['result_component']; $result->component = $params['result_component'];
$result->benchmark = $params['result_benchmark']; $result->benchmark = $params['result_benchmark'];
$result->type = $params['result_type']; $result->type = $params['result_type'];

View File

@ -0,0 +1,53 @@
<?php
namespace BitGoblin\Colossus\Controllers;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Routing\RouteContext;
use Slim\Views\Twig;
use BitGoblin\Colossus\Models\Test;
class TestController extends Controller {
public function getList(Request $request, Response $response): Response {
$tests = Test::all();
$view = Twig::fromRequest($request);
return $view->render($response, 'test/list.twig', [
'tests' => $tests,
]);
}
public function getView(Request $request, Response $response, array $args): Response {
$test = Test::where('id', $args['test_id'])->first();
$view = Twig::fromRequest($request);
return $view->render($response, 'test/view.twig', [
'test' => $test,
]);
}
public function getAdd(Request $request, Response $response): Response {
$view = Twig::fromRequest($request);
return $view->render($response, 'test/add.twig');
}
public function postAdd(Request $request, Response $response): Response {
$params = (array)$request->getParsedBody();
$test = new Test;
$test->name = $params['test_name'];
$test->description = $params['test_description'];
$test->save();
// redirect the user back to the home page
$routeContext = RouteContext::fromRequest($request);
$routeParser = $routeContext->getRouteParser();
return $response
->withHeader('Location', $routeParser->urlFor('test.list'))
->withStatus(302);
}
}

View File

@ -7,6 +7,7 @@ use Illuminate\Database\Eloquent\Model;
class Result extends Model { class Result extends Model {
protected $fillable = [ protected $fillable = [
'test_id',
'component', 'component',
'benchmark', 'benchmark',
'type', 'type',
@ -15,4 +16,8 @@ class Result extends Model {
'maximum', 'maximum',
]; ];
public function test() {
return $this->belongsTo(Test::class);
}
} }

18
src/Models/Test.php Normal file
View File

@ -0,0 +1,18 @@
<?php
namespace BitGoblin\Colossus\Models;
use Illuminate\Database\Eloquent\Model;
class Test extends Model {
protected $fillable = [
'name',
'description',
];
public function results() {
return $this->hasMany(Result::class);
}
}

View File

@ -2,6 +2,11 @@
$app->get('/', '\\BitGoblin\\Colossus\\Controllers\\HomeController:getIndex')->setName('dashboard'); $app->get('/', '\\BitGoblin\\Colossus\\Controllers\\HomeController:getIndex')->setName('dashboard');
$app->get('/test', '\\BitGoblin\\Colossus\\Controllers\\TestController:getList')->setName('test.list');
$app->get('/test/add', '\\BitGoblin\\Colossus\\Controllers\\TestController:getAdd')->setName('test.add');
$app->post('/test/add', '\\BitGoblin\\Colossus\\Controllers\\TestController:postAdd');
$app->get('/test/{test_id}', '\\BitGoblin\\Colossus\\Controllers\\TestController:getView')->setName('test.view');
$app->get('/result', '\\BitGoblin\\Colossus\\Controllers\\ResultController:getList')->setName('result.list'); $app->get('/result', '\\BitGoblin\\Colossus\\Controllers\\ResultController:getList')->setName('result.list');
$app->get('/result/add', '\\BitGoblin\\Colossus\\Controllers\\ResultController:getAdd')->setName('result.add'); $app->get('/result/add', '\\BitGoblin\\Colossus\\Controllers\\ResultController:getAdd')->setName('result.add');
$app->post('/result/add', '\\BitGoblin\\Colossus\\Controllers\\ResultController:postAdd'); $app->post('/result/add', '\\BitGoblin\\Colossus\\Controllers\\ResultController:postAdd');

View File

@ -3,6 +3,7 @@
<ul class="nav-left"> <ul class="nav-left">
<li class="site-logo">Colossus</li> <li class="site-logo">Colossus</li>
<li><a href="{{ url_for('dashboard') }}">Dashboard</a></li> <li><a href="{{ url_for('dashboard') }}">Dashboard</a></li>
<li><a href="{{ url_for('test.list') }}">Test</a></li>
<li><a href="/result">Results</a></li> <li><a href="/result">Results</a></li>
</ul> </ul>

View File

@ -14,11 +14,19 @@
<div class="twelve columns"> <div class="twelve columns">
<form action="{{ url_for('result.add') }}" method="POST" class="u-full-width"> <form action="{{ url_for('result.add') }}" method="POST" class="u-full-width">
<div class="row"> <div class="row">
<div class="six columns"> <div class="four columns">
<label for="result_test">Associated test:</label>
<select name="result_test" id="result_test" class="u-full-width">
{% for t in tests %}
<option value="{{ t.id }}">{{ t.name }}</option>
{% endfor %}
</select>
</div>
<div class="four columns">
<label for="result_component">Hardware name:</label> <label for="result_component">Hardware name:</label>
<input type="text" id="result_component" class="u-full-width" name="result_component"> <input type="text" id="result_component" class="u-full-width" name="result_component">
</div> </div>
<div class="six columns"> <div class="four columns">
<label for="result_benchmark">Benchmark used:</label> <label for="result_benchmark">Benchmark used:</label>
<input type="text" id="result_benchmark" class="u-full-width" name="result_benchmark"> <input type="text" id="result_benchmark" class="u-full-width" name="result_benchmark">
</div> </div>

35
views/test/add.twig Normal file
View File

@ -0,0 +1,35 @@
{% extends 'layout.twig' %}
{% block title %}Add New Test{% endblock %}
{% block content %}
<div class="row">
<div class="twelve columns">
<h1>Add new test</h1>
</div>
</div>
<div class="row">
<div class="twelve columns">
<form action="{{ url_for('test.add') }}" method="POST" class="u-full-width">
<div class="row">
<div class="twelve columns">
<label for="test_name">Test name:</label>
<input type="text" id="test_name" class="u-full-width" name="test_name">
</div>
</div>
<div class="row">
<div class="twelve columns">
<label for="test_description">Description</label>
<textarea class="u-full-width" name="test_description" id="test_description" placeholder="Describe this test..."></textarea>
</div>
</div>
<input class="button button-primary u-full-width" type="submit" value="Submit">
</form>
</div>
</div>
{% endblock %}

28
views/test/list.twig Normal file
View File

@ -0,0 +1,28 @@
{% extends 'layout.twig' %}
{% block title %}List of Tests{% endblock %}
{% block content %}
<p>Tests list...</p>
{% if tests | length > 0 %}
<table class="u-full-width">
<thead>
<tr>
<th>Test name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{% for t in tests %}
<tr>
<td><a href="{{ url_for('test.view', { test_id: t.id }) }}">{{ t.name }}</a></td>
<td>{{ t.description | slice(0, 100) }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>There are no tests in the database - perhaps you should <a href="{{ url_for('test.add') }}">create one</a>?</p>
{% endif %}
{% endblock %}

49
views/test/view.twig Normal file
View File

@ -0,0 +1,49 @@
{% extends 'layout.twig' %}
{% block title %}Test: {{ test.name }}{% endblock %}
{% block content %}
<div class="row">
<div class="twelve columns">
<h1>{{ test.name }}</h1>
<p>{{ test.description }}</p>
</div>
</div>
<hr>
<div class="row">
<div class="twelve columns">
<h3>Test results:</h3>
{% if test.results | length > 0 %}
<table class="u-full-width">
<thead>
<tr>
<th>Component</th>
<th>Benchmark</th>
<th>Scoring</th>
<th>Avg.</th>
<th>Min.</th>
<th>Max.</th>
</tr>
</thead>
<tbody>
{% for r in test.results %}
<tr>
<td>{{ r.component }}</td>
<td>{{ r.benchmark }}</td>
<td>{{ r.type | capitalize }}</td>
<td>{{ r.average }}</td>
<td>{{ r.minimum ? r.minimum : 'N/a' }}</td>
<td>{{ r.maximum ? r.maximum : 'N/a' }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<p>There are no results associated with this.</p>
{% endif %}
</div>
</div>
{% endblock %}