require 'multi_json' require 'gherkin/formatter/model' require 'gherkin/native' require 'base64' module Gherkin module Formatter # This class doesn't really generate JSON - instead it populates an Array that can easily # be turned into JSON. class JSONFormatter native_impl('gherkin') include Base64 def initialize(io) raise "Must be writeable" unless io.respond_to?(:write) @io = io @feature_hashes = [] @current_step_or_hook = nil end def done @io.write(MultiJson.dump(@feature_hashes, :pretty => true)) end def uri(uri) @uri = uri end def feature(feature) @feature_hash = feature.to_hash @feature_hash['uri'] = @uri @feature_hashes << @feature_hash end def background(background) feature_elements << background.to_hash end def scenario(scenario) feature_elements << scenario.to_hash end def scenario_outline(scenario_outline) feature_elements << scenario_outline.to_hash end def examples(examples) all_examples << examples.to_hash end def step(step) @current_step_or_hook = step.to_hash steps << @current_step_or_hook end def match(match) @current_step_or_hook['match'] = match.to_hash end def result(result) @current_step_or_hook['result'] = result.to_hash end def append_duration(timestamp) #check to make sure result exists (scenario outlines do not have results yet) if !@current_step_or_hook['result'].nil? #convert to nanoseconds timestamp = timestamp * 1000000000 rshash = @current_step_or_hook['result'].to_hash rshash['duration'] = timestamp.to_i @current_step_or_hook['result'] = rshash end end def before(match, result) add_hook(match, result, "before") end def after(match, result) add_hook(match, result, "after") end def embedding(mime_type, data) embeddings << {'mime_type' => mime_type, 'data' => encode64s(data)} end def write(text) output << text end def eof end private def add_hook(match, result, hook) hooks = feature_element[hook] ||= [] hooks << {'match' => match.to_hash, 'result' => result.to_hash} end def feature_elements @feature_hash['elements'] ||= [] end def feature_element feature_elements[-1] end def all_examples feature_element['examples'] ||= [] end def steps feature_element['steps'] ||= [] end def embeddings @current_step_or_hook['embeddings'] ||= [] end def output @current_step_or_hook['output'] ||= [] end def encode64s(data) # Strip newlines Base64.encode64(data).gsub(/\n/, '') end end end end