@contember/database
Advanced tools
Comparing version 0.9.2-alpha.3 to 0.9.2-alpha.4
@@ -1,2 +0,2 @@ | ||
import 'jasmine'; | ||
export {}; | ||
//# sourceMappingURL=queryBuilderTest.d.ts.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
require("jasmine"); | ||
const src_1 = require("../../../src"); | ||
const database_tester_1 = require("@contember/database-tester"); | ||
const tags_1 = require("../../src/tags"); | ||
const uvu_1 = require("uvu"); | ||
const execute = async (test) => { | ||
@@ -14,34 +14,33 @@ const connection = database_tester_1.createConnectionMock([ | ||
}, | ||
], (expected, actual, message) => expect(actual).toEqual(expected, message)); | ||
]); | ||
const wrapper = new src_1.Client(connection, 'public', {}); | ||
await test.query(wrapper); | ||
}; | ||
describe('query builder', () => { | ||
it('constructs condition', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.from('foo') | ||
.where(cond => cond | ||
.compare('a', src_1.Operator.eq, 1) | ||
.compare('b', src_1.Operator.notEq, 2) | ||
.compare('c', src_1.Operator.lt, 3) | ||
.compare('d', src_1.Operator.lte, 4) | ||
.compare('e', src_1.Operator.gt, 5) | ||
.compare('f', src_1.Operator.gte, 6) | ||
.compare('g', src_1.Operator.contains, 'foo\\%bar') | ||
.compare('h', src_1.Operator.startsWith, 'lorem_ipsum') | ||
.compare('i', src_1.Operator.endsWith, 'dolor%sit') | ||
.compare('j', src_1.Operator.containsCI, 'X') | ||
.compare('k', src_1.Operator.startsWithCI, 'Y') | ||
.compare('l', src_1.Operator.endsWithCI, 'Z') | ||
.compareColumns('z', src_1.Operator.eq, ['foo', 'x']) | ||
.in('o', [1, 2, 3]) | ||
.in('m', wrapper.selectBuilder().select(expr => expr.selectValue(1))) | ||
.null('n') | ||
.raw('false')); | ||
await qb.getResult(wrapper); | ||
}, | ||
sql: tags_1.SQL `select * | ||
uvu_1.test('query builder: constructs condition', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.from('foo') | ||
.where(cond => cond | ||
.compare('a', src_1.Operator.eq, 1) | ||
.compare('b', src_1.Operator.notEq, 2) | ||
.compare('c', src_1.Operator.lt, 3) | ||
.compare('d', src_1.Operator.lte, 4) | ||
.compare('e', src_1.Operator.gt, 5) | ||
.compare('f', src_1.Operator.gte, 6) | ||
.compare('g', src_1.Operator.contains, 'foo\\%bar') | ||
.compare('h', src_1.Operator.startsWith, 'lorem_ipsum') | ||
.compare('i', src_1.Operator.endsWith, 'dolor%sit') | ||
.compare('j', src_1.Operator.containsCI, 'X') | ||
.compare('k', src_1.Operator.startsWithCI, 'Y') | ||
.compare('l', src_1.Operator.endsWithCI, 'Z') | ||
.compareColumns('z', src_1.Operator.eq, ['foo', 'x']) | ||
.in('o', [1, 2, 3]) | ||
.in('m', wrapper.selectBuilder().select(expr => expr.selectValue(1))) | ||
.null('n') | ||
.raw('false')); | ||
await qb.getResult(wrapper); | ||
}, | ||
sql: tags_1.SQL `select * | ||
from "public"."foo" | ||
@@ -52,25 +51,25 @@ where "a" = ? and "b" != ? and "c" < ? and "d" <= ? and "e" > ? and "f" >= ? | ||
and "z" = "foo"."x" and "o" in (?, ?, ?) and "m" in (select ?) and "n" is null and false`, | ||
parameters: [1, 2, 3, 4, 5, 6, 'foo\\\\\\%bar', 'lorem\\_ipsum', 'dolor\\%sit', 'X', 'Y', 'Z', 1, 2, 3, 1], | ||
}); | ||
parameters: [1, 2, 3, 4, 5, 6, 'foo\\\\\\%bar', 'lorem\\_ipsum', 'dolor\\%sit', 'X', 'Y', 'Z', 1, 2, 3, 1], | ||
}); | ||
it('constructs "on"', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.select(['foo', 'id']) | ||
.from('foo') | ||
.join('bar', 'bar', clause => clause | ||
.or(clause => clause | ||
.compare(['bar', 'a'], src_1.Operator.eq, 1) | ||
.compare(['bar', 'a'], src_1.Operator.eq, 2) | ||
.not(clause => clause.compare(['bar', 'b'], src_1.Operator.eq, 1))) | ||
.and(clause => clause | ||
.in(['bar', 'c'], [1, 2, 3]) | ||
.null(['bar', 'd']) | ||
.not(clause => clause.null(['bar', 'd'])) | ||
.compareColumns(['bar', 'e'], src_1.Operator.lte, ['bar', 'f']))); | ||
await qb.getResult(wrapper); | ||
}, | ||
sql: tags_1.SQL `select "foo"."id" | ||
}); | ||
uvu_1.test('query builder: construct "on"', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.select(['foo', 'id']) | ||
.from('foo') | ||
.join('bar', 'bar', clause => clause | ||
.or(clause => clause | ||
.compare(['bar', 'a'], src_1.Operator.eq, 1) | ||
.compare(['bar', 'a'], src_1.Operator.eq, 2) | ||
.not(clause => clause.compare(['bar', 'b'], src_1.Operator.eq, 1))) | ||
.and(clause => clause | ||
.in(['bar', 'c'], [1, 2, 3]) | ||
.null(['bar', 'd']) | ||
.not(clause => clause.null(['bar', 'd'])) | ||
.compareColumns(['bar', 'e'], src_1.Operator.lte, ['bar', 'f']))); | ||
await qb.getResult(wrapper); | ||
}, | ||
sql: tags_1.SQL `select "foo"."id" | ||
from "public"."foo" | ||
@@ -80,46 +79,46 @@ inner join "public"."bar" as "bar" | ||
and "bar"."e" <= "bar"."f"`, | ||
parameters: [1, 2, 1, 1, 2, 3], | ||
}); | ||
parameters: [1, 2, 1, 1, 2, 3], | ||
}); | ||
it('constructs simple insert', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const builder = wrapper | ||
.insertBuilder() | ||
.into('author') | ||
.values({ | ||
id: 1, | ||
title: 'foo', | ||
content: expr => expr.selectValue('bar'), | ||
}); | ||
await builder.execute(wrapper); | ||
}, | ||
sql: tags_1.SQL `insert into "public"."author" ("id", "title", "content") values (?, ?, ?)`, | ||
parameters: [1, 'foo', 'bar'], | ||
}); | ||
}); | ||
uvu_1.test('query builder: construct simple insert', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const builder = wrapper | ||
.insertBuilder() | ||
.into('author') | ||
.values({ | ||
id: 1, | ||
title: 'foo', | ||
content: expr => expr.selectValue('bar'), | ||
}); | ||
await builder.execute(wrapper); | ||
}, | ||
sql: tags_1.SQL `insert into "public"."author" ("id", "title", "content") values (?, ?, ?)`, | ||
parameters: [1, 'foo', 'bar'], | ||
}); | ||
it('constructs insert with cte', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const builder = wrapper | ||
.insertBuilder() | ||
.with('root_', qb => { | ||
return qb | ||
.select(expr => expr.selectValue('Hello', 'text'), 'title') | ||
.select(expr => expr.selectValue(1, 'int'), 'id') | ||
.select(expr => expr.selectValue(null, 'text'), 'content'); | ||
}) | ||
.into('author') | ||
.values({ | ||
id: expr => expr.select('id'), | ||
title: expr => expr.select('title'), | ||
}) | ||
.from(qb => { | ||
return qb.from('root_'); | ||
}) | ||
.returning('id') | ||
.onConflict(src_1.ConflictActionType.doNothing); | ||
await builder.execute(wrapper); | ||
}, | ||
sql: tags_1.SQL ` | ||
}); | ||
uvu_1.test('query builder: construct insert with cte', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const builder = wrapper | ||
.insertBuilder() | ||
.with('root_', qb => { | ||
return qb | ||
.select(expr => expr.selectValue('Hello', 'text'), 'title') | ||
.select(expr => expr.selectValue(1, 'int'), 'id') | ||
.select(expr => expr.selectValue(null, 'text'), 'content'); | ||
}) | ||
.into('author') | ||
.values({ | ||
id: expr => expr.select('id'), | ||
title: expr => expr.select('title'), | ||
}) | ||
.from(qb => { | ||
return qb.from('root_'); | ||
}) | ||
.returning('id') | ||
.onConflict(src_1.ConflictActionType.doNothing); | ||
await builder.execute(wrapper); | ||
}, | ||
sql: tags_1.SQL ` | ||
with "root_" as (select ? :: text as "title", ? :: int as "id", ? :: text as "content") | ||
@@ -129,26 +128,26 @@ insert into "public"."author" ("id", "title") | ||
on conflict do nothing returning "id"`, | ||
parameters: ['Hello', 1, null], | ||
}); | ||
parameters: ['Hello', 1, null], | ||
}); | ||
it('constructs insert with on conflict update', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const builder = wrapper | ||
.insertBuilder() | ||
.into('author') | ||
.values({ | ||
id: expr => expr.selectValue('123'), | ||
title: expr => expr.select('title'), | ||
}) | ||
.from(qb => { | ||
return qb.from('foo'); | ||
}) | ||
.returning('id') | ||
.onConflict(src_1.ConflictActionType.update, ['id'], { | ||
id: expr => expr.selectValue('123'), | ||
title: expr => expr.select('title'), | ||
}); | ||
await builder.execute(wrapper); | ||
}, | ||
sql: tags_1.SQL `insert into "public"."author" ("id", "title") | ||
}); | ||
uvu_1.test('query builder: construct insert with on conflict update', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const builder = wrapper | ||
.insertBuilder() | ||
.into('author') | ||
.values({ | ||
id: expr => expr.selectValue('123'), | ||
title: expr => expr.select('title'), | ||
}) | ||
.from(qb => { | ||
return qb.from('foo'); | ||
}) | ||
.returning('id') | ||
.onConflict(src_1.ConflictActionType.update, ['id'], { | ||
id: expr => expr.selectValue('123'), | ||
title: expr => expr.select('title'), | ||
}); | ||
await builder.execute(wrapper); | ||
}, | ||
sql: tags_1.SQL `insert into "public"."author" ("id", "title") | ||
select | ||
@@ -159,64 +158,64 @@ ?, | ||
on conflict ("id") do update set "id" = ?, "title" = "title" returning "id"`, | ||
parameters: ['123', '123'], | ||
}); | ||
parameters: ['123', '123'], | ||
}); | ||
it('constructs insert with on conflict do nothing', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const builder = wrapper | ||
.insertBuilder() | ||
.into('author') | ||
.values({ | ||
id: expr => expr.selectValue('123'), | ||
}) | ||
.onConflict(src_1.ConflictActionType.doNothing, { constraint: 'bar' }); | ||
await builder.execute(wrapper); | ||
}, | ||
sql: tags_1.SQL `insert into "public"."author" ("id") | ||
}); | ||
uvu_1.test('query builder: construct insert with on conflict do nothing', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const builder = wrapper | ||
.insertBuilder() | ||
.into('author') | ||
.values({ | ||
id: expr => expr.selectValue('123'), | ||
}) | ||
.onConflict(src_1.ConflictActionType.doNothing, { constraint: 'bar' }); | ||
await builder.execute(wrapper); | ||
}, | ||
sql: tags_1.SQL `insert into "public"."author" ("id") | ||
values (?) | ||
on conflict on constraint "bar" do nothing`, | ||
parameters: ['123'], | ||
}); | ||
parameters: ['123'], | ||
}); | ||
it('constructs simple update', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.updateBuilder() | ||
.table('author') | ||
.values({ | ||
title: 'Hello', | ||
}) | ||
.where({ id: 12 }); | ||
await qb.execute(wrapper); | ||
}, | ||
sql: tags_1.SQL `update "public"."author" | ||
}); | ||
uvu_1.test('query builder: construct simple update', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.updateBuilder() | ||
.table('author') | ||
.values({ | ||
title: 'Hello', | ||
}) | ||
.where({ id: 12 }); | ||
await qb.execute(wrapper); | ||
}, | ||
sql: tags_1.SQL `update "public"."author" | ||
set "title" = ? | ||
where "id" = ?`, | ||
parameters: ['Hello', 12], | ||
}); | ||
parameters: ['Hello', 12], | ||
}); | ||
it('constructs update with cte', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.updateBuilder() | ||
.with('root_', qb => { | ||
return qb | ||
.select(expr => expr.selectValue('Hello', 'text'), 'title') | ||
.select(expr => expr.selectValue(1, 'int'), 'id') | ||
.select(expr => expr.selectValue(null, 'text'), 'content'); | ||
}) | ||
.table('author') | ||
.values({ | ||
id: expr => expr.select(['root_', 'id']), | ||
title: expr => expr.select(['root_', 'title']), | ||
}) | ||
.from(qb => { | ||
return qb.from('root_').where({ foo: 'bar' }); | ||
}) | ||
.where({ id: 12 }); | ||
await qb.execute(wrapper); | ||
}, | ||
sql: tags_1.SQL `with "root_" as (select | ||
}); | ||
uvu_1.test('query builder: construct update with cte', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.updateBuilder() | ||
.with('root_', qb => { | ||
return qb | ||
.select(expr => expr.selectValue('Hello', 'text'), 'title') | ||
.select(expr => expr.selectValue(1, 'int'), 'id') | ||
.select(expr => expr.selectValue(null, 'text'), 'content'); | ||
}) | ||
.table('author') | ||
.values({ | ||
id: expr => expr.select(['root_', 'id']), | ||
title: expr => expr.select(['root_', 'title']), | ||
}) | ||
.from(qb => { | ||
return qb.from('root_').where({ foo: 'bar' }); | ||
}) | ||
.where({ id: 12 }); | ||
await qb.execute(wrapper); | ||
}, | ||
sql: tags_1.SQL `with "root_" as (select | ||
? :: text as "title", | ||
@@ -227,30 +226,30 @@ ? :: int as "id", | ||
where "foo" = ? and "id" = ?`, | ||
parameters: ['Hello', 1, null, 'bar', 12], | ||
}); | ||
parameters: ['Hello', 1, null, 'bar', 12], | ||
}); | ||
it('constructs select with condition', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.select(expr => expr.selectCondition(condition => condition.or(condition => condition.compare('foo', src_1.Operator.gte, 1).compare('foo', src_1.Operator.lte, 0))), 'bar'); | ||
await qb.getResult(wrapper); | ||
}, | ||
sql: tags_1.SQL `select ("foo" >= ? or "foo" <= ?) as "bar"`, | ||
parameters: [1, 0], | ||
}); | ||
}); | ||
uvu_1.test('query builder: constructs select with condition', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.select(expr => expr.selectCondition(condition => condition.or(condition => condition.compare('foo', src_1.Operator.gte, 1).compare('foo', src_1.Operator.lte, 0))), 'bar'); | ||
await qb.getResult(wrapper); | ||
}, | ||
sql: tags_1.SQL `select ("foo" >= ? or "foo" <= ?) as "bar"`, | ||
parameters: [1, 0], | ||
}); | ||
it('constructs delete', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.deleteBuilder() | ||
.with('data', qb => qb.from('abc')) | ||
.from('bar') | ||
.using('data') | ||
.where(cond => cond.compare(['data', 'a'], src_1.Operator.gte, 1)) | ||
.returning('xyz'); | ||
await qb.execute(wrapper); | ||
}, | ||
sql: tags_1.SQL `with "data" as | ||
}); | ||
uvu_1.test('query builder: constructs delete', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.deleteBuilder() | ||
.with('data', qb => qb.from('abc')) | ||
.from('bar') | ||
.using('data') | ||
.where(cond => cond.compare(['data', 'a'], src_1.Operator.gte, 1)) | ||
.returning('xyz'); | ||
await qb.execute(wrapper); | ||
}, | ||
sql: tags_1.SQL `with "data" as | ||
(select * from "public"."abc") | ||
@@ -260,31 +259,31 @@ delete from "public"."bar" | ||
where "data"."a" >= ? returning "xyz"`, | ||
parameters: [1], | ||
}); | ||
parameters: [1], | ||
}); | ||
it('constructs window function', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.select(expr => expr.window(window => window.orderBy(['foo', 'bar'], 'desc').rowNumber().partitionBy(['lorem', 'ipsum']))); | ||
await qb.getResult(wrapper); | ||
}, | ||
sql: tags_1.SQL `select row_number() | ||
}); | ||
uvu_1.test('query builder: constructs window function', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.select(expr => expr.window(window => window.orderBy(['foo', 'bar'], 'desc').rowNumber().partitionBy(['lorem', 'ipsum']))); | ||
await qb.getResult(wrapper); | ||
}, | ||
sql: tags_1.SQL `select row_number() | ||
over(partition by "lorem"."ipsum" | ||
order by "foo"."bar" desc)`, | ||
parameters: [], | ||
}); | ||
parameters: [], | ||
}); | ||
it('applies limit by group', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper.selectBuilder().select(['foo', 'bar']).from('foo'); | ||
await new src_1.LimitByGroupWrapper(['foo', 'lorem'], (orderable, qb) => { | ||
if (orderable) { | ||
return [orderable.orderBy(['foo', 'ipsum']), qb.orderBy(['foo', 'ipsum'])]; | ||
} | ||
return [null, qb.orderBy(['foo', 'ipsum'])]; | ||
}, 1, 3).getResult(qb, wrapper); | ||
}, | ||
sql: tags_1.SQL `with "data" as | ||
}); | ||
uvu_1.test('query builder: applies limit by group', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper.selectBuilder().select(['foo', 'bar']).from('foo'); | ||
await new src_1.LimitByGroupWrapper(['foo', 'lorem'], (orderable, qb) => { | ||
if (orderable) { | ||
return [orderable.orderBy(['foo', 'ipsum']), qb.orderBy(['foo', 'ipsum'])]; | ||
} | ||
return [null, qb.orderBy(['foo', 'ipsum'])]; | ||
}, 1, 3).getResult(qb, wrapper); | ||
}, | ||
sql: tags_1.SQL `with "data" as | ||
(select "foo"."bar", | ||
@@ -294,48 +293,48 @@ row_number() over(partition by "foo"."lorem" order by "foo"."ipsum" asc) as "rowNumber_" | ||
select "data".* from "data" where "data"."rowNumber_" > ? and "data"."rowNumber_" <= ?`, | ||
parameters: [1, 4], | ||
}); | ||
parameters: [1, 4], | ||
}); | ||
it('select with no key update', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper.selectBuilder().select('id').from('foo').lock(src_1.LockType.forNoKeyUpdate); | ||
await qb.getResult(wrapper); | ||
}, | ||
sql: tags_1.SQL `select "id" from "public"."foo" for no key update`, | ||
parameters: [], | ||
}); | ||
}); | ||
uvu_1.test('query builder: select with no key update', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper.selectBuilder().select('id').from('foo').lock(src_1.LockType.forNoKeyUpdate); | ||
await qb.getResult(wrapper); | ||
}, | ||
sql: tags_1.SQL `select "id" from "public"."foo" for no key update`, | ||
parameters: [], | ||
}); | ||
it('select union', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.select('id') | ||
.from('foo') | ||
.unionAll(qb => qb.select('id').from('bar')); | ||
await qb.getResult(wrapper); | ||
}, | ||
sql: tags_1.SQL `select "id" from "public"."foo" union all ( select "id" from "public"."bar")`, | ||
parameters: [], | ||
}); | ||
}); | ||
uvu_1.test('select union', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.select('id') | ||
.from('foo') | ||
.unionAll(qb => qb.select('id').from('bar')); | ||
await qb.getResult(wrapper); | ||
}, | ||
sql: tags_1.SQL `select "id" from "public"."foo" union all ( select "id" from "public"."bar")`, | ||
parameters: [], | ||
}); | ||
it('select with recursive', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.withRecursive('recent_events', qb => qb | ||
.select('id') | ||
.from('events') | ||
.where({ id: '123' }) | ||
.unionAll(qb => qb | ||
.select('id') | ||
.from('events') | ||
.from('recent_events') | ||
.where(expr => expr.columnsEq(['events', 'id'], ['recent_events', 'previous_id'])))) | ||
.select('id') | ||
.from('recent_events'); | ||
await qb.getResult(wrapper); | ||
}, | ||
sql: tags_1.SQL ` | ||
}); | ||
uvu_1.test('query builder: select with recursive', async () => { | ||
await execute({ | ||
query: async (wrapper) => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.withRecursive('recent_events', qb => qb | ||
.select('id') | ||
.from('events') | ||
.where({ id: '123' }) | ||
.unionAll(qb => qb | ||
.select('id') | ||
.from('events') | ||
.from('recent_events') | ||
.where(expr => expr.columnsEq(['events', 'id'], ['recent_events', 'previous_id'])))) | ||
.select('id') | ||
.from('recent_events'); | ||
await qb.getResult(wrapper); | ||
}, | ||
sql: tags_1.SQL ` | ||
with recursive | ||
@@ -345,6 +344,6 @@ "recent_events" as (select "id" from "public"."events" where "id" = ? | ||
select "id" from "recent_events"`, | ||
parameters: ['123'], | ||
}); | ||
parameters: ['123'], | ||
}); | ||
}); | ||
uvu_1.test.run(); | ||
//# sourceMappingURL=queryBuilderTest.js.map |
{ | ||
"name": "@contember/database", | ||
"version": "0.9.2-alpha.3", | ||
"version": "0.9.2-alpha.4", | ||
"license": "Apache-2.0", | ||
@@ -8,15 +8,14 @@ "main": "dist/src/index.js", | ||
"scripts": { | ||
"test": "jasmine --config=jasmine.json" | ||
"test": "uvu dist/tests/cases/ \\.js$" | ||
}, | ||
"dependencies": { | ||
"@contember/queryable": "^0.9.2-alpha.3", | ||
"@contember/queryable": "^0.9.2-alpha.4", | ||
"pg": "^7.17.1" | ||
}, | ||
"devDependencies": { | ||
"@contember/database-tester": "^0.9.2-alpha.3", | ||
"@types/jasmine": "^3.5.10", | ||
"@contember/database-tester": "^0.9.2-alpha.4", | ||
"@types/node": "^14.6.4", | ||
"@types/pg": "^7.14.1", | ||
"jasmine": "^3.5.0" | ||
"uvu": "^0.3.3" | ||
} | ||
} |
@@ -1,5 +0,5 @@ | ||
import 'jasmine' | ||
import { Client, ConflictActionType, LimitByGroupWrapper, LockType, Operator } from '../../../src' | ||
import { createConnectionMock } from '@contember/database-tester' | ||
import { SQL } from '../../src/tags' | ||
import { test } from 'uvu' | ||
@@ -13,12 +13,9 @@ interface Test { | ||
const execute = async (test: Test) => { | ||
const connection = createConnectionMock( | ||
[ | ||
{ | ||
sql: test.sql, | ||
parameters: test.parameters, | ||
response: { rows: [] }, | ||
}, | ||
], | ||
(expected, actual, message) => expect(actual).toEqual(expected, message), | ||
) | ||
const connection = createConnectionMock([ | ||
{ | ||
sql: test.sql, | ||
parameters: test.parameters, | ||
response: { rows: [] }, | ||
}, | ||
]) | ||
const wrapper = new Client(connection, 'public', {}) | ||
@@ -29,36 +26,35 @@ | ||
describe('query builder', () => { | ||
it('constructs condition', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.from('foo') | ||
.where(cond => | ||
cond | ||
.compare('a', Operator.eq, 1) | ||
.compare('b', Operator.notEq, 2) | ||
.compare('c', Operator.lt, 3) | ||
.compare('d', Operator.lte, 4) | ||
.compare('e', Operator.gt, 5) | ||
.compare('f', Operator.gte, 6) | ||
.compare('g', Operator.contains, 'foo\\%bar') | ||
.compare('h', Operator.startsWith, 'lorem_ipsum') | ||
.compare('i', Operator.endsWith, 'dolor%sit') | ||
.compare('j', Operator.containsCI, 'X') | ||
.compare('k', Operator.startsWithCI, 'Y') | ||
.compare('l', Operator.endsWithCI, 'Z') | ||
.compareColumns('z', Operator.eq, ['foo', 'x']) | ||
.in('o', [1, 2, 3]) | ||
.in( | ||
'm', | ||
wrapper.selectBuilder().select(expr => expr.selectValue(1)), | ||
) | ||
.null('n') | ||
.raw('false'), | ||
) | ||
test('query builder: constructs condition', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.from('foo') | ||
.where(cond => | ||
cond | ||
.compare('a', Operator.eq, 1) | ||
.compare('b', Operator.notEq, 2) | ||
.compare('c', Operator.lt, 3) | ||
.compare('d', Operator.lte, 4) | ||
.compare('e', Operator.gt, 5) | ||
.compare('f', Operator.gte, 6) | ||
.compare('g', Operator.contains, 'foo\\%bar') | ||
.compare('h', Operator.startsWith, 'lorem_ipsum') | ||
.compare('i', Operator.endsWith, 'dolor%sit') | ||
.compare('j', Operator.containsCI, 'X') | ||
.compare('k', Operator.startsWithCI, 'Y') | ||
.compare('l', Operator.endsWithCI, 'Z') | ||
.compareColumns('z', Operator.eq, ['foo', 'x']) | ||
.in('o', [1, 2, 3]) | ||
.in( | ||
'm', | ||
wrapper.selectBuilder().select(expr => expr.selectValue(1)), | ||
) | ||
.null('n') | ||
.raw('false'), | ||
) | ||
await qb.getResult(wrapper) | ||
}, | ||
sql: SQL`select * | ||
await qb.getResult(wrapper) | ||
}, | ||
sql: SQL`select * | ||
from "public"."foo" | ||
@@ -69,32 +65,32 @@ where "a" = ? and "b" != ? and "c" < ? and "d" <= ? and "e" > ? and "f" >= ? | ||
and "z" = "foo"."x" and "o" in (?, ?, ?) and "m" in (select ?) and "n" is null and false`, | ||
parameters: [1, 2, 3, 4, 5, 6, 'foo\\\\\\%bar', 'lorem\\_ipsum', 'dolor\\%sit', 'X', 'Y', 'Z', 1, 2, 3, 1], | ||
}) | ||
parameters: [1, 2, 3, 4, 5, 6, 'foo\\\\\\%bar', 'lorem\\_ipsum', 'dolor\\%sit', 'X', 'Y', 'Z', 1, 2, 3, 1], | ||
}) | ||
}) | ||
it('constructs "on"', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.select(['foo', 'id']) | ||
.from('foo') | ||
.join('bar', 'bar', clause => | ||
clause | ||
.or(clause => | ||
clause | ||
.compare(['bar', 'a'], Operator.eq, 1) | ||
.compare(['bar', 'a'], Operator.eq, 2) | ||
.not(clause => clause.compare(['bar', 'b'], Operator.eq, 1)), | ||
) | ||
.and(clause => | ||
clause | ||
.in(['bar', 'c'], [1, 2, 3]) | ||
.null(['bar', 'd']) | ||
.not(clause => clause.null(['bar', 'd'])) | ||
.compareColumns(['bar', 'e'], Operator.lte, ['bar', 'f']), | ||
), | ||
) | ||
await qb.getResult(wrapper) | ||
}, | ||
sql: SQL`select "foo"."id" | ||
test('query builder: construct "on"', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.select(['foo', 'id']) | ||
.from('foo') | ||
.join('bar', 'bar', clause => | ||
clause | ||
.or(clause => | ||
clause | ||
.compare(['bar', 'a'], Operator.eq, 1) | ||
.compare(['bar', 'a'], Operator.eq, 2) | ||
.not(clause => clause.compare(['bar', 'b'], Operator.eq, 1)), | ||
) | ||
.and(clause => | ||
clause | ||
.in(['bar', 'c'], [1, 2, 3]) | ||
.null(['bar', 'd']) | ||
.not(clause => clause.null(['bar', 'd'])) | ||
.compareColumns(['bar', 'e'], Operator.lte, ['bar', 'f']), | ||
), | ||
) | ||
await qb.getResult(wrapper) | ||
}, | ||
sql: SQL`select "foo"."id" | ||
from "public"."foo" | ||
@@ -104,48 +100,48 @@ inner join "public"."bar" as "bar" | ||
and "bar"."e" <= "bar"."f"`, | ||
parameters: [1, 2, 1, 1, 2, 3], | ||
}) | ||
parameters: [1, 2, 1, 1, 2, 3], | ||
}) | ||
}) | ||
it('constructs simple insert', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const builder = wrapper | ||
.insertBuilder() | ||
.into('author') | ||
.values({ | ||
id: 1, | ||
title: 'foo', | ||
content: expr => expr.selectValue('bar'), | ||
}) | ||
await builder.execute(wrapper) | ||
}, | ||
sql: SQL`insert into "public"."author" ("id", "title", "content") values (?, ?, ?)`, | ||
parameters: [1, 'foo', 'bar'], | ||
}) | ||
test('query builder: construct simple insert', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const builder = wrapper | ||
.insertBuilder() | ||
.into('author') | ||
.values({ | ||
id: 1, | ||
title: 'foo', | ||
content: expr => expr.selectValue('bar'), | ||
}) | ||
await builder.execute(wrapper) | ||
}, | ||
sql: SQL`insert into "public"."author" ("id", "title", "content") values (?, ?, ?)`, | ||
parameters: [1, 'foo', 'bar'], | ||
}) | ||
}) | ||
it('constructs insert with cte', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const builder = wrapper | ||
.insertBuilder() | ||
.with('root_', qb => { | ||
return qb | ||
.select(expr => expr.selectValue('Hello', 'text'), 'title') | ||
.select(expr => expr.selectValue(1, 'int'), 'id') | ||
.select(expr => expr.selectValue(null, 'text'), 'content') | ||
}) | ||
.into('author') | ||
.values({ | ||
id: expr => expr.select('id'), | ||
title: expr => expr.select('title'), | ||
}) | ||
.from(qb => { | ||
return qb.from('root_') | ||
}) | ||
.returning('id') | ||
.onConflict(ConflictActionType.doNothing) | ||
await builder.execute(wrapper) | ||
}, | ||
sql: SQL` | ||
test('query builder: construct insert with cte', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const builder = wrapper | ||
.insertBuilder() | ||
.with('root_', qb => { | ||
return qb | ||
.select(expr => expr.selectValue('Hello', 'text'), 'title') | ||
.select(expr => expr.selectValue(1, 'int'), 'id') | ||
.select(expr => expr.selectValue(null, 'text'), 'content') | ||
}) | ||
.into('author') | ||
.values({ | ||
id: expr => expr.select('id'), | ||
title: expr => expr.select('title'), | ||
}) | ||
.from(qb => { | ||
return qb.from('root_') | ||
}) | ||
.returning('id') | ||
.onConflict(ConflictActionType.doNothing) | ||
await builder.execute(wrapper) | ||
}, | ||
sql: SQL` | ||
with "root_" as (select ? :: text as "title", ? :: int as "id", ? :: text as "content") | ||
@@ -155,27 +151,27 @@ insert into "public"."author" ("id", "title") | ||
on conflict do nothing returning "id"`, | ||
parameters: ['Hello', 1, null], | ||
}) | ||
parameters: ['Hello', 1, null], | ||
}) | ||
}) | ||
it('constructs insert with on conflict update', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const builder = wrapper | ||
.insertBuilder() | ||
.into('author') | ||
.values({ | ||
id: expr => expr.selectValue('123'), | ||
title: expr => expr.select('title'), | ||
}) | ||
.from(qb => { | ||
return qb.from('foo') | ||
}) | ||
.returning('id') | ||
.onConflict(ConflictActionType.update, ['id'], { | ||
id: expr => expr.selectValue('123'), | ||
title: expr => expr.select('title'), | ||
}) | ||
await builder.execute(wrapper) | ||
}, | ||
sql: SQL`insert into "public"."author" ("id", "title") | ||
test('query builder: construct insert with on conflict update', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const builder = wrapper | ||
.insertBuilder() | ||
.into('author') | ||
.values({ | ||
id: expr => expr.selectValue('123'), | ||
title: expr => expr.select('title'), | ||
}) | ||
.from(qb => { | ||
return qb.from('foo') | ||
}) | ||
.returning('id') | ||
.onConflict(ConflictActionType.update, ['id'], { | ||
id: expr => expr.selectValue('123'), | ||
title: expr => expr.select('title'), | ||
}) | ||
await builder.execute(wrapper) | ||
}, | ||
sql: SQL`insert into "public"."author" ("id", "title") | ||
select | ||
@@ -186,67 +182,67 @@ ?, | ||
on conflict ("id") do update set "id" = ?, "title" = "title" returning "id"`, | ||
parameters: ['123', '123'], | ||
}) | ||
parameters: ['123', '123'], | ||
}) | ||
}) | ||
it('constructs insert with on conflict do nothing', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const builder = wrapper | ||
.insertBuilder() | ||
.into('author') | ||
.values({ | ||
id: expr => expr.selectValue('123'), | ||
}) | ||
.onConflict(ConflictActionType.doNothing, { constraint: 'bar' }) | ||
await builder.execute(wrapper) | ||
}, | ||
sql: SQL`insert into "public"."author" ("id") | ||
test('query builder: construct insert with on conflict do nothing', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const builder = wrapper | ||
.insertBuilder() | ||
.into('author') | ||
.values({ | ||
id: expr => expr.selectValue('123'), | ||
}) | ||
.onConflict(ConflictActionType.doNothing, { constraint: 'bar' }) | ||
await builder.execute(wrapper) | ||
}, | ||
sql: SQL`insert into "public"."author" ("id") | ||
values (?) | ||
on conflict on constraint "bar" do nothing`, | ||
parameters: ['123'], | ||
}) | ||
parameters: ['123'], | ||
}) | ||
}) | ||
it('constructs simple update', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.updateBuilder() | ||
.table('author') | ||
.values({ | ||
title: 'Hello', | ||
}) | ||
.where({ id: 12 }) | ||
await qb.execute(wrapper) | ||
}, | ||
sql: SQL`update "public"."author" | ||
test('query builder: construct simple update', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.updateBuilder() | ||
.table('author') | ||
.values({ | ||
title: 'Hello', | ||
}) | ||
.where({ id: 12 }) | ||
await qb.execute(wrapper) | ||
}, | ||
sql: SQL`update "public"."author" | ||
set "title" = ? | ||
where "id" = ?`, | ||
parameters: ['Hello', 12], | ||
}) | ||
parameters: ['Hello', 12], | ||
}) | ||
}) | ||
it('constructs update with cte', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.updateBuilder() | ||
.with('root_', qb => { | ||
return qb | ||
.select(expr => expr.selectValue('Hello', 'text'), 'title') | ||
.select(expr => expr.selectValue(1, 'int'), 'id') | ||
.select(expr => expr.selectValue(null, 'text'), 'content') | ||
}) | ||
.table('author') | ||
.values({ | ||
id: expr => expr.select(['root_', 'id']), | ||
title: expr => expr.select(['root_', 'title']), | ||
}) | ||
.from(qb => { | ||
return qb.from('root_').where({ foo: 'bar' }) | ||
}) | ||
.where({ id: 12 }) | ||
await qb.execute(wrapper) | ||
}, | ||
sql: SQL`with "root_" as (select | ||
test('query builder: construct update with cte', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.updateBuilder() | ||
.with('root_', qb => { | ||
return qb | ||
.select(expr => expr.selectValue('Hello', 'text'), 'title') | ||
.select(expr => expr.selectValue(1, 'int'), 'id') | ||
.select(expr => expr.selectValue(null, 'text'), 'content') | ||
}) | ||
.table('author') | ||
.values({ | ||
id: expr => expr.select(['root_', 'id']), | ||
title: expr => expr.select(['root_', 'title']), | ||
}) | ||
.from(qb => { | ||
return qb.from('root_').where({ foo: 'bar' }) | ||
}) | ||
.where({ id: 12 }) | ||
await qb.execute(wrapper) | ||
}, | ||
sql: SQL`with "root_" as (select | ||
? :: text as "title", | ||
@@ -257,38 +253,38 @@ ? :: int as "id", | ||
where "foo" = ? and "id" = ?`, | ||
parameters: ['Hello', 1, null, 'bar', 12], | ||
}) | ||
parameters: ['Hello', 1, null, 'bar', 12], | ||
}) | ||
}) | ||
it('constructs select with condition', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.select( | ||
expr => | ||
expr.selectCondition(condition => | ||
condition.or(condition => condition.compare('foo', Operator.gte, 1).compare('foo', Operator.lte, 0)), | ||
), | ||
'bar', | ||
) | ||
await qb.getResult(wrapper) | ||
}, | ||
sql: SQL`select ("foo" >= ? or "foo" <= ?) as "bar"`, | ||
parameters: [1, 0], | ||
}) | ||
test('query builder: constructs select with condition', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.select( | ||
expr => | ||
expr.selectCondition(condition => | ||
condition.or(condition => condition.compare('foo', Operator.gte, 1).compare('foo', Operator.lte, 0)), | ||
), | ||
'bar', | ||
) | ||
await qb.getResult(wrapper) | ||
}, | ||
sql: SQL`select ("foo" >= ? or "foo" <= ?) as "bar"`, | ||
parameters: [1, 0], | ||
}) | ||
}) | ||
it('constructs delete', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.deleteBuilder() | ||
.with('data', qb => qb.from('abc')) | ||
.from('bar') | ||
.using('data') | ||
.where(cond => cond.compare(['data', 'a'], Operator.gte, 1)) | ||
.returning('xyz') | ||
await qb.execute(wrapper) | ||
}, | ||
sql: SQL`with "data" as | ||
test('query builder: constructs delete', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.deleteBuilder() | ||
.with('data', qb => qb.from('abc')) | ||
.from('bar') | ||
.using('data') | ||
.where(cond => cond.compare(['data', 'a'], Operator.gte, 1)) | ||
.returning('xyz') | ||
await qb.execute(wrapper) | ||
}, | ||
sql: SQL`with "data" as | ||
(select * from "public"."abc") | ||
@@ -298,42 +294,42 @@ delete from "public"."bar" | ||
where "data"."a" >= ? returning "xyz"`, | ||
parameters: [1], | ||
}) | ||
parameters: [1], | ||
}) | ||
}) | ||
it('constructs window function', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.select(expr => | ||
expr.window(window => window.orderBy(['foo', 'bar'], 'desc').rowNumber().partitionBy(['lorem', 'ipsum'])), | ||
) | ||
test('query builder: constructs window function', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.select(expr => | ||
expr.window(window => window.orderBy(['foo', 'bar'], 'desc').rowNumber().partitionBy(['lorem', 'ipsum'])), | ||
) | ||
await qb.getResult(wrapper) | ||
}, | ||
sql: SQL`select row_number() | ||
await qb.getResult(wrapper) | ||
}, | ||
sql: SQL`select row_number() | ||
over(partition by "lorem"."ipsum" | ||
order by "foo"."bar" desc)`, | ||
parameters: [], | ||
}) | ||
parameters: [], | ||
}) | ||
}) | ||
it('applies limit by group', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper.selectBuilder().select(['foo', 'bar']).from('foo') | ||
test('query builder: applies limit by group', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper.selectBuilder().select(['foo', 'bar']).from('foo') | ||
await new LimitByGroupWrapper( | ||
['foo', 'lorem'], | ||
(orderable, qb) => { | ||
if (orderable) { | ||
return [orderable.orderBy(['foo', 'ipsum']), qb.orderBy(['foo', 'ipsum'])] | ||
} | ||
return [null, qb.orderBy(['foo', 'ipsum'])] | ||
}, | ||
1, | ||
3, | ||
).getResult(qb, wrapper) | ||
}, | ||
sql: SQL`with "data" as | ||
await new LimitByGroupWrapper( | ||
['foo', 'lorem'], | ||
(orderable, qb) => { | ||
if (orderable) { | ||
return [orderable.orderBy(['foo', 'ipsum']), qb.orderBy(['foo', 'ipsum'])] | ||
} | ||
return [null, qb.orderBy(['foo', 'ipsum'])] | ||
}, | ||
1, | ||
3, | ||
).getResult(qb, wrapper) | ||
}, | ||
sql: SQL`with "data" as | ||
(select "foo"."bar", | ||
@@ -343,58 +339,58 @@ row_number() over(partition by "foo"."lorem" order by "foo"."ipsum" asc) as "rowNumber_" | ||
select "data".* from "data" where "data"."rowNumber_" > ? and "data"."rowNumber_" <= ?`, | ||
parameters: [1, 4], | ||
}) | ||
parameters: [1, 4], | ||
}) | ||
}) | ||
it('select with no key update', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper.selectBuilder().select('id').from('foo').lock(LockType.forNoKeyUpdate) | ||
test('query builder: select with no key update', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper.selectBuilder().select('id').from('foo').lock(LockType.forNoKeyUpdate) | ||
await qb.getResult(wrapper) | ||
}, | ||
sql: SQL`select "id" from "public"."foo" for no key update`, | ||
parameters: [], | ||
}) | ||
await qb.getResult(wrapper) | ||
}, | ||
sql: SQL`select "id" from "public"."foo" for no key update`, | ||
parameters: [], | ||
}) | ||
}) | ||
it('select union', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.select('id') | ||
.from('foo') | ||
.unionAll(qb => qb.select('id').from('bar')) | ||
test('select union', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.select('id') | ||
.from('foo') | ||
.unionAll(qb => qb.select('id').from('bar')) | ||
await qb.getResult(wrapper) | ||
}, | ||
sql: SQL`select "id" from "public"."foo" union all ( select "id" from "public"."bar")`, | ||
parameters: [], | ||
}) | ||
await qb.getResult(wrapper) | ||
}, | ||
sql: SQL`select "id" from "public"."foo" union all ( select "id" from "public"."bar")`, | ||
parameters: [], | ||
}) | ||
}) | ||
it('select with recursive', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.withRecursive('recent_events', qb => | ||
qb | ||
.select('id') | ||
.from('events') | ||
.where({ id: '123' }) | ||
.unionAll(qb => | ||
qb | ||
.select('id') | ||
.from('events') | ||
.from('recent_events') | ||
.where(expr => expr.columnsEq(['events', 'id'], ['recent_events', 'previous_id'])), | ||
), | ||
) | ||
.select('id') | ||
.from('recent_events') | ||
test('query builder: select with recursive', async () => { | ||
await execute({ | ||
query: async wrapper => { | ||
const qb = wrapper | ||
.selectBuilder() | ||
.withRecursive('recent_events', qb => | ||
qb | ||
.select('id') | ||
.from('events') | ||
.where({ id: '123' }) | ||
.unionAll(qb => | ||
qb | ||
.select('id') | ||
.from('events') | ||
.from('recent_events') | ||
.where(expr => expr.columnsEq(['events', 'id'], ['recent_events', 'previous_id'])), | ||
), | ||
) | ||
.select('id') | ||
.from('recent_events') | ||
await qb.getResult(wrapper) | ||
}, | ||
sql: SQL` | ||
await qb.getResult(wrapper) | ||
}, | ||
sql: SQL` | ||
with recursive | ||
@@ -404,5 +400,6 @@ "recent_events" as (select "id" from "public"."events" where "id" = ? | ||
select "id" from "recent_events"`, | ||
parameters: ['123'], | ||
}) | ||
parameters: ['123'], | ||
}) | ||
}) | ||
test.run() |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
4
1325201
213
5004