2020-01-21 18:12:14 +00:00
|
|
|
// Copyright IBM Corp. 2018,2019. All Rights Reserved.
|
2018-09-17 16:00:12 +00:00
|
|
|
// Node module: loopback-datasource-juggler
|
|
|
|
// This file is licensed under the MIT License.
|
|
|
|
// License text available at https://opensource.org/licenses/MIT
|
|
|
|
|
2018-09-17 15:22:21 +00:00
|
|
|
'use strict';
|
|
|
|
|
2018-12-07 14:54:29 +00:00
|
|
|
const should = require('./init.js');
|
|
|
|
const List = require('../lib/list');
|
2019-10-23 16:31:39 +00:00
|
|
|
const parentRefHelper = require('./helpers/setup-parent-ref');
|
|
|
|
const {ModelBuilder} = require('../lib/model-builder');
|
|
|
|
|
|
|
|
const builder = new ModelBuilder(); // dummy builder instance for tests
|
2018-09-17 15:22:21 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Phone as a class
|
|
|
|
*/
|
|
|
|
class Phone {
|
|
|
|
constructor(label, num) {
|
|
|
|
this.label = label;
|
|
|
|
this.num = num;
|
|
|
|
}
|
|
|
|
|
|
|
|
toJSON() {
|
|
|
|
return {
|
|
|
|
label: this.label,
|
|
|
|
num: this.num,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-23 16:31:39 +00:00
|
|
|
/**
|
|
|
|
* Dummy property for testing parent reference
|
|
|
|
* @type {ModelBuilder}
|
|
|
|
*/
|
|
|
|
Phone.modelBuilder = builder;
|
|
|
|
|
2018-09-17 15:22:21 +00:00
|
|
|
/**
|
|
|
|
* Phone as a constructor function
|
|
|
|
* @param {string} label
|
|
|
|
* @param {number} num
|
|
|
|
*/
|
|
|
|
function PhoneCtor(label, num) {
|
|
|
|
if (!(this instanceof PhoneCtor)) {
|
|
|
|
return new PhoneCtor(label, num);
|
|
|
|
}
|
|
|
|
this.label = label;
|
|
|
|
this.num = num;
|
|
|
|
}
|
|
|
|
|
2019-10-23 16:31:39 +00:00
|
|
|
/**
|
|
|
|
* Dummy property for testing parent reference
|
|
|
|
* @type {ModelBuilder}
|
|
|
|
*/
|
|
|
|
PhoneCtor.modelBuilder = builder;
|
|
|
|
|
2019-11-27 03:07:19 +00:00
|
|
|
describe('Does not break default Array functionality', function() {
|
|
|
|
it('allows creating an empty length with a specified length', function() {
|
|
|
|
const list = new List(4);
|
|
|
|
list.should.be.an.instanceOf(Array);
|
|
|
|
list.length.should.be.eql(4);
|
|
|
|
should.not.exist(list.itemType);
|
|
|
|
list.toJSON().should.eql([undefined, undefined, undefined, undefined]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-09-17 15:22:21 +00:00
|
|
|
describe('list of items typed by a class', function() {
|
2019-10-23 16:31:39 +00:00
|
|
|
parentRefHelper(() => builder);
|
2018-09-17 15:22:21 +00:00
|
|
|
it('allows itemType to be a class', function() {
|
2018-12-07 14:54:29 +00:00
|
|
|
const phones = givenPhones();
|
2018-09-17 15:22:21 +00:00
|
|
|
|
2018-12-07 14:54:29 +00:00
|
|
|
const list = new List(phones, Phone);
|
2018-09-17 15:22:21 +00:00
|
|
|
list.should.be.an.instanceOf(Array);
|
|
|
|
list.toJSON().should.be.eql(phones);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('converts items of plain json to the itemType', function() {
|
2018-12-07 14:54:29 +00:00
|
|
|
const phones = givenPhonesAsJSON();
|
2018-09-17 15:22:21 +00:00
|
|
|
|
2018-12-07 14:54:29 +00:00
|
|
|
const list = new List(phones, Phone);
|
2018-09-17 15:22:21 +00:00
|
|
|
list[0].should.be.an.instanceOf(Phone);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('converts stringified items to the itemType', function() {
|
2018-12-07 14:54:29 +00:00
|
|
|
const phones = givenPhonesAsJSON();
|
2018-09-17 15:22:21 +00:00
|
|
|
|
2018-12-07 14:54:29 +00:00
|
|
|
const list = new List(JSON.stringify(phones), Phone);
|
2018-09-17 15:22:21 +00:00
|
|
|
list[0].should.be.an.instanceOf(Phone);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('converts items of plain json to the itemType with push', function() {
|
2018-12-07 14:54:29 +00:00
|
|
|
const phones = givenPhonesAsJSON();
|
2018-09-17 15:22:21 +00:00
|
|
|
|
2018-12-07 14:54:29 +00:00
|
|
|
const list = new List([], Phone);
|
2018-09-17 15:22:21 +00:00
|
|
|
list.push(phones[0]);
|
|
|
|
list[0].should.be.an.instanceOf(Phone);
|
|
|
|
});
|
2019-10-23 16:31:39 +00:00
|
|
|
|
|
|
|
it('should assign the list\'s parent as parent to every child element', () => {
|
|
|
|
const phones = givenPhones();
|
|
|
|
const listParent = {name: 'PhoneBook'};
|
|
|
|
const list = new List(phones, Phone, listParent);
|
|
|
|
list.forEach((listItem) => {
|
|
|
|
listItem.should.have.property('__parent').which.equals(listParent);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should assign the list\'s parent as element parent with push', () => {
|
|
|
|
const phones = givenPhonesAsJSON();
|
|
|
|
const listParent = {name: 'PhoneBook'};
|
|
|
|
const list = new List([], Phone, listParent);
|
|
|
|
list.push(phones[0], phones[1]);
|
|
|
|
list.forEach((listItem) => {
|
|
|
|
listItem.should.have.property('__parent').which.equals(listParent);
|
|
|
|
});
|
|
|
|
});
|
2018-09-17 15:22:21 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
describe('list of items typed by a ctor', function() {
|
2019-10-23 16:31:39 +00:00
|
|
|
parentRefHelper(() => builder);
|
2018-09-17 15:22:21 +00:00
|
|
|
it('allows itemType to be a ctor', function() {
|
2018-12-07 14:54:29 +00:00
|
|
|
const phones = givenPhonesWithCtor();
|
2018-09-17 15:22:21 +00:00
|
|
|
|
2018-12-07 14:54:29 +00:00
|
|
|
const list = new List(phones, PhoneCtor);
|
2018-09-17 15:22:21 +00:00
|
|
|
list.should.be.an.instanceOf(Array);
|
|
|
|
list.toJSON().should.be.eql(phones);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('converts items of plain json to the itemType', function() {
|
2018-12-07 14:54:29 +00:00
|
|
|
const phones = givenPhonesAsJSON();
|
2018-09-17 15:22:21 +00:00
|
|
|
|
2018-12-07 14:54:29 +00:00
|
|
|
const list = new List(phones, PhoneCtor);
|
2018-09-17 15:22:21 +00:00
|
|
|
list[0].should.be.an.instanceOf(PhoneCtor);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('converts stringified items to the itemType', function() {
|
2018-12-07 14:54:29 +00:00
|
|
|
const phones = givenPhonesAsJSON();
|
2018-09-17 15:22:21 +00:00
|
|
|
|
2018-12-07 14:54:29 +00:00
|
|
|
const list = new List(JSON.stringify(phones), PhoneCtor);
|
2018-09-17 15:22:21 +00:00
|
|
|
list[0].should.be.an.instanceOf(PhoneCtor);
|
|
|
|
});
|
|
|
|
|
|
|
|
it('converts items of plain json to the itemType with push', function() {
|
2018-12-07 14:54:29 +00:00
|
|
|
const phones = givenPhonesAsJSON();
|
2018-09-17 15:22:21 +00:00
|
|
|
|
2018-12-07 14:54:29 +00:00
|
|
|
const list = new List([], PhoneCtor);
|
2018-09-17 15:22:21 +00:00
|
|
|
list.push(phones[0]);
|
|
|
|
list[0].should.be.an.instanceOf(PhoneCtor);
|
|
|
|
});
|
2019-10-23 16:31:39 +00:00
|
|
|
|
|
|
|
it('should assign the list\'s parent as parent to every child element', () => {
|
|
|
|
const phones = givenPhones();
|
|
|
|
const listParent = {name: 'PhoneBook'};
|
|
|
|
const list = new List(phones, PhoneCtor, listParent);
|
|
|
|
list.forEach((listItem) => {
|
|
|
|
listItem.should.have.property('__parent').which.equals(listParent);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('should assign the list\'s parent as element parent with push', () => {
|
|
|
|
const phones = givenPhonesAsJSON();
|
|
|
|
const listParent = {name: 'PhoneBook'};
|
|
|
|
const list = new List([], PhoneCtor, listParent);
|
|
|
|
list.push(phones[0], phones[1]);
|
|
|
|
list.forEach((listItem) => {
|
|
|
|
listItem.should.have.property('__parent').which.equals(listParent);
|
|
|
|
});
|
|
|
|
});
|
2018-09-17 15:22:21 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
function givenPhones() {
|
|
|
|
return [
|
|
|
|
new Phone('home', '111-222-3333'),
|
|
|
|
new Phone('work', '111-222-5555'),
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
function givenPhonesWithCtor() {
|
|
|
|
return [
|
|
|
|
new PhoneCtor('home', '111-222-3333'),
|
|
|
|
PhoneCtor('work', '111-222-5555'),
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
function givenPhonesAsJSON() {
|
|
|
|
return [
|
|
|
|
{label: 'home', num: '111-222-3333'},
|
|
|
|
{label: 'work', num: '111-222-5555'},
|
|
|
|
];
|
|
|
|
}
|