1 | 'use strict';
|
2 |
|
3 | const _ = require('lodash');
|
4 | const expect = require('chai').expect;
|
5 | const connect = require('../index').connect;
|
6 | const Document = require('../index').Document;
|
7 | const Data = require('./data');
|
8 | const getData1 = require('./util').data1;
|
9 | const getData2 = require('./util').data2;
|
10 | const validateData1 = require('./util').validateData1;
|
11 | const validateData2 = require('./util').validateData2;
|
12 | const validateId = require('./util').validateId;
|
13 | const isNativeId = require('../lib/validate').isNativeId;
|
14 |
|
15 | describe('Client', function() {
|
16 |
|
17 | const url = 'nedb://memory';
|
18 |
|
19 | let database = null;
|
20 |
|
21 | before(function(done) {
|
22 | connect(url).then(function(db) {
|
23 | database = db;
|
24 | return database.dropDatabase();
|
25 | }).then(function() {
|
26 | return done();
|
27 | });
|
28 | });
|
29 |
|
30 | beforeEach(function(done) {
|
31 | done();
|
32 | });
|
33 |
|
34 | afterEach(function(done) {
|
35 | database.dropDatabase().then(function() {}).then(done, done);
|
36 | });
|
37 |
|
38 | after(function(done) {
|
39 | database.dropDatabase().then(function() {}).then(done, done);
|
40 | });
|
41 |
|
42 | describe('#save()', function() {
|
43 | it('should persist the object and its members to the database', function(done) {
|
44 |
|
45 | let data = getData1();
|
46 |
|
47 | data.save().then(function() {
|
48 | validateId(data);
|
49 | validateData1(data);
|
50 | }).then(done, done);
|
51 | });
|
52 | });
|
53 |
|
54 | class Address extends Document {
|
55 | constructor() {
|
56 | super();
|
57 |
|
58 | this.street = String;
|
59 | this.city = String;
|
60 | this.zipCode = Number;
|
61 | }
|
62 |
|
63 | static collectionName() {
|
64 | return 'addresses';
|
65 | }
|
66 | }
|
67 |
|
68 | class Pet extends Document {
|
69 | constructor() {
|
70 | super();
|
71 |
|
72 | this.schema({
|
73 | type: String,
|
74 | name: String,
|
75 | });
|
76 | }
|
77 | }
|
78 |
|
79 | class User extends Document {
|
80 | constructor() {
|
81 | super();
|
82 |
|
83 | this.schema({
|
84 | firstName: String,
|
85 | lastName: String,
|
86 | pet: Pet,
|
87 | address: Address
|
88 | });
|
89 | }
|
90 | }
|
91 |
|
92 | describe('#findOne()', function() {
|
93 | it('should load a single object from the collection', function(done) {
|
94 |
|
95 | let data = getData1();
|
96 |
|
97 | data.save().then(function() {
|
98 | validateId(data);
|
99 | return Data.findOne({item:99});
|
100 | }).then(function(d) {
|
101 | validateId(d);
|
102 | validateData1(d);
|
103 | }).then(done, done);
|
104 | });
|
105 |
|
106 | it('should populate all fields', function(done) {
|
107 | let address = Address.create({
|
108 | street: '123 Fake St.',
|
109 | city: 'Cityville',
|
110 | zipCode: 12345
|
111 | });
|
112 |
|
113 | let dog = Pet.create({
|
114 | type: 'dog',
|
115 | name: 'Fido',
|
116 | });
|
117 |
|
118 | let user = User.create({
|
119 | firstName: 'Billy',
|
120 | lastName: 'Bob',
|
121 | pet: dog,
|
122 | address: address
|
123 | });
|
124 |
|
125 | Promise.all([address.save(), dog.save()]).then(function() {
|
126 | validateId(address);
|
127 | validateId(dog);
|
128 | return user.save();
|
129 | }).then(function() {
|
130 | validateId(user);
|
131 | return User.findOne({_id: user._id}, {populate: true});
|
132 | }).then(function(u) {
|
133 | expect(u.pet).to.be.an.instanceof(Pet);
|
134 | expect(u.address).to.be.an.instanceof(Address);
|
135 | }).then(done, done);
|
136 | });
|
137 |
|
138 | it('should not populate any fields', function(done) {
|
139 | let address = Address.create({
|
140 | street: '123 Fake St.',
|
141 | city: 'Cityville',
|
142 | zipCode: 12345
|
143 | });
|
144 |
|
145 | let dog = Pet.create({
|
146 | type: 'dog',
|
147 | name: 'Fido',
|
148 | });
|
149 |
|
150 | let user = User.create({
|
151 | firstName: 'Billy',
|
152 | lastName: 'Bob',
|
153 | pet: dog,
|
154 | address: address
|
155 | });
|
156 |
|
157 | Promise.all([address.save(), dog.save()]).then(function() {
|
158 | validateId(address);
|
159 | validateId(dog);
|
160 | return user.save();
|
161 | }).then(function() {
|
162 | validateId(user);
|
163 | return User.findOne({_id: user._id}, {populate: false});
|
164 | }).then(function(u) {
|
165 | expect(isNativeId(u.pet)).to.be.true;
|
166 | expect(isNativeId(u.address)).to.be.true;
|
167 | }).then(done, done);
|
168 | });
|
169 |
|
170 | it('should populate specified fields', function(done) {
|
171 | let address = Address.create({
|
172 | street: '123 Fake St.',
|
173 | city: 'Cityville',
|
174 | zipCode: 12345
|
175 | });
|
176 |
|
177 | let dog = Pet.create({
|
178 | type: 'dog',
|
179 | name: 'Fido',
|
180 | });
|
181 |
|
182 | let user = User.create({
|
183 | firstName: 'Billy',
|
184 | lastName: 'Bob',
|
185 | pet: dog,
|
186 | address: address
|
187 | });
|
188 |
|
189 | Promise.all([address.save(), dog.save()]).then(function() {
|
190 | validateId(address);
|
191 | validateId(dog);
|
192 | return user.save();
|
193 | }).then(function() {
|
194 | validateId(user);
|
195 | return User.findOne({_id: user._id}, {populate: ['pet']});
|
196 | }).then(function(u) {
|
197 | expect(u.pet).to.be.an.instanceof(Pet);
|
198 | expect(isNativeId(u.address)).to.be.true;
|
199 | }).then(done, done);
|
200 | });
|
201 | });
|
202 |
|
203 | describe('#findOneAndUpdate()', function() {
|
204 | it('should load and update a single object from the collection', function(done) {
|
205 |
|
206 | let data = getData1();
|
207 |
|
208 | data.save().then(function() {
|
209 | validateId(data);
|
210 | return Data.findOneAndUpdate({number: 1}, {source: 'wired'});
|
211 | }).then(function(d) {
|
212 | validateId(d);
|
213 | expect(d.number).to.equal(1);
|
214 | expect(d.source).to.equal('wired');
|
215 | }).then(done, done);
|
216 | });
|
217 |
|
218 | it('should insert a single object to the collection', function(done) {
|
219 | Data.findOne({number: 1}).then(function(d) {
|
220 | expect(d).to.be.null;
|
221 | return Data.findOneAndUpdate({number: 1}, {number: 1}, {upsert: true});
|
222 | }).then(function(data) {
|
223 | validateId(data);
|
224 | expect(data.number).to.equal(1);
|
225 | return Data.findOne({number: 1});
|
226 | }).then(function(d) {
|
227 | validateId(d);
|
228 | expect(d.number).to.equal(1);
|
229 | }).then(done, done);
|
230 | });
|
231 | });
|
232 |
|
233 | describe('#findOneAndDelete()', function() {
|
234 | it('should load and delete a single object from the collection', function(done) {
|
235 |
|
236 | let data = getData1();
|
237 |
|
238 | data.save().then(function() {
|
239 | validateId(data);
|
240 | return Data.count({ number: 1 });
|
241 | }).then(function(count) {
|
242 | expect(count).to.be.equal(1);
|
243 | return Data.findOneAndDelete({number: 1});
|
244 | }).then(function(numDeleted) {
|
245 | expect(numDeleted).to.equal(1);
|
246 | return Data.count({ number: 1 });
|
247 | }).then(function(count) {
|
248 | expect(count).to.equal(0);
|
249 | }).then(done, done);
|
250 | });
|
251 | });
|
252 |
|
253 | describe('#find()', function() {
|
254 | class City extends Document {
|
255 | constructor() {
|
256 | super();
|
257 |
|
258 | this.name = String;
|
259 | this.population = Number;
|
260 | }
|
261 |
|
262 | static collectionName() {
|
263 | return 'cities';
|
264 | }
|
265 | }
|
266 |
|
267 | var Springfield, SouthPark, Quahog;
|
268 |
|
269 | beforeEach(function(done) {
|
270 | Springfield = City.create({
|
271 | name: 'Springfield',
|
272 | population: 30720
|
273 | });
|
274 |
|
275 | SouthPark = City.create({
|
276 | name: 'South Park',
|
277 | population: 4388
|
278 | });
|
279 |
|
280 | Quahog = City.create({
|
281 | name: 'Quahog',
|
282 | population: 800
|
283 | });
|
284 |
|
285 | Promise.all([Springfield.save(), SouthPark.save(), Quahog.save()])
|
286 | .then(function() {
|
287 | validateId(Springfield);
|
288 | validateId(SouthPark);
|
289 | validateId(Quahog);
|
290 | done();
|
291 | });
|
292 | });
|
293 |
|
294 | it('should load multiple objects from the collection', function(done) {
|
295 | City.find({}).then(function(cities) {
|
296 | expect(cities).to.have.length(3);
|
297 | validateId(cities[0]);
|
298 | validateId(cities[1]);
|
299 | validateId(cities[2]);
|
300 | }).then(done, done);
|
301 | });
|
302 |
|
303 | it('should load all objects when query is not provided', function(done) {
|
304 | City.find().then(function(cities) {
|
305 | expect(cities).to.have.length(3);
|
306 | validateId(cities[0]);
|
307 | validateId(cities[1]);
|
308 | validateId(cities[2]);
|
309 | }).then(done, done);
|
310 | });
|
311 |
|
312 | it('should sort results in ascending order', function(done) {
|
313 | City.find({}, {sort: 'population'}).then(function(cities) {
|
314 | expect(cities).to.have.length(3);
|
315 | validateId(cities[0]);
|
316 | validateId(cities[1]);
|
317 | validateId(cities[2]);
|
318 | expect(cities[0].population).to.be.equal(800);
|
319 | expect(cities[1].population).to.be.equal(4388);
|
320 | expect(cities[2].population).to.be.equal(30720);
|
321 | }).then(done, done);
|
322 | });
|
323 |
|
324 | it('should sort results in descending order', function(done) {
|
325 | City.find({}, {sort: '-population'}).then(function(cities) {
|
326 | expect(cities).to.have.length(3);
|
327 | validateId(cities[0]);
|
328 | validateId(cities[1]);
|
329 | validateId(cities[2]);
|
330 | expect(cities[0].population).to.be.equal(30720);
|
331 | expect(cities[1].population).to.be.equal(4388);
|
332 | expect(cities[2].population).to.be.equal(800);
|
333 | }).then(done, done);
|
334 | });
|
335 |
|
336 | it('should sort results using multiple keys', function(done) {
|
337 | let AlphaVille = City.create({
|
338 | name: 'Alphaville',
|
339 | population: 4388
|
340 | });
|
341 |
|
342 | let BetaTown = City.create({
|
343 | name: 'Beta Town',
|
344 | population: 4388
|
345 | });
|
346 |
|
347 | Promise.all([AlphaVille.save(), BetaTown.save()]).then(function() {
|
348 | return City.find({}, {sort: ['population', '-name']});
|
349 | }).then(function(cities) {
|
350 | expect(cities).to.have.length(5);
|
351 | validateId(cities[0]);
|
352 | validateId(cities[1]);
|
353 | validateId(cities[2]);
|
354 | validateId(cities[3]);
|
355 | validateId(cities[4]);
|
356 | expect(cities[0].population).to.be.equal(800);
|
357 | expect(cities[0].name).to.be.equal('Quahog');
|
358 | expect(cities[1].population).to.be.equal(4388);
|
359 | expect(cities[1].name).to.be.equal('South Park');
|
360 | expect(cities[2].population).to.be.equal(4388);
|
361 | expect(cities[2].name).to.be.equal('Beta Town');
|
362 | expect(cities[3].population).to.be.equal(4388);
|
363 | expect(cities[3].name).to.be.equal('Alphaville');
|
364 | expect(cities[4].population).to.be.equal(30720);
|
365 | expect(cities[4].name).to.be.equal('Springfield');
|
366 | }).then(done, done);
|
367 | });
|
368 |
|
369 | it('should limit number of results returned', function(done) {
|
370 | City.find({}, {limit: 2}).then(function(cities) {
|
371 | expect(cities).to.have.length(2);
|
372 | validateId(cities[0]);
|
373 | validateId(cities[1]);
|
374 | }).then(done, done);
|
375 | });
|
376 |
|
377 | it('should skip given number of results', function(done) {
|
378 | City.find({}, {sort: 'population', skip: 1}).then(function(cities) {
|
379 | expect(cities).to.have.length(2);
|
380 | validateId(cities[0]);
|
381 | validateId(cities[1]);
|
382 | expect(cities[0].population).to.be.equal(4388);
|
383 | expect(cities[1].population).to.be.equal(30720);
|
384 | }).then(done, done);
|
385 | });
|
386 |
|
387 | it('should populate all fields', function(done) {
|
388 | let address = Address.create({
|
389 | street: '123 Fake St.',
|
390 | city: 'Cityville',
|
391 | zipCode: 12345
|
392 | });
|
393 |
|
394 | let dog = Pet.create({
|
395 | type: 'dog',
|
396 | name: 'Fido',
|
397 | });
|
398 |
|
399 | let user1 = User.create({
|
400 | firstName: 'Billy',
|
401 | lastName: 'Bob',
|
402 | pet: dog,
|
403 | address: address
|
404 | });
|
405 |
|
406 | let user2 = User.create({
|
407 | firstName: 'Sally',
|
408 | lastName: 'Bob',
|
409 | pet: dog,
|
410 | address: address
|
411 | });
|
412 |
|
413 | Promise.all([address.save(), dog.save()]).then(function() {
|
414 | validateId(address);
|
415 | validateId(dog);
|
416 | return Promise.all([user1.save(), user2.save()]);
|
417 | }).then(function() {
|
418 | validateId(user1);
|
419 | validateId(user2);
|
420 | return User.find({}, {populate: true});
|
421 | }).then(function(users) {
|
422 | expect(users[0].pet).to.be.an.instanceof(Pet);
|
423 | expect(users[0].address).to.be.an.instanceof(Address);
|
424 | expect(users[1].pet).to.be.an.instanceof(Pet);
|
425 | expect(users[1].address).to.be.an.instanceof(Address);
|
426 | }).then(done, done);
|
427 | });
|
428 |
|
429 | it('should not populate any fields', function(done) {
|
430 | let address = Address.create({
|
431 | street: '123 Fake St.',
|
432 | city: 'Cityville',
|
433 | zipCode: 12345
|
434 | });
|
435 |
|
436 | let dog = Pet.create({
|
437 | type: 'dog',
|
438 | name: 'Fido',
|
439 | });
|
440 |
|
441 | let user1 = User.create({
|
442 | firstName: 'Billy',
|
443 | lastName: 'Bob',
|
444 | pet: dog,
|
445 | address: address
|
446 | });
|
447 |
|
448 | let user2 = User.create({
|
449 | firstName: 'Sally',
|
450 | lastName: 'Bob',
|
451 | pet: dog,
|
452 | address: address
|
453 | });
|
454 |
|
455 | Promise.all([address.save(), dog.save()]).then(function() {
|
456 | validateId(address);
|
457 | validateId(dog);
|
458 | return Promise.all([user1.save(), user2.save()]);
|
459 | }).then(function() {
|
460 | validateId(user1);
|
461 | validateId(user2);
|
462 | return User.find({}, {populate: false});
|
463 | }).then(function(users) {
|
464 | expect(isNativeId(users[0].pet)).to.be.true;
|
465 | expect(isNativeId(users[0].address)).to.be.true;
|
466 | expect(isNativeId(users[1].pet)).to.be.true;
|
467 | expect(isNativeId(users[1].address)).to.be.true;
|
468 | }).then(done, done);
|
469 | });
|
470 |
|
471 | it('should populate specified fields', function(done) {
|
472 | let address = Address.create({
|
473 | street: '123 Fake St.',
|
474 | city: 'Cityville',
|
475 | zipCode: 12345
|
476 | });
|
477 |
|
478 | let dog = Pet.create({
|
479 | type: 'dog',
|
480 | name: 'Fido',
|
481 | });
|
482 |
|
483 | let user1 = User.create({
|
484 | firstName: 'Billy',
|
485 | lastName: 'Bob',
|
486 | pet: dog,
|
487 | address: address
|
488 | });
|
489 |
|
490 | let user2 = User.create({
|
491 | firstName: 'Sally',
|
492 | lastName: 'Bob',
|
493 | pet: dog,
|
494 | address: address
|
495 | });
|
496 |
|
497 | Promise.all([address.save(), dog.save()]).then(function() {
|
498 | validateId(address);
|
499 | validateId(dog);
|
500 | return Promise.all([user1.save(), user2.save()]);
|
501 | }).then(function() {
|
502 | validateId(user1);
|
503 | validateId(user2);
|
504 | return User.find({}, {populate: ['pet']});
|
505 | }).then(function(users) {
|
506 | expect(users[0].pet).to.be.an.instanceof(Pet);
|
507 | expect(isNativeId(users[0].address)).to.be.true;
|
508 | expect(users[1].pet).to.be.an.instanceof(Pet);
|
509 | expect(isNativeId(users[1].address)).to.be.true;
|
510 | }).then(done, done);
|
511 | });
|
512 | });
|
513 |
|
514 | describe('#count()', function() {
|
515 | it('should return 0 objects from the collection', function(done) {
|
516 |
|
517 | let data1 = getData1();
|
518 | let data2 = getData2();
|
519 |
|
520 | Promise.all([data1.save(), data2.save()]).then(function() {
|
521 | validateId(data1);
|
522 | validateId(data2);
|
523 | return Data.count({ number: 3 });
|
524 | }).then(function(count) {
|
525 | expect(count).to.be.equal(0);
|
526 | }).then(done, done);
|
527 | });
|
528 |
|
529 | it('should return 2 matching objects from the collection', function(done) {
|
530 |
|
531 | let data1 = getData1();
|
532 | let data2 = getData2();
|
533 |
|
534 | Promise.all([data1.save(), data2.save()]).then(function() {
|
535 | validateId(data1);
|
536 | validateId(data2);
|
537 | return Data.count({});
|
538 | }).then(function(count) {
|
539 | expect(count).to.be.equal(2);
|
540 | }).then(done, done);
|
541 | });
|
542 | });
|
543 |
|
544 | describe('#delete()', function() {
|
545 | it('should remove instance from the collection', function(done) {
|
546 |
|
547 | let data = getData1();
|
548 |
|
549 | data.save().then(function() {
|
550 | validateId(data);
|
551 | return data.delete();
|
552 | }).then(function(numDeleted) {
|
553 | expect(numDeleted).to.be.equal(1);
|
554 | return Data.findOne({item:99});
|
555 | }).then(function(d) {
|
556 | expect(d).to.be.null;
|
557 | }).then(done, done);
|
558 | });
|
559 | });
|
560 |
|
561 | describe('#deleteOne()', function() {
|
562 | it('should remove the object from the collection', function(done) {
|
563 |
|
564 | let data = getData1();
|
565 |
|
566 | data.save().then(function() {
|
567 | validateId(data);
|
568 | return Data.deleteOne({number: 1});
|
569 | }).then(function(numDeleted) {
|
570 | expect(numDeleted).to.be.equal(1);
|
571 | return Data.findOne({number: 1});
|
572 | }).then(function(d) {
|
573 | expect(d).to.be.null;
|
574 | }).then(done, done);
|
575 | });
|
576 | });
|
577 |
|
578 | describe('#deleteMany()', function() {
|
579 | it('should remove multiple objects from the collection', function(done) {
|
580 |
|
581 | let data1 = getData1();
|
582 | let data2 = getData2();
|
583 |
|
584 | Promise.all([data1.save(), data2.save()]).then(function() {
|
585 | validateId(data1);
|
586 | validateId(data2);
|
587 | return Data.deleteMany({});
|
588 | }).then(function(numDeleted) {
|
589 | expect(numDeleted).to.be.equal(2);
|
590 | return Data.find({});
|
591 | }).then(function(datas) {
|
592 | expect(datas).to.have.length(0);
|
593 | }).then(done, done);
|
594 | });
|
595 |
|
596 | it('should remove all objects when query is not provided', function(done) {
|
597 |
|
598 | let data1 = getData1();
|
599 | let data2 = getData2();
|
600 |
|
601 | Promise.all([data1.save(), data2.save()]).then(function() {
|
602 | validateId(data1);
|
603 | validateId(data2);
|
604 | return Data.deleteMany();
|
605 | }).then(function(numDeleted) {
|
606 | expect(numDeleted).to.be.equal(2);
|
607 | return Data.find({});
|
608 | }).then(function(datas) {
|
609 | expect(datas).to.have.length(0);
|
610 | }).then(done, done);
|
611 | });
|
612 | });
|
613 |
|
614 | describe('#clearCollection()', function() {
|
615 | it('should remove all objects from the collection', function(done) {
|
616 |
|
617 | let data1 = getData1();
|
618 | let data2 = getData2();
|
619 |
|
620 | Promise.all([data1.save(), data2.save()]).then(function() {
|
621 | validateId(data1);
|
622 | validateId(data2);
|
623 | return Data.clearCollection();
|
624 | }).then(function() {
|
625 | return Data.find();
|
626 | }).then(function(datas) {
|
627 | expect(datas).to.have.length(0);
|
628 | }).then(done, done);
|
629 | });
|
630 | });
|
631 |
|
632 |
|
633 | }); |
\ | No newline at end of file |