#include "tileset/TileAdjacencyBehavior.h" #include "unittest/TestSuite.h" static void testInit(void) { TileAdjacencyRule rule = {TILE_CONDITION_MATCH_SINGLE, {.single = {{1, 2}, 3}}}; TileAdjacencyOverlay overlay = {4, {5, 6}, {7, 8, 9, 10}, 11, 0}; TileAdjacencyBehavior behavior = TileAdjacencyBehavior_init(0, false, rule, RECT4i(1, 2, 3, 4), 1, &overlay, true); TestCase_assertUIntEqual(behavior.ownTileID, 0); TestCase_assertBoolFalse(behavior.exclusive); TestCase_assertIntEqual(behavior.rule.type, TILE_CONDITION_MATCH_SINGLE); TestCase_assertIntEqual(behavior.rule.rule.single.offset.x, 1); TestCase_assertIntEqual(behavior.rule.rule.single.offset.y, 2); TestCase_assertUIntEqual(behavior.rule.rule.single.tileID, 3); TestCase_assertIntEqual(behavior.sliceInsets.xMin, 1); TestCase_assertIntEqual(behavior.sliceInsets.xMax, 2); TestCase_assertIntEqual(behavior.sliceInsets.yMin, 3); TestCase_assertIntEqual(behavior.sliceInsets.yMax, 4); TestCase_assertUIntEqual(behavior.overlayCount, 1); TestCase_assertPointerNonNULL(behavior.overlays); TestCase_assertPointerUnequal(behavior.overlays, &overlay); TestCase_assertUIntEqual(behavior.overlays[0].imageID, 4); TestCase_assertIntEqual(behavior.overlays[0].offset.x, 5); TestCase_assertIntEqual(behavior.overlays[0].offset.y, 6); TestCase_assertIntEqual(behavior.overlays[0].sliceInsets.xMin, 7); TestCase_assertIntEqual(behavior.overlays[0].sliceInsets.xMax, 8); TestCase_assertIntEqual(behavior.overlays[0].sliceInsets.yMin, 9); TestCase_assertIntEqual(behavior.overlays[0].sliceInsets.yMax, 10); TestCase_assertIntEqual(behavior.overlays[0].drawPriority, 11); TileAdjacencyBehavior_dispose(&behavior); } struct queryContextStructExact { Vector2i targetPosition; TileID tileIDEqual; TileID tileIDUnequal; }; static TileID queryCallbackExact(Vector2i position, void * context) { struct queryContextStructExact * contextStruct = context; if (Vector2i_isEqual(position, contextStruct->targetPosition)) { return contextStruct->tileIDEqual; } return contextStruct->tileIDUnequal; } static void testMatchRules(void) { TileAdjacencyRule rule = {TILE_CONDITION_MATCH_SINGLE, {.single = {{1, 2}, 3}}}; TileAdjacencyBehavior behavior = TileAdjacencyBehavior_init(0, false, rule, RECT4i_EMPTY, 0, NULL, true); struct queryContextStructExact contextStruct = {{4, 4}, 3, 1}; bool applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(4, 5), queryCallbackExact, &contextStruct); TestCase_assertBoolFalse(applicable); applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(3, 2), queryCallbackExact, &contextStruct); TestCase_assertBoolTrue(applicable); behavior.rule.rule.single.tileID = TILE_ID_SELF; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(3, 2), queryCallbackExact, &contextStruct); TestCase_assertBoolFalse(applicable); behavior.ownTileID = 3; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(3, 2), queryCallbackExact, &contextStruct); TestCase_assertBoolTrue(applicable); behavior.ownTileID = 0; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(0, 0), queryCallbackExact, &contextStruct); TestCase_assertBoolFalse(applicable); behavior.rule.type = TILE_CONDITION_NONMATCH_SINGLE; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(3, 2), queryCallbackExact, &contextStruct); TestCase_assertBoolTrue(applicable); behavior.ownTileID = 3; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(3, 2), queryCallbackExact, &contextStruct); TestCase_assertBoolFalse(applicable); behavior.ownTileID = 0; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(0, 0), queryCallbackExact, &contextStruct); TestCase_assertBoolTrue(applicable); behavior.rule.type = TILE_CONDITION_MATCH_MULTIPLE; behavior.rule.rule.multiple.offset = V2i(2, 1); behavior.rule.rule.multiple.tileIDCount = 2; behavior.rule.rule.multiple.tileIDs = malloc(behavior.rule.rule.multiple.tileIDCount * sizeof(*behavior.rule.rule.multiple.tileIDs)); behavior.rule.rule.multiple.tileIDs[0] = 3; behavior.rule.rule.multiple.tileIDs[1] = TILE_ID_SELF; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(2, 3), queryCallbackExact, &contextStruct); TestCase_assertBoolTrue(applicable); applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(3, 2), queryCallbackExact, &contextStruct); TestCase_assertBoolFalse(applicable); contextStruct.tileIDEqual = 2; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(2, 3), queryCallbackExact, &contextStruct); TestCase_assertBoolFalse(applicable); behavior.ownTileID = 2; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(2, 3), queryCallbackExact, &contextStruct); TestCase_assertBoolTrue(applicable); TileAdjacencyBehavior_dispose(&behavior); } struct queryContextStructList { unsigned int targetPositionCount; Vector2i * targetPositions; TileID tileIDEqual; TileID tileIDUnequal; }; static TileID queryCallbackList(Vector2i position, void * context) { struct queryContextStructList * contextStruct = context; for (unsigned int positionIndex = 0; positionIndex < contextStruct->targetPositionCount; positionIndex++) { if (Vector2i_isEqual(position, contextStruct->targetPositions[positionIndex])) { return contextStruct->tileIDEqual; } } return contextStruct->tileIDUnequal; } static void testConditionals(void) { TileAdjacencyRule conditions[2] = { {TILE_CONDITION_MATCH_SINGLE, {.single = {{0, 1}, 3}}}, {TILE_CONDITION_MATCH_SINGLE, {.single = {{1, 0}, 3}}} }; TileAdjacencyRule rule = {TILE_CONDITION_AND, {.conditionList = {2, conditions}}}; TileAdjacencyBehavior behavior = TileAdjacencyBehavior_init(0, false, rule, RECT4i_EMPTY, 0, NULL, true); Vector2i targetPositions[2] = {{0, 1}, {1, 0}}; struct queryContextStructList contextStruct = {2, targetPositions, 3, 1}; bool applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(0, 0), queryCallbackList, &contextStruct); TestCase_assertBoolTrue(applicable); targetPositions[0].y = 0; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(0, 0), queryCallbackList, &contextStruct); TestCase_assertBoolFalse(applicable); targetPositions[0].y = 1; targetPositions[1].x = 0; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(0, 0), queryCallbackList, &contextStruct); TestCase_assertBoolFalse(applicable); targetPositions[1].x = 1; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(1, 0), queryCallbackList, &contextStruct); TestCase_assertBoolFalse(applicable); behavior.rule.type = TILE_CONDITION_OR; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(0, 0), queryCallbackList, &contextStruct); TestCase_assertBoolTrue(applicable); targetPositions[0].y = 0; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(0, 0), queryCallbackList, &contextStruct); TestCase_assertBoolTrue(applicable); targetPositions[1].x = 0; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(0, 0), queryCallbackList, &contextStruct); TestCase_assertBoolFalse(applicable); targetPositions[0].y = 1; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(0, 0), queryCallbackList, &contextStruct); TestCase_assertBoolTrue(applicable); targetPositions[1].x = 1; applicable = TileAdjacencyBehavior_isApplicable(&behavior, V2i(1, 0), queryCallbackList, &contextStruct); TestCase_assertBoolFalse(applicable); TileAdjacencyBehavior_dispose(&behavior); } TEST_SUITE(TileAdjacencyBehaviorTest, testInit, testMatchRules, testConditionals)