-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
WIP on i18n: re-org of FeatureParser stuff to accommodate Language ob…
…j; old tests pass but new do not yet
- Loading branch information
Showing
17 changed files
with
363 additions
and
230 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# language: no | ||
@i18n | ||
Egenskap: Summering | ||
For å unngå at firmaet går konkurs | ||
Må regnskapsførerere bruke en regnemaskin for å legge sammen tall | ||
|
||
Scenario: to tall | ||
Gitt at jeg har tastet inn 5 | ||
Og at jeg har tastet inn 7 | ||
Når jeg summerer | ||
Så skal resultatet være 12 | ||
|
||
Scenario: tre tall | ||
Gitt at jeg har tastet inn 5 | ||
Og at jeg har tastet inn 7 | ||
Og at jeg har tastet inn 1 | ||
Når jeg summerer | ||
Så skal resultatet være 13 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# Copyright 2011 ThoughtWorks, Inc. Licensed under the MIT License | ||
|
||
module Cuporter | ||
module FeatureParser | ||
class Language | ||
|
||
def initialize(line_1) | ||
@iso_code = line_1.to_s =~ LANGUAGE_LINE ? $1 : 'en' | ||
end | ||
|
||
def feature_pattern | ||
/^\s*(Feature:[^#]*)/u | ||
end | ||
alias :feature_line :feature_pattern | ||
|
||
def scenario_pattern | ||
/^\s*(Scenario:[^#]*)$/u | ||
end | ||
alias :scenario_line :scenario_pattern | ||
|
||
def scenario_outline_pattern | ||
/^\s*(Scenario Outline:[^#]*)$/u | ||
end | ||
alias :scenario_outline_line :scenario_outline_pattern | ||
|
||
def examples_pattern | ||
/^\s*((Scenarios|Examples):[^#]*)$/u | ||
end | ||
alias :examples_line :examples_pattern | ||
|
||
|
||
LANGUAGE_LINE = /^\s*#\s*language:\s*([\w-]+)/u | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# Copyright 2011 ThoughtWorks, Inc. Licensed under the MIT License | ||
|
||
module Cuporter | ||
module FeatureParser | ||
class NodeParser < ParserBase | ||
|
||
# ++sub_expression++ is the paren group in the regex, dereferenced with $1 in the caller | ||
def new_feature_node(sub_expression, file) | ||
f = Node.new_node(:Feature, @doc, :cuke_name => sub_expression, :tags => @current_tags, :file_path => file) | ||
f.filter = @filter | ||
f | ||
end | ||
|
||
def handle_scenario_line(sub_expression) | ||
if @filter.pass?(@current_tags | @feature.tags) | ||
@feature.add_child(Node.new_node(:Scenario, @doc, :cuke_name => sub_expression, :tags => @current_tags)) | ||
end | ||
end | ||
|
||
def new_scenario_outline_node(sub_expression) | ||
so = Node.new_node(:ScenarioOutline, @doc, :cuke_name => sub_expression, :tags => @current_tags) | ||
so.filter = @filter | ||
so | ||
end | ||
|
||
def handle_example_set_line | ||
if @filter.pass?(@feature.tags | @scenario_outline.tags | @example_set.tags) | ||
@scenario_outline.add_child @example_set | ||
end | ||
end | ||
|
||
def new_example_set_node(sub_expression) | ||
es = Node.new_node(:Examples, @doc, :cuke_name => sub_expression, :tags => @current_tags) | ||
es.filter = @filter | ||
es | ||
end | ||
|
||
def new_example_line(sub_expression) | ||
example_type = :ExampleHeader | ||
# if the example set has a child already, then it must be the header | ||
example_type = :Example if @example_set.has_children? | ||
@example_set.add_child(Node.new_node(example_type, @doc, :cuke_name => sub_expression)) | ||
end | ||
|
||
def close_scenario_outline | ||
if @scenario_outline | ||
if @example_set | ||
handle_example_set_line | ||
@example_set = nil | ||
end | ||
@feature.add_child(@scenario_outline) if @scenario_outline.has_children? | ||
@scenario_outline = nil | ||
end | ||
end | ||
|
||
def initialize(file, doc, filter) | ||
super(file) | ||
@filter = filter | ||
@doc = doc | ||
end | ||
|
||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# Copyright 2010 ThoughtWorks, Inc. Licensed under the MIT License | ||
|
||
module Cuporter | ||
module FeatureParser | ||
class ParserBase | ||
TAG_LINE = /^\s*(@\w.+)/u | ||
EXAMPLE_LINE = /^\s*(\|.*\|)\s*$/u | ||
PY_STRING_LINE = /^\s*"""\s*$/u | ||
|
||
def initialize(file) | ||
@file = file | ||
@current_tags = [] | ||
@lines = File.read(@file).split(/\n/) | ||
@lang = Language.new(@lines.first)# =~ LANGUAGE_LINE ? $1 : 'en' | ||
end | ||
attr_reader :lang | ||
attr_writer :root | ||
|
||
def file_relative_path | ||
@file_relative_path ||= @file.sub(/^.*#{@root}\//,"#{@root}/") | ||
end | ||
|
||
def parse_feature | ||
@open_comment_block = false | ||
|
||
@lines.each do |line| | ||
next if @open_comment_block && line !~ PY_STRING_LINE | ||
|
||
case line | ||
when PY_STRING_LINE | ||
# toggle, to declare the multiline comment 'heredoc' open or closed | ||
@open_comment_block = !@open_comment_block | ||
when TAG_LINE | ||
# may be more than one tag line | ||
@current_tags |= clean_cuke_line($1).split(/\s+/) | ||
when @lang.feature_line | ||
@feature = new_feature_node(clean_cuke_line($1), file_relative_path) | ||
@current_tags = [] | ||
when @lang.scenario_line | ||
# How do we know when we have read all the lines from a "Scenario Outline:"? | ||
# One way is when we encounter a "Scenario:" | ||
close_scenario_outline | ||
|
||
handle_scenario_line(clean_cuke_line($1)) | ||
@current_tags = [] | ||
when @lang.scenario_outline_line | ||
# ... another is when we hit a subsequent "Scenario Outline:" | ||
close_scenario_outline | ||
|
||
@scenario_outline = new_scenario_outline_node(clean_cuke_line($1)) | ||
@current_tags = [] | ||
when @lang.examples_line | ||
handle_example_set_line if @example_set | ||
|
||
@example_set = new_example_set_node(clean_cuke_line($1)) | ||
@current_tags = [] | ||
when @example_set && EXAMPLE_LINE | ||
new_example_line(clean_cuke_line($1)) | ||
end | ||
end | ||
|
||
# EOF is the final way that we know we are finished with a "Scenario Outline" | ||
close_scenario_outline | ||
return @feature | ||
end | ||
|
||
def clean_cuke_line(sub_expression) | ||
sub_expression.strip.escape_apostrophe | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
# Copyright 2011 ThoughtWorks, Inc. Licensed under the MIT License | ||
|
||
module Cuporter | ||
module FeatureParser | ||
class TagNodesParser < ParserBase | ||
|
||
# ++sub_expression++ is the paren group in the regex, dereferenced with $1 in the caller | ||
def new_feature_node(sub_expression, file) | ||
{:cuke_name => sub_expression, :tags => @current_tags, :file_path => file} | ||
end | ||
|
||
def handle_scenario_line(sub_expression) | ||
if @filter.pass?(@feature[:tags] | @current_tags) | ||
s = {:cuke_name => sub_expression, :tags => @current_tags} | ||
|
||
(@feature[:tags] | s[:tags]).each do |tag| | ||
next unless @filter.pass?([tag]) | ||
add_scenario(tag, @feature, s) | ||
end | ||
end | ||
end | ||
|
||
def new_scenario_outline_node(sub_expression) | ||
{:cuke_name => sub_expression, :tags => @current_tags} | ||
end | ||
|
||
def handle_example_set_line | ||
end | ||
|
||
def new_example_set_node(sub_expression) | ||
{:cuke_name => sub_expression.to_s.strip, :tags => @current_tags} | ||
end | ||
|
||
def new_example_line(sub_expression) | ||
context_tags = (@feature[:tags] | @scenario_outline[:tags] | @example_set[:tags]) | ||
if @filter.pass?(context_tags) | ||
e = {:cuke_name => sub_expression} | ||
|
||
context_tags.each do |tag| | ||
next unless @filter.pass?([tag]) | ||
add_example(tag, @feature, @scenario_outline, @example_set, e) | ||
end | ||
end | ||
end | ||
|
||
def close_scenario_outline | ||
if @scenario_outline | ||
if @example_set | ||
@example_set = nil | ||
end | ||
@scenario_outline = nil | ||
end | ||
end | ||
def add_scenario(tag, feature, scenario) | ||
unless ( t = @report.tag_node(tag)) | ||
t = @report.add_child(Node.new_node(:tag, @doc, 'cuke_name' => tag)) | ||
end | ||
unless ( f = t.feature_node(feature) ) | ||
f = t.add_child(Node.new_node(:Feature, @doc, feature)) | ||
end | ||
f.add_child(Node.new_node(:Scenario, @doc, scenario)) | ||
end | ||
|
||
def add_example(tag, feature, scenario_outline, example_set, example) | ||
unless ( t = @report.tag_node(tag)) | ||
t = @report.add_child(Node.new_node(:Tag, @doc, 'cuke_name' => tag)) | ||
end | ||
unless ( f = t.feature_node(feature) ) | ||
f = t.add_child(Node.new_node(:Feature, @doc, feature)) | ||
end | ||
unless ( so = f.scenario_outline_node(scenario_outline) ) | ||
so = f.add_child(Node.new_node(:ScenarioOutline, @doc, scenario_outline)) | ||
end | ||
|
||
# The first Example is an ExampleHeader, which does not get counted or | ||
# numbered. If the ExampleSet is new, it has no children, and therefore | ||
# this is the first and should be an ExampleHeader. | ||
example_type = :Example | ||
unless ( es = so.example_set_node(example_set) ) | ||
es = so.add_child(Node.new_node(:Examples, @doc, example_set)) | ||
example_type = :ExampleHeader | ||
end | ||
es.add_child(Node.new_node(example_type, @doc, example)) | ||
end | ||
|
||
|
||
def initialize(file, report, filter) | ||
super(file) | ||
@filter = filter | ||
@report = report | ||
@doc = report.document | ||
end | ||
|
||
end | ||
end | ||
end |
Oops, something went wrong.