mirror of
https://github.com/lubosz/overte.git
synced 2025-04-08 04:42:20 +02:00
Merge pull request #11455 from utkarshgautamnyu/feat/JS-Baker
Feat/JS-Baker
This commit is contained in:
commit
8a331e29a2
9 changed files with 480 additions and 3 deletions
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include <ClientServerUtils.h>
|
||||
#include <FBXBaker.h>
|
||||
#include <JSBaker.h>
|
||||
#include <NodeType.h>
|
||||
#include <SharedUtil.h>
|
||||
#include <PathUtils.h>
|
||||
|
@ -49,10 +50,12 @@ static const int INTERFACE_RUNNING_CHECK_FREQUENCY_MS = 1000;
|
|||
|
||||
const QString ASSET_SERVER_LOGGING_TARGET_NAME = "asset-server";
|
||||
|
||||
static const QStringList BAKEABLE_MODEL_EXTENSIONS = { "fbx" };
|
||||
static const QStringList BAKEABLE_MODEL_EXTENSIONS = {"fbx"};
|
||||
static QStringList BAKEABLE_TEXTURE_EXTENSIONS;
|
||||
static const QStringList BAKEABLE_SCRIPT_EXTENSIONS = {"js"};
|
||||
static const QString BAKED_MODEL_SIMPLE_NAME = "asset.fbx";
|
||||
static const QString BAKED_TEXTURE_SIMPLE_NAME = "texture.ktx";
|
||||
static const QString BAKED_SCRIPT_SIMPLE_NAME = "asset.js";
|
||||
|
||||
void AssetServer::bakeAsset(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath) {
|
||||
qDebug() << "Starting bake for: " << assetPath << assetHash;
|
||||
|
@ -99,6 +102,8 @@ std::pair<BakingStatus, QString> AssetServer::getAssetStatus(const AssetPath& pa
|
|||
bakedFilename = BAKED_MODEL_SIMPLE_NAME;
|
||||
} else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(extension.toLocal8Bit()) && hasMetaFile(hash)) {
|
||||
bakedFilename = BAKED_TEXTURE_SIMPLE_NAME;
|
||||
} else if (BAKEABLE_SCRIPT_EXTENSIONS.contains(extension)) {
|
||||
bakedFilename = BAKED_SCRIPT_SIMPLE_NAME;
|
||||
} else {
|
||||
return { Irrelevant, "" };
|
||||
}
|
||||
|
@ -186,6 +191,8 @@ bool AssetServer::needsToBeBaked(const AssetPath& path, const AssetHash& assetHa
|
|||
bakedFilename = BAKED_MODEL_SIMPLE_NAME;
|
||||
} else if (loaded && BAKEABLE_TEXTURE_EXTENSIONS.contains(extension.toLocal8Bit())) {
|
||||
bakedFilename = BAKED_TEXTURE_SIMPLE_NAME;
|
||||
} else if (BAKEABLE_SCRIPT_EXTENSIONS.contains(extension)) {
|
||||
bakedFilename = BAKED_SCRIPT_SIMPLE_NAME;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -488,6 +495,8 @@ void AssetServer::handleGetMappingOperation(ReceivedMessage& message, SharedNode
|
|||
bakedRootFile = BAKED_MODEL_SIMPLE_NAME;
|
||||
} else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(assetPathExtension.toLocal8Bit())) {
|
||||
bakedRootFile = BAKED_TEXTURE_SIMPLE_NAME;
|
||||
} else if (BAKEABLE_SCRIPT_EXTENSIONS.contains(assetPathExtension)) {
|
||||
bakedRootFile = BAKED_SCRIPT_SIMPLE_NAME;
|
||||
}
|
||||
|
||||
auto originalAssetHash = it->second;
|
||||
|
@ -1141,6 +1150,7 @@ bool AssetServer::renameMapping(AssetPath oldPath, AssetPath newPath) {
|
|||
|
||||
static const QString BAKED_ASSET_SIMPLE_FBX_NAME = "asset.fbx";
|
||||
static const QString BAKED_ASSET_SIMPLE_TEXTURE_NAME = "texture.ktx";
|
||||
static const QString BAKED_ASSET_SIMPLE_JS_NAME = "asset.js";
|
||||
|
||||
QString getBakeMapping(const AssetHash& hash, const QString& relativeFilePath) {
|
||||
return HIDDEN_BAKED_CONTENT_FOLDER + hash + "/" + relativeFilePath;
|
||||
|
@ -1204,14 +1214,14 @@ void AssetServer::handleCompletedBake(QString originalAssetHash, QString origina
|
|||
// setup the mapping for this bake file
|
||||
auto relativeFilePath = QUrl(filePath).fileName();
|
||||
qDebug() << "Relative file path is: " << relativeFilePath;
|
||||
|
||||
if (relativeFilePath.endsWith(".fbx", Qt::CaseInsensitive)) {
|
||||
// for an FBX file, we replace the filename with the simple name
|
||||
// (to handle the case where two mapped assets have the same hash but different names)
|
||||
relativeFilePath = BAKED_ASSET_SIMPLE_FBX_NAME;
|
||||
} else if (relativeFilePath.endsWith(".js", Qt::CaseInsensitive)) {
|
||||
relativeFilePath = BAKED_ASSET_SIMPLE_JS_NAME;
|
||||
} else if (!originalAssetPath.endsWith(".fbx", Qt::CaseInsensitive)) {
|
||||
relativeFilePath = BAKED_ASSET_SIMPLE_TEXTURE_NAME;
|
||||
|
||||
}
|
||||
|
||||
QString bakeMapping = getBakeMapping(originalAssetHash, relativeFilePath);
|
||||
|
@ -1364,6 +1374,8 @@ bool AssetServer::setBakingEnabled(const AssetPathList& paths, bool enabled) {
|
|||
bakedFilename = BAKED_MODEL_SIMPLE_NAME;
|
||||
} else if (BAKEABLE_TEXTURE_EXTENSIONS.contains(extension.toLocal8Bit()) && hasMetaFile(hash)) {
|
||||
bakedFilename = BAKED_TEXTURE_SIMPLE_NAME;
|
||||
} else if (BAKEABLE_SCRIPT_EXTENSIONS.contains(extension)) {
|
||||
bakedFilename = BAKED_SCRIPT_SIMPLE_NAME;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <FBXBaker.h>
|
||||
#include <PathUtils.h>
|
||||
#include <JSBaker.h>
|
||||
|
||||
BakeAssetTask::BakeAssetTask(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath) :
|
||||
_assetHash(assetHash),
|
||||
|
@ -52,6 +53,10 @@ void BakeAssetTask::run() {
|
|||
_baker = std::unique_ptr<FBXBaker> {
|
||||
new FBXBaker(QUrl("file:///" + _filePath), fn, tempOutputDir)
|
||||
};
|
||||
} else if (_assetPath.endsWith(".js", Qt::CaseInsensitive)) {
|
||||
_baker = std::unique_ptr<JSBaker>{
|
||||
new JSBaker(QUrl("file:///" + _filePath), PathUtils::generateTemporaryDir())
|
||||
};
|
||||
} else {
|
||||
tempOutputDir = PathUtils::generateTemporaryDir();
|
||||
_baker = std::unique_ptr<TextureBaker> {
|
||||
|
|
247
libraries/baking/src/JSBaker.cpp
Normal file
247
libraries/baking/src/JSBaker.cpp
Normal file
|
@ -0,0 +1,247 @@
|
|||
//
|
||||
// JSBaker.cpp
|
||||
// libraries/baking/src
|
||||
//
|
||||
// Created by Utkarsh Gautam on 9/18/17.
|
||||
// Copyright 2017 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 <PathUtils.h>
|
||||
|
||||
#include "JSBaker.h"
|
||||
#include "Baker.h"
|
||||
|
||||
const int ASCII_CHARACTERS_UPPER_LIMIT = 126;
|
||||
|
||||
JSBaker::JSBaker(const QUrl& jsURL, const QString& bakedOutputDir) :
|
||||
_jsURL(jsURL),
|
||||
_bakedOutputDir(bakedOutputDir)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void JSBaker::bake() {
|
||||
qCDebug(js_baking) << "JS Baker " << _jsURL << "bake starting";
|
||||
|
||||
// Import file to start baking
|
||||
QFile jsFile(_jsURL.toLocalFile());
|
||||
if (!jsFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
handleError("Error opening " + _jsURL.fileName() + " for reading");
|
||||
return;
|
||||
}
|
||||
|
||||
// Read file into an array
|
||||
QByteArray inputJS = jsFile.readAll();
|
||||
QByteArray outputJS;
|
||||
|
||||
// Call baking on inputJS and store result in outputJS
|
||||
bool success = bakeJS(inputJS, outputJS);
|
||||
if (!success) {
|
||||
qCDebug(js_baking) << "Bake Failed";
|
||||
handleError("Unterminated multi-line comment");
|
||||
return;
|
||||
}
|
||||
|
||||
// Bake Successful. Export the file
|
||||
auto fileName = _jsURL.fileName();
|
||||
auto baseName = fileName.left(fileName.lastIndexOf('.'));
|
||||
auto bakedFilename = baseName + BAKED_JS_EXTENSION;
|
||||
|
||||
_bakedJSFilePath = _bakedOutputDir + "/" + bakedFilename;
|
||||
|
||||
QFile bakedFile;
|
||||
bakedFile.setFileName(_bakedJSFilePath);
|
||||
if (!bakedFile.open(QIODevice::WriteOnly)) {
|
||||
handleError("Error opening " + _bakedJSFilePath + " for writing");
|
||||
return;
|
||||
}
|
||||
|
||||
bakedFile.write(outputJS);
|
||||
|
||||
// Export successful
|
||||
_outputFiles.push_back(_bakedJSFilePath);
|
||||
qCDebug(js_baking) << "Exported" << _jsURL << "minified to" << _bakedJSFilePath;
|
||||
|
||||
// emit signal to indicate the JS baking is finished
|
||||
emit finished();
|
||||
}
|
||||
|
||||
bool JSBaker::bakeJS(const QByteArray& inputFile, QByteArray& outputFile) {
|
||||
// Read from inputFile and write to outputFile per character
|
||||
QTextStream in(inputFile, QIODevice::ReadOnly);
|
||||
QTextStream out(outputFile, QIODevice::WriteOnly);
|
||||
|
||||
// Algorithm requires the knowledge of previous and next character for each character read
|
||||
QChar currentCharacter;
|
||||
QChar nextCharacter;
|
||||
// Initialize previousCharacter with new line
|
||||
QChar previousCharacter = '\n';
|
||||
|
||||
in >> currentCharacter;
|
||||
|
||||
while (!in.atEnd()) {
|
||||
in >> nextCharacter;
|
||||
|
||||
if (currentCharacter == '\r') {
|
||||
out << '\n';
|
||||
} else if (currentCharacter == '/') {
|
||||
// Check if single line comment i.e. //
|
||||
if (nextCharacter == '/') {
|
||||
handleSingleLineComments(in);
|
||||
|
||||
//Start fresh after handling comments
|
||||
previousCharacter = '\n';
|
||||
in >> currentCharacter;
|
||||
continue;
|
||||
} else if (nextCharacter == '*') {
|
||||
// Check if multi line comment i.e. /*
|
||||
bool success = handleMultiLineComments(in);
|
||||
if (!success) {
|
||||
// Errors present return false
|
||||
return false;
|
||||
}
|
||||
//Start fresh after handling comments
|
||||
previousCharacter = '\n';
|
||||
in >> currentCharacter;
|
||||
continue;
|
||||
} else {
|
||||
// If '/' is not followed by '/' or '*' print '/'
|
||||
out << currentCharacter;
|
||||
}
|
||||
} else if (isSpaceOrTab(currentCharacter)) {
|
||||
// Check if white space or tab
|
||||
|
||||
// Skip multiple spaces or tabs
|
||||
while (isSpaceOrTab(nextCharacter)) {
|
||||
in >> nextCharacter;
|
||||
if (nextCharacter == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// check if space can be omitted
|
||||
if (!canOmitSpace(previousCharacter, nextCharacter)) {
|
||||
out << ' ';
|
||||
}
|
||||
} else if (currentCharacter == '\n') {
|
||||
// Check if new line
|
||||
|
||||
//Skip multiple new lines
|
||||
//Skip new line followed by space or tab
|
||||
while (nextCharacter == '\n' || isSpaceOrTab(nextCharacter)) {
|
||||
in >> nextCharacter;
|
||||
}
|
||||
|
||||
// Check if new line can be omitted
|
||||
if (!canOmitNewLine(previousCharacter, nextCharacter)) {
|
||||
out << '\n';
|
||||
}
|
||||
} else if (isQuote(currentCharacter)) {
|
||||
// Print the current quote and nextCharacter as is
|
||||
out << currentCharacter;
|
||||
out << nextCharacter;
|
||||
|
||||
// Store the type of quote we are processing
|
||||
QChar quote = currentCharacter;
|
||||
|
||||
// Don't modify the quoted strings
|
||||
while (nextCharacter != quote) {
|
||||
in >> nextCharacter;
|
||||
out << nextCharacter;
|
||||
}
|
||||
|
||||
//Start fresh after handling quoted strings
|
||||
previousCharacter = nextCharacter;
|
||||
in >> currentCharacter;
|
||||
continue;
|
||||
} else {
|
||||
// In all other cases write the currentCharacter to outputFile
|
||||
out << currentCharacter;
|
||||
}
|
||||
|
||||
previousCharacter = currentCharacter;
|
||||
currentCharacter = nextCharacter;
|
||||
}
|
||||
|
||||
//write currentCharacter to output file when nextCharacter reaches EOF
|
||||
if (currentCharacter != '\n') {
|
||||
out << currentCharacter;
|
||||
}
|
||||
|
||||
// Successful bake. Return true
|
||||
return true;
|
||||
}
|
||||
|
||||
void JSBaker::handleSingleLineComments(QTextStream& in) {
|
||||
QChar character;
|
||||
while (!in.atEnd()) {
|
||||
in >> character;
|
||||
if (character == '\n') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool JSBaker::handleMultiLineComments(QTextStream& in) {
|
||||
QChar character;
|
||||
while (!in.atEnd()) {
|
||||
in >> character;
|
||||
if (character == '*') {
|
||||
if (in.read(1) == '/') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JSBaker::canOmitSpace(QChar previousCharacter, QChar nextCharacter) {
|
||||
return(!((isAlphanum(previousCharacter) || isNonAscii(previousCharacter) || isSpecialCharacter(previousCharacter)) &&
|
||||
(isAlphanum(nextCharacter) || isNonAscii(nextCharacter) || isSpecialCharacter(nextCharacter)))
|
||||
);
|
||||
}
|
||||
|
||||
bool JSBaker::canOmitNewLine(QChar previousCharacter, QChar nextCharacter) {
|
||||
return (!((isAlphanum(previousCharacter) || isNonAscii(previousCharacter) || isSpecialCharacterPrevious(previousCharacter)) &&
|
||||
(isAlphanum(nextCharacter) || isNonAscii(nextCharacter) || isSpecialCharacterNext(nextCharacter)))
|
||||
);
|
||||
}
|
||||
|
||||
//Check if character is alphabet, number or one of the following: '_', '$', '\\' or a non-ASCII character
|
||||
bool JSBaker::isAlphanum(QChar c) {
|
||||
return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z')
|
||||
|| c == '_' || c == '$' || c == '\\' || c > ASCII_CHARACTERS_UPPER_LIMIT);
|
||||
}
|
||||
|
||||
bool JSBaker::isNonAscii(QChar c) {
|
||||
return ((int)c.toLatin1() > ASCII_CHARACTERS_UPPER_LIMIT);
|
||||
}
|
||||
|
||||
// If previous and next characters are special characters, don't omit space
|
||||
bool JSBaker::isSpecialCharacter(QChar c) {
|
||||
return (c == '\'' || c == '$' || c == '_' || c == '/' || c== '+' || c == '-');
|
||||
}
|
||||
|
||||
// If previous character is a special character, maybe don't omit new line (depends on next character as well)
|
||||
bool JSBaker::isSpecialCharacterPrevious(QChar c) {
|
||||
return (c == '\'' || c == '$' || c == '_' || c == '}' || c == ']' || c == ')' || c == '+' || c == '-'
|
||||
|| c == '"' || c == "'");
|
||||
}
|
||||
|
||||
// If next character is a special character, maybe don't omit new line (depends on previous character as well)
|
||||
bool JSBaker::isSpecialCharacterNext(QChar c) {
|
||||
return (c == '\'' || c == '$' || c == '_' || c == '{' || c == '[' || c == '(' || c == '+' || c == '-');
|
||||
}
|
||||
|
||||
// Check if white space or tab
|
||||
bool JSBaker::isSpaceOrTab(QChar c) {
|
||||
return (c == ' ' || c == '\t');
|
||||
}
|
||||
|
||||
// Check If the currentCharacter is " or ' or `
|
||||
bool JSBaker::isQuote(QChar c) {
|
||||
return (c == '"' || c == "'" || c == '`');
|
||||
}
|
49
libraries/baking/src/JSBaker.h
Normal file
49
libraries/baking/src/JSBaker.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// JSBaker.h
|
||||
// libraries/baking/src
|
||||
//
|
||||
// Created by Utkarsh Gautam on 9/18/17.
|
||||
// Copyright 2017 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_JSBaker_h
|
||||
#define hifi_JSBaker_h
|
||||
|
||||
#include "Baker.h"
|
||||
#include "JSBakingLoggingCategory.h"
|
||||
|
||||
static const QString BAKED_JS_EXTENSION = ".baked.js";
|
||||
|
||||
class JSBaker : public Baker {
|
||||
Q_OBJECT
|
||||
public:
|
||||
JSBaker(const QUrl& jsURL, const QString& bakedOutputDir);
|
||||
static bool bakeJS(const QByteArray& inputFile, QByteArray& outputFile);
|
||||
|
||||
public slots:
|
||||
virtual void bake() override;
|
||||
|
||||
private:
|
||||
QUrl _jsURL;
|
||||
QString _bakedOutputDir;
|
||||
QString _bakedJSFilePath;
|
||||
|
||||
static void handleSingleLineComments(QTextStream& in);
|
||||
static bool handleMultiLineComments(QTextStream& in);
|
||||
|
||||
static bool canOmitSpace(QChar previousCharacter, QChar nextCharacter);
|
||||
static bool canOmitNewLine(QChar previousCharacter, QChar nextCharacter);
|
||||
|
||||
static bool isAlphanum(QChar c);
|
||||
static bool isNonAscii(QChar c);
|
||||
static bool isSpecialCharacter(QChar c);
|
||||
static bool isSpecialCharacterPrevious(QChar c);
|
||||
static bool isSpecialCharacterNext(QChar c);
|
||||
static bool isSpaceOrTab(QChar c);
|
||||
static bool isQuote(QChar c);
|
||||
};
|
||||
|
||||
#endif // !hifi_JSBaker_h
|
14
libraries/baking/src/JSBakingLoggingCategory.cpp
Normal file
14
libraries/baking/src/JSBakingLoggingCategory.cpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// JSBakingLoggingCategory.cpp
|
||||
// libraries/baking/src
|
||||
//
|
||||
// Created by Utkarsh Gautam on 9/18/17.
|
||||
// Copyright 2017 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 "JSBakingLoggingCategory.h"
|
||||
|
||||
Q_LOGGING_CATEGORY(js_baking, "hifi.JS-baking");
|
19
libraries/baking/src/JSBakingLoggingCategory.h
Normal file
19
libraries/baking/src/JSBakingLoggingCategory.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// JSBakingLoggingCategory.h
|
||||
// libraries/baking/src
|
||||
//
|
||||
// Created by Utkarsh Gautam on 9/18/17.
|
||||
// Copyright 2017 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_JSBakingLoggingCategory_h
|
||||
#define hifi_JSBakingLoggingCategory_h
|
||||
|
||||
#include <QtCore/QLoggingCategory>
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(js_baking)
|
||||
|
||||
#endif // hifi_ModelBakingLoggingCategory_h
|
10
tests/baking/CMakeLists.txt
Normal file
10
tests/baking/CMakeLists.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
|
||||
# Declare dependencies
|
||||
macro (setup_testcase_dependencies)
|
||||
# link in the shared libraries
|
||||
link_hifi_libraries(shared baking)
|
||||
|
||||
package_libraries_for_deployment()
|
||||
endmacro ()
|
||||
|
||||
setup_hifi_testcase()
|
92
tests/baking/src/JSBakerTest.cpp
Normal file
92
tests/baking/src/JSBakerTest.cpp
Normal file
|
@ -0,0 +1,92 @@
|
|||
//
|
||||
// JSBakerTest.cpp
|
||||
// tests/networking/src
|
||||
//
|
||||
// Created by Utkarsh Gautam on 09/26/17.
|
||||
// Copyright 2015 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 "JSBakerTest.h"
|
||||
QTEST_MAIN(JSBakerTest)
|
||||
|
||||
void JSBakerTest::setTestCases() {
|
||||
// Test cases contain a std::pair(input, desiredOutput)
|
||||
|
||||
_testCases.emplace_back("var a=1;", "var a=1;");
|
||||
_testCases.emplace_back("var a=1;//single line comment\nvar b=2;", "var a=1;var b=2;");
|
||||
_testCases.emplace_back("a\rb", "a\nb");
|
||||
_testCases.emplace_back("a/*multi\n line \n comment*/ b", "ab");
|
||||
_testCases.emplace_back("a/b", "a/b");
|
||||
_testCases.emplace_back("var a = 1;", "var a=1;"); // Multiple spaces omitted
|
||||
_testCases.emplace_back("var a=\t\t\t1;", "var a=1;"); // Multiple tabs omitted
|
||||
|
||||
// Cases for space not omitted
|
||||
_testCases.emplace_back("var x", "var x");
|
||||
_testCases.emplace_back("a '", "a '");
|
||||
_testCases.emplace_back("a $", "a $");
|
||||
_testCases.emplace_back("a _", "a _");
|
||||
_testCases.emplace_back("a /", "a /");
|
||||
_testCases.emplace_back("a 1", "a 1");
|
||||
_testCases.emplace_back("1 a", "1 a");
|
||||
_testCases.emplace_back("$ a", "$ a");
|
||||
_testCases.emplace_back("_ a", "_ a");
|
||||
_testCases.emplace_back("/ a", "/ a");
|
||||
_testCases.emplace_back("$ $", "$ $");
|
||||
_testCases.emplace_back("_ _", "_ _");
|
||||
_testCases.emplace_back("/ /", "/ /");
|
||||
|
||||
_testCases.emplace_back("a\n\n\n\nb", "a\nb"); // Skip multiple new lines
|
||||
_testCases.emplace_back("a\n\n b", "a\nb"); // Skip multiple new lines followed by whitespace
|
||||
_testCases.emplace_back("a\n\n b", "a\nb"); // Skip multiple new lines followed by tab
|
||||
|
||||
//Cases for new line not omitted
|
||||
_testCases.emplace_back("a\nb", "a\nb");
|
||||
_testCases.emplace_back("a\n9", "a\n9");
|
||||
_testCases.emplace_back("9\na", "9\na");
|
||||
_testCases.emplace_back("a\n$", "a\n$");
|
||||
_testCases.emplace_back("a\n[", "a\n[");
|
||||
_testCases.emplace_back("a\n{", "a\n{");
|
||||
_testCases.emplace_back("a\n(", "a\n(");
|
||||
_testCases.emplace_back("a\n+", "a\n+");
|
||||
_testCases.emplace_back("a\n'", "a\n'");
|
||||
_testCases.emplace_back("a\n-", "a\n-");
|
||||
_testCases.emplace_back("$\na", "$\na");
|
||||
_testCases.emplace_back("$\na", "$\na");
|
||||
_testCases.emplace_back("_\na", "_\na");
|
||||
_testCases.emplace_back("]\na", "]\na");
|
||||
_testCases.emplace_back("}\na", "}\na");
|
||||
_testCases.emplace_back(")\na", ")\na");
|
||||
_testCases.emplace_back("+\na", "+\na");
|
||||
_testCases.emplace_back("-\na", "-\na");
|
||||
|
||||
// Cases to check quoted strings are not modified
|
||||
_testCases.emplace_back("'abcd1234$%^&[](){}'\na", "'abcd1234$%^&[](){}'\na");
|
||||
_testCases.emplace_back("\"abcd1234$%^&[](){}\"\na", "\"abcd1234$%^&[](){}\"\na");
|
||||
_testCases.emplace_back("`abcd1234$%^&[](){}`\na", "`abcd1234$%^&[](){}`a");
|
||||
|
||||
// Edge Cases
|
||||
|
||||
//No semicolon to terminate an expression, instead a new line used for termination
|
||||
_testCases.emplace_back("var x=5\nvar y=6;", "var x=5\nvar y=6;");
|
||||
|
||||
//a + ++b is minified as a+ ++b.
|
||||
_testCases.emplace_back("a + ++b", "a + ++b");
|
||||
|
||||
//a - --b is minified as a- --b.
|
||||
_testCases.emplace_back("a - --b", "a - --b");
|
||||
}
|
||||
|
||||
void JSBakerTest::testJSBaking() {
|
||||
|
||||
for (int i = 0;i < _testCases.size();i++) {
|
||||
QByteArray output;
|
||||
auto input = _testCases.at(i).first;
|
||||
JSBaker::bakeJS(input, output);
|
||||
|
||||
auto desiredOutput = _testCases.at(i).second;
|
||||
QCOMPARE(output, desiredOutput);
|
||||
}
|
||||
}
|
29
tests/baking/src/JSBakerTest.h
Normal file
29
tests/baking/src/JSBakerTest.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
//
|
||||
// JSBakerTest.h
|
||||
// tests/networking/src
|
||||
//
|
||||
// Created by Utkarsh Gautam on 9/26/17.
|
||||
// Copyright 2015 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_JSBakerTest_h
|
||||
#define hifi_JSBakerTest_h
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
#include <JSBaker.h>
|
||||
|
||||
class JSBakerTest : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void setTestCases();
|
||||
void testJSBaking();
|
||||
|
||||
private:
|
||||
std::vector<std::pair<QByteArray, QByteArray>> _testCases;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue