functional-models 1.0.28 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/.eslintignore +1 -0
  2. package/.eslintrc +9 -15
  3. package/cucumber.js +10 -0
  4. package/features/arrayFields.feature +7 -7
  5. package/features/basic-ts.feature +13 -0
  6. package/features/functions.feature +2 -3
  7. package/package.json +33 -10
  8. package/src/constants.ts +15 -0
  9. package/src/{errors.js → errors.ts} +6 -4
  10. package/src/index.ts +11 -0
  11. package/src/interfaces.ts +323 -0
  12. package/src/{lazy.js → lazy.ts} +7 -9
  13. package/src/methods.ts +30 -0
  14. package/src/models.ts +183 -0
  15. package/src/properties.ts +375 -0
  16. package/src/serialization.ts +39 -0
  17. package/src/{utils.js → utils.ts} +16 -26
  18. package/src/validation.ts +390 -0
  19. package/{features/stepDefinitions/steps.js → stepDefinitions/oldSteps.ts} +76 -53
  20. package/stepDefinitions/tssteps.ts +107 -0
  21. package/test/src/errors.test.ts +31 -0
  22. package/test/src/{lazy.test.js → lazy.test.ts} +4 -4
  23. package/test/src/methods.test.ts +45 -0
  24. package/test/src/models.test.ts +417 -0
  25. package/test/src/{properties.test.js → properties.test.ts} +251 -58
  26. package/test/src/serialization.test.ts +80 -0
  27. package/test/src/{utils.test.js → utils.test.ts} +29 -7
  28. package/test/src/{validation.test.js → validation.test.ts} +278 -210
  29. package/tsconfig.json +100 -0
  30. package/src/constants.js +0 -19
  31. package/src/functions.js +0 -7
  32. package/src/index.js +0 -10
  33. package/src/models.js +0 -152
  34. package/src/properties.js +0 -313
  35. package/src/serialization.js +0 -50
  36. package/src/validation.js +0 -285
  37. package/test/base/index.test.js +0 -5
  38. package/test/src/functions.test.js +0 -45
  39. package/test/src/index.test.js +0 -5
  40. package/test/src/models.test.js +0 -380
  41. package/test/src/serialization.test.js +0 -127
@@ -1,9 +1,10 @@
1
- const assert = require('chai').assert
2
- const sinon = require('sinon')
3
- const {
1
+ import { assert } from 'chai'
2
+ import sinon from 'sinon'
3
+ import {
4
4
  UniqueId,
5
5
  Property,
6
6
  DateProperty,
7
+ BooleanProperty,
7
8
  ReferenceProperty,
8
9
  ArrayProperty,
9
10
  ConstantValueProperty,
@@ -12,16 +13,19 @@ const {
12
13
  TextProperty,
13
14
  IntegerProperty,
14
15
  EmailProperty,
15
- } = require('../../src/properties')
16
- const { TYPE_PRIMATIVES, arrayType } = require('../../src/validation')
17
- const { Model } = require('../../src/models')
16
+ } from '../../src/properties'
17
+ import { TYPE_PRIMITIVES, arrayType } from '../../src/validation'
18
+ import { BaseModel } from '../../src/models'
19
+ import { ModelInstance } from '../../src/interfaces'
18
20
 
19
- const TestModel1 = Model('TestModel1', {
20
- id: UniqueId(),
21
- name: TextProperty(),
21
+ type TestModelType = { name: string }
22
+ const TestModel1 = BaseModel<TestModelType>('TestModel1', {
23
+ properties: {
24
+ name: TextProperty(),
25
+ },
22
26
  })
23
27
 
24
- describe('/src/properties.js', () => {
28
+ describe('/src/properties.ts', () => {
25
29
  describe('#EmailProperty()', () => {
26
30
  describe('#createGetter()', () => {
27
31
  it('should be able to create without a config', () => {
@@ -42,7 +46,26 @@ describe('/src/properties.js', () => {
42
46
  const PropertyInstance = EmailProperty({})
43
47
  const getter = PropertyInstance.createGetter('testme@email.com')
44
48
  const validator = PropertyInstance.getValidator(getter)
45
- const actual = await validator()
49
+ // @ts-ignore
50
+ const actual = await validator(null, {})
51
+ const expected = 0
52
+ assert.equal(actual.length, expected)
53
+ })
54
+ })
55
+ })
56
+ describe('#BooleanProperty()', () => {
57
+ it('should be able to create without a config', () => {
58
+ assert.doesNotThrow(() => {
59
+ BooleanProperty()
60
+ })
61
+ })
62
+ describe('#getValidator()', () => {
63
+ it('should return and validate successful with basic input', async () => {
64
+ const PropertyInstance = BooleanProperty({})
65
+ const getter = PropertyInstance.createGetter(true)
66
+ const validator = PropertyInstance.getValidator(getter)
67
+ // @ts-ignore
68
+ const actual = await validator(null, {})
46
69
  const expected = 0
47
70
  assert.equal(actual.length, expected)
48
71
  })
@@ -63,7 +86,8 @@ describe('/src/properties.js', () => {
63
86
  const PropertyInstance = ConstantValueProperty('constant')
64
87
  const getter = PropertyInstance.createGetter('changed')
65
88
  const validator = PropertyInstance.getValidator(getter)
66
- const actual = await validator()
89
+ // @ts-ignore
90
+ const actual = await validator(null, {})
67
91
  const expected = 0
68
92
  assert.equal(actual.length, expected)
69
93
  })
@@ -95,7 +119,8 @@ describe('/src/properties.js', () => {
95
119
  complex: { it: 'is' },
96
120
  })
97
121
  const validator = PropertyInstance.getValidator(getter)
98
- const actual = await validator()
122
+ // @ts-ignore
123
+ const actual = await validator(null, {})
99
124
  const expected = 0
100
125
  assert.equal(actual.length, expected)
101
126
  })
@@ -109,6 +134,12 @@ describe('/src/properties.js', () => {
109
134
  NumberProperty()
110
135
  })
111
136
  })
137
+ it('should be able to create even with a null config', () => {
138
+ assert.doesNotThrow(() => {
139
+ // @ts-ignore
140
+ NumberProperty(null)
141
+ })
142
+ })
112
143
  it('should be able to get the number passed in', async () => {
113
144
  const PropertyInstance = NumberProperty({})
114
145
  const getter = PropertyInstance.createGetter(5)
@@ -129,7 +160,8 @@ describe('/src/properties.js', () => {
129
160
  const PropertyInstance = NumberProperty({})
130
161
  const getter = PropertyInstance.createGetter(5)
131
162
  const validator = PropertyInstance.getValidator(getter)
132
- const actual = await validator()
163
+ // @ts-ignore
164
+ const actual = await validator(null, {})
133
165
  const expected = 0
134
166
  assert.equal(actual.length, expected)
135
167
  })
@@ -137,15 +169,18 @@ describe('/src/properties.js', () => {
137
169
  const PropertyInstance = NumberProperty({})
138
170
  const getter = PropertyInstance.createGetter(5.123)
139
171
  const validator = PropertyInstance.getValidator(getter)
140
- const actual = await validator()
172
+ // @ts-ignore
173
+ const actual = await validator(null, {})
141
174
  const expected = 0
142
175
  assert.equal(actual.length, expected)
143
176
  })
144
177
  it('should return with errors with a non integer input', async () => {
145
178
  const PropertyInstance = NumberProperty({})
179
+ // @ts-ignore
146
180
  const getter = PropertyInstance.createGetter('string')
147
181
  const validator = PropertyInstance.getValidator(getter)
148
- const actual = await validator()
182
+ // @ts-ignore
183
+ const actual = await validator(null, {})
149
184
  const expected = 1
150
185
  assert.equal(actual.length, expected)
151
186
  })
@@ -153,6 +188,7 @@ describe('/src/properties.js', () => {
153
188
  const PropertyInstance = NumberProperty({ maxValue: 3 })
154
189
  const getter = PropertyInstance.createGetter(5)
155
190
  const validator = PropertyInstance.getValidator(getter)
191
+ // @ts-ignore
156
192
  const actual = await validator()
157
193
  const expected = 1
158
194
  assert.equal(actual.length, expected)
@@ -161,6 +197,7 @@ describe('/src/properties.js', () => {
161
197
  const PropertyInstance = NumberProperty({ minValue: 3 })
162
198
  const getter = PropertyInstance.createGetter(2)
163
199
  const validator = PropertyInstance.getValidator(getter)
200
+ // @ts-ignore
164
201
  const actual = await validator()
165
202
  const expected = 1
166
203
  assert.equal(actual.length, expected)
@@ -169,6 +206,7 @@ describe('/src/properties.js', () => {
169
206
  const PropertyInstance = NumberProperty({ minValue: 3, maxValue: 3 })
170
207
  const getter = PropertyInstance.createGetter(3)
171
208
  const validator = PropertyInstance.getValidator(getter)
209
+ // @ts-ignore
172
210
  const actual = await validator()
173
211
  const expected = 0
174
212
  assert.equal(actual.length, expected)
@@ -177,6 +215,12 @@ describe('/src/properties.js', () => {
177
215
  })
178
216
 
179
217
  describe('#IntegerProperty()', () => {
218
+ it('should be able to create even with a null config', () => {
219
+ assert.doesNotThrow(() => {
220
+ // @ts-ignore
221
+ IntegerProperty(null)
222
+ })
223
+ })
180
224
  describe('#createGetter()', () => {
181
225
  it('should be able to create without a config', () => {
182
226
  assert.doesNotThrow(() => {
@@ -196,6 +240,7 @@ describe('/src/properties.js', () => {
196
240
  const PropertyInstance = IntegerProperty({})
197
241
  const getter = PropertyInstance.createGetter(5)
198
242
  const validator = PropertyInstance.getValidator(getter)
243
+ // @ts-ignore
199
244
  const actual = await validator()
200
245
  const expected = 0
201
246
  assert.equal(actual.length, expected)
@@ -204,14 +249,17 @@ describe('/src/properties.js', () => {
204
249
  const PropertyInstance = IntegerProperty({})
205
250
  const getter = PropertyInstance.createGetter(5.123)
206
251
  const validator = PropertyInstance.getValidator(getter)
252
+ // @ts-ignore
207
253
  const actual = await validator()
208
254
  const expected = 1
209
255
  assert.equal(actual.length, expected)
210
256
  })
211
257
  it('should return with errors with a non integer input', async () => {
212
258
  const PropertyInstance = IntegerProperty({})
259
+ // @ts-ignore
213
260
  const getter = PropertyInstance.createGetter('string')
214
261
  const validator = PropertyInstance.getValidator(getter)
262
+ // @ts-ignore
215
263
  const actual = await validator()
216
264
  const expected = 1
217
265
  assert.equal(actual.length, expected)
@@ -220,6 +268,7 @@ describe('/src/properties.js', () => {
220
268
  const PropertyInstance = IntegerProperty({ maxValue: 3 })
221
269
  const getter = PropertyInstance.createGetter(5)
222
270
  const validator = PropertyInstance.getValidator(getter)
271
+ // @ts-ignore
223
272
  const actual = await validator()
224
273
  const expected = 1
225
274
  assert.equal(actual.length, expected)
@@ -228,6 +277,7 @@ describe('/src/properties.js', () => {
228
277
  const PropertyInstance = IntegerProperty({ minValue: 3 })
229
278
  const getter = PropertyInstance.createGetter(2)
230
279
  const validator = PropertyInstance.getValidator(getter)
280
+ // @ts-ignore
231
281
  const actual = await validator()
232
282
  const expected = 1
233
283
  assert.equal(actual.length, expected)
@@ -236,6 +286,7 @@ describe('/src/properties.js', () => {
236
286
  const PropertyInstance = IntegerProperty({ minValue: 3, maxValue: 3 })
237
287
  const getter = PropertyInstance.createGetter(3)
238
288
  const validator = PropertyInstance.getValidator(getter)
289
+ // @ts-ignore
239
290
  const actual = await validator()
240
291
  const expected = 0
241
292
  assert.equal(actual.length, expected)
@@ -244,6 +295,12 @@ describe('/src/properties.js', () => {
244
295
  })
245
296
 
246
297
  describe('#TextProperty()', () => {
298
+ it('should be able to create even with a null config', () => {
299
+ assert.doesNotThrow(() => {
300
+ // @ts-ignore
301
+ TextProperty(null)
302
+ })
303
+ })
247
304
  describe('#createGetter()', () => {
248
305
  it('should be able to create without a config', () => {
249
306
  assert.doesNotThrow(() => {
@@ -263,14 +320,17 @@ describe('/src/properties.js', () => {
263
320
  const PropertyInstance = TextProperty({})
264
321
  const getter = PropertyInstance.createGetter('basic input')
265
322
  const validator = PropertyInstance.getValidator(getter)
323
+ // @ts-ignore
266
324
  const actual = await validator()
267
325
  const expected = 0
268
326
  assert.equal(actual.length, expected)
269
327
  })
270
328
  it('should return with errors with a value=5', async () => {
271
329
  const PropertyInstance = TextProperty({})
330
+ // @ts-ignore
272
331
  const getter = PropertyInstance.createGetter(5)
273
332
  const validator = PropertyInstance.getValidator(getter)
333
+ // @ts-ignore
274
334
  const actual = await validator()
275
335
  const expected = 1
276
336
  assert.equal(actual.length, expected)
@@ -279,6 +339,7 @@ describe('/src/properties.js', () => {
279
339
  const PropertyInstance = TextProperty({ maxLength: 3 })
280
340
  const getter = PropertyInstance.createGetter('hello')
281
341
  const validator = PropertyInstance.getValidator(getter)
342
+ // @ts-ignore
282
343
  const actual = await validator()
283
344
  const expected = 1
284
345
  assert.equal(actual.length, expected)
@@ -287,6 +348,7 @@ describe('/src/properties.js', () => {
287
348
  const PropertyInstance = TextProperty({ minLength: 10 })
288
349
  const getter = PropertyInstance.createGetter('hello')
289
350
  const validator = PropertyInstance.getValidator(getter)
351
+ // @ts-ignore
290
352
  const actual = await validator()
291
353
  const expected = 1
292
354
  assert.equal(actual.length, expected)
@@ -295,6 +357,7 @@ describe('/src/properties.js', () => {
295
357
  const PropertyInstance = TextProperty({ minLength: 5, maxLength: 5 })
296
358
  const getter = PropertyInstance.createGetter('hello')
297
359
  const validator = PropertyInstance.getValidator(getter)
360
+ // @ts-ignore
298
361
  const actual = await validator()
299
362
  const expected = 0
300
363
  assert.equal(actual.length, expected)
@@ -320,13 +383,15 @@ describe('/src/properties.js', () => {
320
383
  })
321
384
  it('should return an empty array if defaultValue is not changed in config and null is passed', async () => {
322
385
  const theProperty = ArrayProperty()
386
+ // @ts-ignore
323
387
  const getter = theProperty.createGetter(null)
324
388
  const actual = await getter()
325
- const expected = []
389
+ const expected: any[] = []
326
390
  assert.deepEqual(actual, expected)
327
391
  })
328
392
  it('should return the passed in defaultValue if set in config and null is passed', async () => {
329
393
  const theProperty = ArrayProperty({ defaultValue: [1, 2, 3] })
394
+ // @ts-ignore
330
395
  const getter = theProperty.createGetter(null)
331
396
  const actual = await getter()
332
397
  const expected = [1, 2, 3]
@@ -338,16 +403,18 @@ describe('/src/properties.js', () => {
338
403
  const theProperty = ArrayProperty({})
339
404
  const getter = theProperty.createGetter([1, 2, 3])
340
405
  const validator = theProperty.getValidator(getter)
406
+ // @ts-ignore
341
407
  const actual = await validator()
342
- const expected = []
408
+ const expected: any[] = []
343
409
  assert.deepEqual(actual, expected)
344
410
  })
345
411
  it('should error an array passed in when it doesnt have the right types', async () => {
346
412
  const theProperty = ArrayProperty({
347
- validators: [arrayType(TYPE_PRIMATIVES.integer)],
413
+ validators: [arrayType(TYPE_PRIMITIVES.integer)],
348
414
  })
349
415
  const getter = theProperty.createGetter([1, 'string', 3])
350
416
  const validator = theProperty.getValidator(getter)
417
+ // @ts-ignore
351
418
  const actual = await validator()
352
419
  const expected = 1
353
420
  assert.deepEqual(actual.length, expected)
@@ -356,14 +423,16 @@ describe('/src/properties.js', () => {
356
423
  const theProperty = ArrayProperty({ choices: [4, 5, 6] })
357
424
  const getter = theProperty.createGetter([4, 4, 5, 5, 6, 6])
358
425
  const validator = theProperty.getValidator(getter)
426
+ // @ts-ignore
359
427
  const actual = await validator()
360
- const expected = []
428
+ const expected: any[] = []
361
429
  assert.deepEqual(actual, expected)
362
430
  })
363
431
  it('should return errors when an array with [4,4,3,5,5,6,6] when choices are [4,5,6]', async () => {
364
432
  const theProperty = ArrayProperty({ choices: [4, 5, 6] })
365
433
  const getter = theProperty.createGetter([4, 4, 3, 5, 5, 6, 6])
366
434
  const validator = theProperty.getValidator(getter)
435
+ // @ts-ignore
367
436
  const actual = await validator()
368
437
  const expected = 1
369
438
  assert.equal(actual.length, expected)
@@ -371,8 +440,21 @@ describe('/src/properties.js', () => {
371
440
  })
372
441
  })
373
442
  describe('#Property()', () => {
443
+ it('should throw an exception if a type is not provided', () => {
444
+ assert.throws(() => {
445
+ // @ts-ignore
446
+ Property(undefined, {})
447
+ })
448
+ })
449
+ it('should throw an exception if a type is not provided, and config is null', () => {
450
+ assert.throws(() => {
451
+ // @ts-ignore
452
+ Property(undefined, null)
453
+ })
454
+ })
374
455
  it('should throw an exception if config.valueSelector is not a function but is set', () => {
375
456
  assert.throws(() => {
457
+ // @ts-ignore
376
458
  Property('MyProperty', { valueSelector: 'blah' })
377
459
  })
378
460
  })
@@ -381,6 +463,77 @@ describe('/src/properties.js', () => {
381
463
  Property('MyProperty', { valueSelector: () => ({}) })
382
464
  })
383
465
  })
466
+ it('should not throw an exception if config is null', () => {
467
+ assert.doesNotThrow(() => {
468
+ // @ts-ignore
469
+ Property('MyProperty', null)
470
+ })
471
+ })
472
+ describe('#getConstantValue()', () => {
473
+ it('should provide undefined if no config', () => {
474
+ // @ts-ignore
475
+ const instance = Property('MyTYpe', null)
476
+ const actual = instance.getConstantValue()
477
+ const expected = undefined
478
+ assert.deepEqual(actual, expected)
479
+ })
480
+ })
481
+ describe('#getPropertyType()', () => {
482
+ it('should use the type that is passed in via config', () => {
483
+ const instance = Property('OverrideMe', { type: 'ExtendedType' })
484
+ const actual = instance.getPropertyType()
485
+ const expected = 'ExtendedType'
486
+ assert.equal(actual, expected)
487
+ })
488
+ })
489
+ describe('#getConfig()', () => {
490
+ it('should provide the config that is passed in ', () => {
491
+ // @ts-ignore
492
+ const instance = Property('MyTYpe', { custom: 'value' })
493
+ const actual = instance.getConfig()
494
+ const expected = { custom: 'value' }
495
+ assert.deepEqual(actual, expected)
496
+ })
497
+ it('should provide {} if no config', () => {
498
+ // @ts-ignore
499
+ const instance = Property('MyTYpe', null)
500
+ const actual = instance.getConfig()
501
+ const expected = {}
502
+ assert.deepEqual(actual, expected)
503
+ })
504
+ })
505
+ describe('#getDefaultValue()', () => {
506
+ it('should provide undefined if no config', () => {
507
+ // @ts-ignore
508
+ const instance = Property('MyTYpe', null)
509
+ const actual = instance.getDefaultValue()
510
+ const expected = undefined
511
+ assert.deepEqual(actual, expected)
512
+ })
513
+ it('should provide the defaultValue that is passed in if no value', () => {
514
+ // @ts-ignore
515
+ const instance = Property('MyTYpe', { defaultValue: 'test-me' })
516
+ const actual = instance.getDefaultValue()
517
+ const expected = 'test-me'
518
+ assert.deepEqual(actual, expected)
519
+ })
520
+ })
521
+ describe('#getChoices()', () => {
522
+ it('should provide [] if no config', () => {
523
+ // @ts-ignore
524
+ const instance = Property('MyTYpe', null)
525
+ const actual = instance.getChoices()
526
+ const expected: any[] = []
527
+ assert.deepEqual(actual, expected)
528
+ })
529
+ it('should provide the choices that are passed in ', () => {
530
+ // @ts-ignore
531
+ const instance = Property('MyTYpe', { choices: [1, 2, 3] })
532
+ const actual = instance.getChoices()
533
+ const expected = [1, 2, 3]
534
+ assert.deepEqual(actual, expected)
535
+ })
536
+ })
384
537
  describe('#createGetter()', () => {
385
538
  it('should return a function even if config.value is set to a value', () => {
386
539
  const instance = Property('MyProperty', { value: 'my-value' })
@@ -411,7 +564,8 @@ describe('/src/properties.js', () => {
411
564
  describe('#createGetter()', () => {
412
565
  it('should call createUuid only once even if called twice', async () => {
413
566
  const uniqueProperty = UniqueId({})
414
- const getter = uniqueProperty.createGetter()
567
+ // @ts-ignore
568
+ const getter = uniqueProperty.createGetter(undefined)
415
569
  const first = await getter()
416
570
  const second = await getter()
417
571
  assert.deepEqual(first, second)
@@ -428,12 +582,12 @@ describe('/src/properties.js', () => {
428
582
  describe('#DateProperty()', () => {
429
583
  it('should allow creation without a config', async () => {
430
584
  const proto = DateProperty()
431
- const instance = proto.createGetter('my-date')
585
+ const instance = proto.createGetter(new Date())
432
586
  assert.isOk(await instance())
433
587
  })
434
588
  it('should create a new date once when config.autoNow=true and called multiple times', async () => {
435
589
  const proto = DateProperty({ autoNow: true })
436
- const instance = proto.createGetter()
590
+ const instance = proto.createGetter(undefined)
437
591
  const first = await instance()
438
592
  const second = await instance()
439
593
  const third = await instance()
@@ -448,103 +602,142 @@ describe('/src/properties.js', () => {
448
602
  const expected = date
449
603
  assert.deepEqual(actual, expected)
450
604
  })
605
+ it('should return null, if null config is passed and no value created.', async () => {
606
+ // @ts-ignore
607
+ const proto = DateProperty(null)
608
+ const date = null
609
+ const instance = proto.createGetter(date)
610
+ const actual = await instance()
611
+ const expected = null
612
+ assert.deepEqual(actual, expected)
613
+ })
451
614
  })
452
615
 
453
616
  describe('#ReferenceProperty()', () => {
454
617
  it('should throw an exception if a model value is not passed in', () => {
455
618
  assert.throws(() => {
456
619
  const input = ['obj-id']
620
+ // @ts-ignore
457
621
  const actual = ReferenceProperty(null, {})
458
622
  })
459
623
  })
460
624
  describe('#meta.getReferencedModel()', () => {
461
625
  it('should return the same value passed in as the model', async () => {
462
626
  const property = ReferenceProperty(TestModel1)
463
- const actual = property.meta.getReferencedModel()
627
+ const actual = property.getReferencedModel()
464
628
  const expected = TestModel1
465
629
  assert.deepEqual(actual, expected)
466
630
  })
467
631
  it('should allow a function input for model to allow delayed creation', async () => {
468
632
  const property = ReferenceProperty(() => TestModel1)
469
- const actual = property.meta.getReferencedModel()
633
+ const actual = property.getReferencedModel()
470
634
  const expected = TestModel1
471
635
  assert.deepEqual(actual, expected)
472
636
  })
473
637
  })
474
638
  describe('#createGetter()', () => {
475
639
  it('should return "obj-id" when no fetcher is used', async () => {
476
- const input = ['obj-id']
477
640
  const actual = await ReferenceProperty(TestModel1, {}).createGetter(
478
- ...input
641
+ 'obj-id'
479
642
  )()
480
643
  const expected = 'obj-id'
481
644
  assert.equal(actual, expected)
482
645
  })
483
646
  it('should allow null as the input', async () => {
484
- const input = [null]
485
647
  const actual = await ReferenceProperty(TestModel1, {}).createGetter(
486
- ...input
648
+ null
487
649
  )()
488
650
  const expected = null
489
651
  assert.equal(actual, expected)
490
652
  })
491
653
  it('should return "obj-id" from {}.id when no fetcher is used', async () => {
492
- const input = [{ id: 'obj-id' }]
493
654
  const actual = await ReferenceProperty(TestModel1, {}).createGetter(
494
- ...input
655
+ // @ts-ignore
656
+ { id: 'obj-id' }
495
657
  )()
496
658
  const expected = 'obj-id'
497
659
  assert.equal(actual, expected)
498
660
  })
661
+ it('should return 123 from {}.id when no fetcher is used', async () => {
662
+ const actual = await ReferenceProperty(TestModel1, {}).createGetter(
663
+ 123
664
+ )()
665
+ const expected = 123
666
+ assert.equal(actual, expected)
667
+ })
499
668
  it('should return name:"switch-a-roo" when switch-a-roo fetcher is used', async () => {
500
- const input = ['obj-id']
501
- const actual = await ReferenceProperty(TestModel1, {
502
- fetcher: () => ({ id: 'obj-id', name: 'switch-a-roo' }),
503
- }).createGetter(...input)()
669
+ const actual = (await ReferenceProperty(TestModel1, {
670
+ fetcher: async () => ({ id: 'obj-id', name: 'switch-a-roo' }),
671
+ }).createGetter('obj-id')()) as ModelInstance<TestModelType>
504
672
  const expected = 'switch-a-roo'
505
- assert.deepEqual(await actual.getName(), expected)
673
+ assert.deepEqual(actual.get.name(), expected)
674
+ })
675
+ it('should return "obj-id" if no config passed', async () => {
676
+ // @ts-ignore
677
+ const actual = (await ReferenceProperty(TestModel1, null).createGetter(
678
+ 'obj-id'
679
+ )()) as string
680
+ const expected = 'obj-id'
681
+ assert.deepEqual(actual, expected)
682
+ })
683
+ it('should return null when fetcher is used, but the instance value passed in is empty', async () => {
684
+ const actual = (await ReferenceProperty(TestModel1, {
685
+ fetcher: async () => ({ id: 'obj-id', name: 'switch-a-roo' }),
686
+ }).createGetter(null)()) as ModelInstance<TestModelType>
687
+ const expected = null
688
+ assert.deepEqual(actual, expected)
506
689
  })
507
690
  it('should provide the passed in model and the instance values when switch-a-roo fetcher is used', async () => {
508
- const input = ['obj-id']
691
+ const input = 'obj-id'
509
692
  const fetcher = sinon.stub().callsFake((modelName, id) => ({ id }))
510
693
  await ReferenceProperty(TestModel1, {
511
694
  fetcher,
512
- }).createGetter(...input)()
695
+ }).createGetter(input)()
513
696
  const actual = fetcher.getCall(0).args[0]
514
697
  const expected = TestModel1
515
698
  assert.deepEqual(actual, expected)
516
699
  })
517
700
  it('should take the smartObject as a value', async () => {
518
- const proto = Model('name', {
519
- id: UniqueId({ value: 'obj-id' }),
701
+ const id = 'obj-id'
702
+ const proto = BaseModel<TestModelType>('name', {
703
+ properties: {
704
+ id: UniqueId({ value: id }),
705
+ name: TextProperty({}),
706
+ },
520
707
  })
521
- const input = [proto.create({ id: 'obj-id' })]
522
- const instance = await ReferenceProperty(TestModel1, {}).createGetter(
523
- ...input
524
- )()
525
- const actual = await instance.getId()
708
+ const input = proto.create({ id, name: 'name' })
709
+ const instance = (await ReferenceProperty<TestModelType>(
710
+ TestModel1,
711
+ {}
712
+ ).createGetter(input)()) as ModelInstance<TestModelType>
713
+ const actual = await instance.get.id()
526
714
  const expected = 'obj-id'
527
715
  assert.deepEqual(actual, expected)
528
716
  })
529
- describe('#functions.toObj()', () => {
717
+ describe('#toObj()', () => {
530
718
  it('should use the getId of the smartObject passed in when toObj is called', async () => {
531
- const proto = Model('name', {
532
- id: UniqueId({ value: 'obj-id' }),
719
+ const proto = BaseModel<TestModelType>('name', {
720
+ properties: {
721
+ id: UniqueId({ value: 'obj-id' }),
722
+ name: TextProperty({}),
723
+ },
533
724
  })
534
- const input = [proto.create({ id: 'obj-id' })]
535
- const instance = await ReferenceProperty(TestModel1, {}).createGetter(
536
- ...input
537
- )()
538
- const actual = await instance.functions.toObj()
725
+ const input = proto.create({ id: 'obj-id', name: 'name' })
726
+ const instance = (await ReferenceProperty<TestModelType>(
727
+ TestModel1,
728
+ {}
729
+ ).createGetter(input)()) as ModelInstance<{}>
730
+ const actual = await instance.toObj()
539
731
  const expected = 'obj-id'
540
732
  assert.deepEqual(actual, expected)
541
733
  })
542
734
  it('should return "obj-id" when switch-a-roo fetcher is used and toObj is called', async () => {
543
- const input = ['obj-id']
544
- const instance = await ReferenceProperty(TestModel1, {
545
- fetcher: () => ({ id: 'obj-id', prop: 'switch-a-roo' }),
546
- }).createGetter(...input)()
547
- const actual = await instance.functions.toObj()
735
+ const input = 'obj-id'
736
+ const instance = (await ReferenceProperty(TestModel1, {
737
+ fetcher: () =>
738
+ Promise.resolve({ id: 'obj-id', prop: 'switch-a-roo' }),
739
+ }).createGetter(input)()) as ModelInstance<{}>
740
+ const actual = await instance.toObj()
548
741
  const expected = 'obj-id'
549
742
  assert.deepEqual(actual, expected)
550
743
  })