test.group('parseModelDependencies', models(async (t, file) => { const model = to.clone(contents[file]); model.data.dependencies = t.context.resolvePaths(model.data.dependencies, path.resolve(t.context.options.root, path.dirname(file))); await t.context.parseModelDependencies(model); if (model.data.dependencies.length === 0) { t.plan(0); } else { const length = t.context.models.length; t.is(length, to.unique(t.context.registered_models).length); } let count = 0; function check(dependencies) { if (count++ >= 20) { t.fail('parseModelDependencies has ran too many checks'); return; } for (let dependency_path of dependencies) { t.truthy(t.context.registered_models.includes(dependency_path)); const dependency = _.find(t.context.models, [ 'file', dependency_path ]); if (dependency_path === file) { t.falsy(dependency.is_dependency); } else { t.truthy(dependency.is_dependency); } if (dependency.data.dependencies.length) { check(dependency.data.dependencies); } } } check(model.data.dependencies); }));
setOptions(options) { options = to.arguments({ language: { prefix: '@', // header comment style // @note {10} only 1 of these can be used per file header: { start: '////', line: '///', end: '////', type: 'header' }, // body comment style body: { start: '', line: '///', end: '', type: 'body' }, // inline comment style inline: { start: '', line: '///#', end: '', type: 'inline' }, // this is used for any interpolations that might occur in annotations. // I don't see this needing to change but just incase I'm making it a setting. // @note {10} This setting is used to create a RegExp so certain characters need to be escaped interpolation: { start: '\\${', end: '}' }, }, type: undefined, blank_lines: 4, indent: true, annotations: {}, sort: [], log: logger }, arguments) let { annotations, type, log, ...rest } = options this.log = log this.options = rest this.api = new AnnotationApi({ annotations, type }) // this is used to pass to the annotations when they're called this.annotation_options = { log: this.log, options: this.options } const { language } = this.options this.comment_values = to.flatten([ ...to.values(language.header, '!type'), ...to.values(language.body, '!type'), ...to.values(language.inline, '!type') ]) this.comment_values = to.unique(this.comment_values).filter(Boolean) { let { alias, parse } = this.api.annotations parse = to.keys(parse) const reverse_alias_list = to.reduce(alias, (previous, { key, value }) => { value = value .filter((_alias) => !is.in(parse, _alias)) .reduce((a, b) => to.extend(a, { [b]: key }), {}) return to.extend(previous, value) }, {}) const regex = new RegExp(`^\s*${language.prefix}(?:(${to.keys(reverse_alias_list).join('|')})|(${parse.join('|')}))\\b\\s*`) const available = to.unique(to.reduce(this.api.annotations, (previous, { value }) => previous.concat(to.keys(value)), [])) this.annotations_list = { available, reverse_alias_list, regex } } this.options.order = sort(this.options.sort, { extras: this.annotations_list.available, amount: 3 }) this.options.order.push('inline') // this is for the inline part of the annotation }