C++ (Qt) void parseData( const QString &input, QList<QVector3D> &points, QList<QVector3D> &indexes ) throw(EmptyInput, BadLine);
C++ (Qt)#include <QString>#include <QtTest>#include "Parser.h"#include <QVector3D>#include "EmptyInput.h"#include "BadLine.h" enum ExceptionType { noException, emptyInput, badLine}; class CubeFromBlenderTests : public QObject { Q_OBJECT public: CubeFromBlenderTests( ); static inline bool qFuzzyCompare( double p1, double p2, double delta ) { return ( qAbs( p1 - p2 ) <= delta * qMin( qAbs( p1 ), qAbs( p2 ) )); } privateQ_SLOTS: // Right result void testCase1_data( ); void testCase1( ); // Input string is empty void testCase2_data( ); void testCase2( );}; CubeFromBlenderTests::CubeFromBlenderTests( ) {} void CubeFromBlenderTests::testCase1_data( ) { QTest::addColumn<QString>("input"); QTest::addColumn<QList<QVector3D> >("expected_points"); QTest::addColumn<QList<QVector3D> >("expected_indexes"); QTest::addColumn<bool>("isExpectedException"); bool exception = true; bool no_exception = false; QString input = QString( "# Blender v2.68 (sub 0) OBJ File: ''\n" "# www.blender.org\n" "o Cube\n" "v 1.000000 1.000001 -0.999999\n" "v 1.000000 -0.999999 -1.000001\n" "v -1.000000 -0.999999 -1.000001\n" "v -1.000000 1.000001 -0.999999\n" "v 1.000000 0.999999 1.000001\n" "v 0.999999 -1.000001 0.999999\n" "v -1.000000 -1.000000 0.999999\n" "v -1.000000 0.999999 1.000001\n" "s off\n" "f 1 2 4\n" "f 5 8 6\n" "f 1 5 2\n" "f 2 6 3\n" "f 3 7 4\n" "f 5 1 8\n" "f 2 3 4\n" "f 8 7 6\n" "f 5 6 2\n" "f 6 7 3\n" "f 7 8 4\n" "f 1 4 8\n" ); QList<QVector3D> expected_points; QVector3D point; // 1 point.setX( 1.000000 ); point.setY( 1.000001 ); point.setZ( -0.999999 ); expected_points.append( point ); // 2 point.setX( 1.000000 ); point.setY( -0.999999 ); point.setZ( -1.000001 ); expected_points.append( point ); // 3 point.setX( -1.000000 ); point.setY( -0.999999 ); point.setZ( -1.000001 ); expected_points.append( point ); // 4 point.setX( -1.000000 ); point.setY( 1.000001 ); point.setZ( -0.999999 ); expected_points.append( point ); // 5 point.setX( 1.000000 ); point.setY( 0.999999 ); point.setZ( 1.000001 ); expected_points.append( point ); // 6 point.setX( 0.999999 ); point.setY( -1.000001 ); point.setZ( 0.999999 ); expected_points.append( point ); // 7 point.setX( -1.000000 ); point.setY( -1.000000 ); point.setZ( 0.999999 ); expected_points.append( point ); // 8 point.setX( -1.000000 ); point.setY( 0.999999 ); point.setZ( 1.000001 ); expected_points.append( point ); QList<QVector3D> expected_indexes; QVector3D indexes; // 1 indexes.setX( 1.0 ); indexes.setY( 2.0 ); indexes.setZ( 4.0 ); expected_indexes.append( indexes ); // 2 indexes.setX( 5.0 ); indexes.setY( 8.0 ); indexes.setZ( 6.0 ); expected_indexes.append( indexes ); // 3 indexes.setX( 1.0 ); indexes.setY( 5.0 ); indexes.setZ( 2.0 ); expected_indexes.append( indexes ); // 4 indexes.setX( 2.0 ); indexes.setY( 6.0 ); indexes.setZ( 3.0 ); expected_indexes.append( indexes ); // 5 indexes.setX( 3.0 ); indexes.setY( 7.0 ); indexes.setZ( 4.0 ); expected_indexes.append( indexes ); // 6 indexes.setX( 5.0 ); indexes.setY( 1.0 ); indexes.setZ( 8.0 ); expected_indexes.append( indexes ); // 7 indexes.setX( 2.0 ); indexes.setY( 3.0 ); indexes.setZ( 4.0 ); expected_indexes.append( indexes ); // 8 indexes.setX( 8.0 ); indexes.setY( 7.0 ); indexes.setZ( 6.0 ); expected_indexes.append( indexes ); // 9 indexes.setX( 5.0 ); indexes.setY( 6.0 ); indexes.setZ( 2.0 ); expected_indexes.append( indexes ); // 10 indexes.setX( 6.0 ); indexes.setY( 7.0 ); indexes.setZ( 3.0 ); expected_indexes.append( indexes ); // 11 indexes.setX( 7.0 ); indexes.setY( 8.0 ); indexes.setZ( 4.0 ); expected_indexes.append( indexes ); // 12 indexes.setX( 1.0 ); indexes.setY( 4.0 ); indexes.setZ( 8.0 ); expected_indexes.append( indexes ); QTest::newRow( "parseData_01" ) << input << expected_points << expected_indexes << no_exception;} void CubeFromBlenderTests::testCase1( ) { QFETCH( QString, input ); QFETCH( QList<QVector3D>, expected_points ); QFETCH( QList<QVector3D>, expected_indexes ); QFETCH( bool, isExpectedException ); Parser parser; QList<QVector3D> points; QList<QVector3D> indexes; try { parser.parseData( input, points, indexes ); } catch ( const LogicError& e ) { QVERIFY2( false, "Exception was occur." ); } catch ( ... ) { QVERIFY2( false, "Uncaught exception." ); } double delta = 0.0001; bool result = false; QString msg; // Check size of points and indexes QCOMPARE( points.size( ), expected_points.size( ) ); QCOMPARE( indexes.size( ), expected_indexes.size( ) ); // Check points for ( std::size_t i = 0; i < points.size( ); ++i ) { // Check x result = qFuzzyCompare( points[i].x( ), expected_points[i].x( ), delta ); msg = QString( "\nActual: %1" "\nExpected: %2" "\nDelta: %3" ).arg( points[i].x( ) ).arg( expected_points[i].x( ) ).arg( delta ); QVERIFY2( result, msg.toStdString( ).c_str( ) ); // Check y result = qFuzzyCompare( points[i].y( ), expected_points[i].y( ), delta ); msg = QString( "\nActual: %1" "\nExpected: %2" "\nDelta: %3" ).arg( points[i].y( ) ).arg( expected_points[i].y( ) ).arg( delta ); QVERIFY2( result, msg.toStdString( ).c_str( ) ); // Check z result = qFuzzyCompare( points[i].z( ), expected_points[i].z( ), delta ); msg = QString( "\nActual: %1" "\nExpected: %2" "\nDelta: %3" ).arg( points[i].z( ) ).arg( expected_points[i].z( ) ).arg( delta ); QVERIFY2( result, msg.toStdString( ).c_str( ) ); } // Check indexes int actualIndex = 0; int expectedIndex = 0; for ( std::size_t i = 0; i < indexes.size( ); ++i ) { // 1 actualIndex = (int) indexes[i].x( ); expectedIndex = (int) indexes[i].x( ); QCOMPARE( actualIndex, expectedIndex ); // 2 actualIndex = (int) indexes[i].y( ); expectedIndex = (int) indexes[i].y( ); QCOMPARE( actualIndex, expectedIndex ); // 3 actualIndex = (int) indexes[i].z( ); expectedIndex = (int) indexes[i].z( ); QCOMPARE( actualIndex, expectedIndex ); }} void CubeFromBlenderTests::testCase2_data( ) { QTest::addColumn<QString>("input"); QTest::addColumn<QList<QVector3D> >("expected_points"); QTest::addColumn<QList<QVector3D> >("expected_indexes"); QTest::addColumn<int>("exceptionType"); QString input = QString( "" ); QList<QVector3D> expected_points; QList<QVector3D> expected_indexes; ExceptionType exceptionType; exceptionType = emptyInput; QTest::newRow( "Empty input" ) << input << expected_points << expected_indexes << (int) exceptionType; input = QString( "# Blender v2.68 (sub 0) OBJ File: ''\n" "# www.blender.org\n" "o Cube\n" "v 1.000w000 1.000001 -0.999999\n" "v 1.000000 -0.999999 -1.000001\n" "v -1.000000 -0.999999 -1.000001\n" "v -1.000000 1.000001 -0.999999\n" "v 1.000000 0.999999 1.000001\n" "v 0.999999 -1.000001 0.999999\n" "v -1.000000 -1.000000 0.999999\n" "v -1.000000 0.999999 1.000001\n" "s off\n" "f 1 2 4\n" "f 5 8 6\n" "f 1 5 2\n" "f 2 6 3\n" "f 3 7 4\n" "f 5 1 8\n" "f 2 3 4\n" "f 8 7 6\n" "f 5 6 2\n" "f 6 7 3\n" "f 7 8 4\n" "f 1 4 8\n" ); exceptionType = badLine; QTest::newRow( "Bad vertex" ) << input << expected_points << expected_indexes << (int) exceptionType; input = QString( "# Blender v2.68 (sub 0) OBJ File: ''\n" "# www.blender.org\n" "o Cube\n" "v 1.000000 1.000001 -0.999999\n" "v 1.000000 -0.999999 -1.000001\n" "v -1.000000 -0.999999 -1.000001\n" "v -1.000000 1.000001 -0.999999\n" "v 1.000000 0.999999 1.000001\n" "v 0.999999 -1.000001 0.999999\n" "v -1.000000 -1.000000 0.999999\n" "v -1.000000 0.999999 1.000001\n" "s off\n" "f 1w 2 4\n" "f 5 8 6\n" "f 1 5 2\n" "f 2 6 3\n" "f 3 7 4\n" "f 5 1 8\n" "f 2 3 4\n" "f 8 7 6\n" "f 5 6 2\n" "f 6 7 3\n" "f 7 8 4\n" "f 1 4 8\n" ); exceptionType = badLine; QTest::newRow( "Bad index" ) << input << expected_points << expected_indexes << (int) exceptionType; input = QString( "# Blender v2.68 (sub 0) OBJ File: ''\n" "# www.blender.org\n" "o Cube\n" "v 1.000000 1.000001 -0.999999\n" "v -0.999999 -1.000001\n" "v -1.000000 -0.999999 -1.000001\n" "v -1.000000 1.000001 -0.999999\n" "v 1.000000 0.999999 1.000001\n" "v 0.999999 -1.000001 0.999999\n" "v -1.000000 -1.000000 0.999999\n" "v -1.000000 0.999999 1.000001\n" "s off\n" "f 1 2 4\n" "f 5 8 6\n" "f 1 5 2\n" "f 2 6 3\n" "f 3 7 4\n" "f 5 1 8\n" "f 2 3 4\n" "f 8 7 6\n" "f 5 6 2\n" "f 6 7 3\n" "f 7 8 4\n" "f 1 4 8\n" ); exceptionType = badLine; QTest::newRow( "Deleted vertex" ) << input << expected_points << expected_indexes << (int) exceptionType; input = QString( "# Blender v2.68 (sub 0) OBJ File: ''\n" "# www.blender.org\n" "o Cube\n" "v 1.000000 1.000001 -0.999999\n" "v 1.000000 -0.999999 -1.000001\n" "v -1.000000 -0.999999 -1.000001\n" "v -1.000000 1.000001 -0.999999\n" "v 1.000000 0.999999 1.000001\n" "v 0.999999 -1.000001 0.999999\n" "v -1.000000 -1.000000 0.999999\n" "v -1.000000 0.999999 1.000001\n" "s off\n" "f 1 2 4\n" "f 8 6\n" "f 1 5 2\n" "f 2 6 3\n" "f 3 7 4\n" "f 5 1 8\n" "f 2 3 4\n" "f 8 7 6\n" "f 5 6 2\n" "f 6 7 3\n" "f 7 8 4\n" "f 1 4 8\n" ); exceptionType = badLine; QTest::newRow( "Deleted index" ) << input << expected_points << expected_indexes << (int) exceptionType;} void CubeFromBlenderTests::testCase2( ) { QFETCH( QString, input ); QFETCH( QList<QVector3D>, expected_points ); QFETCH( QList<QVector3D>, expected_indexes ); QFETCH( int, exceptionType ); Parser parser; QList<QVector3D> points; QList<QVector3D> indexes; try { parser.parseData( input, points, indexes ); if (exceptionType != noException) { QVERIFY2( false, "There is no exception." ); } else { QVERIFY2( true, "" ); } } catch ( const LogicError& e ) { switch( exceptionType ) { case noException: QVERIFY2( false, "Exception was occur." ); break; case emptyInput: if ( std::string("Input argument is empty.") == std::string( e.what() ) ) { QVERIFY2( true, "" ); } else { QVERIFY2( false, "We expecte EmptyInput exception." ); } break; case badLine: if ( std::string("Error string \"v 1.000w000 1.000001 -0.999999\" at line 3") == std::string( e.what() ) || std::string("Error string \"f 1w 2 4\" at line 12") == std::string( e.what() ) || std::string("Error string \"v -0.999999 -1.000001\" at line 4") == std::string( e.what() ) || std::string("Error string \"f 8 6\" at line 13") == std::string( e.what() ) ) { QVERIFY2( true, "" ); } else { QVERIFY2( false, "We expecte BadLine exception." ); } break; default: QVERIFY2( false, "We don't expecte this exception." ); break; } } catch ( ... ) { QVERIFY2( false, "Uncaught exception." ); }} QTEST_APPLESS_MAIN( CubeFromBlenderTests ) #include "tst_CubeFromBlenderTests.moc"
C++ (Qt) QList<QVector3D> points; QList<QVector3D> indexes; Parser parser; try { parser.parseData( all, points, indexes ); } catch ( const LogicError &e ) { QMessageBox::information( this, tr( "Information" ), QString::fromUtf8( e.what() ) ); return; } catch ( ... ) { QMessageBox::information( this, tr( "Information" ), tr( "Uncaught exception." ) ); return; }
C++ (Qt)#ifndef EMPTYINPUT_H#define EMPTYINPUT_H #include "LogicError.h" class EmptyInput : public LogicError {public: EmptyInput( std::string argument ) : LogicError( argument ) { m_message = "Input argument is empty."; }}; #endif // EMPTYINPUT_H
C++ (Qt)#ifndef BADLINE_H#define BADLINE_H #include "LogicError.h"#include <sstream> class BadLine : public LogicError {public: BadLine( const std::string &line, int lineNum ) : LogicError( line ), m_lineNum( lineNum ) { std::ostringstream ostr; ostr << "Error string \"" << line << "\" at line " << lineNum; m_message = ostr.str( ); } protected: int m_lineNum;}; #endif // BADLINE_H
C++ (Qt)#ifndef PARSER_H#define PARSER_H #include <QList>#include <QVector3D>#include <QString>#include "EmptyInput.h"#include "BadLine.h" class Parser {public: void parseData( const QString &input, QList<QVector3D> &points, QList<QVector3D> &indexes ) throw(EmptyInput, BadLine);}; #endif // PARSER_H
C++ (Qt)#include "Parser.h"#include <QStringList> void Parser::parseData( const QString &input, QList<QVector3D> &points, QList<QVector3D> &indexes ) throw(EmptyInput, BadLine) { if ( input.isEmpty( ) ) { throw( EmptyInput( input.toStdString( ) ) ); } QStringList list = input.split( "\n" ); for ( std::size_t i = 0; i < list.size( ); ++i ) { // Poitns if ( list[i][0] == QChar( 'v' ) ) { QStringList listForPoints = list[i].split( " " ); if ( listForPoints.size( ) == 4 ) { bool ok; float x = listForPoints[1].toFloat( &ok ); if ( !ok ) { throw( BadLine( list[i].toStdString(), i ) ); } float y = listForPoints[2].toFloat( &ok ); if ( !ok ) { throw( BadLine( list[i].toStdString(), i ) ); } float z = listForPoints[3].toFloat( &ok ); if ( !ok ) { throw( BadLine( list[i].toStdString(), i ) ); } points.append( QVector3D( x, y, z ) ); } else { throw( BadLine( list[i].toStdString(), i ) ); } } // Indexes if ( list[i][0] == QChar( 'f' ) ) { QStringList listForIndexes = list[i].split( " " ); if ( listForIndexes.size( ) == 4 ) { bool ok; float x = listForIndexes[1].toFloat( &ok ); if ( !ok ) { throw( BadLine( list[i].toStdString(), i ) ); } float y = listForIndexes[2].toFloat( &ok ); if ( !ok ) { throw( BadLine( list[i].toStdString(), i ) ); } float z = listForIndexes[3].toFloat( &ok ); if ( !ok ) { throw( BadLine( list[i].toStdString(), i ) ); } indexes.append( QVector3D( x, y, z ) ); } else { throw( BadLine( list[i].toStdString(), i ) ); } } }}
C++ (Qt)#ifndef LOGICERROR_H#define LOGICERROR_H #include <stdexcept> class LogicError : public std::logic_error {public: LogicError( std::string argument ) : std::logic_error( "" ), m_argument( argument ) { } virtual const char *what( ) const throw () { return m_message.c_str( ); } virtual ~LogicError( ) throw () { } protected: std::string m_argument; std::string m_message;}; #endif // LOGICERROR_H
C++ (Qt) bool ok; float x = listForPoints[1].toFloat( &ok ); if ( !ok ) { throw( BadLine( list[i].toStdString(), i ) ); } float y = listForPoints[2].toFloat( &ok ); if ( !ok ) { throw( BadLine( list[i].toStdString(), i ) ); } float z = listForPoints[3].toFloat( &ok ); if ( !ok ) { throw( BadLine( list[i].toStdString(), i ) ); } points.append( QVector3D( x, y, z ) ); } else { throw( BadLine( list[i].toStdString(), i ) ); }
C++ (Qt)const QStringList & v = listForPoints;points.append( QVector3D( Read1V(v[1], Read1V(v[2]), Read1V(v[3]) ) );