Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Comments and Tags now have line numbers in JSON, making it possible t…

…o properly filter features coming from JSON
  • Loading branch information...
commit e58885ff274adf6a190f6b2519f6d9b61e450159 1 parent 6ca4e1b
@aslakhellesoy aslakhellesoy authored
View
41 features/json_formatter.feature
@@ -17,7 +17,7 @@ Feature: JSON formatter
"""
{
"type": "feature",
- "comments": ["# language: no", "# Another comment"],
+ "comments": [{"value": "# language: no", "line": 1}, {"value": "# Another comment", "line": 2}],
"keyword": "Egenskap",
"name": "Kjapp",
"description": "",
@@ -74,7 +74,7 @@ Feature: JSON formatter
"""
{
"type": "feature",
- "tags": ["@one"],
+ "tags": [{"name": "@one", "line":1}],
"keyword": "Feature",
"name": "OH HAI",
"description": "",
@@ -102,7 +102,7 @@ Feature: JSON formatter
},
{
"type": "scenario",
- "tags": ["@two"],
+ "tags": [{"name": "@two", "line":8}],
"keyword": "Scenario",
"name": "_why",
"description": "",
@@ -122,7 +122,7 @@ Feature: JSON formatter
},
{
"type": "scenario_outline",
- "tags": ["@three", "@four"],
+ "tags": [{"name": "@three", "line":13}, {"name": "@four", "line":13}],
"keyword": "Scenario Outline",
"name": "Life",
"description": "",
@@ -137,7 +137,7 @@ Feature: JSON formatter
"examples": [
{
"type": "examples",
- "tags": ["@five"],
+ "tags": [{"name": "@five", "line":17}],
"keyword": "Examples",
"name": "Real life",
"description": "",
@@ -170,31 +170,38 @@ Feature: JSON formatter
"keyword": "When ",
"name": "I was",
"line": 24,
- "table": [
- {
- "line": 25,
- "cells": ["asleep"]
- }
- ]
+ "multiline_arg": {
+ "type": "table",
+ "value": [
+ {
+ "line": 25,
+ "cells": ["asleep"]
+ }
+ ]
+ }
},
{
"keyword": "And ",
"name": "so",
"line": 26,
- "py_string": "innocent"
+ "multiline_arg": {
+ "type": "py_string",
+ "value": "innocent",
+ "line": 27
+ }
}
]
},
{
"type": "scenario_outline",
- "comments": ["# The"],
+ "comments": [{"value": "# The", "line":31}],
"keyword": "Scenario Outline",
"name": "with",
"description": "",
"line": 32,
"steps": [
{
- "comments": ["# all"],
+ "comments": [{"value": "# all", "line":33}],
"keyword": "Then ",
"line": 34,
"name": "nice"
@@ -203,14 +210,14 @@ Feature: JSON formatter
"examples": [
{
"type": "examples",
- "comments": ["# comments", "# everywhere"],
+ "comments": [{"value": "# comments", "line": 36}, {"value": "# everywhere", "line": 37}],
"keyword": "Examples",
"name": "An example",
"description": "",
"line": 38,
"table": [
{
- "comments": ["# I mean"],
+ "comments": [{"value": "# I mean", "line": 39}],
"line": 40,
"cells": ["partout"]
}
@@ -260,7 +267,7 @@ Feature: JSON formatter
},
{
"type": "scenario",
- "comments": ["# Writing JSON by hand sucks"],
+ "comments": [{"value": "# Writing JSON by hand sucks", "line": 6}],
"keyword": "Scenario",
"name": "",
"description": "",
View
50 features/json_parser.feature
@@ -11,7 +11,10 @@ Feature: JSON lexer
"""
{
"type": "feature",
- "comments": ["# language: no", "# Another comment"],
+ "comments": [
+ {"value": "# language: no"},
+ {"value": "# Another comment"}
+ ],
"description": "",
"keyword": "Egenskap",
"name": "Kjapp",
@@ -34,7 +37,7 @@ Feature: JSON lexer
"comments": [],
"keyword": "Feature",
"name": "OH HAI",
- "tags": ["@one"],
+ "tags": [{"name": "@one"}],
"uri": "test.feature",
"description": "",
"elements":[
@@ -63,7 +66,7 @@ Feature: JSON lexer
},
{
"comments": [],
- "tags": ["@two"],
+ "tags": [{"name": "@two"}],
"keyword": "Scenario",
"name": "_why",
"description": "",
@@ -86,7 +89,7 @@ Feature: JSON lexer
},
{
"comments": [],
- "tags": ["@three", "@four"],
+ "tags": [{"name": "@three"}, {"name": "@four"}],
"keyword": "Scenario Outline",
"name": "Life",
"description": "",
@@ -104,7 +107,7 @@ Feature: JSON lexer
{
"type": "examples",
"comments": [],
- "tags": ["@five"],
+ "tags": [{"name": "@five"}],
"keyword": "Examples",
"name": "Real life",
"description": "",
@@ -143,25 +146,32 @@ Feature: JSON lexer
"keyword": "When ",
"name": "I was",
"line": 24,
- "table": [
- {
- "comments": [],
- "line": 25,
- "cells": ["asleep"]
- }
- ]
+ "multiline_arg": {
+ "type": "table",
+ "value": [
+ {
+ "comments": [],
+ "line": 25,
+ "cells": ["asleep"]
+ }
+ ]
+ }
},
{
"comments": [],
"keyword": "And ",
"name": "so",
"line": 26,
- "py_string": "innocent"
+ "multiline_arg": {
+ "type": "py_string",
+ "value": "innocent",
+ "line": 27
+ }
}
]
},
{
- "comments": ["# The"],
+ "comments": [{"value": "# The"}],
"tags": [],
"keyword": "Scenario Outline",
"description": "",
@@ -170,7 +180,7 @@ Feature: JSON lexer
"name": "with",
"steps": [
{
- "comments": ["# all"],
+ "comments": [{"value": "# all"}],
"keyword": "Then ",
"line": 34,
"name": "nice"
@@ -179,22 +189,20 @@ Feature: JSON lexer
"examples": [
{
"type": "examples",
- "comments": ["# comments", "# everywhere"],
+ "comments": [{"value": "# comments"}, {"value": "# everywhere"}],
"tags": [],
"keyword": "Examples",
"name": "An example",
- // TODO - the description should now be the comment
- // It should be on the first row of the examples_table!
"description": "",
"line": 38,
"table": [
{
- "comments": ["# I mean"],
+ "comments": [{"value": "# I mean"}],
"line": 40,
"cells": ["partout"]
},
{
- "comments": ["# I really mean"],
+ "comments": [{"value": "# I really mean"}],
"line": 40,
"cells": ["bartout"]
}
@@ -281,7 +289,7 @@ Feature: JSON lexer
},
{
"type": "scenario",
- "comments": ["# Writing JSON by hand sucks"],
+ "comments": [{"value": "# Writing JSON by hand sucks"}],
"tags": [],
"keyword": "Scenario",
"name": "",
View
44 lib/gherkin/formatter/json_formatter.rb
@@ -1,6 +1,7 @@
require 'json'
require 'json/pure' # Needed to make JSON.generate work.
require 'gherkin/rubify'
+require 'gherkin/formatter/model'
module Gherkin
module Formatter
@@ -52,12 +53,28 @@ def statement_hash(type, statement)
'line' => statement.line,
}
element['type'] = type if type
- element['comments'] = statement.comments.map{|comment| comment.value} if statement.comments && statement.comments.any?
- element['tags'] = statement.tags.map{|tag| tag.name} if statement.tags && statement.tags.any?
+ add_comments(element, statement)
+ add_tags(element, statement)
element['description'] = statement.description if statement.description
element
end
+ def add_comments(element, comment_holder)
+ if comment_holder.comments && comment_holder.comments.any?
+ element['comments'] = comment_holder.comments.map do |comment|
+ {'value' => comment.value, 'line' => comment.line}
+ end
+ end
+ end
+
+ def add_tags(element, statement)
+ if statement.tags && statement.tags.any?
+ element['tags'] = statement.tags.map do |tag|
+ {'name' => tag.name, 'line' => tag.line}
+ end
+ end
+ end
+
def add_element(type, statement)
element = statement_hash(type, statement)
@json_hash['elements'] ||= []
@@ -84,15 +101,32 @@ def last_element
def to_hash_array(rows)
rows.map do |row|
e = {"cells" => row.cells.to_a, "line" => row.line}
- e["comments"] = row.comments.map{|comment| comment.value} if row.comments && row.comments.any?
+ add_comments(e, row)
e
end
end
def step_arg_to_hash(multiline_arg)
- return {} if multiline_arg.nil?
multiline_arg = rubify(multiline_arg)
- Array === multiline_arg ? {"table" => to_hash_array(multiline_arg) } : { "py_string" => multiline_arg.value }
+ case multiline_arg
+ when Array
+ {
+ "multiline_arg" => {
+ "type" => "table",
+ "value" => to_hash_array(multiline_arg)
+ }
+ }
+ when Model::PyString
+ {
+ "multiline_arg" => {
+ "type" => "py_string",
+ "value" => multiline_arg.value,
+ "line" => multiline_arg.line
+ }
+ }
+ else
+ {}
+ end
end
end
end
View
44 lib/gherkin/json_parser.rb
@@ -46,54 +46,56 @@ def parse_element(feature_element)
comments_for(examples)
tags_for(examples)
multiline_event(examples)
- rows_for(examples)
+ rows_for(examples['table'])
end
end
end
def comments_for(element)
- element["comments"].each do |comment|
- @listener.comment(comment, line_for(comment))
- end if element["comments"]
+ (element["comments"] || []).each do |comment|
+ @listener.comment(comment['value'], comment['line'])
+ end
end
def tags_for(element)
- element["tags"].each do |tag|
- @listener.tag(tag, line_for(tag))
- end if element["tags"]
+ (element["tags"] || []).each do |tag|
+ @listener.tag(tag['name'], tag['line'])
+ end
end
def steps_for(element)
element["steps"].each do |step|
comments_for(step)
- @listener.step(step["keyword"], step["name"], line_for(step))
- py_string_for(step)
- rows_for(step)
+ @listener.step(step["keyword"], step["name"], step['line'])
+ multiline_arg_for(step)
end
end
- def py_string_for(element)
- @listener.py_string(element["py_string"], 0) if element["py_string"]
+ def multiline_arg_for(element)
+ if ma = element["multiline_arg"]
+ case ma["type"]
+ when "py_string"
+ @listener.py_string(ma["value"], ma["line"])
+ when "table"
+ rows_for(ma["value"])
+ end
+ end
end
- def rows_for(element)
- element["table"].each do |row|
+ def rows_for(rows)
+ (rows || []).each do |row|
comments_for(row)
- @listener.row(cells_for(row), 0)
- end if element["table"]
+ @listener.row(cells_for(row), row['line'])
+ end
end
def cells_for(row)
row["cells"]
end
- def line_for(element)
- element["line"].to_i || 0
- end
-
def multiline_event(element)
if element["keyword"]
- @listener.__send__(element['type'].to_sym, element["keyword"], element["name"] || "", element["description"] || "", line_for(element))
+ @listener.__send__(element['type'].to_sym, element["keyword"], element["name"] || "", element["description"] || "", element['line'])
end
end
end
View
93 spec/gherkin/fixtures/complex.json
@@ -4,8 +4,8 @@
"keyword": "Feature",
"description": "In order to test multiline forms",
"tags": [
- "@tag1",
- "@tag2"
+ {"name": "@tag1"},
+ {"name": "@tag2"}
],
"elements": [
{ "type": "background",
@@ -24,15 +24,20 @@
"keyword": "Scenario Outline",
"name": "An Scenario Outline",
"description": "",
- "tags": [ "@foo" ],
+ "tags": [
+ {"name": "@foo"}
+ ],
"steps": [
{ "name": "A step with a table",
"keyword": "Given ",
- "table" : [
- {"cells":
- [ "a","row","for","a","step" ]
- }
- ]
+ "multiline_arg": {
+ "type": "table",
+ "value" : [
+ {"cells":
+ [ "a","row","for","a","step" ]
+ }
+ ]
+ }
}
],
"examples": [
@@ -48,7 +53,7 @@
[ "The","Blanks" ]
}
],
- "tags" : [ "@exampletag" ]
+ "tags" : [ {"name": "@exampletag"} ]
}
]
},
@@ -57,8 +62,8 @@
"name" : "Reading a Scenario",
"description": "",
"tags" : [
- "@tag3",
- "@tag4"
+ {"name": "@tag3"},
+ {"name": "@tag4"}
],
"steps" : [
{ "name" : "there is a step",
@@ -71,38 +76,45 @@
"keyword": "Scenario",
"name" : "Reading a second scenario",
"description": "With two lines of text",
- "tags" : [ "@tag3" ],
+ "tags" : [ {"name": "@tag3"} ],
"steps" : [
{ "name" : "a third step with a table",
"keyword": "Given ",
- "table" : [
- { "cells" :
- [ "a","b" ]
- },
- { "cells" :
- [ "c","d" ]
- },
- { "cells" :
- [ "e", "f" ]
- }
- ]
+ "multiline_arg": {
+ "type": "table",
+ "value": [
+ {
+ "cells" : [ "a","b" ],
+ "line" : 987
+ },
+ { "cells" :
+ [ "c","d" ]
+ },
+ { "cells" :
+ [ "e", "f" ]
+ }
+ ]
+ }
},
{ "name" : "I am still testing things",
"keyword": "Given ",
- "table" : [
- { "cells" :
- [ "g","h" ]
- },
- { "cells" :
- [ "e","r" ]
- },
- { "cells" :
- [ "k", "i" ]
- },
- { "cells" :
- [ "n", "" ]
- }
- ]
+ "multiline_arg": {
+ "type": "table",
+ "value": [
+ { "cells" :
+ [ "g","h" ]
+ },
+ { "cells" :
+ [ "e","r" ]
+ },
+ { "cells" :
+ [ "k", "i" ]
+ },
+ { "cells" :
+ [ "n", "" ]
+ }
+ ]
+ }
},
{ "name" : "I am done testing these tables",
"keyword": "Given " },
@@ -117,7 +129,12 @@
"steps" : [
{ "name" : "All work and no play",
"keyword": "Given ",
- "py_string" : "Makes Homer something something\nAnd something else" },
+ "multiline_arg": {
+ "type": "py_string",
+ "value": "Makes Homer something something\nAnd something else",
+ "line": 777
+ }
+ },
{ "name" : "crazy",
"keyword": "Given " }
]
View
83 spec/gherkin/json_parser_spec.rb
@@ -31,23 +31,12 @@ module Gherkin
end
end
- describe "Missing line numbers" do
- it "should indicate a line number of 0 if a line attribute doesn't exist" do
- @parser.parse_with_listener('{ "type": "feature", "name": "My Sweet Featur", "keyword": "Feature", "description": "" }', @listener)
- @listener.to_sexp.should == [
- [:location, "unknown.json"],
- [:feature, "Feature", "My Sweet Featur", "", 0],
- [:eof]
- ]
- end
- end
-
describe "Keywords" do
it "should use the keyword from the source when provided" do
@parser.parse_with_listener('{ "type": "feature", "name" : "My Sweet Featur", "language": "fr", "keyword": "Feature", "description": "" }', @listener)
@listener.to_sexp.should == [
[:location, "unknown.json"],
- [:feature, "Feature", "My Sweet Featur", "", 0],
+ [:feature, "Feature", "My Sweet Featur", "", nil],
[:eof]
]
end
@@ -58,42 +47,42 @@ module Gherkin
@parser.parse_with_listener(fixture("complex.json"), @listener)
@listener.to_sexp.should == [
[:location, "unknown.json"],
- [:tag, "@tag1", 0],
- [:tag, "@tag2", 0],
- [:feature, "Feature", "Feature Text","In order to test multiline forms", 0],
- [:background, "Background", "", "", 0],
- [:step, "Given ", "this is a background step", 0],
+ [:tag, "@tag1", nil],
+ [:tag, "@tag2", nil],
+ [:feature, "Feature", "Feature Text","In order to test multiline forms", nil],
+ [:background, "Background", "", "", nil],
+ [:step, "Given ", "this is a background step", nil],
[:step, "When ", "this is another one", 412],
- [:tag, "@foo", 0],
- [:scenario_outline, "Scenario Outline", "An Scenario Outline","", 0],
- [:step, "Given ", "A step with a table", 0],
- [:row, %w{a row for a step}, 0],
- [:tag, "@exampletag", 0],
- [:examples, "Examples", "Sweet Example", "", 0],
- [:row, %w{Fill In}, 0],
- [:row, %w{The Blanks}, 0],
- [:tag, "@tag3", 0],
- [:tag, "@tag4", 0],
- [:scenario, "Scenario", "Reading a Scenario", "", 0],
- [:step, "Given ", "there is a step", 0],
- [:step, "But ", "not another step", 0],
- [:tag, "@tag3", 0],
- [:scenario, "Scenario", "Reading a second scenario", "With two lines of text", 0],
- [:step, "Given ", "a third step with a table", 0],
- [:row, %w{a b}, 0],
- [:row, %w{c d}, 0],
- [:row, %w{e f}, 0],
- [:step, "Given ", "I am still testing things", 0],
- [:row, %w{g h}, 0],
- [:row, %w{e r}, 0],
- [:row, %w{k i}, 0],
- [:row, ['n', ''], 0],
- [:step, "Given ", "I am done testing these tables", 0],
- [:step, "Given ", "I am happy", 0],
- [:scenario, "Scenario", "Hammerzeit", "", 0],
- [:step, "Given ", "All work and no play", 0],
- [:py_string, "Makes Homer something something\nAnd something else", 0 ],
- [:step, "Given ", "crazy", 0],
+ [:tag, "@foo", nil],
+ [:scenario_outline, "Scenario Outline", "An Scenario Outline","", nil],
+ [:step, "Given ", "A step with a table", nil],
+ [:row, %w{a row for a step}, nil],
+ [:tag, "@exampletag", nil],
+ [:examples, "Examples", "Sweet Example", "", nil],
+ [:row, %w{Fill In}, nil],
+ [:row, %w{The Blanks}, nil],
+ [:tag, "@tag3", nil],
+ [:tag, "@tag4", nil],
+ [:scenario, "Scenario", "Reading a Scenario", "", nil],
+ [:step, "Given ", "there is a step", nil],
+ [:step, "But ", "not another step", nil],
+ [:tag, "@tag3", nil],
+ [:scenario, "Scenario", "Reading a second scenario", "With two lines of text", nil],
+ [:step, "Given ", "a third step with a table", nil],
+ [:row, %w{a b}, 987],
+ [:row, %w{c d}, nil],
+ [:row, %w{e f}, nil],
+ [:step, "Given ", "I am still testing things", nil],
+ [:row, %w{g h}, nil],
+ [:row, %w{e r}, nil],
+ [:row, %w{k i}, nil],
+ [:row, ['n', ''], nil],
+ [:step, "Given ", "I am done testing these tables", nil],
+ [:step, "Given ", "I am happy", nil],
+ [:scenario, "Scenario", "Hammerzeit", "", nil],
+ [:step, "Given ", "All work and no play", nil],
+ [:py_string, "Makes Homer something something\nAnd something else", 777],
+ [:step, "Given ", "crazy", nil],
[:eof]
]
end
Please sign in to comment.
Something went wrong with that request. Please try again.