|
5 | 5 | #include <scratchcpp/sprite.h>
|
6 | 6 | #include <scratchcpp/stage.h>
|
7 | 7 | #include <scratchcpp/costume.h>
|
| 8 | +#include <scratchcpp/variable.h> |
8 | 9 | #include <enginemock.h>
|
9 | 10 | #include <timermock.h>
|
10 | 11 | #include <clockmock.h>
|
@@ -706,10 +707,35 @@ TEST_F(SensingBlocksTest, Of)
|
706 | 707 | addDropdownField(block20, "PROPERTY", SensingBlocks::PROPERTY, "backdrop name", SensingBlocks::BackdropName);
|
707 | 708 | addDropdownInput(block20, "OBJECT", SensingBlocks::OBJECT, "", createNullBlock("ad"));
|
708 | 709 |
|
| 710 | + // [some variable] of (Stage) |
| 711 | + auto block21 = std::make_shared<Block>("ae", "sensing_of"); |
| 712 | + addDropdownField(block21, "PROPERTY", SensingBlocks::PROPERTY, "some variable", static_cast<SensingBlocks::FieldValues>(-1)); |
| 713 | + addDropdownInput(block21, "OBJECT", SensingBlocks::OBJECT, "_stage_"); |
| 714 | + |
| 715 | + // [some invalid variable] of (Stage) |
| 716 | + auto block22 = std::make_shared<Block>("af", "sensing_of"); |
| 717 | + addDropdownField(block22, "PROPERTY", SensingBlocks::PROPERTY, "some invalid variable", static_cast<SensingBlocks::FieldValues>(-1)); |
| 718 | + addDropdownInput(block22, "OBJECT", SensingBlocks::OBJECT, "_stage_"); |
| 719 | + |
| 720 | + // [some variable] of (Sprite2) |
| 721 | + auto block23 = std::make_shared<Block>("ag", "sensing_of"); |
| 722 | + addDropdownField(block23, "PROPERTY", SensingBlocks::PROPERTY, "some variable", static_cast<SensingBlocks::FieldValues>(-1)); |
| 723 | + addDropdownInput(block23, "OBJECT", SensingBlocks::OBJECT, "Sprite2"); |
| 724 | + |
| 725 | + // [some invalid variable] of (Sprite2) |
| 726 | + auto block24 = std::make_shared<Block>("ah", "sensing_of"); |
| 727 | + addDropdownField(block24, "PROPERTY", SensingBlocks::PROPERTY, "some invalid variable", static_cast<SensingBlocks::FieldValues>(-1)); |
| 728 | + addDropdownInput(block24, "OBJECT", SensingBlocks::OBJECT, "Sprite2"); |
| 729 | + |
| 730 | + // [some variable] of (null block) |
| 731 | + auto block25 = std::make_shared<Block>("ai", "sensing_of"); |
| 732 | + addDropdownField(block25, "PROPERTY", SensingBlocks::PROPERTY, "some variable", static_cast<SensingBlocks::FieldValues>(-1)); |
| 733 | + addDropdownInput(block25, "OBJECT", SensingBlocks::OBJECT, "", createNullBlock("aj")); |
| 734 | + |
709 | 735 | compiler.init();
|
710 | 736 |
|
711 |
| - EXPECT_CALL(m_engineMock, findTarget("Sprite2")).Times(7).WillRepeatedly(Return(6)); |
712 |
| - EXPECT_CALL(m_engineMock, findTarget("_stage_")).Times(3).WillRepeatedly(Return(0)); |
| 737 | + EXPECT_CALL(m_engineMock, findTarget("Sprite2")).Times(9).WillRepeatedly(Return(6)); |
| 738 | + EXPECT_CALL(m_engineMock, findTarget("_stage_")).Times(5).WillRepeatedly(Return(0)); |
713 | 739 |
|
714 | 740 | EXPECT_CALL(m_engineMock, functionIndex(&SensingBlocks::xPositionOfSpriteByIndex)).WillOnce(Return(0));
|
715 | 741 | compiler.setBlock(block1);
|
@@ -791,6 +817,34 @@ TEST_F(SensingBlocksTest, Of)
|
791 | 817 | compiler.setBlock(block20);
|
792 | 818 | SensingBlocks::compileOf(&compiler);
|
793 | 819 |
|
| 820 | + Stage stage; |
| 821 | + auto v1 = std::make_shared<Variable>("var1", "test"); |
| 822 | + auto v2 = std::make_shared<Variable>("var2", "some variable"); |
| 823 | + stage.addVariable(v1); |
| 824 | + stage.addVariable(v2); |
| 825 | + EXPECT_CALL(m_engineMock, targetAt(0)).WillOnce(Return(&stage)); |
| 826 | + compiler.setBlock(block21); |
| 827 | + SensingBlocks::compileOf(&compiler); |
| 828 | + |
| 829 | + EXPECT_CALL(m_engineMock, targetAt(0)).WillOnce(Return(&stage)); |
| 830 | + compiler.setBlock(block22); |
| 831 | + SensingBlocks::compileOf(&compiler); |
| 832 | + |
| 833 | + Sprite sprite; |
| 834 | + auto v3 = std::make_shared<Variable>("var3", "some variable"); |
| 835 | + sprite.addVariable(v3); |
| 836 | + EXPECT_CALL(m_engineMock, targetAt(6)).WillOnce(Return(&sprite)); |
| 837 | + compiler.setBlock(block23); |
| 838 | + SensingBlocks::compileOf(&compiler); |
| 839 | + |
| 840 | + EXPECT_CALL(m_engineMock, targetAt(6)).WillOnce(Return(&sprite)); |
| 841 | + compiler.setBlock(block24); |
| 842 | + SensingBlocks::compileOf(&compiler); |
| 843 | + |
| 844 | + EXPECT_CALL(m_engineMock, functionIndex(&SensingBlocks::variableOfTarget)).WillOnce(Return(18)); |
| 845 | + compiler.setBlock(block25); |
| 846 | + SensingBlocks::compileOf(&compiler); |
| 847 | + |
794 | 848 | compiler.end();
|
795 | 849 |
|
796 | 850 | ASSERT_EQ(
|
@@ -867,8 +921,20 @@ TEST_F(SensingBlocksTest, Of)
|
867 | 921 | vm::OP_NULL,
|
868 | 922 | vm::OP_EXEC,
|
869 | 923 | 17,
|
| 924 | + vm::OP_READ_VAR, |
| 925 | + 0, |
| 926 | + vm::OP_NULL, |
| 927 | + vm::OP_READ_VAR, |
| 928 | + 1, |
| 929 | + vm::OP_NULL, |
| 930 | + vm::OP_CONST, |
| 931 | + 10, |
| 932 | + vm::OP_NULL, |
| 933 | + vm::OP_EXEC, |
| 934 | + 18, |
870 | 935 | vm::OP_HALT }));
|
871 |
| - ASSERT_EQ(compiler.constValues(), std::vector<Value>({ 6, 6, 6, 6, 6, 6, 6, 0, 0, 0 })); |
| 936 | + ASSERT_EQ(compiler.constValues(), std::vector<Value>({ 6, 6, 6, 6, 6, 6, 6, 0, 0, 0, "some variable" })); |
| 937 | + ASSERT_EQ(compiler.variables(), std::vector<Variable *>({ v2.get(), v3.get() })); |
872 | 938 | }
|
873 | 939 |
|
874 | 940 | TEST_F(SensingBlocksTest, XPositionOfSprite)
|
@@ -1114,6 +1180,75 @@ TEST_F(SensingBlocksTest, VolumeOfTarget)
|
1114 | 1180 | ASSERT_EQ(vm.getInput(0, 1)->toDouble(), stage.volume());
|
1115 | 1181 | }
|
1116 | 1182 |
|
| 1183 | +TEST_F(SensingBlocksTest, VariableOfTarget) |
| 1184 | +{ |
| 1185 | + static unsigned int bytecode1[] = { vm::OP_START, vm::OP_CONST, 0, vm::OP_CONST, 2, vm::OP_EXEC, 0, vm::OP_HALT }; |
| 1186 | + static unsigned int bytecode2[] = { vm::OP_START, vm::OP_CONST, 1, vm::OP_CONST, 2, vm::OP_EXEC, 0, vm::OP_HALT }; |
| 1187 | + static unsigned int bytecode3[] = { vm::OP_START, vm::OP_CONST, 0, vm::OP_CONST, 3, vm::OP_EXEC, 0, vm::OP_HALT }; |
| 1188 | + static unsigned int bytecode4[] = { vm::OP_START, vm::OP_CONST, 1, vm::OP_CONST, 3, vm::OP_EXEC, 0, vm::OP_HALT }; |
| 1189 | + static unsigned int bytecode5[] = { vm::OP_START, vm::OP_CONST, 0, vm::OP_CONST, 4, vm::OP_EXEC, 0, vm::OP_HALT }; |
| 1190 | + static BlockFunc functions[] = { &SensingBlocks::variableOfTarget }; |
| 1191 | + static Value constValues[] = { "variable", "invalid variable", "Sprite2", "_stage_", "test" }; |
| 1192 | + |
| 1193 | + Sprite sprite; |
| 1194 | + auto v1 = std::make_shared<Variable>("var1", "variable", 64.13); |
| 1195 | + sprite.addVariable(v1); |
| 1196 | + |
| 1197 | + Stage stage; |
| 1198 | + auto v2 = std::make_shared<Variable>("var2", "test", 98); |
| 1199 | + auto v3 = std::make_shared<Variable>("var3", "variable", -0.85); |
| 1200 | + stage.addVariable(v2); |
| 1201 | + stage.addVariable(v3); |
| 1202 | + |
| 1203 | + VirtualMachine vm(nullptr, &m_engineMock, nullptr); |
| 1204 | + vm.setFunctions(functions); |
| 1205 | + vm.setConstValues(constValues); |
| 1206 | + |
| 1207 | + EXPECT_CALL(m_engineMock, findTarget("Sprite2")).WillOnce(Return(6)); |
| 1208 | + EXPECT_CALL(m_engineMock, targetAt(6)).WillOnce(Return(&sprite)); |
| 1209 | + vm.setBytecode(bytecode1); |
| 1210 | + vm.run(); |
| 1211 | + |
| 1212 | + ASSERT_EQ(vm.registerCount(), 1); |
| 1213 | + ASSERT_EQ(vm.getInput(0, 1)->toDouble(), v1->value().toDouble()); |
| 1214 | + |
| 1215 | + EXPECT_CALL(m_engineMock, findTarget("Sprite2")).WillOnce(Return(6)); |
| 1216 | + EXPECT_CALL(m_engineMock, targetAt(6)).WillOnce(Return(&sprite)); |
| 1217 | + vm.reset(); |
| 1218 | + vm.setBytecode(bytecode2); |
| 1219 | + vm.run(); |
| 1220 | + |
| 1221 | + ASSERT_EQ(vm.registerCount(), 1); |
| 1222 | + ASSERT_EQ(vm.getInput(0, 1)->toDouble(), 0); |
| 1223 | + |
| 1224 | + EXPECT_CALL(m_engineMock, findTarget("_stage_")).WillOnce(Return(0)); |
| 1225 | + EXPECT_CALL(m_engineMock, targetAt(0)).WillOnce(Return(&stage)); |
| 1226 | + vm.reset(); |
| 1227 | + vm.setBytecode(bytecode3); |
| 1228 | + vm.run(); |
| 1229 | + |
| 1230 | + ASSERT_EQ(vm.registerCount(), 1); |
| 1231 | + ASSERT_EQ(vm.getInput(0, 1)->toDouble(), v3->value().toDouble()); |
| 1232 | + |
| 1233 | + EXPECT_CALL(m_engineMock, findTarget("_stage_")).WillOnce(Return(0)); |
| 1234 | + EXPECT_CALL(m_engineMock, targetAt(0)).WillOnce(Return(&stage)); |
| 1235 | + vm.reset(); |
| 1236 | + vm.setBytecode(bytecode4); |
| 1237 | + vm.run(); |
| 1238 | + |
| 1239 | + ASSERT_EQ(vm.registerCount(), 1); |
| 1240 | + ASSERT_EQ(vm.getInput(0, 1)->toDouble(), 0); |
| 1241 | + |
| 1242 | + EXPECT_CALL(m_engineMock, findTarget("test")).WillOnce(Return(-1)); |
| 1243 | + EXPECT_CALL(m_engineMock, targetAt(-1)).WillOnce(Return(nullptr)); |
| 1244 | + vm.reset(); |
| 1245 | + vm.setBytecode(bytecode5); |
| 1246 | + vm.run(); |
| 1247 | + |
| 1248 | + ASSERT_EQ(vm.registerCount(), 1); |
| 1249 | + ASSERT_EQ(vm.getInput(0, 1)->toDouble(), 0); |
| 1250 | +} |
| 1251 | + |
1117 | 1252 | TEST_F(SensingBlocksTest, BackdropNumberOfStage)
|
1118 | 1253 | {
|
1119 | 1254 | static unsigned int bytecode1[] = { vm::OP_START, vm::OP_CONST, 0, vm::OP_EXEC, 0, vm::OP_HALT };
|
|
0 commit comments