@function test-bind-1($value) {
    $foo: __this('foo');
    @return $foo + $value;
}
@function test-bind-2($value) {
    @return $value;
}
@function test-bind-3($greeting, $punc) {
    @return $greeting + ' ' + __this('user') + $punc;
}
@include test-module('_bind') {
    @include test('should bind a function to a scope') {
        $_: __scope(('foo': 1));
        $func: _bind(test-bind-1);
        $_: __scope(false);

        @include assert-equal(_exec($func, 3), 4);
    }

    @include test('should bind a function to a map') {
        $_: __scope();
        $func: _bind(test-bind-1, ('foo': 2));
        $_: __scope(false);

        @include assert-equal(_exec($func, 3), 5);
    }

    @include test('should accept a falsey this-arg argument') {
        @each $value in $test-falsey {
            $func: _bind(test-bind-2, $value);

            @include assert-equal(_exec($func, 1), 1);
        }
    }

    @include test('should partially apply arguments') {
        $scope: __scope(('user': 'fred'));
        $scope-id: __get($scope, '_id');
        $func: _bind(test-bind-3, $scope-id, 'hi');
        $_: __scope(false);

        @include assert-equal(_exec($func, '!'), 'hi fred!');
    }

    @include xit('should support placeholders') {} // todo

    @include test('should ensure new bound is an executable function') {
        $func: _bind(test-bind-3, ('foo': 'bar'));

        @include assert-true(_is-function($func));
    }
}