Use JPG->PNG trick to keep file sizes down.

This commit is contained in:
NissimHadar 2018-03-05 17:45:51 -08:00
parent 5a79f272f3
commit 84815fadae
5 changed files with 43 additions and 69 deletions

View file

@ -12,6 +12,8 @@
#include <assert.h> #include <assert.h>
#include <QtCore/QTextStream> #include <QtCore/QTextStream>
#include <QDirIterator> #include <QDirIterator>
#include <QImageReader>
#include <QImageWriter>
#include <quazip5/quazip.h> #include <quazip5/quazip.h>
#include <quazip5/JlCompress.h> #include <quazip5/JlCompress.h>
@ -20,7 +22,7 @@
extern AutoTester* autoTester; extern AutoTester* autoTester;
Test::Test() { Test::Test() {
QString regex(EXPECTED_IMAGE_PREFIX + QString("\\\\d").repeated(NUM_DIGITS) + IMAGE_FORMAT); QString regex(EXPECTED_IMAGE_PREFIX + QString("\\\\d").repeated(NUM_DIGITS) + ".png");
expectedImageFilenameFormat = QRegularExpression(regex); expectedImageFilenameFormat = QRegularExpression(regex);
@ -194,11 +196,23 @@ void Test::startTestsEvaluation() {
return; return;
} }
// Before any processing - all images are converted to PNGs, as this is the format stored on GitHub
QStringList sortedSnapshotFilenames = createListOfAll_imagesInDirectory("jpg", pathToTestResultsDirectory);
foreach(QString filename, sortedSnapshotFilenames) {
QStringList stringParts = filename.split(".");
copyJPGtoPNG(
pathToTestResultsDirectory + "/" + stringParts[0] + ".jpg",
pathToTestResultsDirectory + "/" + stringParts[0] + ".png"
);
QFile::remove(pathToTestResultsDirectory + "/" + stringParts[0] + ".jpg");
}
// Create two lists. The first is the test results, the second is the expected images // Create two lists. The first is the test results, the second is the expected images
// The expected images are represented as a URL to enabel download from GitHub // The expected images are represented as a URL to enable download from GitHub
// Images that are in the wrong format are ignored. // Images that are in the wrong format are ignored.
QStringList sortedTestResultsFilenames = createListOfAll_IMAGE_FORMAT_imagesInDirectory(pathToTestResultsDirectory); QStringList sortedTestResultsFilenames = createListOfAll_imagesInDirectory("png", pathToTestResultsDirectory);
QStringList expectedImagesURLs; QStringList expectedImagesURLs;
const QString URLPrefix("https://raw.githubusercontent.com"); const QString URLPrefix("https://raw.githubusercontent.com");
@ -212,7 +226,7 @@ void Test::startTestsEvaluation() {
foreach(QString currentFilename, sortedTestResultsFilenames) { foreach(QString currentFilename, sortedTestResultsFilenames) {
QString fullCurrentFilename = pathToTestResultsDirectory + "/" + currentFilename; QString fullCurrentFilename = pathToTestResultsDirectory + "/" + currentFilename;
if (isInSnapshotFilenameFormat(currentFilename)) { if (isInSnapshotFilenameFormat("png", currentFilename)) {
resultImagesFullFilenames << fullCurrentFilename; resultImagesFullFilenames << fullCurrentFilename;
QString expectedImagePartialSourceDirectory = getExpectedImagePartialSourceDirectory(currentFilename); QString expectedImagePartialSourceDirectory = getExpectedImagePartialSourceDirectory(currentFilename);
@ -220,7 +234,7 @@ void Test::startTestsEvaluation() {
// Images are stored on GitHub as ExpectedImage_ddddd.png // Images are stored on GitHub as ExpectedImage_ddddd.png
// Extract the digits at the end of the filename (exluding the file extension) // Extract the digits at the end of the filename (exluding the file extension)
QString expectedImageFilenameTail = currentFilename.left(currentFilename.length() - 4).right(NUM_DIGITS); QString expectedImageFilenameTail = currentFilename.left(currentFilename.length() - 4).right(NUM_DIGITS);
QString expectedImageStoredFilename = EXPECTED_IMAGE_PREFIX + expectedImageFilenameTail + IMAGE_FORMAT; QString expectedImageStoredFilename = EXPECTED_IMAGE_PREFIX + expectedImageFilenameTail + ".png";
QString imageURLString(URLPrefix + "/" + githubUser + "/" + testsRepo + "/" + branch + "/" + QString imageURLString(URLPrefix + "/" + githubUser + "/" + testsRepo + "/" + branch + "/" +
expectedImagePartialSourceDirectory + "/" + expectedImageStoredFilename); expectedImagePartialSourceDirectory + "/" + expectedImageStoredFilename);
@ -351,24 +365,23 @@ void Test::createTest() {
return; return;
} }
QStringList sortedImageFilenames = createListOfAll_IMAGE_FORMAT_imagesInDirectory(imageSourceDirectory); QStringList sortedImageFilenames = createListOfAll_imagesInDirectory("jpg", imageSourceDirectory);
int i = 1; int i = 1;
const int maxImages = pow(10, NUM_DIGITS); const int maxImages = pow(10, NUM_DIGITS);
foreach (QString currentFilename, sortedImageFilenames) { foreach (QString currentFilename, sortedImageFilenames) {
QString fullCurrentFilename = imageSourceDirectory + "/" + currentFilename; QString fullCurrentFilename = imageSourceDirectory + "/" + currentFilename;
if (isInSnapshotFilenameFormat(currentFilename)) { if (isInSnapshotFilenameFormat("jpg", currentFilename)) {
if (i >= maxImages) { if (i >= maxImages) {
messageBox.critical(0, "Error", "More than " + QString::number(maxImages) + " images not supported"); messageBox.critical(0, "Error", "More than " + QString::number(maxImages) + " images not supported");
exit(-1); exit(-1);
} }
QString newFilename = "ExpectedImage_" + QString::number(i - 1).rightJustified(5, '0') + IMAGE_FORMAT; QString newFilename = "ExpectedImage_" + QString::number(i - 1).rightJustified(5, '0') + ".png";
QString imageDestinationDirectory = getExpectedImageDestinationDirectory(currentFilename); QString imageDestinationDirectory = getExpectedImageDestinationDirectory(currentFilename);
QString fullNewFileName = imageDestinationDirectory + "/" + newFilename; QString fullNewFileName = imageDestinationDirectory + "/" + newFilename;
try { try {
QFile::remove(fullNewFileName); copyJPGtoPNG(fullCurrentFilename, fullNewFileName);
QFile::copy(fullCurrentFilename, fullNewFileName);
} catch (...) { } catch (...) {
messageBox.critical(0, "Error", "Could not delete existing file: " + currentFilename + "\nTest creation aborted"); messageBox.critical(0, "Error", "Could not delete existing file: " + currentFilename + "\nTest creation aborted");
exit(-1); exit(-1);
@ -380,45 +393,23 @@ void Test::createTest() {
messageBox.information(0, "Success", "Test images have been created"); messageBox.information(0, "Success", "Test images have been created");
} }
void Test::deleteOldSnapshots() { void Test::copyJPGtoPNG(QString sourceJPGFullFilename, QString destinationPNGFullFilename) {
// Select folder to start recursing from QFile::remove(destinationPNGFullFilename);
QString topLevelDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select root folder for snapshot deletion", ".", QFileDialog::ShowDirsOnly);
if (topLevelDirectory == "") {
return;
}
// Recurse over folders QImageReader reader;
QDirIterator it(topLevelDirectory.toStdString().c_str(), QDirIterator::Subdirectories); reader.setFileName(sourceJPGFullFilename);
while (it.hasNext()) {
QString directory = it.next();
// Only process directories QImage image = reader.read();
QDir dir(directory);
if (!isAValidDirectory(directory)) {
continue;
}
QStringList sortedImageFilenames = createListOfAll_IMAGE_FORMAT_imagesInDirectory(directory); QImageWriter writer;
writer.setFileName(destinationPNGFullFilename);
// Delete any file that is a snapshot (NOT the Expected Images) writer.write(image);
QStringList expectedImages;
QStringList resultImages;
foreach(QString currentFilename, sortedImageFilenames) {
QString fullCurrentFilename = directory + "/" + currentFilename;
if (isInSnapshotFilenameFormat(currentFilename)) {
if (!QFile::remove(fullCurrentFilename)) {
messageBox.critical(0, "Error", "Could not delete existing file: " + currentFilename + "\nSnapshot deletion aborted");
exit(-1);
}
}
}
}
} }
QStringList Test::createListOfAll_IMAGE_FORMAT_imagesInDirectory(QString pathToImageDirectory) { QStringList Test::createListOfAll_imagesInDirectory(QString imageFormat, QString pathToImageDirectory) {
imageDirectory = QDir(pathToImageDirectory); imageDirectory = QDir(pathToImageDirectory);
QStringList nameFilters; QStringList nameFilters;
nameFilters << "*" + IMAGE_FORMAT; nameFilters << "*." + imageFormat;
return imageDirectory.entryList(nameFilters, QDir::Files, QDir::Name); return imageDirectory.entryList(nameFilters, QDir::Files, QDir::Name);
} }
@ -428,7 +419,7 @@ QStringList Test::createListOfAll_IMAGE_FORMAT_imagesInDirectory(QString pathToI
// Filename (i.e. without extension) contains _tests_ (this is based on all test scripts being within the tests folder // Filename (i.e. without extension) contains _tests_ (this is based on all test scripts being within the tests folder
// Last 5 characters in filename are digits // Last 5 characters in filename are digits
// Extension is jpg // Extension is jpg
bool Test::isInSnapshotFilenameFormat(QString filename) { bool Test::isInSnapshotFilenameFormat(QString imageFormat, QString filename) {
QStringList filenameParts = filename.split("."); QStringList filenameParts = filename.split(".");
bool filnameHasNoPeriods = (filenameParts.size() == 2); bool filnameHasNoPeriods = (filenameParts.size() == 2);
@ -437,7 +428,7 @@ bool Test::isInSnapshotFilenameFormat(QString filename) {
bool last5CharactersAreDigits; bool last5CharactersAreDigits;
filenameParts[0].right(5).toInt(&last5CharactersAreDigits, 10); filenameParts[0].right(5).toInt(&last5CharactersAreDigits, 10);
bool extensionIsIMAGE_FORMAT = filenameParts[1] == IMAGE_FORMAT.right(3); // without the period bool extensionIsIMAGE_FORMAT = (filenameParts[1] == imageFormat);
return (filnameHasNoPeriods && contains_tests && last5CharactersAreDigits && extensionIsIMAGE_FORMAT); return (filnameHasNoPeriods && contains_tests && last5CharactersAreDigits && extensionIsIMAGE_FORMAT);
} }

View file

@ -33,9 +33,9 @@ public:
bool compareImageLists(bool isInteractiveMode, QProgressBar* progressBar); bool compareImageLists(bool isInteractiveMode, QProgressBar* progressBar);
QStringList createListOfAll_IMAGE_FORMAT_imagesInDirectory(QString pathToImageDirectory); QStringList createListOfAll_imagesInDirectory(QString imageFormat, QString pathToImageDirectory);
bool isInSnapshotFilenameFormat(QString filename); bool isInSnapshotFilenameFormat(QString imageFormat, QString filename);
void importTest(QTextStream& textStream, const QString& testPathname); void importTest(QTextStream& textStream, const QString& testPathname);
@ -49,6 +49,8 @@ public:
QString getExpectedImageDestinationDirectory(QString filename); QString getExpectedImageDestinationDirectory(QString filename);
QString getExpectedImagePartialSourceDirectory(QString filename); QString getExpectedImagePartialSourceDirectory(QString filename);
void copyJPGtoPNG(QString sourceJPGFullFilename, QString destinationPNGFullFilename);
private: private:
const QString TEST_FILENAME { "test.js" }; const QString TEST_FILENAME { "test.js" };
const QString TEST_RESULTS_FOLDER { "TestResults" }; const QString TEST_RESULTS_FOLDER { "TestResults" };
@ -70,7 +72,6 @@ private:
// Expected images are in the format ExpectedImage_dddd.jpg (d == decimal digit) // Expected images are in the format ExpectedImage_dddd.jpg (d == decimal digit)
const int NUM_DIGITS { 5 }; const int NUM_DIGITS { 5 };
const QString EXPECTED_IMAGE_PREFIX { "ExpectedImage_" }; const QString EXPECTED_IMAGE_PREFIX { "ExpectedImage_" };
const QString IMAGE_FORMAT { ".png" };
QString pathToTestResultsDirectory; QString pathToTestResultsDirectory;
QStringList expectedImagesFilenames; QStringList expectedImagesFilenames;

View file

@ -36,10 +36,6 @@ void AutoTester::on_createTestButton_clicked() {
test->createTest(); test->createTest();
} }
void AutoTester::on_deleteOldSnapshotsButton_clicked() {
test->deleteOldSnapshots();
}
void AutoTester::on_closeButton_clicked() { void AutoTester::on_closeButton_clicked() {
exit(0); exit(0);
} }

View file

@ -30,7 +30,6 @@ private slots:
void on_createRecursiveScriptButton_clicked(); void on_createRecursiveScriptButton_clicked();
void on_createRecursiveScriptsRecursivelyButton_clicked(); void on_createRecursiveScriptsRecursivelyButton_clicked();
void on_createTestButton_clicked(); void on_createTestButton_clicked();
void on_deleteOldSnapshotsButton_clicked();
void on_closeButton_clicked(); void on_closeButton_clicked();
void saveImage(int index); void saveImage(int index);

View file

@ -30,8 +30,8 @@
<widget class="QPushButton" name="createTestButton"> <widget class="QPushButton" name="createTestButton">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>360</x> <x>20</x>
<y>210</y> <y>30</y>
<width>220</width> <width>220</width>
<height>40</height> <height>40</height>
</rect> </rect>
@ -44,7 +44,7 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>20</x> <x>20</x>
<y>75</y> <y>135</y>
<width>220</width> <width>220</width>
<height>40</height> <height>40</height>
</rect> </rect>
@ -70,7 +70,7 @@
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>23</x> <x>23</x>
<y>40</y> <y>100</y>
<width>131</width> <width>131</width>
<height>20</height> <height>20</height>
</rect> </rect>
@ -95,19 +95,6 @@
<number>24</number> <number>24</number>
</property> </property>
</widget> </widget>
<widget class="QPushButton" name="deleteOldSnapshotsButton">
<property name="geometry">
<rect>
<x>360</x>
<y>270</y>
<width>220</width>
<height>40</height>
</rect>
</property>
<property name="text">
<string>Delete Old Snapshots</string>
</property>
</widget>
<widget class="QPushButton" name="createRecursiveScriptsRecursivelyButton"> <widget class="QPushButton" name="createRecursiveScriptsRecursivelyButton">
<property name="geometry"> <property name="geometry">
<rect> <rect>