Пример #1
0
void OctreeTests::propertyFlagsTests() {
    qDebug() << "******************************************************************************************";
    qDebug() << "OctreeTests::propertyFlagsTests()";

    {    
        qDebug() << "Test 1: ModelProperties: using setHasProperty()";
        ModelPropertyFlags props;
        props.setHasProperty(PROP_VISIBLE);
        props.setHasProperty(PROP_POSITION);
        props.setHasProperty(PROP_RADIUS);
        props.setHasProperty(PROP_MODEL_URL);
        props.setHasProperty(PROP_ROTATION);
    
        QByteArray encoded = props.encode();

        qDebug() << "encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
    }

    {    
        qDebug() << "Test 2: ParticlePropertyFlags: using setHasProperty()";
        ParticlePropertyFlags props2;
        props2.setHasProperty(PARTICLE_PROP_VISIBLE);
        props2.setHasProperty(PARTICLE_PROP_ANIMATION_URL);
        props2.setHasProperty(PARTICLE_PROP_ANIMATION_FPS);
        props2.setHasProperty(PARTICLE_PROP_ANIMATION_FRAME_INDEX);
        props2.setHasProperty(PARTICLE_PROP_ANIMATION_PLAYING);
        props2.setHasProperty(PARTICLE_PROP_PAUSE_SIMULATION);
    
        QByteArray encoded = props2.encode();

        qDebug() << "encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());

        qDebug() << "Test 2b: remove flag with setHasProperty() PARTICLE_PROP_PAUSE_SIMULATION";

        props2.setHasProperty(PARTICLE_PROP_PAUSE_SIMULATION, false);
    
        encoded = props2.encode();

        qDebug() << "encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());

    }

    {    
        qDebug() << "Test 3: ParticlePropertyFlags: using | operator";
        ParticlePropertyFlags props;

        props = ParticlePropertyFlags(PARTICLE_PROP_VISIBLE) 
                    | ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_URL)
                    | ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FPS)
                    | ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FRAME_INDEX)
                    | ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_PLAYING) 
                    | ParticlePropertyFlags(PARTICLE_PROP_PAUSE_SIMULATION);
    
        QByteArray encoded = props.encode();

        qDebug() << "encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());

        qDebug() << "Test 3b: remove flag with -= PARTICLE_PROP_PAUSE_SIMULATION";
        props -= PARTICLE_PROP_PAUSE_SIMULATION;
    
        encoded = props.encode();
    
        qDebug() << "encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
    }

    {    
        qDebug() << "Test 3c: ParticlePropertyFlags: using |= operator";
        ParticlePropertyFlags props;

        props |= PARTICLE_PROP_VISIBLE;
        props |= PARTICLE_PROP_ANIMATION_URL;
        props |= PARTICLE_PROP_ANIMATION_FPS;
        props |= PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        props |= PARTICLE_PROP_ANIMATION_PLAYING;
        props |= PARTICLE_PROP_PAUSE_SIMULATION;

        QByteArray encoded = props.encode();

        qDebug() << "encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
    }

    {    
        qDebug() << "Test 4: ParticlePropertyFlags: using + operator";
        ParticlePropertyFlags props;

        props = ParticlePropertyFlags(PARTICLE_PROP_VISIBLE) 
                    + ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_URL)
                    + ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FPS)
                    + ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FRAME_INDEX)
                    + ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_PLAYING) 
                    + ParticlePropertyFlags(PARTICLE_PROP_PAUSE_SIMULATION);
    
        QByteArray encoded = props.encode();

        qDebug() << "encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
    }

    {    
        qDebug() << "Test 4b: ParticlePropertyFlags: using += operator";
        ParticlePropertyFlags props;

        props += PARTICLE_PROP_VISIBLE;
        props += PARTICLE_PROP_ANIMATION_URL;
        props += PARTICLE_PROP_ANIMATION_FPS;
        props += PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        props += PARTICLE_PROP_ANIMATION_PLAYING;
        props += PARTICLE_PROP_PAUSE_SIMULATION;
    
        QByteArray encoded = props.encode();

        qDebug() << "encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
    }

    {    
        qDebug() << "Test 5: ParticlePropertyFlags: using = ... << operator";
        ParticlePropertyFlags props;

        props = ParticlePropertyFlags(PARTICLE_PROP_VISIBLE) 
                    << ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_URL)
                    << ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FPS)
                    << ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FRAME_INDEX)
                    << ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_PLAYING) 
                    << ParticlePropertyFlags(PARTICLE_PROP_PAUSE_SIMULATION);
    
        QByteArray encoded = props.encode();

        qDebug() << "encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
    }

    {
        qDebug() << "Test 5b: ParticlePropertyFlags: using <<= operator";
        ParticlePropertyFlags props;

        props <<= PARTICLE_PROP_VISIBLE;
        props <<= PARTICLE_PROP_ANIMATION_URL;
        props <<= PARTICLE_PROP_ANIMATION_FPS;
        props <<= PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        props <<= PARTICLE_PROP_ANIMATION_PLAYING;
        props <<= PARTICLE_PROP_PAUSE_SIMULATION;
    
        QByteArray encoded = props.encode();

        qDebug() << "encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
    }

    {
        qDebug() << "Test 5c: ParticlePropertyFlags: using << enum operator";
        ParticlePropertyFlags props;

        props << PARTICLE_PROP_VISIBLE;
        props << PARTICLE_PROP_ANIMATION_URL;
        props << PARTICLE_PROP_ANIMATION_FPS;
        props << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        props << PARTICLE_PROP_ANIMATION_PLAYING;
        props << PARTICLE_PROP_PAUSE_SIMULATION;

        QByteArray encoded = props.encode();

        qDebug() << "encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
    }

    {
        qDebug() << "Test 5d: ParticlePropertyFlags: using << flags operator ";
        ParticlePropertyFlags props;
        ParticlePropertyFlags props2;

        props << PARTICLE_PROP_VISIBLE;
        props << PARTICLE_PROP_ANIMATION_URL;
        props << PARTICLE_PROP_ANIMATION_FPS;

        props2 << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        props2 << PARTICLE_PROP_ANIMATION_PLAYING;
        props2 << PARTICLE_PROP_PAUSE_SIMULATION;

        props << props2;

        QByteArray encoded = props.encode();

        qDebug() << "encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
    }
  
    {
        qDebug() << "Test 6: ParticlePropertyFlags comparison";
        ParticlePropertyFlags propsA;

        qDebug() << "!propsA:" << (!propsA) << "{ expect true }";

        propsA << PARTICLE_PROP_VISIBLE;
        propsA << PARTICLE_PROP_ANIMATION_URL;
        propsA << PARTICLE_PROP_ANIMATION_FPS;
        propsA << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        propsA << PARTICLE_PROP_ANIMATION_PLAYING;
        propsA << PARTICLE_PROP_PAUSE_SIMULATION;

        qDebug() << "!propsA:" << (!propsA) << "{ expect false }";

        ParticlePropertyFlags propsB;
        qDebug() << "!propsB:" << (!propsB) << "{ expect true }";


        propsB << PARTICLE_PROP_VISIBLE;
        propsB << PARTICLE_PROP_ANIMATION_URL;
        propsB << PARTICLE_PROP_ANIMATION_FPS;
        propsB << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        propsB << PARTICLE_PROP_ANIMATION_PLAYING;
        propsB << PARTICLE_PROP_PAUSE_SIMULATION;

        qDebug() << "!propsB:" << (!propsB) << "{ expect false }";

        qDebug() << "propsA == propsB:" << (propsA == propsB) << "{ expect true }";
        qDebug() << "propsA != propsB:" << (propsA != propsB) << "{ expect false }";


        qDebug() << "AFTER propsB -= PARTICLE_PROP_PAUSE_SIMULATION...";
        propsB -= PARTICLE_PROP_PAUSE_SIMULATION;

        qDebug() << "propsA == propsB:" << (propsA == propsB) << "{ expect false }";
        qDebug() << "propsA != propsB:" << (propsA != propsB) << "{ expect true }";

        qDebug() << "AFTER propsB = propsA...";
        propsB = propsA;

        qDebug() << "propsA == propsB:" << (propsA == propsB) << "{ expect true }";
        qDebug() << "propsA != propsB:" << (propsA != propsB) << "{ expect false }";

    }

    {
        qDebug() << "Test 7: ParticlePropertyFlags testing individual properties";
        ParticlePropertyFlags props;

        qDebug() << "ParticlePropertyFlags props;";
        QByteArray encoded = props.encode();
        qDebug() << "props... encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());

        qDebug() << "props.getHasProperty(PARTICLE_PROP_VISIBLE)" << (props.getHasProperty(PARTICLE_PROP_VISIBLE)) 
                        << "{ expect false }";

        qDebug() << "props << PARTICLE_PROP_VISIBLE;";
        props << PARTICLE_PROP_VISIBLE;

        encoded = props.encode();
        qDebug() << "props... encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        qDebug() << "props.getHasProperty(PARTICLE_PROP_VISIBLE)" << (props.getHasProperty(PARTICLE_PROP_VISIBLE)) 
                        << "{ expect true }";

        qDebug() << "props << PARTICLE_PROP_ANIMATION_URL;";
        props << PARTICLE_PROP_ANIMATION_URL;

        encoded = props.encode();
        qDebug() << "props... encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        qDebug() << "props.getHasProperty(PARTICLE_PROP_VISIBLE)" << (props.getHasProperty(PARTICLE_PROP_VISIBLE)) 
                        << "{ expect true }";

        qDebug() << "props << ... more ...";
        props << PARTICLE_PROP_ANIMATION_FPS;
        props << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        props << PARTICLE_PROP_ANIMATION_PLAYING;
        props << PARTICLE_PROP_PAUSE_SIMULATION;

        encoded = props.encode();
        qDebug() << "props... encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        qDebug() << "props.getHasProperty(PARTICLE_PROP_VISIBLE)" << (props.getHasProperty(PARTICLE_PROP_VISIBLE)) 
                        << "{ expect true }";

        qDebug() << "ParticlePropertyFlags propsB = props & PARTICLE_PROP_VISIBLE;";
        ParticlePropertyFlags propsB = props & PARTICLE_PROP_VISIBLE;

        qDebug() << "propsB.getHasProperty(PARTICLE_PROP_VISIBLE)" << (propsB.getHasProperty(PARTICLE_PROP_VISIBLE)) 
                        << "{ expect true }";

        encoded = propsB.encode();
        qDebug() << "propsB... encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());

        qDebug() << "ParticlePropertyFlags propsC = ~propsB;";
        ParticlePropertyFlags propsC = ~propsB;
        
        qDebug() << "propsC.getHasProperty(PARTICLE_PROP_VISIBLE)" << (propsC.getHasProperty(PARTICLE_PROP_VISIBLE))
                        << "{ expect false }";

        encoded = propsC.encode();
        qDebug() << "propsC... encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
    }
    
    {
        qDebug() << "Test 8: ParticlePropertyFlags: decode tests";
        ParticlePropertyFlags props;

        props << PARTICLE_PROP_VISIBLE;
        props << PARTICLE_PROP_ANIMATION_URL;
        props << PARTICLE_PROP_ANIMATION_FPS;
        props << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        props << PARTICLE_PROP_ANIMATION_PLAYING;
        props << PARTICLE_PROP_PAUSE_SIMULATION;

        QByteArray encoded = props.encode();
        qDebug() << "encoded=";
        outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());

        qDebug() << "encoded.size()=" << encoded.size();

        ParticlePropertyFlags propsDecoded;
        propsDecoded.decode(encoded);
        
        qDebug() << "propsDecoded == props:" << (propsDecoded == props) << "{ expect true }";

        QByteArray encodedAfterDecoded = propsDecoded.encode();

        qDebug() << "encodedAfterDecoded=";
        outputBufferBits((const unsigned char*)encodedAfterDecoded.constData(), encodedAfterDecoded.size());

        qDebug() << "fill encoded byte array with extra garbage (as if it was bitstream with more content)";
        QByteArray extraContent;
        extraContent.fill(0xba, 10);
        encoded.append(extraContent);
        qDebug() << "encoded.size()=" << encoded.size() << "includes extra garbage";

        ParticlePropertyFlags propsDecodedExtra;
        propsDecodedExtra.decode(encoded);
        
        qDebug() << "propsDecodedExtra == props:" << (propsDecodedExtra == props) << "{ expect true }";

        QByteArray encodedAfterDecodedExtra = propsDecodedExtra.encode();

        qDebug() << "encodedAfterDecodedExtra=";
        outputBufferBits((const unsigned char*)encodedAfterDecodedExtra.constData(), encodedAfterDecodedExtra.size());

    }

    qDebug() << "******************************************************************************************";
}
Пример #2
0
void OctreeTests::propertyFlagsTests(bool verbose) {
    int testsTaken = 0;
    int testsPassed = 0;
    int testsFailed = 0;

    if (verbose) {
        qDebug() << "******************************************************************************************";
    }
    
    qDebug() << "OctreeTests::propertyFlagsTests()";

    {
        if (verbose) {
            qDebug() << "Test 1: EntityProperties: using setHasProperty()";
        }
        testsTaken++;

        EntityPropertyFlags props;
        props.setHasProperty(PROP_VISIBLE);
        props.setHasProperty(PROP_POSITION);
        props.setHasProperty(PROP_RADIUS);
        props.setHasProperty(PROP_MODEL_URL);
        props.setHasProperty(PROP_ROTATION);
    
        QByteArray encoded = props.encode();

        if (verbose) {
            qDebug() << "encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        }
        
        char expectedBytes[] = { 31 };
        QByteArray expectedResult(expectedBytes, sizeof(expectedBytes)/sizeof(expectedBytes[0]));
        
        if (encoded == expectedResult) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 1: EntityProperties: using setHasProperty()";
        }

    }

    {    
        if (verbose) {
            qDebug() << "Test 2: ParticlePropertyFlags: using setHasProperty()";
        }
        testsTaken++;

        ParticlePropertyFlags props2;
        props2.setHasProperty(PARTICLE_PROP_VISIBLE);
        props2.setHasProperty(PARTICLE_PROP_ANIMATION_URL);
        props2.setHasProperty(PARTICLE_PROP_ANIMATION_FPS);
        props2.setHasProperty(PARTICLE_PROP_ANIMATION_FRAME_INDEX);
        props2.setHasProperty(PARTICLE_PROP_ANIMATION_PLAYING);
        props2.setHasProperty(PARTICLE_PROP_PAUSE_SIMULATION);
    
        QByteArray encoded = props2.encode();

        if (verbose) {
            qDebug() << "encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        }

        char expectedBytes[] = { (char)196, (char)15, (char)2 };
        QByteArray expectedResult(expectedBytes, sizeof(expectedBytes)/sizeof(expectedBytes[0]));
        
        if (encoded == expectedResult) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 2: ParticlePropertyFlags: using setHasProperty()";
        }

        
        if (verbose) {
            qDebug() << "Test 2b: remove flag with setHasProperty() PARTICLE_PROP_PAUSE_SIMULATION";
        }
        testsTaken++;

        props2.setHasProperty(PARTICLE_PROP_PAUSE_SIMULATION, false);
    
        encoded = props2.encode();

        if (verbose) {
            qDebug() << "encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        }

        char expectedBytesB[] = { (char)136, (char)30 };
        QByteArray expectedResultB(expectedBytesB, sizeof(expectedBytesB)/sizeof(expectedBytesB[0]));
        
        if (encoded == expectedResultB) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 2b: remove flag with setHasProperty() PARTICLE_PROP_PAUSE_SIMULATION";
        }
    }

    {    
        if (verbose) {
            qDebug() << "Test 3: ParticlePropertyFlags: using | operator";
        }
        testsTaken++;
        
        ParticlePropertyFlags props;

        props = ParticlePropertyFlags(PARTICLE_PROP_VISIBLE) 
                    | ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_URL)
                    | ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FPS)
                    | ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FRAME_INDEX)
                    | ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_PLAYING) 
                    | ParticlePropertyFlags(PARTICLE_PROP_PAUSE_SIMULATION);
    
        QByteArray encoded = props.encode();

        if (verbose) {
            qDebug() << "encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        }
        char expectedBytes[] = { (char)196, (char)15, (char)2 };
        QByteArray expectedResult(expectedBytes, sizeof(expectedBytes)/sizeof(expectedBytes[0]));
        
        if (encoded == expectedResult) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 3: ParticlePropertyFlags: using | operator";
        }


        if (verbose) {
            qDebug() << "Test 3b: remove flag with -= PARTICLE_PROP_PAUSE_SIMULATION";
        }
        testsTaken++;
        
        props -= PARTICLE_PROP_PAUSE_SIMULATION;
    
        encoded = props.encode();
    
        if (verbose) {
            qDebug() << "encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        }
        
        char expectedBytesB[] = { (char)136, (char)30 };
        QByteArray expectedResultB(expectedBytesB, sizeof(expectedBytesB)/sizeof(expectedBytesB[0]));
        
        if (encoded == expectedResultB) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 3b: remove flag with -= PARTICLE_PROP_PAUSE_SIMULATION";
        }
        
    }

    {    
        if (verbose) {
            qDebug() << "Test 3c: ParticlePropertyFlags: using |= operator";
        }
        testsTaken++;

        ParticlePropertyFlags props;

        props |= PARTICLE_PROP_VISIBLE;
        props |= PARTICLE_PROP_ANIMATION_URL;
        props |= PARTICLE_PROP_ANIMATION_FPS;
        props |= PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        props |= PARTICLE_PROP_ANIMATION_PLAYING;
        props |= PARTICLE_PROP_PAUSE_SIMULATION;

        QByteArray encoded = props.encode();

        if (verbose) {
            qDebug() << "encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        }

        char expectedBytes[] = { (char)196, (char)15, (char)2 };
        QByteArray expectedResult(expectedBytes, sizeof(expectedBytes)/sizeof(expectedBytes[0]));
        
        if (encoded == expectedResult) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - 3c: ParticlePropertyFlags: using |= operator";
        }
    }

    {    
        if (verbose) {
            qDebug() << "Test 4: ParticlePropertyFlags: using + operator";
        }
        testsTaken++;

        ParticlePropertyFlags props;

        props = ParticlePropertyFlags(PARTICLE_PROP_VISIBLE) 
                    + ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_URL)
                    + ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FPS)
                    + ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FRAME_INDEX)
                    + ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_PLAYING) 
                    + ParticlePropertyFlags(PARTICLE_PROP_PAUSE_SIMULATION);
    
        QByteArray encoded = props.encode();

        if (verbose) {
            qDebug() << "encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        }

        char expectedBytes[] = { (char)196, (char)15, (char)2 };
        QByteArray expectedResult(expectedBytes, sizeof(expectedBytes)/sizeof(expectedBytes[0]));
        
        if (encoded == expectedResult) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 4: ParticlePropertyFlags: using + operator";
        }
    }

    {    
        if (verbose) {
            qDebug() << "Test 5: ParticlePropertyFlags: using += operator";
        }
        testsTaken++;
        ParticlePropertyFlags props;

        props += PARTICLE_PROP_VISIBLE;
        props += PARTICLE_PROP_ANIMATION_URL;
        props += PARTICLE_PROP_ANIMATION_FPS;
        props += PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        props += PARTICLE_PROP_ANIMATION_PLAYING;
        props += PARTICLE_PROP_PAUSE_SIMULATION;
    
        QByteArray encoded = props.encode();

        if (verbose) {
            qDebug() << "encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        }

        char expectedBytes[] = { (char)196, (char)15, (char)2 };
        QByteArray expectedResult(expectedBytes, sizeof(expectedBytes)/sizeof(expectedBytes[0]));
        
        if (encoded == expectedResult) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 5: ParticlePropertyFlags: using += operator";
        }
    }

    {    
        if (verbose) {
            qDebug() << "Test 6: ParticlePropertyFlags: using = ... << operator";
        }
        testsTaken++;
        
        ParticlePropertyFlags props;

        props = ParticlePropertyFlags(PARTICLE_PROP_VISIBLE) 
                    << ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_URL)
                    << ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FPS)
                    << ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_FRAME_INDEX)
                    << ParticlePropertyFlags(PARTICLE_PROP_ANIMATION_PLAYING) 
                    << ParticlePropertyFlags(PARTICLE_PROP_PAUSE_SIMULATION);
    
        QByteArray encoded = props.encode();

        if (verbose) {
            qDebug() << "encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        }

        char expectedBytes[] = { (char)196, (char)15, (char)2 };
        QByteArray expectedResult(expectedBytes, sizeof(expectedBytes)/sizeof(expectedBytes[0]));
        
        if (encoded == expectedResult) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 6: ParticlePropertyFlags: using = ... << operator";
        }
    }

    {
        if (verbose) {
            qDebug() << "Test 7: ParticlePropertyFlags: using <<= operator";
        }
        testsTaken++;
        
        ParticlePropertyFlags props;

        props <<= PARTICLE_PROP_VISIBLE;
        props <<= PARTICLE_PROP_ANIMATION_URL;
        props <<= PARTICLE_PROP_ANIMATION_FPS;
        props <<= PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        props <<= PARTICLE_PROP_ANIMATION_PLAYING;
        props <<= PARTICLE_PROP_PAUSE_SIMULATION;
    
        QByteArray encoded = props.encode();

        if (verbose) {
            qDebug() << "encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        }

        char expectedBytes[] = { (char)196, (char)15, (char)2 };
        QByteArray expectedResult(expectedBytes, sizeof(expectedBytes)/sizeof(expectedBytes[0]));
        
        if (encoded == expectedResult) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 7: ParticlePropertyFlags: using <<= operator";
        }
    }

    {
        if (verbose) {
            qDebug() << "Test 8: ParticlePropertyFlags: using << enum operator";
        }
        testsTaken++;
        
        ParticlePropertyFlags props;

        props << PARTICLE_PROP_VISIBLE;
        props << PARTICLE_PROP_ANIMATION_URL;
        props << PARTICLE_PROP_ANIMATION_FPS;
        props << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        props << PARTICLE_PROP_ANIMATION_PLAYING;
        props << PARTICLE_PROP_PAUSE_SIMULATION;

        QByteArray encoded = props.encode();

        if (verbose) {
            qDebug() << "encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        }

        char expectedBytes[] = { (char)196, (char)15, (char)2 };
        QByteArray expectedResult(expectedBytes, sizeof(expectedBytes)/sizeof(expectedBytes[0]));
        
        if (encoded == expectedResult) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 8: ParticlePropertyFlags: using << enum operator";
        }
    }

    {
        if (verbose) {
            qDebug() << "Test 9: ParticlePropertyFlags: using << flags operator ";
        }
        testsTaken++;

        ParticlePropertyFlags props;
        ParticlePropertyFlags props2;

        props << PARTICLE_PROP_VISIBLE;
        props << PARTICLE_PROP_ANIMATION_URL;
        props << PARTICLE_PROP_ANIMATION_FPS;

        props2 << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        props2 << PARTICLE_PROP_ANIMATION_PLAYING;
        props2 << PARTICLE_PROP_PAUSE_SIMULATION;

        props << props2;

        QByteArray encoded = props.encode();

        if (verbose) {
            qDebug() << "encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        }

        char expectedBytes[] = { (char)196, (char)15, (char)2 };
        QByteArray expectedResult(expectedBytes, sizeof(expectedBytes)/sizeof(expectedBytes[0]));
        
        if (encoded == expectedResult) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 9: ParticlePropertyFlags: using << flags operator";
        }
    }
  
    {
        if (verbose) {
            qDebug() << "Test 10: ParticlePropertyFlags comparison";
        }
        ParticlePropertyFlags propsA;

        if (verbose) {
            qDebug() << "!propsA:" << (!propsA) << "{ expect true }";
        }
        testsTaken++;
        bool resultA = (!propsA);
        bool expectedA = true;
        if (resultA == expectedA) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 10a: ParticlePropertyFlags comparison, uninitialized !propsA";
        }

        propsA << PARTICLE_PROP_VISIBLE;
        propsA << PARTICLE_PROP_ANIMATION_URL;
        propsA << PARTICLE_PROP_ANIMATION_FPS;
        propsA << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        propsA << PARTICLE_PROP_ANIMATION_PLAYING;
        propsA << PARTICLE_PROP_PAUSE_SIMULATION;

        if (verbose) {
            qDebug() << "!propsA:" << (!propsA) << "{ expect false }";
        }
        testsTaken++;
        bool resultB = (!propsA);
        bool expectedB = false;
        if (resultB == expectedB) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 10b: ParticlePropertyFlags comparison, initialized !propsA";
        }

        ParticlePropertyFlags propsB;
        propsB << PARTICLE_PROP_VISIBLE;
        propsB << PARTICLE_PROP_ANIMATION_URL;
        propsB << PARTICLE_PROP_ANIMATION_FPS;
        propsB << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        propsB << PARTICLE_PROP_ANIMATION_PLAYING;
        propsB << PARTICLE_PROP_PAUSE_SIMULATION;

        if (verbose) {
            qDebug() << "propsA == propsB:" << (propsA == propsB) << "{ expect true }";
            qDebug() << "propsA != propsB:" << (propsA != propsB) << "{ expect false }";
        }
        testsTaken++;
        bool resultC = (propsA == propsB);
        bool expectedC = true;
        if (resultC == expectedC) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 10c: ParticlePropertyFlags comparison, propsA == propsB";
        }

        testsTaken++;
        bool resultD = (propsA != propsB);
        bool expectedD = false;
        if (resultD == expectedD) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 10d: ParticlePropertyFlags comparison, propsA != propsB";
        }
        
        if (verbose) {
            qDebug() << "AFTER propsB -= PARTICLE_PROP_PAUSE_SIMULATION...";
        }
        
        propsB -= PARTICLE_PROP_PAUSE_SIMULATION;

        if (verbose) {
            qDebug() << "propsA == propsB:" << (propsA == propsB) << "{ expect false }";
            qDebug() << "propsA != propsB:" << (propsA != propsB) << "{ expect true }";
        }
        testsTaken++;
        bool resultE = (propsA == propsB);
        bool expectedE = false;
        if (resultE == expectedE) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 10e: ParticlePropertyFlags comparison, AFTER propsB -= PARTICLE_PROP_PAUSE_SIMULATION";
        }
        
        if (verbose) {
            qDebug() << "AFTER propsB = propsA...";
        }
        propsB = propsA;
        if (verbose) {
            qDebug() << "propsA == propsB:" << (propsA == propsB) << "{ expect true }";
            qDebug() << "propsA != propsB:" << (propsA != propsB) << "{ expect false }";
        }
        testsTaken++;
        bool resultF = (propsA == propsB);
        bool expectedF = true;
        if (resultF == expectedF) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 10f: ParticlePropertyFlags comparison, AFTER propsB = propsA";
        }
    }

    {
        if (verbose) {
            qDebug() << "Test 11: ParticlePropertyFlags testing individual properties";
        }
        ParticlePropertyFlags props;

        if (verbose) {
            qDebug() << "ParticlePropertyFlags props;";
        }
        
        QByteArray encoded = props.encode();

        if (verbose) {
            qDebug() << "props... encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        }

        char expectedBytes[] = { 0 };
        QByteArray expectedResult(expectedBytes, sizeof(expectedBytes)/sizeof(expectedBytes[0]));
        
        testsTaken++;
        if (encoded == expectedResult) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 11a: ParticlePropertyFlags testing individual properties";
        }


        if (verbose) {
            qDebug() << "Test 11b: props.getHasProperty(PARTICLE_PROP_VISIBLE)" << (props.getHasProperty(PARTICLE_PROP_VISIBLE)) 
                        << "{ expect false }";
        }
        testsTaken++;
        bool resultB = props.getHasProperty(PARTICLE_PROP_VISIBLE);
        bool expectedB = false;
        if (resultB == expectedB) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 11b: props.getHasProperty(PARTICLE_PROP_VISIBLE)";
        }

        if (verbose) {
            qDebug() << "props << PARTICLE_PROP_VISIBLE;";
        }
        props << PARTICLE_PROP_VISIBLE;
        testsTaken++;
        bool resultC = props.getHasProperty(PARTICLE_PROP_VISIBLE);
        bool expectedC = true;
        if (resultC == expectedC) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 11c: props.getHasProperty(PARTICLE_PROP_VISIBLE) after props << PARTICLE_PROP_VISIBLE";
        }

        encoded = props.encode();

        if (verbose) {
            qDebug() << "props... encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
            qDebug() << "props.getHasProperty(PARTICLE_PROP_VISIBLE)" << (props.getHasProperty(PARTICLE_PROP_VISIBLE)) 
                            << "{ expect true }";
        }

        char expectedBytesC[] = { 16 };
        QByteArray expectedResultC(expectedBytesC, sizeof(expectedBytesC)/sizeof(expectedBytesC[0]));
        
        testsTaken++;
        if (encoded == expectedResultC) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 11c: ParticlePropertyFlags testing individual properties";
        }

        if (verbose) {
            qDebug() << "props << PARTICLE_PROP_ANIMATION_URL;";
        }
        props << PARTICLE_PROP_ANIMATION_URL;

        encoded = props.encode();
        if (verbose) {
            qDebug() << "props... encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
            qDebug() << "props.getHasProperty(PARTICLE_PROP_VISIBLE)" << (props.getHasProperty(PARTICLE_PROP_VISIBLE)) 
                            << "{ expect true }";
        }
        char expectedBytesD[] = { (char)136, (char)16 };
        QByteArray expectedResultD(expectedBytesD, sizeof(expectedBytesD)/sizeof(expectedBytesD[0]));
        
        testsTaken++;
        if (encoded == expectedResultD) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 11d: ParticlePropertyFlags testing individual properties";
        }
        testsTaken++;
        bool resultE = props.getHasProperty(PARTICLE_PROP_VISIBLE);
        bool expectedE = true;
        if (resultE == expectedE) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 11e: props.getHasProperty(PARTICLE_PROP_VISIBLE) after props << PARTICLE_PROP_ANIMATION_URL";
        }


        if (verbose) {
            qDebug() << "props << ... more ...";
        }
        props << PARTICLE_PROP_ANIMATION_FPS;
        props << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        props << PARTICLE_PROP_ANIMATION_PLAYING;
        props << PARTICLE_PROP_PAUSE_SIMULATION;

        encoded = props.encode();
        if (verbose) {
            qDebug() << "props... encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
            qDebug() << "props.getHasProperty(PARTICLE_PROP_VISIBLE)" << (props.getHasProperty(PARTICLE_PROP_VISIBLE)) 
                            << "{ expect true }";
        }
        testsTaken++;
        bool resultF = props.getHasProperty(PARTICLE_PROP_VISIBLE);
        bool expectedF = true;
        if (resultF == expectedF) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 11f: props.getHasProperty(PARTICLE_PROP_VISIBLE) after props << more";
        }

        if (verbose) {
            qDebug() << "ParticlePropertyFlags propsB = props & PARTICLE_PROP_VISIBLE;";
        }
        ParticlePropertyFlags propsB = props & PARTICLE_PROP_VISIBLE;

        if (verbose) {
            qDebug() << "propsB.getHasProperty(PARTICLE_PROP_VISIBLE)" << (propsB.getHasProperty(PARTICLE_PROP_VISIBLE)) 
                        << "{ expect true }";
        }
        testsTaken++;
        bool resultG = propsB.getHasProperty(PARTICLE_PROP_VISIBLE);
        bool expectedG = true;
        if (resultG == expectedG) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 11g: propsB = props & PARTICLE_PROP_VISIBLE";
        }

        encoded = propsB.encode();
        if (verbose) {
            qDebug() << "propsB... encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        }
        char expectedBytesH[] = { 16 };
        QByteArray expectedResultH(expectedBytesC, sizeof(expectedBytesH)/sizeof(expectedBytesH[0]));
        
        testsTaken++;
        if (encoded == expectedResultH) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 11h: ParticlePropertyFlags testing individual properties";
        }

        if (verbose) {
            qDebug() << "ParticlePropertyFlags propsC = ~propsB;";
        }
        ParticlePropertyFlags propsC = ~propsB;
        
        if (verbose) {
            qDebug() << "propsC.getHasProperty(PARTICLE_PROP_VISIBLE)" << (propsC.getHasProperty(PARTICLE_PROP_VISIBLE))
                        << "{ expect false }";
        }
        testsTaken++;
        bool resultI = propsC.getHasProperty(PARTICLE_PROP_VISIBLE);
        bool expectedI = false;
        if (resultI == expectedI) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 11i: propsC = ~propsB";
        }

        encoded = propsC.encode();
        if (verbose) {
            qDebug() << "propsC... encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        }
    }
    
    {
        if (verbose) {
            qDebug() << "Test 12: ParticlePropertyFlags: decode tests";
        }
        ParticlePropertyFlags props;

        props << PARTICLE_PROP_VISIBLE;
        props << PARTICLE_PROP_ANIMATION_URL;
        props << PARTICLE_PROP_ANIMATION_FPS;
        props << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        props << PARTICLE_PROP_ANIMATION_PLAYING;
        props << PARTICLE_PROP_PAUSE_SIMULATION;

        QByteArray encoded = props.encode();
        if (verbose) {
            qDebug() << "encoded=";
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
            qDebug() << "encoded.size()=" << encoded.size();
        }

        ParticlePropertyFlags propsDecoded;
        propsDecoded.decode(encoded);
        
        if (verbose) {
            qDebug() << "propsDecoded == props:" << (propsDecoded == props) << "{ expect true }";
        }
        testsTaken++;
        bool resultA = (propsDecoded == props);
        bool expectedA = true;
        if (resultA == expectedA) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 12a: propsDecoded == props";
        }

        QByteArray encodedAfterDecoded = propsDecoded.encode();

        if (verbose) {
            qDebug() << "encodedAfterDecoded=";
            outputBufferBits((const unsigned char*)encodedAfterDecoded.constData(), encodedAfterDecoded.size());
        }
        testsTaken++;
        bool resultB = (encoded == encodedAfterDecoded);
        bool expectedB = true;
        if (resultB == expectedB) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 12b: (encoded == encodedAfterDecoded)";
        }

        if (verbose) {
            qDebug() << "fill encoded byte array with extra garbage (as if it was bitstream with more content)";
        }
        QByteArray extraContent;
        extraContent.fill(0xba, 10);
        encoded.append(extraContent);

        if (verbose) {
            qDebug() << "encoded.size()=" << encoded.size() << "includes extra garbage";
        }

        ParticlePropertyFlags propsDecodedExtra;
        propsDecodedExtra.decode(encoded);
        
        if (verbose) {
            qDebug() << "propsDecodedExtra == props:" << (propsDecodedExtra == props) << "{ expect true }";
        }
        testsTaken++;
        bool resultC = (propsDecodedExtra == props);
        bool expectedC = true;
        if (resultC == expectedC) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 12c: (propsDecodedExtra == props)";
        }

        QByteArray encodedAfterDecodedExtra = propsDecodedExtra.encode();

        if (verbose) {
            qDebug() << "encodedAfterDecodedExtra=";
            outputBufferBits((const unsigned char*)encodedAfterDecodedExtra.constData(), encodedAfterDecodedExtra.size());
        }
    }
    
    {
        if (verbose) {
            qDebug() << "Test 13: ParticlePropertyFlags: QByteArray << / >> tests";
        }
        ParticlePropertyFlags props;

        props << PARTICLE_PROP_VISIBLE;
        props << PARTICLE_PROP_ANIMATION_URL;
        props << PARTICLE_PROP_ANIMATION_FPS;
        props << PARTICLE_PROP_ANIMATION_FRAME_INDEX;
        props << PARTICLE_PROP_ANIMATION_PLAYING;
        props << PARTICLE_PROP_PAUSE_SIMULATION;

        if (verbose) {
            qDebug() << "testing encoded << props";
        }
        QByteArray encoded;
        encoded << props;

        if (verbose) {
            outputBufferBits((const unsigned char*)encoded.constData(), encoded.size());
        }

        ParticlePropertyFlags propsDecoded;
        if (verbose) {
            qDebug() << "testing encoded >> propsDecoded";
        }
        encoded >> propsDecoded;

        if (verbose) {
            qDebug() << "propsDecoded==props" << (propsDecoded==props);
        }

        testsTaken++;
        bool resultA = (propsDecoded == props);
        bool expectedA = true;
        if (resultA == expectedA) {
            testsPassed++;
        } else {
            testsFailed++;
            qDebug() << "FAILED - Test 13: ParticlePropertyFlags: QByteArray << / >> tests";
        }
    }

    qDebug() << "   tests passed:" << testsPassed << "out of" << testsTaken;
    if (verbose) {
        qDebug() << "******************************************************************************************";
    }
}