* @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(); }); });