Skip to content
This repository has been archived by the owner on May 28, 2019. It is now read-only.

Commit

Permalink
Pretty formatter now prints in colour (at least mostly)
Browse files Browse the repository at this point in the history
  • Loading branch information
aslakhellesoy committed Oct 12, 2010
1 parent eaa350f commit da8e06a
Show file tree
Hide file tree
Showing 22 changed files with 271 additions and 148 deletions.
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@ gemspec

@dependencies.reject!{|dep| dep.name == 'cucumber'}
gem 'cucumber', :path => '../cucumber'
gem 'jruby-openssl'
5 changes: 3 additions & 2 deletions features/step_definitions/json_parser_steps.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
require 'stringio'
require 'gherkin/formatter/pretty_formatter'
require 'gherkin/formatter/monochrome_io'
require 'gherkin/json_parser'

Given /^a PrettyFormatter$/ do
@io = StringIO.new
@formatter = Gherkin::Formatter::PrettyFormatter.new(@io, true)
@io = Gherkin::Formatter::MonochromeIO.new(StringIO.new)
@formatter = Gherkin::Formatter::PrettyFormatter.new(@io)
end

Given /^a JSON lexer$/ do
Expand Down
9 changes: 5 additions & 4 deletions features/step_definitions/pretty_formatter_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
require 'gherkin'
require 'gherkin/formatter/pretty_formatter'
require 'gherkin/formatter/json_formatter'
require 'gherkin/formatter/monochrome_io'
require 'gherkin/json_parser'

module PrettyPlease
def pretty_machinery(gherkin, feature_path)
io = StringIO.new
formatter = Gherkin::Formatter::PrettyFormatter.new(io, false)
io = Gherkin::Formatter::MonochromeIO.new(StringIO.new)
formatter = Gherkin::Formatter::PrettyFormatter.new(io)
parser = Gherkin::Parser::Parser.new(formatter, true)
parse(parser, gherkin, feature_path)
io.string
Expand All @@ -20,8 +21,8 @@ def json_machinery(gherkin, feature_path)
gherkin_parser = Gherkin::Parser::Parser.new(json_formatter, true)
parse(gherkin_parser, gherkin, feature_path)

result = StringIO.new
pretty_formatter = Gherkin::Formatter::PrettyFormatter.new(result, false)
result = Gherkin::Formatter::MonochromeIO.new(StringIO.new)
pretty_formatter = Gherkin::Formatter::PrettyFormatter.new(result)
json_parser = Gherkin::JSONParser.new(pretty_formatter)
json_parser.parse(json.string, "#{feature_path}.json", 0)

Expand Down
2 changes: 1 addition & 1 deletion java/src/main/java/gherkin/I18n.java
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public List<String> getStepKeywords() {

public String getKeywordTable() {
StringWriter writer = new StringWriter();
PrettyFormatter pf = new PrettyFormatter(writer, true);
PrettyFormatter pf = new PrettyFormatter(writer);
List<Row> table = new ArrayList<Row>();
for (String key : KEYWORD_KEYS) {
List<String> cells = Arrays.asList(key, join(map(keywords(key), QUOTE_MAPPER), ", "));
Expand Down
7 changes: 0 additions & 7 deletions java/src/main/java/gherkin/formatter/Colors.java

This file was deleted.

37 changes: 37 additions & 0 deletions java/src/main/java/gherkin/formatter/MonochromeIO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package gherkin.formatter;

import java.io.FilterWriter;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.regex.Pattern;

/**
* This class filters away ANSI color codes
*/
public class MonochromeIO extends FilterWriter {
private static final Pattern COLOR_PATTERN = Pattern.compile(new String(new char[(char)27]) + "\\[(?:[34][0-7]|[0-9]|90)?m");
private static final String EMPTY_STRING = "";

public MonochromeIO(Writer w) {
super(w);
}

@Override
public void write(String str, int off, int len) throws IOException {
String monochromeString = COLOR_PATTERN.matcher(str).replaceAll(EMPTY_STRING);
super.write(monochromeString, off, monochromeString.length());
}

/**
* Convenience method for our ruby tests.
* @return the String data in the underlying writer - if it is a StringWriter.
*/
public String getString() {
if(out instanceof StringWriter) {
return out.toString();
} else {
throw new UnsupportedOperationException("Can only getString() from StringWriter");
}
}
}
69 changes: 40 additions & 29 deletions java/src/main/java/gherkin/formatter/PrettyFormatter.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,26 @@
package gherkin.formatter;

import gherkin.formatter.model.*;
import gherkin.formatter.model.Background;
import gherkin.formatter.model.Comment;
import gherkin.formatter.model.Examples;
import gherkin.formatter.model.Feature;
import gherkin.formatter.model.PyString;
import gherkin.formatter.model.Result;
import gherkin.formatter.model.Row;
import gherkin.formatter.model.Scenario;
import gherkin.formatter.model.ScenarioOutline;
import gherkin.formatter.model.Step;
import gherkin.formatter.model.Tag;
import gherkin.formatter.model.TagStatement;
import gherkin.util.Mapper;

import java.io.*;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.List;
import java.util.regex.Pattern;

import static gherkin.formatter.Colors.comments;
import static gherkin.util.FixJava.join;
import static gherkin.util.FixJava.map;

Expand All @@ -19,7 +32,6 @@
*/
public class PrettyFormatter implements Formatter {
private final PrintWriter out;
private final boolean monochrome;
private int maxStepLength = -1;
private int[] stepLengths;
private int stepIndex;
Expand All @@ -32,13 +44,12 @@ public String map(Object tag) {
}
};

public PrettyFormatter(Writer out, boolean monochrome) {
public PrettyFormatter(Writer out) {
this.out = new PrintWriter(out);
this.monochrome = monochrome;
}

public PrettyFormatter(OutputStream out, boolean monochrome) throws UnsupportedEncodingException {
this(new OutputStreamWriter(out, "UTF-8"), monochrome);
public PrettyFormatter(OutputStream out) {
this(new OutputStreamWriter(out));
}

public void uri(String uri) {
Expand Down Expand Up @@ -72,7 +83,12 @@ private void printTagStatement(TagStatement statement) {
out.println();
printComments(statement.getComments(), " ");
printTags(statement.getTags(), " ");
out.println(" " + statement.getKeyword() + ": " + statement.getName() + indentedScenarioLocation(statement.getKeyword(), statement.getName(), statement.getLine()));
out.print(" ");
out.print(statement.getKeyword());
out.print(": ");
out.print(statement.getName());
printIndentedScenarioLocation(statement.getKeyword(), statement.getName(), statement.getLine());
out.println();
printDescription(statement.getDescription(), " ", true);
out.flush();
}
Expand All @@ -81,7 +97,11 @@ public void examples(Examples examples) {
out.println();
printComments(examples.getComments(), " ");
printTags(examples.getTags(), " ");
out.println(" " + examples.getKeyword() + ": " + examples.getName());
out.print(" ");
out.print(examples.getKeyword());
out.print(": ");
out.print(examples.getName());
out.println();
printDescription(examples.getDescription(), " ", true);
table(examples.getRows());
}
Expand All @@ -102,7 +122,8 @@ private void printStep(Step step) {
out.print(" ");
out.print(step.getKeyword());
out.print(step.getName());
out.println(indentedStepLocation(location));
printIndentedStepLocation(location);
out.println();
if(step.getResult() != null && step.getResult().getErrorMessage() != null) {
out.println(indent(step.getResult().getErrorMessage(), " "));
}
Expand Down Expand Up @@ -170,12 +191,6 @@ public void steps(List<Step> steps) {
stepIndex = -1;
}

private void padSpace(int indent, StringBuffer buffer) {
for (int i = 0; i < indent; i++) {
buffer.append(" ");
}
}

private void padSpace(int indent) {
for (int i = 0; i < indent; i++) {
out.write(" ");
Expand All @@ -197,26 +212,22 @@ private void printTags(List<Tag> tags, String indent) {
out.flush();
}

private String indentedScenarioLocation(String keyword, String name, long line) {
if (maxStepLength == -1) return "";
private void printIndentedScenarioLocation(String keyword, String name, long line) {
if (maxStepLength == -1) return;
int l = keyword.length() + name.length();
maxStepLength = Math.max(maxStepLength, l);
int indent = maxStepLength - l;

StringBuffer buffer = new StringBuffer();
padSpace(indent, buffer);
buffer.append(" ").append(comments("# " + uri + ":" + line, monochrome));
return buffer.toString();
padSpace(indent);
out.append(" ").append("# ").append(uri).append(":").print(line);
}

private String indentedStepLocation(String location) {
if (location == null || "".equals(location)) return "";
private void printIndentedStepLocation(String location) {
if (location == null || "".equals(location)) return;
int indent = maxStepLength - stepLengths[stepIndex += 1];

StringBuffer buffer = new StringBuffer();
padSpace(indent, buffer);
buffer.append(" ").append(comments("# " + location, monochrome));
return buffer.toString();
padSpace(indent);
out.append(" ").append("# ").append(location);
}

private void printDescription(String description, String indentation, boolean newline) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
public class PrettyFormatterTest {
@Test
public void testShouldPrintNiceColors() throws UnsupportedEncodingException {
PrettyFormatter f = new PrettyFormatter(System.out, false);
PrettyFormatter f = new PrettyFormatter(System.out);
Argument arg = new Argument(7, "6");
Result result = new Result("passed", null, Arrays.asList(arg), null);
Step step = new Step(new ArrayList<Comment>(), "Given ", "I have 6 cukes", 1, null, result);
Expand Down
21 changes: 4 additions & 17 deletions lib/gherkin/formatter/argument.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,11 @@ module Gherkin
module Formatter
class Argument
native_impl('gherkin')
attr_reader :byte_offset, :val
attr_reader :offset, :val

def initialize(byte_offset, val)
@byte_offset, @val = byte_offset, val
end

def self.format(string, argument_format, arguments)
arguments ||= []
s = string.dup
offset = past_offset = 0
arguments.each do |arg|
next if arg.byte_offset.nil? || arg.byte_offset < past_offset
replacement = argument_format.format_argument(arg.val)
s[arg.byte_offset + offset, arg.val.length] = replacement
offset += replacement.unpack("U*").length - arg.val.unpack("U*").length
past_offset = arg.byte_offset + arg.val.length
end
s
# Creates a new Argument that starts at character offset +offset+ with value +val+
def initialize(offset, val)
@offset, @val = offset, val
end
end
end
Expand Down
16 changes: 9 additions & 7 deletions lib/gherkin/formatter/colors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,11 @@ module Colors
ALIASES.each do |method, color|
unless method =~ /.*_param/
code = <<-EOF
def #{method}(string=nil, monochrome=false, &proc)
return string if monochrome
def #{method}(string=nil, &proc)
#{ALIASES[method].split(",").join("(") + "(string, &proc" + ")" * ALIASES[method].split(",").length}
end
# This resets the colour to the non-param colour
def #{method}_param(string=nil, monochrome=false, &proc)
return string if monochrome
#{ALIASES[method+'_param'].split(",").join("(") + "(string, &proc" + ")" * ALIASES[method+'_param'].split(",").length} + #{ALIASES[method].split(",").join(' + ')}
def #{method}_param(string=nil, &proc)
#{ALIASES[method+'_param'].split(",").join("(") + "(string, &proc" + ")" * ALIASES[method+'_param'].split(",").length}
end
EOF
eval(code)
Expand Down Expand Up @@ -112,8 +109,13 @@ def grey(m) #:nodoc:
"\e[90m#{m}\e[0m"
end
end

define_grey

COLOR_PATTERN = /\e\[(?:[34][0-7]|[0-9]|90)?m/
def monochrome(string)
string.gsub(COLOR_PATTERN, '')
end
end
end
end
8 changes: 8 additions & 0 deletions lib/gherkin/formatter/model.rb
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,14 @@ def replay(formatter)
formatter.step(self)
end

def status
result ? result.status : 'undefined'
end

def arguments
result ? result.arguments : []
end

def to_hash
hash = super
if Array === @multiline_arg
Expand Down
9 changes: 0 additions & 9 deletions lib/gherkin/formatter/monochrome_format.rb

This file was deleted.

28 changes: 28 additions & 0 deletions lib/gherkin/formatter/monochrome_io.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require 'gherkin/formatter/colors'
require 'gherkin/native'

module Gherkin
module Formatter
class MonochromeIO
native_impl('gherkin')

include Colors

def initialize(io)
@io = io
end

def write(*a)
@io.write(*(a.map{|e| monochrome(e)}))
end

def puts(*a)
@io.puts(*(a.map{|e| monochrome(e)}))
end

def string
@io.string
end
end
end
end
Loading

0 comments on commit da8e06a

Please sign in to comment.