JD2022-TU1/main/unittests/engine/musicband/MusicScore.cpp

255 lines
9.4 KiB
C++

// ----------------------------------------------------------------------------
// Unit test for the class engine/musicband/MusicScore
// ----------------------------------------------------------------------------
#include "precompiled_unittests_engine.h"
#include "engine/musicband/MusicScore.h"
#include "engine/sound/musictrack/MusicTrackMetronome.h"
// mocks
#include "musicband/ConductorBrickMock.h"
#include "sound/musictrack/MusicTrackManagerMock.h"
using ::testing::Return;
using ::testing::_;
namespace ITF
{
class MusicScoreTestFixture : public ::testing::Test
{
public:
MusicScoreTestFixture()
: m_musicScoreType(MusicScoreType_Menu)
, m_musicScore(m_musicScoreType)
{
m_brickDescriptor.m_localStartBeat = 0;
m_brickDescriptor.m_prefetchDuration = 2;
m_brickDescriptor.m_duration = 4;
m_musicScore.init(&m_musicTrackManager);
ON_CALL(m_musicTrackManager, getMetronome(_)).WillByDefault(Return(&m_metronome));
}
~MusicScoreTestFixture()
{
// waits while all bricks in the music score are removed
// supposes that the bricks are auto removable
m_musicScore.reset();
while (m_musicScore.hasBricks())
{
m_musicScore.update();
}
}
protected:
BrickDescriptor m_brickDescriptor;
MusicScoreType m_musicScoreType;
typedef ::testing::NiceMock<MusicTrackManagerMock> MusicTrackManagerType;
MusicTrackManagerType m_musicTrackManager;
MusicTrackMetronome m_metronome;
// tested music score
MusicScore m_musicScore;
};
// test result of hasError() function when a music score has no bricks
TEST(MusicScore, test_hasError_False_NoBricks)
{
MusicScore musicScore(MusicScoreType_Menu);
EXPECT_FALSE(musicScore.hasError());
}
// test result of hasError() function when a music score has
// a brick but the brick is not in the error state
TEST_F(MusicScoreTestFixture, test_hasError_False_BrickHasNoErrors)
{
typedef ::testing::NiceMock<ConductorBrickMock> BrickInstanceType;
/*BrickInstanceType* brickInstance = */m_musicScore.addBrick<BrickInstanceType>(m_brickDescriptor, m_musicScoreType);
EXPECT_FALSE(m_musicScore.hasError());
}
// test result of hasError() function when a music score has
// a brick and the brick is in the error state
TEST_F(MusicScoreTestFixture, test_hasError_True_BrickHasErrors)
{
typedef ::testing::NiceMock<ConductorBrickMock> BrickInstanceType;
BrickInstanceType* brickInstance = m_musicScore.addBrick<BrickInstanceType>(m_brickDescriptor, m_musicScoreType);
// specify the behavior of the brick
ON_CALL(*brickInstance, brickHasError()).WillByDefault(Return(true));
ON_CALL(*brickInstance, isBrickDiscarded()).WillByDefault(Return(true));
// no error at the beginning
EXPECT_FALSE(m_musicScore.hasError());
// update music score in order to bring brick instance to error state
m_musicScore.update();
m_musicScore.update();
// expect error
EXPECT_TRUE(m_musicScore.hasError());
}
// test result of hasError() function when a music score has
// bricks and one brick is in the error state
TEST_F(MusicScoreTestFixture, test_hasError_True_BricksHaveErrors)
{
typedef ::testing::NiceMock<ConductorBrickMock> BrickInstanceType;
BrickInstanceType* brickInstance1 = m_musicScore.addBrick<BrickInstanceType>(m_brickDescriptor, m_musicScoreType);
BrickInstanceType* brickInstance2 = m_musicScore.addBrick<BrickInstanceType>(m_brickDescriptor, m_musicScoreType);
ON_CALL(*brickInstance1, brickHasError()).WillByDefault(Return(false));
ON_CALL(*brickInstance1, isBrickReady()).WillByDefault(Return(true));
ON_CALL(*brickInstance1, isBrickDiscarded()).WillByDefault(Return(true));
ON_CALL(*brickInstance2, brickHasError()).WillByDefault(Return(true));
ON_CALL(*brickInstance2, isBrickDiscarded()).WillByDefault(Return(true));
// no error at the beginning
EXPECT_FALSE(m_musicScore.hasError());
// update music score in order to bring brick instance to error state
m_musicScore.update();
m_musicScore.update();
//expect error
EXPECT_TRUE(m_musicScore.hasError());
}
// test result of getError() function when a music score has
// bricks and all bricks are in the error state
TEST_F(MusicScoreTestFixture, test_getError_AllBricksHaveErrors)
{
typedef ::testing::NiceMock<ConductorBrickMock> BrickInstanceType;
BrickInstanceType* brickInstance1 = m_musicScore.addBrick<BrickInstanceType>(m_brickDescriptor, m_musicScoreType);
BrickInstanceType* brickInstance2 = m_musicScore.addBrick<BrickInstanceType>(m_brickDescriptor, m_musicScoreType);
MusicScore::ErrorList expectedErrorList;
expectedErrorList.push_back(ConductorBrickError(brickInstance1, ConductorBrickError::OpenFailed, 0, 23));
expectedErrorList.push_back(ConductorBrickError(brickInstance2, ConductorBrickError::OnlineErrorNetwork, 0, 404));
ON_CALL(*brickInstance1, brickHasError()).WillByDefault(Return(true));
ON_CALL(*brickInstance1, getError()).WillByDefault(Return(expectedErrorList[0]));
ON_CALL(*brickInstance1, isBrickDiscarded()).WillByDefault(Return(true));
ON_CALL(*brickInstance2, brickHasError()).WillByDefault(Return(true));
ON_CALL(*brickInstance2, getError()).WillByDefault(Return(expectedErrorList[1]));
ON_CALL(*brickInstance2, isBrickDiscarded()).WillByDefault(Return(true));
// update music score in order to bring brick instances to error state
m_musicScore.update();
m_musicScore.update();
MusicScore::ErrorList errorList;
m_musicScore.getErrors(errorList);
EXPECT_EQ(expectedErrorList, errorList);
}
// test result of removeBricksWithError() function when a music score has
// bricks and all bricks are in the error state
TEST_F(MusicScoreTestFixture, test_removeBricksWithError)
{
typedef ::testing::NiceMock<ConductorBrickMock> BrickInstanceType;
BrickInstanceType* brickInstance1 = m_musicScore.addBrick<BrickInstanceType>(m_brickDescriptor, m_musicScoreType);
BrickInstanceType* brickInstance2 = m_musicScore.addBrick<BrickInstanceType>(m_brickDescriptor, m_musicScoreType);
ON_CALL(*brickInstance1, brickHasError()).WillByDefault(Return(true));
ON_CALL(*brickInstance1, isBrickDiscarded()).WillByDefault(Return(true));
ON_CALL(*brickInstance2, brickHasError()).WillByDefault(Return(true));
ON_CALL(*brickInstance2, isBrickDiscarded()).WillByDefault(Return(true));
// update music score in order to bring brick instances to error state
m_musicScore.update();
m_musicScore.update();
// demand removal of bricks with error
m_musicScore.removeBricksWithError();
// update the system
m_musicScore.update();
m_musicScore.update();
EXPECT_FALSE(m_musicScore.hasBricks());
}
// test result of isStarving() function when a music score has no bricks
TEST(MusicScore, test_isStarving_False_NoBricks)
{
MusicScore musicScore(MusicScoreType_Menu);
EXPECT_FALSE(musicScore.isStarving());
}
// test result of isStarving() function when a music score has
// a brick but the brick is not starving
TEST_F(MusicScoreTestFixture, test_isStarving_False_BrickIsNotStarving)
{
typedef ::testing::NiceMock<ConductorBrickMock> BrickInstanceType;
/*BrickInstanceType* brickInstance = */m_musicScore.addBrick<BrickInstanceType>(m_brickDescriptor, m_musicScoreType);
EXPECT_FALSE(m_musicScore.isStarving());
}
// test result of isStarving() function when a music score has
// a brick and the brick is starving
TEST_F(MusicScoreTestFixture, test_isStarving_True_BrickIsStarving)
{
typedef ::testing::NiceMock<ConductorBrickMock> BrickInstanceType;
BrickInstanceType* brickInstance = m_musicScore.addBrick<BrickInstanceType>(m_brickDescriptor, m_musicScoreType);
// specify the behavior of the brick
ON_CALL(*brickInstance, isBrickStarving()).WillByDefault(Return(true));
ON_CALL(*brickInstance, isBrickReady()).WillByDefault(Return(true));
ON_CALL(*brickInstance, isBrickDiscarded()).WillByDefault(Return(true));
// no error at the beginning
EXPECT_FALSE(m_musicScore.isStarving());
// update music score in order to bring brick instance to error state
m_musicScore.update();
m_musicScore.update();
m_musicScore.update();
m_musicScore.update();
// expect error
EXPECT_TRUE(m_musicScore.isStarving());
}
// test result of isStarving() function when a music score has
// bricks and one brick is starving
TEST_F(MusicScoreTestFixture, test_isStarving_True_BricksStarve)
{
typedef ::testing::NiceMock<ConductorBrickMock> BrickInstanceType;
BrickInstanceType* brickInstance1 = m_musicScore.addBrick<BrickInstanceType>(m_brickDescriptor, m_musicScoreType);
BrickInstanceType* brickInstance2 = m_musicScore.addBrick<BrickInstanceType>(m_brickDescriptor, m_musicScoreType);
ON_CALL(*brickInstance1, isBrickReady()).WillByDefault(Return(true));
ON_CALL(*brickInstance1, isBrickDiscarded()).WillByDefault(Return(true));
ON_CALL(*brickInstance2, isBrickStarving()).WillByDefault(Return(true));
ON_CALL(*brickInstance2, isBrickReady()).WillByDefault(Return(true));
ON_CALL(*brickInstance2, isBrickDiscarded()).WillByDefault(Return(true));
// no error at the beginning
EXPECT_FALSE(m_musicScore.isStarving());
// update music score in order to bring brick instance to error state
m_musicScore.update();
m_musicScore.update();
m_musicScore.update();
m_musicScore.update();
//expect error
EXPECT_TRUE(m_musicScore.isStarving());
}
} // namespace ITF