<commit_before><?php

namespace Vector\Test\Core;

use PHPUnit\Framework\TestCase;
use Vector\Core\Module;
use Vector\Core\Exception\FunctionNotFoundException;

class ModuleTest extends TestCase
{
    /**
     * Test to make sure we can pull functions off the capsule and they'll return closures
     */
    public function testUsingFunctions()
    {
        $noArgFunction = Stub\TestFunctions::Using('noArgFunction');

        $functionMap = Stub\TestFunctions::Using('noArgFunction', 'oneArgFunction');

        // Test that singular-loading works
        $this->assertInstanceOf('\\Closure', $noArgFunction);

        // Test that multiple-loading works
        $this->assertInstanceOf('\\Closure', $functionMap[0]);
        $this->assertInstanceOf('\\Closure', $functionMap[1]);
    }

    /**
     * Test that the module caches function resolutions
     */
    public function testModuleCaching()
    {
        // Loading the function should add it to the cache
        $notAPureFunction = Stub\TestFunctions::using('notAPureFunction');

        $cache = Stub\TestFunctions::getFulfillmentCache()['Vector\Test\Core\Stub\TestFunctions'];

        $this->assertArrayHasKey('__notAPureFunction', $cache);
    }

    /**
     * Test alternative function calling scheme
     */
    public function testAlternativeFunctionPattern()
    {
        $this->assertInstanceOf('\\Closure', Stub\TestFunctions::oneArgFunction());
    }

    /**
     * Tests that memoization works on the module
     */
    public function testMemoization()
    {
        $memoizedFunction = Stub\TestFunctions::using('memoizedFunction');

        // On the first run we expect side effects
        ob_start();
        $this->assertEquals($memoizedFunction(1, 2, 3), 6);
        $sideEffects = ob_get_clean();

        $this->assertEquals($sideEffects, "I'm a side effect.");

        // But on the second run we don't
        ob_start();
        $this->assertEquals($memoizedFunction(1, 2, 3), 6);
        $sideEffects = ob_get_clean();

        $this->assertEquals($sideEffects, "");
    }

    /**
     * Test that caching on the Module core works by returning exact duplicates of the functions you request
     */
    public function testCachedFunctions()
    {
        $noArgFunctionA = Stub\TestFunctions::Using('noArgFunction');
        $noArgFunctionB = Stub\TestFunctions::Using('noArgFunction');

        $this->assertEquals($noArgFunctionA, $noArgFunctionB);
        $this->assertEquals($noArgFunctionA(), $noArgFunctionB());
    }

    /**
     * Test to make sure that a function in the function capsule with no arguments is
     * curried properly
     */
    public function testNoArgFunctionIsCurried()
    {
        $noArgFunction = Stub\TestFunctions::Using('noArgFunction');

        // Invoking the function should return true
        $this->assertEquals($noArgFunction(), true);
    }

    /**
     * Test to make sure that one-argument functions are treated like normal functions
     */
    public function testOneArgFunctionIsCurried()
    {
        $oneArgFunction = Stub\TestFunctions::Using('oneArgFunction');

        // Invoking the curried function should be a closure
        $this->assertInstanceOf('\\Closure', $oneArgFunction());

        // Giving an argument to the curried function should return true
        $this->assertEquals($oneArgFunction(true), true);
    }

    /**
     * Test that two-argument functions are curried and partially applicable
     */
    public function testTwoArgFunctionIsCurried()
    {
        $twoArgFunction = Stub\TestFunctions::Using('twoArgFunction');

        $oneArgApplied = $twoArgFunction(true);

        // Invoking the original function should be a closure
        $this->assertInstanceOf('\\Closure', $twoArgFunction());

        // Invoking the applied function should be a closure
        $this->assertInstanceOf('\\Closure', $oneArgApplied());

        // The applied function should be a closure
        $this->assertInstanceOf('\\Closure', $oneArgApplied);

        // The original function, when given 2 args, should return true
        $this->assertEquals($twoArgFunction(true, true), true);

        // The applied function, given its remaining argument, should return true
        $this->assertEquals($oneArgApplied(true), true);
    }

    /**
     * Tests the currying of variadic functions
     */
    public function testVariadicFunctionIsCurried()
    {
        $variadicFunction = Stub\TestFunctions::Using('variadicFunction');

        // Test zero arguments
        $this->assertInstanceOf('\\Closure', $variadicFunction());<commit_msg>Added two tests to cover passing arguments to curried functions using unpacking<commit_after><?php

namespace Vector\Test\Core;

use PHPUnit\Framework\TestCase;
use Vector\Core\Module;
use Vector\Core\Exception\FunctionNotFoundException;

class ModuleTest extends TestCase
{
    /**
     * Test to make sure we can pull functions off the capsule and they'll return closures
     */
    public function testUsingFunctions()
    {
        $noArgFunction = Stub\TestFunctions::Using('noArgFunction');

        $functionMap = Stub\TestFunctions::Using('noArgFunction', 'oneArgFunction');

        // Test that singular-loading works
        $this->assertInstanceOf('\\Closure', $noArgFunction);

        // Test that multiple-loading works
        $this->assertInstanceOf('\\Closure', $functionMap[0]);
        $this->assertInstanceOf('\\Closure', $functionMap[1]);
    }

    /**
     * Test that the module caches function resolutions
     */
    public function testModuleCaching()
    {
        // Loading the function should add it to the cache
        $notAPureFunction = Stub\TestFunctions::using('notAPureFunction');

        $cache = Stub\TestFunctions::getFulfillmentCache()['Vector\Test\Core\Stub\TestFunctions'];

        $this->assertArrayHasKey('__notAPureFunction', $cache);
    }

    /**
     * Test alternative function calling scheme
     */
    public function testAlternativeFunctionPattern()
    {
        $this->assertInstanceOf('\\Closure', Stub\TestFunctions::oneArgFunction());
    }

    /**
     * Tests that memoization works on the module
     */
    public function testMemoization()
    {
        $memoizedFunction = Stub\TestFunctions::using('memoizedFunction');

        // On the first run we expect side effects
        ob_start();
        $this->assertEquals($memoizedFunction(1, 2, 3), 6);
        $sideEffects = ob_get_clean();

        $this->assertEquals($sideEffects, "I'm a side effect.");

        // But on the second run we don't
        ob_start();
        $this->assertEquals($memoizedFunction(1, 2, 3), 6);
        $sideEffects = ob_get_clean();

        $this->assertEquals($sideEffects, "");
    }

    /**
     * Test that caching on the Module core works by returning exact duplicates of the functions you request
     */
    public function testCachedFunctions()
    {
        $noArgFunctionA = Stub\TestFunctions::Using('noArgFunction');
        $noArgFunctionB = Stub\TestFunctions::Using('noArgFunction');

        $this->assertEquals($noArgFunctionA, $noArgFunctionB);
        $this->assertEquals($noArgFunctionA(), $noArgFunctionB());
    }

    /**
     * Test to make sure that a function in the function capsule with no arguments is
     * curried properly
     */
    public function testNoArgFunctionIsCurried()
    {
        $noArgFunction = Stub\TestFunctions::Using('noArgFunction');

        // Invoking the function should return true
        $this->assertEquals($noArgFunction(), true);
    }

    /**
     * Test to make sure that one-argument functions are treated like normal functions
     */
    public function testOneArgFunctionIsCurried()
    {
        $oneArgFunction = Stub\TestFunctions::Using('oneArgFunction');

        // Invoking the curried function should be a closure
        $this->assertInstanceOf('\\Closure', $oneArgFunction());

        // Giving an argument to the curried function should return true
        $this->assertEquals($oneArgFunction(true), true);
    }

    /**
     * Test that two-argument functions are curried and partially applicable
     */
    public function testTwoArgFunctionIsCurried()
    {
        $twoArgFunction = Stub\TestFunctions::Using('twoArgFunction');

        $oneArgApplied = $twoArgFunction(true);

        // Invoking the original function should be a closure
        $this->assertInstanceOf('\\Closure', $twoArgFunction());

        // Invoking the applied function should be a closure
        $this->assertInstanceOf('\\Closure', $oneArgApplied());

        // The applied function should be a closure
        $this->assertInstanceOf('\\Closure', $oneArgApplied);

        // The original function, when given 2 args, should return true
        $this->assertEquals($twoArgFunction(true, true), true);

        // The applied function, given its remaining argument, should return true
        $this->assertEquals($oneArgApplied(true), true);
    }

    /**
     * Test that passing an argument unpacking operator to a curried function works
     */
    public function testCurriedArgumentUnpacking()
    {
        $twoArgFunction = Stub\TestFunctions::twoArgFunction();

        $this->assertInstanceOf('\\Closure', $twoArgFunction(...[true]));
        $this->assertEquals($twoArgFunction(...[true, true]), true);
    }

    /**
     * Tests the currying of variadic functions
     */
    public function testVariadicFunctionIsCurried()
    {
        $variadicFunction = Stub\TestFunctions::Using('variadicFunction');

        // Test zero arguments
        $this->assertInstanceOf('\\Closure', $variadicFunction());
{'fraction_non_alphanumeric': 0.11552009946125155, 'fraction_numerical': 0.0022793203481143802, 'mean_word_length': 2.951289398280802, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 45, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2819392', 'n_tokens_mistral': 2616, 'n_tokens_neox': 2486, 'n_words': 662}