pdo-document/tests/Unit/FieldTest.php

419 lines
18 KiB
PHP

<?php
/**
* @author Daniel J. Summers <daniel@bitbadger.solutions>
* @license MIT
*/
declare(strict_types=1);
use BitBadger\PDODocument\{Configuration, Field, Mode, Op};
pest()->group('unit');
describe('->appendParameter()', function () {
afterEach(function () { Configuration::overrideMode(null); });
test('appends no parameter for exists', function () {
expect(Field::exists('exists')->appendParameter([]))->toBeEmpty();
});
test('appends no parameter for notExists', function () {
expect(Field::notExists('absent')->appendParameter([]))->toBeEmpty();
});
test('appends two parameters for between', function () {
expect(Field::between('exists', 5, 9, '@num')->appendParameter([]))
->toHaveLength(2)
->toEqual(['@nummin' => 5, '@nummax' => 9]);
});
test('appends a parameter for each value for in', function () {
expect(Field::in('it', ['test', 'unit', 'great'], ':val')->appendParameter([]))
->toHaveLength(3)
->toEqual([':val_0' => 'test', ':val_1' => 'unit', ':val_2' => 'great']);
});
test('appends a parameter for each value for inArray [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
expect(Field::inArray('it', 'table', [2, 8, 64], ':bit')->appendParameter([]))
->toHaveLength(3)
->toEqual([':bit_0' => '2', ':bit_1' => '8', ':bit_2' => '64']);
})->group('postgresql');
test('appends a parameter for each value for inArray [SQLite]', function () {
Configuration::overrideMode(Mode::SQLite);
expect(Field::inArray('it', 'table', [2, 8, 64], ':bit')->appendParameter([]))
->toHaveLength(3)
->toEqual([':bit_0' => 2, ':bit_1' => 8, ':bit_2' => 64]);
})->group('sqlite');
test('appends a parameter for other operators', function () {
expect(Field::equal('the_field', 33, ':test')->appendParameter([]))
->toHaveLength(1)
->toEqual([':test' => 33]);
});
});
describe('->path()', function () {
afterEach(function () { Configuration::overrideMode(null); });
test('returns simple SQL path [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
expect(Field::equal('it', 'that'))->path()->toBe("data->>'it'");
})->group('postgresql');
test('returns simple SQL path [SQLite]', function () {
Configuration::overrideMode(Mode::SQLite);
expect(Field::equal('top', 'that'))->path()->toBe("data->>'top'");
})->group('sqlite');
test('returns nested SQL path [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
expect(Field::equal('parts.to.the.path', ''))->path()->toBe("data#>>'{parts,to,the,path}'");
})->group('postgresql');
test('returns nested SQL path [SQLite]', function () {
Configuration::overrideMode(Mode::SQLite);
expect(Field::equal('one.two.three', ''))->path()->toBe("data->'one'->'two'->>'three'");
})->group('sqlite');
test('returns simple JSON path [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
expect(Field::equal('it', 'that'))->path(true)->toBe("data->'it'");
})->group('postgresql');
test('returns simple JSON path [SQLite]', function () {
Configuration::overrideMode(Mode::SQLite);
expect(Field::equal('top', 'that'))->path(true)->toBe("data->'top'");
})->group('sqlite');
test('returns nested JSON path [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
expect(Field::equal('parts.to.the.path', ''))->path(true)->toBe("data#>'{parts,to,the,path}'");
})->group('postgresql');
test('returns nested JSON path [SQLite]', function () {
Configuration::overrideMode(Mode::SQLite);
expect(Field::equal('one.two.three', ''))->path(true)->toBe("data->'one'->'two'->'three'");
})->group('sqlite');
});
describe('->toWhere()', function () {
afterEach(function () { Configuration::overrideMode(null); });
test('generates IS NOT NULL for exists w/o qualifier [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
expect(Field::exists('that_field'))->toWhere()->toBe("data->>'that_field' IS NOT NULL");
})->group('postgresql');
test('generates IS NOT NULL for exists w/o qualifier [SQLite]', function () {
Configuration::overrideMode(Mode::SQLite);
expect(Field::exists('that_field'))->toWhere()->toBe("data->>'that_field' IS NOT NULL");
})->group('sqlite');
test('generates IS NULL for notExists w/o qualifier [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
expect(Field::notExists('a_field'))->toWhere()->toBe("data->>'a_field' IS NULL");
})->group('postgresql');
test('generates IS NULL for notExists w/o qualifier [SQLite]', function () {
Configuration::overrideMode(Mode::SQLite);
expect(Field::notExists('a_field'))->toWhere()->toBe("data->>'a_field' IS NULL");
})->group('sqlite');
test('generates BETWEEN for between w/o qualifier [SQLite]', function () {
Configuration::overrideMode(Mode::SQLite);
expect(Field::between('age', 13, 17, '@age'))->toWhere()->toBe("data->>'age' BETWEEN @agemin AND @agemax");
})->group('sqlite');
test('generates BETWEEN for between w/o qualifier, numeric range [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
expect(Field::between('age', 13, 17, '@age'))->toWhere()
->toBe("(data->>'age')::numeric BETWEEN @agemin AND @agemax");
})->group('postgresql');
test('generates BETWEEN for between w/o qualifier, non-numeric range [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
expect(Field::between('city', 'Atlanta', 'Chicago', ':city'))->toWhere()
->toBe("data->>'city' BETWEEN :citymin AND :citymax");
})->group('postgresql');
test('generates BETWEEN for between w/ qualifier [SQLite]', function () {
Configuration::overrideMode(Mode::SQLite);
$field = Field::between('age', 13, 17, '@age');
$field->qualifier = 'me';
expect($field)->toWhere()->toBe("me.data->>'age' BETWEEN @agemin AND @agemax");
})->group('sqlite');
test('generates BETWEEN for between w/ qualifier, numeric range [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
$field = Field::between('age', 13, 17, '@age');
$field->qualifier = 'me';
expect($field)->toWhere()->toBe("(me.data->>'age')::numeric BETWEEN @agemin AND @agemax");
})->group('postgresql');
test('generates BETWEEN for between w/ qualifier, non-numeric range [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
$field = Field::between('city', 'Atlanta', 'Chicago', ':city');
$field->qualifier = 'me';
expect($field)->toWhere()->toBe("me.data->>'city' BETWEEN :citymin AND :citymax");
})->group('postgresql');
test('generates IN for in, non-numeric values [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
expect(Field::in('test', ['Atlanta', 'Chicago'], ':city'))->toWhere()
->toBe("data->>'test' IN (:city_0, :city_1)");
})->group('postgresql');
test('generates IN for in, numeric values [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
expect(Field::in('even', [2, 4, 6], ':nbr'))->toWhere()
->toBe("(data->>'even')::numeric IN (:nbr_0, :nbr_1, :nbr_2)");
})->group('postgresql');
test('generates IN for in [SQLite]', function () {
Configuration::overrideMode(Mode::SQLite);
expect(Field::in('test', ['Atlanta', 'Chicago'], ':city'))->toWhere()
->toBe("data->>'test' IN (:city_0, :city_1)");
})->group('sqlite');
test('generates clause for inArray [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
expect(Field::inArray('even', 'tbl', [2, 4, 6, 8], ':it'))->toWhere()
->toBe("data->'even' ??| ARRAY[:it_0, :it_1, :it_2, :it_3]");
})->group('postgresql');
test('generates clause for inArray [SQLite]', function () {
Configuration::overrideMode(Mode::SQLite);
expect(Field::inArray('test', 'tbl', ['Atlanta', 'Chicago'], ':city'))->toWhere()
->toBe("EXISTS (SELECT 1 FROM json_each(tbl.data, '\$.test') WHERE value IN (:city_0, :city_1))");
})->group('sqlite');
test('generates clause for other operators w/o qualifier [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
expect(Field::equal('some_field', '', ':value'))->toWhere()->toBe("data->>'some_field' = :value");
})->group('postgresql');
test('generates clause for other operators w/o qualifier [SQLite]', function () {
Configuration::overrideMode(Mode::SQLite);
expect(Field::equal('some_field', '', ':value'))->toWhere()->toBe("data->>'some_field' = :value");
})->group('sqlite');
test('generates no-parameter clause w/ qualifier [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
$field = Field::exists('no_field');
$field->qualifier = 'test';
expect($field)->toWhere()->toBe("test.data->>'no_field' IS NOT NULL");
})->group('postgresql');
test('generates no-parameter clause w/ qualifier [SQLite]', function () {
Configuration::overrideMode(Mode::SQLite);
$field = Field::exists('no_field');
$field->qualifier = 'test';
expect($field)->toWhere()->toBe("test.data->>'no_field' IS NOT NULL");
})->group('sqlite');
test('generates parameter clause w/ qualifier [PostgreSQL]', function () {
Configuration::overrideMode(Mode::PgSQL);
$field = Field::lessOrEqual('le_field', 18, ':it');
$field->qualifier = 'q';
expect($field)->toWhere()->toBe("(q.data->>'le_field')::numeric <= :it");
})->group('postgresql');
test('generates parameter clause w/ qualifier [SQLite]', function () {
Configuration::overrideMode(Mode::SQLite);
$field = Field::lessOrEqual('le_field', 18, ':it');
$field->qualifier = 'q';
expect($field)->toWhere()->toBe("q.data->>'le_field' <= :it");
})->group('sqlite');
});
describe('::equal()', function () {
test('creates Field w/o parameter', function () {
$field = Field::equal('my_test', 9);
expect($field)
->not->toBeNull()
->fieldName->toBe('my_test')
->op->toBe(Op::Equal)
->paramName->toBeEmpty()
->and($field->value)->toBe(9);
});
test('creates Field w/ parameter', function () {
$field = Field::equal('another_test', 'turkey', ':test');
expect($field)
->not->toBeNull()
->fieldName->toBe('another_test')
->op->toBe(Op::Equal)
->paramName->toBe(':test')
->and($field->value)->toBe('turkey');
});
});
describe('::greater()', function () {
test('creates Field w/o parameter', function () {
$field = Field::greater('your_test', 4);
expect($field)
->not->toBeNull()
->fieldName->toBe('your_test')
->op->toBe(Op::Greater)
->paramName->toBeEmpty()
->and($field->value)->toBe(4);
});
test('creates Field w/ parameter', function () {
$field = Field::greater('more_test', 'chicken', ':value');
expect($field)
->not->toBeNull()
->fieldName->toBe('more_test')
->op->toBe(Op::Greater)
->paramName->toBe(':value')
->and($field->value)->toBe('chicken');
});
});
describe('::greaterOrEqual()', function () {
test('creates Field w/o parameter', function () {
$field = Field::greaterOrEqual('their_test', 6);
expect($field)
->not->toBeNull()
->fieldName->toBe('their_test')
->op->toBe(Op::GreaterOrEqual)
->paramName->toBeEmpty()
->and($field->value)->toBe(6);
});
test('creates Field w/ parameter', function () {
$field = Field::greaterOrEqual('greater_test', 'poultry', ':cluck');
expect($field)
->not->toBeNull()
->fieldName->toBe('greater_test')
->op->toBe(Op::GreaterOrEqual)
->paramName->toBe(':cluck')
->and($field->value)->toBe('poultry');
});
});
describe('::less()', function () {
test('creates Field w/o parameter', function () {
$field = Field::less('z', 32);
expect($field)
->not->toBeNull()
->fieldName->toBe('z')
->op->toBe(Op::Less)
->paramName->toBeEmpty()
->and($field->value)->toBe(32);
});
test('creates Field w/ parameter', function () {
$field = Field::less('additional_test', 'fowl', ':boo');
expect($field)
->not->toBeNull()
->fieldName->toBe('additional_test')
->op->toBe(Op::Less)
->paramName->toBe(':boo')
->and($field->value)->toBe('fowl');
});
});
describe('::lessOrEqual()', function () {
test('creates Field w/o parameter', function () {
$field = Field::lessOrEqual('g', 87);
expect($field)
->not->toBeNull()
->fieldName->toBe('g')
->op->toBe(Op::LessOrEqual)
->paramName->toBeEmpty()
->and($field->value)->toBe(87);
});
test('creates Field w/ parameter', function () {
$field = Field::lessOrEqual('lesser_test', 'hen', ':woo');
expect($field)
->not->toBeNull()
->fieldName->toBe('lesser_test')
->op->toBe(Op::LessOrEqual)
->paramName->toBe(':woo')
->and($field->value)->toBe('hen');
});
});
describe('::notEqual()', function () {
test('creates Field w/o parameter', function () {
$field = Field::notEqual('j', 65);
expect($field)
->not->toBeNull()
->fieldName->toBe('j')
->op->toBe(Op::NotEqual)
->paramName->toBeEmpty()
->and($field->value)->toBe(65);
});
test('creates Field w/ parameter', function () {
$field = Field::notEqual('unequal_test', 'egg', ':zoo');
expect($field)
->not->toBeNull()
->fieldName->toBe('unequal_test')
->op->toBe(Op::NotEqual)
->paramName->toBe(':zoo')
->and($field->value)->toBe('egg');
});
});
describe('::between()', function () {
test('creates Field w/o parameter', function () {
$field = Field::between('k', 'alpha', 'zed');
expect($field)
->not->toBeNull()
->fieldName->toBe('k')
->op->toBe(Op::Between)
->paramName->toBeEmpty()
->and($field->value)->toEqual(['alpha', 'zed']);
});
test('creates Field w/ parameter', function () {
$field = Field::between('between_test', 18, 49, ':count');
expect($field)
->not->toBeNull()
->fieldName->toBe('between_test')
->op->toBe(Op::Between)
->paramName->toBe(':count')
->and($field->value)->toEqual([18, 49]);
});
});
describe('::in()', function () {
test('creates Field w/o parameter', function () {
$field = Field::in('test', [1, 2, 3]);
expect($field)
->not->toBeNull()
->fieldName->toBe('test')
->op->toBe(Op::In)
->paramName->toBeEmpty()
->and($field->value)->toEqual([1, 2, 3]);
});
test('creates Field w/ parameter', function () {
$field = Field::in('unit', ['a', 'b'], ':inParam');
expect($field)
->not->toBeNull()
->fieldName->toBe('unit')
->op->toBe(Op::In)
->paramName->toBe(':inParam')
->and($field->value)->toEqual(['a', 'b']);
});
});
describe('::inArray()', function () {
test('creates Field w/o parameter', function () {
$field = Field::inArray('test', 'tbl', [1, 2, 3]);
expect($field)
->not->toBeNull()
->fieldName->toBe('test')
->op->toBe(Op::InArray)
->paramName->toBeEmpty()
->and($field->value)->toEqual(['table' => 'tbl', 'values' => [1, 2, 3]]);
});
test('creates Field w/ parameter', function () {
$field = Field::inArray('unit', 'tab', ['a', 'b'], ':inAParam');
expect($field)
->not->toBeNull()
->fieldName->toBe('unit')
->op->toBe(Op::InArray)
->paramName->toBe(':inAParam')
->and($field->value)->toEqual(['table' => 'tab', 'values' => ['a', 'b']]);
});
});
describe('::exists()', function () {
test('creates Field', function () {
$field = Field::exists('be_there');
expect($field)
->not->toBeNull()
->fieldName->toBe('be_there')
->op->toBe(Op::Exists)
->paramName->toBeEmpty()
->and($field->value)->toBeEmpty();
});
});
describe('::notExists()', function () {
test('creates Field', function () {
$field = Field::notExists('be_absent');
expect($field)
->not->toBeNull()
->fieldName->toBe('be_absent')
->op->toBe(Op::NotExists)
->paramName->toBeEmpty()
->and($field->value)->toBeEmpty();
});
});
describe('::named()', function () {
test('creates Field', function () {
$field = Field::named('the_field');
expect($field)
->not->toBeNull()
->fieldName->toBe('the_field')
->op->toBe(Op::Equal)
->value->toBeEmpty()
->and($field->value)->toBeEmpty();
});
});