2023-05-03 15:27:46 +02:00
|
|
|
/*
|
|
|
|
|
SplitSplice(Test) - verify interval splicing
|
|
|
|
|
|
|
|
|
|
Copyright (C) Lumiera.org
|
|
|
|
|
2023, 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 split-splice-test.cpp
|
|
|
|
|
** unit test \ref SplitSplice_test
|
2023-05-04 14:43:40 +02:00
|
|
|
** to verify proper working of the »SplitSplice« algorithm.
|
|
|
|
|
** This is a generic setup to modify a segmentation (partitioning)
|
|
|
|
|
** of an ordered axis; the axis is represented as a collection of _segments,_
|
|
|
|
|
** which are assumed to be ordered and seamless, with the start point inclusive
|
|
|
|
|
** and the end point exclusive (thus the start of the next segment is identical
|
|
|
|
|
** with the end point of the current segment).
|
|
|
|
|
**
|
|
|
|
|
** This test uses the natural number axis between -100 ... +100
|
|
|
|
|
** and establishes a binding for the generic algorithm with suitably rigged
|
|
|
|
|
** test data, to verify the algorithm properly inserts a new segment under all
|
|
|
|
|
** conceivable circumstances, since there are many possibilities of arrangement
|
|
|
|
|
** for two ordered segments of arbitrary length.
|
2023-05-03 15:27:46 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "lib/test/run.hpp"
|
2023-05-04 00:48:29 +02:00
|
|
|
#include "lib/test/test-helper.hpp"
|
2023-05-03 15:27:46 +02:00
|
|
|
#include "lib/format-cout.hpp"
|
|
|
|
|
#include "lib/format-util.hpp"
|
|
|
|
|
#include "lib/format-string.hpp"
|
|
|
|
|
#include "lib/split-splice.hpp"
|
|
|
|
|
#include "lib/nocopy.hpp"
|
|
|
|
|
#include "lib/util.hpp"
|
|
|
|
|
|
|
|
|
|
#include <utility>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <list>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
namespace lib {
|
|
|
|
|
namespace test {
|
|
|
|
|
|
|
|
|
|
using util::_Fmt;
|
|
|
|
|
using util::isnil;
|
|
|
|
|
using std::string;
|
|
|
|
|
using std::move;
|
2023-05-04 00:48:29 +02:00
|
|
|
|
2023-05-03 15:27:46 +02:00
|
|
|
namespace {// Test Fixture....
|
|
|
|
|
|
2023-05-04 00:48:29 +02:00
|
|
|
/**
|
|
|
|
|
* Test Dummy: a "segment" representing an integer interval.
|
|
|
|
|
* Memory management can be tracked since each instance gets a
|
|
|
|
|
* distinct ID number. Moreover, a Seg can be marked as "empty",
|
|
|
|
|
* which is visible on the `string` conversion
|
|
|
|
|
*/
|
2023-05-03 15:27:46 +02:00
|
|
|
struct Seg
|
|
|
|
|
: util::MoveOnly
|
|
|
|
|
{
|
|
|
|
|
int start;
|
|
|
|
|
int after;
|
|
|
|
|
bool empty;
|
|
|
|
|
|
2023-05-04 02:07:38 +02:00
|
|
|
~Seg()
|
|
|
|
|
{
|
|
|
|
|
check -= id;
|
|
|
|
|
if (id) --cnt;
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-03 15:27:46 +02:00
|
|
|
Seg (int s, int a, bool nil=false)
|
|
|
|
|
: start{s}
|
|
|
|
|
, after{a}
|
|
|
|
|
, empty{nil}
|
|
|
|
|
, id{++idGen}
|
|
|
|
|
{
|
2023-05-04 00:48:29 +02:00
|
|
|
++cnt;
|
2023-05-03 15:27:46 +02:00
|
|
|
check += id;
|
|
|
|
|
}
|
2023-05-04 00:48:29 +02:00
|
|
|
|
2023-05-04 02:07:38 +02:00
|
|
|
/** create a clone, but modify bounds */
|
|
|
|
|
Seg (Seg const& ref, int s, int a)
|
|
|
|
|
: start{s}
|
|
|
|
|
, after{a}
|
|
|
|
|
, empty{ref.empty}
|
|
|
|
|
, id{ref.id}
|
2023-05-03 15:27:46 +02:00
|
|
|
{
|
2023-05-04 02:07:38 +02:00
|
|
|
++cnt;
|
|
|
|
|
check += id;
|
2023-05-03 15:27:46 +02:00
|
|
|
}
|
|
|
|
|
|
2023-05-04 02:07:38 +02:00
|
|
|
/** move-init: causes source-ref to be invalidated */
|
2023-05-03 15:27:46 +02:00
|
|
|
Seg (Seg&& rr)
|
|
|
|
|
: start{rr.start}
|
|
|
|
|
, after{rr.after}
|
|
|
|
|
, empty{rr.empty}
|
|
|
|
|
, id{0}
|
|
|
|
|
{
|
|
|
|
|
std::swap (id, rr.id);
|
|
|
|
|
}//transfer identity
|
|
|
|
|
|
|
|
|
|
operator string() const
|
|
|
|
|
{
|
|
|
|
|
return _Fmt{"[%i%s%i["}
|
|
|
|
|
% start
|
|
|
|
|
% (empty? "~":"_")
|
|
|
|
|
% after
|
|
|
|
|
;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//-- Diagnostics --
|
|
|
|
|
uint id;
|
|
|
|
|
static uint idGen;
|
2023-05-04 00:48:29 +02:00
|
|
|
static size_t cnt;
|
|
|
|
|
static size_t check;
|
2023-05-03 15:27:46 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Storage for static ID-Generator
|
|
|
|
|
size_t Seg::check{0};
|
2023-05-04 00:48:29 +02:00
|
|
|
size_t Seg::cnt{0};
|
2023-05-03 15:27:46 +02:00
|
|
|
uint Seg::idGen{0};
|
|
|
|
|
|
|
|
|
|
const int SMIN = -100;
|
|
|
|
|
const int SMAX = +100;
|
|
|
|
|
|
|
|
|
|
/**
|
2023-05-04 00:48:29 +02:00
|
|
|
* Test-Segmentation comprised of a sequence of Seg entries.
|
|
|
|
|
* It can be checked for _validity_ according to the following conditions
|
|
|
|
|
* - the segmentation spans the complete range -100 ... +100
|
|
|
|
|
* - segments follow each other _seamlessly_
|
|
|
|
|
* - the bounds within each segment are ordered ascending
|
|
|
|
|
* - segments are not empty (i.e. start differs from end)
|
|
|
|
|
* The assessment of this validity conditions is appended on the string conversion.
|
2023-05-03 15:27:46 +02:00
|
|
|
*/
|
|
|
|
|
struct SegL
|
|
|
|
|
: std::list<Seg>
|
|
|
|
|
{
|
|
|
|
|
SegL (std::initializer_list<int> breaks)
|
|
|
|
|
{
|
|
|
|
|
int p = SMIN;
|
|
|
|
|
bool bound = true;
|
|
|
|
|
for (int b : breaks)
|
|
|
|
|
{
|
|
|
|
|
emplace_back (p,b, bound);
|
|
|
|
|
bound = false;
|
|
|
|
|
p = b;
|
|
|
|
|
}
|
|
|
|
|
emplace_back(p,SMAX, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SegL()
|
|
|
|
|
: SegL({})
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
// using standard copy
|
|
|
|
|
|
|
|
|
|
operator string() const
|
2023-05-04 00:48:29 +02:00
|
|
|
{
|
|
|
|
|
return renderContent() + assess();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool
|
|
|
|
|
isValid() const
|
|
|
|
|
{
|
|
|
|
|
return isnil (this->assess());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string
|
|
|
|
|
renderContent() const
|
2023-05-03 15:27:46 +02:00
|
|
|
{
|
|
|
|
|
return "├"+util::join(*this,"")+"┤";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
string
|
|
|
|
|
assess() const
|
|
|
|
|
{
|
|
|
|
|
string diagnosis;
|
|
|
|
|
if (empty())
|
|
|
|
|
diagnosis = "!empty!";
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (front().start != SMIN)
|
|
|
|
|
diagnosis += "missing-lower-bound!";
|
|
|
|
|
if (back().after != SMAX)
|
|
|
|
|
diagnosis += "missing-upper-bound!";
|
|
|
|
|
int p = SMIN;
|
|
|
|
|
for (auto const& s : *this)
|
|
|
|
|
{
|
|
|
|
|
if (s.start != p)
|
|
|
|
|
diagnosis += _Fmt{"!gap_%i<>%i_!"} % p % s.start;
|
|
|
|
|
if (s.start == s.after)
|
|
|
|
|
diagnosis += _Fmt{"!degen_%i_!"} % s.start;
|
|
|
|
|
if (s.start > s.after)
|
|
|
|
|
diagnosis += _Fmt{"!order_%i>%i_!"} % s.start % s.after;
|
|
|
|
|
p = s.after;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return diagnosis;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2023-05-04 12:01:25 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ======= Split/Splice-Algo Setup ======= */
|
|
|
|
|
|
|
|
|
|
using OptInt = std::optional<int>;
|
|
|
|
|
using Iter = typename SegL::iterator;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Perform the »SplitSplice« Algorithm to splice a new Segment
|
|
|
|
|
* into the given [segmentation of the integer-axis](\ref SegL).
|
|
|
|
|
* A local λ-binding is setup to define the basic operations
|
|
|
|
|
* required by the Algo implementation to work with this
|
|
|
|
|
* specific kind of data.
|
|
|
|
|
* @return Tuple `(s,n,e)` to indicate where changes happened
|
|
|
|
|
* - s the first changed element
|
|
|
|
|
* - n the new main segment (may be identical to s)
|
|
|
|
|
* - e the first unaltered element after the changed range (may be `end()`)
|
|
|
|
|
* @see lib::splitsplice::Algo
|
|
|
|
|
* @see [setup for the Fixture-Segmentation](\ref steam::fixture::Segmentation::splitSplice)
|
|
|
|
|
*/
|
|
|
|
|
auto
|
|
|
|
|
invokeSplitSplice (SegL& segs, OptInt startNew, OptInt afterNew)
|
|
|
|
|
{
|
|
|
|
|
/*---configure-contextually-bound-Functors--------------------*/
|
|
|
|
|
auto getStart = [](Iter elm) -> int { return elm->start; };
|
|
|
|
|
auto getAfter = [](Iter elm) -> int { return elm->after; };
|
|
|
|
|
auto createSeg= [&](Iter pos, int start, int after) -> Iter { return segs.emplace (pos, start, after); };
|
|
|
|
|
auto emptySeg = [&](Iter pos, int start, int after) -> Iter { return segs.emplace (pos, start, after, true); };
|
|
|
|
|
auto cloneSeg = [&](Iter pos, int start, int after, Iter src) -> Iter { return segs.emplace (pos, *src, start, after); };
|
|
|
|
|
auto discard = [&](Iter pos, Iter after) -> Iter { return segs.erase (pos,after); };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
lib::splitsplice::Algo splicer{ getStart
|
|
|
|
|
, getAfter
|
|
|
|
|
, createSeg
|
|
|
|
|
, emptySeg
|
|
|
|
|
, cloneSeg
|
|
|
|
|
, discard
|
|
|
|
|
, SMAX
|
|
|
|
|
, segs.begin(),segs.end()
|
|
|
|
|
, startNew, afterNew
|
|
|
|
|
};
|
|
|
|
|
splicer.determineRelations();
|
|
|
|
|
return splicer.performSplitSplice();
|
|
|
|
|
}
|
2023-05-03 15:27:46 +02:00
|
|
|
}//(End)Test Fixture
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-05-04 00:48:29 +02:00
|
|
|
|
2023-05-03 15:27:46 +02:00
|
|
|
/****************************************************************************//**
|
|
|
|
|
* @test verify proper working of a generic procedure to splice an interval
|
|
|
|
|
* into a complete segmentation of an ordered axis into seamless intervals.
|
|
|
|
|
* - demonstrate how to setup the invocation with custom data types
|
|
|
|
|
* - systematic coverage of all possible arrangements of intervals
|
|
|
|
|
* - handling of irregular cases
|
|
|
|
|
* @see split-splice.hpp
|
|
|
|
|
* @see steam::fixture::Segmentation::splitSplice
|
|
|
|
|
*/
|
|
|
|
|
class SplitSplice_test : public Test
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
virtual void
|
|
|
|
|
run (Arg)
|
|
|
|
|
{
|
|
|
|
|
demonstrate_usage();
|
|
|
|
|
verify_testFixture();
|
|
|
|
|
verify_standardCases();
|
|
|
|
|
verify_cornerCases();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test demonstrate how to use the »Split-Splice« algorithm with custom data
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
demonstrate_usage()
|
|
|
|
|
{
|
2023-05-04 12:01:25 +02:00
|
|
|
SegL segmentation;
|
|
|
|
|
CHECK (segmentation == "├[-100~100[┤"_expect);
|
2023-05-04 02:07:38 +02:00
|
|
|
|
2023-05-04 12:01:25 +02:00
|
|
|
OptInt startNew{5},
|
|
|
|
|
afterNew{23};
|
2023-05-04 02:07:38 +02:00
|
|
|
|
2023-05-04 12:01:25 +02:00
|
|
|
invokeSplitSplice (segmentation, startNew, afterNew);
|
|
|
|
|
|
|
|
|
|
// The given segmentation was modified by side-effect
|
|
|
|
|
// - a new segment [5...23[ has been inserted in the middle
|
|
|
|
|
// - suitably adapted empty predecessor and successor segments
|
|
|
|
|
CHECK (segmentation == "├[-100~5[[5_23[[23~100[┤"_expect);
|
2023-05-04 02:07:38 +02:00
|
|
|
|
2023-05-04 12:01:25 +02:00
|
|
|
// The modified segmentation still seamlessly covers the whole axis
|
|
|
|
|
CHECK (segmentation.isValid());
|
2023-05-03 15:27:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-05-04 14:43:40 +02:00
|
|
|
|
2023-05-03 15:27:46 +02:00
|
|
|
/** @test verify the fixture and self-diagnostics for this test */
|
|
|
|
|
void
|
|
|
|
|
verify_testFixture()
|
|
|
|
|
{
|
2023-05-04 02:07:38 +02:00
|
|
|
CHECK (0 == Seg::check);
|
|
|
|
|
Seg::idGen = 0;
|
2023-05-03 15:27:46 +02:00
|
|
|
{
|
2023-05-04 00:48:29 +02:00
|
|
|
Seg x{1,3}; // a segment 1 (inclusive) to 3 (exclusive)
|
|
|
|
|
Seg u{2,4,true}; // an "empty" segment 2 (incl) to 4 (excl)
|
|
|
|
|
CHECK (x == "[1_3["_expect);
|
|
|
|
|
CHECK (u == "[2~4["_expect); // "empty" interval is marked with '~' in string stylisation
|
|
|
|
|
CHECK (3 == Seg::check);
|
|
|
|
|
CHECK (2 == Seg::cnt);
|
|
|
|
|
|
2023-05-03 15:27:46 +02:00
|
|
|
Seg z{move(u)};
|
2023-05-04 00:48:29 +02:00
|
|
|
CHECK (z == "[2~4["_expect);
|
|
|
|
|
CHECK (3 == Seg::check);
|
|
|
|
|
CHECK (2 == Seg::cnt); // the "dead" instance u is not counted
|
|
|
|
|
CHECK (0 == u.id); // (its ID has been reset to zero in move-ctor)
|
|
|
|
|
CHECK (2 == z.id);
|
2023-05-03 15:27:46 +02:00
|
|
|
|
2023-05-04 00:48:29 +02:00
|
|
|
SegL l1; // default ctor always adds an empty base segment -100 ... +100
|
2023-05-03 15:27:46 +02:00
|
|
|
SegL l2{3};
|
|
|
|
|
SegL l3{5,-5,10};
|
2023-05-04 00:48:29 +02:00
|
|
|
CHECK (l1 == "├[-100~100[┤"_expect);
|
|
|
|
|
CHECK (l2 == "├[-100~3[[3~100[┤"_expect);
|
|
|
|
|
CHECK (l3 == "├[-100~5[[5_-5[[-5_10[[10~100[┤!order_5>-5_!"_expect);
|
|
|
|
|
|
|
|
|
|
CHECK (l1.isValid());
|
|
|
|
|
CHECK (l2.isValid());
|
|
|
|
|
CHECK (not l3.isValid()); // l3 violates validity condition, because segment [5 ... -5[ is reversed
|
|
|
|
|
CHECK (l3.assess() == "!order_5>-5_!"_expect);
|
2023-05-03 15:27:46 +02:00
|
|
|
|
2023-05-04 00:48:29 +02:00
|
|
|
CHECK ( 9 == Seg::cnt ); // 9 objects are alive
|
|
|
|
|
CHECK ( 9 == Seg::idGen); // ID generator sticks at 9
|
|
|
|
|
CHECK (45 == Seg::check); // checksum 1+..+9
|
2023-05-03 15:27:46 +02:00
|
|
|
|
|
|
|
|
l3.erase(l3.begin());
|
2023-05-04 00:48:29 +02:00
|
|
|
CHECK (l3.assess() == "missing-lower-bound!!gap_-100<>5_!!order_5>-5_!"_expect);
|
|
|
|
|
CHECK ( 8 == Seg::cnt ); // also one object less alive
|
|
|
|
|
|
|
|
|
|
l3.begin()->after = 5; // manipulate first segment to make it degenerate (empty
|
|
|
|
|
CHECK (l3.renderContent() == "├[5_5[[-5_10[[10~100[┤"_expect);
|
|
|
|
|
CHECK (l3.assess() == "missing-lower-bound!!gap_-100<>5_!!degen_5_!!gap_5<>-5_!"_expect);
|
2023-05-03 15:27:46 +02:00
|
|
|
l3.clear();
|
2023-05-04 00:48:29 +02:00
|
|
|
CHECK (l3.assess() == "!empty!"_expect);
|
2023-05-03 15:27:46 +02:00
|
|
|
|
2023-05-04 00:48:29 +02:00
|
|
|
CHECK ( 5 == Seg::cnt );
|
|
|
|
|
CHECK ( 9 == Seg::idGen);
|
|
|
|
|
CHECK (15 == Seg::check);
|
2023-05-03 15:27:46 +02:00
|
|
|
}
|
2023-05-04 00:48:29 +02:00
|
|
|
// all objects go out of scope
|
|
|
|
|
CHECK (0 == Seg::cnt );
|
|
|
|
|
CHECK (0 == Seg::check);
|
|
|
|
|
CHECK (9 == Seg::idGen);
|
2023-05-03 15:27:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2023-05-04 14:43:40 +02:00
|
|
|
|
2023-05-03 15:27:46 +02:00
|
|
|
/**
|
|
|
|
|
* @test cover all possible cases of splicing an interval
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
verify_standardCases()
|
|
|
|
|
{
|
2023-05-04 14:43:40 +02:00
|
|
|
auto testCase = [](SegL segmentation
|
|
|
|
|
,int startNew
|
|
|
|
|
,int afterNew
|
|
|
|
|
,ExpectString expectedResult)
|
|
|
|
|
{
|
|
|
|
|
OptInt startSpec{startNew},
|
|
|
|
|
afterSpec{afterNew};
|
|
|
|
|
|
|
|
|
|
invokeSplitSplice (segmentation, startSpec, afterSpec);
|
|
|
|
|
CHECK (segmentation == expectedResult);
|
|
|
|
|
CHECK (segmentation.isValid());
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
testCase (SegL{}, -23,24, "├[-100~-23[[-23_24[[24~100[┤"_expect); // simple segment into empty axis
|
|
|
|
|
|
|
|
|
|
testCase (SegL{5,10}, 2,3, "├[-100~2[[2_3[[3~5[[5_10[[10~100[┤"_expect); // smaller segment left spaced off
|
|
|
|
|
testCase (SegL{5,10}, 4,5, "├[-100~4[[4_5[[5_10[[10~100[┤"_expect); // left adjacent
|
|
|
|
|
testCase (SegL{5,10}, 4,8, "├[-100~4[[4_8[[8_10[[10~100[┤"_expect); // left overlapping
|
|
|
|
|
testCase (SegL{5,10}, 5,8, "├[-100~5[[5_8[[8_10[[10~100[┤"_expect); // left inside justified
|
|
|
|
|
testCase (SegL{5,10}, 6,8, "├[-100~5[[5_6[[6_8[[8_10[[10~100[┤"_expect); // smaller segment complete inside
|
|
|
|
|
testCase (SegL{5,10}, 7,10, "├[-100~5[[5_7[[7_10[[10~100[┤"_expect); // right inside justified
|
|
|
|
|
testCase (SegL{5,10}, 9,13, "├[-100~5[[5_9[[9_13[[13~100[┤"_expect); // right overlapping
|
|
|
|
|
testCase (SegL{5,10}, 10,13, "├[-100~5[[5_10[[10_13[[13~100[┤"_expect); // right adjacent
|
|
|
|
|
testCase (SegL{5,10}, 13,23, "├[-100~5[[5_10[[10~13[[13_23[[23~100[┤"_expect); // right spaced off
|
|
|
|
|
|
|
|
|
|
testCase (SegL{5,10}, 5,10, "├[-100~5[[5_10[[10~100[┤"_expect); // identical size replacement
|
|
|
|
|
|
|
|
|
|
testCase (SegL{5,10}, 3,10, "├[-100~3[[3_10[[10~100[┤"_expect); // larger segment right aligned
|
|
|
|
|
testCase (SegL{5,10}, 3,23, "├[-100~3[[3_23[[23~100[┤"_expect); // larger segment overarching
|
|
|
|
|
testCase (SegL{5,10}, 5,23, "├[-100~5[[5_23[[23~100[┤"_expect); // larger segment left aligned
|
2023-05-03 15:27:46 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @test cover special and boundary cases
|
|
|
|
|
*/
|
|
|
|
|
void
|
|
|
|
|
verify_cornerCases()
|
|
|
|
|
{
|
|
|
|
|
UNIMPLEMENTED ("corner cases");
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
LAUNCHER (SplitSplice_test, "unit common");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}} // namespace lib::test
|