Skip to content

Commit

Permalink
Added Step,Tag and Scenario and test for them
Browse files Browse the repository at this point in the history
  • Loading branch information
szikszail committed Apr 14, 2017
1 parent 929d27a commit 21ad3d3
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 5 deletions.
21 changes: 20 additions & 1 deletion lib/ast/Scenario.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

const Tag = require('./Tag');
const Step = require('./Step');
const utils = require('../utils');

class Scenario {
constructor(keyword, name, description) {
this.keyword = keyword;
this.name = name;
this.description = description;
this.description = description ? utils.normalize(description) : '';
this.tags = [];
this.steps = [];
}
Expand All @@ -25,6 +26,24 @@ class Scenario {
}
return scenario;
}

toString() {
const lines = [];
if (this.tags.length > 0) {
lines.push(this.tags.join(' '));
}
lines.push(`${this.keyword}: ${this.name}`);
if (this.description) {
lines.push(utils.indent(this.description));
}
if (this.steps.length > 0) {
lines.push('');
this.steps.forEach(step => {
lines.push(utils.indent(step.toString()));
});
}
return lines.join('\n');
}
}

module.exports = Scenario;
21 changes: 21 additions & 0 deletions lib/ast/Step.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
'use strict';

class Step {
constructor(keyword, text) {
this.keyword = keyword.trim();
this.text = text;
}

static parse(obj) {
if (!obj || obj.type !== 'Step') {
throw new TypeError('The given object is not a Step!');
}
return new Step(obj.keyword, obj.text);
}

toString() {
return `${this.keyword} ${this.text}`;
}
}

module.exports = Step;
4 changes: 4 additions & 0 deletions lib/ast/Tag.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ class Tag {
}
return new Tag(obj.name);
}

toString() {
return this.name;
}
}

module.exports = Tag;
20 changes: 20 additions & 0 deletions lib/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
'use strict';

const utils = {
indent(text, indentation) {
indentation = indentation || ' ';
return text
.split('\n')
.map(line => indentation + line)
.join('\n');
},

normalize(text) {
return text
.split('\n')
.map(line => line.trim().replace(/\s+/g, ' '))
.join('\n');
}
};

module.exports = utils;
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
"main": "lib/index.js",
"scripts": {
"test": "mocha test/**/*.spec.js",
"coverage": "istanbul cover --include-all-sources ./node_modules/mocha/bin/_mocha -v --root ./lib --report lcovonly -- test/**/*.spec.js",
"travis": "istanbul cover --include-all-sources ./node_modules/mocha/bin/_mocha -v --root ./lib --report lcovonly -- test/**/*.spec.js -R spec && cat ./coverage/lcov.info | node ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage"
"coverage": "istanbul cover --include-all-sources ./node_modules/mocha/bin/_mocha --root ./lib -- test/**/*.spec.js",
"travis": "istanbul cover --include-all-sources ./node_modules/mocha/bin/_mocha --root ./lib --report lcovonly -- test/**/*.spec.js -R spec && cat ./coverage/lcov.info | node ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage"
},
"repository": {
"type": "git",
Expand Down
46 changes: 46 additions & 0 deletions test/ast/Scenario.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
'use strict';

const path = require('path');
const fs = require('fs');
const Scenario = require(path.resolve('lib/ast/Scenario.js'));
const Step = require(path.resolve('lib/ast/Step.js'));
const Tag = require(path.resolve('lib/ast/Tag.js'));

const scenarioAst = require('../data/scenario.json');
const scenarioFeature = fs.readFileSync(path.resolve('test/data/scenario.txt'), 'utf8');

const expect = require('chai').expect;

describe('Ast.Scenario', () => {
it('should represent an Ast Scenario instance', () => {
const scenario = new Scenario('Scenario', 'this is a scenario', 'this is a good scenario\n a');
expect(scenario).to.be.instanceOf(Scenario);
expect(scenario.keyword).to.equal('Scenario');
expect(scenario.name).to.equal('this is a scenario');
expect(scenario.description).to.equal('this is a good scenario\na');
expect(scenario.tags).to.eql([]);
expect(scenario.steps).to.eql([]);
});

it('should not parse regular objects', () => {
expect(() => Scenario.parse()).to.throw(TypeError);
expect(() => Scenario.parse({type: 'Type'})).to.throw(TypeError);
});

it('should parse Gherkin Ast Scenario type to Scenario', () => {
const scenario = Scenario.parse(scenarioAst);
expect(scenario).to.be.instanceOf(Scenario);
expect(scenario.keyword).to.equal(scenarioAst.keyword);
expect(scenario.name).to.equal(scenarioAst.name);
expect(scenario.tags).to.have.lengthOf(2);
scenario.tags.forEach((tag, i) => {
expect(tag).to.be.instanceOf(Tag);
expect(tag.name).to.equal(scenarioAst.tags[i].name);
});
});

it('should have proper string representation', () => {
const scenario = Scenario.parse(scenarioAst);
expect(scenario.toString()).to.equal(scenarioFeature);
});
});
32 changes: 32 additions & 0 deletions test/ast/Step.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use strict';

const path = require('path');
const Step = require(path.resolve('./lib/ast/Step.js'));

const expect = require('chai').expect;

describe('Ast.Step', () => {
it('should represent an Ast Step instance', () => {
const step = new Step('When ', 'this is a when step');
expect(step).to.be.instanceOf(Step);
expect(step.keyword).to.equal('When');
expect(step.text).to.equal('this is a when step');
});

it('should not parse regular objects', () => {
expect(() => Step.parse()).to.throw(TypeError);
expect(() => Step.parse({type: 'Type'})).to.throw(TypeError);
});

it('should parse Gherkin Ast Step type to Step', () => {
const step = Step.parse({type: 'Step', keyword: 'When ', text: 'this is a when step'});
expect(step).to.be.instanceOf(Step);
expect(step.keyword).to.equal('When');
expect(step.text).to.equal('this is a when step');
});

it('should have proper string representation', () => {
const step = new Step('When ', 'this is a when step');
expect(step.toString()).to.equal('When this is a when step');
});
});
9 changes: 7 additions & 2 deletions test/ast/Tag.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,18 @@ describe('Ast.Tag', () => {
});

it('should not parse regular objects', () => {
expect(() => Tag.parse()).to.throw;
expect(() => Tag.parse({type: 'Type'})).to.throw;
expect(() => Tag.parse()).to.throw(TypeError);
expect(() => Tag.parse({type: 'Type'})).to.throw(TypeError);
});

it('should parse Gherkin Ast Tag type to Tag', () => {
const tag = Tag.parse({type: 'Tag', name: 'tagName'});
expect(tag).to.be.instanceOf(Tag);
expect(tag.name).to.equal('tagName');
});

it('should have proper string representation', () => {
const tag = new Tag('tagName');
expect(tag.toString()).to.equal('tagName');
});
});
18 changes: 18 additions & 0 deletions test/data/scenario.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"type": "Scenario",
"keyword": "Scenario",
"name": "this is a scenario",
"description": "this is a good\n scenario",
"tags": [
{
"type": "Tag",
"name": "@tag1"
},
{
"type": "Tag",
"name": "@tag2"
}
],
"steps": [
]
}
4 changes: 4 additions & 0 deletions test/data/scenario.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@tag1 @tag2
Scenario: this is a scenario
this is a good
scenario

0 comments on commit 21ad3d3

Please sign in to comment.