em = new ExpressionManager(); } // public function testVariables() // { // $vars = array( // 'one' => array('sgqa'=>'one', 'code'=>1, 'jsName'=>'java_one', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>4), // 'two' => array('sgqa'=>'two', 'code'=>2, 'jsName'=>'java_two', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>4), // 'three' => array('sgqa'=>'three', 'code'=>3, 'jsName'=>'java_three', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>4), // 'four' => array('sgqa'=>'four', 'code'=>4, 'jsName'=>'java_four', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>1), // 'five' => array('sgqa'=>'five', 'code'=>5, 'jsName'=>'java_five', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>1), // 'six' => array('sgqa'=>'six', 'code'=>6, 'jsName'=>'java_six', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>1), // 'seven' => array('sgqa'=>'seven', 'code'=>7, 'jsName'=>'java_seven', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>5), // 'eight' => array('sgqa'=>'eight', 'code'=>8, 'jsName'=>'java_eight', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>5), // 'nine' => array('sgqa'=>'nine', 'code'=>9, 'jsName'=>'java_nine', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>5), // 'ten' => array('sgqa'=>'ten', 'code'=>10, 'jsName'=>'java_ten', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), // 'half' => array('sgqa'=>'half', 'code'=>.5, 'jsName'=>'java_half', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), // 'hi' => array('sgqa'=>'hi', 'code'=>'there', 'jsName'=>'java_hi', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), // 'hello' => array('sgqa'=>'hello', 'code'=>"Tom", 'jsName'=>'java_hello', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), // 'a' => array('sgqa'=>'a', 'code'=>0, 'jsName'=>'java_a', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>2), // 'b' => array('sgqa'=>'b', 'code'=>0, 'jsName'=>'java_b', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>2), // 'c' => array('sgqa'=>'c', 'code'=>0, 'jsName'=>'java_c', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>2), // 'd' => array('sgqa'=>'d', 'code'=>0, 'jsName'=>'java_d', 'readWrite'=>'Y', 'gseq'=>2,'qseq'=>2), // 'eleven' => array('sgqa'=>'eleven', 'code'=>11, 'jsName'=>'java_eleven', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), // 'twelve' => array('sgqa'=>'twelve', 'code'=>12, 'jsName'=>'java_twelve', 'readWrite'=>'Y', 'gseq'=>1,'qseq'=>1), // // Constants // 'ASSESSMENT_HEADING' => array('sgqa'=>'ASSESSMENT_HEADING', 'code'=>'"Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"', 'jsName'=>'', 'readWrite'=>'N'), // 'QID' => array('sgqa'=>'QID', 'code'=>'value for {QID}', 'jsName'=>'', 'readWrite'=>'N'), // 'QUESTIONHELP' => array('sgqa'=>'QUESTIONHELP', 'code'=>'"can single quoted strings" . \'contain nested \'quoted sections\'?', 'jsName'=>'', 'readWrite'=>'N'), // 'QUESTION_HELP' => array('sgqa'=>'QUESTION_HELP', 'code'=>'Can strings have embedded like , or even unbalanced "quotes or entities without terminal semicolons like & and <?', 'jsName'=>'', 'readWrite'=>'N'), // 'NUMBEROFQUESTIONS' => array('sgqa'=>'NUMBEROFQUESTIONS', 'code'=>'value for {NUMBEROFQUESTIONS}', 'jsName'=>'', 'readWrite'=>'N'), // 'THEREAREXQUESTIONS' => array('sgqa'=>'THEREAREXQUESTIONS', 'code'=>'value for {THEREAREXQUESTIONS}', 'jsName'=>'', 'readWrite'=>'N'), // 'TOKEN:FIRSTNAME' => array('sgqa'=>'TOKEN:FIRSTNAME', 'code' => 'value for {TOKEN:FIRSTNAME}', 'jsName' => '', 'readWrite' => 'N'), // 'WELCOME' => array('sgqa'=>'WELCOME', 'code'=>'value for {WELCOME}', 'jsName'=>'', 'readWrite'=>'N'), // // also include SGQA values and read-only variable attributes // '12X34X56' => array('sgqa'=>'12X34X56', 'code'=>5, 'jsName'=>'', 'readWrite'=>'N', 'gseq'=>1,'qseq'=>1), // '12X3X5lab1_ber' => array('sgqa'=>'12X3X5lab1_ber', 'code'=>10, 'jsName'=>'', 'readWrite'=>'N', 'gseq'=>1,'qseq'=>1), // 'q5pointChoice' => array('sgqa'=>'q5pointChoice', 'code'=> 3, 'jsName'=>'java_q5pointChoice', 'readWrite'=>'N','shown'=>'Father', 'relevance'=>1, 'type'=>'5', 'question'=>'(question for q5pointChoice)', 'qid'=>14,'gseq'=>2,'qseq'=>14), // 'qArrayNumbers_ls1_min' => array('sgqa'=>'qArrayNumbers_ls1_min', 'code'=> 7, 'jsName'=>'java_qArrayNumbers_ls1_min', 'readWrite'=>'N','shown'=> 'I love LimeSurvey', 'relevance'=>1, 'type'=>'A', 'question'=>'(question for qArrayNumbers)', 'qid'=>6,'gseq'=>2,'qseq'=>6), // '12X3X5lab1_ber#1' => array('sgqa'=>'12X3X5lab1_ber#1', 'code'=> 15, 'jsName'=>'', 'readWrite'=>'N', 'gseq'=>1,'qseq'=>1), // 'zero' => array('sgqa'=>'zero', 'code'=>0, 'jsName'=>'java_zero', 'gseq'=>0,'qseq'=>0), // 'empty' => array('sgqa'=>'empty', 'code'=>'', 'jsName'=>'java_empty', 'gseq'=>0,'qseq'=>0), // 'BREAKS' => array('sgqa'=>'BREAKS', 'code'=>"1\n2\n3", 'jsName'=>'', 'readWrite'=>'N'), // ); // $this->lem->setTempVars($vars); // // foreach ($vars as $var => $attributes) // { // foreach ($attributes as $key => $val) // { // $this->assertEquals($val, $this->lem->GetVarAttribute($var, $key, null, 0, 0), "Failed GetVarAttribute: $var.$key"); // } // } // // } // public function testEvaluator() { $booleanExpressions = array( "1" => true, "0" => false, "" => false, "1 == 1" => true, "0 == 1" => false, "1 && 0" => false, "1 && 1" => true, "1 || 0" => true, "0 || 0" => false, ); foreach ($booleanExpressions as $expr => $expected) { $this->assertEquals($expected, $this->em->ProcessBooleanExpression($expr), "Expression: '$expr'"); } } public function testFunctions() { $functions = array( 'abs(5)' => 5, 'abs(-5)' => 5, 'abs(0)' => 0, 'acos(0.5)' => acos(0.5), 'acos(0.1)' => acos(0.1), ); foreach ($functions as $function => $expected) { $this->assertEquals($expected, $this->em->sProcessStringContainingExpressions('{' . $function . '}')); } } public function testEscapes() { $strings = array( '\{1+1}' => '{1+1}', 'x{1+1}' => 'x2', 'x{1+1\}' => 'x{1+1}', ); foreach ($strings as $escaped => $expected) { $this->assertEquals($expected, $this->em->sProcessStringContainingExpressions($escaped)); } } public function testJuggling() { $equalities = array( '"1" == 1' => 1, '"5" + "2"' => 7, '"1" == 0' => '', // False is an empty string. '1 == "1"' => 1, '1 + "2"' => 3, '"1" + "a"' => '1a', '1 + "a"' => '1a', '"05" + "1"' => 6, '"" + "1" + "2"' => 12 ); foreach ($equalities as $expression => $expected) { $result = $this->em->sProcessStringContainingExpressions('{' . $expression . '}'); $this->assertEquals($expected, $result); } } public function oldTestEvaluator() { // Syntax for $tests is // expectedResult~expression // if the expected result is an error, use NULL for the expected result $tests = <<Empty Vs. Empty~"Empty Vs. Empty" 1~'' == '' 0~'' != '' 0~'' > '' 1~'' >= '' 0~'' < '' 1~'' <= '' 1~!'' ~('' and '') ~('' or '') Empty Vs. Zero~"Empty Vs. Zero" 0~'' == 0 1~'' != 0 0~'' > 0 0~'' >= 0 0~'' < 0 0~'' <= 0 1~!'' 1~!0 0~('' and 0) 0~('' or 0) Empty Vs. Constant~"Empty Vs. Constant" 0~'' == 3 1~'' != 3 0~'' > 3 0~'' >= 3 0~'' < 3 0~'' <= 3 1~!'' 0~!3 0~('' and 3) 1~('' or 3) Empty Vs. Empty_Var~"Empty Vs. Empty_Var" 1~'' == empty 0~'' != empty 0~'' > empty 1~'' >= empty 0~'' < empty 1~'' <= empty 1~!'' 1~!empty ~('' and empty) ~('' or empty) Empty_Var Vs. Zero~"Empty_Var Vs. Zero" 0~empty == 0 1~empty != 0 0~empty > 0 0~empty >= 0 0~empty < 0 0~empty <= 0 1~!empty 1~!0 0~(empty and 0) 0~(empty or 0) Empty_Var Vs. Zero~"Empty_Var Vs. Zero" 0~empty == zero 1~empty != zero 0~empty > zero 0~empty >= zero 0~empty < zero 0~empty <= zero 1~!empty 1~!zero 0~(empty and zero) 0~(empty or zero) Empty_Var Vs. Constant~"Empty_Var Vs. Constant" 0~empty == 3 1~empty != 3 0~empty > 3 0~empty >= 3 0~empty < 3 0~empty <= 3 1~!empty 0~!3 0~(empty and 3) 1~(empty or 3) Solution: Empty_Var Vs. Zero~"Solution: Empty_Var Vs. Zero" 0~!is_empty(empty) && (empty == 0) 0~!is_empty(five) && (five == 0) 1~!is_empty(zero) && (zero == 0) 0~!is_empty(empty) && (empty > 0) 0~!is_empty(empty) && (empty >= 0) 0~!is_empty(empty) && (empty < 0) 0~!is_empty(empty) && (empty <= 0) 0~!is_empty(empty) && ((empty and 0)) 0~!is_empty(empty) && ((empty or 0)) Solution: Empty_Var Vs. Zero~"Solution: Empty_Var Vs. Zero" 0~!is_empty(empty) && (empty == zero) 0~!is_empty(five) && (five == zero) 1~!is_empty(zero) && (zero == zero) 0~!is_empty(empty) && (empty > zero) 0~!is_empty(empty) && (empty >= zero) 0~!is_empty(empty) && (empty < zero) 0~!is_empty(empty) && (empty <= zero) 0~!is_empty(empty) && ((empty and zero)) 0~!is_empty(empty) && ((empty or zero)) Solution: Empty_Var Vs. Constant~"Solution: Empty_Var Vs. Constant" 0~!is_empty(empty) && (empty < 3) 0~!is_empty(empty) && (empty <= 3) Solution: Empty_Var Vs. Variable~"Solution: Empty_Var Vs. Variable" 0~!is_empty(empty) && (empty < five) 0~!is_empty(empty) && (empty <= five) Solution: The Hard One is Empty_Var != 0~"Solution: The Hard One is Empty_Var != 0" 1~(empty != 0) 1~!is_empty(empty) && (empty != 0) 1~is_empty(empty) || (empty != 0) 1~is_empty(empty) || (empty != zero) 0~is_empty(zero) || (zero != 0) 1~is_empty(five) || (five != 0) SETUP~'SETUP' "Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"~a=htmlspecialchars(ASSESSMENT_HEADING) "can single quoted strings" . 'contain nested 'quoted sections'?~b=htmlspecialchars(QUESTIONHELP) Can strings have embedded <tags> like <html>, or even unbalanced "quotes or entities without terminal semicolons like &amp and &lt?~c=htmlspecialchars(QUESTION_HELP) Hi there!~d='Hi there!' FUNCTIONS~'FUNCTIONS' 5~abs(five) 5~abs(-five) 0.2~acos(cos(0.2)) 0~acos(cos(pi()))-pi() "Can strings contain embedded \\"quoted passages\\" (and parentheses + other characters?)?"~addslashes(a) "can single quoted strings" . 'contain nested 'quoted sections'?~addslashes(b) Can strings have embedded <tags> like <html>, or even unbalanced "quotes or entities without terminal semicolons like &amp and &lt?~addslashes(c) 0.2~asin(sin(0.2)) 0.2~atan(tan(0.2)) 0~atan2(0,1) 1~ceil(0.3) 1~ceil(0.7) 0~ceil(-0.3) 0~ceil(-0.7) 10~ceil(9.1) 1~checkdate(1,29,1967) 0~checkdate(2,29,1967) 0.2~cos(acos(0.2)) 5~count(1,2,3,4,5) 0~count() 5~count(one,two,three,four,five) 2~count(a,'',c) NULL~date('F j, Y, g:i a',time()) April 5, 2006, 1:02 am~date('F j, Y, g:i a',mktime(1,2,3,4,5,6)) 20~floor(exp(3)) 0~floor(asin(sin(pi()))) 9~floor(9.9) 3~floor(pi()) January 12, 2012, 5:27 pm~date('F j, Y, g:i a',1326410867) January 12, 2012, 11:27 pm~gmdate('F j, Y, g:i a',1326410867) "Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"~html_entity_decode(a) "can single quoted strings" . 'contain nested 'quoted sections'?~html_entity_decode(b) Can strings have embedded like , or even unbalanced "quotes or entities without terminal semicolons like & and <?~html_entity_decode(c) "Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"~htmlentities(a) "can single quoted strings" . 'contain nested 'quoted sections'?~htmlentities(b) Can strings have embedded <tags> like <html>, or even unbalanced "quotes or entities without terminal semicolons like &amp and &lt?~htmlentities(c) 1~c==htmlspecialchars(htmlspecialchars_decode(c)) 1~b==htmlspecialchars(htmlspecialchars_decode(b)) 1~a==htmlspecialchars(htmlspecialchars_decode(a)) "Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"~htmlspecialchars_decode(a) "can single quoted strings" . 'contain nested 'quoted sections'?~htmlspecialchars_decode(b) Can strings have embedded like , or even unbalanced "quotes or entities without terminal semicolons like & and like , or even unbalanced "quotes or entities without terminal semicolons like & and <?~htmlspecialchars(c) 9~idate('B',1326410867) 0~if('0',1,0) 0~if(0,1,0) 1~if(!0,1,0) 0~if(!(!0),1,0) 1~if('true',1,0) 1~if('false',1,0) 1~if('00',1,0) 0~if('',1,0) 1~if('A',1,0) 0~if(empty,1,0) 4~if(5 > 7,2,4) 1~if(' ',1,0) there~if((one > two),'hi','there') 64~if((one < two),pow(2,6),pow(6,2)) H e l l o~implode(' ','H','e','l','l','o') 1|2|3|4|5~implode('|',one,two,three,four,five) 123~join(1,2,3) 123 5~join(one,2,three," ",five) 4~intval('4') 4~intval('100',2) 5~intval(5.7) 0~is_empty(four) 1~is_empty(empty) 1~is_empty('') 0~is_empty(0) 0~is_empty('0') 0~is_empty('false') 0~is_empty('NULL') 0~is_empty(1) 1~is_empty(one==two) 0~!is_empty(one==two) 1~is_float(half) 0~is_float(one) 1~is_float(pi()) 0~is_float(5) 0~is_int(half) 1~is_int(one) 0~is_nan(half) 1~is_nan(WELCOME) 1~is_null(sdfjskdfj) 0~is_null(four) 0~is_numeric(empty) 1~is_numeric('1') 1~is_numeric(four) 0~is_numeric('hi') 1~is_numeric(five) 0~is_numeric(hi) 0~is_string(four) 1~is_string('hi') 1~is_string(hi) 1, 2, 3, 4, 5~list(one,two,three,min(four,five,six),max(three,four,five)) 11, 12~list(eleven,twelve) 0, 1, 3, 5~list(0,one,'',three,'',five) 1~log(exp(1)) 2~log(exp(2)) I was trimmed ~ltrim(' I was trimmed ') 10~max(5,6,10,-20) 6~max(five,(one + (two * four)- three)) 6~max((one + (two * four)- three)) 212~5 + max(1,(2+3),(4 + (5 + 6)),((7 + 8) + 9),((10 + 11), 12),(13 + (14 * 15) - 16)) 29~five + max(one, (two + three), (four + (five + six)),((seven + eight) + nine),((ten + eleven), twelve),(one + (two * three) - four)) 1024~max(one,(two*three),pow(four,five),six) 2~max(one,two) 5~max(one,two,three,four,five) -5~min(-5,10,15,12,-3) 1~min(five,four,one,two,three) 1344765967~mktime(5,6,7,8) 1144191723~mktime(1,2,3,4,5,6) 1,000~number_format(1000) 1,000.23~number_format(1000.23) 1,234,567~number_format(1234567) 315~ceil(100*pi()) 1~pi() == pi() * 2 - pi() 4~pow(2,2) 27~pow(3,3) =~quoted_printable_decode(quoted_printable_encode('=')) \\$~quotemeta('$') IGNORE THIS ERROR~rand(3,5) 0~(a=rand())-a 1~regexMatch('/embedded/',c) 1~regexMatch('/^.*embedded.*$/',c) 0~regexMatch('/joe/',c) 1~regexMatch('/(?:dog|cat)food/','catfood stinks') 1~regexMatch('/(?:dog|cat)food/','catfood stinks') 1~regexMatch('/[0-9]{3}-[0-9]{2}-[0-9]{4}/','123-45-6789') 1~regexMatch('/\d{3}-\d{2}-\d{4}/','123-45-6789') 1~regexMatch('/(?:\(\d{3}\))\s*\d{3}-\d{4}/','(212) 555-1212') 0~round(0.2) 1~round(.8) 0.07~0.01 + 0.06 0.07~round(0.01 + 0.06,10) I was trimmed~rtrim(' I was trimmed ') 0.2~sin(asin(0.2)) 1~sin(pi()/2) 1~sin(pi()/2) == sin(.5 * pi()) 1~sin(0.5 * pi()) hello,5~sprintf('%s,%d','hello',5) 2~sqrt(4) 158~round(stddev(4,5,6,7,8)*100) hello-----~str_pad('hello',10,'-') hello ~str_pad('hello',10) hello~str_pad('hello',3) testtesttest~str_repeat('test',3) I am awesome~str_replace('You are','I am','You are awesome') I love LimeSurvey~str_replace('like','love','I like LimeSurvey') 1~0==strcasecmp('Hello','hello') 0~0==strcasecmp('Hello','hi') 1~0==strcmp('Hello','Hello') 0~0==strcmp('Hello','hi') Hi there!~c=strip_tags(d) hello~strip_tags('hello') 5~stripos('ABCDEFGHI','f') hi~stripslashes('\\h\\i') FGHI~stristr('ABCDEFGHI','fg') 5~strlen('12345') 5~strlen(hi) 0~strpos('ABCDEFGHI','f') 5~strpos('ABCDEFGHI','F') 2~strpos('I like LimeSurvey','like') 54321~strrev('12345') 0~strstr('ABCDEFGHI','fg') FGHI~strstr('ABCDEFGHI','FG') hi there!~strtolower(c) HI THERE!~strtoupper(c) 3600~strtotime("27 Mar 1976 8:20")-strtotime("1976/03/27 7:20") 10~(strtotime("13 Apr 2013")-strtotime("2013-04-03"))/60/60/24 1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("05 Nov 1985")) HOURS PASSED SINCE 1970~round(strtotime("now")/60/60) ~"" 1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("11/5/85")) 2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("8/9/10")) 2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("8/9/2010")) 2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("2010/8/9")) ~"" 1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("85-11-5")) 2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("10-8-9")) 2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("9-8-2010")) 2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("2010-8-9")) ~"" 1985-11-05 00:53:20~date("Y-m-d H:i:s",strtotime("85-11-5 0:53:20")) 2010-08-09 00:53:20~date("Y-m-d H:i:s",strtotime("10-8-9 0:53:20")) 2010-08-09 11:12:13~date("Y-m-d H:i:s",strtotime("9-8-2010 11:12:13")) 2010-08-09 11:12:13~date("Y-m-d H:i:s",strtotime("2010-8-9 11:12:13")) ~"" Today 11:11:59~date("Y-m-d H:i:s",strtotime("11.11.59")) Today 9:08:10~date("Y-m-d H:i:s",strtotime("9.8.10")) 2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("9.8.2010")) ~"" 1985-11-05 00:53:20~date("Y-m-d H:i:s",strtotime("5.11.85 0:53:20")) 2010-08-09 11:12:13~date("Y-m-d H:i:s",strtotime("9.8.2010 11:12:13")) ~"" 1970-01-01 00:00:00~date("Y-m-d H:i:s",strtotime("70-01-01")) 1999-01-01 00:00:00~date("Y-m-d H:i:s",strtotime("99-01-01")) 2001-01-01 00:00:00~date("Y-m-d H:i:s",strtotime("01-01-01")) 1902-01-01 00:00:00~date("Y-m-d H:i:s",strtotime("1902-01-01")) ~"" today 2:15:00~date("Y-m-d H:i:s",strtotime("2:15:00")) Some dates that are not (correctly) parsed:~"Some dates that are not (correctly) parsed:" 1969-01-19 00:00:00~date("Y-m-d H:i:s",strtotime("69-01-19")) 1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("85/11/5")) 1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("5-11-85")) 2010-08-09 00:00:00~date("Y-m-d H:i:s",strtotime("2010.8.9")) 1985-11-05 00:00:00~date("Y-m-d H:i:s",strtotime("85.11.5")) 1985-11-05 00:53:20~date("Y-m-d H:i:s",strtotime("85.11.5 0:53:20")) 2010-08-09 11:12:13~date("Y-m-d H:i:s",strtotime("9.8.10 11:12:13")) 678~substr('1234567890',5,3) 15~sum(1,2,3,4,5) 15~sum(one,two,three,four,five) 0.2~tan(atan(0.2)) IGNORE THIS ERROR~time() I was trimmed~trim(' I was trimmed ') Hi There You~ucwords('hi there you') EXPRESSIONS~'EXPRESSIONS' 1~!'0' 1~0 eq '0' 0~0 ne '0' 0~0 eq empty 1~0 ne empty 0~0 eq '' 1~0 ne '' 0~'' < 10 0~0 < empty 1~0 <= empty 0~0 > empty 1~0 >= empty 0~'0' eq empty 1~'0' ne empty 0~'0' < empty 1~'0' <= empty 0~'0' > empty 1~'0' >= empty 1~empty eq empty 0~empty ne empty 0~'' > 0 0~' ' > 0 1~!0 0~!' ' 0~!'A' 0~!1 0~!'1' 1~!'' 1~!empty 1~'0'==0 0~'A'>0 0~'A'<0 0~'A'==0 0~'A'>=0 0~'A'<=0 0~0>'A' 0~0>='B' 0~0=='C' 0~0<'D' 0~0<='E' 1~0!='F' 1~'A' or 'B' 1~'A' and 'B' 0~'A' eq 'B' 1~'A' ne 'B' 1~'A' < 'B' 1~'A' <= 'B' 0~'A' > 'B' 0~'A' >= 'B' AB~'A' + 'B' NAN~'A' - 'B' NAN~'A' * 'B' NAN~'A' / 'B' 1~'A' or empty 0~'A' and empty 0~'A' eq empty 1~'A' ne empty 0~'A' < empty 0~'A' <= empty 1~'A' > empty 1~'A' >= empty A~'A' + empty NAN~'A' - empty NAN~'A' * empty NAN~'A' / empty 0~0 or empty 0~0 and empty 0~0 + empty 0~0 - empty 0~0 * empty NAN~0 / empty 0~(-1 > 0) 0~zero ~empty 1~five > zero 1~five > empty 1~empty < 16 1~zero == empty 3~q5pointChoice.code 5~q5pointChoice.type (question for q5pointChoice)~q5pointChoice.question 1~q5pointChoice.relevance 4~q5pointChoice.NAOK + 1 NULL~q5pointChoice.bogus 14~q5pointChoice.qid 7~qArrayNumbers_ls1_min.code 1~(one * (two + (three - four) + five) / six) 2.4~(one * two) + (three * four) / (five * six) 50~12X34X56 * 12X3X5lab1_ber 1~c == 'Hi there!' 1~c == "Hi there!" 3~a=three 3~c=a 12~c*=four 15~c+=a 5~c/=a -1~c-=six 24~one * two * three * four -4~five - four - three - two 0~two * three - two - two - two 4~two * three - two 105~5 + 1, 7 * 15 7~7 15~10 + 5 24~12 * 2 10~13 - 3 3.5~14 / 4 5~3 + 1 * 2 1~one there~hi 6.25~one * two - three / four + five 1~one + hi 1~two > one 1~two gt one 1~three >= two 1~three ge two 0~four < three 0~four lt three 0~four <= three 0~four le three 0~four == three 0~four eq three 1~four != three 0~four ne four NAN~one * hi 0~a='hello',b='',c=0 hello~a 0~c 0~one && 0 0~two and 0 1~five && 6 1~seven && eight 1~one or 0 1~one || 0 1~(one and 0) || (two and three) value for {QID}~QID "Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"~ASSESSMENT_HEADING "can single quoted strings" . 'contain nested 'quoted sections'?~QUESTIONHELP Can strings have embedded like , or even unbalanced "quotes or entities without terminal semicolons like & and <?~QUESTION_HELP value for {TOKEN:FIRSTNAME}~TOKEN:FIRSTNAME value for {THEREAREXQUESTIONS}~THEREAREXQUESTIONS 15~12X3X5lab1_ber#1 1~three == three 1~three == 3 11~eleven 144~twelve * twelve 0~!three 8~five + + three 2~five + - three SYNTAX ERRORS~'SYNTAX ERRORS' NULL~* NULL~three + NULL~four * / seven NULL~(five - three NULL~five + three) NULL~seven + = four NULL~> NULL~five > > three NULL~seven > = four NULL~seven >= NULL~three && NULL~three || NULL~three + NULL~three >= NULL~three += NULL~three ! NULL~three * NULL~five ! three NULL~(5 + 7) = 8 NULL~&& four NULL~min( NULL~max three, four, five) NULL~three four NULL~max(three,four,five) six NULL~WELCOME='Good morning' NULL~TOKEN:FIRSTNAME='Tom' NULL~NUMBEROFQUESTIONS+=3 NULL~NUMBEROFQUESTIONS*=4 NULL~NUMBEROFQUESTIONS/=5 NULL~NUMBEROFQUESTIONS-=6 NULL~'Tom'='tired' NULL~max() EOD; $atests = explode("\n",$tests); $atests[] = "1\n2\n3~BREAKS"; $atests[] = "1
\n2
\n3~nl2br(BREAKS)"; $atests[] = "hi
\nthere
\nhow
\nare
\nyou?~nl2br('hi\\nthere\\nhow\\nare\\nyou?')"; $atests[] = "hi
\nthere,
\nuser!~nl2br(implode('\\n','hi','there,','user!'))"; $LEM =& LimeExpressionManager::singleton(); $em = new ExpressionManager(); $LEM->setTempVars($vars); //$LEMsessid = 'survey_' . Yii::app()->getConfig('surveyID'); $LEMsessid = 'survey_12345'; // manually set relevance status $_SESSION[$LEMsessid]['relevanceStatus'] = array(); foreach ($vars as $var) { if (isset($var['qseq'])) { $_SESSION[$LEMsessid]['relevanceStatus'][$var['qseq']] = 1; } } $allJsVarnamesUsed = array(); $body = ''; $body .= ''; $i=0; $javaScript = array(); foreach($atests as $test) { ++$i; $values = explode("~",$test); $expectedResult = array_shift($values); $expr = implode("~",$values); $resultStatus = 'ok'; $em->groupSeq=2; $em->questionSeq=3; $status = $em->RDP_Evaluate($expr); if ($status) { $allJsVarnamesUsed = array_merge($allJsVarnamesUsed,$em->GetJsVarsUsed()); } $result = $em->GetResult(); $valToShow = $result; // htmlspecialchars($result,ENT_QUOTES,'UTF-8',false); $expectedToShow = $expectedResult; // htmlspecialchars($expectedResult,ENT_QUOTES,'UTF-8',false); $body .= ""; $body .= "\n"; if (is_null($result)) { $valToShow = "NULL"; } if ($valToShow != $expectedToShow) { $resultStatus = 'error'; } $body .= "\n"; $body .= '\n"; $javaScript[] = $em->GetJavascriptTestforExpression($expectedToShow, $i); $body .= "\n"; $varsUsed = $em->GetVarsUsed(); if (is_array($varsUsed) and count($varsUsed) > 0) { $varDesc = array(); foreach ($varsUsed as $v) { $varDesc[] = $v; } $body .= '\n"; } else { $body .= "\n"; } $jsEqn = $em->GetJavaScriptEquivalentOfExpression(); if ($jsEqn == '') { $body .= "\n"; } else { $body .= '\n"; } $body .= ''; } $body .= '
ExpressionPHP ResultExpectedJavaScript ResultVarNamesJavaScript Eqn
" . $em->GetPrettyPrintString() . "" . $valToShow . "' . $expectedToShow . " ' . implode(',
', $varDesc) . "
  ' . $jsEqn . "
'; $body .= "\n"; $allJsVarnamesUsed = array_unique($allJsVarnamesUsed); asort($allJsVarnamesUsed); $pre = ''; $pre .= "

Change some Relevance values to 0 to see how it affects computations

\n"; $pre .= ''; $i=0; $LEMvarNameAttr=array(); $LEMalias2varName=array(); foreach ($allJsVarnamesUsed as $jsVarName) { ++$i; $pre .= "\n"; $LEMalias2varName[] = "'" . substr($jsVarName,5) . "':'" . $jsVarName . "'"; $LEMalias2varName[] = "'" . $jsVarName . "':'" . $jsVarName . "'"; $attrInfo = "'" . $jsVarName . "': {'jsName':'" . $jsVarName . "'"; $varInfo = $vars[substr($jsVarName,5)]; foreach ($varInfo as $k=>$v) { if ($k == 'code') { continue; // will access it from hidden node } if ($k == 'shown') { $k = 'shown'; $v = htmlspecialchars(preg_replace("/[[:space:]]/",' ',$v),ENT_QUOTES); } if ($k == 'jsName') { continue; // since already set } $attrInfo .= ", '" . $k . "':'" . $v . "'"; } $attrInfo .= ",'qid':" . $i . "}"; $LEMvarNameAttr[] = $attrInfo; } $pre .= "
#JsVarnameStarting ValueRelevance
" . $i . "" . $jsVarName; foreach($vars as $k => $v) { if ($v['jsName'] == $jsVarName) { $value = $v['code']; } } $pre .= "" . $value . "\n"; $pre .= "\n"; $pre .= "
\n"; $pre .= "\n"; print $pre; print $body; } /** * Unit test the asSplitStringOnExpressions() function to ensure that accurately parses out all expressions * surrounded by curly braces, allowing for strings and escaped curly braces. */ public function oldStringSplitter() { $tests = << INSERT61764X1X4),'children','pets')} than you do {if((INSERT61764X1X3 > INSERT61764X1X4),'pets','children')}, do you feel that the {if((INSERT61764X1X3 > INSERT61764X1X4),'pets','children')} are at a disadvantage? Here is a String that failed to parse prior to fixing the preg_split() command to avoid recursive search of sub-strings: [{((617167X9X3241 == "Y" or 617167X9X3242 == "Y" or 617167X9X3243 == "Y" or 617167X9X3244 == "Y" or 617167X9X3245 == "Y" or 617167X9X3246 == "Y" or 617167X9X3247 == "Y" or 617167X9X3248 == "Y" or 617167X9X3249 == "Y") and (617167X9X3301 == "Y" or 617167X9X3302 == "Y" or 617167X9X3303 == "Y" or 617167X9X3304 == "Y" or 617167X9X3305 == "Y" or 617167X9X3306 == "Y" or 617167X9X3307 == "Y" or 617167X9X3308 == "Y" or 617167X9X3309 == "Y"))}] Here is the question. EOD; // Here is a String that failed to parse prior to fixing the preg_split() command to avoid recursive search of sub-strings: [{((617167X9X3241 == "Y" or 617167X9X3242 == "Y" or 617167X9X3243 == "Y" or 617167X9X3244 == "Y" or 617167X9X3245 == "Y" or 617167X9X3246 == "Y" or 617167X9X3247 == "Y" or 617167X9X3248 == "Y" or 617167X9X3249 == "Y") and (617167X9X3301 == "Y" or 617167X9X3302 == "Y" or 617167X9X3303 == "Y" or 617167X9X3304 == "Y" or 617167X9X3305 == "Y" or 617167X9X3306 == "Y" or 617167X9X3307 == "Y" or 617167X9X3308 == "Y" or 617167X9X3309 == "Y"))}] Here is the question. $em = new ExpressionManager(); $atests = explode("\n",$tests); array_push($atests,'"hi\nthere\nhow\nare\nyou?\n"'); foreach($atests as $test) { $tokens = $em->asSplitStringOnExpressions($test); print '' . $test . '
'; print ''; print implode("
\n",explode("\n",print_r($tokens,TRUE))); print '

'; } } /** * Unit test the Tokenizer - Tokenize and generate a HTML-compatible print-out of a comprehensive set of test cases */ public function oldTokenizer() { // Comprehensive test cases for tokenizing $tests = << >= < <= == != gt ge lt le eq ne (target large gents built agile less equal) Assign: = += -= *= /= SGQA: 1X6X12 1X6X12ber1 1X6X12ber1_lab1 3583X84X249 12X3X5lab1_ber#1 1X6X12.NAOK 1X6X12ber1.NAOK 1X6X12ber1_lab1.NAOK 3583X84X249.NAOK 12X3X5lab1_ber#1.NAOK Errors: Apt # 10C; (2 > 0) ? 'hi' : 'there'; array[30]; >>> <<< /* this is not a comment */ // neither is this Words: q5pointChoice q5pointChoice.bogus q5pointChoice.code q5pointChoice.mandatory q5pointChoice.NAOK q5pointChoice.qid q5pointChoice.question q5pointChoice.relevance q5pointChoice.shown q5pointChoice.type EOD; $em = new ExpressionManager(); foreach(explode("\n",$tests) as $test) { $tokens = array(); //$em->RDP_Tokenize($test); print '' . $test . '
'; print ''; print implode("
\n",explode("\n",print_r($tokens,TRUE))); print '

'; } } } ?>