1
0
Fork 0
mirror of https://github.com/opentx/opentx.git synced 2025-07-23 08:15:17 +03:00

Code formatting

This commit is contained in:
Bertrand Songis 2016-03-05 15:44:42 +01:00
parent 8e2c280e4a
commit 3b8c5bbeb1
10 changed files with 2627 additions and 2751 deletions

View file

@ -1,27 +1,12 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
* Copyright (C) OpenTX
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@ -31,7 +16,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include "gtests.h"

View file

@ -1,164 +1,148 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include "gtests.h"
#if !defined(PCBSKY9X)
TEST(Eeprom, 100_random_writes)
{
eepromFile = NULL; // in memory
RlcFile f;
uint8_t buf[1000];
uint8_t buf2[1000];
storageFormat();
for(int i=0; i<100; i++) {
int size = rand()%800;
for(int j=0; j<size; j++) {
buf[j] = rand() < (RAND_MAX/10000*i) ? 0 : (j&0xff);
}
f.writeRlc(5, 5, buf, size, 100);
// printf("size=%4d red=%4d\n\n\n", size, f.size());
f.openRd(5);
uint16_t n = f.readRlc(buf2,size+1);
EXPECT_EQ(n, size);
EXPECT_EQ(memcmp(buf, buf2, size), 0);
}
}
TEST(Eeprom, test2)
{
eepromFile = NULL; // in memory
RlcFile f;
uint8_t buf[1000];
storageFormat();
for(int i=0; i<1000; i++) buf[i]='6'+i%4;
f.writeRlc(6, 6, buf, 300, 100);
f.openRd(6);
uint16_t sz=0;
for(int i=0; i<500; i++){
uint8_t b;
uint16_t n=f.readRlc(&b,1);
if(n) EXPECT_EQ(b, ('6'+sz%4));
sz+=n;
}
EXPECT_EQ(sz, 300);
}
TEST(Eeprom, storageCheckImmediately)
{
eepromFile = NULL; // in memory
// RlcFile f;
uint8_t buf[1000];
storageFormat();
for(int i=0; i<1000; i++) buf[i]='6'+i%4;
theFile.writeRlc(6, 6, buf, 300, false);
storageCheck(true);
theFile.openRd(6);
uint16_t sz=0;
for(int i=0; i<500; i++){
uint8_t b;
uint16_t n=theFile.readRlc(&b,1);
if(n) EXPECT_EQ(b, ('6'+sz%4));
sz+=n;
}
EXPECT_EQ(sz, 300);
}
TEST(Eeprom, copy)
{
eepromFile = NULL; // in memory
uint8_t buf[1000];
storageFormat();
for(int i=0; i<1000; i++) buf[i]='6'+i%4;
theFile.writeRlc(5, 6, buf, 300, true);
theFile.copy(6, 5);
theFile.openRd(6);
uint16_t sz=0;
for(int i=0; i<500; i++){
uint8_t b;
uint16_t n=theFile.readRlc(&b,1);
if(n) EXPECT_EQ(b, ('6'+sz%4));
sz+=n;
}
EXPECT_EQ(sz, 300);
}
TEST(Eeprom, rm)
{
eepromFile = NULL; // in memory
uint8_t buf[1000];
storageFormat();
for(int i=0; i<1000; i++) buf[i]='6'+i%4;
theFile.writeRlc(5, 6, buf, 300, true);
EXPECT_EQ(EFile::exists(5), true);
EFile::rm(5);
EXPECT_EQ(EFile::exists(5), false);
theFile.openRd(5);
uint16_t sz=0;
for(int i=0; i<500; i++){
uint8_t b;
uint16_t n=theFile.readRlc(&b,1);
if(n) EXPECT_EQ(b, ('6'+sz%4));
sz+=n;
}
EXPECT_EQ(sz, 0);
}
#endif
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "gtests.h"
#if !defined(PCBSKY9X)
TEST(Eeprom, 100_random_writes)
{
eepromFile = NULL; // in memory
RlcFile f;
uint8_t buf[1000];
uint8_t buf2[1000];
storageFormat();
for(int i=0; i<100; i++) {
int size = rand()%800;
for(int j=0; j<size; j++) {
buf[j] = rand() < (RAND_MAX/10000*i) ? 0 : (j&0xff);
}
f.writeRlc(5, 5, buf, size, 100);
// printf("size=%4d red=%4d\n\n\n", size, f.size());
f.openRd(5);
uint16_t n = f.readRlc(buf2,size+1);
EXPECT_EQ(n, size);
EXPECT_EQ(memcmp(buf, buf2, size), 0);
}
}
TEST(Eeprom, test2)
{
eepromFile = NULL; // in memory
RlcFile f;
uint8_t buf[1000];
storageFormat();
for(int i=0; i<1000; i++) buf[i]='6'+i%4;
f.writeRlc(6, 6, buf, 300, 100);
f.openRd(6);
uint16_t sz=0;
for(int i=0; i<500; i++){
uint8_t b;
uint16_t n=f.readRlc(&b,1);
if(n) EXPECT_EQ(b, ('6'+sz%4));
sz+=n;
}
EXPECT_EQ(sz, 300);
}
TEST(Eeprom, storageCheckImmediately)
{
eepromFile = NULL; // in memory
// RlcFile f;
uint8_t buf[1000];
storageFormat();
for(int i=0; i<1000; i++) buf[i]='6'+i%4;
theFile.writeRlc(6, 6, buf, 300, false);
storageCheck(true);
theFile.openRd(6);
uint16_t sz=0;
for(int i=0; i<500; i++){
uint8_t b;
uint16_t n=theFile.readRlc(&b,1);
if(n) EXPECT_EQ(b, ('6'+sz%4));
sz+=n;
}
EXPECT_EQ(sz, 300);
}
TEST(Eeprom, copy)
{
eepromFile = NULL; // in memory
uint8_t buf[1000];
storageFormat();
for(int i=0; i<1000; i++) buf[i]='6'+i%4;
theFile.writeRlc(5, 6, buf, 300, true);
theFile.copy(6, 5);
theFile.openRd(6);
uint16_t sz=0;
for(int i=0; i<500; i++){
uint8_t b;
uint16_t n=theFile.readRlc(&b,1);
if(n) EXPECT_EQ(b, ('6'+sz%4));
sz+=n;
}
EXPECT_EQ(sz, 300);
}
TEST(Eeprom, rm)
{
eepromFile = NULL; // in memory
uint8_t buf[1000];
storageFormat();
for(int i=0; i<1000; i++) buf[i]='6'+i%4;
theFile.writeRlc(5, 6, buf, 300, true);
EXPECT_EQ(EFile::exists(5), true);
EFile::rm(5);
EXPECT_EQ(EFile::exists(5), false);
theFile.openRd(5);
uint16_t sz=0;
for(int i=0; i<500; i++){
uint8_t b;
uint16_t n=theFile.readRlc(&b,1);
if(n) EXPECT_EQ(b, ('6'+sz%4));
sz+=n;
}
EXPECT_EQ(sz, 0);
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,69 +1,53 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <QtGui/QApplication>
#include "gtests.h"
int32_t lastAct = 0;
uint16_t anaInValues[NUM_STICKS+NUM_POTS] = { 0 };
uint16_t anaIn(uint8_t chan)
{
if (chan < NUM_STICKS+NUM_POTS)
return anaInValues[chan];
else
return 0;
}
static char _zchar2stringResult[200];
const char * zchar2string(const char * zstring, int size)
{
if (size > (int)sizeof(_zchar2stringResult) ) {
return 0;
}
zchar2str(_zchar2stringResult, zstring, size);
return _zchar2stringResult;
}
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
simuInit();
StartEepromThread(NULL);
menuLevel = 0;
menuHandlers[0] = menuMainView;
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <QtGui/QApplication>
#include "gtests.h"
int32_t lastAct = 0;
uint16_t anaInValues[NUM_STICKS+NUM_POTS] = { 0 };
uint16_t anaIn(uint8_t chan)
{
if (chan < NUM_STICKS+NUM_POTS)
return anaInValues[chan];
else
return 0;
}
static char _zchar2stringResult[200];
const char * zchar2string(const char * zstring, int size)
{
if (size > (int)sizeof(_zchar2stringResult) ) {
return 0;
}
zchar2str(_zchar2stringResult, zstring, size);
return _zchar2stringResult;
}
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
simuInit();
StartEepromThread(NULL);
menuLevel = 0;
menuHandlers[0] = menuMainView;
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View file

@ -1,5 +1,25 @@
#ifndef __GTESTS_H
#define __GTESTS_H
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _GTESTS_H_
#define _GTESTS_H_
#include <QtCore/QString>
#include <math.h>
@ -71,4 +91,4 @@ inline void TELEMETRY_RESET()
bool checkScreenshot(QString test);
#endif
#endif // _GTESTS_H_

View file

@ -1,477 +1,461 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <QtCore/QDir>
#include <QtCore/QDebug>
#include <QtGui/QApplication>
#include <QtGui/QPainter>
#include <math.h>
#include <gtest/gtest.h>
#define SWAP_DEFINED
#include "opentx.h"
#include "location.h"
void doPaint(QPainter & p)
{
QRgb rgb = qRgb(161, 161, 161);
p.setBackground(QBrush(rgb));
p.eraseRect(0, 0, LCD_W, LCD_H);
if (1) {
#if !defined(PCBTARANIS)
rgb = qRgb(0, 0, 0);
p.setPen(rgb);
p.setBrush(QBrush(rgb));
#endif
#if defined(PCBTARANIS)
unsigned int previousDepth = 0xFF;
#endif
for (int y=0; y<LCD_H; y++) {
#if defined(PCBTARANIS)
unsigned int idx = (y/2) * LCD_W;
#else
unsigned int idx = (y/8) * LCD_W;
unsigned int mask = (1 << (y%8));
#endif
for (int x=0; x<LCD_W; x++, idx++) {
#if !defined(PCBTARANIS)
if (simuLcdBuf[idx] & mask) {
p.drawPoint(x, y);
}
#else
unsigned int z = (y & 1) ? (simuLcdBuf[idx] >> 4) : (simuLcdBuf[idx] & 0x0F);
if (z) {
if (z != previousDepth) {
previousDepth = z;
rgb = qRgb(161-(z*161)/15, 161-(z*161)/15, 161-(z*161)/15);
p.setPen(rgb);
p.setBrush(QBrush(rgb));
}
p.drawPoint(x, y);
}
#endif
}
}
}
}
bool checkScreenshot(const QString & test)
{
lcdRefresh();
QImage buffer(LCD_W, LCD_H, QImage::Format_RGB32);
QPainter p(&buffer);
doPaint(p);
QString filename(QString("%1_%2x%3.png").arg(test).arg(LCD_W).arg(LCD_H));
buffer.save("/tmp/" + filename);
QFile screenshot("/tmp/" + filename);
if (!screenshot.open(QIODevice::ReadOnly))
return false;
QFile reference( TESTS_PATH "/tests/" + filename);
if (!reference.open(QIODevice::ReadOnly))
return false;
if (reference.readAll() != screenshot.readAll())
return false;
screenshot.remove();
return true;
}
TEST(outdezNAtt, test_unsigned)
{
lcdClear();
lcdDrawNumber(0, 0, 65530, LEFT|UNSIGN);
EXPECT_TRUE(checkScreenshot("unsigned")) << "Unsigned numbers will be bad displayed";
}
#if defined(CPUARM)
TEST(outdezNAtt, testBigNumbers)
{
lcdClear();
lcdDrawNumber(0, 0, 1234567, LEFT);
lcdDrawNumber(0, FH, -1234567, LEFT);
EXPECT_TRUE(checkScreenshot("big_numbers"));
}
#endif // #if defined(CPUARM)
TEST(Lcd, Invers_0_0)
{
lcdClear();
lcdDrawText(0, 0, "Test", INVERS);
EXPECT_TRUE(checkScreenshot("invers_0_0"));
}
TEST(Lcd, Invers_0_1)
{
lcdClear();
lcdDrawText(0, 1, "Test", INVERS);
EXPECT_TRUE(checkScreenshot("invers_0_1"));
}
TEST(Lcd, Prec2_Left)
{
lcdClear();
lcdDrawNumber(0, 0, 2, PREC2|LEFT);
EXPECT_TRUE(checkScreenshot("prec2_left"));
}
TEST(Lcd, Prec2_Right)
{
lcdClear();
lcdDrawNumber(LCD_W, LCD_H-FH, 2, PREC2);
EXPECT_TRUE(checkScreenshot("prec2_right"));
}
#if defined(CPUARM)
TEST(Lcd, Prec1_Dblsize_Invers)
{
lcdClear();
lcdDrawNumber(LCD_W, 10, 51, PREC1|DBLSIZE|INVERS);
EXPECT_TRUE(checkScreenshot("prec1_dblsize_invers"));
}
#endif
TEST(Lcd, Line_Wrap)
{
lcdClear();
lcdDrawText(LCD_W-10, 0, "TEST");
EXPECT_TRUE(checkScreenshot("line_wrap"));
}
TEST(Lcd, DblsizeBottomRight)
{
lcdClear();
lcdDrawText(LCD_W-20, LCD_H-16, "TEST", DBLSIZE);
EXPECT_TRUE(checkScreenshot("dblsize_bottom_right"));
}
#if defined(CPUARM)
TEST(Lcd, Smlsize_drawStringWithIndex)
{
lcdClear();
drawStringWithIndex(0, 0, "FM", 0, SMLSIZE);
EXPECT_TRUE(checkScreenshot("smlsize_drawstringwithindex"));
}
#endif
TEST(Lcd, vline)
{
lcdClear();
for (int x=0; x<100; x+=2) {
lcdDrawSolidVerticalLine(x, x/2, 12);
}
EXPECT_TRUE(checkScreenshot("vline"));
}
#if defined(CPUARM)
TEST(Lcd, vline_x_lt0)
{
lcdClear();
lcdDrawSolidVerticalLine(50, -10, 12);
lcdDrawSolidVerticalLine(100, -10, 1);
EXPECT_TRUE(checkScreenshot("vline_lt0"));
}
#endif
#if defined(CPUARM)
TEST(Lcd, Smlsize)
{
lcdClear();
lcdDrawText(0, 0, "TESTgy,", SMLSIZE);
lcdDrawText(10, 22, "TESTgy,", SMLSIZE|INVERS);
lcdDrawFilledRect(8, 40, 100, 20);
lcdDrawText(10, 42, "TESTgy,", SMLSIZE);
bool invert = false;
for(int i=0; i<3; i++) {
lcdDrawText(40+(4*i), 0+(4*i), "ABC", SMLSIZE|(invert?INVERS:0));
invert = !invert;
}
EXPECT_TRUE(checkScreenshot("smlsize"));
}
TEST(Lcd, Stdsize)
{
lcdClear();
lcdDrawText(0, 0, "TEST", 0);
lcdDrawText(10, 22, "TEST", INVERS);
lcdDrawFilledRect(8, 40, 100, 20);
lcdDrawText(10, 42, "TEST", 0);
bool invert = false;
for(int i=0; i<3; i++) {
lcdDrawText(40+(4*i), 0+(4*i), "ABC", (invert?INVERS:0));
invert = !invert;
}
EXPECT_TRUE(checkScreenshot("stdsize"));
}
TEST(Lcd, Midsize)
{
lcdClear();
lcdDrawText(0, 0, "TEST", MIDSIZE);
lcdDrawText(10, 22, "TEST", MIDSIZE|INVERS);
lcdDrawFilledRect(8, 40, 100, 20);
lcdDrawText(10, 42, "TEST", MIDSIZE);
bool invert = false;
for(int i=0; i<3; i++) {
lcdDrawText(40+(4*i), 0+(4*i), "ABC", MIDSIZE|(invert?INVERS:0));
invert = !invert;
}
EXPECT_TRUE(checkScreenshot("midsize"));
}
TEST(Lcd, Dblsize)
{
lcdClear();
lcdDrawText(2, 10, "TST", DBLSIZE);
lcdDrawText(42, 10, "TST", DBLSIZE|INVERS);
lcdDrawFilledRect(80, 8, 46, 24);
lcdDrawText(82, 10, "TST", DBLSIZE);
bool invert = false;
for(int i=0; i<3; i++) {
lcdDrawText(10+(4*i), 30+(4*i), "ABC", DBLSIZE|(invert?INVERS:0));
invert = !invert;
}
EXPECT_TRUE(checkScreenshot("dblsize"));
}
#endif
#if defined(PCBTARANIS)
TEST(Lcd, DrawSwitch)
{
lcdClear();
putsSwitches(0, 10, SWSRC_SA0, 0);
putsSwitches(30, 10, SWSRC_SA0, SMLSIZE);
// putsSwitches(60, 10, SWSRC_SA0, MIDSIZE); missing arrows in this font
putsSwitches(90, 10, SWSRC_SA0, DBLSIZE);
EXPECT_TRUE(checkScreenshot("drawswitch"));
}
#endif
#if defined(PCBTARANIS)
TEST(Lcd, BMPWrapping)
{
lcdClear();
uint8_t bitmap[2+40*40/2];
lcdLoadBitmap(bitmap, TESTS_PATH "/tests/plane.bmp", 40, 40);
lcdDrawBitmap(200, 0, bitmap);
lcdDrawBitmap(200, 60, bitmap);
lcdDrawBitmap(240, 60, bitmap); // x too big
lcdDrawBitmap(20, 200, bitmap); // y too big
EXPECT_TRUE(checkScreenshot("bmpwrapping"));
}
#endif
#if defined(PCBTARANIS)
TEST(Lcd, lcdDrawHorizontalLine)
{
lcdClear();
lcdDrawHorizontalLine(0, 10, LCD_W, DOTTED);
lcdDrawHorizontalLine(0, 20, LCD_W, SOLID);
lcdDrawHorizontalLine(50, 30, LCD_W, 0xEE); //too wide
lcdDrawHorizontalLine(50, LCD_H + 10, 20, SOLID); //too low
lcdDrawHorizontalLine(250, 30, LCD_W, SOLID); //x outside display
EXPECT_TRUE(checkScreenshot("lcdDrawHorizontalLine"));
}
#endif
#if defined(PCBTARANIS)
TEST(Lcd, lcdDrawVerticalLine)
{
lcdClear();
lcdDrawVerticalLine(10, 0, LCD_H, DOTTED);
lcdDrawVerticalLine(20, 0, LCD_H, SOLID);
lcdDrawVerticalLine(30, 30, LCD_H, 0xEE); //too high
lcdDrawVerticalLine(40, LCD_H + 10, 20, SOLID); //too low
lcdDrawVerticalLine(250, LCD_H + 10, LCD_H, SOLID); //x outside display
EXPECT_TRUE(checkScreenshot("lcdDrawVerticalLine"));
}
#endif
template <int padding> class TestBuffer
{
private:
uint8_t * buf;
uint32_t size;
public:
TestBuffer(uint32_t size) : buf(0), size(size) {
buf = new uint8_t[size + padding * 2];
memset(buf, 0xA5, padding);
memset(buf+padding, 0x00, size);
memset(buf+padding+size, 0x5A, padding);
};
~TestBuffer() { if (buf) delete[] buf; };
uint8_t * buffer() { return buf + padding; };
void leakCheck() const {
uint8_t paddingCompareBuf[padding];
memset(paddingCompareBuf, 0xA5, padding);
if (memcmp(buf, paddingCompareBuf, padding) != 0) {
ADD_FAILURE() << "buffer leaked low";
};
memset(paddingCompareBuf, 0x5A, padding);
if (memcmp(buf+padding+size, paddingCompareBuf, padding) != 0) {
ADD_FAILURE() << "buffer leaked high";
}
};
};
#if defined(PCBTARANIS)
TEST(Lcd, lcdDrawBitmapLoadAndDisplay)
{
lcdClear();
// Test proper BMP files, they should display correctly
{
TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(7, 32));
EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/4b_7x32.bmp", 7, 32) != NULL);
bitmap.leakCheck();
lcdDrawBitmap(10, 2, bitmap.buffer());
}
{
TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(6, 32));
EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/1b_6x32.bmp", 6, 32) != NULL);
bitmap.leakCheck();
lcdDrawBitmap(20, 2, bitmap.buffer());
}
{
TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(31, 31));
EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/4b_31x31.bmp", 31, 31) != NULL);
bitmap.leakCheck();
lcdDrawBitmap(30, 2, bitmap.buffer());
}
{
TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(39, 32));
EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/1b_39x32.bmp", 39, 32) != NULL);
bitmap.leakCheck();
lcdDrawBitmap(70, 2, bitmap.buffer());
}
{
TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(20, 20));
EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/4b_20x20.bmp", 20, 20) != NULL);
bitmap.leakCheck();
lcdDrawBitmap(120, 2, bitmap.buffer());
}
EXPECT_TRUE(checkScreenshot("lcdDrawBitmapLoadAndDisplay"));
// Test various bad BMP files, they should not display
{
TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(LCD_W+1, 32));
EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), "", LCD_W+1, 32) == NULL) << "to wide";
bitmap.leakCheck();
}
{
TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(10, 10));
EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/1b_39x32.bmp", 10, 10) == NULL) << "to small buffer";
bitmap.leakCheck();
}
}
#endif
#if defined(PCBTARANIS)
TEST(Lcd, lcdDrawLine)
{
int start, length, xOffset;
uint8_t pattern;
lcdClear();
start = 5;
pattern = SOLID;
length = 40;
xOffset = 0;
lcdDrawLine(start+(length>0?1:-1)+xOffset, start, start+(length>0?1:-1)+xOffset+length, start, pattern, 0);
lcdDrawLine(start+xOffset, start+(length>0?1:-1), start+xOffset, start+(length>0?1:-1)+length, pattern, 0);
start = 10;
pattern = DOTTED;
length = 40;
xOffset = 0;
lcdDrawLine(start+(length>0?1:-1)+xOffset, start, start+(length>0?1:-1)+xOffset+length, start, pattern, 0);
lcdDrawLine(start+xOffset, start+(length>0?1:-1), start+xOffset, start+(length>0?1:-1)+length, pattern, 0);
start = 55;
pattern = SOLID;
length = -40;
xOffset = 80;
lcdDrawLine(start+(length>0?1:-1)+xOffset, start, start+(length>0?1:-1)+xOffset+length, start, pattern, 0);
lcdDrawLine(start+xOffset, start+(length>0?1:-1), start+xOffset, start+(length>0?1:-1)+length, pattern, 0);
start = 50;
pattern = DOTTED;
length = -40;
xOffset = 80;
lcdDrawLine(start+(length>0?1:-1)+xOffset, start, start+(length>0?1:-1)+xOffset+length, start, pattern, 0);
lcdDrawLine(start+xOffset, start+(length>0?1:-1), start+xOffset, start+(length>0?1:-1)+length, pattern, 0);
// 45 deg lines
lcdDrawLine( 35, 40, 45, 40, SOLID, FORCE );
lcdDrawLine( 40, 35, 40, 45, SOLID, FORCE );
lcdDrawLine( 20, 40, 40, 20, SOLID, FORCE );
lcdDrawLine( 40, 20, 60, 40, SOLID, FORCE );
lcdDrawLine( 60, 40, 40, 60, SOLID, FORCE );
lcdDrawLine( 40, 60, 20, 40, SOLID, FORCE );
lcdDrawLine( 31, 39, 39, 31, SOLID, FORCE );
lcdDrawLine( 41, 31, 49, 39, SOLID, FORCE );
lcdDrawLine( 49, 41, 41, 49, SOLID, FORCE );
lcdDrawLine( 39, 49, 31, 41, SOLID, FORCE );
// slanted lines
lcdDrawLine( 150, 10, 190, 10, SOLID, FORCE );
lcdDrawLine( 150, 10, 190, 20, SOLID, FORCE );
lcdDrawLine( 150, 10, 190, 30, SOLID, FORCE );
lcdDrawLine( 150, 10, 190, 40, SOLID, FORCE );
lcdDrawLine( 150, 10, 190, 50, SOLID, FORCE );
lcdDrawLine( 150, 10, 190, 50, SOLID, FORCE );
lcdDrawLine( 150, 10, 180, 50, SOLID, FORCE );
lcdDrawLine( 150, 10, 170, 50, SOLID, FORCE );
lcdDrawLine( 150, 10, 160, 50, SOLID, FORCE );
lcdDrawLine( 150, 10, 150, 50, SOLID, FORCE );
EXPECT_TRUE(checkScreenshot("lcdDrawLine"));
}
#endif
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <QtCore/QDir>
#include <QtCore/QDebug>
#include <QtGui/QApplication>
#include <QtGui/QPainter>
#include <math.h>
#include <gtest/gtest.h>
#define SWAP_DEFINED
#include "opentx.h"
#include "location.h"
void doPaint(QPainter & p)
{
QRgb rgb = qRgb(161, 161, 161);
p.setBackground(QBrush(rgb));
p.eraseRect(0, 0, LCD_W, LCD_H);
if (1) {
#if !defined(PCBTARANIS)
rgb = qRgb(0, 0, 0);
p.setPen(rgb);
p.setBrush(QBrush(rgb));
#endif
#if defined(PCBTARANIS)
unsigned int previousDepth = 0xFF;
#endif
for (int y=0; y<LCD_H; y++) {
#if defined(PCBTARANIS)
unsigned int idx = (y/2) * LCD_W;
#else
unsigned int idx = (y/8) * LCD_W;
unsigned int mask = (1 << (y%8));
#endif
for (int x=0; x<LCD_W; x++, idx++) {
#if !defined(PCBTARANIS)
if (simuLcdBuf[idx] & mask) {
p.drawPoint(x, y);
}
#else
unsigned int z = (y & 1) ? (simuLcdBuf[idx] >> 4) : (simuLcdBuf[idx] & 0x0F);
if (z) {
if (z != previousDepth) {
previousDepth = z;
rgb = qRgb(161-(z*161)/15, 161-(z*161)/15, 161-(z*161)/15);
p.setPen(rgb);
p.setBrush(QBrush(rgb));
}
p.drawPoint(x, y);
}
#endif
}
}
}
}
bool checkScreenshot(const QString & test)
{
lcdRefresh();
QImage buffer(LCD_W, LCD_H, QImage::Format_RGB32);
QPainter p(&buffer);
doPaint(p);
QString filename(QString("%1_%2x%3.png").arg(test).arg(LCD_W).arg(LCD_H));
buffer.save("/tmp/" + filename);
QFile screenshot("/tmp/" + filename);
if (!screenshot.open(QIODevice::ReadOnly))
return false;
QFile reference( TESTS_PATH "/tests/" + filename);
if (!reference.open(QIODevice::ReadOnly))
return false;
if (reference.readAll() != screenshot.readAll())
return false;
screenshot.remove();
return true;
}
TEST(outdezNAtt, test_unsigned)
{
lcdClear();
lcdDrawNumber(0, 0, 65530, LEFT|UNSIGN);
EXPECT_TRUE(checkScreenshot("unsigned")) << "Unsigned numbers will be bad displayed";
}
#if defined(CPUARM)
TEST(outdezNAtt, testBigNumbers)
{
lcdClear();
lcdDrawNumber(0, 0, 1234567, LEFT);
lcdDrawNumber(0, FH, -1234567, LEFT);
EXPECT_TRUE(checkScreenshot("big_numbers"));
}
#endif // #if defined(CPUARM)
TEST(Lcd, Invers_0_0)
{
lcdClear();
lcdDrawText(0, 0, "Test", INVERS);
EXPECT_TRUE(checkScreenshot("invers_0_0"));
}
TEST(Lcd, Invers_0_1)
{
lcdClear();
lcdDrawText(0, 1, "Test", INVERS);
EXPECT_TRUE(checkScreenshot("invers_0_1"));
}
TEST(Lcd, Prec2_Left)
{
lcdClear();
lcdDrawNumber(0, 0, 2, PREC2|LEFT);
EXPECT_TRUE(checkScreenshot("prec2_left"));
}
TEST(Lcd, Prec2_Right)
{
lcdClear();
lcdDrawNumber(LCD_W, LCD_H-FH, 2, PREC2);
EXPECT_TRUE(checkScreenshot("prec2_right"));
}
#if defined(CPUARM)
TEST(Lcd, Prec1_Dblsize_Invers)
{
lcdClear();
lcdDrawNumber(LCD_W, 10, 51, PREC1|DBLSIZE|INVERS);
EXPECT_TRUE(checkScreenshot("prec1_dblsize_invers"));
}
#endif
TEST(Lcd, Line_Wrap)
{
lcdClear();
lcdDrawText(LCD_W-10, 0, "TEST");
EXPECT_TRUE(checkScreenshot("line_wrap"));
}
TEST(Lcd, DblsizeBottomRight)
{
lcdClear();
lcdDrawText(LCD_W-20, LCD_H-16, "TEST", DBLSIZE);
EXPECT_TRUE(checkScreenshot("dblsize_bottom_right"));
}
#if defined(CPUARM)
TEST(Lcd, Smlsize_drawStringWithIndex)
{
lcdClear();
drawStringWithIndex(0, 0, "FM", 0, SMLSIZE);
EXPECT_TRUE(checkScreenshot("smlsize_drawstringwithindex"));
}
#endif
TEST(Lcd, vline)
{
lcdClear();
for (int x=0; x<100; x+=2) {
lcdDrawSolidVerticalLine(x, x/2, 12);
}
EXPECT_TRUE(checkScreenshot("vline"));
}
#if defined(CPUARM)
TEST(Lcd, vline_x_lt0)
{
lcdClear();
lcdDrawSolidVerticalLine(50, -10, 12);
lcdDrawSolidVerticalLine(100, -10, 1);
EXPECT_TRUE(checkScreenshot("vline_lt0"));
}
#endif
#if defined(CPUARM)
TEST(Lcd, Smlsize)
{
lcdClear();
lcdDrawText(0, 0, "TESTgy,", SMLSIZE);
lcdDrawText(10, 22, "TESTgy,", SMLSIZE|INVERS);
lcdDrawFilledRect(8, 40, 100, 20);
lcdDrawText(10, 42, "TESTgy,", SMLSIZE);
bool invert = false;
for(int i=0; i<3; i++) {
lcdDrawText(40+(4*i), 0+(4*i), "ABC", SMLSIZE|(invert?INVERS:0));
invert = !invert;
}
EXPECT_TRUE(checkScreenshot("smlsize"));
}
TEST(Lcd, Stdsize)
{
lcdClear();
lcdDrawText(0, 0, "TEST", 0);
lcdDrawText(10, 22, "TEST", INVERS);
lcdDrawFilledRect(8, 40, 100, 20);
lcdDrawText(10, 42, "TEST", 0);
bool invert = false;
for(int i=0; i<3; i++) {
lcdDrawText(40+(4*i), 0+(4*i), "ABC", (invert?INVERS:0));
invert = !invert;
}
EXPECT_TRUE(checkScreenshot("stdsize"));
}
TEST(Lcd, Midsize)
{
lcdClear();
lcdDrawText(0, 0, "TEST", MIDSIZE);
lcdDrawText(10, 22, "TEST", MIDSIZE|INVERS);
lcdDrawFilledRect(8, 40, 100, 20);
lcdDrawText(10, 42, "TEST", MIDSIZE);
bool invert = false;
for(int i=0; i<3; i++) {
lcdDrawText(40+(4*i), 0+(4*i), "ABC", MIDSIZE|(invert?INVERS:0));
invert = !invert;
}
EXPECT_TRUE(checkScreenshot("midsize"));
}
TEST(Lcd, Dblsize)
{
lcdClear();
lcdDrawText(2, 10, "TST", DBLSIZE);
lcdDrawText(42, 10, "TST", DBLSIZE|INVERS);
lcdDrawFilledRect(80, 8, 46, 24);
lcdDrawText(82, 10, "TST", DBLSIZE);
bool invert = false;
for(int i=0; i<3; i++) {
lcdDrawText(10+(4*i), 30+(4*i), "ABC", DBLSIZE|(invert?INVERS:0));
invert = !invert;
}
EXPECT_TRUE(checkScreenshot("dblsize"));
}
#endif
#if defined(PCBTARANIS)
TEST(Lcd, DrawSwitch)
{
lcdClear();
putsSwitches(0, 10, SWSRC_SA0, 0);
putsSwitches(30, 10, SWSRC_SA0, SMLSIZE);
// putsSwitches(60, 10, SWSRC_SA0, MIDSIZE); missing arrows in this font
putsSwitches(90, 10, SWSRC_SA0, DBLSIZE);
EXPECT_TRUE(checkScreenshot("drawswitch"));
}
#endif
#if defined(PCBTARANIS)
TEST(Lcd, BMPWrapping)
{
lcdClear();
uint8_t bitmap[2+40*40/2];
lcdLoadBitmap(bitmap, TESTS_PATH "/tests/plane.bmp", 40, 40);
lcdDrawBitmap(200, 0, bitmap);
lcdDrawBitmap(200, 60, bitmap);
lcdDrawBitmap(240, 60, bitmap); // x too big
lcdDrawBitmap(20, 200, bitmap); // y too big
EXPECT_TRUE(checkScreenshot("bmpwrapping"));
}
#endif
#if defined(PCBTARANIS)
TEST(Lcd, lcdDrawHorizontalLine)
{
lcdClear();
lcdDrawHorizontalLine(0, 10, LCD_W, DOTTED);
lcdDrawHorizontalLine(0, 20, LCD_W, SOLID);
lcdDrawHorizontalLine(50, 30, LCD_W, 0xEE); //too wide
lcdDrawHorizontalLine(50, LCD_H + 10, 20, SOLID); //too low
lcdDrawHorizontalLine(250, 30, LCD_W, SOLID); //x outside display
EXPECT_TRUE(checkScreenshot("lcdDrawHorizontalLine"));
}
#endif
#if defined(PCBTARANIS)
TEST(Lcd, lcdDrawVerticalLine)
{
lcdClear();
lcdDrawVerticalLine(10, 0, LCD_H, DOTTED);
lcdDrawVerticalLine(20, 0, LCD_H, SOLID);
lcdDrawVerticalLine(30, 30, LCD_H, 0xEE); //too high
lcdDrawVerticalLine(40, LCD_H + 10, 20, SOLID); //too low
lcdDrawVerticalLine(250, LCD_H + 10, LCD_H, SOLID); //x outside display
EXPECT_TRUE(checkScreenshot("lcdDrawVerticalLine"));
}
#endif
template <int padding> class TestBuffer
{
private:
uint8_t * buf;
uint32_t size;
public:
TestBuffer(uint32_t size) : buf(0), size(size) {
buf = new uint8_t[size + padding * 2];
memset(buf, 0xA5, padding);
memset(buf+padding, 0x00, size);
memset(buf+padding+size, 0x5A, padding);
};
~TestBuffer() { if (buf) delete[] buf; };
uint8_t * buffer() { return buf + padding; };
void leakCheck() const {
uint8_t paddingCompareBuf[padding];
memset(paddingCompareBuf, 0xA5, padding);
if (memcmp(buf, paddingCompareBuf, padding) != 0) {
ADD_FAILURE() << "buffer leaked low";
};
memset(paddingCompareBuf, 0x5A, padding);
if (memcmp(buf+padding+size, paddingCompareBuf, padding) != 0) {
ADD_FAILURE() << "buffer leaked high";
}
};
};
#if defined(PCBTARANIS)
TEST(Lcd, lcdDrawBitmapLoadAndDisplay)
{
lcdClear();
// Test proper BMP files, they should display correctly
{
TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(7, 32));
EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/4b_7x32.bmp", 7, 32) != NULL);
bitmap.leakCheck();
lcdDrawBitmap(10, 2, bitmap.buffer());
}
{
TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(6, 32));
EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/1b_6x32.bmp", 6, 32) != NULL);
bitmap.leakCheck();
lcdDrawBitmap(20, 2, bitmap.buffer());
}
{
TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(31, 31));
EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/4b_31x31.bmp", 31, 31) != NULL);
bitmap.leakCheck();
lcdDrawBitmap(30, 2, bitmap.buffer());
}
{
TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(39, 32));
EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/1b_39x32.bmp", 39, 32) != NULL);
bitmap.leakCheck();
lcdDrawBitmap(70, 2, bitmap.buffer());
}
{
TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(20, 20));
EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/4b_20x20.bmp", 20, 20) != NULL);
bitmap.leakCheck();
lcdDrawBitmap(120, 2, bitmap.buffer());
}
EXPECT_TRUE(checkScreenshot("lcdDrawBitmapLoadAndDisplay"));
// Test various bad BMP files, they should not display
{
TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(LCD_W+1, 32));
EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), "", LCD_W+1, 32) == NULL) << "to wide";
bitmap.leakCheck();
}
{
TestBuffer<1000> bitmap(BITMAP_BUFFER_SIZE(10, 10));
EXPECT_TRUE(lcdLoadBitmap(bitmap.buffer(), TESTS_PATH "/tests/1b_39x32.bmp", 10, 10) == NULL) << "to small buffer";
bitmap.leakCheck();
}
}
#endif
#if defined(PCBTARANIS)
TEST(Lcd, lcdDrawLine)
{
int start, length, xOffset;
uint8_t pattern;
lcdClear();
start = 5;
pattern = SOLID;
length = 40;
xOffset = 0;
lcdDrawLine(start+(length>0?1:-1)+xOffset, start, start+(length>0?1:-1)+xOffset+length, start, pattern, 0);
lcdDrawLine(start+xOffset, start+(length>0?1:-1), start+xOffset, start+(length>0?1:-1)+length, pattern, 0);
start = 10;
pattern = DOTTED;
length = 40;
xOffset = 0;
lcdDrawLine(start+(length>0?1:-1)+xOffset, start, start+(length>0?1:-1)+xOffset+length, start, pattern, 0);
lcdDrawLine(start+xOffset, start+(length>0?1:-1), start+xOffset, start+(length>0?1:-1)+length, pattern, 0);
start = 55;
pattern = SOLID;
length = -40;
xOffset = 80;
lcdDrawLine(start+(length>0?1:-1)+xOffset, start, start+(length>0?1:-1)+xOffset+length, start, pattern, 0);
lcdDrawLine(start+xOffset, start+(length>0?1:-1), start+xOffset, start+(length>0?1:-1)+length, pattern, 0);
start = 50;
pattern = DOTTED;
length = -40;
xOffset = 80;
lcdDrawLine(start+(length>0?1:-1)+xOffset, start, start+(length>0?1:-1)+xOffset+length, start, pattern, 0);
lcdDrawLine(start+xOffset, start+(length>0?1:-1), start+xOffset, start+(length>0?1:-1)+length, pattern, 0);
// 45 deg lines
lcdDrawLine( 35, 40, 45, 40, SOLID, FORCE );
lcdDrawLine( 40, 35, 40, 45, SOLID, FORCE );
lcdDrawLine( 20, 40, 40, 20, SOLID, FORCE );
lcdDrawLine( 40, 20, 60, 40, SOLID, FORCE );
lcdDrawLine( 60, 40, 40, 60, SOLID, FORCE );
lcdDrawLine( 40, 60, 20, 40, SOLID, FORCE );
lcdDrawLine( 31, 39, 39, 31, SOLID, FORCE );
lcdDrawLine( 41, 31, 49, 39, SOLID, FORCE );
lcdDrawLine( 49, 41, 41, 49, SOLID, FORCE );
lcdDrawLine( 39, 49, 31, 41, SOLID, FORCE );
// slanted lines
lcdDrawLine( 150, 10, 190, 10, SOLID, FORCE );
lcdDrawLine( 150, 10, 190, 20, SOLID, FORCE );
lcdDrawLine( 150, 10, 190, 30, SOLID, FORCE );
lcdDrawLine( 150, 10, 190, 40, SOLID, FORCE );
lcdDrawLine( 150, 10, 190, 50, SOLID, FORCE );
lcdDrawLine( 150, 10, 190, 50, SOLID, FORCE );
lcdDrawLine( 150, 10, 180, 50, SOLID, FORCE );
lcdDrawLine( 150, 10, 170, 50, SOLID, FORCE );
lcdDrawLine( 150, 10, 160, 50, SOLID, FORCE );
lcdDrawLine( 150, 10, 150, 50, SOLID, FORCE );
EXPECT_TRUE(checkScreenshot("lcdDrawLine"));
}
#endif

View file

@ -1,184 +1,168 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <math.h>
#include "gtests.h"
#if defined(LUA)
#define SWAP_DEFINED
#include "opentx.h"
extern const char * zchar2string(const char * zstring, int size);
#define EXPECT_ZSTREQ(c_string, z_string) EXPECT_STREQ(c_string, zchar2string(z_string, sizeof(z_string)))
::testing::AssertionResult __luaExecStr(const char * str)
{
extern lua_State * L;
if (!L) luaInit();
if (!L) return ::testing::AssertionFailure() << "No Lua state!";
if (luaL_dostring(L, str)) {
return ::testing::AssertionFailure() << "lua error: " << lua_tostring(L, -1);
}
return ::testing::AssertionSuccess();
}
#define luaExecStr(test) EXPECT_TRUE(__luaExecStr(test))
TEST(Lua, testSetModelInfo)
{
luaExecStr("info = model.getInfo()");
// luaExecStr("print('model name: '..info.name..' id: '..info.id)");
luaExecStr("info.name = 'modelA'");
luaExecStr("model.setInfo(info)");
// luaExecStr("print('model name: '..info.name..' id: '..info.id)");
EXPECT_ZSTREQ("modelA", g_model.header.name);
luaExecStr("info.name = 'Model 1'");
luaExecStr("model.setInfo(info)");
// luaExecStr("print('model name: '..info.name..' id: '..info.id)");
EXPECT_ZSTREQ("Model 1", g_model.header.name);
}
TEST(Lua, testPanicProtection)
{
bool passed = false;
PROTECT_LUA() {
PROTECT_LUA() {
//simulate panic
longjmp(global_lj->b, 1);
}
else {
//we should come here
passed = true;
}
UNPROTECT_LUA();
}
else {
// an not here
// TRACE("testLuaProtection: test 1 FAILED");
FAIL() << "Failed test 1";
}
UNPROTECT_LUA()
EXPECT_EQ(passed, true);
passed = false;
PROTECT_LUA() {
PROTECT_LUA() {
int a = 5;
a = a; // avoids the warning
}
else {
//we should not come here
// TRACE("testLuaProtection: test 2 FAILED");
FAIL() << "Failed test 2";
}
UNPROTECT_LUA()
//simulate panic
longjmp(global_lj->b, 1);
}
else {
// we should come here
passed = true;
}
UNPROTECT_LUA()
EXPECT_EQ(passed, true);
}
TEST(Lua, testModelInputs)
{
MODEL_RESET();
luaExecStr("noInputs = model.getInputsCount(0)");
luaExecStr("if noInputs > 0 then error('getInputsCount()') end");
// add one line on Input4
luaExecStr("model.insertInput(3, 0, {name='test1', source=MIXSRC_Thr, weight=56, offset=3, switch=2})");
EXPECT_EQ(3, (int)g_model.expoData[0].chn);
EXPECT_ZSTREQ("test1", g_model.expoData[0].name);
EXPECT_EQ(MIXSRC_Thr, g_model.expoData[0].srcRaw);
EXPECT_EQ(56, g_model.expoData[0].weight);
EXPECT_EQ(3, g_model.expoData[0].offset);
EXPECT_EQ(2, g_model.expoData[0].swtch);
// add another one before existing line on Input4
luaExecStr("model.insertInput(3, 0, {name='test2', source=MIXSRC_Rud, weight=-56})");
EXPECT_EQ(3, (int)g_model.expoData[0].chn);
EXPECT_ZSTREQ("test2", g_model.expoData[0].name);
EXPECT_EQ(MIXSRC_Rud, g_model.expoData[0].srcRaw);
EXPECT_EQ(-56, g_model.expoData[0].weight);
EXPECT_EQ(0, g_model.expoData[0].offset);
EXPECT_EQ(0, g_model.expoData[0].swtch);
EXPECT_EQ(3, (int)g_model.expoData[1].chn);
EXPECT_ZSTREQ("test1", g_model.expoData[1].name);
EXPECT_EQ(MIXSRC_Thr, g_model.expoData[1].srcRaw);
EXPECT_EQ(56, g_model.expoData[1].weight);
EXPECT_EQ(3, g_model.expoData[1].offset);
EXPECT_EQ(2, g_model.expoData[1].swtch);
// add another line after existing lines on Input4
luaExecStr("model.insertInput(3, model.getInputsCount(3), {name='test3', source=MIXSRC_Ail, weight=100})");
EXPECT_EQ(3, (int)g_model.expoData[0].chn);
EXPECT_ZSTREQ("test2", g_model.expoData[0].name);
EXPECT_EQ(MIXSRC_Rud, g_model.expoData[0].srcRaw);
EXPECT_EQ(-56, g_model.expoData[0].weight);
EXPECT_EQ(0, g_model.expoData[0].offset);
EXPECT_EQ(0, g_model.expoData[0].swtch);
EXPECT_EQ(3, (int)g_model.expoData[1].chn);
EXPECT_ZSTREQ("test1", g_model.expoData[1].name);
EXPECT_EQ(MIXSRC_Thr, g_model.expoData[1].srcRaw);
EXPECT_EQ(56, g_model.expoData[1].weight);
EXPECT_EQ(3, g_model.expoData[1].offset);
EXPECT_EQ(2, g_model.expoData[1].swtch);
EXPECT_EQ(3, (int)g_model.expoData[2].chn);
EXPECT_ZSTREQ("test3", g_model.expoData[2].name);
EXPECT_EQ(MIXSRC_Ail, g_model.expoData[2].srcRaw);
EXPECT_EQ(100, g_model.expoData[2].weight);
EXPECT_EQ(0, g_model.expoData[2].offset);
EXPECT_EQ(0, g_model.expoData[2].swtch);
// verify number of lines for Input4
luaExecStr("noInputs = model.getInputsCount(3)");
luaExecStr("if noInputs ~= 3 then error('getInputsCount()') end");
}
#endif // #if defined(LUA)
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <math.h>
#include "gtests.h"
#if defined(LUA)
#define SWAP_DEFINED
#include "opentx.h"
extern const char * zchar2string(const char * zstring, int size);
#define EXPECT_ZSTREQ(c_string, z_string) EXPECT_STREQ(c_string, zchar2string(z_string, sizeof(z_string)))
::testing::AssertionResult __luaExecStr(const char * str)
{
extern lua_State * L;
if (!L) luaInit();
if (!L) return ::testing::AssertionFailure() << "No Lua state!";
if (luaL_dostring(L, str)) {
return ::testing::AssertionFailure() << "lua error: " << lua_tostring(L, -1);
}
return ::testing::AssertionSuccess();
}
#define luaExecStr(test) EXPECT_TRUE(__luaExecStr(test))
TEST(Lua, testSetModelInfo)
{
luaExecStr("info = model.getInfo()");
// luaExecStr("print('model name: '..info.name..' id: '..info.id)");
luaExecStr("info.name = 'modelA'");
luaExecStr("model.setInfo(info)");
// luaExecStr("print('model name: '..info.name..' id: '..info.id)");
EXPECT_ZSTREQ("modelA", g_model.header.name);
luaExecStr("info.name = 'Model 1'");
luaExecStr("model.setInfo(info)");
// luaExecStr("print('model name: '..info.name..' id: '..info.id)");
EXPECT_ZSTREQ("Model 1", g_model.header.name);
}
TEST(Lua, testPanicProtection)
{
bool passed = false;
PROTECT_LUA() {
PROTECT_LUA() {
//simulate panic
longjmp(global_lj->b, 1);
}
else {
//we should come here
passed = true;
}
UNPROTECT_LUA();
}
else {
// an not here
// TRACE("testLuaProtection: test 1 FAILED");
FAIL() << "Failed test 1";
}
UNPROTECT_LUA()
EXPECT_EQ(passed, true);
passed = false;
PROTECT_LUA() {
PROTECT_LUA() {
int a = 5;
a = a; // avoids the warning
}
else {
//we should not come here
// TRACE("testLuaProtection: test 2 FAILED");
FAIL() << "Failed test 2";
}
UNPROTECT_LUA()
//simulate panic
longjmp(global_lj->b, 1);
}
else {
// we should come here
passed = true;
}
UNPROTECT_LUA()
EXPECT_EQ(passed, true);
}
TEST(Lua, testModelInputs)
{
MODEL_RESET();
luaExecStr("noInputs = model.getInputsCount(0)");
luaExecStr("if noInputs > 0 then error('getInputsCount()') end");
// add one line on Input4
luaExecStr("model.insertInput(3, 0, {name='test1', source=MIXSRC_Thr, weight=56, offset=3, switch=2})");
EXPECT_EQ(3, (int)g_model.expoData[0].chn);
EXPECT_ZSTREQ("test1", g_model.expoData[0].name);
EXPECT_EQ(MIXSRC_Thr, g_model.expoData[0].srcRaw);
EXPECT_EQ(56, g_model.expoData[0].weight);
EXPECT_EQ(3, g_model.expoData[0].offset);
EXPECT_EQ(2, g_model.expoData[0].swtch);
// add another one before existing line on Input4
luaExecStr("model.insertInput(3, 0, {name='test2', source=MIXSRC_Rud, weight=-56})");
EXPECT_EQ(3, (int)g_model.expoData[0].chn);
EXPECT_ZSTREQ("test2", g_model.expoData[0].name);
EXPECT_EQ(MIXSRC_Rud, g_model.expoData[0].srcRaw);
EXPECT_EQ(-56, g_model.expoData[0].weight);
EXPECT_EQ(0, g_model.expoData[0].offset);
EXPECT_EQ(0, g_model.expoData[0].swtch);
EXPECT_EQ(3, (int)g_model.expoData[1].chn);
EXPECT_ZSTREQ("test1", g_model.expoData[1].name);
EXPECT_EQ(MIXSRC_Thr, g_model.expoData[1].srcRaw);
EXPECT_EQ(56, g_model.expoData[1].weight);
EXPECT_EQ(3, g_model.expoData[1].offset);
EXPECT_EQ(2, g_model.expoData[1].swtch);
// add another line after existing lines on Input4
luaExecStr("model.insertInput(3, model.getInputsCount(3), {name='test3', source=MIXSRC_Ail, weight=100})");
EXPECT_EQ(3, (int)g_model.expoData[0].chn);
EXPECT_ZSTREQ("test2", g_model.expoData[0].name);
EXPECT_EQ(MIXSRC_Rud, g_model.expoData[0].srcRaw);
EXPECT_EQ(-56, g_model.expoData[0].weight);
EXPECT_EQ(0, g_model.expoData[0].offset);
EXPECT_EQ(0, g_model.expoData[0].swtch);
EXPECT_EQ(3, (int)g_model.expoData[1].chn);
EXPECT_ZSTREQ("test1", g_model.expoData[1].name);
EXPECT_EQ(MIXSRC_Thr, g_model.expoData[1].srcRaw);
EXPECT_EQ(56, g_model.expoData[1].weight);
EXPECT_EQ(3, g_model.expoData[1].offset);
EXPECT_EQ(2, g_model.expoData[1].swtch);
EXPECT_EQ(3, (int)g_model.expoData[2].chn);
EXPECT_ZSTREQ("test3", g_model.expoData[2].name);
EXPECT_EQ(MIXSRC_Ail, g_model.expoData[2].srcRaw);
EXPECT_EQ(100, g_model.expoData[2].weight);
EXPECT_EQ(0, g_model.expoData[2].offset);
EXPECT_EQ(0, g_model.expoData[2].swtch);
// verify number of lines for Input4
luaExecStr("noInputs = model.getInputsCount(3)");
luaExecStr("if noInputs ~= 3 then error('getInputsCount()') end");
}
#endif // #if defined(LUA)

File diff suppressed because it is too large Load diff

View file

@ -1,27 +1,12 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
* Copyright (C) OpenTX
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@ -31,7 +16,6 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include "gtests.h"

View file

@ -1,255 +1,239 @@
/*
* Authors (alphabetical order)
* - Andre Bernet <bernet.andre@gmail.com>
* - Andreas Weitl
* - Bertrand Songis <bsongis@gmail.com>
* - Bryan J. Rentoul (Gruvin) <gruvin@gmail.com>
* - Cameron Weeks <th9xer@gmail.com>
* - Erez Raviv
* - Gabriel Birkus
* - Jean-Pierre Parisy
* - Karl Szmutny
* - Michael Blandford
* - Michal Hlavinka
* - Pat Mackenzie
* - Philip Moss
* - Rob Thomson
* - Romolo Manfredini <romolo.manfredini@gmail.com>
* - Thomas Husterer
*
* opentx is based on code named
* gruvin9x by Bryan J. Rentoul: http://code.google.com/p/gruvin9x/,
* er9x by Erez Raviv: http://code.google.com/p/er9x/,
* and the original (and ongoing) project by
* Thomas Husterer, th9x: http://code.google.com/p/th9x/
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include "gtests.h"
#include "opentx.h"
#include "timers.h"
#if !defined(CPUARM)
#undef timerSet
void timerSet(int idx, int16_t val)
{
TimerState & timerState = timersStates[idx];
timerState.state = TMR_OFF; // is changed to RUNNING dep from mode
timerState.val = val;
timerState.val_10ms = 0 ;
}
#endif // #if !defined(CPUARM)
#if defined(ACCURAT_THROTTLE_TIMER)
#define THR_100 128 // approximately 10% full throttle
#define THR_50 64 // approximately 10% full throttle
#define THR_10 13 // approximately 10% full throttle
#else
#define THR_100 32 // approximately 10% full throttle
#define THR_50 16 // approximately 10% full throttle
#define THR_10 3 // approximately 10% full throttle
#endif
#define TEST_AB_EQUAL(a, b) if (a != b) { return ::testing::AssertionFailure() << \
#a "= " << (uint32_t)a << ", " << #b "= " << (uint32_t)b; };
void initModelTimer(uint32_t idx, uint8_t mode, int16_t start = 0)
{
g_model.timers[0].mode = mode;
g_model.timers[0].start = start;
g_model.timers[0].countdownBeep = COUNTDOWN_SILENT;
g_model.timers[0].minuteBeep = 0;
g_model.timers[0].spare = 0;
#if defined(CPUARM) || defined(CPUM2560)
g_model.timers[0].persistent = 0;
g_model.timers[0].value = 0;
#endif
}
/*
Run timers for n seconds and test the end state
*/
::testing::AssertionResult evalTimersForNSecondsAndTest(unsigned int n, uint8_t throttle, uint32_t idx, uint8_t state, int value)
{
unsigned int noLoops = n * 100;
while (noLoops--) {
evalTimers(throttle, 1);
}
TEST_AB_EQUAL(timersStates[idx].state, state);
TEST_AB_EQUAL(timersStates[idx].val, value);
return ::testing::AssertionSuccess();
}
TEST(Timers, timerReset)
{
initModelTimer(0, TMRMODE_THR_REL, 200);
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 0, TMR_OFF, 200));
initModelTimer(1, TMRMODE_THR_REL, 0);
timerReset(1);
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 1, TMR_OFF, 0));
}
#if defined(CPUARM)
TEST(Timers, timerSet)
{
timerSet(0, 500);
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 0, TMR_OFF, 500));
timerSet(1, 300);
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 1, TMR_OFF, 300));
}
TEST(Timers, timerGreaterThan9hours)
{
initModelTimer(0, TMRMODE_ABS, 0);
timerSet(0, 0);
// test with 24 hours
EXPECT_TRUE(evalTimersForNSecondsAndTest(24*3600, THR_100, 0, TMR_RUNNING, 24*3600));
}
#endif // #if defined(CPUARM)
#if defined(CPUARM) || defined(CPUM2560)
TEST(Timers, saveRestoreTimers)
{
g_model.timers[0].persistent = 1;
g_model.timers[1].persistent = 1;
timerSet(0, 500);
timerSet(1, 1500);
saveTimers();
EXPECT_EQ(g_model.timers[0].value, 500);
EXPECT_EQ(g_model.timers[1].value, 1500);
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 0, TMR_OFF, 500));
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 1, TMR_OFF, 1500));
timerReset(0);
timerReset(1);
restoreTimers();
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 0, TMR_OFF, 500));
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 1, TMR_OFF, 1500));
}
#endif
TEST(Timers, timerOff)
{
initModelTimer(0, TMRMODE_NONE, 0);
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 0, TMR_OFF, 0));
EXPECT_TRUE(evalTimersForNSecondsAndTest(10, THR_100, 0, TMR_OFF, 0));
}
TEST(Timers, timerAbsolute)
{
initModelTimer(0, TMRMODE_ABS, 0);
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, 1));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 101));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_RUNNING, 201));
// max timer value test
timerSet(0, TIMER_MAX-10);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, TIMER_MAX-9));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, TIMER_MAX));
// test down-running
g_model.timers[0].start = 200;
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, 199));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 99));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_NEGATIVE, -1));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_STOPPED, -101));
#if !defined(CPUARM)
// min timer value test
timerSet(0, TIMER_MIN+10);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, TIMER_MIN+9));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, TIMER_MIN));
#endif
}
TEST(Timers, timerThrottle)
{
initModelTimer(0, TMRMODE_THR, 0);
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_RUNNING, 0));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 100));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10, 0, TMR_RUNNING, 200));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_RUNNING, 200));
// test down-running
g_model.timers[0].start = 200;
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, 199));
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_RUNNING, 199));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 99));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_50, 0, TMR_NEGATIVE, -1));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_STOPPED,-101));
}
TEST(Timers, timerThrottleRelative)
{
initModelTimer(0, TMRMODE_THR_REL, 0);
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_RUNNING, 0));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 100));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_50, 0, TMR_RUNNING, 150)); // 50% throttle == 50s
#if defined(ACCURAT_THROTTLE_TIMER)
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10, 0, TMR_RUNNING, 160)); // 10% throttle == 10s
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_RUNNING, 160));
#else
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10, 0, TMR_RUNNING, 159)); // 10% throttle == 10s
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_RUNNING, 159));
#endif
// test down-running
initModelTimer(0, TMRMODE_THR_REL, 200);
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, 199));
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_RUNNING, 199));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 99));
EXPECT_TRUE(evalTimersForNSecondsAndTest(200, THR_50, 0, TMR_NEGATIVE, -1)); // 50% throttle == 100s
#if defined(ACCURAT_THROTTLE_TIMER)
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10, 0, TMR_NEGATIVE,-11)); // 10% throttle == 10s
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_STOPPED,-111));
#else
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10, 0, TMR_NEGATIVE,-10)); // 10% throttle == 10s
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_STOPPED,-110));
#endif
}
TEST(Timers, timerThrottleTriggered)
{
initModelTimer(0, TMRMODE_THR_TRG, 0);
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_OFF, 0));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10-1, 0, TMR_OFF, 0)); // below threshold
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_50, 0, TMR_RUNNING, 100));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 200));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_RUNNING, 300));
// test down-running
initModelTimer(0, TMRMODE_THR_TRG, 200);
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_OFF, 200));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10-1, 0, TMR_OFF, 200)); // below threshold
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 100));
EXPECT_TRUE(evalTimersForNSecondsAndTest(101, THR_50, 0, TMR_NEGATIVE, -1));
EXPECT_TRUE(evalTimersForNSecondsAndTest(10, 0, 0, TMR_NEGATIVE,-11));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_STOPPED,-111));
}
/*
* Copyright (C) OpenTX
*
* Based on code named
* th9x - http://code.google.com/p/th9x
* er9x - http://code.google.com/p/er9x
* gruvin9x - http://code.google.com/p/gruvin9x
*
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "gtests.h"
#include "opentx.h"
#include "timers.h"
#if !defined(CPUARM)
#undef timerSet
void timerSet(int idx, int16_t val)
{
TimerState & timerState = timersStates[idx];
timerState.state = TMR_OFF; // is changed to RUNNING dep from mode
timerState.val = val;
timerState.val_10ms = 0 ;
}
#endif // #if !defined(CPUARM)
#if defined(ACCURAT_THROTTLE_TIMER)
#define THR_100 128 // approximately 10% full throttle
#define THR_50 64 // approximately 10% full throttle
#define THR_10 13 // approximately 10% full throttle
#else
#define THR_100 32 // approximately 10% full throttle
#define THR_50 16 // approximately 10% full throttle
#define THR_10 3 // approximately 10% full throttle
#endif
#define TEST_AB_EQUAL(a, b) if (a != b) { return ::testing::AssertionFailure() << \
#a "= " << (uint32_t)a << ", " << #b "= " << (uint32_t)b; };
void initModelTimer(uint32_t idx, uint8_t mode, int16_t start = 0)
{
g_model.timers[0].mode = mode;
g_model.timers[0].start = start;
g_model.timers[0].countdownBeep = COUNTDOWN_SILENT;
g_model.timers[0].minuteBeep = 0;
g_model.timers[0].spare = 0;
#if defined(CPUARM) || defined(CPUM2560)
g_model.timers[0].persistent = 0;
g_model.timers[0].value = 0;
#endif
}
/*
Run timers for n seconds and test the end state
*/
::testing::AssertionResult evalTimersForNSecondsAndTest(unsigned int n, uint8_t throttle, uint32_t idx, uint8_t state, int value)
{
unsigned int noLoops = n * 100;
while (noLoops--) {
evalTimers(throttle, 1);
}
TEST_AB_EQUAL(timersStates[idx].state, state);
TEST_AB_EQUAL(timersStates[idx].val, value);
return ::testing::AssertionSuccess();
}
TEST(Timers, timerReset)
{
initModelTimer(0, TMRMODE_THR_REL, 200);
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 0, TMR_OFF, 200));
initModelTimer(1, TMRMODE_THR_REL, 0);
timerReset(1);
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 1, TMR_OFF, 0));
}
#if defined(CPUARM)
TEST(Timers, timerSet)
{
timerSet(0, 500);
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 0, TMR_OFF, 500));
timerSet(1, 300);
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 1, TMR_OFF, 300));
}
TEST(Timers, timerGreaterThan9hours)
{
initModelTimer(0, TMRMODE_ABS, 0);
timerSet(0, 0);
// test with 24 hours
EXPECT_TRUE(evalTimersForNSecondsAndTest(24*3600, THR_100, 0, TMR_RUNNING, 24*3600));
}
#endif // #if defined(CPUARM)
#if defined(CPUARM) || defined(CPUM2560)
TEST(Timers, saveRestoreTimers)
{
g_model.timers[0].persistent = 1;
g_model.timers[1].persistent = 1;
timerSet(0, 500);
timerSet(1, 1500);
saveTimers();
EXPECT_EQ(g_model.timers[0].value, 500);
EXPECT_EQ(g_model.timers[1].value, 1500);
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 0, TMR_OFF, 500));
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 1, TMR_OFF, 1500));
timerReset(0);
timerReset(1);
restoreTimers();
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 0, TMR_OFF, 500));
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 1, TMR_OFF, 1500));
}
#endif
TEST(Timers, timerOff)
{
initModelTimer(0, TMRMODE_NONE, 0);
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(0, THR_100, 0, TMR_OFF, 0));
EXPECT_TRUE(evalTimersForNSecondsAndTest(10, THR_100, 0, TMR_OFF, 0));
}
TEST(Timers, timerAbsolute)
{
initModelTimer(0, TMRMODE_ABS, 0);
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, 1));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 101));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_RUNNING, 201));
// max timer value test
timerSet(0, TIMER_MAX-10);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, TIMER_MAX-9));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, TIMER_MAX));
// test down-running
g_model.timers[0].start = 200;
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, 199));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 99));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_NEGATIVE, -1));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_STOPPED, -101));
#if !defined(CPUARM)
// min timer value test
timerSet(0, TIMER_MIN+10);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, TIMER_MIN+9));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, TIMER_MIN));
#endif
}
TEST(Timers, timerThrottle)
{
initModelTimer(0, TMRMODE_THR, 0);
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_RUNNING, 0));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 100));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10, 0, TMR_RUNNING, 200));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_RUNNING, 200));
// test down-running
g_model.timers[0].start = 200;
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, 199));
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_RUNNING, 199));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 99));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_50, 0, TMR_NEGATIVE, -1));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_STOPPED,-101));
}
TEST(Timers, timerThrottleRelative)
{
initModelTimer(0, TMRMODE_THR_REL, 0);
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_RUNNING, 0));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 100));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_50, 0, TMR_RUNNING, 150)); // 50% throttle == 50s
#if defined(ACCURAT_THROTTLE_TIMER)
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10, 0, TMR_RUNNING, 160)); // 10% throttle == 10s
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_RUNNING, 160));
#else
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10, 0, TMR_RUNNING, 159)); // 10% throttle == 10s
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_RUNNING, 159));
#endif
// test down-running
initModelTimer(0, TMRMODE_THR_REL, 200);
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, THR_100, 0, TMR_RUNNING, 199));
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_RUNNING, 199));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 99));
EXPECT_TRUE(evalTimersForNSecondsAndTest(200, THR_50, 0, TMR_NEGATIVE, -1)); // 50% throttle == 100s
#if defined(ACCURAT_THROTTLE_TIMER)
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10, 0, TMR_NEGATIVE,-11)); // 10% throttle == 10s
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_STOPPED,-111));
#else
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10, 0, TMR_NEGATIVE,-10)); // 10% throttle == 10s
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_STOPPED,-110));
#endif
}
TEST(Timers, timerThrottleTriggered)
{
initModelTimer(0, TMRMODE_THR_TRG, 0);
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_OFF, 0));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10-1, 0, TMR_OFF, 0)); // below threshold
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_50, 0, TMR_RUNNING, 100));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 200));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_RUNNING, 300));
// test down-running
initModelTimer(0, TMRMODE_THR_TRG, 200);
timerReset(0);
EXPECT_TRUE(evalTimersForNSecondsAndTest(1, 0, 0, TMR_OFF, 200));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_10-1, 0, TMR_OFF, 200)); // below threshold
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, THR_100, 0, TMR_RUNNING, 100));
EXPECT_TRUE(evalTimersForNSecondsAndTest(101, THR_50, 0, TMR_NEGATIVE, -1));
EXPECT_TRUE(evalTimersForNSecondsAndTest(10, 0, 0, TMR_NEGATIVE,-11));
EXPECT_TRUE(evalTimersForNSecondsAndTest(100, 0, 0, TMR_STOPPED,-111));
}