Skip to content

Commit 9103591

Browse files
authored
Fix circular dependencies in the validation module for the style spec (#1946)
* Fix circular dependencies in the validation module for the style spec * Fixed issues with sprite validation after merging the circular import changes
1 parent 26344c9 commit 9103591

15 files changed

Lines changed: 105 additions & 71 deletions

src/style-spec/validate/validate.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export default function validate(options) {
6262
const value = options.value;
6363
const valueSpec = options.valueSpec;
6464
const styleSpec = options.styleSpec;
65+
options.validateSpec = validate;
6566

6667
if (valueSpec.expression && isFunction(unbundle(value))) {
6768
return validateFunction(options);

src/style-spec/validate/validate_array.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
21
import getType from '../util/get_type';
3-
import validate from './validate';
42
import ValidationError from '../error/validation_error';
53

64
export default function validateArray(options) {
75
const array = options.value;
86
const arraySpec = options.valueSpec;
7+
const validateSpec = options.validateSpec;
98
const style = options.style;
109
const styleSpec = options.styleSpec;
1110
const key = options.key;
12-
const validateArrayElement = options.arrayElementValidator || validate;
11+
const validateArrayElement = options.arrayElementValidator || validateSpec;
1312

1413
if (getType(array) !== 'array') {
1514
return [new ValidationError(key, array, `array expected, ${getType(array)} found`)];
@@ -43,6 +42,7 @@ export default function validateArray(options) {
4342
arrayIndex: i,
4443
value: array[i],
4544
valueSpec: arrayElementSpec,
45+
validateSpec: options.validateSpec,
4646
style,
4747
styleSpec,
4848
key: `${key}[${i}]`

src/style-spec/validate/validate_function.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11

22
import ValidationError from '../error/validation_error';
33
import getType from '../util/get_type';
4-
import validate from './validate';
54
import validateObject from './validate_object';
65
import validateArray from './validate_array';
76
import validateNumber from './validate_number';
@@ -32,6 +31,7 @@ export default function validateFunction(options): Array<ValidationError> {
3231
key: options.key,
3332
value: options.value,
3433
valueSpec: options.styleSpec.function,
34+
validateSpec: options.validateSpec,
3535
style: options.style,
3636
styleSpec: options.styleSpec,
3737
objectElementValidators: {
@@ -78,6 +78,7 @@ export default function validateFunction(options): Array<ValidationError> {
7878
key: options.key,
7979
value,
8080
valueSpec: options.valueSpec,
81+
validateSpec: options.validateSpec,
8182
style: options.style,
8283
styleSpec: options.styleSpec,
8384
arrayElementValidator: validateFunctionStop
@@ -125,6 +126,7 @@ export default function validateFunction(options): Array<ValidationError> {
125126
key: `${key}[0]`,
126127
value: value[0],
127128
valueSpec: {zoom: {}},
129+
validateSpec: options.validateSpec,
128130
style: options.style,
129131
styleSpec: options.styleSpec,
130132
objectElementValidators: {zoom: validateNumber, value: validateStopDomainValue}
@@ -134,6 +136,7 @@ export default function validateFunction(options): Array<ValidationError> {
134136
key: `${key}[0]`,
135137
value: value[0],
136138
valueSpec: {},
139+
validateSpec: options.validateSpec,
137140
style: options.style,
138141
styleSpec: options.styleSpec
139142
}, value));
@@ -143,10 +146,11 @@ export default function validateFunction(options): Array<ValidationError> {
143146
return errors.concat([new ValidationError(`${key}[1]`, value[1], 'expressions are not allowed in function stops.')]);
144147
}
145148

146-
return errors.concat(validate({
149+
return errors.concat(options.validateSpec({
147150
key: `${key}[1]`,
148151
value: value[1],
149152
valueSpec: functionValueSpec,
153+
validateSpec: options.validateSpec,
150154
style: options.style,
151155
styleSpec: options.styleSpec
152156
}));
@@ -196,10 +200,11 @@ export default function validateFunction(options): Array<ValidationError> {
196200
}
197201

198202
function validateFunctionDefault(options): Array<ValidationError> {
199-
return validate({
203+
return options.validateSpec({
200204
key: options.key,
201205
value: options.value,
202206
valueSpec: functionValueSpec,
207+
validateSpec: options.validateSpec,
203208
style: options.style,
204209
styleSpec: options.styleSpec
205210
});

src/style-spec/validate/validate_layer.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import validateObject from './validate_object';
55
import validateFilter from './validate_filter';
66
import validatePaintProperty from './validate_paint_property';
77
import validateLayoutProperty from './validate_layout_property';
8-
import validateSpec from './validate';
98
import extend from '../util/extend';
109

1110
export default function validateLayer(options) {
@@ -81,19 +80,21 @@ export default function validateLayer(options) {
8180
valueSpec: styleSpec.layer,
8281
style: options.style,
8382
styleSpec: options.styleSpec,
83+
validateSpec: options.validateSpec,
8484
objectElementValidators: {
8585
'*'() {
8686
return [];
8787
},
8888
// We don't want to enforce the spec's `"requires": true` for backward compatibility with refs;
8989
// the actual requirement is validated above. See https://github.com/mapbox/mapbox-gl-js/issues/5772.
9090
type() {
91-
return validateSpec({
91+
return options.validateSpec({
9292
key: `${key}.type`,
9393
value: layer.type,
9494
valueSpec: styleSpec.layer.type,
9595
style: options.style,
9696
styleSpec: options.styleSpec,
97+
validateSpec: options.validateSpec,
9798
object: layer,
9899
objectKey: 'type'
99100
});
@@ -106,6 +107,7 @@ export default function validateLayer(options) {
106107
value: options.value,
107108
style: options.style,
108109
styleSpec: options.styleSpec,
110+
validateSpec: options.validateSpec,
109111
objectElementValidators: {
110112
'*'(options) {
111113
return validateLayoutProperty(extend({layerType: type}, options));
@@ -120,6 +122,7 @@ export default function validateLayer(options) {
120122
value: options.value,
121123
style: options.style,
122124
styleSpec: options.styleSpec,
125+
validateSpec: options.validateSpec,
123126
objectElementValidators: {
124127
'*'(options) {
125128
return validatePaintProperty(extend({layerType: type}, options));

src/style-spec/validate/validate_light.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
21
import ValidationError from '../error/validation_error';
32
import getType from '../util/get_type';
4-
import validate from './validate';
53

64
export default function validateLight(options) {
75
const light = options.value;
@@ -23,18 +21,20 @@ export default function validateLight(options) {
2321
const transitionMatch = key.match(/^(.*)-transition$/);
2422

2523
if (transitionMatch && lightSpec[transitionMatch[1]] && lightSpec[transitionMatch[1]].transition) {
26-
errors = errors.concat(validate({
24+
errors = errors.concat(options.validateSpec({
2725
key,
2826
value: light[key],
2927
valueSpec: styleSpec.transition,
28+
validateSpec: options.validateSpec,
3029
style,
3130
styleSpec
3231
}));
3332
} else if (lightSpec[key]) {
34-
errors = errors.concat(validate({
33+
errors = errors.concat(options.validateSpec({
3534
key,
3635
value: light[key],
3736
valueSpec: lightSpec[key],
37+
validateSpec: options.validateSpec,
3838
style,
3939
styleSpec
4040
}));

src/style-spec/validate/validate_object.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11

22
import ValidationError from '../error/validation_error';
33
import getType from '../util/get_type';
4-
import validateSpec from './validate';
54

65
export default function validateObject(options): Array<ValidationError> {
76
const key = options.key;
@@ -10,6 +9,7 @@ export default function validateObject(options): Array<ValidationError> {
109
const elementValidators = options.objectElementValidators || {};
1110
const style = options.style;
1211
const styleSpec = options.styleSpec;
12+
const validateSpec = options.validateSpec;
1313
let errors = [] as Array<ValidationError>;
1414

1515
const type = getType(object);
@@ -42,7 +42,8 @@ export default function validateObject(options): Array<ValidationError> {
4242
style,
4343
styleSpec,
4444
object,
45-
objectKey
45+
objectKey,
46+
validateSpec,
4647
}, object));
4748
}
4849

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,83 @@
1+
import validateSpec from './validate';
12
import validatePadding from './validate_padding';
23

34
describe('Validate Padding', () => {
45
test('Should return error if type is not number or array', () => {
5-
let errors = validatePadding({key: 'padding', value: '3'});
6+
let errors = validatePadding({validateSpec, key: 'padding', value: '3'});
67
expect(errors).toHaveLength(1);
78
expect(errors[0].message).toBe('padding: number expected, string found');
89

9-
errors = validatePadding({key: 'padding', value: true});
10+
errors = validatePadding({validateSpec, key: 'padding', value: true});
1011
expect(errors).toHaveLength(1);
1112
expect(errors[0].message).toBe('padding: number expected, boolean found');
1213

13-
errors = validatePadding({key: 'padding', value: null});
14+
errors = validatePadding({validateSpec, key: 'padding', value: null});
1415
expect(errors).toHaveLength(1);
1516
expect(errors[0].message).toBe('padding: number expected, null found');
1617

17-
errors = validatePadding({key: 'padding', value: {x: 1, y: 1}});
18+
errors = validatePadding({validateSpec, key: 'padding', value: {x: 1, y: 1}});
1819
expect(errors).toHaveLength(1);
1920
expect(errors[0].message).toBe('padding: number expected, object found');
2021

21-
errors = validatePadding({key: 'padding', value: NaN});
22+
errors = validatePadding({validateSpec, key: 'padding', value: NaN});
2223
expect(errors).toHaveLength(1);
2324
expect(errors[0].message).toBe('padding: number expected, NaN found');
2425
});
2526

2627
test('Should pass if type is number', () => {
27-
const errors = validatePadding({key: 'padding', value: 1});
28+
const errors = validatePadding({validateSpec, key: 'padding', value: 1});
2829
expect(errors).toHaveLength(0);
2930
});
3031

3132
test('Should return error if array length is invalid', () => {
32-
let errors = validatePadding({key: 'padding', value: []});
33+
let errors = validatePadding({validateSpec, key: 'padding', value: []});
3334
expect(errors).toHaveLength(1);
3435
expect(errors[0].message).toBe('padding: padding requires 1 to 4 values; 0 values found');
3536

36-
errors = validatePadding({key: 'padding', value: [1, 1, 1, 1, 1]});
37+
errors = validatePadding({validateSpec, key: 'padding', value: [1, 1, 1, 1, 1]});
3738
expect(errors).toHaveLength(1);
3839
expect(errors[0].message).toBe('padding: padding requires 1 to 4 values; 5 values found');
3940

40-
errors = validatePadding({key: 'padding', value: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]});
41+
errors = validatePadding({validateSpec, key: 'padding', value: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]});
4142
expect(errors).toHaveLength(1);
4243
expect(errors[0].message).toBe('padding: padding requires 1 to 4 values; 12 values found');
4344
});
4445

4546
test('Should return error if array contains non-numeric values', () => {
46-
let errors = validatePadding({key: 'padding', value: ['1']});
47+
let errors = validatePadding({validateSpec, key: 'padding', value: ['1']});
4748
expect(errors).toHaveLength(1);
4849
expect(errors[0].message).toBe('padding[0]: number expected, string found');
4950

50-
errors = validatePadding({key: 'padding', value: [true]});
51+
errors = validatePadding({validateSpec, key: 'padding', value: [true]});
5152
expect(errors).toHaveLength(1);
5253
expect(errors[0].message).toBe('padding[0]: number expected, boolean found');
5354

54-
errors = validatePadding({key: 'padding', value: [NaN]});
55+
errors = validatePadding({validateSpec, key: 'padding', value: [NaN]});
5556
expect(errors).toHaveLength(1);
5657
expect(errors[0].message).toBe('padding[0]: number expected, NaN found');
5758

58-
errors = validatePadding({key: 'padding', value: [{x: 1}]});
59+
errors = validatePadding({validateSpec, key: 'padding', value: [{x: 1}]});
5960
expect(errors).toHaveLength(1);
6061
expect(errors[0].message).toBe('padding[0]: number expected, object found');
6162

62-
errors = validatePadding({key: 'padding', value: [1, 3, false]});
63+
errors = validatePadding({validateSpec, key: 'padding', value: [1, 3, false]});
6364
expect(errors).toHaveLength(1);
6465
expect(errors[0].message).toBe('padding[2]: number expected, boolean found');
6566

66-
errors = validatePadding({key: 'padding', value: ['1', 3, false]});
67+
errors = validatePadding({validateSpec, key: 'padding', value: ['1', 3, false]});
6768
expect(errors).toHaveLength(2);
6869
expect(errors[0].message).toBe('padding[0]: number expected, string found');
6970
expect(errors[1].message).toBe('padding[2]: number expected, boolean found');
7071
});
7172

7273
test('Should pass if type is numeric array', () => {
73-
let errors = validatePadding({key: 'padding', value: [1]});
74+
let errors = validatePadding({validateSpec, key: 'padding', value: [1]});
7475
expect(errors).toHaveLength(0);
75-
errors = validatePadding({key: 'padding', value: [1, 1]});
76+
errors = validatePadding({validateSpec, key: 'padding', value: [1, 1]});
7677
expect(errors).toHaveLength(0);
77-
errors = validatePadding({key: 'padding', value: [1, 1, 1]});
78+
errors = validatePadding({validateSpec, key: 'padding', value: [1, 1, 1]});
7879
expect(errors).toHaveLength(0);
79-
errors = validatePadding({key: 'padding', value: [1, 1, 1, 1]});
80+
errors = validatePadding({validateSpec, key: 'padding', value: [1, 1, 1, 1]});
8081
expect(errors).toHaveLength(0);
8182
});
8283
});

src/style-spec/validate/validate_padding.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import ValidationError from '../error/validation_error';
22
import getType from '../util/get_type';
3-
import validate from './validate';
43
import validateNumber from './validate_number';
54

65
export default function validatePadding(options) {
@@ -19,9 +18,10 @@ export default function validatePadding(options) {
1918

2019
let errors = [];
2120
for (let i = 0; i < value.length; i++) {
22-
errors = errors.concat(validate({
21+
errors = errors.concat(options.validateSpec({
2322
key: `${key}[${i}]`,
2423
value: value[i],
24+
validateSpec: options.validateSpec,
2525
valueSpec: arrayElementSpec
2626
}));
2727
}

src/style-spec/validate/validate_property.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11

2-
import validate from './validate';
32
import ValidationError from '../error/validation_error';
43
import getType from '../util/get_type';
54
import {isFunction} from '../function';
@@ -8,6 +7,7 @@ import {supportsPropertyExpression} from '../util/properties';
87

98
export default function validateProperty(options, propertyType) {
109
const key = options.key;
10+
const validateSpec = options.validateSpec;
1111
const style = options.style;
1212
const styleSpec = options.styleSpec;
1313
const value = options.value;
@@ -18,7 +18,7 @@ export default function validateProperty(options, propertyType) {
1818

1919
const transitionMatch = propertyKey.match(/^(.*)-transition$/);
2020
if (propertyType === 'paint' && transitionMatch && layerSpec[transitionMatch[1]] && layerSpec[transitionMatch[1]].transition) {
21-
return validate({
21+
return validateSpec({
2222
key,
2323
value,
2424
valueSpec: styleSpec.transition,
@@ -51,7 +51,7 @@ export default function validateProperty(options, propertyType) {
5151
}
5252
}
5353

54-
return errors.concat(validate({
54+
return errors.concat(validateSpec({
5555
key: options.key,
5656
value,
5757
valueSpec,

0 commit comments

Comments
 (0)