diff --git a/testing/search_view/data/autocompletion_tests.cpp b/testing/search_view/data/autocompletion_tests.cpp new file mode 100644 index 00000000..b501f565 --- /dev/null +++ b/testing/search_view/data/autocompletion_tests.cpp @@ -0,0 +1,124 @@ + +namespace AUTOCOMPLETION_TESTS +{ + +// TEST: Find Shortcut +// START ---------------------------------------------------------------------- + +// ACTION: Use Find Shortcut: Edit -> Find Symbol +// RESULTS: +// - search field is focused +// - content is selected +// - when typing content is cleared + +// END ------------------------------------------------------------------------ + + + +// TEST: Find Symbol +// START ---------------------------------------------------------------------- + +// ACTION: Search symbol 'main' and press enter +// RESULT: main is activated + +// END ------------------------------------------------------------------------ + + + +// TEST: Find Symbol with button +// START ---------------------------------------------------------------------- + +// ACTION: Search symbol 'main' and click find button +// RESULT: main is activated + +// END ------------------------------------------------------------------------ + + + +// TEST: Choose symbol from list - keyboard +// START ---------------------------------------------------------------------- + +// ACTION: Search symbol 'main' and use down arrow to select second symbol, press enter +// RESULT: 'main.cpp' is activated + +// END ------------------------------------------------------------------------ + + + +// TEST: Choose symbol from list - mouse +// START ---------------------------------------------------------------------- + +// ACTION: Search symbol 'main' and click in list on 3rd symbol +// RESULT: 'HumanPlayer::Input' is activated + +// END ------------------------------------------------------------------------ + + + +// TEST: Fuzzy matching +// START ---------------------------------------------------------------------- + +// ACTION: Search symbol 'ttt' +// RESULT: top result is class 'TicTacToe' + +// END ------------------------------------------------------------------------ + + + +// TEST: Tab completion to find symbols +// START ---------------------------------------------------------------------- + +// ACTION: Search symbol 'ttt' and press tab +// RESULTS: +// - content is extended to 'TicTacToe::' +// - all children of 'TicTacToe' are shown + +// END ------------------------------------------------------------------------ + + + +// TEST: Namespace as subtext +// START ---------------------------------------------------------------------- + +// ACTION: Search symbol 'num' +// RESULT: top result is 'io::numberIn', namespace 'io' in subtext + +// END ------------------------------------------------------------------------ + + + +// TEST: Directory as subtext +// START ---------------------------------------------------------------------- + +// ACTION: Search symbol 'ttt.' +// RESULT: top result is 'tictactoe.h', directory in subtext + +// END ------------------------------------------------------------------------ + + + +// TEST: No template specializations in autocompletions +// START ---------------------------------------------------------------------- + +// ACTION 1: Search symbol 'sum' +// RESULT 1: List shows 'sum' and 'sum, but not 'sum' + +// ACTION 2: Activate 'sum' +// RESULT 2: Graph shows 'sum' and 'sum' as well + +// END ------------------------------------------------------------------------ + + + +// TEST: Undefined templates shortened with '<..>' +// START ---------------------------------------------------------------------- + +// ACTION 1: Search symbol 'diff' +// RESULT 1: List shows 'diff<..>' + +// ACTION 2: Activate 'diff<..>' +// RESULT 2: Graph shows 'diff' and 'diff' + +// END ------------------------------------------------------------------------ + +} diff --git a/testing/search_view/data/files/artificial_player.cpp b/testing/search_view/data/files/artificial_player.cpp new file mode 100644 index 00000000..a6457f73 --- /dev/null +++ b/testing/search_view/data/files/artificial_player.cpp @@ -0,0 +1,67 @@ +#include "artificial_player.h" + +ArtificialPlayer::ArtificialPlayer( Field::Token token, const char* name ) + : Player( token, name ) { +} + +ArtificialPlayer::~ArtificialPlayer() { +} + +Field::Move ArtificialPlayer::Turn( const Field& field ) const { + Field fakeField = field.Clone(); + Node node = MinMax( fakeField, token_ ); + return node.move; +} + +ArtificialPlayer::Node ArtificialPlayer::MinMax( Field& field, Field::Token token ) const { + Node node; + node.value = -10000; + + Field::Move move; + int sameMove; + + for ( int i = 0; i < 3; i++ ) { + move.row = i; + + for ( int j = 0; j < 3; j++ ) { + move.col = j; + + if ( !field.IsEmpty( move ) ) { + continue; + } + + field.MakeMove( move, token ); + + int turnValue = Evaluate( field, token ); + if ( !turnValue && !field.IsFull() ) { + turnValue = -MinMax( field, Field::Opponent( token ) ).value; + } + + field.ClearMove( move ); + + if ( turnValue > node.value ) { + node.move = move; + node.value = turnValue; + sameMove = 1; + } else if ( turnValue == node.value ) { + sameMove++; + if ( 1 % sameMove == 0 ) { + node.move = move; + } + } + } + } + + return node; +} + +int ArtificialPlayer::Evaluate( const Field& field, Field::Token token ) const { + if ( field.SameInRow( token, 3 ) ) { + return 2; + } else if ( field.SameInRow( Field::Opponent( token ), 2 ) ) { + return -1; + } else if ( field.SameInRow( token, 2 ) > 1 ) { + return 1; + } + return 0; +} diff --git a/testing/search_view/data/files/artificial_player.h b/testing/search_view/data/files/artificial_player.h new file mode 100644 index 00000000..8b564edd --- /dev/null +++ b/testing/search_view/data/files/artificial_player.h @@ -0,0 +1,24 @@ +#ifndef _ARTIFICIAL_PLAYER_ +#define _ARTIFICIAL_PLAYER_ + +#include "player.h" + +class ArtificialPlayer : public Player { +public: + ArtificialPlayer( Field::Token token, const char* name ); + virtual ~ArtificialPlayer(); + + virtual Field::Move Turn( const Field& field ) const; + +private: + struct Node { + Field::Move move; + int value; + }; + + Node MinMax( Field& field, Field::Token token ) const; + + int Evaluate( const Field& field, Field::Token token ) const; +}; + +#endif // _ARTIFICIAL_PLAYER_ diff --git a/testing/search_view/data/files/field.cpp b/testing/search_view/data/files/field.cpp new file mode 100644 index 00000000..d87128a8 --- /dev/null +++ b/testing/search_view/data/files/field.cpp @@ -0,0 +1,126 @@ +#include "field.h" + +#include "io.h" + +Field::Token Field::Opponent( Token token ) { + if ( token == PlayerA ) { + return PlayerB; + } else if (token == PlayerB){ + return PlayerA; + } else { + return None; + } +} + +Field::Field() + : left_( 9 ) { + grid_ = new Token* [3]; + for ( int i = 0; i < 3 ; i++ ) { + grid_[i] = new Token[3]; + } +} + +Field::~Field() { + for ( int i = 0; i < 3; i++ ) { + delete [] grid_[i]; + } + delete [] grid_; +} + +Field Field::Clone() const { + Field field; + for ( int i = 0; i < 3; i++ ) { + for ( int j = 0; j < 3; j++ ) { + field.grid_[i][j] = grid_[i][j]; + } + } + field.left_ = left_; + return field; +} + +void Field::Clear() { + for ( int i = 0; i < 3; i++ ) { + for ( int j = 0; j < 3; j++ ) { + grid_[i][j] = None; + } + } + left_ = 9; +} + +void Field::Show() const { + io::stringOut(" 1 2 3\n"); + for ( int row = 0; row < 3; row++ ) { + io::numberOut(row + 1); + io::stringOut(" "); + + for ( int col = 0; col < 3; col++ ) { + if ( grid_[row][col] == PlayerA ) { + io::stringOut(" X "); + } else if ( grid_[row][col] == PlayerB ) { + io::stringOut(" O "); + } else { + io::stringOut(" "); + } + + if ( col < 2 ) { + io::stringOut("|"); + } + } + + if ( row < 2 ) { + io::stringOut("\n -----------\n"); + } + } + io::stringOut("\n\n"); +} + +int Field::SameInRow( Token token, int amount ) const { + int sum = amount * token; + int count = 0; + + for ( int i = 0; i < 3; i++ ) { + if ( grid_[i][0] + grid_[i][1] + grid_[i][2] == sum ) { + count++; + } else if ( grid_[0][i] + grid_[1][i] + grid_[2][i] == sum ) { + count++; + } + } + + if ( grid_[0][0] + grid_[1][1] + grid_[2][2] == sum ) { + count++; + } else if ( grid_[2][0] + grid_[1][1] + grid_[0][2] == sum ) { + count++; + } + + return count; +} + +bool Field::InRange( const Move& move ) const { + return move.row >= 0 && move.row < 3 && move.col >= 0 && move.col < 3; +} + +bool Field::IsEmpty( const Move& move ) const { + return grid_[move.row][move.col] == None; +} + +bool Field::IsFull() const { + return left_ == 0; +} + +void Field::MakeMove( const Move& move, Token token ) { + if ( !InRange( move ) || !IsEmpty( move ) || token == None || !left_ ) { + return; + } + + grid_[move.row][move.col] = token; + left_--; +} + +void Field::ClearMove( const Move& move ) { + if ( !InRange( move ) || !IsEmpty( move ) || left_ == 9 ) { + return; + } + + grid_[move.row][move.col] = None; + left_++; +} diff --git a/testing/search_view/data/files/field.h b/testing/search_view/data/files/field.h new file mode 100644 index 00000000..c93ea640 --- /dev/null +++ b/testing/search_view/data/files/field.h @@ -0,0 +1,43 @@ +#ifndef _FIELD_ +#define _FIELD_ + +#include "game_object.h" + +class Field : public GameObject { +public: + enum Token { + None = 0, + PlayerA = 1, + PlayerB = 4 + }; + + static Token Opponent( Token token ); + + struct Move { + int row; + int col; + }; + + Field(); + ~Field(); + + Field Clone() const; + void Clear(); + + void Show() const; + + int SameInRow( Token token, int amount ) const; + + bool InRange( const Move& move ) const; + bool IsEmpty( const Move& move ) const; + bool IsFull() const; + + void MakeMove( const Move& move, Token token ); + void ClearMove( const Move& move ); + +private: + Token** grid_; + int left_; +}; + +#endif // _FIELD_ diff --git a/testing/search_view/data/files/game_object.h b/testing/search_view/data/files/game_object.h new file mode 100644 index 00000000..fba0e6f3 --- /dev/null +++ b/testing/search_view/data/files/game_object.h @@ -0,0 +1,10 @@ +#ifndef _GAME_OBJECT_ +#define _GAME_OBJECT_ + +class GameObject { +public: + GameObject() {} + virtual ~GameObject() {} +}; + +#endif // _GAME_OBJECT_ diff --git a/testing/search_view/data/files/human_player.cpp b/testing/search_view/data/files/human_player.cpp new file mode 100644 index 00000000..4357d897 --- /dev/null +++ b/testing/search_view/data/files/human_player.cpp @@ -0,0 +1,49 @@ +#include "human_player.h" + +#include "io.h" + +HumanPlayer::HumanPlayer( Field::Token token, const char* name ) + : Player( token, name ) { +} + +HumanPlayer::~HumanPlayer() { +} + +Field::Move HumanPlayer::Turn( const Field& field ) const { + Field::Move move; + io::stringOut(name_); + io::stringOut("\n"); + + do { + move = Input(); + move.row -= 1; + move.col -= 1; + } while ( !Check( field, move ) ); + return move; +} + +Field::Move HumanPlayer::Input() const { + Field::Move move; + move.row = -1; + move.col = -1; + + io::stringOut("Insert row: "); + move.row = io::numberIn(); + + io::stringOut("Insert column: "); + move.col = io::numberIn(); + + io::stringOut("\n"); + return move; +} + +bool HumanPlayer::Check( const Field& field, const Field::Move& move ) const { + if ( !field.InRange( move ) ) { + io::stringOut("Wrong input!\n"); + return false; + } else if ( !field.IsEmpty( move ) ) { + io::stringOut("Is occupied!\n"); + return false; + } + return true; +} diff --git a/testing/search_view/data/files/human_player.h b/testing/search_view/data/files/human_player.h new file mode 100644 index 00000000..afa98d55 --- /dev/null +++ b/testing/search_view/data/files/human_player.h @@ -0,0 +1,20 @@ +#ifndef _HUMAN_PLAYER_ +#define _HUMAN_PLAYER_ + +#include "player.h" + + +class HumanPlayer : public Player { +public: + HumanPlayer( Field::Token token, const char* name ); + virtual ~HumanPlayer(); + + virtual Field::Move Turn( const Field& field ) const; + +private: + Field::Move Input() const; + + bool Check( const Field& field, const Field::Move& move ) const; +}; + +#endif // _HUMAN_PLAYER_ diff --git a/testing/search_view/data/files/io.cpp b/testing/search_view/data/files/io.cpp new file mode 100644 index 00000000..ec65d0da --- /dev/null +++ b/testing/search_view/data/files/io.cpp @@ -0,0 +1,23 @@ +#include "io.h" + +#include +#include +#include + +int io::numberIn() { + std::string input; + getline( std::cin, input ); + std::stringstream stream( input ); + + int number; + stream >> number; + return number; +} + +void io::numberOut(int num) { + std::cout << num; +} + +void io::stringOut(const char* str) { + std::cout << str; +} diff --git a/testing/search_view/data/files/io.h b/testing/search_view/data/files/io.h new file mode 100644 index 00000000..bacfe58e --- /dev/null +++ b/testing/search_view/data/files/io.h @@ -0,0 +1,13 @@ +#ifndef _IO_ +#define _IO_ + +namespace io { + + int numberIn(); + void numberOut(int num); + + void stringOut(const char* str); + +} + +#endif // _IO_ diff --git a/testing/search_view/data/files/main.cpp b/testing/search_view/data/files/main.cpp new file mode 100644 index 00000000..8d15ea5f --- /dev/null +++ b/testing/search_view/data/files/main.cpp @@ -0,0 +1,11 @@ +#include "tictactoe.h" + +int main() { + TicTacToe tictactoe; + + while ( tictactoe.Start() ) { + tictactoe.Run(); + } + + return 0; +} diff --git a/testing/search_view/data/files/player.cpp b/testing/search_view/data/files/player.cpp new file mode 100644 index 00000000..a1b3694c --- /dev/null +++ b/testing/search_view/data/files/player.cpp @@ -0,0 +1,19 @@ +#include "player.h" + +Player::Player( Field::Token token, const char* name ) + : token_( token ) + , name_( name ) { +} + +Player::~Player() { +} + +const Field::Token& Player::getToken() const +{ + return token_; +} + +const char* Player::getName() const +{ + return name_; +} diff --git a/testing/search_view/data/files/player.h b/testing/search_view/data/files/player.h new file mode 100644 index 00000000..700b3e5e --- /dev/null +++ b/testing/search_view/data/files/player.h @@ -0,0 +1,23 @@ +#ifndef _PLAYER_ +#define _PLAYER_ + +#include "field.h" +#include "game_object.h" + + +class Player : public GameObject { +public: + Player( Field::Token token, const char* name ); + virtual ~Player(); + + virtual Field::Move Turn( const Field& field ) const = 0; + + const Field::Token& getToken() const; + const char* getName() const; + +protected: + const Field::Token token_; + const char* name_; +}; + +#endif // _PLAYER_ diff --git a/testing/search_view/data/files/template.cpp b/testing/search_view/data/files/template.cpp new file mode 100644 index 00000000..0839d349 --- /dev/null +++ b/testing/search_view/data/files/template.cpp @@ -0,0 +1,24 @@ + +#include "template.h" + +template +T sum(T a, T b) +{ + return a + b; +} + +template <> +int sum(int a, int b) +{ + return a + b; +} + +void work() +{ + double x = sum(0.1, 0.2); + int y = sum(-1, 2); + unsigned int z = sum(1, 2); + + int v = diff(9, 5); + double w = diff(0.5, 0.3); +} diff --git a/testing/search_view/data/files/template.h b/testing/search_view/data/files/template.h new file mode 100644 index 00000000..b0ae449a --- /dev/null +++ b/testing/search_view/data/files/template.h @@ -0,0 +1,6 @@ + +template +T diff(T a, T b) +{ + return a - b; +} diff --git a/testing/search_view/data/files/tictactoe.cpp b/testing/search_view/data/files/tictactoe.cpp new file mode 100644 index 00000000..b4ba8ef1 --- /dev/null +++ b/testing/search_view/data/files/tictactoe.cpp @@ -0,0 +1,86 @@ +#include "tictactoe.h" + +#include "artificial_player.h" +#include "human_player.h" +#include "io.h" + +TicTacToe::TicTacToe() { + players_[0] = 0; + players_[1] = 0; +} + +TicTacToe::~TicTacToe() { + Reset(); +} + + +bool TicTacToe::Start() { + Reset(); + io::stringOut("Tic Tac Toe\n\n[1] Human\n[2] Computer\n[3] Quit\n\n"); + + players_[0] = SelectPlayer( Field::PlayerA, "Player A" ); + if ( !players_[0] ) { + return false; + } + + players_[1] = SelectPlayer( Field::PlayerB, "Player B" ); + if ( !players_[1] ) { + return false; + } + + io::stringOut("\n"); + return true; +} + +void TicTacToe::Run() { + field_.Show(); + + int playerIndex = 0; + + for ( int i = 0; i < 9; i++ ) { + Player& player = *players_[playerIndex]; + + field_.MakeMove( player.Turn( field_ ), player.getToken() ); + field_.Show(); + + if ( field_.SameInRow( player.getToken(), 3 ) ) { + io::stringOut(player.getName()); + io::stringOut(" won!\n\n"); + return; + } + + playerIndex = ( playerIndex + 1 ) % 2; + } + + io::stringOut("Game ends in draw!\n\n"); +} + +void TicTacToe::Reset() { + field_.Clear(); + + for ( int i = 0; i < 2; i++ ) { + if ( players_[i] ) { + delete players_[i]; + players_[i] = 0; + } + } +} + +Player* TicTacToe::SelectPlayer( Field::Token token, const char* name ) const { + int selection = 0; + + while ( true ) { + io::stringOut("Choose "); + io::stringOut(name); + io::stringOut(": "); + + selection = io::numberIn(); + + switch ( selection ) { + case 1 : return new HumanPlayer( token, name ); + case 2 : return new ArtificialPlayer( token, name ); + case 3 : return 0; + default : io::stringOut("Wrong input!\n"); + } + } +} diff --git a/testing/search_view/data/files/tictactoe.h b/testing/search_view/data/files/tictactoe.h new file mode 100644 index 00000000..6bf279da --- /dev/null +++ b/testing/search_view/data/files/tictactoe.h @@ -0,0 +1,23 @@ +#ifndef _TIC_TAC_TOE_ +#define _TIC_TAC_TOE_ + +#include "field.h" +#include "player.h" + +class TicTacToe { +public: + TicTacToe(); + ~TicTacToe(); + + bool Start(); + void Run(); + +private: + void Reset(); + Player* SelectPlayer( Field::Token token, const char* name ) const; + + Player* players_[2]; + Field field_; +}; + +#endif // _TIC_TAC_TOE_ diff --git a/testing/search_view/data/fulltext_tests.cpp b/testing/search_view/data/fulltext_tests.cpp new file mode 100644 index 00000000..6e7bd1c8 --- /dev/null +++ b/testing/search_view/data/fulltext_tests.cpp @@ -0,0 +1,56 @@ + +namespace FULLTEXT_TESTS +{ + +// TEST: shortcut +// START ---------------------------------------------------------------------- + +// ACTION: Use Find Shortcut: Edit -> Find Text +// RESULTS: +// - search field is focused +// - content is replaced with '?' +// - followed with cursor + +// END ------------------------------------------------------------------------ + + + +// TEST: enter button +// START ---------------------------------------------------------------------- + +// ACTION: Search for '?reset', press enter +// Result: Code view shows 5 references + +// END ------------------------------------------------------------------------ + + + +// TEST: mouse click +// START ---------------------------------------------------------------------- + +// ACTION: Search for '?won', press search button +// Result: Code view shows 2 references + +// END ------------------------------------------------------------------------ + + + +// TEST: implicit +// START ---------------------------------------------------------------------- + +// ACTION: Search for 'player a', press search button +// Result: fulltext search is used and shows 2 references + +// END ------------------------------------------------------------------------ + + + +// TEST: case sensitive +// START ---------------------------------------------------------------------- + +// ACTION: Search for '??game' +// Result: code view shows 3 references + +// END ------------------------------------------------------------------------ + +} diff --git a/testing/search_view/data/keyword_tests.cpp b/testing/search_view/data/keyword_tests.cpp new file mode 100644 index 00000000..6ad28fb9 --- /dev/null +++ b/testing/search_view/data/keyword_tests.cpp @@ -0,0 +1,40 @@ + +namespace KEYWORD_TESTS +{ + +// TEST: certain keywords +// START ---------------------------------------------------------------------- + +// ACTION: Search for 'overview' +// ACTION: Search for 'errors' +// ACTION: Search for 'legend' +// ACTION: Search for 'file' +// ACTION: Search for 'field' + +// RESULTS: correct things are activated + +// END ------------------------------------------------------------------------ + + + +// TEST: autocomplete within symbol types +// START ---------------------------------------------------------------------- + +// ACTION: Search for 'file', press tab, enter 'main' +// RESULTS: only 'main.cpp' is shown in list + +// END ------------------------------------------------------------------------ + + + +// TEST: autocomplete within multiple symbol types +// START ---------------------------------------------------------------------- + +// ACTION: Search for 'method', press tab, then 'field', enter 'ttt' +// RESULTS: only methods and fields of TicTacToe are in the list + +// END ------------------------------------------------------------------------ + +} + +error; diff --git a/testing/search_view/search_view_tests.srctrlprj b/testing/search_view/search_view_tests.srctrlprj new file mode 100644 index 00000000..925879bb --- /dev/null +++ b/testing/search_view/search_view_tests.srctrlprj @@ -0,0 +1,33 @@ + + + Test Suites:\n\n [::\tmAUTOCOMPLETION_TESTS\ts\tp]\n [::\tmFULLTEXT_TESTS\ts\tp]\n [::\tmKEYWORD_TESTS\ts\tp]\n + + + c++17 + + + unknown + x86_64 + unknown + unknown + + 0 + + + data/files/template.h + + C++ Source Group + + .cpp + .cxx + .cc + + + data + + enabled + C++ Source Group + + + 7 +