Skip to content

Commit 15f4754

Browse files
committed
chore: add validation of schema
--- type: pre_commit_static_analysis_report description: Results of running static analysis checks when committing changes. report: - task: lint_filenames status: passed - task: lint_editorconfig status: passed - task: lint_markdown status: na - task: lint_package_json status: na - task: lint_repl_help status: na - task: lint_javascript_src status: passed - task: lint_javascript_cli status: na - task: lint_javascript_examples status: na - task: lint_javascript_tests status: passed - task: lint_javascript_benchmarks status: na - task: lint_python status: na - task: lint_r status: na - task: lint_c_src status: na - task: lint_c_examples status: na - task: lint_c_benchmarks status: na - task: lint_c_tests_fixtures status: na - task: lint_shell status: na - task: lint_typescript_declarations status: na - task: lint_typescript_tests status: na - task: lint_license_headers status: passed ---
1 parent d9b5da1 commit 15f4754

File tree

3 files changed

+159
-4
lines changed

3 files changed

+159
-4
lines changed

lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/lib/validate.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,66 @@
2020

2121
// MODULES //
2222

23+
var objectKeys = require( '@stdlib/utils/keys' );
2324
var isObject = require( '@stdlib/assert/is-plain-object' );
2425
var hasOwnProp = require( '@stdlib/assert/has-own-property' );
26+
var isArray = require( '@stdlib/assert/is-array' );
27+
var isString = require( '@stdlib/assert/is-string' );
2528
var format = require( '@stdlib/string/format' );
2629

2730

31+
// FUNCTIONS //
32+
33+
/**
34+
* Validates a section schema configuration.
35+
*
36+
* @private
37+
* @param {Object} schema - schema section to validate
38+
* @param {string} section - section name
39+
* @returns {(Error|null)} null or an error object
40+
*/
41+
function validateSection( schema, section ) {
42+
var i;
43+
var j;
44+
45+
if ( !isObject( schema ) ) {
46+
return new TypeError( format( 'invalid option. `%s` schema section must be an object. Value: `%s`.', section, schema ) );
47+
}
48+
49+
// Check if 'required' exists and is an array of strings
50+
if ( hasOwnProp( schema, 'required' ) ) {
51+
if ( !isArray( schema.required ) ) {
52+
return new TypeError( format( 'invalid option. `%s.required` must be an array. Value: `%s`.', section, schema.required ) );
53+
}
54+
// Validate each element in the 'required' array is a string
55+
for ( i = 0; i < schema.required.length; i++ ) {
56+
if ( !isString( schema.required[ i ] ) ) {
57+
return new TypeError( format( 'invalid option. `%s.required` must only contain strings. Found: `%s`.', section, schema.required[ i ] ) );
58+
}
59+
}
60+
} else {
61+
return new TypeError( format( 'invalid option. `%s` schema section must have a `required` property.', section ) );
62+
}
63+
64+
// Check if 'optional' exists and is an array of strings
65+
if ( hasOwnProp( schema, 'optional' ) ) {
66+
if ( !isArray( schema.optional ) ) {
67+
return new TypeError( format( 'invalid option. `%s.optional` must be an array. Value: `%s`.', section, schema.optional ) );
68+
}
69+
// Validate each element in the 'optional' array is a string
70+
for ( j = 0; j < schema.optional.length; j++ ) {
71+
if ( !isString( schema.optional[ j ] ) ) {
72+
return new TypeError( format( 'invalid option. `%s.optional` must only contain strings. Found: `%s`.', section, schema.optional[ j ] ) );
73+
}
74+
}
75+
} else {
76+
return new TypeError( format( 'invalid option. `%s` schema section must have an `optional` property.', section ) );
77+
}
78+
79+
return null;
80+
}
81+
82+
2883
// MAIN //
2984

3085
/**
@@ -52,15 +107,32 @@ var format = require( '@stdlib/string/format' );
52107
* }
53108
*/
54109
function validate( opts, options ) {
110+
var section;
111+
var keys;
112+
var err;
113+
var i;
114+
55115
if ( !isObject( options ) ) {
56116
return new TypeError( format( 'invalid argument. Options argument must be an object. Value: `%s`.', options ) );
57117
}
58118
if ( hasOwnProp( options, 'schema' ) ) {
59119
if ( !isObject( options.schema ) ) {
60120
return new TypeError( format( 'invalid option. `%s` option must be an object. Option: `%s`.', 'schema', options.schema ) );
61121
}
122+
if ( !hasOwnProp( options.schema, 'root' ) ) {
123+
return new TypeError( format( 'invalid option. Schema must contain a `root` section.' ) );
124+
}
125+
keys = objectKeys( options.schema );
126+
for ( i = 0; i < keys.length; i++ ) {
127+
section = keys[ i ];
128+
err = validateSection( options.schema[ section ], section );
129+
if ( err ) {
130+
return err;
131+
}
132+
}
62133
opts.schema = options.schema;
63134
}
135+
64136
return null;
65137
}
66138

lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/test.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ var join = require( 'path' ).join;
2424
var tape = require( 'tape' );
2525
var remark = require( 'remark' );
2626
var readFileSync = require( '@stdlib/fs/read-file' ).sync;
27+
var contains = require( '@stdlib/assert/contains' );
2728
var expectedSections = require( './../lib' );
2829

2930

@@ -103,7 +104,7 @@ tape( 'detects missing C usage section in invalid_asin.md.txt', function test( t
103104
t.fail( err.message );
104105
}
105106
t.strictEqual( file.messages.length, 1, 'has one error for invalid asin fixture' );
106-
t.strictEqual( file.messages[0].reason.includes('Missing required sections in "c" section: `usage`'), true, 'error identifies the missing C usage section' );
107+
t.strictEqual( contains( file.messages[ 0 ].reason, 'Missing required sections in "c" section: `usage`' ), true, 'error identifies the missing C usage section' );
107108
t.end();
108109
}
109110
});
@@ -116,7 +117,7 @@ tape( 'reports error for missing required root sections', function test( t ) {
116117
t.fail( err.message );
117118
}
118119
t.strictEqual( file.messages.length, 1, 'has one error for fixture missing a required root section' );
119-
t.strictEqual( file.messages[0].reason.includes('Missing required root-level sections: `usage`'), true, 'error identifies the missing section' );
120+
t.strictEqual( contains( file.messages[ 0 ].reason, 'Missing required root-level sections: `usage`' ), true, 'error identifies the missing section' );
120121
t.end();
121122
}
122123
});
@@ -129,7 +130,7 @@ tape( 'reports error for incomplete C section', function test( t ) {
129130
t.fail( err.message );
130131
}
131132
t.strictEqual( file.messages.length, 1, 'has one error for fixture with an incomplete C section' );
132-
t.strictEqual( file.messages[0].reason.includes('Missing required sections in "c" section: `usage`, `examples`'), true, 'error identifies the missing C sections' );
133+
t.strictEqual( contains( file.messages[ 0 ].reason, 'Missing required sections in "c" section: `usage`, `examples`' ), true, 'error identifies the missing C sections' );
133134
t.end();
134135
}
135136
});
@@ -159,7 +160,7 @@ tape( 'reports correct errors with custom schema', function test( t ) {
159160
t.fail( err.message );
160161
}
161162
t.strictEqual( file.messages.length, 1, 'has correct number of errors with custom schema' );
162-
t.strictEqual( file.messages[0].reason.includes('usage') && file.messages[0].reason.includes('related'), true, 'error identifies both missing sections' );
163+
t.strictEqual( contains( file.messages[ 0 ].reason, 'usage' ) && contains( file.messages[ 0 ].reason, 'related' ), true, 'error identifies both missing sections' );
163164
t.end();
164165
}
165166
});

lib/node_modules/@stdlib/_tools/remark/plugins/remark-lint-expected-html-sections/test/test.validate.js

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,88 @@ tape( 'the function returns an error if provided a `schema` option which is not
8484
t.end();
8585
});
8686

87+
tape( 'the function returns an error if provided a schema without a root section', function test( t ) {
88+
var options;
89+
var opts;
90+
var err;
91+
92+
opts = {};
93+
options = {
94+
'schema': {
95+
'section': {
96+
'required': [ 'usage' ],
97+
'optional': [ 'notes' ]
98+
}
99+
}
100+
};
101+
102+
err = validate( opts, options );
103+
t.strictEqual( err instanceof TypeError, true, 'returns a type error' );
104+
105+
t.end();
106+
});
107+
108+
tape( 'the function returns an error if provided a schema with incorrect structure', function test( t ) {
109+
var options;
110+
var opts;
111+
var err;
112+
113+
opts = {};
114+
options = {
115+
'schema': {
116+
'root': {
117+
'required': 'usage', // Should be an array
118+
'optional': [ 'notes' ]
119+
}
120+
}
121+
};
122+
123+
err = validate( opts, options );
124+
t.strictEqual( err instanceof TypeError, true, 'returns a type error' );
125+
126+
t.end();
127+
});
128+
129+
tape( 'the function returns an error if a schema section is missing the required property', function test( t ) {
130+
var options;
131+
var opts;
132+
var err;
133+
134+
opts = {};
135+
options = {
136+
'schema': {
137+
'root': {
138+
'optional': [ 'notes' ]
139+
}
140+
}
141+
};
142+
143+
err = validate( opts, options );
144+
t.strictEqual( err instanceof TypeError, true, 'returns a type error' );
145+
146+
t.end();
147+
});
148+
149+
tape( 'the function returns an error if a schema section is missing the optional property', function test( t ) {
150+
var options;
151+
var opts;
152+
var err;
153+
154+
opts = {};
155+
options = {
156+
'schema': {
157+
'root': {
158+
'required': [ 'usage' ]
159+
}
160+
}
161+
};
162+
163+
err = validate( opts, options );
164+
t.strictEqual( err instanceof TypeError, true, 'returns a type error' );
165+
166+
t.end();
167+
});
168+
87169
tape( 'the function returns `null` if all options are valid', function test( t ) {
88170
var options;
89171
var opts;

0 commit comments

Comments
 (0)