Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion sqlite/test/queries-without-models.test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const impl = require.resolve('../index')
const cds = require('@sap/cds')
const cds = require('../../test/cds.js')
const { expect } = cds.test

// eslint-disable-next-line no-global-assign
Expand Down
8 changes: 8 additions & 0 deletions sqlite/test/service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const path = require('node:path')

module.exports = {
"impl": "@cap-js/sqlite",
"credentials": {
"database": path.resolve(__dirname,"../../test/db.sqlite")
}
}
3 changes: 0 additions & 3 deletions sqlite/test/service.json

This file was deleted.

68 changes: 0 additions & 68 deletions test/cds.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

const cdsTest = cds.test

let isolateCounter = 0

Check warning on line 22 in test/cds.js

View workflow job for this annotation

GitHub Actions / Tests (22)

'isolateCounter' is assigned a value but never used

// REVISIT: this caused lots of errors -> all is fine when I remove it
// const orgIn = cdsTest.constructor.prototype.in
Expand Down Expand Up @@ -51,74 +51,6 @@

let ret = cdsTest(...arguments)

global.beforeAll(async () => {
// Setup isolation after cds has prepare the project (e.g. cds.model)
if (ret.data._autoIsolation) {
await ret.data.isolate()
}
})

let isolate = null

ret.data.isolate =
ret.data.isolate ||
async function (db) {
if (!db) db = await cds.connect.to('db')

// If database driver supports database and tenant isolation run test in isolation
if (typeof db.database === 'function' && typeof db.tenant === 'function') {
const { createHash } = require('crypto')
const hash = createHash('sha1')
const isolateName = (require.main.filename || 'test_tenant') + isolateCounter++
hash.update(isolateName)
ret.data.isolation = isolate = {
// Create one database for each overall test execution
database: process.env.TRAVIS_JOB_ID || process.env.GITHUB_RUN_ID || require('os').userInfo().username || 'test_db',
// Create one tenant for each test suite
tenant: 'T' + hash.digest('hex'),
}

// Create new database isolation
await db.database(isolate)

// Create new tenant isolation in database
await db.tenant(isolate)

ret.credentials = db.options.credentials
}
}

ret.data.autoIsolation =
ret.data.autoIsolation ||
function (enabled) {
this._autoIsolation = enabled
return this
}
ret.data.autoIsolation(true)

global.beforeAll(async () => {
if (ret.data._autoIsolation && !ret.data._deployed) {
ret.data._deployed = cds.deploy(cds.options.from[0])
await ret.data._deployed
}
})

global.afterAll(async () => {
// Clean database connection pool
await cds.db?.disconnect?.()

if (isolate) {
await cds.db?.tenant?.(isolate, true)
}

// Clean cache
delete cds.services._pending.db
delete cds.services.db
delete cds.db
delete cds.model
global.cds.resolve.cache = {}
})

ret.expect = cdsTest.expect
return ret
}, cdsTest.constructor.prototype)
Expand Down
17 changes: 2 additions & 15 deletions test/compliance/CREATE.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -166,21 +166,8 @@ const dataTest = async function (entity, table, type, obj) {
}
}

describe('CREATE', () => {
// TODO: reference to ./definitions.test.js

// Set cds.root before requiring cds.Service as it resolves and caches package.json
// Call default cds.test API
const { data } = cds.test(__dirname + '/resources')
// Prevent deployment
/* skipping deploy causes issues with running all compliance tests in a single suite
cds.deploy = () => ({
to:() => {return cds.db || cds.connect('db')},
then:() => {return cds.db || cds.connect('db')}
})
// */
data.autoIsolation(true)
data._deployed = true // Skip automatic deployment
describe.skip('CREATE', () => {
cds.test(__dirname + '/resources')

// Load model before test suite to generate test suite from model definition
const model = cds.load(__dirname + '/resources/db', { sync: true })
Expand Down
12 changes: 7 additions & 5 deletions test/compliance/DELETE.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@ const RootPWithKeys = 'complex.RootPWithKeys'
const ChildPWithWhere = 'complex.ChildPWithWhere'

describe('DELETE', () => {
const { data, expect } = cds.test(__dirname + '/resources')
data.autoIsolation(true)
data.autoReset()
const { expect } = cds.test(__dirname + '/resources')

describe('from', () => {
describe('deep', () => {
Expand Down Expand Up @@ -47,6 +45,10 @@ describe('DELETE', () => {
expect(insertsResp[0].affectedRows).to.be.eq(1)
})

after(async () => {
await DELETE.from(Root).where({ ID: [5, 6, 7, 8, 9] })
})

test('on root with keys', async () => {
const deepDelete = await cds.run(DELETE.from(RootPWithKeys).where({ ID: 5 }))
expect(deepDelete).to.be.eq(1)
Expand Down Expand Up @@ -77,8 +79,8 @@ describe('DELETE', () => {
test('ref', async () => {
const { Authors } = cds.entities('complex.associations')
await INSERT.into(Authors).entries(new Array(9).fill().map((e, i) => ({ ID: 100 + i, name: 'name' + i })))
const changes = await cds.run(DELETE.from(Authors))
expect(changes | 0).to.be.eq(10, 'Ensure that all rows are affected') // 1 from csv, 9 newly added
const changes = await cds.run(DELETE.from(Authors).where(`ID BETWEEN 100 AND 109`))
expect(changes | 0).to.be.eq(9, 'Ensure that all rows are affected')
})
})

Expand Down
51 changes: 39 additions & 12 deletions test/compliance/INSERT.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ const { text } = require('stream/consumers')
const { PassThrough, Readable } = require('stream')

describe('INSERT', () => {
const { data, expect } = cds.test(__dirname + '/resources')
data.autoIsolation(true)
const { expect } = cds.test(__dirname + '/resources')

describe('into', () => {
test.skip('missing', () => {
Expand All @@ -13,19 +12,32 @@ describe('INSERT', () => {
})

describe('entries', () => {
const list = []
const where = [{ ref: ['uuid'] }, 'in', { list }]
let genCount = 0
const gen = function* () {
for (var i = 0; i < 100; i++)
yield { uuid: cds.utils.uuid() }
for (var i = 0; i < 100; i++) {
const row = { uuid: cds.utils.uuid() }
list.push({ val: row.uuid })
yield row
}
genCount += i
}

after(async () => {
const { uuid } = cds.entities('basic.literals')
const { Order } = cds.entities('complex.keywords')

await DELETE.from(uuid).where(where)
await DELETE.from(Order).where({ ID: 1 })
})

test('array', async () => {
const { uuid } = cds.entities('basic.literals')

await INSERT([...gen()]).into(uuid)

const result = await SELECT.from(uuid)
const result = await SELECT.from(uuid).where(where)
expect(result.length).to.eq(genCount)
})

Expand All @@ -34,7 +46,7 @@ describe('INSERT', () => {

await INSERT(gen()).into(uuid)

const result = await SELECT.from(uuid)
const result = await SELECT.from(uuid).where(where)
expect(result.length).to.eq(genCount)
})

Expand All @@ -43,7 +55,7 @@ describe('INSERT', () => {

await INSERT(Readable.from(gen())).into(uuid)

const result = await SELECT.from(uuid)
const result = await SELECT.from(uuid).where(where)
expect(result.length).to.eq(genCount)
})

Expand All @@ -63,7 +75,7 @@ describe('INSERT', () => {

await INSERT(Readable.from(raw(gen()), { objectMode: false })).into(uuid)

const result = await SELECT.from(uuid)
const result = await SELECT.from(uuid).where(where)
expect(result.length).to.eq(genCount)
})

Expand Down Expand Up @@ -143,7 +155,7 @@ describe('INSERT', () => {
],
}
await INSERT(data).into(Order)
const select = await cds.run(cds.ql`SELECT from ${Order} { ID, alter { * } } where exists alter`)
const select = await cds.run(cds.ql`SELECT from ${Order} { ID, alter { * } } where ID = ${1} and exists alter`)
expect(select[0]).to.deep.eql(data)
})
})
Expand All @@ -163,6 +175,13 @@ describe('INSERT', () => {
})

describe('from', () => {
after(async () => {
const { Alter, ASC } = cds.entities('complex.keywords')

await DELETE.from(ASC).where({ ID: 1 })
await DELETE.from(Alter).where({ ID: 1 })
})

test('smart quoting', async () => {
const { Alter, ASC } = cds.entities('complex.keywords')
// fill other table first
Expand All @@ -179,6 +198,10 @@ describe('INSERT', () => {
})
})

after(async () => {
await DELETE.from('complex.associations.Books').where({ ID: 5 })
})

test('InsertResult', async () => {
const insert = INSERT.into('complex.associations.Books').entries({ ID: 5 })
const affectedRows = await cds.db.run(insert)
Expand All @@ -188,15 +211,19 @@ describe('INSERT', () => {
expect(affectedRows).not.to.include({ _affectedRows: 1 }) // lastInsertRowid not available on postgres
})

after(async () => {
await DELETE.from('basic.common.dollar_now_default').where({ ID: [5, 6] })
})

test('default $now adds current tx timestamp in correct format', async () => {
await cds.tx(async tx => {
// the statements are run explicitly in sequential order to ensure current_timestamp would create different timestamps
await tx.run(INSERT.into('basic.common.dollar_now_default').entries({ id: 5 }))
await tx.run(INSERT.into('basic.common.dollar_now_default').entries({ id: 6 }))
await tx.run(INSERT.into('basic.common.dollar_now_default').entries({ ID: 5 }))
await tx.run(INSERT.into('basic.common.dollar_now_default').entries({ ID: 6 }))
})

const result = await SELECT.from('basic.common.dollar_now_default')

expect(result.length).to.eq(2)
expect(result[0].date).to.match(/^\d{4}-\d{2}-\d{2}$/)
expect(result[0].date).to.eq(result[1].date)
Expand Down
Loading
Loading