Skip to content

Commit 8e13a10

Browse files
Merge pull request #577 from IENT/feature/addGoogleTestAsSubmodule
Added google test and moved tests.
2 parents 6aadaea + 1fc6743 commit 8e13a10

File tree

96 files changed

+4126
-3079
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+4126
-3079
lines changed

.github/workflows/Build.yml

+18-10
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ jobs:
2020
QMAKE_COMMAND: qmake6
2121
steps:
2222
- uses: actions/checkout@v4
23+
with:
24+
submodules: true
2325
- run: git fetch --prune --unshallow
2426
- name: Install Linux packages
2527
run: |
@@ -32,7 +34,8 @@ jobs:
3234
cd build
3335
${{matrix.QMAKE_COMMAND}} CONFIG+=UNITTESTS ..
3436
make -j$(nproc)
35-
make check
37+
- name: Run Unittests
38+
run: $GITHUB_WORKSPACE/build/YUViewUnitTest/YUViewUnitTest
3639
build-mac-native:
3740
runs-on: ${{ matrix.os }}
3841
strategy:
@@ -42,6 +45,8 @@ jobs:
4245
- os: macos-14
4346
steps:
4447
- uses: actions/checkout@v4
48+
with:
49+
submodules: true
4550
- run: git fetch --prune --unshallow
4651
- name: Install packages
4752
run: |
@@ -53,7 +58,8 @@ jobs:
5358
cd build
5459
qmake6 CONFIG+=UNITTESTS ..
5560
make -j $(sysctl -n hw.logicalcpu)
56-
make check
61+
- name: Run Unittests
62+
run: $GITHUB_WORKSPACE/build/YUViewUnitTest/YUViewUnitTest
5763
build-unix:
5864
runs-on: ${{ matrix.os }}
5965
strategy:
@@ -79,6 +85,8 @@ jobs:
7985
CPU_COUNT_COMMAND: sysctl -n hw.logicalcpu
8086
steps:
8187
- uses: actions/checkout@v4
88+
with:
89+
submodules: true
8290
- run: git fetch --prune --unshallow
8391
- name: Install Qt base
8492
run: |
@@ -104,15 +112,16 @@ jobs:
104112
curl -L https://github.com/ChristianFeldmann/libde265/releases/download/v1.1/${{matrix.LIBDE265_REMOTE}} -o ${{matrix.LIBDE265_LOCAL}}
105113
curl -L https://raw.githubusercontent.com/ChristianFeldmann/libde265/master/COPYING -o libde265License.txt
106114
shell: bash
107-
- name: Build Linux/Mac
115+
- name: Build
108116
run: |
109117
cd $GITHUB_WORKSPACE
110118
export PATH=$GITHUB_WORKSPACE/../../YUViewQt/YUViewQt/Qt/bin:$PATH
111119
mkdir build
112120
cd build
113121
qmake CONFIG+=UNITTESTS ..
114122
make -j $(${{matrix.CPU_COUNT_COMMAND}})
115-
make check
123+
- name: Run Unittests
124+
run: $GITHUB_WORKSPACE/build/YUViewUnitTest/YUViewUnitTest
116125
- name: Build App (Mac)
117126
run: |
118127
macdeployqt build/YUViewApp/YUView.app -always-overwrite -verbose=2
@@ -122,7 +131,7 @@ jobs:
122131
zip -r ${{matrix.ARTIFACT_NAME}} YUView.app/
123132
mkdir $GITHUB_WORKSPACE/artifacts
124133
cp ${{matrix.ARTIFACT_NAME}} $GITHUB_WORKSPACE/artifacts/
125-
if: matrix.os == 'macos-11' || matrix.os == 'macos-12'
134+
if: matrix.os == 'macos-12' || matrix.os == 'macos-14'
126135
- name: Build Appimage (Linux)
127136
run: |
128137
cd build
@@ -157,6 +166,8 @@ jobs:
157166
QT_FILE: qtBase_6.7.2_win2019.zip
158167
steps:
159168
- uses: actions/checkout@v4
169+
with:
170+
submodules: true
160171
- uses: ilammy/msvc-dev-cmd@v1
161172
- run: git fetch --prune --unshallow
162173
- name: Install Qt base
@@ -196,11 +207,8 @@ jobs:
196207
d:\a\YUViewQt\YUViewQt\Qt\bin\qmake CONFIG+=UNITTESTS ..
197208
echo "Executing jom:"
198209
jom
199-
- name: Run tests
200-
run: |
201-
cd build
202-
nmake check
203-
cd ..
210+
- name: Run Unittests
211+
run: D:\a\YUView\YUView\build\YUViewUnitTest\YUViewUnitTest
204212
- name: WindeployQT
205213
run: |
206214
mkdir deploy

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "submodules/googletest"]
2+
path = submodules/googletest
3+
url = [email protected]:google/googletest.git

YUView.pro

+4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ YUViewLib.subdir = YUViewLib
77
YUViewApp.depends = YUViewLib
88

99
UNITTESTS {
10+
SUBDIRS += Googletest
11+
Googletest.subdir = submodules/googletest-qmake
12+
1013
SUBDIRS += YUViewUnitTest
1114
YUViewUnitTest.subdir = YUViewUnitTest
15+
YUViewUnitTest.depends = Googletest
1216
YUViewUnitTest.depends = YUViewLib
1317
}

YUViewLib/src/common/EnumMapper.h

+125-94
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* This file is part of YUView - The YUV player with advanced analytics toolset
22
* <https://github.com/IENT/YUView>
3-
* Copyright (C) 2015 Institut f�r Nachrichtentechnik, RWTH Aachen University, GERMANY
3+
* Copyright (C) 2015 Institut für Nachrichtentechnik, RWTH Aachen University, GERMANY
44
*
55
* This program is free software; you can redistribute it and/or modify
66
* it under the terms of the GNU General Public License as published by
@@ -32,135 +32,166 @@
3232

3333
#pragma once
3434

35-
#include <common/Functions.h>
36-
37-
#include <map>
35+
#include <algorithm>
36+
#include <array>
37+
#include <iterator>
3838
#include <optional>
39-
#include <stdexcept>
40-
#include <string>
41-
#include <vector>
39+
#include <string_view>
4240

43-
/* This class implement mapping of "enum class" values to and from names (string).
44-
*/
45-
template <typename T> class EnumMapper
46-
{
47-
public:
48-
enum class StringType
49-
{
50-
Name,
51-
Text,
52-
NameOrIndex
53-
};
54-
struct Entry
55-
{
56-
Entry(T value, std::string name) : value(value), name(name) {}
57-
Entry(T value, std::string name, std::string text) : value(value), name(name), text(text) {}
58-
T value;
59-
std::string name;
60-
std::string text;
61-
};
41+
#include "Functions.h"
6242

63-
using EntryVector = std::vector<Entry>;
43+
using namespace std::string_view_literals;
6444

65-
EnumMapper() = default;
66-
EnumMapper(const EntryVector &entryVector) : entryVector(entryVector){};
45+
template <class ValueType, std::size_t N> struct EnumMapper
46+
{
47+
public:
48+
using ValueNamePair = std::pair<ValueType, std::string_view>;
49+
using ItemArray = std::array<ValueType, N>;
50+
using ItemIterator = typename ItemArray::const_iterator;
51+
using NameArray = std::array<std::string_view, N>;
52+
using NameIterator = typename NameArray::const_iterator;
6753

68-
std::optional<T> getValue(std::string name, StringType stringType = StringType::Name) const
54+
struct Iterator
6955
{
70-
if (stringType == StringType::NameOrIndex)
71-
if (auto index = functions::toUnsigned(name))
72-
return this->at(*index);
56+
using iterator_category = std::forward_iterator_tag;
57+
using difference_type = int;
58+
using value_type = ValueNamePair;
59+
using pointer = ValueNamePair *;
60+
using reference = ValueNamePair &;
7361

74-
for (const auto &entry : this->entryVector)
62+
Iterator(const ItemIterator itItem, const NameIterator itName) : itItem(itItem), itName(itName)
7563
{
76-
if ((stringType == StringType::Name && entry.name == name) ||
77-
(stringType == StringType::NameOrIndex && entry.text == name) ||
78-
(stringType == StringType::Text && entry.text == name))
79-
return entry.value;
64+
this->valueNamePair.first = *itItem;
65+
this->valueNamePair.second = *itName;
8066
}
81-
return {};
82-
}
8367

84-
std::optional<T> getValueCaseInsensitive(std::string name,
85-
StringType stringType = StringType::Name) const
86-
{
87-
if (stringType == StringType::NameOrIndex)
88-
if (auto index = functions::toUnsigned(name))
89-
return this->at(*index);
68+
ValueNamePair const &operator*() const { return this->valueNamePair; }
69+
ValueNamePair const *operator->() const { return &this->valueNamePair; }
9070

91-
name = functions::toLower(name);
92-
for (const auto &entry : this->entryVector)
71+
Iterator &operator++()
9372
{
94-
if ((stringType == StringType::Name && functions::toLower(entry.name) == name) ||
95-
(stringType == StringType::NameOrIndex && functions::toLower(entry.text) == name) ||
96-
(stringType == StringType::Text && functions::toLower(entry.text) == name))
97-
return entry.value;
73+
++this->itItem;
74+
++this->itName;
75+
this->valueNamePair.first = *this->itItem;
76+
this->valueNamePair.second = *this->itName;
77+
return *this;
9878
}
99-
return {};
100-
}
10179

102-
std::string getName(T value) const
80+
friend bool operator==(const Iterator &a, const Iterator &b)
81+
{
82+
return a.itItem == b.itItem && a.itName == b.itName;
83+
};
84+
friend bool operator!=(const Iterator &a, const Iterator &b)
85+
{
86+
return a.itItem != b.itItem || a.itName != b.itName;
87+
};
88+
89+
private:
90+
ItemIterator itItem;
91+
NameIterator itName;
92+
ValueNamePair valueNamePair{};
93+
};
94+
95+
Iterator begin() const { return Iterator(this->items.begin(), this->names.begin()); }
96+
Iterator end() const { return Iterator(this->items.end(), this->names.end()); }
97+
98+
template <typename... Args> constexpr EnumMapper(Args... args)
10399
{
104-
for (const auto &entry : this->entryVector)
105-
if (entry.value == value)
106-
return entry.name;
107-
throw std::logic_error(
108-
"The given type T was not registered in the mapper. All possible enums must be mapped.");
100+
static_assert(sizeof...(Args) == N);
101+
this->addElementsRecursively(0, args...);
109102
}
110103

111-
std::string getText(T value) const
104+
constexpr std::size_t size() const { return N; }
105+
106+
constexpr std::string_view getName(const ValueType value) const
112107
{
113-
for (const auto &entry : this->entryVector)
114-
if (entry.value == value)
115-
return entry.text;
116-
throw std::logic_error(
117-
"The given type T was not registered in the mapper. All possible enums must be mapped.");
108+
const auto it = std::find(this->items.begin(), this->items.end(), value);
109+
if (it == this->items.end())
110+
throw std::logic_error(
111+
"The given type T was not registered in the mapper. All possible enums must be mapped.");
112+
const auto index = std::distance(this->items.begin(), it);
113+
return this->names.at(index);
118114
}
119115

120-
size_t indexOf(T value) const
116+
constexpr std::optional<ValueType> getValue(const std::string_view name) const
121117
{
122-
for (size_t i = 0; i < this->entryVector.size(); i++)
123-
if (this->entryVector.at(i).value == value)
124-
return i;
125-
throw std::logic_error(
126-
"The given type T was not registered in the mapper. All possible enums must be mapped.");
118+
const auto it =
119+
std::find_if(this->begin(),
120+
this->end(),
121+
[&name](const ValueNamePair &pair) { return pair.second == name; });
122+
if (it == this->end())
123+
return {};
124+
125+
return it->first;
127126
}
128127

129-
std::optional<T> at(size_t index) const
128+
constexpr std::optional<ValueType> getValueCaseInsensitive(const std::string_view name) const
130129
{
131-
if (index >= this->entryVector.size())
130+
const auto compareToNameLowercase = [&name](const std::string_view str)
131+
{
132+
if (name.length() != str.length())
133+
return false;
134+
for (std::size_t i = 0; i < name.length(); ++i)
135+
{
136+
if (std::tolower(name.at(i)) != std::tolower(str.at(i)))
137+
return false;
138+
}
139+
return true;
140+
};
141+
142+
const auto it = std::find_if(this->names.begin(), this->names.end(), compareToNameLowercase);
143+
if (it == this->names.end())
132144
return {};
133-
return this->entryVector.at(index).value;
145+
146+
const auto index = std::distance(this->names.begin(), it);
147+
return this->items.at(index);
134148
}
135149

136-
std::vector<T> getEnums() const
150+
std::optional<ValueType> getValueFromNameOrIndex(const std::string_view nameOrIndex) const
137151
{
138-
std::vector<T> m;
139-
for (const auto &entry : this->entryVector)
140-
m.push_back(entry.value);
141-
return m;
152+
if (auto index = functions::toUnsigned(nameOrIndex))
153+
if (*index < N)
154+
return this->items.at(*index);
155+
156+
return this->getValue(nameOrIndex);
142157
}
143158

144-
std::vector<std::string> getNames() const
159+
constexpr size_t indexOf(const ValueType value) const
145160
{
146-
std::vector<std::string> l;
147-
for (const auto &entry : this->entryVector)
148-
l.push_back(entry.name);
149-
return l;
161+
const auto it = std::find(this->items.begin(), this->items.end(), value);
162+
if (it == this->items.end())
163+
throw std::logic_error(
164+
"The given type T was not registered in the mapper. All possible enums must be mapped.");
165+
166+
const auto index = std::distance(this->items.begin(), it);
167+
return index;
150168
}
151169

152-
std::vector<std::string> getTextEntries() const
170+
constexpr std::optional<ValueType> at(const size_t index) const
153171
{
154-
std::vector<std::string> l;
155-
for (const auto &entry : this->entryVector)
156-
l.push_back(entry.text);
157-
return l;
172+
if (index >= N)
173+
return {};
174+
return this->items.at(index);
158175
}
159176

160-
size_t size() const { return this->entryVector.size(); }
161-
162-
const EntryVector &entries() const { return this->entryVector; }
177+
constexpr const ItemArray &getValues() const { return this->items; }
178+
constexpr const NameArray &getNames() const { return this->names; }
163179

164180
private:
165-
EntryVector entryVector;
181+
constexpr void addElementsRecursively(const std::size_t) {};
182+
183+
template <typename ArgumentType, typename... Args>
184+
constexpr void addElementsRecursively(const std::size_t index, ArgumentType first, Args... args)
185+
{
186+
static_assert(std::is_same<ValueNamePair, ArgumentType>());
187+
188+
const auto [value, name] = first;
189+
this->items[index] = value;
190+
this->names[index] = name;
191+
192+
addElementsRecursively(index + 1, args...);
193+
}
194+
195+
ItemArray items{};
196+
NameArray names{};
166197
};

0 commit comments

Comments
 (0)