Skip to content

Commit f620a22

Browse files
committed
validate: add support for is isSubplotObj attributes
1 parent 1958dc6 commit f620a22

File tree

2 files changed

+67
-9
lines changed

2 files changed

+67
-9
lines changed

src/plot_api/validate.js

+39-7
Original file line numberDiff line numberDiff line change
@@ -107,25 +107,27 @@ function crawl(objIn, objOut, schema, list, path) {
107107
var valIn = objIn[k],
108108
valOut = objOut[k];
109109

110-
if(isPlainObject(valIn) && isPlainObject(valOut)) {
111-
crawl(valIn, valOut, schema[k], list, p);
112-
}
113-
else if(!(k in schema)) {
110+
var nestedSchema = getNestedSchema(schema, k);
111+
112+
if(!isInSchema(schema, k)) {
114113
list.push(format('schema', p));
115114
}
116-
else if(schema[k].items && Array.isArray(valIn)) {
115+
else if(isPlainObject(valIn) && isPlainObject(valOut)) {
116+
crawl(valIn, valOut, nestedSchema, list, p);
117+
}
118+
else if(nestedSchema.items && Array.isArray(valIn)) {
117119
var itemName = k.substr(0, k.length - 1);
118120

119121
for(var j = 0; j < valIn.length; j++) {
120122
p[p.length - 1] = k + '[' + j + ']';
121123

122-
crawl(valIn[j], valOut[j], schema[k].items[itemName], list, p);
124+
crawl(valIn[j], valOut[j], nestedSchema.items[itemName], list, p);
123125
}
124126
}
125127
else if(!(k in objOut)) {
126128
list.push(format('unused', p, valIn));
127129
}
128-
else if(!Lib.validate(valIn, schema[k])) {
130+
else if(!Lib.validate(valIn, nestedSchema)) {
129131
list.push(format('value', p, valIn));
130132
}
131133
}
@@ -154,3 +156,33 @@ function format(code, path, valIn) {
154156
msg: code2msgFunc[code](path, valIn)
155157
};
156158
}
159+
160+
function isInSchema(schema, key) {
161+
var parts = splitKey(key),
162+
keyMinusId = parts.keyMinusId,
163+
id = parts.id;
164+
165+
if((keyMinusId in schema) && schema[keyMinusId]._isSubplotObj && id) {
166+
return true;
167+
}
168+
169+
return (key in schema);
170+
}
171+
172+
function getNestedSchema(schema, key) {
173+
var parts = splitKey(key);
174+
175+
return schema[parts.keyMinusId];
176+
}
177+
178+
function splitKey(key) {
179+
var idRegex = /([2-9]|[1-9][0-9]+)$/;
180+
181+
var keyMinusId = key.split(idRegex)[0],
182+
id = key.substr(keyMinusId.length, key.length);
183+
184+
return {
185+
keyMinusId: keyMinusId,
186+
id: id
187+
};
188+
}

test/jasmine/tests/validate_test.js

+28-2
Original file line numberDiff line numberDiff line change
@@ -95,15 +95,41 @@ describe('Plotly.validate', function() {
9595
}]
9696
}
9797
},
98+
xaxis2: {
99+
type: 'date',
100+
rangeselector: {
101+
buttons: [{
102+
title: '1 month'
103+
}]
104+
}
105+
},
98106
shapes: [{
99107
opacity: 'none'
100108
}]
101109
});
102110

103-
assertErrorShape(out, [], 4);
111+
assertErrorShape(out, [], 5);
104112
assertErrorContent(out.layout[0], 'schema', ['annotations[1]', 'arrowSymbol'], '');
105113
assertErrorContent(out.layout[1], 'unused', ['xaxis', 'rangeselector', 'buttons[0]', 'count'], '');
106114
assertErrorContent(out.layout[2], 'schema', ['xaxis', 'rangeselector', 'buttons[1]', 'title'], '');
107-
assertErrorContent(out.layout[3], 'value', ['shapes[0]', 'opacity'], '');
115+
assertErrorContent(out.layout[3], 'schema', ['xaxis2', 'rangeselector', 'buttons[0]', 'title'], '');
116+
assertErrorContent(out.layout[4], 'value', ['shapes[0]', 'opacity'], '');
117+
});
118+
119+
it('should work with isSubplotObj attributes', function() {
120+
var out = Plotly.validate([], {
121+
xaxis2: {
122+
range: 30
123+
},
124+
scene10: {
125+
bgcolor: 'red'
126+
},
127+
geo0: {},
128+
});
129+
130+
assertErrorShape(out, [], 4);
131+
assertErrorContent(out.layout[0], 'value', ['xaxis2', 'range'], '');
132+
assertErrorContent(out.layout[1], 'unused', ['scene10'], '');
133+
assertErrorContent(out.layout[2], 'schema', ['geo0'], '');
108134
});
109135
});

0 commit comments

Comments
 (0)