Skip to content

Commit 81003f9

Browse files
committed
edit: more tests
1 parent bd246e0 commit 81003f9

File tree

3 files changed

+290
-121
lines changed

3 files changed

+290
-121
lines changed

tests/bool.ts

Lines changed: 187 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -6,110 +6,194 @@ import { buildAQL } from '../src/index'
66
const ARANGO_URL = process.env.TEST_ARANGODB_URL || "http://localhost:8529"
77

88
describe("boolean search logic", () => {
9-
let db: Database
10-
let collection: DocumentCollection<any>
11-
let view
12-
const dbName = `testdb_${Date.now()}`
13-
const collectionName = `coll_${Date.now()}`
14-
15-
16-
before(async () => {
17-
18-
/* create db */
19-
db = new Database({ url: ARANGO_URL })
20-
await db.createDatabase(dbName)
21-
db.useDatabase(dbName)
22-
23-
/* create coll */
24-
collection = db.collection(collectionName)
25-
await collection.create()
26-
27-
/* create view */
28-
view = db.arangoSearchView(`view_${Date.now()}`)
29-
const links = {}
30-
links[collectionName] = {
31-
fields: { text: { analyzers: ['text_en'] } }
32-
}
33-
await view.create({ links })
34-
let info = await view.get()
35-
expect(info.name).to.equal(view.name)
36-
37-
/* add documents */
38-
const doc1 = { title: 'doc A', text: 'words in text in document' }
39-
const doc2 = { title: 'doc A', text: 'sample word string to search across' }
40-
await db.query(aql`INSERT ${doc1} INTO ${collection}`)
41-
await db.query(aql`INSERT ${doc2} INTO ${collection}`)
9+
let db: Database
10+
let collection: DocumentCollection<any>
11+
let view
12+
const dbName = `testdb_${Date.now()}`
13+
const collectionName = `coll_${Date.now()}`
14+
15+
before(async () => {
16+
17+
/* create db */
18+
db = new Database({ url: ARANGO_URL })
19+
await db.createDatabase(dbName)
20+
db.useDatabase(dbName)
21+
22+
/* create coll */
23+
collection = db.collection(collectionName)
24+
await collection.create()
25+
26+
/* create view */
27+
view = db.arangoSearchView(`view_${Date.now()}`)
28+
const links = {}
29+
links[ collectionName ] = {
30+
fields: { text: { analyzers: [ 'text_en' ] } }
31+
}
32+
await view.create({ links })
33+
let info = await view.get()
34+
expect(info.name).to.equal(view.name)
35+
36+
expect(info.error).to.deep.equal(false)
37+
expect(info.code).to.deep.equal(200)
38+
expect(info.name).to.deep.equal(view.name)
39+
expect(info.type).to.deep.equal('arangosearch')
40+
expect(+info.id).to.be.a('number')
41+
expect(info.globallyUniqueId).to.contain('/')
42+
43+
/* add documents */
44+
const docA = { title: 'doc A', text: 'words in text in document' }
45+
const docB = { title: 'doc B', text: 'sample word string to search across' }
46+
let insert: any = await db.query(aql`INSERT ${docA} INTO ${collection} RETURN NEW`)
47+
expect(insert._result[ 0 ].title).to.equal('doc A')
48+
49+
insert = await db.query(aql`INSERT ${docB} INTO ${collection} RETURN NEW`)
50+
expect(insert._result[ 0 ].title).to.equal('doc B')
51+
52+
const wait = (t: number) => new Promise(keep => setTimeout(keep, t))
53+
await wait(1400)
54+
55+
const getAllInViewQuery = aql`
56+
FOR doc in ${aql.literal(info.name)}
57+
RETURN doc
58+
`
59+
let allResults = await db.query(getAllInViewQuery)
60+
expect(allResults.hasNext()).to.be.ok
61+
let all = await allResults.all()
62+
expect(all[ 0 ]).to.have.property('title')
63+
expect(all[ 0 ].title).to.contain('doc')
64+
})
65+
66+
after(async () => {
67+
try {
68+
db.useDatabase("_system")
69+
await db.dropDatabase(dbName)
70+
/* should get deleted when dropping db */
71+
/* await view.drop() */
72+
} finally {
73+
db.close()
74+
}
75+
})
76+
77+
describe('empty terms', () => {
78+
it(`should exclude all results that do not match required terms`, async () => {
79+
80+
const info = await view.get()
81+
expect(info.name).to.be.a('string')
82+
83+
let query = {
84+
view: info.name,
85+
collections: [ {
86+
name: collectionName,
87+
analyzer: 'text_en'
88+
} ],
89+
terms: ''
90+
}
91+
const aqlQuery = buildAQL(query)
92+
const cursor = await db.query(aqlQuery)
93+
let has = cursor.hasNext()
94+
expect(has).to.be.ok
95+
96+
let result = await cursor.next()
97+
expect(result.title).to.match(/doc/)
4298
})
43-
after(async () => {
44-
try {
45-
db.useDatabase("_system")
46-
await db.dropDatabase(dbName)
47-
await view.drop()
48-
} finally {
49-
db.close()
50-
}
99+
})
100+
101+
describe('ANDS', () => {
102+
it(`only bring back results that include required words and phrases`, async () => {
103+
104+
const info = await view.get()
105+
expect(info.name).to.be.a('string')
106+
107+
108+
/* phrase */
109+
let query = {
110+
view: info.name,
111+
collections: [ {
112+
name: collectionName,
113+
analyzer: 'text_en'
114+
} ],
115+
terms: '+"word"'
116+
}
117+
let aqlQuery = buildAQL(query)
118+
119+
expect(Object.keys(aqlQuery.bindVars)).to.have.length(4)
120+
121+
let cursor = await db.query(aqlQuery)
122+
expect(cursor.hasNext()).to.be.ok
123+
/* should have two results*/
124+
let result = await cursor.next()
125+
expect(cursor.hasNext()).to.be.ok
126+
await cursor.next()
127+
expect(cursor.hasNext()).to.not.be.ok
128+
129+
/* should only have one document */
130+
query.terms = '+"in document"'
131+
cursor = await db.query(buildAQL(query))
132+
expect(cursor.hasNext()).to.be.ok
133+
result = await cursor.all()
134+
expect(result).to.have.length(1)
135+
expect(result[ 0 ].title).to.equal('doc A')
136+
137+
query.terms = '+"across"'
138+
cursor = await db.query(buildAQL(query))
139+
expect(cursor.hasNext()).to.be.ok
140+
result = await cursor.all()
141+
expect(result).to.have.length(1)
142+
expect(result[ 0 ].title).to.equal('doc A')
143+
expect(cursor.hasNext()).to.not.be.ok
144+
145+
146+
query.terms = '+"nowhere found"'
147+
cursor = await db.query(buildAQL(query))
148+
expect(cursor.hasNext()).to.be.ok
149+
150+
/* tokens */
151+
query = {
152+
view: info.name,
153+
collections: [ {
154+
name: collectionName,
155+
analyzer: 'text_en'
156+
} ],
157+
terms: '+word'
158+
}
159+
aqlQuery = buildAQL(query)
160+
161+
expect(Object.keys(aqlQuery.bindVars)).to.have.length(7)
162+
expect(aqlQuery.bindVars.value0).to.equal('word')
163+
expect(aqlQuery.bindVars.value1).to.equal('text_en')
164+
expect(aqlQuery.bindVars.value2).to.equal('text')
165+
expect(aqlQuery.bindVars.value3).to.equal(1)
166+
expect(aqlQuery.bindVars.value4).to.deep.equal({ collections: [ collectionName ] })
167+
expect(aqlQuery.bindVars.value5).to.equal(0)
168+
expect(aqlQuery.bindVars.value6).to.equal(20)
169+
170+
cursor = await db.query(aqlQuery)
171+
expect(cursor.hasNext()).to.be.ok
172+
173+
result = await cursor.next()
174+
expect(result.title).to.deep.equal('doc A')
175+
expect(cursor.hasNext()).to.be.ok
51176
})
52-
53-
describe('ANDS', () => {
54-
it(`should exclude all results that do not match required terms`, async () => {
55-
const query = {
56-
view: view.name,
57-
collections: [{
58-
name: collectionName,
59-
analyzer: 'text_en'
60-
}],
61-
terms: '+word'
62-
}
63-
const aqlQuery = buildAQL(query)
64-
65-
expect(Object.keys(aqlQuery.bindVars)).to.have.length(7)
66-
expect(aqlQuery.bindVars.value0).to.equal('word')
67-
expect(aqlQuery.bindVars.value1).to.equal('text_en')
68-
expect(aqlQuery.bindVars.value2).to.equal('text')
69-
expect(aqlQuery.bindVars.value3).to.equal(1)
70-
expect(aqlQuery.bindVars.value4).to.deep.equal({ collections: [collectionName] })
71-
expect(aqlQuery.bindVars.value5).to.equal(0)
72-
expect(aqlQuery.bindVars.value6).to.equal(20)
73-
expect(aqlQuery.query).to.equal(`
74-
FOR doc IN ${view.name}
75-
76-
SEARCH
77-
MIN_MATCH(
78-
ANALYZER(
79-
TOKENS(@value0, @value1)
80-
ALL IN doc.@value2, @value1),
81-
@value3)
82-
83-
84-
85-
OPTIONS @value4
86-
SORT TFIDF(doc) DESC
87-
88-
LIMIT @value5, @value6
89-
RETURN doc`)
90-
91-
const cursor = await db.query(aqlQuery)
92-
let has = cursor.hasNext()
93-
expect(has).to.be.ok
94-
95-
let result = await cursor.next()
96-
expect(result).to.deep.equal({ a: 1 })
97-
})
98-
})
99-
describe('ORS', () => {
100-
it(`should exclude all results that do not match required terms`, async () => {
101-
const query = {
102-
view: view.name,
103-
collections: [{
104-
name: collectionName,
105-
analyzer: 'text_en'
106-
}],
107-
terms: '+mandatory -exclude ?"optional phrase"'
108-
}
109-
const aqlQuery = buildAQL(query)
110-
expect(aqlQuery.query).to.equal('')
111-
112-
})
177+
})
178+
179+
describe('ORS', () => {
180+
it(`should exclude all results that do not match required terms`, async () => {
181+
const query = {
182+
view: view.name,
183+
collections: [ {
184+
name: collectionName,
185+
analyzer: 'text_en'
186+
} ],
187+
terms: '+mandatory -exclude ?"optional phrase"'
188+
}
189+
const aqlQuery = buildAQL(query)
190+
const cursor = await db.query(aqlQuery)
191+
192+
let has = cursor.hasNext()
193+
expect(has).to.be.ok
194+
195+
let result = await cursor.next()
196+
expect(result).to.deep.equal({ a: 1 })
113197
})
114-
198+
})
115199
})

tests/index.ts

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,26 @@ import { expect } from 'chai'
33
import { buildAQL } from '../src/index'
44

55
describe('index.ts', () => {
6-
it('should export a function named buildAQL', () => {
7-
expect(buildAQL).to.exist
8-
expect(buildAQL).to.be.a('function')
9-
})
6+
it('should export a function named buildAQL', () => {
7+
expect(buildAQL).to.exist
8+
expect(buildAQL).to.be.a('function')
9+
})
1010

11-
it('should validate the query', () => {
12-
expect(() => buildAQL({ view: '', collections: [], terms: [] })).to.throw(/query.view must be a valid ArangoSearch View name/)
11+
it('should validate the query', () => {
12+
expect(() => buildAQL({ view: '', collections: [], terms: [] })).to.throw(/query.view must be a valid ArangoSearch View name/)
1313

14-
expect(() => buildAQL({ view: 'view', collections: [], terms: [] })).to.throw(/query.collections must have at least one name/)
15-
})
14+
expect(() => buildAQL({ view: 'view', collections: [], terms: [] })).to.throw(/query.collections must have at least one name/)
15+
})
1616
})
1717

1818
describe('buildAQL', () => {
19-
it(`should return an aql object
20-
when a string is passed for query terms`, () => {
21-
const query = { view: 'view', collections: [ { name: 'coll', analyzer: 'analyzer' } ], terms: '' }
22-
const builtAQL = buildAQL(query)
23-
expect(builtAQL).to.be.an('object')
19+
it(`should return an aql object
20+
when an empty string is passed for query terms`, () => {
21+
let query = { view: 'view', collections: [{ name: 'coll', analyzer: 'analyzer' }], terms: '' }
22+
const builtAQL = buildAQL(query)
23+
expect(builtAQL).to.be.an('object')
2424

25-
expect(builtAQL.query).to.equal(`
25+
expect(builtAQL.query).to.equal(`
2626
FOR doc IN view
2727
2828
SEARCH
@@ -35,6 +35,52 @@ describe('buildAQL', () => {
3535
3636
LIMIT @value2, @value3
3737
RETURN doc`
38-
)
39-
})
38+
)
39+
})
40+
41+
it(`should return an aql object
42+
when an empty array is passed for query terms`, () => {
43+
let query = { view: 'view', collections: [{ name: 'coll', analyzer: 'analyzer' }], terms: [] }
44+
const builtAQL = buildAQL(query)
45+
expect(builtAQL).to.be.an('object')
46+
47+
expect(builtAQL.query).to.equal(`
48+
FOR doc IN view
49+
50+
SEARCH
51+
52+
53+
54+
@value0
55+
OPTIONS @value1
56+
SORT TFIDF(doc) DESC
57+
58+
LIMIT @value2, @value3
59+
RETURN doc`
60+
)
61+
})
62+
63+
it(`should return an aql object
64+
when a phrase string is passed for query terms`, () => {
65+
let query = { view: 'view', collections: [{ name: 'coll', analyzer: 'analyzer' }], terms: '"phrase search"' }
66+
const builtAQL = buildAQL(query)
67+
expect(builtAQL).to.be.an('object')
68+
69+
expect(builtAQL.query).to.equal(`
70+
FOR doc IN view
71+
72+
SEARCH
73+
74+
@value0
75+
76+
77+
OPTIONS @value1
78+
SORT TFIDF(doc) DESC
79+
80+
LIMIT @value2, @value3
81+
RETURN doc`)
82+
83+
expect(builtAQL.bindVars.value0[0].query).to.deep.equal('PHRASE(doc.@value0, @value1, @value2)')
84+
})
85+
4086
})

0 commit comments

Comments
 (0)