mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 10:00:18 +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
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// Developer >> Tests >>>
|
||||||
|
MenuWrapper* testMenu = developerMenu->addMenu("Tests");
|
||||||
|
addActionToQMenuAndActionHash(testMenu, MenuOption::RunClientScriptTests, 0, dialogsManager.data(), SLOT(showTestingResults()));
|
||||||
|
|
||||||
// Developer > Timing >>>
|
// Developer > Timing >>>
|
||||||
MenuWrapper* timingMenu = developerMenu->addMenu("Timing");
|
MenuWrapper* timingMenu = developerMenu->addMenu("Timing");
|
||||||
|
|
|
@ -172,6 +172,7 @@ namespace MenuOption {
|
||||||
const QString ResetAvatarSize = "Reset Avatar Size";
|
const QString ResetAvatarSize = "Reset Avatar Size";
|
||||||
const QString ResetSensors = "Reset Sensors";
|
const QString ResetSensors = "Reset Sensors";
|
||||||
const QString RunningScripts = "Running Scripts...";
|
const QString RunningScripts = "Running Scripts...";
|
||||||
|
const QString RunClientScriptTests = "Run Client Script Tests";
|
||||||
const QString RunTimingTests = "Run Timing Tests";
|
const QString RunTimingTests = "Run Timing Tests";
|
||||||
const QString ScriptEditor = "Script Editor...";
|
const QString ScriptEditor = "Script Editor...";
|
||||||
const QString ScriptedMotorControl = "Enable Scripted Motor Control";
|
const QString ScriptedMotorControl = "Enable Scripted Motor Control";
|
||||||
|
|
|
@ -158,6 +158,15 @@ void DialogsManager::showScriptEditor() {
|
||||||
_scriptEditor->raise();
|
_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() {
|
void DialogsManager::showDomainConnectionDialog() {
|
||||||
// if the dialog already exists we delete it so the connection data is refreshed
|
// if the dialog already exists we delete it so the connection data is refreshed
|
||||||
if (_domainConnectionDialog) {
|
if (_domainConnectionDialog) {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
|
|
||||||
#include "HMDToolsDialog.h"
|
#include "HMDToolsDialog.h"
|
||||||
|
#include "TestingDialog.h"
|
||||||
|
|
||||||
class AnimationsDialog;
|
class AnimationsDialog;
|
||||||
class AttachmentsDialog;
|
class AttachmentsDialog;
|
||||||
|
@ -26,6 +27,7 @@ class DiskCacheEditor;
|
||||||
class LodToolsDialog;
|
class LodToolsDialog;
|
||||||
class OctreeStatsDialog;
|
class OctreeStatsDialog;
|
||||||
class ScriptEditorWindow;
|
class ScriptEditorWindow;
|
||||||
|
class TestingDialog;
|
||||||
class QMessageBox;
|
class QMessageBox;
|
||||||
class DomainConnectionDialog;
|
class DomainConnectionDialog;
|
||||||
|
|
||||||
|
@ -38,6 +40,7 @@ public:
|
||||||
QPointer<HMDToolsDialog> getHMDToolsDialog() const { return _hmdToolsDialog; }
|
QPointer<HMDToolsDialog> getHMDToolsDialog() const { return _hmdToolsDialog; }
|
||||||
QPointer<LodToolsDialog> getLodToolsDialog() const { return _lodToolsDialog; }
|
QPointer<LodToolsDialog> getLodToolsDialog() const { return _lodToolsDialog; }
|
||||||
QPointer<OctreeStatsDialog> getOctreeStatsDialog() const { return _octreeStatsDialog; }
|
QPointer<OctreeStatsDialog> getOctreeStatsDialog() const { return _octreeStatsDialog; }
|
||||||
|
QPointer<TestingDialog> getTestingDialog() const { return _testingDialog; }
|
||||||
void emitAddressBarShown(bool visible) { emit addressBarShown(visible); }
|
void emitAddressBarShown(bool visible) { emit addressBarShown(visible); }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
@ -55,6 +58,7 @@ public slots:
|
||||||
void hmdTools(bool showTools);
|
void hmdTools(bool showTools);
|
||||||
void showScriptEditor();
|
void showScriptEditor();
|
||||||
void showDomainConnectionDialog();
|
void showDomainConnectionDialog();
|
||||||
|
void showTestingResults();
|
||||||
|
|
||||||
// Application Update
|
// Application Update
|
||||||
void showUpdateDialog();
|
void showUpdateDialog();
|
||||||
|
@ -83,6 +87,7 @@ private:
|
||||||
QPointer<LodToolsDialog> _lodToolsDialog;
|
QPointer<LodToolsDialog> _lodToolsDialog;
|
||||||
QPointer<OctreeStatsDialog> _octreeStatsDialog;
|
QPointer<OctreeStatsDialog> _octreeStatsDialog;
|
||||||
QPointer<ScriptEditorWindow> _scriptEditor;
|
QPointer<ScriptEditorWindow> _scriptEditor;
|
||||||
|
QPointer<TestingDialog> _testingDialog;
|
||||||
QPointer<DomainConnectionDialog> _domainConnectionDialog;
|
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() {
|
(function() {
|
||||||
|
var BALLOT_X = '✗';
|
||||||
|
var CHECKMARK = '✓';
|
||||||
|
var DOWN_RIGHT_ARROW = '↳';
|
||||||
|
var PASSED = 'passed';
|
||||||
|
var lastSpecStartTime;
|
||||||
function ConsoleReporter(options) {
|
function ConsoleReporter(options) {
|
||||||
|
var startTime = new Date().getTime();
|
||||||
|
var errorCount = 0;
|
||||||
this.jasmineStarted = function (obj) {
|
this.jasmineStarted = function (obj) {
|
||||||
print("jasmineStarted: numSpecs = " + obj.totalSpecsDefined);
|
print('Jasmine started with ' + obj.totalSpecsDefined + ' tests.');
|
||||||
};
|
};
|
||||||
this.jasmineDone = function (obj) {
|
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) {
|
this.suiteStarted = function(obj) {
|
||||||
print("suiteStarted: \"" + obj.fullName + "\"");
|
print(obj.fullName);
|
||||||
};
|
};
|
||||||
this.suiteDone = function(obj) {
|
this.suiteDone = function(obj) {
|
||||||
print("suiteDone: \"" + obj.fullName + "\" " + obj.status);
|
print('');
|
||||||
};
|
};
|
||||||
this.specStarted = function(obj) {
|
this.specStarted = function(obj) {
|
||||||
print("specStarted: \"" + obj.fullName + "\"");
|
lastSpecStartTime = new Date().getTime();
|
||||||
};
|
};
|
||||||
this.specDone = function(obj) {
|
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;
|
var specErrors = obj.failedExpectations.length;
|
||||||
for (i = 0; i < l; i++) {
|
errorCount += specErrors;
|
||||||
print(" " + obj.failedExpectations[i].message);
|
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;
|
return this;
|
||||||
|
@ -44,10 +67,11 @@
|
||||||
|
|
||||||
function extend(destination, source) {
|
function extend(destination, source) {
|
||||||
for (var property in source) {
|
for (var property in source) {
|
||||||
|
if (source.hasOwnProperty(property)) {
|
||||||
destination[property] = source[property];
|
destination[property] = source[property];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return destination;
|
return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
}());
|
}());
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,4 @@
|
||||||
|
|
||||||
Script.include("../libraries/jasmine/jasmine.js");
|
|
||||||
Script.include("../libraries/jasmine/hifi-boot.js");
|
|
||||||
|
|
||||||
// Art3mis
|
// Art3mis
|
||||||
var DEFAULT_AVATAR_URL = "https://hifi-metaverse.s3-us-west-1.amazonaws.com/marketplace/contents/e76946cc-c272-4adf-9bb6-02cde0a4b57d/8fd984ea6fe1495147a3303f87fa6e23.fst?1460131758";
|
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('../../../system/libraries/utils.js');
|
||||||
Script.include('../libraries/jasmine/hifi-boot.js');
|
|
||||||
Script.include('../../system/libraries/utils.js');
|
|
||||||
|
|
||||||
describe('Bind', function() {
|
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';
|
var foo = 'bar';
|
||||||
|
|
||||||
function callAnotherFn(anotherFn) {
|
function callAnotherFn(anotherFn) {
|
||||||
|
@ -22,10 +25,6 @@ describe('Bind', function() {
|
||||||
|
|
||||||
var instance = new TestConstructor();
|
var instance = new TestConstructor();
|
||||||
|
|
||||||
expect(typeof(instance.doSomething.bind) !== 'undefined');
|
|
||||||
expect(instance.doSomething()).toEqual(foo);
|
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