expressionClass('MyFunction'); $this->assertSame('MyFunction()', $f->sql(new ValueBinder())); } /** * Tests generating a function one or multiple arguments and make sure * they are correctly replaced by placeholders */ public function testArityMultiplePlainValues(): void { $f = new $this->expressionClass('MyFunction', ['foo', 'bar']); $binder = new ValueBinder(); $this->assertSame('MyFunction(:param0, :param1)', $f->sql($binder)); $this->assertSame('foo', $binder->bindings()[':param0']['value']); $this->assertSame('bar', $binder->bindings()[':param1']['value']); $binder = new ValueBinder(); $f = new $this->expressionClass('MyFunction', ['bar']); $this->assertSame('MyFunction(:param0)', $f->sql($binder)); $this->assertSame('bar', $binder->bindings()[':param0']['value']); } /** * Tests that it is possible to use literal strings as arguments */ public function testLiteralParams(): void { $binder = new ValueBinder(); $f = new $this->expressionClass('MyFunction', ['foo' => 'literal', 'bar']); $this->assertSame('MyFunction(foo, :param0)', $f->sql($binder)); } /** * Tests that it is possible to nest expression objects and pass them as arguments * In particular nesting multiple FunctionExpression */ public function testFunctionNesting(): void { $binder = new ValueBinder(); $f = new $this->expressionClass('MyFunction', ['foo', 'bar']); $g = new $this->expressionClass('Wrapper', ['bar' => 'literal', $f]); $this->assertSame('Wrapper(bar, MyFunction(:param0, :param1))', $g->sql($binder)); } /** * Tests to avoid regression, prevents double parenthesis * In particular nesting with QueryExpression */ public function testFunctionNestingQueryExpression(): void { $binder = new ValueBinder(); $q = new QueryExpression('a'); $f = new $this->expressionClass('MyFunction', [$q]); $this->assertSame('MyFunction(a)', $f->sql($binder)); } /** * Tests that passing a database query as an argument wraps the query SQL into parentheses. */ public function testFunctionWithDatabaseQuery(): void { $query = ConnectionManager::get('test') ->selectQuery(['column']); $binder = new ValueBinder(); $function = new $this->expressionClass('MyFunction', [$query]); $this->assertSame( 'MyFunction((SELECT column))', preg_replace('/[`"\[\]]/', '', $function->sql($binder)) ); } /** * Tests that it is possible to use a number as a literal in a function. */ public function testNumericLiteral(): void { $binder = new ValueBinder(); $f = new $this->expressionClass('MyFunction', ['a_field' => 'literal', '32' => 'literal']); $this->assertSame('MyFunction(a_field, 32)', $f->sql($binder)); $f = new $this->expressionClass('MyFunction', ['a_field' => 'literal', 32 => 'literal']); $this->assertSame('MyFunction(a_field, 32)', $f->sql($binder)); } /** * Tests setReturnType() and getReturnType() */ public function testGetSetReturnType(): void { $f = new $this->expressionClass('MyFunction'); $f = $f->setReturnType('foo'); $this->assertInstanceOf($this->expressionClass, $f); $this->assertSame('foo', $f->getReturnType()); } }