Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Loading gherkin parser according language comment #116

Closed
wants to merge 2 commits into from

1 participant

@bclozel

Hello there.

This issue could be seen as a duplicate of #109 but @vslinko stopped working on this - I'm willing to give it a try.

I've been working on the same problems @vslinko faced in issue #109 : a lexing error when parsing the first non-comment line (exactly, when parsing the first keyword).
Tests and specs run ok this time - but I've stumbled on the same problems with the non-en parsers.

When debugging this issue, it seemed that valid data was passed to the non-en parser. I'm wondering if it's a parser issue or an encoding issue on our part.

Could you give me directions:

  • how could I dig deeper into this?
  • how could I create a sample testcase to check if this problem is on gherkin's/cucumber-js's side?
  • should I request support on the mailing list?

Some details about this PR:

  • works only if the "# language" meta is on the first line
  • does a "featureSource.toString", which is not optimal for nodejs implementation (since we're converting the buffer to a plain string)
  • this code should be modified in the future if we want to support other meta comments like "# encoding"
This was referenced
Closed
@jbpros jbpros closed this pull request from a commit
@ldegen ldegen Add i18n support (close #156)
Also closes #34, closes #109 and closes #116.

Squashed commit of the following:

commit 8a6b2cfc6fbc32780dc94b17cb62285ee442bc8b
Author: Julien Biezemans <jb@jbpros.com>
Date:   Wed Mar 5 16:11:41 2014 +0100

    Bump TCK

commit 1a3c684d2d737d9dfff4cf6d95b923911f520ad0
Merge: 0beabd4 98a2725
Author: Julien Biezemans <jb@jbpros.com>
Date:   Wed Mar 5 16:05:11 2014 +0100

    Merge branch 'master' into i18n

commit 0beabd4
Author: Lukas Degener <l.degener@tarent.de>
Date:   Tue Sep 10 21:41:34 2013 +0200

    more flexible regexp for detecting language

commit b107286
Author: Brian Clozel <brian.clozel@gmail.com>
Date:   Wed Mar 20 18:26:40 2013 +0100

    update specs for i18n support

commit 6fa8f93
Author: Brian Clozel <brian.clozel@gmail.com>
Date:   Wed Mar 20 18:25:04 2013 +0100

    used a modified patch made by @vslinko - see #109
9ace841
@jbpros jbpros closed this in 9ace841
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 46 additions and 15 deletions.
  1. +12 −4 lib/cucumber/parser.js
  2. +34 −11 spec/cucumber/parser_spec.js
View
16 lib/cucumber/parser.js
@@ -1,6 +1,5 @@
var Parser = function(featureSources, astFilter) {
var Gherkin = require('gherkin');
- var GherkinLexer = require('gherkin/lib/gherkin/lexer/en');
var Cucumber = require('../cucumber');
var features = Cucumber.Ast.Features();
@@ -9,13 +8,22 @@ var Parser = function(featureSources, astFilter) {
var self = {
parse: function parse() {
- var eventHandler = self.getEventHandlers();
- var lexer = new GherkinLexer(self.getEventHandlers());
+ var lexers = {};
+ var lexer = function (lang) {
+ if (!(lang in lexers)) {
+ lexers[lang] = new (Gherkin.Lexer(lang))(self.getEventHandlers());
+ }
+
+ return lexers[lang];
+ };
+
for (i in featureSources) {
var currentSourceUri = featureSources[i][Parser.FEATURE_NAME_SOURCE_PAIR_URI_INDEX];
var featureSource = featureSources[i][Parser.FEATURE_NAME_SOURCE_PAIR_SOURCE_INDEX];
self.setCurrentSourceUri(currentSourceUri);
- lexer.scan(featureSource);
+ var languageMatch = /^# language: ([a-z_]*)/.exec(featureSource.toString());
+ var language = languageMatch == null ? 'en' : languageMatch[1];
+ lexer(language).scan(featureSource);
}
return features;
},
View
45 spec/cucumber/parser_spec.js
@@ -2,17 +2,15 @@ require('../support/spec_helper');
describe("Cucumber.Parser", function () {
var Cucumber = requireLib('cucumber');
- var gherkinLexerConstructor;
var parser, featureSources;
var features, astFilter, astAssembler;
beforeEach(function () {
- gherkinLexerConstructor = spyOnModule("gherkin/lib/gherkin/lexer/en");
features = createSpy("Root 'features' AST element");
astFilter = createSpy("AST filter");
featureSources = [
- ["(feature:1)", createSpy('first feature source')],
- ["(feature:2)", createSpy('second feature source')]
+ ["(feature:1)", createSpyWithStubs('first feature source', {toString:"first feature source"})],
+ ["(feature:2)", createSpyWithStubs('second feature source', {toString:"# language: fr\nsecond feature source"})]
];
astAssembler = createSpy("AST assembler");
spyOn(Cucumber.Ast, 'Features').andReturn(features);
@@ -32,12 +30,25 @@ describe("Cucumber.Parser", function () {
describe("parse()", function () {
var Gherkin = require('gherkin');
- var gherkinLexer;
+ var gherkinENLexerConstructor, gherkinFRLexerConstructor, gherkinENLexer, gherkinFRLexer;
var eventHandlers;
beforeEach(function () {
- gherkinLexer = createSpyWithStubs("English gherkin lexer instance", {scan: null});
- gherkinLexerConstructor.andReturn(gherkinLexer);
+ gherkinENLexer = createSpyWithStubs("English gherkin lexer instance", {scan: null});
+ gherkinFRLexer = createSpyWithStubs("French gherkin lexer instance", {scan: null});
+ gherkinENLexerConstructor = createSpy("English gherkin lexer constructor").andReturn(gherkinENLexer);
+ gherkinFRLexerConstructor = createSpy("French gherkin lexer constructor").andReturn(gherkinFRLexer);
+ spyOn(Gherkin, 'Lexer').andCallFake(
+ function(language){
+ if(language == 'en') {
+ return gherkinENLexerConstructor;
+ } else if(language == 'fr') {
+ return gherkinFRLexerConstructor;
+ } else {
+ throw "Could not instantiate a parser for this language"
+ }
+ }
+ );
eventHandlers = createSpy("Parser event handlers");
spyOn(parser, 'getEventHandlers').andReturn(eventHandlers);
spyOn(parser, 'setCurrentSourceUri');
@@ -50,7 +61,15 @@ describe("Cucumber.Parser", function () {
it("creates a gherkin lexer for the English language", function () {
parser.parse();
- expect(gherkinLexerConstructor).toHaveBeenCalledWith(eventHandlers);
+ expect(Gherkin.Lexer).toHaveBeenCalledWith('en');
+ expect(gherkinENLexerConstructor).toHaveBeenCalledWith(eventHandlers);
+ });
+
+
+ it("creates a gherkin lexer for the French language", function () {
+ parser.parse();
+ expect(Gherkin.Lexer).toHaveBeenCalledWith('fr');
+ expect(gherkinFRLexerConstructor).toHaveBeenCalledWith(eventHandlers);
});
it("sets the uri of each feature source", function () {
@@ -59,12 +78,16 @@ describe("Cucumber.Parser", function () {
expect(parser.setCurrentSourceUri).toHaveBeenCalledWith(featureSources[1][0]);
});
- it("asks the lexer to scan each feature source", function () {
+ it("asks the English lexer to scan the first feature source", function () {
parser.parse();
- expect(gherkinLexer.scan).toHaveBeenCalledWith(featureSources[0][1]);
- expect(gherkinLexer.scan).toHaveBeenCalledWith(featureSources[1][1]);
+ expect(gherkinENLexer.scan).toHaveBeenCalledWith(featureSources[0][1]);
});
+ it("asks the French lexer to scan the second feature source", function () {
+ parser.parse();
+ expect(gherkinFRLexer.scan).toHaveBeenCalledWith(featureSources[1][1]);
+ });
+
it("returns the features root element", function () {
expect(parser.parse()).toBe(features);
});
Something went wrong with that request. Please try again.