UNPKG

5.3 kBJavaScriptView Raw
1// Copyright IBM Corp. 2018,2019. All Rights Reserved.
2// Node module: loopback-datasource-juggler
3// This file is licensed under the MIT License.
4// License text available at https://opensource.org/licenses/MIT
5
6'use strict';
7
8const should = require('./init.js');
9const List = require('../lib/list');
10const parentRefHelper = require('./helpers/setup-parent-ref');
11const {ModelBuilder} = require('../lib/model-builder');
12
13const builder = new ModelBuilder(); // dummy builder instance for tests
14
15/**
16 * Phone as a class
17 */
18class Phone {
19 constructor(label, num) {
20 this.label = label;
21 this.num = num;
22 }
23
24 toJSON() {
25 return {
26 label: this.label,
27 num: this.num,
28 };
29 }
30}
31
32/**
33 * Dummy property for testing parent reference
34 * @type {ModelBuilder}
35 */
36Phone.modelBuilder = builder;
37
38/**
39 * Phone as a constructor function
40 * @param {string} label
41 * @param {number} num
42 */
43function PhoneCtor(label, num) {
44 if (!(this instanceof PhoneCtor)) {
45 return new PhoneCtor(label, num);
46 }
47 this.label = label;
48 this.num = num;
49}
50
51/**
52 * Dummy property for testing parent reference
53 * @type {ModelBuilder}
54 */
55PhoneCtor.modelBuilder = builder;
56
57describe('Does not break default Array functionality', function() {
58 it('allows creating an empty length with a specified length', function() {
59 const list = new List(4);
60 list.should.be.an.instanceOf(Array);
61 list.length.should.be.eql(4);
62 should.not.exist(list.itemType);
63 list.toJSON().should.eql([undefined, undefined, undefined, undefined]);
64 });
65});
66
67describe('list of items typed by a class', function() {
68 parentRefHelper(() => builder);
69 it('allows itemType to be a class', function() {
70 const phones = givenPhones();
71
72 const list = new List(phones, Phone);
73 list.should.be.an.instanceOf(Array);
74 list.toJSON().should.be.eql(phones);
75 });
76
77 it('converts items of plain json to the itemType', function() {
78 const phones = givenPhonesAsJSON();
79
80 const list = new List(phones, Phone);
81 list[0].should.be.an.instanceOf(Phone);
82 });
83
84 it('converts stringified items to the itemType', function() {
85 const phones = givenPhonesAsJSON();
86
87 const list = new List(JSON.stringify(phones), Phone);
88 list[0].should.be.an.instanceOf(Phone);
89 });
90
91 it('converts items of plain json to the itemType with push', function() {
92 const phones = givenPhonesAsJSON();
93
94 const list = new List([], Phone);
95 list.push(phones[0]);
96 list[0].should.be.an.instanceOf(Phone);
97 });
98
99 it('should assign the list\'s parent as parent to every child element', () => {
100 const phones = givenPhones();
101 const listParent = {name: 'PhoneBook'};
102 const list = new List(phones, Phone, listParent);
103 list.forEach((listItem) => {
104 listItem.should.have.property('__parent').which.equals(listParent);
105 });
106 });
107
108 it('should assign the list\'s parent as element parent with push', () => {
109 const phones = givenPhonesAsJSON();
110 const listParent = {name: 'PhoneBook'};
111 const list = new List([], Phone, listParent);
112 list.push(phones[0], phones[1]);
113 list.forEach((listItem) => {
114 listItem.should.have.property('__parent').which.equals(listParent);
115 });
116 });
117});
118
119describe('list of items typed by a ctor', function() {
120 parentRefHelper(() => builder);
121 it('allows itemType to be a ctor', function() {
122 const phones = givenPhonesWithCtor();
123
124 const list = new List(phones, PhoneCtor);
125 list.should.be.an.instanceOf(Array);
126 list.toJSON().should.be.eql(phones);
127 });
128
129 it('converts items of plain json to the itemType', function() {
130 const phones = givenPhonesAsJSON();
131
132 const list = new List(phones, PhoneCtor);
133 list[0].should.be.an.instanceOf(PhoneCtor);
134 });
135
136 it('converts stringified items to the itemType', function() {
137 const phones = givenPhonesAsJSON();
138
139 const list = new List(JSON.stringify(phones), PhoneCtor);
140 list[0].should.be.an.instanceOf(PhoneCtor);
141 });
142
143 it('converts items of plain json to the itemType with push', function() {
144 const phones = givenPhonesAsJSON();
145
146 const list = new List([], PhoneCtor);
147 list.push(phones[0]);
148 list[0].should.be.an.instanceOf(PhoneCtor);
149 });
150
151 it('should assign the list\'s parent as parent to every child element', () => {
152 const phones = givenPhones();
153 const listParent = {name: 'PhoneBook'};
154 const list = new List(phones, PhoneCtor, listParent);
155 list.forEach((listItem) => {
156 listItem.should.have.property('__parent').which.equals(listParent);
157 });
158 });
159
160 it('should assign the list\'s parent as element parent with push', () => {
161 const phones = givenPhonesAsJSON();
162 const listParent = {name: 'PhoneBook'};
163 const list = new List([], PhoneCtor, listParent);
164 list.push(phones[0], phones[1]);
165 list.forEach((listItem) => {
166 listItem.should.have.property('__parent').which.equals(listParent);
167 });
168 });
169});
170
171function givenPhones() {
172 return [
173 new Phone('home', '111-222-3333'),
174 new Phone('work', '111-222-5555'),
175 ];
176}
177
178function givenPhonesWithCtor() {
179 return [
180 new PhoneCtor('home', '111-222-3333'),
181 PhoneCtor('work', '111-222-5555'),
182 ];
183}
184
185function givenPhonesAsJSON() {
186 return [
187 {label: 'home', num: '111-222-3333'},
188 {label: 'work', num: '111-222-5555'},
189 ];
190}