All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gwen.dsl.PrettyPrinter.scala Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2014 Branko Juric, Brady Wood
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package gwen.dsl

import java.io.File

/**
  * Pretty prints a spec node to a string.  This object recursively prints
  * each node to a string and can be invoked as a function.  For example, 
  * `prettyPrint(spec)` prints an entire spec, and `prettyPrint(step)` prints 
  * a single step.  Included in the output is the evaluation status of node 
  * (if not pending).
  * 
  * @author Branko Juric
  */
object prettyPrint {

  /**
    * Prints an [[SpecNode]] to a string.  This method is implicitly 
    * called whenever `prettyPrint(specNode)` is called.  There is no need to 
    * call this method explicitly.   
    *
    * @param node the AST node to print
    */
  def apply(node: SpecNode): String = node match {
    case spec @ FeatureSpec(feature, background, scenarios,  _, _) =>
      apply(feature) +
        formatStatus(spec.evalStatus) +
        background.map(apply).getOrElse("") +
        printAll(scenarios.map(apply), "", "")
    case Feature(tags, name, description) =>
      s"${formatTags("   ", tags)}   Feature: ${name}${formatDescription(description)}"
    case background @ Background(name, description, steps) =>
      s"\n\nBackground: ${name}${formatDescription(description)}${formatStatus(background.evalStatus)}\n" + printAll(steps.map(apply), "  ", "\n")
    case scenario @ Scenario(tags, name, description, background, steps, _) =>
      background.map(apply).getOrElse("") +
      s"\n\n${formatTags("  ", tags)}  Scenario: ${name}${formatDescription(description)}${formatStatus(scenario.evalStatus)}\n" + printAll(steps.map(apply), "  ", "\n")
    case Step(_, keyword, expression, evalStatus, _, _) =>
      rightJustify(keyword.toString) + s"${keyword} ${expression}${formatStatus(evalStatus)}"
  }
  
  private def formatDescription(description: List[String]): String = 
    (description.map { line =>
      s"\n            ${line}"
    }).mkString
  
  /**
    * Formats the given tags to a string.
    * 
    * @param tags the tags to format
    */
  private def formatTags(indent: String, tags: List[Tag]):String = tags.toList match {
    case _ :: _ =>  s"${indent}${tags.mkString(" ")}\n"
    case _ => ""
  }
  
  private def formatStatus(status: EvalStatus): String = status match {
    case Pending => ""
    case Failed(_, error) => s" # ${status}: ${error.getMessage()}" 
    case _ => s" # ${status}"
  }
  
  /**
    * Right justifies a step keyword by padding spaces in front of it. This
    * ensures that when steps are listed one after the other, their
    * clauses line up.
    */
  private def rightJustify(keyword: String) = (" " * (9  - keyword.length))
  
  /**
    * Prints a list of nodes, giving each node a prefix and separator.
    * 
    * @param nodes the list of nodes to print
    * @param prefix the prefix to append the printed node to
    * @param separator the string separating each printed node
    */
  private def printAll[T](nodes: List[T], prefix: String, separator: String) =
    nodes.map(prefix + _) mkString(separator)

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy