Skip to content
This repository was archived by the owner on Nov 8, 2024. It is now read-only.

Commit 4a27f13

Browse files
committed
refactor: rewrite to Node.js
1 parent 863eb96 commit 4a27f13

File tree

11 files changed

+105
-121
lines changed

11 files changed

+105
-121
lines changed

.circleci/config.yml

+2-6
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ jobs:
77
steps:
88
- checkout
99
- run: npm install
10-
- run: npm run lint:features
10+
- run: npm run lint
1111

1212
test-with-python-hooks:
1313
docker:
@@ -23,11 +23,7 @@ jobs:
2323
command: sudo pip install dredd_hooks
2424
- run:
2525
name: Test
26-
command: |
27-
node scripts/prepare-test.js
28-
export PATH=$PATH:$(pwd)/node_modules/.bin
29-
cd ./test
30-
cucumber-js features
26+
command: npm test
3127

3228
workflows:
3329
version: 2

.travis.example.yml

-7
This file was deleted.

Gemfile

-4
This file was deleted.

Gemfile.lock

-33
This file was deleted.

features/step_definitions/dredd_steps.rb

-42
This file was deleted.

features/support/env.rb

-11
This file was deleted.

features/support/steps.js

+70-6
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,25 @@
1-
const { expect } = require('chai');
2-
const fs = require('fs-extra');
31
const os = require('os');
42
const path = require('path');
5-
const which = require('which');
3+
const util = require('util');
64
const childProcess = require('child_process');
5+
const { expect } = require('chai');
6+
const fs = require('fs-extra');
7+
const net = require('net');
8+
const which = require('which');
9+
const kill = require('tree-kill');
710
const { Given, When, Then, Before, After } = require('cucumber');
811

912

1013
Before(function () {
1114
this.dir = fs.mkdtempSync(path.join(os.tmpdir(), 'dredd-hooks-template-'));
1215
this.env = { ...process.env };
16+
this.commands = [];
17+
this.dataSent = '';
1318
});
1419

15-
After(function () {
20+
After(async function () {
1621
fs.remove(this.dir);
22+
await util.promisify(kill)(this.proc.pid);
1723
});
1824

1925

@@ -38,11 +44,69 @@ When(/^I run `([^`]+)`$/, function (command) {
3844
});
3945
});
4046

47+
When(/^I run `([^`]+)` interactively$/, function (command) {
48+
this.proc = childProcess.spawn(command, [], {
49+
shell: true,
50+
cwd: this.dir,
51+
env: this.env,
52+
});
53+
});
54+
55+
When('I wait for output to contain {string}', function (output, callback) {
56+
const proc = this.proc;
57+
58+
function read(data) {
59+
if (data.toString().includes(output)) {
60+
proc.stdout.removeListener('data', read);
61+
proc.stderr.removeListener('data', read);
62+
callback();
63+
}
64+
}
65+
66+
proc.stdout.on('data', read);
67+
proc.stderr.on('data', read);
68+
});
4169

42-
Then('the exit status should be {int}', function (number) {
43-
expect(this.proc.status).to.equal(parseInt(number, 10));
70+
When('I connect to the server', async function () {
71+
this.socket = new net.Socket();
72+
const connect = util.promisify(this.socket.connect.bind(this.socket));
73+
await connect(61321, '127.0.0.1');
74+
});
75+
76+
When('I send a JSON message to the socket:', function (message) {
77+
this.socket.write(message);
78+
this.dataSent += message;
79+
});
80+
81+
When('I send a newline character as a message delimiter to the socket', function () {
82+
this.socket.write('\n');
83+
});
84+
85+
86+
Then('the exit status should be {int}', function (status) {
87+
expect(this.proc.status).to.equal(status);
4488
});
4589

4690
Then('the output should contain:', function (output) {
4791
expect(this.proc.stdout.toString() + this.proc.stderr.toString()).to.contain(output);
4892
});
93+
94+
Then('it should start listening on localhost port {int}', async function (port) {
95+
this.socket = new net.Socket();
96+
const connect = util.promisify(this.socket.connect.bind(this.socket));
97+
await connect(port, '127.0.0.1'); // throws if there's an issue
98+
this.socket.end();
99+
});
100+
101+
Then('I should receive the same response', function (callback) {
102+
this.socket.on('data', (data) => {
103+
const dataReceived = JSON.parse(data.toString());
104+
const dataSent = JSON.parse(this.dataSent);
105+
expect(dataReceived).to.deep.equal(dataSent);
106+
callback();
107+
});
108+
});
109+
110+
Then('I should be able to gracefully disconnect', function () {
111+
this.socket.end();
112+
});

features/tcp_server.feature

+6-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Feature: TCP server and messages
33
Scenario: TCP server
44
When I run `dredd-hooks-{{mylanguage}}` interactively
55
And I wait for output to contain "Starting"
6-
Then It should start listening on localhost port "61321"
6+
Then it should start listening on localhost port 61321
77

88
Scenario: Message exchange for event beforeEach
99
Given I run `dredd-hooks-{{mylanguage}}` interactively
@@ -14,7 +14,7 @@ Scenario: Message exchange for event beforeEach
1414
{"event": "beforeEach", "uuid": "1234-abcd", "data": {"key":"value"}}
1515
"""
1616
And I send a newline character as a message delimiter to the socket
17-
Then I should receive same response
17+
Then I should receive the same response
1818
And I should be able to gracefully disconnect
1919

2020
Scenario: Message exchange for event beforeEachValidation
@@ -26,7 +26,7 @@ Scenario: Message exchange for event beforeEachValidation
2626
{"event": "beforeEachValidation", "uuid": "2234-abcd", "data": {"key":"value"}}
2727
"""
2828
And I send a newline character as a message delimiter to the socket
29-
Then I should receive same response
29+
Then I should receive the same response
3030
And I should be able to gracefully disconnect
3131

3232
Scenario: Message exchange for event afterEach
@@ -38,7 +38,7 @@ Scenario: Message exchange for event afterEach
3838
{"event": "afterEach", "uuid": "3234-abcd", "data": {"key":"value"}}
3939
"""
4040
And I send a newline character as a message delimiter to the socket
41-
Then I should receive same response
41+
Then I should receive the same response
4242
And I should be able to gracefully disconnect
4343

4444
Scenario: Message exchange for event beforeAll
@@ -50,7 +50,7 @@ Scenario: Message exchange for event beforeAll
5050
{"event": "beforeAll", "uuid": "4234-abcd", "data": {"key":"value"}}
5151
"""
5252
And I send a newline character as a message delimiter to the socket
53-
Then I should receive same response
53+
Then I should receive the same response
5454
And I should be able to gracefully disconnect
5555

5656
Scenario: Message exchange for event afterAll
@@ -62,5 +62,5 @@ Scenario: Message exchange for event afterAll
6262
{"event": "afterAll", "uuid": "5234-abcd", "data": {"key":"value"}}
6363
"""
6464
And I send a newline character as a message delimiter to the socket
65-
Then I should receive same response
65+
Then I should receive the same response
6666
And I should be able to gracefully disconnect

package-lock.json

+14-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212
"fs-extra": "7.0.1",
1313
"gherkin-lint": "3.0.3",
1414
"glob": "7.1.3",
15+
"tree-kill": "1.2.1",
1516
"which": "1.3.1"
1617
},
1718
"scripts": {
18-
"lint:features": "gherkin-lint features/"
19+
"test": "node scripts/test.js",
20+
"lint": "gherkin-lint features/"
1921
},
2022
"repository": {
2123
"type": "git",

scripts/prepare-test.js scripts/test.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
const fs = require('fs-extra');
22
const path = require('path');
33
const glob = require('glob');
4+
const { spawnSync } = require('child_process');
45

56

6-
const PROJECT_DIR = path.join(__dirname, '..')
7+
const PROJECT_DIR = path.join(__dirname, '..');
78
const TEST_DIR = path.join(PROJECT_DIR, 'test');
89

910

@@ -45,3 +46,11 @@ glob.sync(path.join(TEST_DIR, '**/*.feature')).forEach((featurePath) => {
4546
const modifiedContent = uncommentPythonCodeBlocks(replacePlaceholders(content));
4647
fs.writeFileSync(featurePath, modifiedContent, { encoding: 'utf-8' });
4748
})
49+
50+
const binDir = path.join(PROJECT_DIR, 'node_modules', '.bin');
51+
const featuresDir = path.join(TEST_DIR, 'features');
52+
53+
const PATH = process.env.PATH.split(path.delimiter).concat([binDir]).join(path.delimiter);
54+
const env = { ...process.env, PATH };
55+
56+
spawnSync('cucumber-js', [featuresDir], { cwd: TEST_DIR, env, stdio: 'inherit' });

0 commit comments

Comments
 (0)