|
4 | 4 | #include <scratchcpp/sprite.h> |
5 | 5 | #include <scratchcpp/block.h> |
6 | 6 | #include <scratchcpp/input.h> |
| 7 | +#include <scratchcpp/field.h> |
7 | 8 | #include <scratchcpp/script.h> |
8 | 9 | #include <scratchcpp/thread.h> |
9 | 10 | #include <scratchcpp/dev/executablecode.h> |
10 | 11 | #include <scratchcpp/dev/executioncontext.h> |
| 12 | +#include <scratchcpp/variable.h> |
11 | 13 |
|
12 | 14 | #include <enginemock.h> |
13 | 15 | #include <stacktimermock.h> |
@@ -646,3 +648,109 @@ TEST_F(ControlBlocksTest, While) |
646 | 648 | } |
647 | 649 | } |
648 | 650 | } |
| 651 | + |
| 652 | +TEST_F(ControlBlocksTest, ForEach) |
| 653 | +{ |
| 654 | + auto target = std::make_shared<Sprite>(); |
| 655 | + auto var1 = std::make_shared<Variable>("", ""); |
| 656 | + auto var2 = std::make_shared<Variable>("", ""); |
| 657 | + target->addVariable(var1); |
| 658 | + target->addVariable(var2); |
| 659 | + |
| 660 | + { |
| 661 | + ScriptBuilder builder(m_extension.get(), m_engine, target); |
| 662 | + |
| 663 | + builder.addBlock("control_for_each"); |
| 664 | + |
| 665 | + auto substack = std::make_shared<Block>("", "test_print"); |
| 666 | + auto input = std::make_shared<Input>("STRING", Input::Type::ObscuredShadow); |
| 667 | + input->primaryValue()->setValuePtr(var1); |
| 668 | + substack->addInput(input); |
| 669 | + |
| 670 | + builder.addObscuredInput("SUBSTACK", substack); |
| 671 | + |
| 672 | + builder.addValueInput("VALUE", 5); |
| 673 | + builder.addEntityField("VARIABLE", var1); |
| 674 | + |
| 675 | + builder.addBlock("control_for_each"); |
| 676 | + substack = std::make_shared<Block>("", "test_print_test"); |
| 677 | + builder.addObscuredInput("SUBSTACK", substack); |
| 678 | + builder.addNullObscuredInput("VALUE"); |
| 679 | + builder.addEntityField("VARIABLE", var2); |
| 680 | + |
| 681 | + builder.build(); |
| 682 | + |
| 683 | + var1->setValue(10); |
| 684 | + testing::internal::CaptureStdout(); |
| 685 | + builder.run(); |
| 686 | + ASSERT_EQ(testing::internal::GetCapturedStdout(), "1\n2\n3\n4\n5\n"); |
| 687 | + ASSERT_EQ(var1->value(), 5); |
| 688 | + } |
| 689 | + |
| 690 | + m_engine->clear(); |
| 691 | + target = std::make_shared<Sprite>(); |
| 692 | + target->addVariable(var1); |
| 693 | + |
| 694 | + { |
| 695 | + ScriptBuilder builder(m_extension.get(), m_engine, target); |
| 696 | + |
| 697 | + builder.addBlock("control_for_each"); |
| 698 | + |
| 699 | + auto substack = std::make_shared<Block>("", "test_print"); |
| 700 | + auto input = std::make_shared<Input>("STRING", Input::Type::ObscuredShadow); |
| 701 | + input->primaryValue()->setValuePtr(var1); |
| 702 | + substack->addInput(input); |
| 703 | + |
| 704 | + auto setVar = std::make_shared<Block>("", "test_set_var"); |
| 705 | + substack->setNext(setVar); |
| 706 | + setVar->setParent(substack); |
| 707 | + auto field = std::make_shared<Field>("VARIABLE", ""); |
| 708 | + setVar->addField(field); |
| 709 | + input = std::make_shared<Input>("VALUE", Input::Type::Shadow); |
| 710 | + input->setPrimaryValue(0); |
| 711 | + setVar->addInput(input); |
| 712 | + |
| 713 | + auto printAgain = std::make_shared<Block>("", "test_print"); |
| 714 | + setVar->setNext(printAgain); |
| 715 | + printAgain->setParent(setVar); |
| 716 | + input = std::make_shared<Input>("STRING", Input::Type::ObscuredShadow); |
| 717 | + printAgain->addInput(input); |
| 718 | + |
| 719 | + builder.addObscuredInput("SUBSTACK", substack); |
| 720 | + |
| 721 | + builder.addValueInput("VALUE", 3); |
| 722 | + builder.addEntityField("VARIABLE", var1); |
| 723 | + |
| 724 | + field->setValuePtr(var1); |
| 725 | + input->primaryValue()->setValuePtr(var1); |
| 726 | + |
| 727 | + builder.build(); |
| 728 | + |
| 729 | + var1->setValue(7); |
| 730 | + testing::internal::CaptureStdout(); |
| 731 | + builder.run(); |
| 732 | + ASSERT_EQ(testing::internal::GetCapturedStdout(), "1\n0\n2\n0\n3\n0\n"); |
| 733 | + ASSERT_EQ(var1->value(), 0); |
| 734 | + } |
| 735 | + |
| 736 | + m_engine->clear(); |
| 737 | + target = std::make_shared<Sprite>(); |
| 738 | + target->addVariable(var1); |
| 739 | + |
| 740 | + { |
| 741 | + ScriptBuilder builder(m_extension.get(), m_engine, target); |
| 742 | + builder.addBlock("control_for_each"); |
| 743 | + builder.addValueInput("VALUE", "Infinity"); |
| 744 | + builder.addEntityField("VARIABLE", var1); |
| 745 | + |
| 746 | + builder.build(); |
| 747 | + m_engine->start(); |
| 748 | + |
| 749 | + for (int i = 0; i < 2; i++) { |
| 750 | + m_engine->step(); |
| 751 | + ASSERT_TRUE(m_engine->isRunning()); |
| 752 | + } |
| 753 | + |
| 754 | + ASSERT_GT(var1->value(), 0); |
| 755 | + } |
| 756 | +} |
0 commit comments