77#include < scratchcpp/thread.h>
88#include < scratchcpp/executablecode.h>
99#include < scratchcpp/executioncontext.h>
10+ #include < scratchcpp/scratchconfiguration.h>
1011#include < enginemock.h>
1112#include < graphicseffectmock.h>
1213#include < stacktimermock.h>
@@ -18,6 +19,8 @@ using namespace libscratchcpp;
1819using namespace libscratchcpp ::test;
1920
2021using ::testing::Return;
22+ using ::testing::ReturnArg;
23+ using ::testing::_;
2124
2225class LooksBlocksTest : public testing ::Test
2326{
@@ -28,6 +31,56 @@ class LooksBlocksTest : public testing::Test
2831 m_engine = m_project.engine ().get ();
2932 m_extension->registerBlocks (m_engine);
3033 m_extension->onInit (m_engine);
34+
35+ // Create and register fake graphic effects
36+ auto colorEffect = std::make_shared<GraphicsEffectMock>();
37+ auto fisheyeEffect = std::make_shared<GraphicsEffectMock>();
38+ auto whirlEffect = std::make_shared<GraphicsEffectMock>();
39+ auto pixelateEffect = std::make_shared<GraphicsEffectMock>();
40+ auto mosaicEffect = std::make_shared<GraphicsEffectMock>();
41+ auto brightnessEffect = std::make_shared<GraphicsEffectMock>();
42+ auto ghostEffect = std::make_shared<GraphicsEffectMock>();
43+
44+ EXPECT_CALL (*colorEffect, name ()).WillOnce (Return (" COLOR" ));
45+ ScratchConfiguration::registerGraphicsEffect (colorEffect);
46+
47+ EXPECT_CALL (*fisheyeEffect, name ()).WillOnce (Return (" FISHEYE" ));
48+ ScratchConfiguration::registerGraphicsEffect (fisheyeEffect);
49+
50+ EXPECT_CALL (*whirlEffect, name ()).WillOnce (Return (" WHIRL" ));
51+ ScratchConfiguration::registerGraphicsEffect (whirlEffect);
52+
53+ EXPECT_CALL (*pixelateEffect, name ()).WillOnce (Return (" PIXELATE" ));
54+ ScratchConfiguration::registerGraphicsEffect (pixelateEffect);
55+
56+ EXPECT_CALL (*mosaicEffect, name ()).WillOnce (Return (" MOSAIC" ));
57+ ScratchConfiguration::registerGraphicsEffect (mosaicEffect);
58+
59+ EXPECT_CALL (*brightnessEffect, name ()).WillOnce (Return (" BRIGHTNESS" ));
60+ ScratchConfiguration::registerGraphicsEffect (brightnessEffect);
61+
62+ EXPECT_CALL (*ghostEffect, name ()).WillOnce (Return (" GHOST" ));
63+ ScratchConfiguration::registerGraphicsEffect (ghostEffect);
64+
65+ EXPECT_CALL (*colorEffect, clamp (_)).WillRepeatedly (ReturnArg<0 >());
66+ EXPECT_CALL (*fisheyeEffect, clamp (_)).WillRepeatedly (ReturnArg<0 >());
67+ EXPECT_CALL (*whirlEffect, clamp (_)).WillRepeatedly (ReturnArg<0 >());
68+ EXPECT_CALL (*pixelateEffect, clamp (_)).WillRepeatedly (ReturnArg<0 >());
69+ EXPECT_CALL (*mosaicEffect, clamp (_)).WillRepeatedly (ReturnArg<0 >());
70+ EXPECT_CALL (*brightnessEffect, clamp (_)).WillRepeatedly (ReturnArg<0 >());
71+ EXPECT_CALL (*ghostEffect, clamp (_)).WillRepeatedly (ReturnArg<0 >());
72+ }
73+
74+ void TearDown () override
75+ {
76+ // Remove fake graphic effects
77+ ScratchConfiguration::removeGraphicsEffect (" COLOR" );
78+ ScratchConfiguration::removeGraphicsEffect (" FISHEYE" );
79+ ScratchConfiguration::removeGraphicsEffect (" WHIRL" );
80+ ScratchConfiguration::removeGraphicsEffect (" PIXELATE" );
81+ ScratchConfiguration::removeGraphicsEffect (" MOSAIC" );
82+ ScratchConfiguration::removeGraphicsEffect (" BRIGHTNESS" );
83+ ScratchConfiguration::removeGraphicsEffect (" GHOST" );
3184 }
3285
3386 std::unique_ptr<IExtension> m_extension;
@@ -260,3 +313,94 @@ TEST_F(LooksBlocksTest, Hide)
260313 builder.run ();
261314 }
262315}
316+
317+ TEST_F (LooksBlocksTest, ChangeEffectBy)
318+ {
319+ // Color
320+ {
321+ auto stage = std::make_shared<Stage>();
322+ stage->setEngine (m_engine);
323+
324+ ScriptBuilder builder (m_extension.get (), m_engine, stage);
325+ IGraphicsEffect *effect = ScratchConfiguration::getGraphicsEffect (" COLOR" );
326+ ASSERT_TRUE (effect);
327+
328+ builder.addBlock (" looks_changeeffectby" );
329+ builder.addDropdownField (" EFFECT" , " COLOR" );
330+ builder.addValueInput (" CHANGE" , 45.2 );
331+ auto block = builder.currentBlock ();
332+
333+ Compiler compiler (m_engine, stage.get ());
334+ auto code = compiler.compile (block);
335+ Script script (stage.get (), block, m_engine);
336+ script.setCode (code);
337+ Thread thread (stage.get (), m_engine, &script);
338+
339+ stage->setGraphicsEffectValue (effect, 86.84 );
340+ thread.run ();
341+ ASSERT_EQ (std::round (stage->graphicsEffectValue (effect) * 100 ) / 100 , 132.04 );
342+ }
343+
344+ // Brightness
345+ {
346+ auto stage = std::make_shared<Stage>();
347+ stage->setEngine (m_engine);
348+
349+ ScriptBuilder builder (m_extension.get (), m_engine, stage);
350+ IGraphicsEffect *effect = ScratchConfiguration::getGraphicsEffect (" BRIGHTNESS" );
351+ ASSERT_TRUE (effect);
352+
353+ builder.addBlock (" looks_changeeffectby" );
354+ builder.addDropdownField (" EFFECT" , " BRIGHTNESS" );
355+ builder.addValueInput (" CHANGE" , 12.05 );
356+ auto block = builder.currentBlock ();
357+
358+ Compiler compiler (m_engine, stage.get ());
359+ auto code = compiler.compile (block);
360+ Script script (stage.get (), block, m_engine);
361+ script.setCode (code);
362+ Thread thread (stage.get (), m_engine, &script);
363+
364+ thread.run ();
365+ ASSERT_EQ (std::round (stage->graphicsEffectValue (effect) * 100 ) / 100 , 12.05 );
366+ }
367+
368+ // Ghost
369+ {
370+ auto stage = std::make_shared<Stage>();
371+ stage->setEngine (m_engine);
372+
373+ ScriptBuilder builder (m_extension.get (), m_engine, stage);
374+ IGraphicsEffect *effect = ScratchConfiguration::getGraphicsEffect (" GHOST" );
375+ ASSERT_TRUE (effect);
376+
377+ builder.addBlock (" looks_changeeffectby" );
378+ builder.addDropdownField (" EFFECT" , " GHOST" );
379+ builder.addValueInput (" CHANGE" , -8.06 );
380+ auto block = builder.currentBlock ();
381+
382+ Compiler compiler (m_engine, stage.get ());
383+ auto code = compiler.compile (block);
384+ Script script (stage.get (), block, m_engine);
385+ script.setCode (code);
386+ Thread thread (stage.get (), m_engine, &script);
387+
388+ stage->setGraphicsEffectValue (effect, 13.12 );
389+ thread.run ();
390+ ASSERT_EQ (std::round (stage->graphicsEffectValue (effect) * 100 ) / 100 , 5.06 );
391+ }
392+
393+ // Invalid
394+ {
395+ auto stage = std::make_shared<Stage>();
396+ stage->setEngine (m_engine);
397+
398+ ScriptBuilder builder (m_extension.get (), m_engine, stage);
399+ builder.addBlock (" looks_changeeffectby" );
400+ builder.addDropdownField (" EFFECT" , " INVALID" );
401+ builder.addValueInput (" CHANGE" , 8.3 );
402+
403+ builder.build ();
404+ builder.run ();
405+ }
406+ }
0 commit comments