Skip to content

Commit

Permalink
Add Catch unittest framework and some tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
john-preston committed Sep 3, 2017
1 parent 48e2a54 commit 5faca8d
Show file tree
Hide file tree
Showing 17 changed files with 453 additions and 39 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
/Telegram/Resources/art/sprite_125x.png
/Telegram/Resources/art/sprite_150x.png
/Telegram/Debug/
/Telegram/Release/
/Telegram/tests/
/Telegram/gyp/tests/*.test
/Telegram/out/
/Telegram/*.user
*.vcxproj*
*.sln
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@
[submodule "Telegram/ThirdParty/GSL"]
path = Telegram/ThirdParty/GSL
url = https://github.com/Microsoft/GSL.git
[submodule "Telegram/ThirdParty/Catch"]
path = Telegram/ThirdParty/Catch
url = https://github.com/philsquared/Catch
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ The source code is published under GPLv3 with OpenSSL exception, the license is
* Mapbox Variant ([BSD License](https://github.com/mapbox/variant/blob/master/LICENSE))
* Open Sans font ([Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html))
* Emoji alpha codes ([MIT License](https://github.com/emojione/emojione/blob/master/extras/alpha-codes/LICENSE.md))
* Catch test framework ([Boost License](https://github.com/philsquared/Catch/blob/master/LICENSE.txt))

## Build instructions

Expand Down
42 changes: 12 additions & 30 deletions Telegram/Patches/gyp.diff
Original file line number Diff line number Diff line change
@@ -1,33 +1,5 @@
diff --git a/pylib/gyp/generator/cmake.py b/pylib/gyp/generator/cmake.py
index a2b9629..68d7020 100644
--- a/pylib/gyp/generator/cmake.py
+++ b/pylib/gyp/generator/cmake.py
@@ -1070,6 +1070,23 @@ def WriteTarget(namer, qualified_target, target_dicts, build_dir, config_to_use,

output.write(')\n')

+ # Precompile header
+ precompiled_header = config.get('cmake_precompiled_header', '')
+ if precompiled_header:
+ precompiled_header_script = config.get('cmake_precompiled_header_script', '')
+ if not precompiled_header_script:
+ print ('ERROR: cmake_precompiled_header requires cmake_precompiled_header_script')
+ cmake_precompiled_header = NormjoinPath(path_from_cmakelists_to_gyp, precompiled_header)
+ cmake_precompiled_header_script = NormjoinPathForceCMakeSource(path_from_cmakelists_to_gyp, precompiled_header_script)
+ output.write('include(')
+ output.write(cmake_precompiled_header_script)
+ output.write(')\n')
+ output.write('add_precompiled_header(')
+ output.write(cmake_target_name)
+ output.write(' ')
+ output.write(cmake_precompiled_header)
+ output.write(')\n')
+
UnsetVariable(output, 'TOOLSET')
UnsetVariable(output, 'TARGET')

diff --git a/pylib/gyp/generator/xcode.py b/pylib/gyp/generator/xcode.py
index db99d6a..f8398cc 100644
index 0e3fb93..4c824ec 100644
--- a/pylib/gyp/generator/xcode.py
+++ b/pylib/gyp/generator/xcode.py
@@ -72,6 +72,10 @@ generator_additional_non_configuration_keys = [
Expand All @@ -41,7 +13,7 @@ index db99d6a..f8398cc 100644
'mac_bundle',
'mac_bundle_resources',
'mac_framework_headers',
@@ -772,6 +776,26 @@ def GenerateOutput(target_list, target_dicts, data, params):
@@ -761,6 +765,26 @@ def GenerateOutput(target_list, target_dicts, data, params):
xcode_targets[qualified_target] = xct
xcode_target_to_target_dict[xct] = spec

Expand All @@ -68,3 +40,13 @@ index db99d6a..f8398cc 100644
spec_actions = spec.get('actions', [])
spec_rules = spec.get('rules', [])

@@ -1130,7 +1154,8 @@ exit 1
groups = [x for x in groups if not x.endswith('_excluded')]
for group in groups:
for item in rule.get(group, []):
- pbxp.AddOrGetFileInRootGroup(item)
+ concrete_item = ExpandXcodeVariables(item, rule_input_dict)
+ pbxp.AddOrGetFileInRootGroup(concrete_item)

# Add "sources".
for source in spec.get('sources', []):
1 change: 1 addition & 0 deletions Telegram/SourceFiles/base/flat_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once

#include <deque>
#include "base/optional.h"

namespace base {
Expand Down
51 changes: 51 additions & 0 deletions Telegram/SourceFiles/base/flat_map_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It 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.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#include "catch.hpp"

#include "base/flat_map.h"
#include <string>

using namespace std;

TEST_CASE("flat_maps should keep items sorted by key", "[flat_map]") {
base::flat_map<int, string> v;
v.emplace(0, "a");
v.emplace(5, "b");
v.emplace(4, "d");
v.emplace(2, "e");

auto checkSorted = [&] {
auto prev = v.begin();
REQUIRE(prev != v.end());
for (auto i = prev + 1; i != v.end(); prev = i, ++i) {
REQUIRE(prev->first < i->first);
}
};
REQUIRE(v.size() == 4);
checkSorted();

SECTION("adding item puts it in the right position") {
v.emplace(3, "c");
REQUIRE(v.size() == 5);
REQUIRE(v.find(3) != v.end());
checkSorted();
}
}
2 changes: 2 additions & 0 deletions Telegram/SourceFiles/base/flat_set.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#pragma once

#include <deque>

namespace base {

template <typename Type>
Expand Down
48 changes: 48 additions & 0 deletions Telegram/SourceFiles/base/flat_set_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It 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.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#include "catch.hpp"

#include "base/flat_set.h"

TEST_CASE("flat_sets should keep items sorted", "[flat_set]") {
base::flat_set<int> v;
v.insert(0);
v.insert(5);
v.insert(4);
v.insert(2);

auto checkSorted = [&] {
auto prev = v.begin();
REQUIRE(prev != v.end());
for (auto i = prev + 1; i != v.end(); prev = i, ++i) {
REQUIRE(*prev < *i);
}
};
REQUIRE(v.size() == 4);
checkSorted();

SECTION("adding item puts it in the right position") {
v.insert(3);
REQUIRE(v.size() == 5);
REQUIRE(v.find(3) != v.end());
checkSorted();
}
}
97 changes: 97 additions & 0 deletions Telegram/SourceFiles/base/tests_main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
This file is part of Telegram Desktop,
the official desktop version of Telegram messaging app, see https://telegram.org
Telegram Desktop is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
It 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.
In addition, as a special exception, the copyright holders give permission
to link the code of portions of this program with the OpenSSL library.
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
*/
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"
#include "reporters/catch_reporter_compact.hpp"
#include <QFile>

namespace Catch {

struct MinimalReporter : CompactReporter {
MinimalReporter( ReporterConfig const& _config )
: CompactReporter( _config )
{}

virtual void testRunEnded( TestRunStats const& _testRunStats ) {
printTotals( _testRunStats.totals );
}

private:
// Colour, message variants:
// - white: No tests ran.
// - red: Failed [both/all] N test cases, failed [both/all] M assertions.
// - white: Passed [both/all] N test cases (no assertions).
// - red: Failed N tests cases, failed M assertions.
// - green: Passed [both/all] N tests cases with M assertions.

std::string bothOrAll( std::size_t count ) const {
return count == 1 ? std::string() : count == 2 ? "both " : "all " ;
}

void printTotals( const Totals& totals ) const {
if( totals.testCases.total() == 0 ) {
}
else if( totals.testCases.failed == totals.testCases.total() ) {
Colour colour( Colour::ResultError );
const std::string qualify_assertions_failed =
totals.assertions.failed == totals.assertions.total() ?
bothOrAll( totals.assertions.failed ) : std::string();
stream <<
"Failed " << bothOrAll( totals.testCases.failed )
<< pluralise( totals.testCases.failed, "test case" ) << ", "
"failed " << qualify_assertions_failed <<
pluralise( totals.assertions.failed, "assertion" ) << '.';
}
else if( totals.assertions.total() == 0 ) {
stream <<
"Passed " << bothOrAll( totals.testCases.total() )
<< pluralise( totals.testCases.total(), "test case" )
<< " (no assertions).";
}
else if( totals.assertions.failed ) {
Colour colour( Colour::ResultError );
stream <<
"Failed " << pluralise( totals.testCases.failed, "test case" ) << ", "
"failed " << pluralise( totals.assertions.failed, "assertion" ) << '.';
}
else {
}
}
};

INTERNAL_CATCH_REGISTER_REPORTER( "minimal", MinimalReporter )

} // end namespace Catch

int main(int argc, const char *argv[]) {
const char *catch_argv[] = { argv[0], "-r", "minimal" };
constexpr auto catch_argc = sizeof(catch_argv) / sizeof(catch_argv[0]);
auto result = Catch::Session().run(catch_argc, catch_argv);
if (result == 0) {
for (auto i = 0; i != argc; ++i) {
if (argv[i] == QString("--touch") && i + 1 != argc) {
QFile(QFile::decodeName(argv[++i])).open(QIODevice::WriteOnly);
}
}
}
return (result < 0xff ? result : 0xff);
}

1 change: 1 addition & 0 deletions Telegram/ThirdParty/Catch
Submodule Catch added at 5ca44b
33 changes: 32 additions & 1 deletion Telegram/create.bat
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ set "FullScriptPath=%~dp0"
set "FullExecPath=%cd%"

set "Command=%1"
if "%Command%" == "header" (
if "%Command%" == "test" (
call :write_test %2
exit /b %errorlevel%
) else if "%Command%" == "header" (
call :write_header %2
exit /b %errorlevel%
) else if "%Command%" == "source" (
Expand Down Expand Up @@ -87,6 +90,34 @@ exit /b %errorlevel%
exit /b
)

:write_test
(
set "CommandPath=%1"
set "CommandPathUnix=!CommandPath:\=/!"
set "CommandPathWin=!CommandPath:/=\!"

if "!CommandPathUnix!" == "" (
echo Provide source path.
exit /b 1
) else if exist "SourceFiles\!CommandPathWin!.cpp" (
echo This source already exists.
exit /b 1
)
echo Generating test !CommandPathUnix!.cpp..
mkdir "SourceFiles\!CommandPathWin!.cpp"
rmdir "SourceFiles\!CommandPathWin!.cpp"

call :write_comment !CommandPathWin!.cpp
set "quote="""
set "quote=!quote:~0,1!"
set "source1=#include !quote!catch.hpp!quote!"
(
echo !source1!
echo.
)>> "SourceFiles\!CommandPathWin!.cpp"
exit /b
)

:write_comment
(
set "Path=%1"
Expand Down
1 change: 1 addition & 0 deletions Telegram/gyp/Telegram.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
'codegen.gyp:codegen_lang',
'codegen.gyp:codegen_numbers',
'codegen.gyp:codegen_style',
'tests/tests.gyp:tests',
'utils.gyp:Updater',
'../ThirdParty/libtgvoip/libtgvoip.gyp:libtgvoip',
],
Expand Down
16 changes: 8 additions & 8 deletions Telegram/gyp/qt.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -225,14 +225,14 @@
'<(linux_lib_ssl)',
'<(linux_lib_crypto)',
'<!@(python -c "for s in \'<(linux_lib_icu)\'.split(\' \'): print(s)")',
'xcb',
'X11',
'X11-xcb',
'dbus-1',
'dl',
'gthread-2.0',
'glib-2.0',
'pthread',
'-lxcb',
'-lX11',
'-lX11-xcb',
'-ldbus-1',
'-ldl',
'-lgthread-2.0',
'-lglib-2.0',
'-lpthread',
],
'include_dirs': [
'<(qt_loc)/mkspecs/linux-g++',
Expand Down
Loading

0 comments on commit 5faca8d

Please sign in to comment.