functional-models 1.0.9 → 1.0.10

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.
package/README.md CHANGED
@@ -10,29 +10,36 @@ This library empowers the creation of pure JavaScript function based models that
10
10
  ## Example Usage
11
11
 
12
12
  const {
13
- smartObject,
14
- property,
15
- typed,
13
+ field,
14
+ constantValueField,
15
+ textField,
16
+ dateField,
17
+ integerField,
16
18
  uniqueId,
19
+ createModel,
20
+ validation,
17
21
  }= require('functional-models')
18
22
 
19
- const Truck = ({ id, make, model, color, year }) => smartObject([
20
- uniqueId(id),
21
- typed('truck'),
22
- property('make', make),
23
- property('model', model),
24
- property('color', color),
25
- property('year', year),
26
- ])
23
+ const Truck = createModel({
24
+ type: constantValueField('truck'),
25
+ id: uniqueId({required: true}),
26
+ make: textField({ maxLength: 20, minLength: 3, required: true}),
27
+ model: textField({ maxLength: 20, minLength: 3, required: true}),
28
+ color: textField({ maxLength: 10, minLength: 3, validators: [
29
+ validation.meetsRegex(/Red/),
30
+ ]}),
31
+ year: integerField({ maxValue: 2500, minValue: 1900}),
32
+ lastModified: dateField({ autoNow: true}),
33
+ })
27
34
 
28
35
 
29
36
  const myTruck = Truck({ make: 'Ford', model: 'F-150', color: 'White', year: 2013})
30
37
 
31
- console.log(myTruck.getId()) // a random uuid
32
- console.log(myTruck.getMake()) // 'Ford'
33
- console.log(myTruck.getModel()) // 'F-150'
34
- console.log(myTruck.getColor()) // 'White'
35
- console.log(myTruck.getYear()) // 2013
38
+ console.log(await myTruck.getId()) // a random uuid
39
+ console.log(await myTruck.getMake()) // 'Ford'
40
+ console.log(await myTruck.getModel()) // 'F-150'
41
+ console.log(await myTruck.getColor()) // 'White'
42
+ console.log(await myTruck.getYear()) // 2013
36
43
 
37
44
  const asJson = await myTruck.functions.toJson()
38
45
  console.log(asJson)
@@ -47,8 +54,19 @@ This library empowers the creation of pure JavaScript function based models that
47
54
  */
48
55
 
49
56
  const sameTruck = Truck(asJson)
50
- console.log(sameTruck.getId()) // same uuid as above
51
- console.log(sameTruck.getMake()) // 'Ford'
52
- console.log(sameTruck.getModel()) // 'F-150'
53
- console.log(sameTruck.getColor()) // 'White'
54
- console.log(sameTruck.getYear()) // 2013
57
+ console.log(await sameTruck.getId()) // same uuid as above
58
+ console.log(await sameTruck.getMake()) // 'Ford'
59
+ console.log(await sameTruck.getModel()) // 'F-150'
60
+ console.log(await sameTruck.getColor()) // 'White'
61
+ console.log(await sameTruck.getYear()) // 2013
62
+
63
+ // Validation
64
+ const errors = await sameTruck.functions.validate.model() // {}
65
+
66
+ const newTruck = Truck({ make: 'Ford', model: 'F-150', color: 'White', year: 20130})
67
+ const errors2 = await newTruck.functions.validate.model()
68
+ console.log(errors2)
69
+ // {"year": 'Value is too long'}
70
+
71
+
72
+
@@ -4,24 +4,24 @@ const { Given, When, Then } = require('@cucumber/cucumber')
4
4
  const { createModel, field, arrayField, validation } = require('../../index')
5
5
 
6
6
  const MODEL_DEFINITIONS = {
7
- TestModel1: createModel({
7
+ TestModel1: createModel("TestModel1", {
8
8
  name: field({ required: true }),
9
9
  type: field({ required: true, isString: true }),
10
10
  flag: field({ required: true, isNumber: true }),
11
11
  }),
12
- ArrayModel1: createModel({
12
+ ArrayModel1: createModel("ArrayModel1", {
13
13
  arrayField: field({
14
14
  isArray: true,
15
15
  validators: [validation.arrayType(validation.TYPE_PRIMATIVES.integer)],
16
16
  }),
17
17
  }),
18
- ArrayModel2: createModel({
18
+ ArrayModel2: createModel("ArrayModel2", {
19
19
  arrayField: field({ isArray: true }),
20
20
  }),
21
- ArrayModel3: createModel({
21
+ ArrayModel3: createModel("ArrayModel3", {
22
22
  arrayField: arrayField({}),
23
23
  }),
24
- ArrayModel4: createModel({
24
+ ArrayModel4: createModel("ArrayModel4", {
25
25
  arrayField: arrayField({
26
26
  choices: [4, 5, 6],
27
27
  validators: [validation.arrayType(validation.TYPE_PRIMATIVES.integer)],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "functional-models",
3
- "version": "1.0.9",
3
+ "version": "1.0.10",
4
4
  "description": "A library for creating JavaScript function based models.",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -29,6 +29,7 @@
29
29
  "nyc": {
30
30
  "all": true,
31
31
  "exclude": [
32
+ "coverage/",
32
33
  "features/stepDefinitions/*",
33
34
  "test/*"
34
35
  ]
package/src/fields.js CHANGED
@@ -53,9 +53,11 @@ const field = (config = {}) => {
53
53
  }
54
54
  },
55
55
  getValidator: valueGetter => {
56
- return async () => {
57
- return createFieldValidator(config)(await valueGetter())
56
+ const validator = createFieldValidator(config)
57
+ const _fieldValidatorWrapper = async () => {
58
+ return validator(await valueGetter())
58
59
  }
60
+ return _fieldValidatorWrapper
59
61
  },
60
62
  }
61
63
  }
@@ -101,7 +103,7 @@ const referenceField = config => {
101
103
  ...objToUse,
102
104
  functions: {
103
105
  ...(objToUse.functions ? objToUse.functions : {}),
104
- toJson: _getId,
106
+ toObj: _getId,
105
107
  },
106
108
  }
107
109
  }
package/src/models.js CHANGED
@@ -1,29 +1,36 @@
1
1
  const merge = require('lodash/merge')
2
- const get = require('lodash/get')
3
- const { toJson } = require('./serialization')
2
+ const pickBy = require('lodash/pickBy')
3
+ const { toObj } = require('./serialization')
4
4
  const { createPropertyTitle } = require('./utils')
5
5
  const { createModelValidator } = require('./validation')
6
6
 
7
- const SYSTEM_KEYS = ['meta', 'functions']
8
-
7
+ const MODEL_DEF_KEYS = ['meta', 'functions']
9
8
  const PROTECTED_KEYS = ['model']
10
9
 
11
- const createModel = keyToField => {
10
+ const createModel = (modelName, keyToField) => {
12
11
  PROTECTED_KEYS.forEach(key => {
13
12
  if (key in keyToField) {
14
13
  throw new Error(`Cannot use ${key}. This is a protected value.`)
15
14
  }
16
15
  })
17
- const systemProperties = SYSTEM_KEYS.reduce((acc, key) => {
18
- const value = get(keyToField, key, {})
19
- return { ...acc, [key]: value }
16
+ const fieldProperties = Object.entries(keyToField).filter(
17
+ ([key, _]) => !(key in MODEL_DEF_KEYS)
18
+ )
19
+ const fields = fieldProperties.reduce((acc, [key, field]) => {
20
+ return { ...acc, [key]: field }
20
21
  }, {})
21
- const nonSystemProperties = Object.entries(keyToField).filter(
22
- ([key, _]) => !(key in SYSTEM_KEYS)
22
+ const modelDefProperties = merge(
23
+ pickBy(keyToField, (value, key) => MODEL_DEF_KEYS.includes(key)),
24
+ {
25
+ meta: {
26
+ fields,
27
+ modelName,
28
+ },
29
+ }
23
30
  )
24
31
 
25
- return (instanceValues={}) => {
26
- const loadedInternals = nonSystemProperties.reduce((acc, [key, field]) => {
32
+ return (instanceValues = {}) => {
33
+ const loadedInternals = fieldProperties.reduce((acc, [key, field]) => {
27
34
  const fieldGetter = field.createGetter(instanceValues[key])
28
35
  const fieldValidator = field.getValidator(fieldGetter)
29
36
  const getFieldKey = createPropertyTitle(key)
@@ -37,16 +44,15 @@ const createModel = keyToField => {
37
44
  }
38
45
  return merge(acc, fleshedOutField)
39
46
  }, {})
40
- const allUserData = merge(systemProperties, loadedInternals)
41
- const internalFunctions = {
47
+ const frameworkProperties = {
42
48
  functions: {
43
- toJson: toJson(loadedInternals),
49
+ toObj: toObj(loadedInternals),
44
50
  validate: {
45
51
  model: createModelValidator(loadedInternals),
46
52
  },
47
53
  },
48
54
  }
49
- return merge(allUserData, internalFunctions)
55
+ return merge(loadedInternals, modelDefProperties, frameworkProperties)
50
56
  }
51
57
  }
52
58
 
@@ -12,8 +12,8 @@ const _getValue = async value => {
12
12
  return _getValue(await value())
13
13
  }
14
14
  // Nested Json
15
- if (type === 'object' && value.functions && value.functions.toJson) {
16
- return _getValue(await value.functions.toJson())
15
+ if (type === 'object' && value.functions && value.functions.toObj) {
16
+ return _getValue(await value.functions.toObj())
17
17
  }
18
18
  // Dates
19
19
  if (type === 'object' && value.toISOString) {
@@ -30,7 +30,7 @@ const _shouldIgnoreKey = key => {
30
30
  return IGNORABLE_KEYS.includes(key)
31
31
  }
32
32
 
33
- const toJson = keyToFunc => async () => {
33
+ const toObj = keyToFunc => async () => {
34
34
  return Object.entries(keyToFunc).reduce(async (acc, [key, value]) => {
35
35
  const realAcc = await acc
36
36
  if (_shouldIgnoreKey(key)) {
@@ -43,5 +43,5 @@ const toJson = keyToFunc => async () => {
43
43
  }
44
44
 
45
45
  module.exports = {
46
- toJson,
46
+ toObj,
47
47
  }
package/src/utils.js CHANGED
@@ -6,7 +6,7 @@ const toTitleCase = string => {
6
6
  return `${string.slice(0, 1).toUpperCase()}${string.slice(1)}`
7
7
  }
8
8
 
9
- const createPropertyTitle = key => {
9
+ const createFieldTitle = key => {
10
10
  const goodName = toTitleCase(key)
11
11
  return `get${goodName}`
12
12
  }
@@ -37,6 +37,6 @@ const loweredTitleCase = string => {
37
37
  module.exports = {
38
38
  createUuid,
39
39
  loweredTitleCase,
40
- createPropertyTitle,
40
+ createPropertyTitle: createFieldTitle,
41
41
  toTitleCase,
42
42
  }
package/src/validation.js CHANGED
@@ -130,16 +130,20 @@ const minTextLength = min => value => {
130
130
  return undefined
131
131
  }
132
132
 
133
- const aggregateValidator = methodOrMethods => async value => {
133
+ const aggregateValidator = methodOrMethods => {
134
134
  const toDo = Array.isArray(methodOrMethods)
135
135
  ? methodOrMethods
136
136
  : [methodOrMethods]
137
- const values = await Promise.all(
138
- toDo.map(method => {
139
- return method(value)
140
- })
141
- )
142
- return values.filter(x => x)
137
+
138
+ const _aggregativeValidator = async value => {
139
+ const values = await Promise.all(
140
+ toDo.map(method => {
141
+ return method(value)
142
+ })
143
+ )
144
+ return values.filter(x => x)
145
+ }
146
+ return _aggregativeValidator
143
147
  }
144
148
 
145
149
  const emptyValidator = () => []
@@ -166,24 +170,33 @@ const createFieldValidator = config => {
166
170
  ].filter(x => x)
167
171
  const validator =
168
172
  validators.length > 0 ? aggregateValidator(validators) : emptyValidator
169
- return async value => {
173
+ const _fieldValidator = async value => {
170
174
  const errors = await validator(value)
171
175
  return [...new Set(flatMap(errors))]
172
176
  }
173
- }
174
-
175
- const createModelValidator = fields => async () => {
176
- const keysAndFunctions = Object.entries(get(fields, 'functions.validate', {}))
177
- const data = await Promise.all(
178
- keysAndFunctions.map(async ([key, validator]) => {
179
- return [key, await validator()]
180
- })
181
- )
182
- return data
183
- .filter(([_, errors]) => Boolean(errors) && errors.length > 0)
184
- .reduce((acc, [key, errors]) => {
185
- return { ...acc, [key]: errors }
186
- }, {})
177
+ return _fieldValidator
178
+ }
179
+
180
+ const createModelValidator = fields => {
181
+ const _modelValidator = async () => {
182
+ const keysAndFunctions = Object.entries(
183
+ get(fields, 'functions.validate', {})
184
+ )
185
+ const data = await Promise.all(
186
+ keysAndFunctions.map(async ([key, validator]) => {
187
+ if (key === 'model') {
188
+ return [key, []]
189
+ }
190
+ return [key, await validator()]
191
+ })
192
+ )
193
+ return data
194
+ .filter(([_, errors]) => Boolean(errors) && errors.length > 0)
195
+ .reduce((acc, [key, errors]) => {
196
+ return { ...acc, [key]: errors }
197
+ }, {})
198
+ }
199
+ return _modelValidator
187
200
  }
188
201
 
189
202
  module.exports = {
@@ -481,7 +481,7 @@ describe('/src/fields.js', () => {
481
481
  assert.deepEqual(actual, expected)
482
482
  })
483
483
  it('should take the smartObject as a value', async () => {
484
- const proto = createModel({
484
+ const proto = createModel('name', {
485
485
  id: uniqueId({ value: 'obj-id' }),
486
486
  })
487
487
  const input = [proto({ id: 'obj-id' })]
@@ -490,23 +490,23 @@ describe('/src/fields.js', () => {
490
490
  const expected = 'obj-id'
491
491
  assert.deepEqual(actual, expected)
492
492
  })
493
- describe('#functions.toJson()', () => {
494
- it('should use the getId of the smartObject passed in when toJson is called', async () => {
495
- const proto = createModel({
493
+ describe('#functions.toObj()', () => {
494
+ it('should use the getId of the smartObject passed in when toObj is called', async () => {
495
+ const proto = createModel('name', {
496
496
  id: uniqueId({ value: 'obj-id' }),
497
497
  })
498
498
  const input = [proto({ id: 'obj-id' })]
499
499
  const instance = await referenceField({}).createGetter(...input)()
500
- const actual = await instance.functions.toJson()
500
+ const actual = await instance.functions.toObj()
501
501
  const expected = 'obj-id'
502
502
  assert.deepEqual(actual, expected)
503
503
  })
504
- it('should return "obj-id" when switch-a-roo fetcher is used and toJson is called', async () => {
504
+ it('should return "obj-id" when switch-a-roo fetcher is used and toObj is called', async () => {
505
505
  const input = ['obj-id']
506
506
  const instance = await referenceField({
507
507
  fetcher: () => ({ id: 'obj-id', prop: 'switch-a-roo' }),
508
508
  }).createGetter(...input)()
509
- const actual = await instance.functions.toJson()
509
+ const actual = await instance.functions.toObj()
510
510
  const expected = 'obj-id'
511
511
  assert.deepEqual(actual, expected)
512
512
  })
@@ -1,3 +1,4 @@
1
+ const _ = require('lodash')
1
2
  const assert = require('chai').assert
2
3
  const { createModel } = require('../../src/models')
3
4
  const { field } = require('../../src/fields')
@@ -5,7 +6,7 @@ const { field } = require('../../src/fields')
5
6
  describe('/src/models.js', () => {
6
7
  describe('#createModel()', () => {
7
8
  it('should return a function when called once with valid data', () => {
8
- const actual = createModel({})
9
+ const actual = createModel('name', {})
9
10
  const expected = 'function'
10
11
  assert.isFunction(actual)
11
12
  })
@@ -14,16 +15,44 @@ describe('/src/models.js', () => {
14
15
  const input = {
15
16
  myField: field({ required: true }),
16
17
  }
17
- const model = createModel(input)
18
+ const model = createModel('name', input)
18
19
  assert.doesNotThrow(() => {
19
20
  model()
20
21
  })
21
22
  })
23
+ it('should return an object that contains meta.fields.myField', () => {
24
+ const input = {
25
+ myField: field({ required: true }),
26
+ }
27
+ const model = createModel('name', input)
28
+ const instance = model({ myField: 'value' })
29
+ const actual = _.get(instance, 'meta.fields.myField')
30
+ assert.isOk(actual)
31
+ })
32
+ it('should return an object that contains meta.modelName===test-the-name', () => {
33
+ const input = {
34
+ myField: field({ required: true }),
35
+ }
36
+ const model = createModel('test-the-name', input)
37
+ const instance = model({ myField: 'value' })
38
+ const actual = _.get(instance, 'meta.modelName')
39
+ const expected = 'test-the-name'
40
+ assert.deepEqual(actual, expected)
41
+ })
42
+ it('should return an object that contains meta.fields.myField', () => {
43
+ const input = {
44
+ myField: field({ required: true }),
45
+ }
46
+ const model = createModel('name', input)
47
+ const instance = model({ myField: 'value' })
48
+ const actual = _.get(instance, 'meta.fields.myField')
49
+ assert.isOk(actual)
50
+ })
22
51
  it('should use the value passed in when field.defaultValue and field.value are not set', async () => {
23
52
  const input = {
24
53
  myField: field({ required: true }),
25
54
  }
26
- const model = createModel(input)
55
+ const model = createModel('name', input)
27
56
  const instance = model({ myField: 'passed-in' })
28
57
  const actual = await instance.getMyField()
29
58
  const expected = 'passed-in'
@@ -33,7 +62,7 @@ describe('/src/models.js', () => {
33
62
  const input = {
34
63
  myField: field({ value: 'value', defaultValue: 'default-value' }),
35
64
  }
36
- const model = createModel(input)
65
+ const model = createModel('name', input)
37
66
  const instance = model({ myField: 'passed-in' })
38
67
  const actual = await instance.getMyField()
39
68
  const expected = 'value'
@@ -43,7 +72,7 @@ describe('/src/models.js', () => {
43
72
  const input = {
44
73
  myField: field({ value: 'value' }),
45
74
  }
46
- const model = createModel(input)
75
+ const model = createModel('name', input)
47
76
  const instance = model({ myField: 'passed-in' })
48
77
  const actual = await instance.getMyField()
49
78
  const expected = 'value'
@@ -53,7 +82,7 @@ describe('/src/models.js', () => {
53
82
  const input = {
54
83
  myField: field({ defaultValue: 'defaultValue' }),
55
84
  }
56
- const model = createModel(input)
85
+ const model = createModel('name', input)
57
86
  const instance = model({})
58
87
  const actual = await instance.getMyField()
59
88
  const expected = 'defaultValue'
@@ -63,7 +92,7 @@ describe('/src/models.js', () => {
63
92
  const input = {
64
93
  myField: field({ defaultValue: 'defaultValue' }),
65
94
  }
66
- const model = createModel(input)
95
+ const model = createModel('name', input)
67
96
  const instance = model({ myField: null })
68
97
  const actual = await instance.getMyField()
69
98
  const expected = 'defaultValue'
@@ -74,7 +103,7 @@ describe('/src/models.js', () => {
74
103
  id: field({ required: true }),
75
104
  type: field(),
76
105
  }
77
- const model = createModel(input)
106
+ const model = createModel('name', input)
78
107
  const actual = model({ id: 'my-id', type: 'my-type' })
79
108
  assert.isOk(actual.getId)
80
109
  assert.isOk(actual.getType)
@@ -84,7 +113,7 @@ describe('/src/models.js', () => {
84
113
  id: field({ required: true }),
85
114
  type: field(),
86
115
  }
87
- const model = createModel(input)
116
+ const model = createModel('name', input)
88
117
  const instance = model({ type: 'my-type' })
89
118
  const actual = await instance.functions.validate.model()
90
119
  const expected = 1
@@ -92,12 +121,12 @@ describe('/src/models.js', () => {
92
121
  })
93
122
  })
94
123
  it('should return a function when called once with valid data', () => {
95
- const actual = createModel({})
124
+ const actual = createModel('name', {})
96
125
  assert.isFunction(actual)
97
126
  })
98
127
  it('should throw an exception if a key "model" is passed in', () => {
99
128
  assert.throws(() => {
100
- createModel({ model: 'weeee' })
129
+ createModel('name', { model: 'weeee' })
101
130
  })
102
131
  })
103
132
  })
@@ -1,10 +1,10 @@
1
1
  const assert = require('chai').assert
2
- const { toJson } = require('../../src/serialization')
2
+ const { toObj } = require('../../src/serialization')
3
3
 
4
4
  describe('/src/serialization.js', () => {
5
- describe('#toJson()', () => {
5
+ describe('#toObj()', () => {
6
6
  it('serialize a very basic input of key-value', async () => {
7
- const actual = await toJson({
7
+ const actual = await toObj({
8
8
  key: 'value',
9
9
  key2: 'value2',
10
10
  })()
@@ -15,7 +15,7 @@ describe('/src/serialization.js', () => {
15
15
  assert.deepEqual(actual, expected)
16
16
  })
17
17
  it('should ignore "meta" properties', async () => {
18
- const actual = await toJson({
18
+ const actual = await toObj({
19
19
  key: 'value',
20
20
  key2: 'value2',
21
21
  meta: {
@@ -29,7 +29,7 @@ describe('/src/serialization.js', () => {
29
29
  assert.deepEqual(actual, expected)
30
30
  })
31
31
  it('should ignore "functions" properties', async () => {
32
- const actual = await toJson({
32
+ const actual = await toObj({
33
33
  key: 'value',
34
34
  key2: 'value2',
35
35
  functions: {
@@ -44,13 +44,13 @@ describe('/src/serialization.js', () => {
44
44
  }
45
45
  assert.deepEqual(actual, expected)
46
46
  })
47
- it('should call "functions.toJson" on nested objects', async () => {
48
- const actual = await toJson({
47
+ it('should call "functions.toObj" on nested objects', async () => {
48
+ const actual = await toObj({
49
49
  key: 'value',
50
50
  key2: {
51
51
  complex: () => ({ func: 'func' }),
52
52
  functions: {
53
- toJson: () => ({ func: 'value' }),
53
+ toObj: () => ({ func: 'value' }),
54
54
  },
55
55
  },
56
56
  })()
@@ -62,12 +62,12 @@ describe('/src/serialization.js', () => {
62
62
  }
63
63
  assert.deepEqual(actual, expected)
64
64
  })
65
- it('should call "toJson" on very nested objects', async () => {
66
- const actual = await toJson({
65
+ it('should call "toObj" on very nested objects', async () => {
66
+ const actual = await toObj({
67
67
  key: 'value',
68
68
  key2: {
69
69
  functions: {
70
- toJson: () => ({ func: 'value' }),
70
+ toObj: () => ({ func: 'value' }),
71
71
  },
72
72
  },
73
73
  })()
@@ -80,7 +80,7 @@ describe('/src/serialization.js', () => {
80
80
  assert.deepEqual(actual, expected)
81
81
  })
82
82
  it('should set an undefined property to null', async () => {
83
- const actual = await toJson({
83
+ const actual = await toObj({
84
84
  key: 'value',
85
85
  key2: undefined,
86
86
  })()
@@ -91,7 +91,7 @@ describe('/src/serialization.js', () => {
91
91
  assert.deepEqual(actual, expected)
92
92
  })
93
93
  it('should get the value of a function', async () => {
94
- const actual = await toJson({
94
+ const actual = await toObj({
95
95
  key: 'value',
96
96
  key2: () => {
97
97
  return 'funcvalue'
@@ -104,7 +104,7 @@ describe('/src/serialization.js', () => {
104
104
  assert.deepEqual(actual, expected)
105
105
  })
106
106
  it('should change property getTheValue to "theValue"', async () => {
107
- const actual = await toJson({
107
+ const actual = await toObj({
108
108
  key: 'value',
109
109
  getTheValue: () => 'funcvalue',
110
110
  })()
@@ -115,7 +115,7 @@ describe('/src/serialization.js', () => {
115
115
  assert.deepEqual(actual, expected)
116
116
  })
117
117
  it('should return "2021-09-16T21:51:56.039Z" for the set date.', async () => {
118
- const actual = await toJson({
118
+ const actual = await toObj({
119
119
  myDate: new Date('2021-09-16T21:51:56.039Z'),
120
120
  })()
121
121
  const expected = {
@@ -258,6 +258,20 @@ describe('/src/validation.js', () => {
258
258
  sinon.assert.calledOnce(fields.functions.validate.id)
259
259
  sinon.assert.calledOnce(fields.functions.validate.type)
260
260
  })
261
+ it('should not run a validate.model function', async () => {
262
+ const fields = {
263
+ functions: {
264
+ validate: {
265
+ id: sinon.stub().returns(undefined),
266
+ type: sinon.stub().returns(undefined),
267
+ model: sinon.stub().returns(undefined),
268
+ },
269
+ },
270
+ }
271
+ const validator = createModelValidator(fields)
272
+ await validator()
273
+ sinon.assert.notCalled(fields.functions.validate.model)
274
+ })
261
275
  it('should combine results for both functions.validate for two objects that error', async () => {
262
276
  const fields = {
263
277
  functions: {