@@ -7,12 +7,16 @@ const IndexField = require('../lib/index-field')
7
7
const Storage = require ( '@plaindb/storage/mock' )
8
8
9
9
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' ] )
12
16
13
17
describe ( 'constructor' , ( ) => {
14
18
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 ' ] )
16
20
} )
17
21
18
22
it ( 'should initialize keys set' , ( ) => {
@@ -31,51 +35,150 @@ describe('Index', () => {
31
35
32
36
describe ( 'by' , ( ) => {
33
37
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 ' ] )
36
40
} )
37
41
} )
38
42
39
- describe ( '@todo - dispatch' , ( ) => {
43
+ describe ( 'dispatch' , ( ) => {
40
44
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
+ }
47
51
} )
48
52
} )
49
53
50
-
51
-
52
-
53
54
describe ( 'buildAdd' , ( ) => {
54
55
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 )
64
66
} )
65
67
} )
66
68
67
69
describe ( 'add' , ( ) => {
68
70
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
+ } )
70
82
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
+ } )
72
96
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' )
74
110
} )
75
111
} )
76
112
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
+ } )
77
138
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 )
78
145
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
+ } )
79
182
} )
80
183
81
184
describe ( 'IndexFactory' , ( ) => {
@@ -123,7 +226,6 @@ describe('IndexField', () => {
123
226
} )
124
227
} )
125
228
126
- /*
127
229
describe ( 'SingleIndexField' , ( ) => {
128
230
} )
129
231
@@ -132,125 +234,3 @@ describe('MultiIndexField', () => {
132
234
133
235
describe ( 'TextIndexField' , ( ) => {
134
236
} )
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