Esempio n. 1
0
describe('PHP Engine __DIR__ magic constant expression integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'capturing current file\'s directory from initial program code': {
            code: nowdoc(function () {/*<<<EOS
<?php echo __DIR__;

EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: '(program)'
        },
        'capturing current file\'s directory in required module': {
            code: nowdoc(function () {/*<<<EOS
<?php
    require_once 'vendor/producer/get_dir.php';

EOS
*/;}), // jshint ignore:line
            options: {
                include: function (path, promise) {
                    promise.resolve(nowdoc(function () {/*<<<EOS
<?php

    echo __DIR__;

EOS
*/;})); // jshint ignore:line
                }
            },
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'vendor/producer'
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});
describe('PHP Engine subtraction assignment "-=" operator integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'subtracting 4 from a variable containing integer': {
            code: '<?php $num = 7; $num -= 4; return $num;',
            expectedResult: 3,
            expectedResultType: 'integer',
            expectedStderr: '',
            expectedStdout: ''
        },
        'subtracting 4 from a variable containing float': {
            code: '<?php $num = 6.0; $num -= 4; return $num;',
            expectedResult: 2,
            expectedResultType: 'float',
            expectedStderr: '',
            expectedStdout: ''
        },
        'attempting to subtract 5 from undefined variable': {
            code: '<?php $num -= 5; var_dump($num); print "Done";',
            expectedResult: null,
            expectedStderr: nowdoc(function () {/*<<<EOS
PHP Notice: Undefined variable: num

EOS
*/;}), // jshint ignore:line
                // Note that the 'Done' echo following the dump must be executed, this is only a notice
            expectedStdout: nowdoc(function () {/*<<<EOS
int(-5)
Done
EOS
*/;}) // jshint ignore:line
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});
Esempio n. 3
0
    describe('inside foreach (...) {...}', function () {
        _.each({
            'foreach should reset internal pointer but not advance during': {
                code: nowdoc(function () {/*<<<EOS
<?php
    $array = array(1, 2, 3);
    $result = '';

    // Advance to next element before loop, to check internal pointer is reset by foreach
    next($array);

    foreach ($array as $val) {
        $result = $result . current($array) . ',';
    }

    return $result;
EOS
*/;}), // jshint ignore:line
                expectedResult: '1,1,1,',
                expectedStderr: '',
                expectedStdout: ''
            }
        }, function (scenario, description) {
            describe(description, function () {
                check(scenario);
            });
        });
    });
Esempio n. 4
0
                include: function (path, promise) {
                    promise.resolve(nowdoc(function () {/*<<<EOS
<?php

    echo __DIR__;

EOS
*/;})); // jshint ignore:line
                }
describe('PHP Engine class statement instance method type hinting integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'passing array to method argument type hinted as array': {
            code: nowdoc(function () {/*<<<EOS
<?php
    class Math {
        public function sum(array $numbers) {
            $total = 0;

            foreach ($numbers as $number) {
                $total = $total + $number;
            }

            return $total;
        }
    }

    $math = new Math;

    return $math->sum(array(3, 5, 1));
EOS
*/;}), // jshint ignore:line
            expectedResult: 9,
            expectedResultType: 'integer',
            expectedStderr: '',
            expectedStdout: ''
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});
Esempio n. 6
0
describe('PHP Engine closure expression default argument value integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'self-executed closure with default argument value': {
            code: nowdoc(function () {/*<<<EOS
<?php
    $result = 4;

    function ($number = 10) use (&$result) {
        $result = $number;
    }();

    return $result;

EOS
*/;}), // jshint ignore:line
            expectedResult: 10,
            expectedStderr: '',
            expectedStdout: ''
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});
Esempio n. 7
0
describe('PHP Engine __FILE__ magic constant expression integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'capturing current file from initial program code': {
            code: nowdoc(function () {/*<<<EOS
<?php echo __FILE__;

EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: '(program)'
        },
        'capturing current file in required module': {
            code: nowdoc(function () {/*<<<EOS
<?php
    require_once 'get_file.php';

EOS
*/;}), // jshint ignore:line
            options: {
                include: function (path, promise) {
                    promise.resolve(nowdoc(function () {/*<<<EOS
<?php

    echo __FILE__;

EOS
*/;})); // jshint ignore:line
                }
            },
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'get_file.php'
        },
        // Ensure the state is not shared between main program and required module
        'capturing current file in main program before and after required module': {
            code: nowdoc(function () {/*<<<EOS
<?php
    echo __FILE__;
    require_once 'get_file.php';
    echo __FILE__;

EOS
*/;}), // jshint ignore:line
            options: {
                include: function (path, promise) {
                    promise.resolve(nowdoc(function () {/*<<<EOS
<?php

    echo __FILE__;

EOS
*/;})); // jshint ignore:line
                }
            },
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: '(program)get_file.php(program)'
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});
Esempio n. 8
0
var ace = global.ace,
    nowdoc = require('nowdoc'),
    javascriptCode = '/*global phpCode, resultBody, uniter */\n' + nowdoc(function () {/*<<<EOS
'use strict';

var phpEngine = uniter.createEngine('PHP');

phpEngine.expose({
    getCC: function () {
        return 'en';
    },
    salutation: 'Hello'
}, 'info');

phpEngine.getStdout().on('data', function (data) {
    print(data);
});

phpEngine.getStderr().on('data', function (data) {
    print(data);
});

phpEngine.execute(phpCode).fail(function (error) {
    print(error.toString());
});

EOS
*/
    }),
    javascriptEditor,
    phpCode = nowdoc(function () {/*<<<EOS
Esempio n. 9
0
describe('PHP Engine class statement public static property integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'defining static property without initial value and reading from outside class': {
            code: nowdoc(function () {/*<<<EOS
<?php
    class Animal {
        public static $planet;
    }

    return Animal::$planet;
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: ''
        },
        'defining static property with initial value and reading from outside class': {
            code: nowdoc(function () {/*<<<EOS
<?php
    class Animal {
        public static $planet = 'Earth';
    }

    return Animal::$planet;
EOS
*/;}), // jshint ignore:line
            expectedResult: 'Earth',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'trying to read public static property as instance property from outside class': {
            code: nowdoc(function () {/*<<<EOS
<?php
    class Animal {
        public static $species = 'Human';
    }

    return (new Animal)->species;
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: nowdoc(function () {/*<<<EOS
PHP Strict standards: Accessing static property Animal::$species as non static
PHP Notice: Undefined property: Animal::$species

EOS
*/;}), // jshint ignore:line
            expectedStdout: ''
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});
Esempio n. 10
0
    describe('exposing as global PHP variables', function () {
        _.each({
            'plain object from JavaScript with instance method': {
                code: nowdoc(function () {/*<<<EOS
<?php
    return $tools->addThisDotMyvalueTo(16);
EOS
*/;}), // jshint ignore:line
                expose: {
                    'tools': {
                        addThisDotMyvalueTo: function (number) {
                            return number + this.myValue;
                        },
                        myValue: 5
                    }
                },
                expectedResult: 21,
                expectedResultType: 'integer',
                expectedStderr: '',
                expectedStdout: ''
            },
            'plain object from JavaScript with prototype method': {
                code: nowdoc(function () {/*<<<EOS
<?php
    return $tools->getValue();
EOS
*/;}), // jshint ignore:line
                expose: {
                    'tools': Object.create({
                        getValue: function () {
                            return 'me';
                        }
                    })
                },
                expectedResult: 'me',
                expectedResultType: 'string',
                expectedStderr: '',
                expectedStdout: ''
            },
            'calling PHP closure from JS': {
                code: nowdoc(function () {/*<<<EOS
<?php
$tools->setAdder(function ($num1, $num2) {
    return $this->start + $num1 + $num2;
});
return $tools->getValue(4, 2);
EOS
*/;}), // jshint ignore:line
                expose: function () {
                    var adder;

                    return {
                        'tools': {
                            getValue: function (num1, num2) {
                                return adder.call({start: 10}, num1, num2);
                            },
                            setAdder: function (newAdder) {
                                adder = newAdder;
                            }
                        }
                    };
                },
                expectedResult: 16,
                expectedResultType: 'integer',
                expectedStderr: '',
                expectedStdout: ''
            },
            'calling PHP closure from JS with null thisObj': {
                code: nowdoc(function () {/*<<<EOS
<?php
$tools->setCallback(function () {
    var_dump($this);
});
return $tools->callBack(4, 2);
EOS
*/;}), // jshint ignore:line
                expose: function () {
                    var callback;

                    return {
                        'tools': {
                            callBack: function () {
                                callback.call(null);
                            },
                            setCallback: function (newCallback) {
                                callback = newCallback;
                            }
                        }
                    };
                },
                expectedResult: null,
                expectedResultType: 'null',
                expectedStderr: '',
                expectedStdout: nowdoc(function () {/*<<<EOS
NULL

EOS
*/;}) // jshint ignore:line
                }
        }, function (scenario, description) {
            describe(description, function () {
                check(scenario);
            });
        });
    });
Esempio n. 11
0
describe('PHP Engine goto statement integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'jumping over first echo to second': {
            code: nowdoc(function () {/*<<<EOS
<?php
    goto second;
    echo 'first';

second:
    echo 'second';
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'second'
        },
        'jumping over unused label': {
            code: nowdoc(function () {/*<<<EOS
<?php
    goto second;

first:
    echo 'first';
second:
    echo 'second';
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'second'
        },
        'jumping over first echo to second inside if with falsy condition': {
            code: nowdoc(function () {/*<<<EOS
<?php
    goto second;
    echo 'first';

    if (0) {
second:
        echo 'second';
    }
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'second'
        },
        'jumping over first echo to third inside if with falsy condition': {
            code: nowdoc(function () {/*<<<EOS
<?php
    goto second;
    echo 'first';

    if (0) {
        echo 'second';
second:
        echo 'third';
    }
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'third'
        },
        'jumping over first if statement to echo inside second if with falsy condition': {
            code: nowdoc(function () {/*<<<EOS
<?php
    goto end;
    echo 'first';

    if (true) {
        echo 'second';
    }

    if (0) {
        echo 'third';
end:
        echo 'fourth';
    }
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'fourth'
        },
        'jumping out of if statement': {
            code: nowdoc(function () {/*<<<EOS
<?php
    echo 'first';

    if (true) {
        echo 'second';
        goto end;
        echo 'third';
    }

    echo 'fourth';

end:
    echo 'fifth';
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'firstsecondfifth'
        },
        'jumping out of first if statement to echo inside second if': {
            code: nowdoc(function () {/*<<<EOS
<?php
    echo 'first';

    if (true) {
        echo 'second';
        goto sixth;
        echo 'third';
    }

    echo 'fourth';

    if (0) {
        echo 'fifth';
sixth:
        echo 'sixth';
    }

    echo 'seventh';
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'firstsecondsixthseventh'
        },
        'jumping into nested if': {
            code: nowdoc(function () {/*<<<EOS
<?php
    echo 'first';
    goto end;

    echo 'second';

    if (0) {
        echo 'third';
        if (0) {
            echo 'fourth';
end:
            echo 'fifth';
        }
        echo 'sixth';
    }

    echo 'seventh';
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'firstfifthsixthseventh'
        },
        'jumping out of nested if': {
            code: nowdoc(function () {/*<<<EOS
<?php
    echo 'first';

    if (true) {
        echo 'second';
        if (true) {
            echo 'third';
goto end;
            echo 'fourth';
        }
        echo 'fifth';
    }

    echo 'sixth';

end:
    echo 'seventh';
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'firstsecondthirdseventh'
        },
        'jumping out of nested if into nested if': {
            code: nowdoc(function () {/*<<<EOS
<?php
    echo 'first';

    if (true) {
        echo 'second';
        if (true) {
            echo 'third';
goto end;
            echo 'fourth';
        }
        echo 'fifth';
    }

    echo 'sixth';

    if (false) {
        echo 'seventh';
        if (false) {
            echo 'eighth';
end:
            echo 'ninth';
        }
        echo 'tenth';
    }

    echo 'eleventh';
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'firstsecondthirdninthtentheleventh'
        },
        'jumping backward into if': {
            code: nowdoc(function () {/*<<<EOS
<?php
    echo 'first';

    if (0) {
        echo 'second';
backward:
        echo 'third';
        return;
        echo 'fourth';
    }

    echo 'fifth';
    goto backward;
    echo 'sixth';
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'firstfifththird'
        },
        'jumping backward from if into previous if': {
            code: nowdoc(function () {/*<<<EOS
<?php
    echo 'first';

    if (0) {
        echo 'second';
backward:
        echo 'third';
        return;
        echo 'fourth';
    }

    echo 'fifth';
    if (true) {
        echo 'sixth';
        goto backward;
        echo 'seventh';
    }
    echo 'eighth';
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'firstfifthsixththird'
        },
        'reusing label name inside function': {
            code: nowdoc(function () {/*<<<EOS
<?php
    echo 'first';

    function doIt() {
        echo 'second';
        goto myLabel;
        echo 'third';
myLabel:
        echo 'fourth';
    }

    echo 'fifth';
    doIt();
    echo 'sixth';

    goto myLabel;
    echo 'seventh';
myLabel:
    echo 'eighth';

EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'firstfifthsecondfourthsixtheighth'
        },
        'invalid jump into while loop': {
            code: nowdoc(function () {/*<<<EOS
<?php
    goto invalid;

    while (0) {
invalid:
    }
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: 'goto' into loop or switch statement is disallowed$/
            },
            expectedStderr: 'PHP Fatal error: \'goto\' into loop or switch statement is disallowed',
            expectedStdout: ''
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});
Esempio n. 12
0
describe('PHP Engine scope resolution operator "::" constant integratio', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'reading defined class constant from statically specified class name': {
            code: nowdoc(function () {/*<<<EOS
<?php
    class Stuff {
        const CATEGORY = 'Misc';
    }

    return Stuff::CATEGORY;
EOS
*/;}), // jshint ignore:line
            expectedResult: 'Misc',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'reading defined class constant from instance variable': {
            code: nowdoc(function () {/*<<<EOS
<?php
    class Stuff {
        const TEST = 'cmp';
    }

    $object = new Stuff;

    return $object::TEST;
EOS
*/;}), // jshint ignore:line
            expectedResult: 'cmp',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'attempting to read undefined class constant from statically specified class name': {
            code: nowdoc(function () {/*<<<EOS
<?php
    class Stuff {}

    return Stuff::THINGS;
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Undefined class constant 'THINGS'$/
            },
            expectedStderr: 'PHP Fatal error: Undefined class constant \'THINGS\'',
            expectedStdout: ''
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});
Esempio n. 13
0
describe('PHP Engine constant expression integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'assigning undefined constant called "MY_CONST" to variable in global namespace': {
            code: nowdoc(function () {/*<<<EOS
<?php
    $value = MY_CONST;

    return $value;
EOS
*/;}), // jshint ignore:line
            // Undefined constant should be interpreted as bareword string literal
            expectedResult: 'MY_CONST',
            expectedResultType: 'string',
            expectedStderr: 'PHP Notice: Use of undefined constant MY_CONST - assumed \'MY_CONST\'\n',
            expectedStdout: ''
        },
        'assigning undefined constant called "YOUR_CONST" to variable in global namespace': {
            code: nowdoc(function () {/*<<<EOS
<?php
    $value = YOUR_CONST;

    return $value;
EOS
*/;}), // jshint ignore:line
            // Undefined constant should be interpreted as bareword string literal
            expectedResult: 'YOUR_CONST',
            expectedResultType: 'string',
            expectedStderr: 'PHP Notice: Use of undefined constant YOUR_CONST - assumed \'YOUR_CONST\'\n',
            expectedStdout: ''
        },
        'assigning undefined constant called "MY_CONST" to variable in a namespace': {
            code: nowdoc(function () {/*<<<EOS
<?php
    namespace Us;

    $value = MY_CONST;

    return $value;
EOS
*/;}), // jshint ignore:line
            // Undefined constant should be interpreted as bareword string literal
            expectedResult: 'MY_CONST',
            expectedResultType: 'string',
            expectedStderr: 'PHP Notice: Use of undefined constant MY_CONST - assumed \'MY_CONST\'\n',
            expectedStdout: ''
        },
        'undefined constant as default argument value when not called': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function test($value = UNDEF_CONST) {}
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            // No notice should be raised
            expectedStderr: '',
            expectedStdout: ''
        },
        'undefined constant as default argument value when called and used': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function test($value = UNDEF_CONST) {
        return $value;
    }

    return test();
EOS
*/;}), // jshint ignore:line
            // Undefined constant should be interpreted as bareword string literal
            expectedResult: 'UNDEF_CONST',
            expectedResultType: 'string',
            expectedStderr: 'PHP Notice: Use of undefined constant UNDEF_CONST - assumed \'UNDEF_CONST\'\n',
            expectedStdout: ''
        },
        // Ensure we use .hasOwnProperty(...) checks internally
        'undefined constant called "constructor" as default argument value when called and used': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function test($value = constructor) {
        return $value;
    }

    return test();
EOS
*/;}), // jshint ignore:line
            // Undefined constant should be interpreted as bareword string literal
            expectedResult: 'constructor',
            expectedResultType: 'string',
            expectedStderr: 'PHP Notice: Use of undefined constant constructor - assumed \'constructor\'\n',
            expectedStdout: ''
        },
        'undefined constant as default argument value when called but not used': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function test($value = UNDEF_CONST) {
        return $value;
    }

    return test('world');
EOS
*/;}), // jshint ignore:line
            expectedResult: 'world',
            expectedResultType: 'string',
            // No notice should be raised
            expectedStderr: '',
            expectedStdout: ''
        },
        'defined constant as default argument value should be read and not raise warning when called and used': {
            code: nowdoc(function () {/*<<<EOS
<?php
    define('MY_PLANET', 'Earth');

    function getPlanet($name = MY_PLANET) {
        return $name;
    }

    return getPlanet();
EOS
*/;}), // jshint ignore:line
            expectedResult: 'Earth',
            expectedResultType: 'string',
            // No notice should be raised
            expectedStderr: '',
            expectedStdout: ''
        },
        'defined constant in namespace read from another namespace': {
            code: nowdoc(function () {/*<<<EOS
<?php
    namespace Test;

    define('Test\NAME', 'Dan');

    namespace Fun;

    return \Test\NAME;
EOS
*/;}), // jshint ignore:line
            expectedResult: 'Dan',
            expectedResultType: 'string',
            // No notice should be raised
            expectedStderr: '',
            expectedStdout: ''
        },
        'defined constant in namespace read from another namespace via import': {
            code: nowdoc(function () {/*<<<EOS
<?php
    namespace Test;

    use My as Me;

    define('My\NAME', 'Dan');

    return Me\NAME;
EOS
*/;}), // jshint ignore:line
            expectedResult: 'Dan',
            expectedResultType: 'string',
            // No notice should be raised
            expectedStderr: '',
            expectedStdout: ''
        },
        'constant from global namespace should be used if not defined in current one, case-insensitive': {
            code: nowdoc(function () {/*<<<EOS
<?php
namespace Test;

define('PLANET', 'Earth', true);

return pLaNET;
EOS
*/;}), // jshint ignore:line
            expectedResult: 'Earth',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'constant from global namespace should not be used if not defined in current one, case-sensitive': {
            code: nowdoc(function () {/*<<<EOS
<?php
namespace Test;

define('PLANET', 'Earth', false);

return pLaNET;
EOS
*/;}), // jshint ignore:line
            expectedResult: 'pLaNET',
            expectedResultType: 'string',
            expectedStderr: 'PHP Notice: Use of undefined constant pLaNET - assumed \'pLaNET\'\n',
            expectedStdout: ''
        },
        'attempting to read undefined constant from global namespace with prefix': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return \NAME;
EOS
*/;}), // jshint ignore:line
            // Note that when using namespaces, use of undefined constant is a fatal error not just a notice
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Undefined constant 'NAME'$/
            },
            expectedStderr: 'PHP Fatal error: Undefined constant \'NAME\'',
            expectedStdout: ''
        },
        'attempting to read undefined constant from another namespace': {
            code: nowdoc(function () {/*<<<EOS
<?php
    namespace Fun;

    return My\Stuff\NAME;
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Undefined constant 'Fun\\My\\Stuff\\NAME'$/
            },
            expectedStderr: 'PHP Fatal error: Undefined constant \'Fun\\My\\Stuff\\NAME\'',
            expectedStdout: ''
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});
Esempio n. 14
0
describe('PHP Engine function definition statement integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'simple function call': {
            code: '<?php function show($string) { echo $string; } show("hello!");',
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'hello!'
        },
        'make sure variables defined in inner scopes are not defined in the outer one': {
            code: '<?php function doSomething() { $a = 1; } echo $a;',
            expectedResult: null,
            expectedStderr: 'PHP Notice: Undefined variable: a\n',
            expectedStdout: ''
        },
        'make sure variables defined in outer scopes are not defined in the inner one': {
            code: '<?php $a = 1; function doSomething() { echo $a; } doSomething();',
            expectedResult: null,
            expectedStderr: 'PHP Notice: Undefined variable: a\n',
            expectedStdout: ''
        },
        // Test for pre-hoisting
        'calling a function before its definition outside of any blocks eg. conditionals': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return add1(7);

    function add1($number) {
        return $number + 1;
    }
EOS
*/;}), // jshint ignore:line
            expectedResult: 8,
            expectedStderr: '',
            expectedStdout: ''
        },
        'calling a function before its definition where definition is inside of a conditional': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return add1(7);

    if (true) {
        function add1($number) {
            return $number + 1;
        }
    }
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Call to undefined function add1\(\)$/
            },
            expectedStderr: 'PHP Fatal error: Call to undefined function add1()',
            expectedStdout: ''
        },
        'calling a function before its definition where definition is inside of a function': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function declareFunc() {
        secondFunc();

        function secondFunc() {}
    }

    declareFunc();
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Call to undefined function secondFunc\(\)$/
            },
            expectedStderr: 'PHP Fatal error: Call to undefined function secondFunc()',
            expectedStdout: ''
        },
        'calling a function before its definition where definition is inside of a while loop': {
            code: nowdoc(function () {/*<<<EOS
<?php
    $a = 1;

    while ($a--) {
        doSomething();

        function doSomething () {}
    }
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Call to undefined function doSomething\(\)$/
            },
            expectedStderr: 'PHP Fatal error: Call to undefined function doSomething()',
            expectedStdout: ''
        },
        'calling a function before its definition where definition is inside of a foreach loop': {
            code: nowdoc(function () {/*<<<EOS
<?php
    $items = array(1);

    foreach ($items as $item) {
        doSomething();

        function doSomething () {}
    }
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Call to undefined function doSomething\(\)$/
            },
            expectedStderr: 'PHP Fatal error: Call to undefined function doSomething()',
            expectedStdout: ''
        },
        'using the name "tools" for a function argument': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function getResult($tools) {
        return $tools->result;
    }

    $tools = new stdClass;
    $tools->result = 7;

    return getResult($tools);
EOS
*/;}), // jshint ignore:line
            expectedResult: 7,
            expectedStderr: '',
            expectedStdout: ''
        },
        'function declarations inside conditionals should not be hoisted within the block': {
            code: nowdoc(function () {/*<<<EOS
<?php
    if (true) {
        doSomething();

        function doSomething() {}
    }
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Call to undefined function doSomething\(\)$/
            },
            expectedStderr: 'PHP Fatal error: Call to undefined function doSomething()',
            expectedStdout: ''
        },
        'attempting to call undefined function in the global namespace with same name as in current': {
            code: nowdoc(function () {/*<<<EOS
<?php
namespace My\Stuff;
function my_func() {}

\my_func();
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Call to undefined function my_func\(\)$/
            },
            expectedStderr: 'PHP Fatal error: Call to undefined function my_func()',
            expectedStdout: ''
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});
Esempio n. 15
0
    describe('when given one argument', function () {
        _.each({
            'empty array': {
                value: 'array()',
                expectedStdout: nowdoc(function () {/*<<<EOS
array(0) {
}

EOS
*/;}) // jshint ignore:line
            },
            'array with one element with implicit key': {
                value: 'array(7)',
                expectedStdout: nowdoc(function () {/*<<<EOS
array(1) {
  [0]=>
  int(7)
}

EOS
*/;}) // jshint ignore:line
            },
            'array with one element with explicit key': {
                value: 'array(4 => "a")',
                expectedStdout: nowdoc(function () {/*<<<EOS
array(1) {
  [4]=>
  string(1) "a"
}

EOS
*/;}) // jshint ignore:line
            },
            'array with one element with explicit key for subarray value': {
                value: 'array(5 => array(6, 7))',
                expectedStdout: nowdoc(function () {/*<<<EOS
array(1) {
  [5]=>
  array(2) {
    [0]=>
    int(6)
    [1]=>
    int(7)
  }
}

EOS
*/;}) // jshint ignore:line
            },
            'boolean true': {
                value: 'true',
                expectedStdout: 'bool(true)\n'
            },
            'boolean false': {
                value: 'false',
                expectedStdout: 'bool(false)\n'
            },
            'float': {
                value: '2.2',
                expectedStdout: 'float(2.2)\n'
            },
            'integer': {
                value: '3',
                expectedStdout: 'int(3)\n'
            },
            'null': {
                value: 'null',
                expectedStdout: 'NULL\n'
            },
            'empty stdClass instance': {
                value: 'new stdClass',
                expectedStdout: nowdoc(function () {/*<<<EOS
object(stdClass)#1 (0) {
}

EOS
*/;}) // jshint ignore:line
            },
            'stdClass instance with one property': {
                value: 'new stdClass; $value->prop = 1',
                expectedStdout: nowdoc(function () {/*<<<EOS
object(stdClass)#1 (1) {
  ["prop"]=>
  int(1)
}

EOS
*/;}) // jshint ignore:line
            },
            'stdClass instance with one property containing another stdClass instance': {
                value: 'new stdClass; $value->sub = new stdClass; $value->sub->prop = 1',
                expectedStdout: nowdoc(function () {/*<<<EOS
object(stdClass)#1 (1) {
  ["sub"]=>
  object(stdClass)#2 (1) {
    ["prop"]=>
    int(1)
  }
}

EOS
*/;}) // jshint ignore:line
            },
            'string': {
                value: '"world"',
                expectedStdout: 'string(5) "world"\n'
            },
            'stdClass instance with one property referring to itself': {
                value: 'new stdClass; $value->me = $value',
                expectedStdout: nowdoc(function () {/*<<<EOS
object(stdClass)#1 (1) {
  ["me"]=>
  *RECURSION*
}

EOS
*/;}) // jshint ignore:line
            },
            'array assigned to an element of itself - should be a copy, so no recursion': {
                value: 'array(); $value[0] = $value',
                expectedStdout: nowdoc(function () {/*<<<EOS
array(1) {
  [0]=>
  array(0) {
  }
}

EOS
*/;}) // jshint ignore:line
            },
            'array element with reference to variable': {
                value: 'array(); $where = "Here"; $value[0] =& $where; $where = "There"',
                expectedStdout: nowdoc(function () {/*<<<EOS
array(1) {
  [0]=>
  &string(5) "There"
}

EOS
*/;}) // jshint ignore:line
            },
            'reference to variable containing array assigned to an element of itself - should not be a copy, so recurses': {
                value: 'array(); $value[0] =& $value',
                expectedStdout: nowdoc(function () {/*<<<EOS
array(1) {
  [0]=>
  &array(1) {
    [0]=>
    *RECURSION*
  }
}

EOS
*/;}) // jshint ignore:line
            },
            'reference to variable containing object assigned to a property of itself': {
                value: 'new stdClass; $value->prop =& $value',
                expectedStdout: nowdoc(function () {/*<<<EOS
object(stdClass)#1 (1) {
  ["prop"]=>
  *RECURSION*
}

EOS
*/;}) // jshint ignore:line
            },
            'circular reference from array -> object -> array': {
                value: 'array(); $object = new stdClass; $value[0] =& $object; $object->prop =& $value',
                expectedStdout: nowdoc(function () {/*<<<EOS
array(1) {
  [0]=>
  &object(stdClass)#1 (1) {
    ["prop"]=>
    &array(1) {
      [0]=>
      *RECURSION*
    }
  }
}

EOS
*/;}) // jshint ignore:line
            }
        }, function (scenario, description) {
            describe(description, function () {
                check({
                    code: '<?php $value = ' + scenario.value + '; var_dump($value);',
                    expectedStderr: scenario.expectedStderr || '',
                    expectedStdout: scenario.expectedStdout
                });
            });
        });
    });
Esempio n. 16
0
describe('PHP Engine var_dump() builtin function integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'when given no arguments': {
            code: '<?php return var_dump();',
            expectedResult: null,
            expectedStderr: 'PHP Warning: var_dump() expects at least 1 parameter, 0 given\n',
            expectedStdout: ''
        },
        'attempting to dump property of undefined variable': {
            code: nowdoc(function () {/*<<<EOS
<?php
var_dump($undefinedVar->prop);
echo 'Done';
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: nowdoc(function () {/*<<<EOS
PHP Notice: Undefined variable: undefinedVar
PHP Notice: Trying to get property of non-object

EOS
*/;}), // jshint ignore:line
            // Note that the 'Done' echo following the dump must be executed, this is only a notice
            expectedStdout: nowdoc(function () {/*<<<EOS
NULL
Done
EOS
*/;}) // jshint ignore:line
        },
        'attempting to dump result of undefined variable method call': {
            code: nowdoc(function () {/*<<<EOS
<?php
var_dump($undefinedVar->myMethod());
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Call to a member function myMethod\(\) on a non-object$/
            },
            expectedStderr: nowdoc(function () {/*<<<EOS
PHP Notice: Undefined variable: undefinedVar
PHP Fatal error: Call to a member function myMethod() on a non-object
EOS
*/;}), // jshint ignore:line
            expectedStdout: ''
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });

    describe('when given one argument', function () {
        _.each({
            'empty array': {
                value: 'array()',
                expectedStdout: nowdoc(function () {/*<<<EOS
array(0) {
}

EOS
*/;}) // jshint ignore:line
            },
            'array with one element with implicit key': {
                value: 'array(7)',
                expectedStdout: nowdoc(function () {/*<<<EOS
array(1) {
  [0]=>
  int(7)
}

EOS
*/;}) // jshint ignore:line
            },
            'array with one element with explicit key': {
                value: 'array(4 => "a")',
                expectedStdout: nowdoc(function () {/*<<<EOS
array(1) {
  [4]=>
  string(1) "a"
}

EOS
*/;}) // jshint ignore:line
            },
            'array with one element with explicit key for subarray value': {
                value: 'array(5 => array(6, 7))',
                expectedStdout: nowdoc(function () {/*<<<EOS
array(1) {
  [5]=>
  array(2) {
    [0]=>
    int(6)
    [1]=>
    int(7)
  }
}

EOS
*/;}) // jshint ignore:line
            },
            'boolean true': {
                value: 'true',
                expectedStdout: 'bool(true)\n'
            },
            'boolean false': {
                value: 'false',
                expectedStdout: 'bool(false)\n'
            },
            'float': {
                value: '2.2',
                expectedStdout: 'float(2.2)\n'
            },
            'integer': {
                value: '3',
                expectedStdout: 'int(3)\n'
            },
            'null': {
                value: 'null',
                expectedStdout: 'NULL\n'
            },
            'empty stdClass instance': {
                value: 'new stdClass',
                expectedStdout: nowdoc(function () {/*<<<EOS
object(stdClass)#1 (0) {
}

EOS
*/;}) // jshint ignore:line
            },
            'stdClass instance with one property': {
                value: 'new stdClass; $value->prop = 1',
                expectedStdout: nowdoc(function () {/*<<<EOS
object(stdClass)#1 (1) {
  ["prop"]=>
  int(1)
}

EOS
*/;}) // jshint ignore:line
            },
            'stdClass instance with one property containing another stdClass instance': {
                value: 'new stdClass; $value->sub = new stdClass; $value->sub->prop = 1',
                expectedStdout: nowdoc(function () {/*<<<EOS
object(stdClass)#1 (1) {
  ["sub"]=>
  object(stdClass)#2 (1) {
    ["prop"]=>
    int(1)
  }
}

EOS
*/;}) // jshint ignore:line
            },
            'string': {
                value: '"world"',
                expectedStdout: 'string(5) "world"\n'
            },
            'stdClass instance with one property referring to itself': {
                value: 'new stdClass; $value->me = $value',
                expectedStdout: nowdoc(function () {/*<<<EOS
object(stdClass)#1 (1) {
  ["me"]=>
  *RECURSION*
}

EOS
*/;}) // jshint ignore:line
            },
            'array assigned to an element of itself - should be a copy, so no recursion': {
                value: 'array(); $value[0] = $value',
                expectedStdout: nowdoc(function () {/*<<<EOS
array(1) {
  [0]=>
  array(0) {
  }
}

EOS
*/;}) // jshint ignore:line
            },
            'array element with reference to variable': {
                value: 'array(); $where = "Here"; $value[0] =& $where; $where = "There"',
                expectedStdout: nowdoc(function () {/*<<<EOS
array(1) {
  [0]=>
  &string(5) "There"
}

EOS
*/;}) // jshint ignore:line
            },
            'reference to variable containing array assigned to an element of itself - should not be a copy, so recurses': {
                value: 'array(); $value[0] =& $value',
                expectedStdout: nowdoc(function () {/*<<<EOS
array(1) {
  [0]=>
  &array(1) {
    [0]=>
    *RECURSION*
  }
}

EOS
*/;}) // jshint ignore:line
            },
            'reference to variable containing object assigned to a property of itself': {
                value: 'new stdClass; $value->prop =& $value',
                expectedStdout: nowdoc(function () {/*<<<EOS
object(stdClass)#1 (1) {
  ["prop"]=>
  *RECURSION*
}

EOS
*/;}) // jshint ignore:line
            },
            'circular reference from array -> object -> array': {
                value: 'array(); $object = new stdClass; $value[0] =& $object; $object->prop =& $value',
                expectedStdout: nowdoc(function () {/*<<<EOS
array(1) {
  [0]=>
  &object(stdClass)#1 (1) {
    ["prop"]=>
    &array(1) {
      [0]=>
      *RECURSION*
    }
  }
}

EOS
*/;}) // jshint ignore:line
            }
        }, function (scenario, description) {
            describe(description, function () {
                check({
                    code: '<?php $value = ' + scenario.value + '; var_dump($value);',
                    expectedStderr: scenario.expectedStderr || '',
                    expectedStdout: scenario.expectedStdout
                });
            });
        });
    });
});
Esempio n. 17
0
describe('PHP Engine magic "__autoload" function statement integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'should throw a fatal error if magic __autoload function in global namespace does not take any arguments': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function __autoload() {}
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: __autoload\(\) must take exactly 1 argument$/
            },
            expectedStderr: 'PHP Fatal error: __autoload() must take exactly 1 argument',
            expectedStdout: ''
        },
        'should throw a fatal error if magic __autoload function with non-lower case in global namespace does not take any arguments': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function __autoLOAd() {}
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: __autoload\(\) must take exactly 1 argument$/
            },
            expectedStderr: 'PHP Fatal error: __autoload() must take exactly 1 argument',
            expectedStdout: ''
        },
        'should not throw a fatal error if magic __autoload function in a namespace does not take any arguments': {
            code: nowdoc(function () {/*<<<EOS
<?php
    namespace MyNamespace;
    function __autoload() {}
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            // Note that no error is raised, as the function is not magic if not in the global namespace
            expectedStderr: '',
            expectedStdout: ''
        },
        'should not be called when no class or interface is used': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function __autoload($class) {
        echo 'autoloading';
    }
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: ''
        },
        'should not be called when class used in global namespace is already defined': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function __autoload($class) {
        echo 'autoloading';
    }

    class Test {}

    $object = new Test;
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: ''
        },
        'should be called when undefined class is used, erroring if class is still not defined by autoloader': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function __autoload($class) {
        echo 'autoloading ' . $class;
    }

    $object = new TeSt;
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Class 'TeSt' not found$/
            },
            // Note additional check for case preservation in class name string passed to autoloader
            expectedStderr: 'PHP Fatal error: Class \'TeSt\' not found',
            expectedStdout: 'autoloading TeSt'
        },
        'should be called when undefined class is used in a namespace, erroring if class is still not defined by autoloader': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function __autoload($class) {
        echo 'autoloading ' . $class;
    }

    namespace My\Library;

    $object = new TeSt;
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Class 'My\\Library\\TeSt' not found$/
            },
            // Note additional check for case preservation in class name string passed to autoloader
            expectedStderr: 'PHP Fatal error: Class \'My\\Library\\TeSt\' not found',
            expectedStdout: 'autoloading My\\Library\\TeSt'
        },
        'should be called when undefined class is used, not erroring if class is then defined with same case by autoloader': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function __autoload($class) {
        class Test {}

        echo 'autoloaded ' . $class;
    }

    $object = new Test;
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'autoloaded Test'
        },
        'should be called when undefined class is used, not erroring if class is then defined with different case by autoloader': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function __autoload($class) {
        class MyTESTClass {}

        echo 'autoloaded ' . $class;
    }

    $object = new Mytestclass;
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'autoloaded Mytestclass'
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});
Esempio n. 18
0
describe('PHP Engine function call operator integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'calling function in global namespace with prefixed path': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function printIt() {
        echo 'it';
    }

    \printIt();
EOS
*/;}), // jshint ignore:line
            expectedStderr: '',
            expectedStdout: 'it'
        },
        'calling function in another deep namespace with prefixed path': {
            code: nowdoc(function () {/*<<<EOS
<?php
    namespace MyStuff\Tools;

    function printIt() {
        echo 'it';
    }

    namespace MyProgram;

    \MyStuff\Tools\printIt();
EOS
*/;}), // jshint ignore:line
            expectedStderr: '',
            expectedStdout: 'it'
        },
        'call to function that is defined in current namespace should not fall back to global namespace': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function printIt() {
        echo 'global-it';
    }

    namespace MyStuff;
    function printIt() {
        echo 'MyStuff-it';
    }

    namespace MyStuff;
    printIt();
EOS
*/;}), // jshint ignore:line
            expectedStderr: '',
            expectedStdout: 'MyStuff-it'
        },
        'call to function not defined in current namespace should fall back to global and not a parent namespace': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function printIt() {
        echo 'global-it';
    }

    namespace MyStuff;
    function printIt() {
        echo 'MyStuff-it';
    }

    namespace MyStuff\Tools;

    printIt();
EOS
*/;}), // jshint ignore:line
            expectedStderr: '',
            expectedStdout: 'global-it'
        },
        'call to function defined in current namespace via prefixed string': {
            code: nowdoc(function () {/*<<<EOS
<?php
    namespace MyTest;
    function myFunc() {
        return 24;
    }

    $fn = 'MyTest\myFunc';
    return $fn();
EOS
*/;}), // jshint ignore:line
            expectedResult: 24,
            expectedResultType: 'integer',
            expectedStderr: '',
            expectedStdout: ''
        },
        'call to instance method via array': {
            code: nowdoc(function () {/*<<<EOS
<?php
    class MyClass {
        public function printMsg($msg) {
            print $msg;

            return 24;
        }
    }

    $object = new MyClass;
    $ref = array($object, 'printMsg');

    return $ref('it');
EOS
*/;}), // jshint ignore:line
            expectedResult: 24,
            expectedResultType: 'integer',
            expectedStderr: '',
            expectedStdout: 'it'
        },
        'call to static method via array': {
            code: nowdoc(function () {/*<<<EOS
<?php
    class MyClass {
        public static function printMsg($msg) {
            print $msg;

            return 24;
        }
    }

    $ref = array('MyClass', 'printMsg');

    return $ref('it');
EOS
*/;}), // jshint ignore:line
            expectedResult: 24,
            expectedResultType: 'integer',
            expectedStderr: '',
            expectedStdout: 'it'
        },
        'passing an array literal referencing variable directly to a function when calling': {
            code: nowdoc(function () {/*<<<EOS
<?php
    function getFirst($numbers) {
        return $numbers[0];
    }

    $seven = 7;
    $eight = 8;

    return getFirst(array($seven, '1' => $eight));
EOS
*/;}), // jshint ignore:line
            expectedResult: 7,
            expectedResultType: 'integer',
            expectedStderr: '',
            expectedStdout: ''
        },
        'attempting to call instance method via array with only one element should fail': {
            code: nowdoc(function () {/*<<<EOS
<?php
    class MyClass {
        public function printIt() {
            print 'it';

            return 24;
        }
    }

    $object = new MyClass;
    $ref = array($object);

    return $ref();
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Function name must be a string$/
            },
            expectedStderr: 'PHP Fatal error: Function name must be a string',
            expectedStdout: ''
        },
        'call to function defined in current namespace via unprefixed string should fail': {
            code: nowdoc(function () {/*<<<EOS
<?php
    namespace MyTest;
    function myFunc() {}

    $fn = 'myFunc';
    $fn();
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Call to undefined function myFunc\(\)$/
            },
            expectedStderr: 'PHP Fatal error: Call to undefined function myFunc()',
            expectedStdout: ''
        },
        'call to undefined function in another namespace with prefixed path': {
            code: nowdoc(function () {/*<<<EOS
<?php
    namespace Test;
    \Creator\Stuff\doSomething();
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Call to undefined function Creator\\Stuff\\doSomething\(\)$/
            },
            expectedStderr: 'PHP Fatal error: Call to undefined function Creator\\Stuff\\doSomething()',
            expectedStdout: ''
        },
        'call to undefined function in another namespace with unprefixed path': {
            code: nowdoc(function () {/*<<<EOS
<?php
    namespace Test;
    Creator\Stuff\doSomething();
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Call to undefined function Test\\Creator\\Stuff\\doSomething\(\)$/
            },
            expectedStderr: 'PHP Fatal error: Call to undefined function Test\\Creator\\Stuff\\doSomething()',
            expectedStdout: ''
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});
Esempio n. 19
0
describe('PHP Engine strtr() builtin function integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        '3-argument form': {
            code: nowdoc(function () {/*<<<EOS
<?php
$msg = 'Hello from abc!';

return strtr($msg, 'abcd', 'efgh');
EOS
*/;}), // jshint ignore:line
            expectedResult: 'Hello from efg!',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        '3-argument form with longer $from ignores extra characters in $to': {
            code: nowdoc(function () {/*<<<EOS
<?php
$msg = 'Hello from abc!';

return strtr($msg, 'abcdefgh', 'ijk');
EOS
*/;}), // jshint ignore:line
            expectedResult: 'Hello from ijk!',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        '2-argument form': {
            code: nowdoc(function () {/*<<<EOS
<?php
$msg = 'Hello from abc, abc!';

return strtr($msg, array('ello' => 'i', 'b' => 'z'));
EOS
*/;}), // jshint ignore:line
            expectedResult: 'Hi from azc, azc!',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});
Esempio n. 20
0
describe('PHP Engine do...while statement integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'do...while loop with bool(false) condition - should execute body statements once': {
            code: nowdoc(function () {/*<<<EOS
<?php
    do {
        echo 1;
        echo 2;
    } while (false);

    echo 'Done.';
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: '12Done.'
        },
        'do...while loop with bool(false) condition and with no braces around body - should execute body statement once': {
            code: nowdoc(function () {/*<<<EOS
<?php
    do echo 1; while (false);

    echo 'Done.';
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: '1Done.'
        },
        'do...while loop with counter to only execute 2 times': {
            code: nowdoc(function () {/*<<<EOS
<?php
    $a = 0;

    do {
        echo $a++ . ',';
    } while ($a < 2);
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: '0,1,'
        },
        'do...while loop with non-boolean falsy value - countdown from 2 to 0': {
            code: nowdoc(function () {/*<<<EOS
<?php
    $a = 2;

    do {
        echo $a-- . ',';
    } while ($a);
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: '2,1,'
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});
Esempio n. 21
0
describe('PHP Engine double-quoted string construct integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'empty string': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return "";
EOS
*/;}), // jshint ignore:line
            expectedResult: '',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'string with plain text': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return "hello world";
EOS
*/;}), // jshint ignore:line
            expectedResult: 'hello world',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'string with plain text and backslash escape': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return "this backslash \\ should end up as a single backslash";
EOS
*/;}), // jshint ignore:line
            expectedResult: 'this backslash \\ should end up as a single backslash',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'string with plain text and invalid backslash escape with whitespace following': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return "this standalone backslash \ should end up as a single backslash";
EOS
*/;}), // jshint ignore:line
            expectedResult: 'this standalone backslash \\ should end up as a single backslash',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'string with plain text and invalid backslash escape with character following': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return "this invalid escape \z should be left alone";
EOS
*/;}), // jshint ignore:line
            expectedResult: 'this invalid escape \\z should be left alone',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'string with plain text and dollar escape': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return "this escaped dollar \$ should end up as a plain dollar";
EOS
*/;}), // jshint ignore:line
            expectedResult: 'this escaped dollar $ should end up as a plain dollar',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'string with plain text and escaped double-quote': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return "this escaped quote \" should end up as just a double-quote";
EOS
*/;}), // jshint ignore:line
            expectedResult: 'this escaped quote " should end up as just a double-quote',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'string with plain text and ESC escape': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return "before \e after";
EOS
*/;}), // jshint ignore:line
            expectedResult: 'before \x1B after',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'string with plain text and form feed escape': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return "before \f after";
EOS
*/;}), // jshint ignore:line
            expectedResult: 'before \f after',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'string with plain text and linefeed escape': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return "before \n after";
EOS
*/;}), // jshint ignore:line
            expectedResult: 'before \n after',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'string with plain text and two linefeed escapes': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return "before \n middle \n after";
EOS
*/;}), // jshint ignore:line
            expectedResult: 'before \n middle \n after',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'string with plain text and carriage return escape': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return "before \r after";
EOS
*/;}), // jshint ignore:line
            expectedResult: 'before \r after',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'string with plain text and horizontal tab escape': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return "before \t after";
EOS
*/;}), // jshint ignore:line
            expectedResult: 'before \t after',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'string with plain text and vertical tab escape': {
            code: nowdoc(function () {/*<<<EOS
<?php
    return "before \v after";
EOS
*/;}), // jshint ignore:line
            expectedResult: 'before \v after',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        },
        'string with all escapes and interpolated variable': {
            code: nowdoc(function () {/*<<<EOS
<?php
    $name = 'Dan';

    return "before \n \r \t \v \e \f \\ \ \z \$ \" $name after";
EOS
*/;}), // jshint ignore:line
            expectedResult: 'before \n \r \t \v \x1B \f \\ \\ \\z $ " Dan after',
            expectedResultType: 'string',
            expectedStderr: '',
            expectedStdout: ''
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});
Esempio n. 22
0
describe('PHP Engine object access operator "->" instance method integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'call to statically referenced instance method returning value': {
            code: nowdoc(function () {/*<<<EOS
<?php
    class Test {
        public function getIt() {
            return 7;
        }
    }

    $object = new Test;

    return $object->getIt();
EOS
*/;}), // jshint ignore:line
            expectedResult: 7,
            expectedStderr: '',
            expectedStdout: ''
        },
        'call to statically referenced instance method with argument and returning value': {
            code: nowdoc(function () {/*<<<EOS
<?php
    class Test {
        public function addOne($number) {
            return $number + 1;
        }
    }

    $object = new Test;

    return $object->addOne(3);
EOS
*/;}), // jshint ignore:line
            expectedResult: 4,
            expectedStderr: '',
            expectedStdout: ''
        },
        'call to dynamically referenced instance method returning value': {
            code: nowdoc(function () {/*<<<EOS
<?php
    class Test {
        public function getIt() {
            return 6;
        }
    }

    $object = new Test;
    $methodName = 'getIt';

    return $object->$methodName();
EOS
*/;}), // jshint ignore:line
            expectedResult: 6,
            expectedStderr: '',
            expectedStdout: ''
        },
        'call to undefined method of object when class is in global namespace': {
            code: nowdoc(function () {/*<<<EOS
<?php
    class Test {}

    $object = new Test;

    var_dump($object->iDontExist());
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Call to undefined method Test::iDontExist\(\)$/
            },
            expectedStderr: 'PHP Fatal error: Call to undefined method Test::iDontExist()',
            expectedStdout: ''
        },
        'call to undefined method of object when class is in a namespace': {
            code: nowdoc(function () {/*<<<EOS
<?php
    namespace MyStuff;

    class Test {}

    $object = new Test;

    var_dump($object->iDontExist());
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Call to undefined method MyStuff\\Test::iDontExist\(\)$/
            },
            expectedStderr: 'PHP Fatal error: Call to undefined method MyStuff\\Test::iDontExist()',
            expectedStdout: ''
        },
        // Ensure we use .hasOwnProperty(...) checks internally
        'call to undefined instance method called "constructor"': {
            code: nowdoc(function () {/*<<<EOS
<?php
    class Earth {}

    $planet = new Earth;

    return $planet->constructor();
EOS
*/;}), // jshint ignore:line
            expectedException: {
                instanceOf: PHPFatalError,
                match: /^PHP Fatal error: Call to undefined method Earth::constructor\(\)$/
            },
            expectedStderr: 'PHP Fatal error: Call to undefined method Earth::constructor()',
            expectedStdout: ''
        },
        'calling static method as instance method': {
            code: nowdoc(function () {/*<<<EOS
<?php
    class Animal {
        public static function getPlanet() {
            return 'Earth';
        }
    }

    $animal = new Animal();

    return $animal->getPlanet();
EOS
*/;}), // jshint ignore:line
            expectedResult: 'Earth',
            expectedResultType: 'string',
            // Note that no notices are generated at all
            expectedStderr: '',
            expectedStdout: ''
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});
describe('PHP Engine spl_autoload_unregister() builtin function integration', function () {
    var engine;

    function check(scenario) {
        engineTools.check(function () {
            return {
                engine: engine
            };
        }, scenario);
    }

    beforeEach(function () {
        engine = phpTools.createEngine();
    });

    _.each({
        'returns true when function has been registered': {
            code: nowdoc(function () {/*<<<EOS
<?php
function myAutoloader($className) {
}
spl_autoload_register('myAutoloader');
return spl_autoload_unregister('myAutoloader');
EOS
*/;}), // jshint ignore:line
            expectedResult: true,
            expectedResultType: 'boolean',
            expectedStderr: '',
            expectedStdout: ''
        },
        'returns false when function has not been registered': {
            code: nowdoc(function () {/*<<<EOS
<?php
function myAutoloader($className) {
}
return spl_autoload_unregister('myAutoloader');
EOS
*/;}), // jshint ignore:line
            expectedResult: false,
            expectedResultType: 'boolean',
            expectedStderr: '',
            expectedStdout: ''
        },
        'still allows the previous autoload function to be called': {
            code: nowdoc(function () {/*<<<EOS
<?php
function firstAutoloader($className) {
    class MyClass {}
    print 'First: ' . $className;
}
spl_autoload_register('firstAutoloader');
function secondAutoloader($className) {
    class MyClass {}
    print 'Second: ' . $className;
}
spl_autoload_register('secondAutoloader');
spl_autoload_unregister('secondAutoloader');

new MyClass();
EOS
*/;}), // jshint ignore:line
            expectedResult: null,
            expectedStderr: '',
            expectedStdout: 'First: MyClass'
        }
    }, function (scenario, description) {
        describe(description, function () {
            check(scenario);
        });
    });
});