mirror of
https://github.com/pdewacht/brlaser
synced 2024-12-27 07:48:21 +01:00
Add some basic tests
This commit is contained in:
parent
bb1ba17b4f
commit
5159844b03
17
Makefile.am
17
Makefile.am
@ -25,3 +25,20 @@ rastertobrlaser_LDADD = $(CUPS_LIBS)
|
|||||||
|
|
||||||
brdecode_SOURCES = \
|
brdecode_SOURCES = \
|
||||||
src/brdecode.cc
|
src/brdecode.cc
|
||||||
|
|
||||||
|
|
||||||
|
TESTS = test_lest test_line test_block
|
||||||
|
check_PROGRAMS = $(TESTS)
|
||||||
|
test_lest_SOURCES = \
|
||||||
|
test/test_lest.cc \
|
||||||
|
test/lest.h
|
||||||
|
test_line_SOURCES = \
|
||||||
|
test/test_line.cc \
|
||||||
|
src/line.h \
|
||||||
|
src/line.cc \
|
||||||
|
test/lest.h
|
||||||
|
test_block_SOURCES = \
|
||||||
|
test/test_block.cc \
|
||||||
|
src/block.h \
|
||||||
|
test/tempfile.h \
|
||||||
|
test/lest.h
|
||||||
|
197
test/lest.hpp
Normal file
197
test/lest.hpp
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
// Copyright 2013 by Martin Moene
|
||||||
|
//
|
||||||
|
// lest is based on ideas by Kevlin Henney, see video at
|
||||||
|
// http://skillsmatter.com/podcast/agile-testing/kevlin-henney-rethinking-unit-testing-in-c-plus-plus
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0:
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
// obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
// this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
// execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
// Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
// do so, all subject to the following:
|
||||||
|
//
|
||||||
|
// The copyright notices in the Software and this entire statement, including
|
||||||
|
// the above license grant, this restriction and the following disclaimer,
|
||||||
|
// must be included in all copies of the Software, in whole or in part, and
|
||||||
|
// all derivative works of the Software, unless such copies or derivative
|
||||||
|
// works are solely in the form of machine-executable object code generated by
|
||||||
|
// a source language processor.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
#ifndef LEST_LEST_H_INCLUDED
|
||||||
|
#define LEST_LEST_H_INCLUDED
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <cstddef>
|
||||||
|
|
||||||
|
#ifndef lest_NO_SHORT_ASSERTION_NAMES
|
||||||
|
# define EXPECT lest_EXPECT
|
||||||
|
# define EXPECT_THROWS lest_EXPECT_THROWS
|
||||||
|
# define EXPECT_THROWS_AS lest_EXPECT_THROWS_AS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define lest_EXPECT( expr ) \
|
||||||
|
try \
|
||||||
|
{ \
|
||||||
|
if ( ! (expr) ) \
|
||||||
|
throw lest::failure{ lest_LOCATION, #expr }; \
|
||||||
|
} \
|
||||||
|
catch( lest::failure const & ) \
|
||||||
|
{ \
|
||||||
|
throw ; \
|
||||||
|
} \
|
||||||
|
catch( std::exception const & e ) \
|
||||||
|
{ \
|
||||||
|
throw lest::unexpected{ lest_LOCATION, #expr, lest::with_message( e.what() ) }; \
|
||||||
|
} \
|
||||||
|
catch(...) \
|
||||||
|
{ \
|
||||||
|
throw lest::unexpected{ lest_LOCATION, #expr, "of unknown type" }; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define lest_EXPECT_THROWS( expr ) \
|
||||||
|
for (;;) \
|
||||||
|
{ \
|
||||||
|
try { lest::serum( expr ); } catch (...) { break; } \
|
||||||
|
throw lest::expected{ lest_LOCATION, #expr }; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define lest_EXPECT_THROWS_AS( expr, excpt ) \
|
||||||
|
for (;;) \
|
||||||
|
{ \
|
||||||
|
try { lest::serum( expr ); } catch ( excpt & ) { break; } catch (...) {} \
|
||||||
|
throw lest::expected{ lest_LOCATION, #expr, lest::of_type( #excpt ) }; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define lest_LOCATION lest::location{__FILE__, __LINE__}
|
||||||
|
|
||||||
|
namespace lest {
|
||||||
|
|
||||||
|
struct test
|
||||||
|
{
|
||||||
|
const std::string name;
|
||||||
|
const std::function<void()> behaviour;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct location
|
||||||
|
{
|
||||||
|
const std::string file;
|
||||||
|
const int line;
|
||||||
|
|
||||||
|
location( std::string file, int line )
|
||||||
|
: file{ file }, line{ line } {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct comment
|
||||||
|
{
|
||||||
|
const std::string text;
|
||||||
|
|
||||||
|
comment( std::string text ) : text{ text } {}
|
||||||
|
explicit operator bool() { return ! text.empty(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct message : std::runtime_error
|
||||||
|
{
|
||||||
|
const std::string kind;
|
||||||
|
const location where;
|
||||||
|
const comment note;
|
||||||
|
|
||||||
|
message( std::string kind, location where, std::string expr, std::string note = "" )
|
||||||
|
: std::runtime_error{ expr }, kind{ kind }, where{ where }, note{ note } {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct failure : message
|
||||||
|
{
|
||||||
|
failure( location where, std::string expr )
|
||||||
|
: message{ "failed", where, expr } {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct expected : message
|
||||||
|
{
|
||||||
|
expected( location where, std::string expr, std::string excpt = "" )
|
||||||
|
: message{ "failed: didn't get exception", where, expr, excpt } {}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct unexpected : message
|
||||||
|
{
|
||||||
|
unexpected( location where, std::string expr, std::string note )
|
||||||
|
: message{ "failed: got unexpected exception", where, expr, note } {}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline bool serum( bool verum ) { return verum; }
|
||||||
|
|
||||||
|
inline std::string with_message( std::string text )
|
||||||
|
{
|
||||||
|
return "with message \"" + text + "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string of_type( std::string text )
|
||||||
|
{
|
||||||
|
return "of type " + text;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string pluralise( int n, std::string text )
|
||||||
|
{
|
||||||
|
return n == 1 ? text : text + "s";
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream & operator<<( std::ostream & os, comment note )
|
||||||
|
{
|
||||||
|
return os << (note ? " " + note.text : "" );
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::ostream & operator<<( std::ostream & os, location where )
|
||||||
|
{
|
||||||
|
#ifdef __GNUG__
|
||||||
|
return os << where.file << ":" << where.line;
|
||||||
|
#else
|
||||||
|
return os << where.file << "(" << where.line << ")";
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void report( std::ostream & os, message const & e, std::string test )
|
||||||
|
{
|
||||||
|
os << e.where << ": " << e.kind << e.note << ": " << test << ": " << e.what() << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t N>
|
||||||
|
int run( test const (&specification)[N], std::ostream & os = std::cout )
|
||||||
|
{
|
||||||
|
int failures = 0;
|
||||||
|
|
||||||
|
for ( auto & testing : specification )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
testing.behaviour();
|
||||||
|
}
|
||||||
|
catch( message const & e )
|
||||||
|
{
|
||||||
|
++failures;
|
||||||
|
report( os, e, testing.name );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( failures > 0 )
|
||||||
|
{
|
||||||
|
os << failures << " out of " << N << " " << pluralise(N, "test") << " failed." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return failures;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace lest
|
||||||
|
|
||||||
|
#endif // LEST_LEST_H_INCLUDED
|
54
test/tempfile.h
Normal file
54
test/tempfile.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
// This file is part of the brlaser printer driver.
|
||||||
|
//
|
||||||
|
// Copyright 2014 Peter De Wachter
|
||||||
|
//
|
||||||
|
// brlaser 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.
|
||||||
|
//
|
||||||
|
// brlaser 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 brlaser. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#ifndef TEMPFILE_H
|
||||||
|
#define TEMPFILE_H
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class tempfile {
|
||||||
|
public:
|
||||||
|
explicit tempfile()
|
||||||
|
: ptr_(0),
|
||||||
|
size_(0),
|
||||||
|
file_(open_memstream(&ptr_, &size_)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
~tempfile() {
|
||||||
|
fclose(file_);
|
||||||
|
free(ptr_);
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *file() {
|
||||||
|
return file_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> data() {
|
||||||
|
if (fflush(file_))
|
||||||
|
return std::vector<uint8_t>();
|
||||||
|
return std::vector<uint8_t>(ptr_, ptr_ + size_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
char *ptr_;
|
||||||
|
size_t size_;
|
||||||
|
FILE *file_;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TEMPFILE_H
|
75
test/test_block.cc
Normal file
75
test/test_block.cc
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
// This file is part of the brlaser printer driver.
|
||||||
|
//
|
||||||
|
// Copyright 2014 Peter De Wachter
|
||||||
|
//
|
||||||
|
// brlaser 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.
|
||||||
|
//
|
||||||
|
// brlaser 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 brlaser. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "lest.hpp"
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <vector>
|
||||||
|
#include "tempfile.h"
|
||||||
|
#include "src/block.h"
|
||||||
|
|
||||||
|
typedef std::vector<uint8_t> vec;
|
||||||
|
|
||||||
|
const lest::test specification[] = {
|
||||||
|
"Block line limit",
|
||||||
|
[] {
|
||||||
|
block b;
|
||||||
|
for (int i = 0; i < 128; ++i) {
|
||||||
|
EXPECT(b.line_fits(1));
|
||||||
|
b.add_line(vec(1));
|
||||||
|
}
|
||||||
|
EXPECT(!b.line_fits(1));
|
||||||
|
},
|
||||||
|
|
||||||
|
"Block size limit",
|
||||||
|
[] {
|
||||||
|
block b;
|
||||||
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
EXPECT(b.line_fits(1000));
|
||||||
|
b.add_line(vec(1000));
|
||||||
|
}
|
||||||
|
EXPECT(!b.line_fits(400));
|
||||||
|
},
|
||||||
|
|
||||||
|
"Flush",
|
||||||
|
[] {
|
||||||
|
block b;
|
||||||
|
{
|
||||||
|
tempfile f;
|
||||||
|
b.flush(f.file());
|
||||||
|
EXPECT(f.data().empty());
|
||||||
|
}
|
||||||
|
for (uint8_t n = 0; n < 10; n += 2) {
|
||||||
|
vec line = {n, static_cast<uint8_t>(n+1)};
|
||||||
|
EXPECT(b.line_fits(line.size()));
|
||||||
|
b.add_line(std::move(line));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
tempfile f;
|
||||||
|
b.flush(f.file());
|
||||||
|
EXPECT(( f.data() == vec{'1','2','w',0,5,0,1,2,3,4,5,6,7,8,9} ));
|
||||||
|
}
|
||||||
|
{
|
||||||
|
tempfile f;
|
||||||
|
b.flush(f.file());
|
||||||
|
EXPECT(f.data().empty());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return lest::run(specification);
|
||||||
|
}
|
291
test/test_lest.cc
Normal file
291
test/test_lest.cc
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
// Copyright 2013 by Martin Moene
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0:
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person or organization
|
||||||
|
// obtaining a copy of the software and accompanying documentation covered by
|
||||||
|
// this license (the "Software") to use, reproduce, display, distribute,
|
||||||
|
// execute, and transmit the Software, and to prepare derivative works of the
|
||||||
|
// Software, and to permit third-parties to whom the Software is furnished to
|
||||||
|
// do so, all subject to the following:
|
||||||
|
//
|
||||||
|
// The copyright notices in the Software and this entire statement, including
|
||||||
|
// the above license grant, this restriction and the following disclaimer,
|
||||||
|
// must be included in all copies of the Software, in whole or in part, and
|
||||||
|
// all derivative works of the Software, unless such copies or derivative
|
||||||
|
// works are solely in the form of machine-executable object code generated by
|
||||||
|
// a source language processor.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||||
|
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||||
|
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||||
|
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
#include "lest.hpp"
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
using namespace lest;
|
||||||
|
|
||||||
|
const lest::test specification[] =
|
||||||
|
{
|
||||||
|
"Function to suppress warning \"expression has no effect\" acts as identity function", []
|
||||||
|
{
|
||||||
|
EXPECT( false == serum( false ) );
|
||||||
|
EXPECT( true == serum( true ) );
|
||||||
|
},
|
||||||
|
|
||||||
|
"Function with_message() returns correct string", []
|
||||||
|
{
|
||||||
|
std::string msg = "Let writing tests become irresistibly easy and attractive.";
|
||||||
|
EXPECT( "with message \"" + msg + "\"" == with_message( msg ) );
|
||||||
|
},
|
||||||
|
|
||||||
|
"Function of_type() returns correct string", []
|
||||||
|
{
|
||||||
|
std::string msg = "this_type";
|
||||||
|
EXPECT( "of type " + msg == of_type( msg ) );
|
||||||
|
},
|
||||||
|
|
||||||
|
"Function pluralise() adds 's' except for 1 item", []
|
||||||
|
{
|
||||||
|
std::string word = "hammer";
|
||||||
|
EXPECT( word == pluralise( 1, word ) );
|
||||||
|
for ( auto i : {0,2,3,4,5,6,7,8,9,10,11,12} )
|
||||||
|
EXPECT( word + "s" == pluralise( i, word ) );
|
||||||
|
},
|
||||||
|
|
||||||
|
"Location constructs properly", []
|
||||||
|
{
|
||||||
|
char const * file = __FILE__; int line = __LINE__;
|
||||||
|
location where{ file, line };
|
||||||
|
EXPECT( file == where.file );
|
||||||
|
EXPECT( line == where.line );
|
||||||
|
},
|
||||||
|
|
||||||
|
"Comment constructs properly", []
|
||||||
|
{
|
||||||
|
std::string text = __FILE__;
|
||||||
|
comment note = text;
|
||||||
|
EXPECT( text == note.text );
|
||||||
|
},
|
||||||
|
|
||||||
|
"Comment converted to bool indicates absence or presence of comment", []
|
||||||
|
{
|
||||||
|
EXPECT( false == bool( comment( "") ) );
|
||||||
|
EXPECT( true == bool( comment("x") ) );
|
||||||
|
},
|
||||||
|
|
||||||
|
"Failure exception type constructs and prints properly", []
|
||||||
|
{
|
||||||
|
std::string name = "test-name";
|
||||||
|
failure msg( location{"filename.cpp", 765}, "expression" );
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
report( os, msg, name );
|
||||||
|
|
||||||
|
#ifndef __GNUG__
|
||||||
|
EXPECT( os.str() == "filename.cpp(765): failed: test-name: expression\n" );
|
||||||
|
#else
|
||||||
|
EXPECT( os.str() == "filename.cpp:765: failed: test-name: expression\n" );
|
||||||
|
#endif
|
||||||
|
},
|
||||||
|
|
||||||
|
"Expected exception type constructs and prints properly", []
|
||||||
|
{
|
||||||
|
std::string name = "test-name";
|
||||||
|
expected msg( location{"filename.cpp", 765}, "expression" );
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
report( os, msg, name );
|
||||||
|
|
||||||
|
#ifndef __GNUG__
|
||||||
|
EXPECT( os.str() == "filename.cpp(765): failed: didn't get exception: test-name: expression\n" );
|
||||||
|
#else
|
||||||
|
EXPECT( os.str() == "filename.cpp:765: failed: didn't get exception: test-name: expression\n" );
|
||||||
|
#endif
|
||||||
|
},
|
||||||
|
|
||||||
|
"Unexpected exception type constructs and prints properly", []
|
||||||
|
{
|
||||||
|
std::string name = "test-name";
|
||||||
|
unexpected msg( location{"filename.cpp", 765}, "expression", "exception-type" );
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
report( os, msg, name );
|
||||||
|
|
||||||
|
#ifndef __GNUG__
|
||||||
|
EXPECT( os.str() == "filename.cpp(765): failed: got unexpected exception exception-type: test-name: expression\n" );
|
||||||
|
#else
|
||||||
|
EXPECT( os.str() == "filename.cpp:765: failed: got unexpected exception exception-type: test-name: expression\n" );
|
||||||
|
#endif
|
||||||
|
},
|
||||||
|
|
||||||
|
"Expect generates no message exception for a succeeding test", []
|
||||||
|
{
|
||||||
|
test pass = { "P", [] { EXPECT( true ); } };
|
||||||
|
|
||||||
|
try { pass.behaviour(); }
|
||||||
|
catch(...) { throw failure(location{__FILE__,__LINE__}, "unexpected error generated"); }
|
||||||
|
},
|
||||||
|
|
||||||
|
"Expect generates a message exception for a failing test", []
|
||||||
|
{
|
||||||
|
test fail = { "F", [] { EXPECT( false ); } };
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
{
|
||||||
|
try { fail.behaviour(); } catch ( message & ) { break; }
|
||||||
|
throw failure(location{__FILE__,__LINE__}, "no error generated");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"Expect succeeds for success (true) and failure (false)", []
|
||||||
|
{
|
||||||
|
test pass[] = {{ "P", [] { EXPECT( true ); } }};
|
||||||
|
test fail[] = {{ "F", [] { EXPECT( false ); } }};
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
|
||||||
|
EXPECT( 0 == run( pass, os ) );
|
||||||
|
EXPECT( 1 == run( fail, os ) );
|
||||||
|
},
|
||||||
|
|
||||||
|
"Expect succeeds for integer comparation", []
|
||||||
|
{
|
||||||
|
test pass [] = {{ "P" , [] { EXPECT( 7 == 7 ); EXPECT( 7 != 8 );
|
||||||
|
EXPECT( 7 >= 6 ); EXPECT( 7 <= 8 );
|
||||||
|
EXPECT( 7 > 6 ); EXPECT( 7 < 8 ); } }};
|
||||||
|
test fail_1[] = {{ "F1", [] { EXPECT( 7 == 8 ); } }};
|
||||||
|
test fail_2[] = {{ "F2", [] { EXPECT( 7 != 7 ); } }};
|
||||||
|
test fail_3[] = {{ "F3", [] { EXPECT( 7 <= 6 ); } }};
|
||||||
|
test fail_4[] = {{ "F4", [] { EXPECT( 7 >= 8 ); } }};
|
||||||
|
test fail_5[] = {{ "F5", [] { EXPECT( 7 < 6 ); } }};
|
||||||
|
test fail_6[] = {{ "F6", [] { EXPECT( 7 > 8 ); } }};
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
|
||||||
|
EXPECT( 0 == run( pass , os ) );
|
||||||
|
EXPECT( 1 == run( fail_1, os ) );
|
||||||
|
EXPECT( 1 == run( fail_2, os ) );
|
||||||
|
EXPECT( 1 == run( fail_3, os ) );
|
||||||
|
EXPECT( 1 == run( fail_4, os ) );
|
||||||
|
EXPECT( 1 == run( fail_5, os ) );
|
||||||
|
EXPECT( 1 == run( fail_6, os ) );
|
||||||
|
},
|
||||||
|
|
||||||
|
"Expect succeeds for string comparation", []
|
||||||
|
{
|
||||||
|
std::string a("a"); std::string b("b");
|
||||||
|
test pass [] = {{ "P" , [=]() { EXPECT( a == a ); EXPECT( a != b );
|
||||||
|
EXPECT( b >= a ); EXPECT( a <= b );
|
||||||
|
EXPECT( b > a ); EXPECT( a < b ); } }};
|
||||||
|
test fail_1[] = {{ "F1", [=]() { EXPECT( a == b ); } }};
|
||||||
|
test fail_2[] = {{ "F2", [=]() { EXPECT( a != a ); } }};
|
||||||
|
test fail_3[] = {{ "F3", [=]() { EXPECT( b <= a ); } }};
|
||||||
|
test fail_4[] = {{ "F4", [=]() { EXPECT( a >= b ); } }};
|
||||||
|
test fail_5[] = {{ "F5", [=]() { EXPECT( b < a ); } }};
|
||||||
|
test fail_6[] = {{ "F6", [=]() { EXPECT( a > b ); } }};
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
|
||||||
|
EXPECT( 0 == run( pass , os ) );
|
||||||
|
EXPECT( 1 == run( fail_1, os ) );
|
||||||
|
EXPECT( 1 == run( fail_2, os ) );
|
||||||
|
EXPECT( 1 == run( fail_3, os ) );
|
||||||
|
EXPECT( 1 == run( fail_4, os ) );
|
||||||
|
EXPECT( 1 == run( fail_5, os ) );
|
||||||
|
EXPECT( 1 == run( fail_6, os ) );
|
||||||
|
},
|
||||||
|
|
||||||
|
"Function run() returns the right failure count", []
|
||||||
|
{
|
||||||
|
test pass [] = {{ "P" , [] { EXPECT( 1==1 ); } }};
|
||||||
|
test fail_1[] = {{ "F1", [] { EXPECT( 0==1 ); } }};
|
||||||
|
test fail_3[] = {{ "F1", [] { EXPECT( 0==1 ); } },
|
||||||
|
{ "F2", [] { EXPECT( 0==1 ); } },
|
||||||
|
{ "F3", [] { EXPECT( 0==1 ); } },};
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
|
||||||
|
EXPECT( 0 == run( pass , os ) );
|
||||||
|
EXPECT( 1 == run( fail_1, os ) );
|
||||||
|
EXPECT( 3 == run( fail_3, os ) );
|
||||||
|
},
|
||||||
|
|
||||||
|
"Expect succeeds with an unexpected standard exception", []
|
||||||
|
{
|
||||||
|
std::string text = "hello-world";
|
||||||
|
test pass[] = {{ "P", [=]() { EXPECT( (throw std::runtime_error(text), true) ); } }};
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
|
||||||
|
EXPECT( 1 == run( pass, os ) );
|
||||||
|
EXPECT( std::string::npos != os.str().find(text) );
|
||||||
|
},
|
||||||
|
|
||||||
|
"Expect succeeds with an unexpected non-standard exception", []
|
||||||
|
{
|
||||||
|
test pass[] = {{ "P", [] { EXPECT( (throw 77, true) ); } }};
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
|
||||||
|
EXPECT( 1 == run( pass, os ) );
|
||||||
|
},
|
||||||
|
|
||||||
|
"Expect_throws succeeds with an expected standard exception", []
|
||||||
|
{
|
||||||
|
std::string text = "hello-world";
|
||||||
|
test pass[] = {{ "P", [=]() { EXPECT_THROWS( (throw std::runtime_error(text), true) ); } }};
|
||||||
|
test fail[] = {{ "F", [ ]() { EXPECT_THROWS( true ); } }};
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
|
||||||
|
EXPECT( 0 == run( pass, os ) );
|
||||||
|
EXPECT( 1 == run( fail, os ) );
|
||||||
|
},
|
||||||
|
|
||||||
|
"Expect_throws succeeds with an expected non-standard exception", []
|
||||||
|
{
|
||||||
|
test pass[] = {{ "P", [] { EXPECT_THROWS( (throw 77, true) ); } }};
|
||||||
|
test fail[] = {{ "F", [] { EXPECT_THROWS( true ); } }};
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
|
||||||
|
EXPECT( 0 == run( pass, os ) );
|
||||||
|
EXPECT( 1 == run( fail, os ) );
|
||||||
|
},
|
||||||
|
|
||||||
|
"Expect_throws_as succeeds with a specific expected standard exception", []
|
||||||
|
{
|
||||||
|
test pass[] = {{ "P", [] { EXPECT_THROWS_AS( (throw std::bad_alloc(), true), std::bad_alloc ); } }};
|
||||||
|
test fail[] = {{ "F", [] { EXPECT_THROWS_AS( (throw std::bad_alloc(), true), std::runtime_error ); } }};
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
|
||||||
|
EXPECT( 0 == run( pass, os ) );
|
||||||
|
EXPECT( 1 == run( fail, os ) );
|
||||||
|
},
|
||||||
|
|
||||||
|
"Expect_throws_as succeeds with a specific expected non-standard exception", []
|
||||||
|
{
|
||||||
|
test pass[] = {{ "P", [] { EXPECT_THROWS_AS( (throw 77, true), int ); } }};
|
||||||
|
test fail[] = {{ "F", [] { EXPECT_THROWS_AS( (throw 77, true), std::runtime_error ); } }};
|
||||||
|
|
||||||
|
std::ostringstream os;
|
||||||
|
|
||||||
|
EXPECT( 0 == run( pass, os ) );
|
||||||
|
EXPECT( 1 == run( fail, os ) );
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return lest::run( specification );
|
||||||
|
}
|
||||||
|
|
||||||
|
// cl -nologo -Wall -EHsc test_lest.cpp && test_lest
|
||||||
|
// g++ -Wall -Wextra -Weffc++ -std=c++11 -o test_lest.exe test_lest.cpp && test_lest
|
||||||
|
|
150
test/test_line.cc
Normal file
150
test/test_line.cc
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
// This file is part of the brlaser printer driver.
|
||||||
|
//
|
||||||
|
// Copyright 2014 Peter De Wachter
|
||||||
|
//
|
||||||
|
// brlaser 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.
|
||||||
|
//
|
||||||
|
// brlaser 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 brlaser. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
#include "lest.hpp"
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <vector>
|
||||||
|
#include "src/line.h"
|
||||||
|
|
||||||
|
typedef std::vector<uint8_t> vec;
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t sub(uint8_t offset, uint8_t count) {
|
||||||
|
assert(offset < 16);
|
||||||
|
assert(count < 8);
|
||||||
|
return (offset << 3) | count;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t rep(uint8_t offset, uint8_t count) {
|
||||||
|
assert(offset < 4);
|
||||||
|
assert(count < 32);
|
||||||
|
return 128 | (offset << 5) | count;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const lest::test specification[] = {
|
||||||
|
"Don't crash on zero-length lines",
|
||||||
|
[] {
|
||||||
|
EXPECT(( encode_line(vec{}) == vec{0xFF} ));
|
||||||
|
EXPECT(( encode_line(vec{}, vec{}) == vec{0xFF} ));
|
||||||
|
},
|
||||||
|
|
||||||
|
"Encoding an initial blank line",
|
||||||
|
[] {
|
||||||
|
EXPECT(( encode_line(vec{0,0,0}) == vec{0xFF} ));
|
||||||
|
},
|
||||||
|
|
||||||
|
"Encoding an initial non-blank line",
|
||||||
|
[] {
|
||||||
|
EXPECT(( encode_line(vec{1,2,3}) == (vec{1,sub(0,2),1,2,3}) ));
|
||||||
|
},
|
||||||
|
|
||||||
|
"Encoding a (non-initial) blank line",
|
||||||
|
[] {
|
||||||
|
EXPECT(( encode_line(vec{0,0,0}, vec{1,2,3}) == vec{0xFF} ));
|
||||||
|
},
|
||||||
|
|
||||||
|
"Encoding a repeated line",
|
||||||
|
[] {
|
||||||
|
EXPECT(( encode_line(vec{1,2,3}, vec{1,2,3}) == vec{0} ));
|
||||||
|
},
|
||||||
|
|
||||||
|
"Using a subsitute command",
|
||||||
|
[] {
|
||||||
|
EXPECT(( encode_line(vec{0,0,1,2,3,0,0}, vec(7)) == vec{1,sub(2,2),1,2,3} ));
|
||||||
|
},
|
||||||
|
|
||||||
|
"Using a repeat command",
|
||||||
|
[] {
|
||||||
|
EXPECT(( encode_line(vec{0,0,1,1,0,0}, vec(6)) == vec{1,rep(2,0),1} ));
|
||||||
|
},
|
||||||
|
|
||||||
|
"Repeat command followed by substitute command",
|
||||||
|
[] {
|
||||||
|
EXPECT(( encode_line(vec{1,1,1,2,3}, vec(5)) == vec{2,rep(0,1),1,sub(0,1),2,3} ));
|
||||||
|
},
|
||||||
|
|
||||||
|
"Substitute comand followed by repeat command",
|
||||||
|
[] {
|
||||||
|
EXPECT(( encode_line(vec{3,2,1,1,1}, vec(5)) == vec{2,sub(0,1),3,2,rep(0,1),1} ));
|
||||||
|
},
|
||||||
|
|
||||||
|
"Substitute with an unmodified byte in the middle",
|
||||||
|
[] {
|
||||||
|
EXPECT(( encode_line(vec{1,2,3,0,1,2,3}, vec(7)) == vec{1,sub(0,6),1,2,3,0,1,2,3} ));
|
||||||
|
},
|
||||||
|
|
||||||
|
"Substitue with two unmodified bytes in the middle",
|
||||||
|
[] {
|
||||||
|
EXPECT(( encode_line(vec{1,2,3,0,0,1,2,3}, vec(8)) == vec{2,sub(0,2),1,2,3,sub(2,2),1,2,3} ));
|
||||||
|
},
|
||||||
|
|
||||||
|
"Repeat with an unmodified byte in the middle",
|
||||||
|
[] {
|
||||||
|
EXPECT(( encode_line(vec{1,1,1,0,1,1,1}, vec(7)) == vec{2,rep(0,1),1,rep(1,1),1} ));
|
||||||
|
},
|
||||||
|
|
||||||
|
"254 edits needed for a single line",
|
||||||
|
[] {
|
||||||
|
vec line, result;
|
||||||
|
for (int i = 0; i < 254; ++i)
|
||||||
|
line.insert(line.end(), {0,0,1});
|
||||||
|
result.push_back(254);
|
||||||
|
for (int i = 0; i < 254; ++i)
|
||||||
|
result.insert(result.end(), {sub(2,0),1});
|
||||||
|
EXPECT(( encode_line(line, vec(line.size())) == result ));
|
||||||
|
},
|
||||||
|
|
||||||
|
"Give up if more than 254 edits needed...",
|
||||||
|
[] {
|
||||||
|
vec line, result;
|
||||||
|
for (int i = 0; i < 255; ++i)
|
||||||
|
line.insert(line.end(), {0,0,1});
|
||||||
|
result.push_back(254);
|
||||||
|
for (int i = 0; i < 253; ++i)
|
||||||
|
result.insert(result.end(), {sub(2,0),1});
|
||||||
|
result.insert(result.end(), {sub(2,3),1,0,0,1});
|
||||||
|
EXPECT(( encode_line(line, vec(line.size())) == result ));
|
||||||
|
},
|
||||||
|
|
||||||
|
"Repeat command with overflow bytes",
|
||||||
|
[] {
|
||||||
|
vec line(3, 0);
|
||||||
|
line.insert(line.end(), 512, 1);
|
||||||
|
vec ref(line.size(), 0);
|
||||||
|
vec expected{1,rep(3,31),0,255,224,1};
|
||||||
|
EXPECT(encode_line(line, ref) == expected);
|
||||||
|
},
|
||||||
|
|
||||||
|
"Substitute command with overflow bytes",
|
||||||
|
[] {
|
||||||
|
vec expected{1,sub(15,7),255,0,255,237};
|
||||||
|
vec line(270, 0);
|
||||||
|
for (int i = 0; i < 250; ++i) {
|
||||||
|
expected.insert(expected.end(), {1,2});
|
||||||
|
line.insert(line.end(), {1,2});
|
||||||
|
}
|
||||||
|
vec ref(line.size(), 0);
|
||||||
|
EXPECT(encode_line(line, ref) == expected);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return lest::run(specification);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user