Commit 4dac52e7 by Szeberényi Imre

gtest fix

parent 30afa5b0
......@@ -86,7 +86,7 @@ Nézd meg az osztályt tartalmazó _allapotgep.hpp_ fejlécfájlt!
## Lyszamlalo
Az állapotgép használatát az első félévben már megismert feladattal mutatom be: [Számoljuk egy szövegben az ly-ok számát!](https://infoc.eet.bme.hu/ea12/#6)
Emlékeztetőül az állapotgáf:
Emlékeztetőül az állapotgráf:
![ly](ly.png)
......@@ -120,7 +120,7 @@ Az egyes állapotokhoz kapcsolódó akciókat a következő módon definiáljuk:
//lyszamlalo.hpp
```
Az állapotgép tábláját az átláhatóság kedvéért sornonként adtam meg inicializáló lista segítségével:
Az állapotgép tábláját az átláthatóság kedvéért soronként adtam meg inicializáló lista segítségével:
```c++
Lyszaml::Lyszaml() : Allapotgep(LyAllapot::alap, tab), sz(0) {
tab[LyAllapot::alap] = {{LyInput::l, new Nop(LyAllapot::l_jott)},
......@@ -156,7 +156,7 @@ Nézd meg a _main.cpp_-ben lévő teszteket, állítsd az _ELKESZULT_ makrót 1-
### Split
Hozz létre egy `Split` osztályt, amely a bemenetére érkező karaktereket úgy dolgozza fel, hogy a konstruktorában megadott **határoló karakter** mentén a szöveget feldarabolja, és **get()** függvénye egy `std::vector<std::string>` példányban adja vissza a szétválasztott elemeket!
A bemenet elején/végén érkező határoló karaktereket figyelmen kívül hagyjuk. Amennyiben több határolójel érkezik egymás után, azt egy jelnek tekintjük, azaz nem keletkezik üres sztring a feldolgozás során.
A bemenet elején/végén érkező határoló karaktereket figyelmen kívül hagyjuk. Amennyiben több határoló karakter érkezik egymás után, azt egy karakternek tekintjük, azaz nem keletkezik üres sztring a feldolgozás során.
Nézd meg a _main.cpp_-ben lévő teszteket, állítsd az _ELKESZULT_ makrót 2-re, és próbáld megoldani a feladatot. A megoldás során a *split.hpp* és *split.cpp* fájlokban dolgozz!
......
......@@ -9,6 +9,7 @@
* Sz.I. 2018 (template), ENDM, ENDMsg, nullptr_t
* Sz.I. 2019 singleton
* Sz.I. 2021 ASSERT.., STRCASE...
* Sz.I. 2021 EXPEXT_REGEXP, CREATE_Has_fn_, cmp w. NULL, EXPECT_ param fix
*
* A tesztelés legalapvetőbb funkcióit támogató függvények és makrók.
* Nem szálbiztos megvalósítás.
......@@ -47,8 +48,12 @@
#include <cstdlib>
#include <string>
#include <fstream>
#if __cplusplus >= 201103L
# include <iterator>
# include <regex>
#endif
#ifdef MEMTRACE
#include "memtrace.h"
# include "memtrace.h"
#endif
// Két makró az egyes tesztek elé és mögé:
......@@ -160,6 +165,10 @@
/// Környezeti változóhoz hasonlít -- ilyen nincs a gtest-ben (kisbetű/nagybetű azonos)
#define EXPECT_ENVCASEEQ(expected, actual) gtest_lite::EXPECTSTR(std::getenv(expected), actual, gtest_lite::eqstrcase, __FILE__, __LINE__, "EXPECT_ENVCASEEQ(" #expected ", " #actual ")" )
#if __cplusplus >= 201103L
/// Reguláris kifejezés illesztése
# define EXPECT_REGEXP(expected, actual, match, err) gtest_lite::EXPECTREGEXP(expected, actual, match, err, __FILE__, __LINE__, "EXPECT_REGEXP(" #expected ", " #actual ", " #match ")" )
#endif
////--------------------------------------------------------------------------------------------
/// ASSERT típusú ellenőrzések. CSak 1-2 van megvalósítva. Nem ostream& -val térnek vissza !!!
/// Kivételt várunk
......@@ -178,7 +187,7 @@
/// https://cpptalk.wordpress.com/2009/09/12/substitution-failure-is-not-an-error-2
/// Használat:
/// CREATE_Has_(size)
/// ... if (Has_size<std::string>::member)...
/// ... if (_Has_size<std::string>::member)...
#define CREATE_Has_(X) \
template<typename T> struct _Has_##X { \
struct Fallback { int X; }; \
......@@ -189,6 +198,14 @@ template<typename T> struct _Has_##X { \
static bool const member = sizeof(f<Derived>(0)) == 2; \
};
#define CREATE_Has_fn_(X, S) \
template<typename R, typename T> struct _Has_fn_##X##_##S { \
template<typename C, R (C::*f)() S> struct ChT; \
template<typename D> static char (&f(ChT<D, &D::X>*))[1]; \
template<typename D> static char (&f(...))[2]; \
static bool const fn = sizeof(f<T>(0)) == 1; \
};
/// Segédfüggvény egy publikus adattag, vagy tagfüggvény létezésének tesztelésére
/// fordítási időben
inline void hasMember(...) {}
......@@ -247,12 +264,13 @@ struct Test {
bool tmp; ///< temp a kivételkezeléshez;
std::string name; ///< éppen futó teszt neve
std::fstream null; ///< nyelő, ha nem kell kiírni semmit
std::ostream& os; ///< ide írunk
static Test& getTest() {
static Test instance;///< egyedüli (singleton) példány
return instance;
}
private: /// singleton minta miatt
Test() :sum(0), failed(0), status(false), null("/dev/null") {}
Test() :sum(0), failed(0), status(false), null("/dev/null"), os(std::cout) {}
Test(const Test&);
void operator=(const Test&);
public:
......@@ -262,9 +280,7 @@ public:
#ifdef MEMTRACE
ablocks = memtrace::allocated_blocks();
#endif
#ifndef CPORTA
std::cerr << "\n---> " << name << std::endl;
#endif // CPORTA
os << "\n---> " << name << std::endl;
++sum;
}
/// Teszt vége
......@@ -272,15 +288,16 @@ public:
#ifdef MEMTRACE
if (memchk && ablocks != memtrace::allocated_blocks()) {
status = false;
return std::cerr << "** Lehet, hogy nem szabaditott fel minden memoriat! **" << std::endl;
return os << "** Lehet, hogy nem szabaditott fel minden memoriat! **" << std::endl;
}
#endif
os << (status ? " SIKERES" : "** HIBAS ****") << "\t" << name << " <---" << std::endl;
#ifdef CPORTA
if (!status)
#endif // CPORTA
std::cerr << (status ? " SIKERES" : "** HIBAS ****") << "\t" << name << " <---" << std::endl;
#endif // CPORTA
if (!status)
return std::cerr;
return os;
else
return null;
}
......@@ -300,17 +317,20 @@ public:
size_t i = str.rfind("\\");
if (i == std::string::npos) i = str.rfind("/");
if (i == std::string::npos) i = 0; else i++;
return std::cerr << "\n**** " << &file[i] << "(" << line << "): " << expr << " ****" << std::endl;
return os << "\n**** " << &file[i] << "(" << line << "): " << expr << " ****" << std::endl;
}
return null;
}
/// Destruktor
~Test() {
if (sum != 0) {
os << "\n==== TESZT VEGE ==== HIBAS/OSSZES: " << failed << "/" << sum << std::endl;
#ifdef CPORTA
if (failed)
#endif // CPORTA
std::cerr << "\n==== TESZT VEGE ==== HIBAS/OSSZES: " << failed << "/" << sum << std::endl;
#endif // CPORTA
}
}
};
......@@ -320,7 +340,7 @@ static Test& test = Test::getTest();
/// általános sablon a várt értékhez.
template <typename T1, typename T2>
std::ostream& EXPECT_(T1 exp, T2 act, bool (*pred)(T1, T2), const char *file, int line,
std::ostream& EXPECT_(T1 exp, T2 act, bool (*pred)(T1, T1), const char *file, int line,
const char *expr, const char *lhs = "elvart", const char *rhs = "aktual") {
return test.expect(pred(exp, act), file, line, expr)
<< "** " << lhs << ": " << std::boolalpha << exp
......@@ -329,7 +349,7 @@ std::ostream& EXPECT_(T1 exp, T2 act, bool (*pred)(T1, T2), const char *file, in
/// pointerre specializált sablon a várt értékhez.
template <typename T1, typename T2>
std::ostream& EXPECT_(T1* exp, T2* act, bool (*pred)(T1*, T2*), const char *file, int line,
std::ostream& EXPECT_(T1* exp, T2* act, bool (*pred)(T1*, T1*), const char *file, int line,
const char *expr, const char *lhs = "elvart", const char *rhs = "aktual") {
return test.expect(pred(exp, act), file, line, expr)
<< "** " << lhs << ": " << (void*) exp
......@@ -338,8 +358,16 @@ std::ostream& EXPECT_(T1* exp, T2* act, bool (*pred)(T1*, T2*), const char *file
#if __cplusplus >= 201103L
/// nullptr-re specializált sablon a várt értékhez.
template <typename T1>
std::ostream& EXPECT_(T1* exp, std::nullptr_t act, bool (*pred)(T1*, std::nullptr_t), const char *file, int line,
template <typename T>
std::ostream& EXPECT_(std::nullptr_t exp, T* act, bool (*pred)(T*, T*), const char *file, int line,
const char *expr, const char *lhs = "elvart", const char *rhs = "aktual") {
return test.expect(pred(exp, act), file, line, expr)
<< "** " << lhs << ": " << (void*) exp
<< "\n** " << rhs << ": " << (void*) act << std::endl;
}
template <typename T>
std::ostream& EXPECT_(T* exp, std::nullptr_t act, bool (*pred)(T*, T*), const char *file, int line,
const char *expr, const char *lhs = "elvart", const char *rhs = "aktual") {
return test.expect(pred(exp, act), file, line, expr)
<< "** " << lhs << ": " << (void*) exp
......@@ -357,10 +385,33 @@ std::ostream& EXPECTSTR(const char *exp, const char *act, bool (*pred)(const cha
<< "\n** " << rhs << ": " << (act == NULL ? "NULL pointer" : std::string("\"") + act + std::string("\"")) << std::endl;
}
#if __cplusplus >= 201103L
/// regexp összehasonlításhoz.
template <typename E, typename S>
int count_regexp(E exp, S str) {
std::regex rexp(exp);
auto w_beg = std::sregex_iterator(str.begin(), str.end(), rexp);
auto w_end = std::sregex_iterator();
return std::distance(w_beg, w_end);
}
template <typename E, typename S>
std::ostream& EXPECTREGEXP(E exp, S str, int match, const char *err, const char *file, int line,
const char *expr, const char *lhs = "regexp", const char *rhs = "string",
const char *m = "elvart/illeszkedik") {
int cnt = count_regexp(exp, str);
if (match < 0) match = cnt;
return test.expect(cnt == match, file, line, expr)
<< "** " << lhs << ": " << std::string("\"") + exp + std::string("\"")
<< "\n** " << rhs << ": " << (err == NULL ? std::string("\"") + str + std::string("\"") : err)
<< "\n** " << m << ": " << match << "/" << cnt << std::endl;
}
#endif
/// segéd sablonok a relációkhoz.
/// azért nem STL (algorithm), mert csak a függvény lehet, hogy menjen a deduckció
template <typename T1, typename T2>
bool eq(T1 a, T2 b) { return a == b; }
template <typename T>
bool eq(T a, T b) { return a == b; }
inline
bool eqstr(const char *a, const char *b) {
......@@ -382,8 +433,8 @@ bool eqstrcase(const char *a, const char *b) {
}
template <typename T1, typename T2>
bool ne(T1 a, T2 b) { return a != b; }
template <typename T>
bool ne(T a, T b) { return a != b; }
inline
bool nestr(const char *a, const char *b) {
......@@ -392,17 +443,17 @@ bool nestr(const char *a, const char *b) {
return false;
}
template <typename T1, typename T2>
bool le(T1 a, T2 b) { return a <= b; }
template <typename T>
bool le(T a, T b) { return a <= b; }
template <typename T1, typename T2>
bool lt(T1 a, T2 b) { return a < b; }
template <typename T>
bool lt(T a, T b) { return a < b; }
template <typename T1, typename T2>
bool ge(T1 a, T2 b) { return a >= b; }
template <typename T>
bool ge(T a, T b) { return a >= b; }
template <typename T1, typename T2>
bool gt(T1 a, T2 b) { return a > b; }
template <typename T>
bool gt(T a, T b) { return a > b; }
/// Segédsablon valós számok összehasonlításához
/// Nem bombabiztos, de nekünk most jó lesz
......@@ -424,6 +475,17 @@ bool almostEQ(T a, T b) {
return (aa - ba) < aa * eps;
}
/// Segédsablon ostream átirányításához
/// A destruktor visszaállít
class ostreamRedir {
std::ostream& src;
std::streambuf *const save;
public:
ostreamRedir(std::ostream& src, std::ostream& dst)
: src(src), save(src.rdbuf(dst.rdbuf())) {}
~ostreamRedir() { src.rdbuf(save); }
};
} // namespace gtest_lite
#endif // GTEST_LITE_H
......@@ -5,8 +5,9 @@ Keszitette: Peregi Tamas, BME IIT, 2011
Kanari: Szeberenyi Imre, 2013.
VS 2012: Szeberényi Imre, 2015.,
mem_dump: 2016.
meset felszabaditaskor: 2018.
memset felszabaditaskor: 2018.
typo: 2019.
poi_check: 2021.
*********************************/
/*definialni kell, ha nem paracssorbol allitjuk be (-DMEMTRACE) */
......@@ -178,7 +179,6 @@ START_NAMESPACE
dying = TRUE;
exit(120);
}
static void initialize();
END_NAMESPACE
......@@ -188,6 +188,7 @@ END_NAMESPACE
#ifdef MEMTRACE_TO_MEMORY
START_NAMESPACE
typedef struct _registry_item {
void * p; /* mem pointer*/
size_t size; /* size*/
......@@ -197,6 +198,12 @@ START_NAMESPACE
static registry_item registry; /*sentinel*/
static registry_item *find_registry_item(void * p) {
registry_item *n = &registry;
for(; n->next && n->next->p != p ; n=n->next);
return n;
}
static void print_registry_item(registry_item * p) {
if (p) {
print_registry_item(p->next);
......@@ -225,6 +232,13 @@ START_NAMESPACE
}
return 0;
}
/* Ellenorzi, hogy a pointer regisztralt-e. Ha nem, akkor 0-val tér vissza */
int poi_check(void *pu) {
if (pu == NULL) return 1;
initialize();
return find_registry_item(P(pu))->next != NULL;
}
END_NAMESPACE
#endif/*MEMTRACE_TO_MEMORY*/
......@@ -271,14 +285,6 @@ START_NAMESPACE
return TRUE;
}
#ifdef MEMTRACE_TO_MEMORY
static registry_item *find_registry_item(void * p) {
registry_item *n = &registry;
for(; n->next && n->next->p != p ; n=n->next);
return n;
}
#endif
static void unregister_memory(void * p, call_t call) {
initialize();
#ifdef MEMTRACE_TO_FILE
......@@ -487,7 +493,15 @@ void operator delete(void * p) THROW_NOTHING {
void operator delete[](void * p) THROW_NOTHING {
memtrace::traced_delete(p,FDELETEARR);
}
#if __cplusplus >= 201402L
void operator delete(void * p, size_t) THROW_NOTHING {
memtrace::traced_delete(p,FDELETE);
}
void operator delete[](void * p, size_t) THROW_NOTHING {
memtrace::traced_delete(p,FDELETEARR);
}
#endif
/* Visual C++ 2012 miatt kell, mert háklis, hogy nincs megfelelő delete, bár senki sem használja */
void operator delete(void * p, int, const char *) THROW_NOTHING {
......
......@@ -5,7 +5,7 @@ Keszitette: Peregi Tamas, BME IIT, 2011
Kanari: Szeberenyi Imre, 2013.,
VS 2012: Szeberényi Imre, 2015.,
mem_dump: 2016.
inclue-ok: 2017., 2018. 2019.
inclue-ok: 2017., 2018., 2019., 2021.
*********************************/
#ifndef MEMTRACE_H
......@@ -102,6 +102,7 @@ END_NAMESPACE
#if defined(MEMTRACE_TO_MEMORY)
START_NAMESPACE
int mem_check(void);
int poi_check(void*);
END_NAMESPACE
#endif
......@@ -159,6 +160,11 @@ END_NAMESPACE
#include <typeinfo>
#include <ostream>
#include <stdexcept>
#include <ctime>
#if __cplusplus >= 201103L
#include <iterator>
#include <regex>
#endif
#endif
#ifdef MEMTRACE_CPP
namespace std {
......@@ -186,7 +192,6 @@ START_NAMESPACE
void mem_dump(void const *mem, size_t size, FILE* fp = stdout);
END_NAMESPACE
#endif/*MEMTRACE_C*/
......@@ -206,6 +211,12 @@ void * operator new[](size_t size) THROW_BADALLOC;
void operator delete(void * p) THROW_NOTHING;
void operator delete[](void * p) THROW_NOTHING;
#if __cplusplus >= 201402L
// sized delete miatt: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3536.html
void operator delete(void * p, size_t) THROW_NOTHING;
void operator delete[](void * p, size_t) THROW_NOTHING;
#endif
/* Visual C++ 2012 miatt kell, mert háklis, hogy nincs megfelelő delete, bár senki sem használja */
void operator delete(void *p, int, const char *) THROW_NOTHING;
void operator delete[](void *p, int, const char *) THROW_NOTHING;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment