77#include < scratchcpp/variable.h>
88#include < scratchcpp/list.h>
99#include < dev/engine/internal/llvm/llvmcodebuilder.h>
10+ #include < dev/engine/internal/llvm/llvmfunctions.h>
1011#include < gmock/gmock.h>
1112#include < targetmock.h>
1213#include < enginemock.h>
14+ #include < randomgeneratormock.h>
1315
1416#include " testfunctions.h"
1517
@@ -27,6 +29,7 @@ class LLVMCodeBuilderTest : public testing::Test
2729 Sub,
2830 Mul,
2931 Div,
32+ Random,
3033 CmpEQ,
3134 CmpGT,
3235 CmpLT,
@@ -49,7 +52,6 @@ class LLVMCodeBuilderTest : public testing::Test
4952 Log10,
5053 Exp,
5154 Exp10
52-
5355 };
5456
5557 void SetUp () override
@@ -93,6 +95,9 @@ class LLVMCodeBuilderTest : public testing::Test
9395 case OpType::Div:
9496 return m_builder->createDiv (arg1, arg2);
9597
98+ case OpType::Random:
99+ return m_builder->createRandom (arg1, arg2);
100+
96101 case OpType::CmpEQ:
97102 return m_builder->createCmpEQ (arg1, arg2);
98103
@@ -189,6 +194,15 @@ class LLVMCodeBuilderTest : public testing::Test
189194 case OpType::Div:
190195 return v1 / v2;
191196
197+ case OpType::Random: {
198+ const double sum = v1.toDouble () + v2.toDouble ();
199+
200+ if (std::isnan (sum) || std::isinf (sum))
201+ return sum;
202+
203+ return v1.isInt () && v2.isInt () ? m_rng.randint (v1.toLong (), v2.toLong ()) : m_rng.randintDouble (v1.toDouble (), v2.toDouble ());
204+ }
205+
192206 case OpType::CmpEQ:
193207 return v1 == v2;
194208
@@ -225,7 +239,7 @@ class LLVMCodeBuilderTest : public testing::Test
225239 }
226240 }
227241
228- void runOpTest (OpType type, const Value &v1, const Value &v2)
242+ void runOpTestCommon (OpType type, const Value &v1, const Value &v2)
229243 {
230244 createBuilder (true );
231245
@@ -241,9 +255,6 @@ class LLVMCodeBuilderTest : public testing::Test
241255 ret = addOp (type, arg1, arg2);
242256 m_builder->addFunctionCall (" test_print_string" , Compiler::StaticType::Void, { Compiler::StaticType::String }, { ret });
243257
244- std::string str = doOp (type, v1, v2).toString () + ' \n ' ;
245- std::string expected = str + str;
246-
247258 auto code = m_builder->finalize ();
248259 Script script (&m_target, nullptr , nullptr );
249260 script.setCode (code);
@@ -252,9 +263,28 @@ class LLVMCodeBuilderTest : public testing::Test
252263
253264 testing::internal::CaptureStdout ();
254265 code->run (ctx.get ());
266+ }
267+
268+ void checkOpTest (const Value &v1, const Value &v2, const std::string &expected)
269+ {
255270 const std::string quotes1 = v1.isString () ? " \" " : " " ;
256271 const std::string quotes2 = v2.isString () ? " \" " : " " ;
257272 ASSERT_THAT (testing::internal::GetCapturedStdout (), Eq (expected)) << quotes1 << v1.toString () << quotes1 << " " << quotes2 << v2.toString () << quotes2;
273+ }
274+
275+ void runOpTest (OpType type, const Value &v1, const Value &v2, const Value &expected)
276+ {
277+ std::string str = expected.toString ();
278+ runOpTestCommon (type, v1, v2);
279+ checkOpTest (v1, v2, str + ' \n ' + str + ' \n ' );
280+ };
281+
282+ void runOpTest (OpType type, const Value &v1, const Value &v2)
283+ {
284+ runOpTestCommon (type, v1, v2);
285+ std::string str = doOp (type, v1, v2).toString () + ' \n ' ;
286+ std::string expected = str + str;
287+ checkOpTest (v1, v2, expected);
258288 };
259289
260290 void runOpTest (OpType type, const Value &v)
@@ -317,6 +347,7 @@ class LLVMCodeBuilderTest : public testing::Test
317347
318348 std::unique_ptr<LLVMCodeBuilder> m_builder;
319349 TargetMock m_target; // NOTE: isStage() is used for call expectations
350+ RandomGeneratorMock m_rng;
320351};
321352
322353TEST_F (LLVMCodeBuilderTest, FunctionCalls)
@@ -605,6 +636,90 @@ TEST_F(LLVMCodeBuilderTest, Divide)
605636 runOpTest (OpType::Div, 0 , 0 );
606637}
607638
639+ TEST_F (LLVMCodeBuilderTest, Random)
640+ {
641+ llvm_rng = &m_rng;
642+
643+ EXPECT_CALL (m_rng, randint (-45 , 12 )).Times (3 ).WillRepeatedly (Return (-18 ));
644+ runOpTest (OpType::Random, -45 , 12 );
645+
646+ EXPECT_CALL (m_rng, randint (-45 , 12 )).Times (3 ).WillRepeatedly (Return (5 ));
647+ runOpTest (OpType::Random, -45.0 , 12.0 );
648+
649+ EXPECT_CALL (m_rng, randintDouble (12 , 6.05 )).Times (3 ).WillRepeatedly (Return (3.486789 ));
650+ runOpTest (OpType::Random, 12 , 6.05 );
651+
652+ EXPECT_CALL (m_rng, randintDouble (-78.686 , -45 )).Times (3 ).WillRepeatedly (Return (-59.468873 ));
653+ runOpTest (OpType::Random, -78.686 , -45 );
654+
655+ EXPECT_CALL (m_rng, randintDouble (6.05 , -78.686 )).Times (3 ).WillRepeatedly (Return (-28.648764 ));
656+ runOpTest (OpType::Random, 6.05 , -78.686 );
657+
658+ EXPECT_CALL (m_rng, randint (-45 , 12 )).Times (3 ).WillRepeatedly (Return (0 ));
659+ runOpTest (OpType::Random, " -45" , " 12" );
660+
661+ EXPECT_CALL (m_rng, randintDouble (-45 , 12 )).Times (3 ).WillRepeatedly (Return (5.2 ));
662+ runOpTest (OpType::Random, " -45.0" , " 12" );
663+
664+ EXPECT_CALL (m_rng, randintDouble (-45 , 12 )).Times (3 ).WillRepeatedly (Return (-15.5787 ));
665+ runOpTest (OpType::Random, " -45" , " 12.0" );
666+
667+ EXPECT_CALL (m_rng, randintDouble (-45 , 12 )).Times (3 ).WillRepeatedly (Return (2.587964 ));
668+ runOpTest (OpType::Random, " -45.0" , " 12.0" );
669+
670+ EXPECT_CALL (m_rng, randintDouble (6.05 , -78.686 )).Times (3 ).WillRepeatedly (Return (5.648764 ));
671+ runOpTest (OpType::Random, " 6.05" , " -78.686" );
672+
673+ EXPECT_CALL (m_rng, randint (-45 , 12 )).Times (3 ).WillRepeatedly (Return (0 ));
674+ runOpTest (OpType::Random, " -45" , 12 );
675+
676+ EXPECT_CALL (m_rng, randint (-45 , 12 )).Times (3 ).WillRepeatedly (Return (0 ));
677+ runOpTest (OpType::Random, -45 , " 12" );
678+
679+ EXPECT_CALL (m_rng, randintDouble (-45 , 12 )).Times (3 ).WillRepeatedly (Return (5.2 ));
680+ runOpTest (OpType::Random, " -45.0" , 12 );
681+
682+ EXPECT_CALL (m_rng, randintDouble (-45 , 12 )).Times (3 ).WillRepeatedly (Return (-15.5787 ));
683+ runOpTest (OpType::Random, -45 , " 12.0" );
684+
685+ EXPECT_CALL (m_rng, randintDouble (6.05 , -78.686 )).Times (3 ).WillRepeatedly (Return (5.648764 ));
686+ runOpTest (OpType::Random, 6.05 , " -78.686" );
687+
688+ EXPECT_CALL (m_rng, randintDouble (6.05 , -78.686 )).Times (3 ).WillRepeatedly (Return (5.648764 ));
689+ runOpTest (OpType::Random, " 6.05" , -78.686 );
690+
691+ EXPECT_CALL (m_rng, randint (0 , 1 )).Times (3 ).WillRepeatedly (Return (1 ));
692+ runOpTest (OpType::Random, false , true );
693+
694+ EXPECT_CALL (m_rng, randint (1 , 5 )).Times (3 ).WillRepeatedly (Return (1 ));
695+ runOpTest (OpType::Random, true , 5 );
696+
697+ EXPECT_CALL (m_rng, randint (8 , 0 )).Times (3 ).WillRepeatedly (Return (1 ));
698+ runOpTest (OpType::Random, 8 , false );
699+
700+ const double inf = std::numeric_limits<double >::infinity ();
701+ const double nan = std::numeric_limits<double >::quiet_NaN ();
702+ EXPECT_CALL (m_rng, randint).WillRepeatedly (Return (0 ));
703+ EXPECT_CALL (m_rng, randintDouble).WillRepeatedly (Return (0 ));
704+
705+ runOpTest (OpType::Random, inf, 2 , inf);
706+ runOpTest (OpType::Random, -8 , inf, inf);
707+ runOpTest (OpType::Random, -inf, -2 , -inf);
708+ runOpTest (OpType::Random, 8 , -inf, -inf);
709+
710+ runOpTest (OpType::Random, inf, 2.5 , inf);
711+ runOpTest (OpType::Random, -8.09 , inf, inf);
712+ runOpTest (OpType::Random, -inf, -2.5 , -inf);
713+ runOpTest (OpType::Random, 8.09 , -inf, -inf);
714+
715+ runOpTest (OpType::Random, inf, inf, inf);
716+ runOpTest (OpType::Random, -inf, -inf, -inf);
717+ runOpTest (OpType::Random, inf, -inf, nan);
718+ runOpTest (OpType::Random, -inf, inf, nan);
719+
720+ llvm_rng = nullptr ;
721+ }
722+
608723TEST_F (LLVMCodeBuilderTest, EqualComparison)
609724{
610725 runOpTest (OpType::CmpEQ, 10 , 10 );
0 commit comments