mirror of https://github.com/status-im/qzxing.git
Multiple changes in test suite. a) Added tests for ReedSolomonEncoder (current status: failing) b) Added printing of stacktrace upon test missmatch, will work only where supported by backward.hpp code.
This commit is contained in:
parent
588d478b7b
commit
5cd96d1aae
|
@ -13,7 +13,7 @@
|
|||
namespace zxing {
|
||||
namespace tests{
|
||||
|
||||
EncodeValidator::EncodeValidator()
|
||||
EncodeValidator::EncodeValidator() : TestCase()
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ void EncodeValidator::execute()
|
|||
qrcode::tests::QRCodeTests t3;
|
||||
t3.execute();
|
||||
|
||||
ReedSolomonEncoderTests t4;
|
||||
ReedSolomonTests t4;
|
||||
t4.execute();
|
||||
|
||||
qrcode::tests::EncoderTests t5;
|
||||
|
|
|
@ -10,6 +10,19 @@ CONFIG -= app_bundle
|
|||
|
||||
TEMPLATE = app
|
||||
|
||||
HEADERS += \
|
||||
DecodeValidator.h \
|
||||
ValidationStats.h \
|
||||
EncodeValidator.h \
|
||||
TestCase.h \
|
||||
zxing/qrcode/encoder/MatrixUtilTests.h \
|
||||
zxing/qrcode/encoder/MaskUtilTests.h \
|
||||
zxing/qrcode/encoder/BitArrayTests.h \
|
||||
zxing/qrcode/encoder/QRCodeTests.h \
|
||||
zxing/qrcode/encoder/EncoderTests.h \
|
||||
zxing/common/reedsolomon/ReedSolomonEncoderTests.h
|
||||
#\backward.hpp
|
||||
|
||||
SOURCES += main.cpp \
|
||||
DecodeValidator.cpp \
|
||||
ValidationStats.cpp \
|
||||
|
@ -19,18 +32,7 @@ SOURCES += main.cpp \
|
|||
zxing/qrcode/encoder/BitArrayTests.cpp \
|
||||
zxing/qrcode/encoder/QRCodeTests.cpp \
|
||||
zxing/qrcode/encoder/EncoderTests.cpp \
|
||||
zxing/common/reedsolomon/ReedSolomonEncoderTests.cpp
|
||||
|
||||
HEADERS += \
|
||||
DecodeValidator.h \
|
||||
ValidationStats.h \
|
||||
EncodeValidator.h \
|
||||
zxing/qrcode/encoder/MatrixUtilTests.h \
|
||||
TestCase.h \
|
||||
zxing/qrcode/encoder/MaskUtilTests.h \
|
||||
zxing/qrcode/encoder/BitArrayTests.h \
|
||||
zxing/qrcode/encoder/QRCodeTests.h \
|
||||
zxing/qrcode/encoder/EncoderTests.h \
|
||||
zxing/common/reedsolomon/ReedSolomonEncoderTests.h
|
||||
zxing/common/reedsolomon/ReedSolomonEncoderTests.cpp \
|
||||
TestCase.cpp
|
||||
|
||||
include(../../../src/QZXing.pri)
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#include "TestCase.h"
|
||||
#include <stdlib.h> /* srand, rand */
|
||||
#include <time.h> /* time */
|
||||
|
||||
void zxing::TestCase::initializeRandom()
|
||||
{
|
||||
srand(time(NULL));
|
||||
}
|
||||
|
||||
int zxing::TestCase::generateRandomNumber(int range)
|
||||
{
|
||||
return rand() % range;
|
||||
}
|
|
@ -5,6 +5,8 @@
|
|||
#include <zxing/Exception.h>
|
||||
#include <QtGlobal>
|
||||
#include <zxing/qrcode/decoder/Mode.h>
|
||||
#include "backward.hpp"
|
||||
#include <QStringList>
|
||||
|
||||
namespace zxing{
|
||||
|
||||
|
@ -52,6 +54,23 @@ protected:
|
|||
if(expected != actual) {
|
||||
QString message = QString("\nExpected: \n[") + itemToString(expected) +
|
||||
QString("], \nGot: \n[") + itemToString(actual) + QString("]");
|
||||
|
||||
backward::StackTrace st;
|
||||
st.load_here(32);
|
||||
|
||||
backward::TraceResolver tr;
|
||||
tr.load_stacktrace(st);
|
||||
for (size_t i = 0; i < st.size(); ++i) {
|
||||
backward::ResolvedTrace trace = tr.resolve(st[i]);
|
||||
message += QString::fromStdString("\n#");
|
||||
message += QString::number(i);
|
||||
message += QString::fromStdString(trace.object_filename);
|
||||
message += QString::fromStdString(trace.object_function);
|
||||
message += QString("[");
|
||||
message += QString::number((int)trace.addr);
|
||||
message += QString("]\n");
|
||||
}
|
||||
|
||||
throw zxing::Exception(message.toStdString().c_str());
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +96,22 @@ protected:
|
|||
assertEquals(0, (int)actual);
|
||||
}
|
||||
|
||||
void assertDataEquals(const std::string &message,
|
||||
const std::vector<int> &expected,
|
||||
const std::vector<int> & received)
|
||||
{
|
||||
for (int i = 0; i < expected.size(); i++) {
|
||||
if (expected[i] != received[i]) {
|
||||
qDebug() << QString::fromStdString(message) << ". Mismatch at " << QString::number(i) /*<< ". Expected " + arrayToString(expected) + ", got " +
|
||||
arrayToString(Arrays.copyOf(received, expected.length)))*/;
|
||||
assertTrue(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void initializeRandom();
|
||||
static int generateRandomNumber(int range);
|
||||
|
||||
public:
|
||||
virtual void execute()=0;
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,16 +1,148 @@
|
|||
#include "ReedSolomonEncoderTests.h"
|
||||
#include "zxing/common/reedsolomon/ReedSolomonEncoder.h"
|
||||
#include "zxing/common/reedsolomon/ReedSolomonDecoder.h"
|
||||
|
||||
namespace zxing{
|
||||
namespace tests{
|
||||
|
||||
ReedSolomonEncoderTests::ReedSolomonEncoderTests()
|
||||
const int ReedSolomonTests::DECODER_RANDOM_TEST_ITERATIONS = 3;
|
||||
const int ReedSolomonTests::DECODER_TEST_ITERATIONS = 10;
|
||||
|
||||
ReedSolomonTests::ReedSolomonTests()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void ReedSolomonEncoderTests::execute()
|
||||
void ReedSolomonTests::execute()
|
||||
{
|
||||
testQRCode();
|
||||
}
|
||||
|
||||
void ReedSolomonTests::testQRCode()
|
||||
{
|
||||
// Test case from example given in ISO 18004, Annex I
|
||||
testEncodeDecode(GenericGF::QR_CODE_FIELD_256, {
|
||||
0x10, 0x20, 0x0C, 0x56, 0x61, 0x80, 0xEC, 0x11,
|
||||
0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11
|
||||
// 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
|
||||
},
|
||||
{0xA5, 0x24, 0xD4, 0xC1, 0xED, 0x36, 0xC7, 0x87,
|
||||
0x2C, 0x55 });
|
||||
testEncodeDecode(GenericGF::QR_CODE_FIELD_256, {
|
||||
0x72, 0x67, 0x2F, 0x77, 0x69, 0x6B, 0x69, 0x2F,
|
||||
0x4D, 0x61, 0x69, 0x6E, 0x5F, 0x50, 0x61, 0x67,
|
||||
0x65, 0x3B, 0x3B, 0x00, 0xEC, 0x11, 0xEC, 0x11,
|
||||
0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11, 0xEC, 0x11 },
|
||||
{0xD8, 0xB8, 0xEF, 0x14, 0xEC, 0xD0, 0xCC, 0x85,
|
||||
0x73, 0x40, 0x0B, 0xB5, 0x5A, 0xB8, 0x8B, 0x2E,
|
||||
0x08, 0x62 });
|
||||
// real life test cases
|
||||
// synthetic test cases
|
||||
testEncodeDecodeRandom(GenericGF::QR_CODE_FIELD_256, 10, 240);
|
||||
testEncodeDecodeRandom(GenericGF::QR_CODE_FIELD_256, 128, 127);
|
||||
testEncodeDecodeRandom(GenericGF::QR_CODE_FIELD_256, 220, 35);
|
||||
}
|
||||
|
||||
void ReedSolomonTests::corrupt(std::vector<int> &received, int howMany, int max)
|
||||
{
|
||||
std::vector<bool> corrupted(false, received.size());
|
||||
for (int j = 0; j < howMany; j++) {
|
||||
int location = generateRandomNumber(received.size());
|
||||
int value = generateRandomNumber(max);
|
||||
if (corrupted[location] || received[location] == value) {
|
||||
j--;
|
||||
} else {
|
||||
corrupted[location] = true;
|
||||
received[location] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReedSolomonTests::testEncodeDecodeRandom(Ref<GenericGF> field, int dataSize, int ecSize)
|
||||
{
|
||||
assertTrue(dataSize > 0 && dataSize <= field->getSize() - 3); /*"Invalid data size for " + field, */
|
||||
assertTrue(ecSize > 0 && ecSize + dataSize <= field->getSize()); /*"Invalid ECC size for " + field, */
|
||||
ReedSolomonEncoder encoder(field);
|
||||
std::vector<int> message;//(dataSize + ecSize);
|
||||
std::vector<int> dataWords(dataSize);
|
||||
std::vector<int> ecWords(ecSize);
|
||||
initializeRandom();
|
||||
int iterations = field->getSize() > 256 ? 1 : DECODER_RANDOM_TEST_ITERATIONS;
|
||||
for (int i = 0; i < iterations; i++) {
|
||||
// generate random data
|
||||
for (int k = 0; k < dataSize; k++) {
|
||||
dataWords[k] = generateRandomNumber(field->getSize());
|
||||
}
|
||||
// generate ECC words
|
||||
message = dataWords;
|
||||
encoder.encode(message, ecWords.size());
|
||||
message.insert(std::end(message), std::begin(ecWords), std::end(ecWords));
|
||||
// check to see if Decoder can fix up to ecWords/2 random errors
|
||||
testDecoder(field, dataWords, ecWords);
|
||||
}
|
||||
}
|
||||
|
||||
void ReedSolomonTests::testEncodeDecode(Ref<GenericGF> field,
|
||||
const std::vector<int> &dataWords,
|
||||
const std::vector<int> & ecWords)
|
||||
{
|
||||
testEncoder(field, dataWords, ecWords);
|
||||
testDecoder(field, dataWords, ecWords);
|
||||
}
|
||||
|
||||
void ReedSolomonTests::testEncoder(Ref<GenericGF> field,
|
||||
const std::vector<int> &dataWords,
|
||||
const std::vector<int> & ecWords)
|
||||
{
|
||||
ReedSolomonEncoder encoder(field);
|
||||
std::vector<int> messageExpected;
|
||||
std::vector<int> message;
|
||||
|
||||
messageExpected = dataWords;
|
||||
messageExpected.insert(std::end(messageExpected), std::begin(ecWords), std::end(ecWords));
|
||||
message = dataWords;
|
||||
|
||||
encoder.encode(message, ecWords.size());
|
||||
assertDataEquals("",//"Encode in " + field + " (" + dataWords.size() + ',' + ecWords.size() + ") failed",
|
||||
messageExpected, message);
|
||||
}
|
||||
|
||||
void ReedSolomonTests::testDecoder(Ref<GenericGF> field,
|
||||
const std::vector<int> &dataWords,
|
||||
const std::vector<int> & ecWords) {
|
||||
ReedSolomonDecoder decoder(field);
|
||||
std::vector<int> message;
|
||||
int maxErrors = ecWords.size() / 2;
|
||||
initializeRandom();
|
||||
int iterations = field->getSize() > 256 ? 1 : DECODER_TEST_ITERATIONS;
|
||||
for (int j = 0; j < iterations; j++) {
|
||||
for (int i = 0; i < ecWords.size(); i++) {
|
||||
if (i > 10 && i < ecWords.size() / 2 - 10) {
|
||||
// performance improvement - skip intermediate cases in long-running tests
|
||||
i += ecWords.size() / 10;
|
||||
}
|
||||
message = dataWords;
|
||||
message.insert(std::end(message), std::begin(ecWords), std::end(ecWords));
|
||||
corrupt(message, i, field->getSize());
|
||||
|
||||
ArrayRef<int> messageArrayRef(message.size());
|
||||
for(int i=0; i<message.size(); i++)
|
||||
messageArrayRef[i] = message[i];
|
||||
try {
|
||||
decoder.decode(messageArrayRef, ecWords.size());
|
||||
} catch(zxing::Exception &e) {
|
||||
// fail only if maxErrors exceeded
|
||||
assertTrue(i > maxErrors); /*"Decode in " + field + " (" + dataWords.length + ',' + ecWords.length + ") failed at " + i + " errors: " + e,*/
|
||||
// else stop
|
||||
break;
|
||||
}
|
||||
|
||||
if (i < maxErrors) {
|
||||
//"Decode in " + field + " (" + dataWords.size() + ',' + ecWords.size() + ") failed at " + i + " errors"
|
||||
assertDataEquals("",dataWords, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,22 +2,37 @@
|
|||
#define REEDSOLOMONENCODERTESTS_H
|
||||
|
||||
#include "TestCase.h"
|
||||
#include "zxing/common/reedsolomon/ReedSolomonEncoder.h"
|
||||
#include <zxing/common/reedsolomon/GenericGF.h>
|
||||
|
||||
namespace zxing{
|
||||
namespace tests{
|
||||
|
||||
class ReedSolomonEncoderTests : public TestCase
|
||||
class ReedSolomonTests : public TestCase
|
||||
{
|
||||
private:
|
||||
static const int DECODER_RANDOM_TEST_ITERATIONS;
|
||||
static const int DECODER_TEST_ITERATIONS;
|
||||
|
||||
public:
|
||||
ReedSolomonEncoderTests();
|
||||
ReedSolomonTests();
|
||||
|
||||
void execute();
|
||||
|
||||
protected:
|
||||
void testQRCode();
|
||||
|
||||
// const std::vector<byte>& dataBytes
|
||||
// void testEncoder(Ref<GenericGF> field, int[] dataWords, int[] ecWords);
|
||||
private:
|
||||
void corrupt(std::vector<int> &received, int howMany, int max);
|
||||
void testEncodeDecodeRandom(Ref<GenericGF> field, int dataSize, int ecSize);
|
||||
void testEncodeDecode(Ref<GenericGF> field,
|
||||
const std::vector<int> &dataWords,
|
||||
const std::vector<int> & ecWords);
|
||||
void testEncoder(Ref<GenericGF> field,
|
||||
const std::vector<int> &dataWords,
|
||||
const std::vector<int> & ecWords);
|
||||
void testDecoder(Ref<GenericGF> field,
|
||||
const std::vector<int> &dataWords,
|
||||
const std::vector<int> & ecWords);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue