mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 08:04:01 +02:00
Merge pull request #9148 from Polyrhythm/ryan/client-side-tests
Client script test runner
This commit is contained in:
commit
a81e7c2d2c
11 changed files with 197 additions and 26 deletions
|
@ -589,7 +589,9 @@ Menu::Menu() {
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
// Developer >> Tests >>>
|
||||
MenuWrapper* testMenu = developerMenu->addMenu("Tests");
|
||||
addActionToQMenuAndActionHash(testMenu, MenuOption::RunClientScriptTests, 0, dialogsManager.data(), SLOT(showTestingResults()));
|
||||
|
||||
// Developer > Timing >>>
|
||||
MenuWrapper* timingMenu = developerMenu->addMenu("Timing");
|
||||
|
|
|
@ -172,6 +172,7 @@ namespace MenuOption {
|
|||
const QString ResetAvatarSize = "Reset Avatar Size";
|
||||
const QString ResetSensors = "Reset Sensors";
|
||||
const QString RunningScripts = "Running Scripts...";
|
||||
const QString RunClientScriptTests = "Run Client Script Tests";
|
||||
const QString RunTimingTests = "Run Timing Tests";
|
||||
const QString ScriptEditor = "Script Editor...";
|
||||
const QString ScriptedMotorControl = "Enable Scripted Motor Control";
|
||||
|
|
|
@ -158,6 +158,15 @@ void DialogsManager::showScriptEditor() {
|
|||
_scriptEditor->raise();
|
||||
}
|
||||
|
||||
void DialogsManager::showTestingResults() {
|
||||
if (!_testingDialog) {
|
||||
_testingDialog = new TestingDialog(qApp->getWindow());
|
||||
connect(_testingDialog, SIGNAL(closed()), _testingDialog, SLOT(deleteLater()));
|
||||
}
|
||||
_testingDialog->show();
|
||||
_testingDialog->raise();
|
||||
}
|
||||
|
||||
void DialogsManager::showDomainConnectionDialog() {
|
||||
// if the dialog already exists we delete it so the connection data is refreshed
|
||||
if (_domainConnectionDialog) {
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <DependencyManager.h>
|
||||
|
||||
#include "HMDToolsDialog.h"
|
||||
#include "TestingDialog.h"
|
||||
|
||||
class AnimationsDialog;
|
||||
class AttachmentsDialog;
|
||||
|
@ -26,6 +27,7 @@ class DiskCacheEditor;
|
|||
class LodToolsDialog;
|
||||
class OctreeStatsDialog;
|
||||
class ScriptEditorWindow;
|
||||
class TestingDialog;
|
||||
class QMessageBox;
|
||||
class DomainConnectionDialog;
|
||||
|
||||
|
@ -38,6 +40,7 @@ public:
|
|||
QPointer<HMDToolsDialog> getHMDToolsDialog() const { return _hmdToolsDialog; }
|
||||
QPointer<LodToolsDialog> getLodToolsDialog() const { return _lodToolsDialog; }
|
||||
QPointer<OctreeStatsDialog> getOctreeStatsDialog() const { return _octreeStatsDialog; }
|
||||
QPointer<TestingDialog> getTestingDialog() const { return _testingDialog; }
|
||||
void emitAddressBarShown(bool visible) { emit addressBarShown(visible); }
|
||||
|
||||
public slots:
|
||||
|
@ -55,6 +58,7 @@ public slots:
|
|||
void hmdTools(bool showTools);
|
||||
void showScriptEditor();
|
||||
void showDomainConnectionDialog();
|
||||
void showTestingResults();
|
||||
|
||||
// Application Update
|
||||
void showUpdateDialog();
|
||||
|
@ -83,6 +87,7 @@ private:
|
|||
QPointer<LodToolsDialog> _lodToolsDialog;
|
||||
QPointer<OctreeStatsDialog> _octreeStatsDialog;
|
||||
QPointer<ScriptEditorWindow> _scriptEditor;
|
||||
QPointer<TestingDialog> _testingDialog;
|
||||
QPointer<DomainConnectionDialog> _domainConnectionDialog;
|
||||
};
|
||||
|
||||
|
|
35
interface/src/ui/TestingDialog.cpp
Normal file
35
interface/src/ui/TestingDialog.cpp
Normal file
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// TestingDialog.cpp
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Ryan Jones on 12/3/2016.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "ScriptEngines.h"
|
||||
|
||||
#include "ui/TestingDialog.h"
|
||||
#include "Application.h"
|
||||
|
||||
TestingDialog::TestingDialog(QWidget* parent) :
|
||||
QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint),
|
||||
_console(new JSConsole(this))
|
||||
{
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
setWindowTitle(windowLabel);
|
||||
|
||||
_console->setFixedHeight(TESTING_CONSOLE_HEIGHT);
|
||||
|
||||
auto _engines = DependencyManager::get<ScriptEngines>();
|
||||
_engine = _engines->loadScript(qApp->applicationDirPath() + testRunnerRelativePath);
|
||||
_console->setScriptEngine(_engine);
|
||||
connect(_engine, &ScriptEngine::finished, this, &TestingDialog::onTestingFinished);
|
||||
}
|
||||
|
||||
void TestingDialog::onTestingFinished(const QString& scriptPath) {
|
||||
_engine = nullptr;
|
||||
_console->setScriptEngine(nullptr);
|
||||
}
|
35
interface/src/ui/TestingDialog.h
Normal file
35
interface/src/ui/TestingDialog.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
//
|
||||
// TestingDialog.h
|
||||
// interface/src/ui
|
||||
//
|
||||
// Created by Ryan Jones on 12/3/2016.
|
||||
// Copyright 2016 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_TestingDialog_h
|
||||
#define hifi_TestingDialog_h
|
||||
|
||||
#include <QDialog>
|
||||
#include "ScriptEngine.h"
|
||||
#include "JSConsole.h"
|
||||
|
||||
const QString windowLabel = "Client Script Tests";
|
||||
const QString testRunnerRelativePath = "/scripts/developer/tests/unit_tests/testRunner.js";
|
||||
const unsigned int TESTING_CONSOLE_HEIGHT = 400;
|
||||
|
||||
class TestingDialog : public QDialog {
|
||||
Q_OBJECT
|
||||
public:
|
||||
TestingDialog(QWidget* parent);
|
||||
|
||||
void onTestingFinished(const QString& scriptPath);
|
||||
|
||||
private:
|
||||
std::unique_ptr<JSConsole> _console;
|
||||
ScriptEngine* _engine;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,27 +1,50 @@
|
|||
|
||||
(function() {
|
||||
var BALLOT_X = '✗';
|
||||
var CHECKMARK = '✓';
|
||||
var DOWN_RIGHT_ARROW = '↳';
|
||||
var PASSED = 'passed';
|
||||
var lastSpecStartTime;
|
||||
function ConsoleReporter(options) {
|
||||
var startTime = new Date().getTime();
|
||||
var errorCount = 0;
|
||||
this.jasmineStarted = function (obj) {
|
||||
print("jasmineStarted: numSpecs = " + obj.totalSpecsDefined);
|
||||
print('Jasmine started with ' + obj.totalSpecsDefined + ' tests.');
|
||||
};
|
||||
this.jasmineDone = function (obj) {
|
||||
print("jasmineDone");
|
||||
var ERROR = errorCount === 1 ? 'error' : 'errors';
|
||||
var endTime = new Date().getTime();
|
||||
print('<hr />');
|
||||
if (errorCount === 0) {
|
||||
print ('<span style="color:green">All tests passed!</span>');
|
||||
} else {
|
||||
print('<span style="color:red">Tests completed with ' +
|
||||
errorCount + ' ' + ERROR + '.<span>');
|
||||
}
|
||||
print('Tests completed in ' + (endTime - startTime) + 'ms.');
|
||||
};
|
||||
this.suiteStarted = function(obj) {
|
||||
print("suiteStarted: \"" + obj.fullName + "\"");
|
||||
print(obj.fullName);
|
||||
};
|
||||
this.suiteDone = function(obj) {
|
||||
print("suiteDone: \"" + obj.fullName + "\" " + obj.status);
|
||||
print('');
|
||||
};
|
||||
this.specStarted = function(obj) {
|
||||
print("specStarted: \"" + obj.fullName + "\"");
|
||||
lastSpecStartTime = new Date().getTime();
|
||||
};
|
||||
this.specDone = function(obj) {
|
||||
print("specDone: \"" + obj.fullName + "\" " + obj.status);
|
||||
var specEndTime = new Date().getTime();
|
||||
var symbol = obj.status === PASSED ?
|
||||
'<span style="color:green">' + CHECKMARK + '</span>' :
|
||||
'<span style="color:red">' + BALLOT_X + '</span>';
|
||||
print('... ' + obj.fullName + ' ' + symbol + ' ' + '<span style="color:orange">[' +
|
||||
(specEndTime - lastSpecStartTime) + 'ms]</span>');
|
||||
|
||||
var i, l = obj.failedExpectations.length;
|
||||
for (i = 0; i < l; i++) {
|
||||
print(" " + obj.failedExpectations[i].message);
|
||||
var specErrors = obj.failedExpectations.length;
|
||||
errorCount += specErrors;
|
||||
for (var i = 0; i < specErrors; i++) {
|
||||
print('<span style="margin-right:0.5em"></span>' + DOWN_RIGHT_ARROW +
|
||||
'<span style="color:red"> ' +
|
||||
obj.failedExpectations[i].message + '</span>');
|
||||
}
|
||||
};
|
||||
return this;
|
||||
|
@ -44,10 +67,11 @@
|
|||
|
||||
function extend(destination, source) {
|
||||
for (var property in source) {
|
||||
destination[property] = source[property];
|
||||
if (source.hasOwnProperty(property)) {
|
||||
destination[property] = source[property];
|
||||
}
|
||||
}
|
||||
return destination;
|
||||
}
|
||||
|
||||
}());
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
|
||||
Script.include("../libraries/jasmine/jasmine.js");
|
||||
Script.include("../libraries/jasmine/hifi-boot.js");
|
||||
|
||||
// Art3mis
|
||||
var DEFAULT_AVATAR_URL = "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/e76946cc-c272-4adf-9bb6-02cde0a4b57d/8fd984ea6fe1495147a3303f87fa6e23.fst?1460131758";
|
||||
|
||||
|
@ -55,5 +52,3 @@ describe("MyAvatar", function () {
|
|||
|
||||
});
|
||||
|
||||
jasmine.getEnv().execute();
|
||||
|
|
@ -1,9 +1,12 @@
|
|||
Script.include('../libraries/jasmine/jasmine.js');
|
||||
Script.include('../libraries/jasmine/hifi-boot.js');
|
||||
Script.include('../../system/libraries/utils.js');
|
||||
Script.include('../../../system/libraries/utils.js');
|
||||
|
||||
describe('Bind', function() {
|
||||
it('functions should have bind available', function() {
|
||||
it('exists for functions', function() {
|
||||
var FUNC = 'function';
|
||||
expect(typeof(function() {}.bind)).toEqual(FUNC);
|
||||
});
|
||||
|
||||
it('should allow for setting context of this', function() {
|
||||
var foo = 'bar';
|
||||
|
||||
function callAnotherFn(anotherFn) {
|
||||
|
@ -22,10 +25,6 @@ describe('Bind', function() {
|
|||
|
||||
var instance = new TestConstructor();
|
||||
|
||||
expect(typeof(instance.doSomething.bind) !== 'undefined');
|
||||
expect(instance.doSomething()).toEqual(foo);
|
||||
});
|
||||
});
|
||||
|
||||
jasmine.getEnv().execute();
|
||||
Script.stop();
|
53
scripts/developer/tests/unit_tests/entityUnitTests.js
Normal file
53
scripts/developer/tests/unit_tests/entityUnitTests.js
Normal file
|
@ -0,0 +1,53 @@
|
|||
describe('Entity', function() {
|
||||
var center = Vec3.sum(
|
||||
MyAvatar.position,
|
||||
Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))
|
||||
);
|
||||
var boxEntity;
|
||||
var boxProps = {
|
||||
type: 'Box',
|
||||
color: {
|
||||
red: 255,
|
||||
green: 255,
|
||||
blue: 255,
|
||||
},
|
||||
position: center,
|
||||
dimensions: {
|
||||
x: 1,
|
||||
y: 1,
|
||||
z: 1,
|
||||
},
|
||||
};
|
||||
|
||||
beforeEach(function() {
|
||||
boxEntity = Entities.addEntity(boxProps);
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
Entities.deleteEntity(boxEntity);
|
||||
boxEntity = null;
|
||||
});
|
||||
|
||||
it('can be added programmatically', function() {
|
||||
expect(typeof(boxEntity)).toEqual('string');
|
||||
});
|
||||
|
||||
it('instantiates itself correctly', function() {
|
||||
var props = Entities.getEntityProperties(boxEntity);
|
||||
expect(props.type).toEqual(boxProps.type);
|
||||
});
|
||||
|
||||
it('can be modified after creation', function() {
|
||||
var newPos = {
|
||||
x: boxProps.position.x,
|
||||
y: boxProps.position.y,
|
||||
z: boxProps.position.z + 1.0,
|
||||
};
|
||||
Entities.editEntity(boxEntity, {
|
||||
position: newPos,
|
||||
});
|
||||
|
||||
var props = Entities.getEntityProperties(boxEntity);
|
||||
expect(Math.round(props.position.z)).toEqual(Math.round(newPos.z));
|
||||
});
|
||||
});
|
13
scripts/developer/tests/unit_tests/testRunner.js
Normal file
13
scripts/developer/tests/unit_tests/testRunner.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
// Include testing library
|
||||
Script.include('../../libraries/jasmine/jasmine.js');
|
||||
Script.include('../../libraries/jasmine/hifi-boot.js')
|
||||
|
||||
// Include unit tests
|
||||
// FIXME: Figure out why jasmine done() is not working.
|
||||
// Script.include('avatarUnitTests.js');
|
||||
Script.include('bindUnitTest.js');
|
||||
Script.include('entityUnitTests.js');
|
||||
|
||||
// Run the tests
|
||||
jasmine.getEnv().execute();
|
||||
Script.stop();
|
Loading…
Reference in a new issue