lumiera_/tests/library/path-array-test.cpp

492 lines
18 KiB
C++

/*
PathArray(Test) - verify container abstraction for a sequence of path elements
Copyright (C) Lumiera.org
2017, Hermann Vosseler <Ichthyostega@web.de>
This program 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 2 of
the License, or (at your option) any later version.
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.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* *****************************************************/
/** @file path-array-test.cpp
** unit test \ref PathArray_test
*/
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/path-array.hpp"
#include "lib/format-util.hpp"
#include "lib/util.hpp"
#include <string>
using std::string;
using lib::Symbol;
using util::isnil;
using util::join;
namespace lib {
namespace test {
using lumiera::error::LUMIERA_ERROR_INDEX_BOUNDS;
using lumiera::error::LUMIERA_ERROR_INVALID;
using ParrT = lib::PathArray<5>;
/******************************************************************************//**
* @test verify abstraction wrapper to handle some char pointers in the way of a
* standard sequence container with iteration and range checks.
*
* @see path-array.hpp
* @see UICoord_test
* @see Navigator
*/
class PathArray_test : public Test
{
virtual void
run (Arg)
{
verify_basics();
verify_iteration();
verify_boundaries();
verify_comparisons();
}
void
verify_basics()
{
ParrT undef;
CHECK (isnil (undef));
ParrT parr{"Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","Ω"};
CHECK (not isnil (parr));
CHECK (8 == parr.size());
// indexed access
CHECK ("Γ" == parr[0]);
CHECK ("Δ" == parr[1]);
CHECK ("Θ" == parr[2]);
CHECK ("Ξ" == parr[3]);
CHECK ("Σ" == parr[4]);
CHECK ("Ψ" == parr[5]);
CHECK ("Φ" == parr[6]);
CHECK ("Ω" == parr[7]);
VERIFY_ERROR (INDEX_BOUNDS, parr[8]);
// string representation
CHECK ("Γ/Δ/Θ/Ξ/Σ/Ψ/Φ/Ω" == string(parr));
// new value can be assigned, but not altered in place
parr = ParrT{nullptr,nullptr,"Θ",nullptr,nullptr,nullptr,"Φ"};
CHECK (7 == parr.size());
// representation is trimmed and filled
CHECK ("Θ/*/*/*/Φ" == string(parr));
CHECK (Symbol::EMPTY == parr[0]);
CHECK (Symbol::EMPTY == parr[1]);
CHECK ("Θ" == parr[2]);
CHECK ("*" == parr[3]);
CHECK ("*" == parr[4]);
CHECK ("*" == parr[5]);
CHECK ("Φ" == parr[6]);
VERIFY_ERROR (INDEX_BOUNDS, parr[7]);
VERIFY_ERROR (INDEX_BOUNDS, parr[8]);
}
void
verify_iteration()
{
ParrT parr;
CHECK (isnil (parr));
// path is iterable
CHECK ("" == join(parr));
parr = ParrT{"Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","Ω"};
CHECK (8 == parr.size());
// path is iterable
CHECK ("ΓΔΘΞΣΨΦΩ" == join(parr,""));
// iteration matches index order
uint i=0;
for (ParrT::iterator ii = parr.begin(); ii; ++ii, ++i)
CHECK (parr[i] == *ii);
CHECK (8 == i);
// path information is automatically trimmed and filled
parr = ParrT{nullptr,nullptr,"Θ",nullptr,nullptr,nullptr,"Φ"};
CHECK (7 == parr.size());
CHECK ("Θ***Φ" == join(parr,""));
parr = ParrT{nullptr,"Δ",nullptr,"Ξ",nullptr,nullptr,nullptr};
CHECK (4 == parr.size());
CHECK ("Δ*Ξ" == join(parr,""));
parr = ParrT{nullptr,"Δ",nullptr,"Ξ",nullptr,nullptr,"Φ"};
CHECK (7 == parr.size());
CHECK ("Δ*Ξ**Φ" == join(parr,""));
parr = ParrT{nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,"Ω",nullptr};
CHECK (16 == parr.size());
CHECK ("Ω" == join(parr,""));
// index numbering starts at absolute root
CHECK ("Ω" == *parr.begin());
CHECK (Symbol::EMPTY == parr[0]);
CHECK (Symbol::EMPTY == parr[1]);
CHECK (Symbol::EMPTY == parr[2]);
CHECK ("Ω" == parr[15]);
VERIFY_ERROR (INDEX_BOUNDS, parr[16]);
// but iteration starts with actual content
parr = ParrT{nullptr,nullptr,"Θ","Ξ","Σ","Ψ","Φ","Ω"};
CHECK ("Θ" == *parr.begin());
CHECK ( 2 == parr.indexOf (*parr.begin()));
CHECK ("Θ" == parr[2]);
parr = ParrT{nullptr,nullptr,nullptr,nullptr,"Σ","Ψ","Φ","Ω"};
CHECK ("Σ" == *parr.begin());
CHECK ( 5 == parr.indexOf (*parr.begin()));
CHECK ( 6 == parr.indexOf (*++parr.begin()));
CHECK ( 7 == parr.indexOf (*++++parr.begin()));
Literal some{"muck"};
VERIFY_ERROR (INVALID, parr.indexOf (some));
}
/** @test cover some tricky corner cases of
* the bound checks and normalisation routine.
* @remark the container used for this test has an
* inline chunk size of 5, which means any further
* elements are in heap allocated extension storage.
* Normalisation seamlessly surpasses that boundary.
*/
void
verify_boundaries()
{
ParrT parr;
CHECK ("" == join(parr));
CHECK (0 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","Ω"};
CHECK ("ΓΔΘΞΣΨΦΩ" == join(parr,""));
CHECK (8 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ","Σ","Ψ","Φ",""};
CHECK ("ΓΔΘΞΣΨΦ" == join(parr,""));
CHECK (7 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ","Σ","Ψ","Φ",nullptr};
CHECK ("ΓΔΘΞΣΨΦ" == join(parr,""));
CHECK (7 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ","Σ","Ψ",nullptr,""};
CHECK ("ΓΔΘΞΣΨ" == join(parr,""));
CHECK (6 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ","Σ","",nullptr,""};
CHECK ("ΓΔΘΞΣ" == join(parr,""));
CHECK (5 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ","Σ",nullptr,"",nullptr};
CHECK ("ΓΔΘΞΣ" == join(parr,""));
CHECK (5 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ","Σ",nullptr,nullptr,nullptr};
CHECK ("ΓΔΘΞΣ" == join(parr,""));
CHECK (5 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ","Σ",nullptr,nullptr,nullptr,""};
CHECK ("ΓΔΘΞΣ" == join(parr,""));
CHECK (5 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ","Σ","","",""};
CHECK ("ΓΔΘΞΣ" == join(parr,""));
CHECK (5 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ","","","Φ",""};
CHECK ("ΓΔΘΞ**Φ" == join(parr,""));
CHECK (7 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ",nullptr,"","Φ",""};
CHECK ("ΓΔΘΞ**Φ" == join(parr,""));
CHECK (7 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ","",nullptr,"Φ",""};
CHECK ("ΓΔΘΞ**Φ" == join(parr,""));
CHECK (7 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ",nullptr,nullptr,"Φ",""};
CHECK ("ΓΔΘΞ**Φ" == join(parr,""));
CHECK (7 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ","","","Φ",nullptr};
CHECK ("ΓΔΘΞ**Φ" == join(parr,""));
CHECK (7 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ","","","Φ",nullptr,""};
CHECK ("ΓΔΘΞ**Φ" == join(parr,""));
CHECK (7 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ","","","Φ",nullptr,"",nullptr};
CHECK ("ΓΔΘΞ**Φ" == join(parr,""));
CHECK (7 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ","","","Φ",nullptr,"",nullptr,""};
CHECK ("ΓΔΘΞ**Φ" == join(parr,""));
CHECK (7 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ","",nullptr,"",nullptr,"",nullptr,""};
CHECK ("ΓΔΘΞ" == join(parr,""));
CHECK (4 == parr.size());
parr = ParrT{"Γ","Δ","Θ","Ξ",nullptr,"",nullptr,"",nullptr,"",nullptr};
CHECK ("ΓΔΘΞ" == join(parr,""));
CHECK (4 == parr.size());
parr = ParrT{"","Δ","Θ","Ξ","","",""};
CHECK ("ΔΘΞ" == join(parr,""));
CHECK (4 == parr.size());
CHECK ("" == parr[0]);
parr = ParrT{nullptr,"Δ","Θ","Ξ","","",""};
CHECK ("ΔΘΞ" == join(parr,""));
CHECK (4 == parr.size());
CHECK ("" == parr[0]);
parr = ParrT{nullptr,"Δ",nullptr,"Ξ","","",""};
CHECK ("Δ*Ξ" == join(parr,""));
CHECK (4 == parr.size());
CHECK ("" == parr[0]);
CHECK ("Δ" == parr[1]);
CHECK ("*" == parr[2]);
CHECK ("Ξ" == parr[3]);
parr = ParrT{nullptr,"",nullptr,"Ξ","","",""};
CHECK ("Ξ" == join(parr,""));
CHECK (4 == parr.size());
CHECK ("" == parr[0]);
CHECK ("" == parr[1]);
CHECK ("" == parr[2]);
CHECK ("Ξ" == parr[3]);
parr = ParrT{nullptr,"",nullptr,"Ξ","","Ψ",""};
CHECK ("Ξ*Ψ" == join(parr,""));
CHECK (6 == parr.size());
CHECK ("" == parr[0]);
CHECK ("" == parr[1]);
CHECK ("" == parr[2]);
CHECK ("Ξ" == parr[3]);
CHECK ("*" == parr[4]);
CHECK ("Ψ" == parr[5]);
parr = ParrT{nullptr,"",nullptr,"Ξ",nullptr,"Ψ",""};
CHECK ("Ξ*Ψ" == join(parr,""));
CHECK (6 == parr.size());
CHECK ("" == parr[0]);
CHECK ("" == parr[1]);
CHECK ("" == parr[2]);
CHECK ("Ξ" == parr[3]);
CHECK ("*" == parr[4]);
CHECK ("Ψ" == parr[5]);
parr = ParrT{nullptr,"",nullptr,"Ξ",nullptr,nullptr,"Φ",""};
CHECK ("Ξ**Φ" == join(parr,""));
CHECK (7 == parr.size());
CHECK ("" == parr[0]);
CHECK ("" == parr[1]);
CHECK ("" == parr[2]);
CHECK ("Ξ" == parr[3]);
CHECK ("*" == parr[4]);
CHECK ("*" == parr[5]);
CHECK ("Φ" == parr[6]);
parr = ParrT{nullptr,"",nullptr,"Ξ","",nullptr,"Φ",""};
CHECK ("Ξ**Φ" == join(parr,""));
CHECK (7 == parr.size());
CHECK ("" == parr[0]);
CHECK ("" == parr[1]);
CHECK ("" == parr[2]);
CHECK ("Ξ" == parr[3]);
CHECK ("*" == parr[4]);
CHECK ("*" == parr[5]);
CHECK ("Φ" == parr[6]);
parr = ParrT{nullptr,"",nullptr,"Ξ",nullptr,"","Φ",""};
CHECK ("Ξ**Φ" == join(parr,""));
CHECK (7 == parr.size());
CHECK ("" == parr[0]);
CHECK ("" == parr[1]);
CHECK ("" == parr[2]);
CHECK ("Ξ" == parr[3]);
CHECK ("*" == parr[4]);
CHECK ("*" == parr[5]);
CHECK ("Φ" == parr[6]);
parr = ParrT{nullptr,"",nullptr,"Ξ","","","Φ",""};
CHECK ("Ξ**Φ" == join(parr,""));
CHECK (7 == parr.size());
CHECK ("" == parr[0]);
CHECK ("" == parr[1]);
CHECK ("" == parr[2]);
CHECK ("Ξ" == parr[3]);
CHECK ("*" == parr[4]);
CHECK ("*" == parr[5]);
CHECK ("Φ" == parr[6]);
parr = ParrT{"",nullptr,"",nullptr,"Σ","","Φ",""};
CHECK ("Σ*Φ" == join(parr,""));
CHECK (7 == parr.size());
CHECK ("" == parr[0]);
CHECK ("" == parr[1]);
CHECK ("" == parr[2]);
CHECK ("" == parr[3]);
CHECK ("Σ" == parr[4]);
CHECK ("*" == parr[5]);
CHECK ("Φ" == parr[6]);
parr = ParrT{"",nullptr,"",nullptr,"Σ",nullptr,"Φ",""};
CHECK ("Σ*Φ" == join(parr,""));
CHECK (7 == parr.size());
CHECK ("" == parr[0]);
CHECK ("" == parr[1]);
CHECK ("" == parr[2]);
CHECK ("" == parr[3]);
CHECK ("Σ" == parr[4]);
CHECK ("*" == parr[5]);
CHECK ("Φ" == parr[6]);
parr = ParrT{"",nullptr,"",nullptr,"","Ψ",nullptr,"Ω",""};
CHECK ("Ψ*Ω" == join(parr,""));
CHECK (8 == parr.size());
CHECK ("" == parr[0]);
CHECK ("" == parr[1]);
CHECK ("" == parr[2]);
CHECK ("" == parr[3]);
CHECK ("" == parr[4]);
CHECK ("Ψ" == parr[5]);
CHECK ("*" == parr[6]);
CHECK ("Ω" == parr[7]);
parr = ParrT{nullptr,"",nullptr,"",nullptr,"Ψ",nullptr,"Ω",""};
CHECK ("Ψ*Ω" == join(parr,""));
CHECK (8 == parr.size());
CHECK ("" == parr[0]);
CHECK ("" == parr[1]);
CHECK ("" == parr[2]);
CHECK ("" == parr[3]);
CHECK ("" == parr[4]);
CHECK ("Ψ" == parr[5]);
CHECK ("*" == parr[6]);
CHECK ("Ω" == parr[7]);
parr = ParrT{nullptr,"",nullptr,"",nullptr,"","Φ",nullptr,"ω",""};
CHECK ("Φ*ω" == join(parr,""));
CHECK (9 == parr.size());
CHECK ("" == parr[0]);
CHECK ("" == parr[1]);
CHECK ("" == parr[2]);
CHECK ("" == parr[3]);
CHECK ("" == parr[4]);
CHECK ("" == parr[5]);
CHECK ("Φ" == parr[6]);
CHECK ("*" == parr[7]);
CHECK ("ω" == parr[8]);
parr = ParrT{"",nullptr,"",nullptr,"",nullptr,"Φ",nullptr,"ω",""};
CHECK ("Φ*ω" == join(parr,""));
CHECK (9 == parr.size());
CHECK ("" == parr[0]);
CHECK ("" == parr[1]);
CHECK ("" == parr[2]);
CHECK ("" == parr[3]);
CHECK ("" == parr[4]);
CHECK ("" == parr[5]);
CHECK ("Φ" == parr[6]);
CHECK ("*" == parr[7]);
CHECK ("ω" == parr[8]);
parr = ParrT{"",nullptr,"",nullptr,"",nullptr,"Φ",nullptr,"ω","*"};
CHECK ("Φ*ω" == join(parr,""));
CHECK (9 == parr.size());
CHECK ("" == parr[0]);
CHECK ("" == parr[1]);
CHECK ("" == parr[2]);
CHECK ("" == parr[3]);
CHECK ("" == parr[4]);
CHECK ("" == parr[5]);
CHECK ("Φ" == parr[6]);
CHECK ("*" == parr[7]);
CHECK ("ω" == parr[8]);
parr = ParrT{"",nullptr,"",nullptr,"",nullptr,"Φ",nullptr,"*",""};
CHECK ("Φ" == join(parr,""));
CHECK (7 == parr.size());
CHECK ("" == parr[0]);
CHECK ("" == parr[1]);
CHECK ("" == parr[2]);
CHECK ("" == parr[3]);
CHECK ("" == parr[4]);
CHECK ("" == parr[5]);
CHECK ("Φ" == parr[6]);
}
/** @test verify equality comparison
* Equality of PathArray is based on overall size, position and _normalised_ content.
* @note especially how `"*"` might match "" or `nullptr` at corresponding positions.
*/
void
verify_comparisons()
{
CHECK (ParrT("Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","Ω") == ParrT("Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","Ω"));
CHECK (ParrT("Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","Ω") != ParrT("Γ","Δ","Θ","Σ","Ξ","Ψ","Φ","Ω"));
CHECK (ParrT("Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","Ω") != ParrT("Γ","Δ","Θ","Ξ","Ξ","Ψ","Φ","Ω"));
CHECK (ParrT("Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","Ω") != ParrT("" ,"Γ","Δ","Θ","Ξ","Σ","Ψ","Φ"));
CHECK (ParrT("Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","" ) != ParrT("" ,"Γ","Δ","Θ","Ξ","Σ","Ψ","Φ"));
CHECK (ParrT("Γ","Δ","Θ","Ξ","Σ","Ψ","Φ","" ) != ParrT("" ,"Γ","Δ","Θ","Ξ","Σ","Ψ","" ));
CHECK (ParrT("" ,"Δ","Θ","Ξ","Σ","Ψ","Φ","" ) != ParrT("*","Δ","Θ","Ξ","Σ","Ψ","Φ","" ));
CHECK (ParrT("" ,"Δ","Θ","Ξ","Σ","Ψ","Φ","" ) != ParrT("" ,"Δ","Θ","Ξ","" ,"Σ","Ψ","Φ"));
CHECK (ParrT("" ,"Δ","Θ","Ξ","Σ","Ψ","Φ","" ) != ParrT("" ,"Δ","Θ","Ξ","Σ***Ψ","Φ","" ));
CHECK (ParrT("" ,"Δ","Θ","Ξ","Σ","" ,"Φ","" ) != ParrT("" ,"Δ","Θ","Ξ","*","Ψ","Φ","" ));
CHECK (ParrT("" ,"Δ","Θ","Ξ","Σ","" ,"Φ","" ) != ParrT("" ,"Δ","Θ","Ξ","Σ","* ","Φ",""));
CHECK (ParrT("" ,"Δ","Θ","Ξ","Σ","" ,"Φ","" ) != ParrT("" ,"Δ","Θ","Ξ","Σ","**","Φ",""));
CHECK (ParrT("" ,"Δ","Θ","Ξ","Σ","Ψ","Φ","" ) == ParrT("" ,"Δ","Θ","Ξ","Σ","Ψ","Φ","*"));
CHECK (ParrT("" ,"Δ","Θ","Ξ","Σ","", "Φ","" ) == ParrT("" ,"Δ","Θ","Ξ","Σ","*","Φ","" ));
CHECK (ParrT("" ,"Δ","Θ","Ξ","Σ","Ψ","Φ","" ) == ParrT(nullptr,"Δ","Θ","Ξ","Σ","Ψ","Φ"));
CHECK (ParrT("" ,"Δ","Θ","Ξ","Σ","Ψ","Φ","" ) == ParrT("" ,"Δ","Θ","Ξ","Σ","Ψ","Φ",nullptr));
CHECK (ParrT("" ,"Δ","Θ","Ξ","Σ","Ψ","Φ","" ) == ParrT("" ,"Δ","Θ","Ξ","Σ","Ψ","Φ"));
CHECK (ParrT("" ,"Δ","Θ","Ξ","" ,"Ψ","Φ","" ) == ParrT("" ,"Δ","Θ","Ξ",nullptr,"Ψ","Φ"));
CHECK (ParrT("" ,"Δ","Θ","Ξ","*","Ψ","Φ","" ) == ParrT("" ,"Δ","Θ","Ξ",nullptr,"Ψ","Φ"));
CHECK (ParrT("" ,"Δ","Θ","Ξ","*","Ψ","Φ","" ) == ParrT("" ,"Δ","Θ","Ξ","", "Ψ","Φ"));
}
};
/** Register this test class... */
LAUNCHER (PathArray_test, "unit gui");
}} // namespace lib::test