From 851d8edfddc6a4a74de472721c67579882ced34b Mon Sep 17 00:00:00 2001 From: Futago-za Ryuu Date: Wed, 31 Jan 2018 02:04:19 +0000 Subject: [PATCH] Implement warning emitter (Closes #327) --- lib/compiler/session.js | 4 ++ test/spec/unit/compiler/passes/helpers.js | 76 ++++++++++++++++++----- 2 files changed, 66 insertions(+), 14 deletions(-) diff --git a/lib/compiler/session.js b/lib/compiler/session.js index a33ac13..7322356 100644 --- a/lib/compiler/session.js +++ b/lib/compiler/session.js @@ -16,6 +16,8 @@ class Session { this.passes = options.passes || []; this.visitor = options.visitor || ast.visitor; + if ( typeof options.warn === "function" ) this.warn = options.warn; + } parse( input, options ) { @@ -30,6 +32,8 @@ class Session { } + warn( message, details ) {} + } module.exports = Session; diff --git a/test/spec/unit/compiler/passes/helpers.js b/test/spec/unit/compiler/passes/helpers.js index 1cd5469..683f7c0 100644 --- a/test/spec/unit/compiler/passes/helpers.js +++ b/test/spec/unit/compiler/passes/helpers.js @@ -9,12 +9,8 @@ module.exports = function ( chai, utils ) { const Assertion = chai.Assertion; - Assertion.addMethod( "changeAST", function ( grammar, props, options, additionalRuleProps ) { - - options = typeof options !== "undefined" ? options : {}; - additionalRuleProps = typeof additionalRuleProps !== "undefined" ? additionalRuleProps : { reportFailures: true }; + function parse( grammar, session, options ) { - const session = new Session( { grammar } ); const ast = session.parse( grammar ); if ( ! options.allowedStartRules ) { @@ -25,6 +21,18 @@ module.exports = function ( chai, utils ) { } + return ast; + + } + + Assertion.addMethod( "changeAST", function ( grammar, props, options, additionalRuleProps ) { + + options = typeof options !== "undefined" ? options : {}; + additionalRuleProps = typeof additionalRuleProps !== "undefined" ? additionalRuleProps : { reportFailures: true }; + + const session = new Session( { grammar } ); + const ast = parse( grammar, session, options ); + ast.rules = ast.rules.map( rule => Object.assign( rule, additionalRuleProps ) ); utils.flag( this, "object" )( ast, session, options ); @@ -38,15 +46,7 @@ module.exports = function ( chai, utils ) { options = typeof options !== "undefined" ? options : {}; const session = new Session( { grammar } ); - const ast = session.parse( grammar ); - - if ( ! options.allowedStartRules ) { - - options.allowedStartRules = ast.rules.length > 0 - ? [ ast.rules[ 0 ].name ] - : []; - - } + const ast = parse( grammar, session, options ); let passed, result; @@ -84,4 +84,52 @@ module.exports = function ( chai, utils ) { } ); + Assertion.addMethod( "reportWarning", function ( grammar, warnings, options ) { + + warnings = Array.isArray( warnings ) + ? warnings + : warnings == null + ? [] + : [ warnings ]; + + options = typeof options !== "undefined" ? options : {}; + + const messages = []; + function warn( message ) { + + messages.push( message ); + + } + + const session = new Session( { grammar, warn } ); + const ast = parse( grammar, session, options ); + + utils.flag( this, "object" )( ast, session, options ); + + const messagesCount = messages.length; + const warningsCount = warnings.length; + + if ( warnings.length ) + + this.assert( + messagesCount === warningsCount, + `expected #{this} to report ${ warningsCount } warnings, but it reported ${ messagesCount } warnings`, + `expected #{this} to not report ${ warningsCount } warnings`, + warnings, + messages + ); + + warnings.forEach( warning => { + + this.assert( + messages.indexOf( warning ) !== -1, + "expected #{this} to report the warning #{exp}, but it didn't", + "expected #{this} to not report the warning #{exp}", + warning + ); + + } ); + + } ); + };