UNPKG

yadda

Version:
93 lines (76 loc) 2.86 kB
'use strict'; var fn = require('./fn'); var $ = require('./Array'); var Context = require('./Context'); var RegularExpression = require('./RegularExpression'); var EventBus = require('./EventBus'); // Understands how to invoke a step var Macro = function (signature, parsed_signature, macro, macro_context, library, options) { /* eslint-disable no-redeclare */ var signature = normalise(signature); var signature_pattern = new RegularExpression(parsed_signature.pattern); var macro = macro || fn.async_noop; var event_bus = EventBus.instance(); var options = options || {}; /* eslint-enable no-redeclare */ this.library = library; this.is_identified_by = function (other_signature) { return signature === normalise(other_signature); }; this.can_interpret = function (step) { return signature_pattern.test(step); }; this.interpret = function (step, scenario_context, next) { var context = new Context({ step: step }).merge(macro_context).merge(scenario_context); convert(signature_pattern.groups(step), function (err, args) { if (err) return next(err); event_bus.send(EventBus.ON_EXECUTE, { step: step, ctx: context.properties, pattern: signature_pattern.toString(), args: args }); var result; try { result = fn.invoke(macro, context.properties, is_sync(args) ? args : args.concat(next)); } catch (err) { if (next) return next(err); throw err; } if (is_promise(result)) return result.then(fn.noargs(next)).catch(next); if (is_sync(args)) return next && next(); }); }; this.is_sibling = function (other_macro) { return other_macro && other_macro.defined_in(library); }; this.defined_in = function (other_library) { return library === other_library; }; this.levenshtein_signature = function () { return signature_pattern.without_expressions(); }; this.toString = function () { return signature; }; function is_promise(result) { if (options.mode) return options.mode === 'promise'; return result && result.then; } function is_sync(args) { if (options.mode) return options.mode === 'sync'; return macro !== fn.async_noop && macro.length !== args.length + 1; } function normalise(signature) { return new RegExp(signature).toString(); } function convert(args, next) { var index = 0; return $(parsed_signature.converters) .collect(function (converter) { return function (callback) { converter.apply(null, args.slice(index, (index += converter.length - 1)).concat(callback)); }; }) .collect_async(function (converter, index, callback) { converter(callback); }, next); } event_bus.send(EventBus.ON_DEFINE, { signature: signature, pattern: signature_pattern.toString() }); }; module.exports = Macro;