Skip to content

Commit a23ccaf

Browse files
committed
finished tests
1 parent b0dbeae commit a23ccaf

File tree

2 files changed

+131
-150
lines changed

2 files changed

+131
-150
lines changed

lib/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ class Index {
155155
const results = await Promise.all(_.map(flat, (value, key) => this.find(key, value)))
156156
return _.intersection(...results)
157157
}
158+
return []
158159
}
159160
}
160161
}

test/index.test.js

Lines changed: 130 additions & 150 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,16 @@ const IndexField = require('../lib/index-field')
77
const Storage = require('@plaindb/storage/mock')
88

99
describe('Index', () => {
10-
const storage = new Storage()
11-
const index = new Index(storage, ['field1', 'field2|multi', 'field3 text'])
10+
const entity = { id: 1, name: 'Alice', age: 33, bio: 'Software Developer', gender: 'F', height: `5'4"` }
11+
const charlie = { id: 2, name: 'Charlie', age: 42, bio: 'Business Developer', gender: 'M', height: `6'4"` }
12+
const newEntity = { ...entity, name: 'Bob' }
13+
14+
let storage = new Storage()
15+
let index = new Index(storage, ['name', 'name|age', 'bio text'])
1216

1317
describe('constructor', () => {
1418
it('should set default fields', () => {
15-
expect(index.fields).to.have.keys(['field1', 'field2Multi', 'field3Text'])
19+
expect(index.fields).to.have.keys(['name', 'nameAge', 'bioText'])
1620
})
1721

1822
it('should initialize keys set', () => {
@@ -31,51 +35,150 @@ describe('Index', () => {
3135

3236
describe('by', () => {
3337
it('should add a new field', () => {
34-
index.by('newField')
35-
expect(index.fields).to.have.keys(['field1', 'field2Multi', 'field3Text', 'newField'])
38+
index.by('gender')
39+
expect(index.fields).to.have.keys(['name', 'nameAge', 'bioText', 'gender'])
3640
})
3741
})
3842

39-
describe('@todo - dispatch', () => {
43+
describe('dispatch', () => {
4044
it('should call storage.root.batch with ops', async () => {
41-
// const ops = [{}, {}, {}]
42-
// index.buildAdd = sinon.stub().returns(ops)
43-
44-
// await index.dispatch('add', {})
45-
46-
// expect(storage.root.batch.calledWith(ops)).to.be.true
45+
await index.dispatch('add', entity)
46+
const db = storage.sub(['name', 'alice'])
47+
for await (const [id, value] of db.iterator()) {
48+
expect(value).to.be.true
49+
expect(id).to.equal('1')
50+
}
4751
})
4852
})
4953

50-
51-
52-
5354
describe('buildAdd', () => {
5455
it('should build operations for adding entity', () => {
55-
// const entity = { id: 1, field1: 'test1' }
56-
// const ops = []
57-
58-
// index.fields.field1 = { add: sinon.stub().returns(ops) }
59-
60-
// const result = index.buildAdd(entity)
61-
62-
// expect(index.fields.field1.add.calledWith(entity, ops)).to.be.true
63-
// expect(result).to.equal(ops)
56+
const expectedOps = [
57+
{ path: [ 'name', 'alice' ], type: 'put', key: 1, value: true },
58+
{ path: [ 'nameAge', 'alice|33' ], type: 'put', key: 1, value: true },
59+
{ path: [ 'bioText', 'software' ], type: 'put', key: 1, value: true },
60+
{ path: [ 'bioText', 'developer' ], type: 'put', key: 1, value: true },
61+
{ path: [ 'gender', 'f' ], type: 'put', key: 1, value: true }
62+
]
63+
const ops = index.buildAdd(entity)
64+
expect(ops).to.have.lengthOf(5)
65+
expect(ops).to.eql(expectedOps)
6466
})
6567
})
6668

6769
describe('add', () => {
6870
it('should dispatch add operation', async () => {
69-
// index.dispatch = sinon.stub().resolves()
71+
await index.add(entity)
72+
const db = storage.sub(['name', 'alice'])
73+
const results = []
74+
for await (const [id, value] of db.iterator()) {
75+
results.push({ id, value })
76+
}
77+
expect(results).to.have.lengthOf(1)
78+
expect(results[0].value).to.be.true
79+
expect(results[0].id).to.equal('1')
80+
})
81+
})
7082

71-
// await index.add({})
83+
describe('buildUpdate', () => {
84+
it('should build operations for updating entity', () => {
85+
const ops = index.buildUpdate(entity, newEntity)
86+
const expectedOps = [
87+
{ path: [ 'name', 'alice' ], type: 'del', key: 1 },
88+
{ path: [ 'name', 'bob' ], type: 'put', key: 1, value: true },
89+
{ path: [ 'nameAge', 'alice|33' ], type: 'del', key: 1 },
90+
{ path: [ 'nameAge', 'bob|33' ], type: 'put', key: 1, value: true }
91+
]
92+
expect(ops).to.have.lengthOf(4)
93+
expect(ops).to.eql(expectedOps)
94+
})
95+
})
7296

73-
// expect(index.dispatch.calledWith('add')).to.be.true
97+
describe('update', () => {
98+
it('should dispatch update operation', async () => {
99+
await index.update(entity, newEntity)
100+
const db = storage.sub(['name', 'bob'])
101+
const results = []
102+
for await (const [id, value] of db.iterator()) {
103+
results.push({ id, value })
104+
expect(value).to.be.true
105+
expect(id).to.equal('1')
106+
}
107+
expect(results).to.have.lengthOf(1)
108+
expect(results[0].value).to.be.true
109+
expect(results[0].id).to.equal('1')
74110
})
75111
})
76112

113+
describe('buildRemove', () => {
114+
it('should build operations for removing entity', () => {
115+
const expectedOps = [
116+
{ path: [ 'name', 'alice' ], type: 'del', key: 1 },
117+
{ path: [ 'nameAge', 'alice|33' ], type: 'del', key: 1 },
118+
{ path: [ 'bioText', 'software' ], type: 'del', key: 1 },
119+
{ path: [ 'bioText', 'developer' ], type: 'del', key: 1 },
120+
{ path: [ 'gender', 'f' ], type: 'del', key: 1 }
121+
]
122+
const ops = index.buildRemove(entity)
123+
expect(ops).to.have.lengthOf(5)
124+
expect(ops).to.eql(expectedOps)
125+
})
126+
})
127+
128+
describe('remove', () => {
129+
it('should dispatch remove operation', async () => {
130+
await index.remove(newEntity)
131+
const results = []
132+
for await (const [id, value] of storage.sub(['name', 'bob']).iterator()) {
133+
results.push(id)
134+
}
135+
expect(results).to.have.lengthOf(0)
136+
})
137+
})
77138

139+
describe('find', async () => {
140+
beforeEach(async () => {
141+
storage = new Storage()
142+
index = new Index(storage, ['name', 'name|age', 'bio text'])
143+
await index.add(entity)
144+
await index.add(charlie)
78145

146+
// // Set up some mock data and methods
147+
// index.keys = new Set([1, 2, 3])
148+
// index.fields.field1 = { find: sinon.stub() }
149+
// index.fields.field2 = { find: sinon.stub() }
150+
})
151+
152+
it('should return empty array if no key matches', async () => {
153+
const results = await index.find('name', 'Bob')
154+
expect(results).to.be.empty
155+
})
156+
157+
it('should return matched keys', async () => {
158+
const results = await index.find('name', 'Alice')
159+
expect(results).to.deep.equal(['1'])
160+
})
161+
162+
it('should work with a single field', async () => {
163+
const results = await index.find({ name: 'Alice' })
164+
expect(results).to.deep.equal(['1'])
165+
})
166+
167+
it('should work with multiple fields', async () => {
168+
const results = await index.find({ name: 'Alice', age: 33 })
169+
expect(results).to.deep.equal(['1'])
170+
})
171+
172+
it('should work with text fields', async () => {
173+
const results = await index.find('bioText', 'developer')
174+
expect(results).to.deep.equal(['1', '2'])
175+
})
176+
177+
it('should handle non-existent fields gracefully', async () => {
178+
const results = await index.find({ nonexistentField: 'value' })
179+
expect(results).to.be.empty
180+
})
181+
})
79182
})
80183

81184
describe('IndexFactory', () => {
@@ -123,7 +226,6 @@ describe('IndexField', () => {
123226
})
124227
})
125228

126-
/*
127229
describe('SingleIndexField', () => {
128230
})
129231

@@ -132,125 +234,3 @@ describe('MultiIndexField', () => {
132234

133235
describe('TextIndexField', () => {
134236
})
135-
*/
136-
137-
describe.omit('Index', () => {
138-
let storage
139-
let index
140-
141-
beforeEach(() => {
142-
storage = {
143-
root: {
144-
batch: sinon.stub().resolves()
145-
}
146-
}
147-
index = new Index(storage, ['field1', 'field2|multi', 'field3 text'])
148-
})
149-
150-
151-
describe('buildRemove', () => {
152-
it('should build operations for removing entity', () => {
153-
const entity = { id: 1, field1: 'test1' }
154-
const ops = []
155-
156-
index.fields.field1 = { remove: sinon.stub().returns(ops) }
157-
158-
const result = index.buildRemove(entity)
159-
160-
expect(index.fields.field1.remove.calledWith(entity, ops)).to.be.true
161-
expect(result).to.equal(ops)
162-
})
163-
})
164-
165-
describe('remove', () => {
166-
it('should dispatch remove operation', async () => {
167-
index.dispatch = sinon.stub().resolves()
168-
169-
await index.remove({})
170-
171-
expect(index.dispatch.calledWith('remove')).to.be.true
172-
})
173-
})
174-
175-
describe('buildUpdate', () => {
176-
it('should build operations for updating entity', () => {
177-
const oldEntity = { id: 1, field1: 'test1' }
178-
const newEntity = { id: 1, field1: 'test2' }
179-
const ops = []
180-
181-
index.fields.field1 = { update: sinon.stub().returns(ops) }
182-
183-
const result = index.buildUpdate(oldEntity, newEntity)
184-
185-
expect(index.fields.field1.update.calledWith(oldEntity, newEntity, ops)).to.be.true
186-
expect(result).to.equal(ops)
187-
})
188-
})
189-
190-
describe('update', () => {
191-
it('should dispatch update operation', async () => {
192-
index.dispatch = sinon.stub().resolves()
193-
194-
await index.update({}, {})
195-
196-
expect(index.dispatch.calledWith('update')).to.be.true
197-
})
198-
})
199-
200-
// You could add more tests for 'find' method depending on your needs
201-
})
202-
203-
describe.omit('Index', () => {
204-
// ... (Previous set-up code and other tests)
205-
206-
describe('find', () => {
207-
beforeEach(() => {
208-
// Set up some mock data and methods
209-
index.keys = new Set([1, 2, 3])
210-
index.fields.field1 = { find: sinon.stub() }
211-
index.fields.field2 = { find: sinon.stub() }
212-
})
213-
214-
it('should return empty array if no key matches', async () => {
215-
index.fields.field1.find.returns(new Set([]))
216-
index.fields.field2.find.returns(new Set([]))
217-
218-
const result = await index.find({ field1: 'value1', field2: 'value2' })
219-
220-
expect(result).to.be.empty
221-
})
222-
223-
it('should return matched keys', async () => {
224-
index.fields.field1.find.returns(new Set([1, 2]))
225-
index.fields.field2.find.returns(new Set([2, 3]))
226-
227-
const result = await index.find({ field1: 'value1', field2: 'value2' })
228-
229-
expect(result).to.deep.equal([2])
230-
})
231-
232-
it('should work with a single field', async () => {
233-
index.fields.field1.find.returns(new Set([1, 2]))
234-
235-
const result = await index.find({ field1: 'value1' })
236-
237-
expect(result).to.deep.equal([1, 2])
238-
})
239-
240-
it('should work with multiple fields', async () => {
241-
index.fields.field1.find.returns(new Set([1, 2]))
242-
index.fields.field2.find.returns(new Set([2, 3]))
243-
index.fields.field3.find.returns(new Set([2, 4]))
244-
245-
const result = await index.find({ field1: 'value1', field2: 'value2', field3: 'value3' })
246-
247-
expect(result).to.deep.equal([2])
248-
})
249-
250-
it('should handle non-existent fields gracefully', async () => {
251-
const result = await index.find({ nonexistentField: 'value' })
252-
253-
expect(result).to.be.empty
254-
})
255-
})
256-
})

0 commit comments

Comments
 (0)