specmatic 0.65.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,10 +1,6 @@
1
- [Specmatic](https://specmatic.in/) is a contract driven development tool that leverages API Specifications, such as [OpenAPI](https://www.openapis.org/), as executable specification. <br />
1
+ # Specmatic Framework Node Module
2
2
 
3
- [![Specmatic - Contract Driven Development](http://img.youtube.com/vi/3HPgpvd8MGg/0.jpg)](http://www.youtube.com/watch?v=3HPgpvd8MGg "Specmatic - Contract Driven Development - Micro-services done right without the pain of integration")
4
-
5
- ## Thin Wrapper
6
-
7
- Specmatic is a **standalone executable** that is **agnostic to programming languages and technology stacks**. This node module is a thin wrapper over the [standalone executable jar](https://specmatic.in/getting_started.html#setup). All core capabilities are in the main [Specmatic project](https://github.com/znsio/specmatic). The purpose of this wrapper module is to act as a convenience to help with below aspects.
3
+ This node module is a thin wrapper over the [standalone executable jar](https://specmatic.in/getting_started.html#setup). All core capabilities are in the main [Specmatic project](https://github.com/znsio/specmatic). The purpose of this wrapper module is to act as a convenience to help with below aspects.
8
4
  * Easy installation and upgrade of the jar file in node projects through npm
9
5
  * JS helper library which provides to do various setup steps like start, stop the specmatic stub server, installing specs etc. These helpers methods can be used inside a setup file inside a javascript project programmatically instead of using cli scripts.
10
6
 
@@ -25,37 +21,31 @@ Tests for Free – Specmatic parses your API Specification files and based on th
25
21
 
26
22
  Check [Documentation](https://specmatic.in/documentation.html) for more information on cli commands and arguments.
27
23
 
28
- ## Test helper library
24
+ ## Programmatic Access
25
+
26
+ Specmatic JS library exposes some of the commands as methods that can be run programmatically from any javascript testing framework, during setup or test phases.
29
27
 
30
28
  ```
31
29
  import {
32
- startStubServer,
33
- runContractTests,
34
- loadDynamicStub,
35
- installContracts,
36
- setSpecmaticEnvironment
30
+ startStub,
31
+ stopStub,
32
+ test,
33
+ setExpecations,
34
+ printJarVersion
37
35
  } from 'specmatic';
38
36
  ```
39
37
 
40
- Specmatic JS library exposes methods which can be used in your JS project to setup the tests, as well as do advanced things like load stubs dynamically. These can be used to programmatically run specmatic commands from any javascript testing framework, during setup or test phases.
41
-
42
- `startStubServer(specmaticDir: string, stubDir: string, host: string, port: string)` <br />
38
+ `startStub(host?: string, port?: string, stubDir?: string) : Promise<ChildProcess>` <br />
43
39
  method to start the stub server.
44
40
 
45
- `runContractTests(specmaticDir: string, host: string, port: string)` <br />
46
- Alias: `startTestServer` <br />
47
- method to start test server.
48
-
49
- `loadDynamicStub(stubPath: string)` <br />
50
- Alias: `setExpectations` <br />
51
- method to load stub dynamically from inside an automated test.
41
+ `stopStub(process: ChildProcess)` <br />
42
+ method to stop the stub server.
52
43
 
53
- `installContracts()` <br />
54
- Alias: `installSpecs` <br />
55
- method to install specs in local machine.
44
+ `test(specs?: string, host?: string, port?: string): Promise<boolean>` <br />
45
+ method to run tests.
56
46
 
57
- `setSpecmaticEnvironment = (environmentName: string, environment: Environment) ` <br />
58
- method to dynamically write new variables or assign values to variables of the environment passed as argument to the function, inside the file 'specmatic.json'.This function expects the file 'specmatic.json' to be in the root directory of your project.
47
+ `setExpectations(stubPath: string, stubServerBaseUrl?: string)` <br />
48
+ method to dynamically set stub expectiona. Stub should be running before invoking this method.
59
49
 
60
50
  `printSpecmaticJarVersion()` <br />
61
51
  method to print the version of specmatic.jar
package/dist/index.js CHANGED
@@ -3,52 +3,34 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- Object.defineProperty(exports, "loadDynamicStub", {
6
+ Object.defineProperty(exports, "startStub", {
7
7
  enumerable: true,
8
8
  get: function get() {
9
- return _lib.loadDynamicStub;
9
+ return _lib.startStub;
10
10
  }
11
11
  });
12
- Object.defineProperty(exports, "setExpectations", {
13
- enumerable: true,
14
- get: function get() {
15
- return _lib.setExpectations;
16
- }
17
- });
18
- Object.defineProperty(exports, "startStubServer", {
19
- enumerable: true,
20
- get: function get() {
21
- return _lib.startStubServer;
22
- }
23
- });
24
- Object.defineProperty(exports, "startTestServer", {
25
- enumerable: true,
26
- get: function get() {
27
- return _lib.startTestServer;
28
- }
29
- });
30
- Object.defineProperty(exports, "runContractTests", {
12
+ Object.defineProperty(exports, "stopStub", {
31
13
  enumerable: true,
32
14
  get: function get() {
33
- return _lib.runContractTests;
15
+ return _lib.stopStub;
34
16
  }
35
17
  });
36
- Object.defineProperty(exports, "installContracts", {
18
+ Object.defineProperty(exports, "test", {
37
19
  enumerable: true,
38
20
  get: function get() {
39
- return _lib.installContracts;
21
+ return _lib.test;
40
22
  }
41
23
  });
42
- Object.defineProperty(exports, "installSpecs", {
24
+ Object.defineProperty(exports, "setExpectations", {
43
25
  enumerable: true,
44
26
  get: function get() {
45
- return _lib.installSpecs;
27
+ return _lib.setExpectations;
46
28
  }
47
29
  });
48
- Object.defineProperty(exports, "setSpecmaticEnvironment", {
30
+ Object.defineProperty(exports, "printJarVersion", {
49
31
  enumerable: true,
50
32
  get: function get() {
51
- return _lib.setSpecmaticEnvironment;
33
+ return _lib.printJarVersion;
52
34
  }
53
35
  });
54
36
 
package/dist/lib/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.printSpecmaticJarVersion = exports.setExpectations = exports.loadDynamicStub = exports.installSpecs = exports.installContracts = exports.runContractTests = exports.startTestServer = exports.startStubServer = exports.setSpecmaticEnvironment = void 0;
6
+ exports.printJarVersion = exports.setExpectations = exports.test = exports.stopStub = exports.startStub = void 0;
7
7
 
8
8
  var _nodeFetch = _interopRequireDefault(require("node-fetch"));
9
9
 
@@ -13,98 +13,95 @@ var _execSh = _interopRequireDefault(require("exec-sh"));
13
13
 
14
14
  var _config = require("../config");
15
15
 
16
- var _fs = _interopRequireDefault(require("fs"));
17
-
18
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
19
17
 
20
18
  var specmaticJarPath = _path.default.resolve(_config.specmaticJarPathLocal);
21
19
 
22
- var setSpecmaticEnvironment = (environmentName, environment) => {
23
- var file = null;
24
-
25
- try {
26
- file = require(_path.default.resolve(_config.specmatic));
27
-
28
- for (var environmentVariable in environment) {
29
- file.environments[environmentName].variables[environmentVariable] = environment[environmentVariable];
30
- }
31
-
32
- _fs.default.writeFileSync(_path.default.resolve(_config.specmatic), JSON.stringify(file, null, 2));
33
- } catch (e) {
34
- if (e.toString().includes("Cannot find module")) console.log(e.toString(), "\nThe file 'specmatic.json' is not present in the root directory of the project.");else console.log(e);
35
- }
36
- };
37
-
38
- exports.setSpecmaticEnvironment = setSpecmaticEnvironment;
39
-
40
- var startStubServer = (specmaticDir, stubDir, host, port) => {
41
- var specmatics = _path.default.resolve(specmaticDir + '');
42
-
20
+ var startStub = (host, port, stubDir) => {
43
21
  var stubs = _path.default.resolve(stubDir + '');
44
22
 
45
- console.log("java -jar ".concat(specmaticJarPath, " stub ").concat(specmatics, " --strict --data=").concat(stubs, " --host=").concat(host, " --port=").concat(port));
23
+ var cmd = "java -jar ".concat(specmaticJarPath, " stub");
24
+ if (stubDir) cmd += " --data=".concat(stubs);
25
+ if (host) cmd += " --host=".concat(host);
26
+ if (port) cmd += " --port=".concat(port);
27
+ console.log(cmd);
46
28
  console.log('Starting specmatic stub server');
47
- (0, _execSh.default)("java -jar ".concat(specmaticJarPath, " stub ").concat(specmatics, " --strict --data=").concat(stubs, " --host=").concat(host, " --port=").concat(port), {}, err => {
48
- if (err) {
49
- console.log('Exit code: ', err.code);
50
- process.exit(err.code);
51
- }
29
+ return new Promise((resolve, _reject) => {
30
+ var javaProcess = (0, _execSh.default)(cmd, {
31
+ stdio: 'pipe',
32
+ stderr: 'pipe'
33
+ }, err => {
34
+ if (err) {
35
+ console.error('Specmatic stub server exited with error', err);
36
+ }
37
+ });
38
+ javaProcess.stdout.on('data', function (data) {
39
+ console.log('STDOUT: ' + data);
40
+
41
+ if (data.indexOf('Stub server is running') > -1) {
42
+ resolve(javaProcess);
43
+ }
44
+ });
45
+ javaProcess.stderr.on('data', function (data) {
46
+ console.log('STDERR: ' + data);
47
+ });
52
48
  });
53
49
  };
54
50
 
55
- exports.startStubServer = startStubServer;
51
+ exports.startStub = startStub;
56
52
 
57
- var startTestServer = (specmaticDir, host, port) => {
58
- var specmatics = _path.default.resolve(specmaticDir);
53
+ var stopStub = javaProcess => {
54
+ var _javaProcess$stdout, _javaProcess$stderr;
59
55
 
60
- console.log('Running specmatic tests');
61
- (0, _execSh.default)("java -jar ".concat(specmaticJarPath, " test ").concat(specmatics, " --host=").concat(host, " --port=").concat(port), {}, err => {
62
- if (err) {
63
- console.log('Exit code: ', err.code);
64
- process.exit(err.code);
65
- }
66
- });
56
+ console.log("Stopping specmatic server");
57
+ (_javaProcess$stdout = javaProcess.stdout) === null || _javaProcess$stdout === void 0 ? void 0 : _javaProcess$stdout.removeAllListeners();
58
+ (_javaProcess$stderr = javaProcess.stderr) === null || _javaProcess$stderr === void 0 ? void 0 : _javaProcess$stderr.removeAllListeners();
59
+ javaProcess.removeAllListeners('close');
60
+ javaProcess.kill();
67
61
  };
68
62
 
69
- exports.startTestServer = startTestServer;
70
- var runContractTests = startTestServer;
71
- exports.runContractTests = runContractTests;
63
+ exports.stopStub = stopStub;
72
64
 
73
- var installContracts = () => {
74
- console.log('Installing contracts');
75
- (0, _execSh.default)("java -jar ".concat(specmaticJarPath, " install"), {}, err => {
76
- if (err) {
77
- console.log('Exit code: ', err.code);
78
- process.exit(err.code);
79
- }
65
+ var test = (specs, host, port) => {
66
+ var specsPath = _path.default.resolve(specs + '');
67
+
68
+ var cmd = "java -jar ".concat(specmaticJarPath, " test");
69
+ if (specs) cmd += " ".concat(specsPath);
70
+ if (host) cmd += " --host=".concat(host);
71
+ if (port) cmd += " --port=".concat(port);
72
+ console.log(cmd);
73
+ console.log('Running specmatic tests');
74
+ return new Promise((resolve, _reject) => {
75
+ (0, _execSh.default)(cmd, {}, err => {
76
+ if (err) {
77
+ console.error('Specmatic test run failed with error', err);
78
+ }
79
+
80
+ resolve(err == null);
81
+ });
80
82
  });
81
83
  };
82
84
 
83
- exports.installContracts = installContracts;
84
- var installSpecs = installContracts;
85
- exports.installSpecs = installSpecs;
85
+ exports.test = test;
86
86
 
87
- var loadDynamicStub = (stubPath, stubServerBaseUrl) => {
87
+ var setExpectations = (stubPath, stubServerBaseUrl) => {
88
88
  var stubResponse = require(_path.default.resolve(stubPath));
89
89
 
90
- console.log("setting expectations");
90
+ console.log('Setting expectations');
91
91
  (0, _nodeFetch.default)("".concat(stubServerBaseUrl ? stubServerBaseUrl : "http://localhost:9000/", "_specmatic/expectations"), {
92
92
  method: 'POST',
93
93
  body: JSON.stringify(stubResponse)
94
- }).then(res => res.json()).then(json => console.log(json));
94
+ }).then(json => console.log(json));
95
95
  };
96
96
 
97
- exports.loadDynamicStub = loadDynamicStub;
98
- var setExpectations = loadDynamicStub;
99
97
  exports.setExpectations = setExpectations;
100
98
 
101
- var printSpecmaticJarVersion = () => {
99
+ var printJarVersion = () => {
102
100
  (0, _execSh.default)("java -jar ".concat(specmaticJarPath, " --version"), {}, err => {
103
101
  if (err) {
104
- console.log('Exit code: ', err.code);
105
- process.exit(err.code);
102
+ console.error('Could not print specmatic version', err);
106
103
  }
107
104
  });
108
105
  };
109
106
 
110
- exports.printSpecmaticJarVersion = printSpecmaticJarVersion;
107
+ exports.printJarVersion = printJarVersion;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specmatic",
3
- "version": "0.65.1",
3
+ "version": "1.0.0",
4
4
  "description": "Node wrapper for Specmatic",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -44,6 +44,7 @@
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/jest": "^26.0.14",
47
- "jest": "^26.4.2"
47
+ "jest": "^26.4.2",
48
+ "jest-mock-extended": "^3.0.4"
48
49
  }
49
50
  }
@@ -10,4 +10,4 @@ test('arguments to be passed correctly to Specmatic lib', () => {
10
10
  startSpecmaticServer(testArgs);
11
11
  expect(execSh.mock.calls[0][0]).toBe(`java -jar ${path.resolve(specmaticJarPathLocal)} ${testArgs.slice(2).join(' ')}`);
12
12
  expect(execSh).toHaveBeenCalledTimes(1);
13
- });
13
+ });
package/src/index.ts CHANGED
@@ -1,10 +1,7 @@
1
1
  export {
2
- loadDynamicStub,
2
+ startStub,
3
+ stopStub,
4
+ test,
3
5
  setExpectations,
4
- startStubServer,
5
- startTestServer,
6
- runContractTests,
7
- installContracts,
8
- installSpecs,
9
- setSpecmaticEnvironment
10
- } from './lib';
6
+ printJarVersion
7
+ } from './lib';
@@ -1,10 +1,14 @@
1
1
  import execSh from 'exec-sh';
2
2
  import fetch from 'node-fetch';
3
3
  import path from 'path';
4
- import { setSpecmaticEnvironment, startStubServer, Environment, startTestServer, runContractTests, loadDynamicStub, printSpecmaticJarVersion, setExpectations, installContracts, installSpecs } from '../';
5
- import { specmaticJarPathLocal, specmatic } from '../../config';
6
- import mockStub from '../../../mockStub.json';
4
+ import { ChildProcess } from 'child_process';
5
+ import { mock as jestMock } from 'jest-mock-extended';
6
+ import { Readable } from "stream";
7
7
 
8
+ import * as specmatic from '../';
9
+ import { startStub, stopStub, printJarVersion, setExpectations } from '../';
10
+ import { specmaticJarPathLocal } from '../../config';
11
+ import mockStub from '../../../mockStub.json';
8
12
 
9
13
  jest.mock('exec-sh');
10
14
  jest.mock('node-fetch');
@@ -13,83 +17,85 @@ const contractsPath = './contracts';
13
17
  const stubDataPath = './data';
14
18
  const host = 'localhost';
15
19
  const port = '8000';
16
-
17
-
18
- const checkSpecmaticEnvironment = (environmentName: string, environment: Environment) => {
19
- let flag = false
20
- try {
21
- let file = require(path.resolve(specmatic))
22
- for (let environmentVariable in environment) flag = file.environments[environmentName].variables[environmentVariable] == environment[environmentVariable]
23
- } catch (e) { console.log(e) }
24
- return flag
25
- }
20
+ const javaProcessMock = jestMock<ChildProcess>();
21
+ const readableMock = jestMock<Readable>();
22
+ javaProcessMock.stdout = readableMock;
23
+ javaProcessMock.stderr = readableMock;
26
24
 
27
25
  beforeEach(() => {
28
26
  execSh.mockReset();
29
27
  fetch.mockReset();
30
28
  });
31
29
 
32
- test('startStubServer method starts the specmatic stub server', () => {
33
- startStubServer(contractsPath, stubDataPath, host, port);
30
+ test('startStub method starts the specmatic stub server', async () => {
31
+ execSh.mockReturnValue(javaProcessMock);
34
32
 
35
- expect(execSh).toHaveBeenCalledTimes(1);
36
- expect(execSh.mock.calls[0][0])
37
- .toBe(`java -jar ${path.resolve(specmaticJarPathLocal)} stub ${path.resolve(contractsPath)} --strict --data=${path.resolve(stubDataPath)} --host=${host} --port=${port}`);
38
- });
33
+ startStub(host, port, stubDataPath).then(javaProcess => {
34
+ expect(javaProcess).toBe(javaProcessMock);
35
+ })
39
36
 
40
- test('startTestServer runs the contract tests', () => {
41
- startTestServer(contractsPath, host, port);
37
+ readableMock.on.mock.calls[0][1]("Stub server is running");
42
38
 
43
39
  expect(execSh).toHaveBeenCalledTimes(1);
44
40
  expect(execSh.mock.calls[0][0])
45
- .toBe(`java -jar ${path.resolve(specmaticJarPathLocal)} test ${path.resolve(contractsPath)} --host=${host} --port=${port}`);
41
+ .toBe(`java -jar ${path.resolve(specmaticJarPathLocal)} stub --data=${path.resolve(stubDataPath)} --host=${host} --port=${port}`);
46
42
  });
47
43
 
48
- test('runContractTests runs the contract tests', () => {
49
- runContractTests(contractsPath, host, port);
44
+ test('startStub method stubDir is optional', async () => {
45
+ execSh.mockReturnValue(javaProcessMock);
46
+
47
+ startStub(host, port).then(javaProcess => {
48
+ expect(javaProcess).toBe(javaProcessMock);
49
+ })
50
+
51
+ readableMock.on.mock.calls[0][1]("Stub server is running");
50
52
 
51
53
  expect(execSh).toHaveBeenCalledTimes(1);
52
54
  expect(execSh.mock.calls[0][0])
53
- .toBe(`java -jar ${path.resolve(specmaticJarPathLocal)} test ${path.resolve(contractsPath)} --host=${host} --port=${port}`);
55
+ .toBe(`java -jar ${path.resolve(specmaticJarPathLocal)} stub --host=${host} --port=${port}`);
54
56
  });
55
57
 
58
+ test('startStub method host and port are optional', async () => {
59
+ execSh.mockReturnValue(javaProcessMock);
60
+
61
+ startStub().then(javaProcess => {
62
+ expect(javaProcess).toBe(javaProcessMock);
63
+ })
56
64
 
57
- test('installContracts installs contracts to local', () => {
58
- installContracts();
65
+ readableMock.on.mock.calls[0][1]("Stub server is running");
59
66
 
60
67
  expect(execSh).toHaveBeenCalledTimes(1);
61
68
  expect(execSh.mock.calls[0][0])
62
- .toBe(`java -jar ${path.resolve(specmaticJarPathLocal)} install`);
69
+ .toBe(`java -jar ${path.resolve(specmaticJarPathLocal)} stub`);
63
70
  });
64
71
 
65
- test('installSpecs installs contracts to local', () => {
66
- installSpecs();
72
+ test('stopStub method stops any running stub server', () => {
73
+ stopStub(javaProcessMock);
67
74
 
68
- expect(execSh).toHaveBeenCalledTimes(1);
69
- expect(execSh.mock.calls[0][0])
70
- .toBe(`java -jar ${path.resolve(specmaticJarPathLocal)} install`);
75
+ expect(readableMock.removeAllListeners).toHaveBeenCalledTimes(2);
76
+ expect(javaProcessMock.removeAllListeners).toHaveBeenCalledTimes(1);
77
+ expect(javaProcessMock.kill).toHaveBeenCalledTimes(1);
71
78
  });
72
79
 
73
- test('printSpecmaticJarVersion', () => {
74
- printSpecmaticJarVersion();
80
+ test('test runs the contract tests', function (done) {
81
+ specmatic.test(contractsPath, host, port).then(result => {
82
+ expect(result).toBeTruthy();
83
+ done();
84
+ });
85
+ execSh.mock.calls[0][2](); //Execute the callback
86
+ expect(execSh).toHaveBeenCalledTimes(1);
87
+ expect(execSh.mock.calls[0][0])
88
+ .toBe(`java -jar ${path.resolve(specmaticJarPathLocal)} test ${path.resolve(contractsPath)} --host=${host} --port=${port}`);
89
+ });
90
+
91
+ test('printJarVersion', () => {
92
+ printJarVersion();
75
93
 
76
94
  expect(execSh).toHaveBeenCalledTimes(1);
77
95
  expect(execSh.mock.calls[0][0])
78
96
  .toBe(`java -jar ${path.resolve(specmaticJarPathLocal)} --version`);
79
97
  });
80
98
 
81
- test('loadDynamicStub with default baseUrl', () => {
82
- fetch.mockReturnValue(Promise.resolve("{}"));
83
- loadDynamicStub(path.resolve('./mockStub.json'));
84
-
85
- expect(fetch).toHaveBeenCalledTimes(1);
86
- expect(fetch.mock.calls[0][0]).toBe('http://localhost:9000/_specmatic/expectations');
87
- expect(fetch.mock.calls[0][1]).toMatchObject({
88
- method: 'POST',
89
- body: JSON.stringify(mockStub)
90
- });
91
- });
92
-
93
99
  test('setExpectations with default baseUrl', () => {
94
100
  fetch.mockReturnValue(Promise.resolve("{}"));
95
101
  setExpectations(path.resolve('./mockStub.json'));
@@ -102,19 +108,6 @@ test('setExpectations with default baseUrl', () => {
102
108
  });
103
109
  });
104
110
 
105
- test('loadDynamicStub with a different baseUrl for the stub server', () => {
106
- fetch.mockReturnValue(Promise.resolve("{}"));
107
- const stubServerBaseUrl = 'http://localhost:8000/'
108
- loadDynamicStub(path.resolve('./mockStub.json'), stubServerBaseUrl);
109
-
110
- expect(fetch).toHaveBeenCalledTimes(1);
111
- expect(fetch.mock.calls[0][0]).toBe(`${stubServerBaseUrl}_specmatic/expectations`);
112
- expect(fetch.mock.calls[0][1]).toMatchObject({
113
- method: 'POST',
114
- body: JSON.stringify(mockStub)
115
- });
116
- });
117
-
118
111
  test('setExpectations with a different baseUrl for the stub server', () => {
119
112
  fetch.mockReturnValue(Promise.resolve("{}"));
120
113
  const stubServerBaseUrl = 'http://localhost:8000/'
@@ -127,19 +120,3 @@ test('setExpectations with a different baseUrl for the stub server', () => {
127
120
  body: JSON.stringify(mockStub)
128
121
  });
129
122
  });
130
-
131
- test('setSpecmaticEnvironment updates the environment variable value in the specmatic.json file', () => {
132
- const variableObj1: Record<string, string> = { "key1": "updated-value1", "key2": "updated-value2", "key3": "updated-value3", "key4": "updated-value4" }
133
- const variableObj2: Record<string, string> = { "key1": "initial-value1", "key2": "initial-value2", "key3": "initial-value3", "key4": "initial-value4" }
134
- setSpecmaticEnvironment("local", variableObj1)
135
- expect(checkSpecmaticEnvironment("local", variableObj1)).toBe(true)
136
- setSpecmaticEnvironment("local", variableObj2)
137
- expect(checkSpecmaticEnvironment("local", variableObj2)).toBe(true)
138
- });
139
-
140
- test('setSpecmaticEnvironment does not updates the environment variable value , when the specified environment name is not present inside specmatic.json file', () => {
141
- const variableObj1: Record<string, string> = { "key1": "updated-value1", "key2": "updated-value2", "key3": "updated-value3", "key4": "updated-value4" }
142
- setSpecmaticEnvironment("production", variableObj1)
143
- expect(checkSpecmaticEnvironment("production", variableObj1)).toBe(false)
144
- });
145
-
package/src/lib/index.ts CHANGED
@@ -2,92 +2,83 @@ import fetch from 'node-fetch';
2
2
  import path from 'path';
3
3
  import execSh from 'exec-sh';
4
4
  import { specmaticJarPathLocal, specmatic } from '../config';
5
- import fs from 'fs';
5
+ import { ChildProcess } from 'child_process';
6
6
 
7
7
  const specmaticJarPath = path.resolve(specmaticJarPathLocal);
8
- export type Environment = Record<string, string>
9
8
 
10
- export const setSpecmaticEnvironment = (environmentName: string, environment: Environment) => {
11
- let file = null
12
- try {
13
- file = require(path.resolve(specmatic))
14
- for (let environmentVariable in environment) file.environments[environmentName].variables[environmentVariable] = environment[environmentVariable]
15
- fs.writeFileSync(path.resolve(specmatic), JSON.stringify(file, null, 2))
16
- } catch (e) {
17
- if (e.toString().includes("Cannot find module")) console.log(e.toString(), "\nThe file 'specmatic.json' is not present in the root directory of the project.")
18
- else console.log(e)
19
- }
20
- }
9
+ const startStub = (host?: string, port?: string, stubDir?: string) : Promise<ChildProcess> => {
10
+ const stubs = path.resolve(stubDir + '');
21
11
 
22
- export const startStubServer = (specmaticDir: string, stubDir: string, host: string, port: string) => {
23
- const specmatics = path.resolve(specmaticDir + '');
24
- const stubs = path.resolve(stubDir + '');
12
+ var cmd = `java -jar ${specmaticJarPath} stub`;
13
+ if (stubDir) cmd += ` --data=${stubs}`;
14
+ if (host) cmd += ` --host=${host}`;
15
+ if (port) cmd += ` --port=${port}`;
16
+ console.log(cmd);
25
17
 
26
- console.log(`java -jar ${specmaticJarPath} stub ${specmatics} --strict --data=${stubs} --host=${host} --port=${port}`)
27
-
28
- console.log('Starting specmatic stub server')
29
- execSh(
30
- `java -jar ${specmaticJarPath} stub ${specmatics} --strict --data=${stubs} --host=${host} --port=${port}`
31
- , {}, (err: any) => {
32
- if (err) {
33
- console.log('Exit code: ', err.code);
34
- process.exit(err.code);
35
- }
18
+ console.log('Starting specmatic stub server');
19
+ return new Promise((resolve, _reject) => {
20
+ const javaProcess = execSh(cmd, { stdio: 'pipe', stderr: 'pipe' }, (err: any) => {
21
+ if (err) {
22
+ console.error('Specmatic stub server exited with error', err);
23
+ }
24
+ });
25
+ javaProcess.stdout.on('data', function (data: String) {
26
+ console.log('STDOUT: ' + data);
27
+ if (data.indexOf('Stub server is running') > -1) {
28
+ resolve(javaProcess);
29
+ }
30
+ });
31
+ javaProcess.stderr.on('data', function (data: String) {
32
+ console.log('STDERR: ' + data);
33
+ });
36
34
  });
37
- }
35
+ };
38
36
 
39
- export const startTestServer = (specmaticDir: string, host: string, port: string) => {
40
- const specmatics = path.resolve(specmaticDir);
37
+ const stopStub = (javaProcess: ChildProcess) => {
38
+ console.log(`Stopping specmatic server`);
39
+ javaProcess.stdout?.removeAllListeners();
40
+ javaProcess.stderr?.removeAllListeners();
41
+ javaProcess.removeAllListeners('close');
42
+ javaProcess.kill();
43
+ };
41
44
 
42
- console.log('Running specmatic tests')
43
- execSh(
44
- `java -jar ${specmaticJarPath} test ${specmatics} --host=${host} --port=${port}`
45
- , {}, (err: any) => {
46
- if (err) {
47
- console.log('Exit code: ', err.code);
48
- process.exit(err.code);
49
- }
50
- });
51
- }
45
+ const test = (specs?: string, host?: string, port?: string): Promise<boolean> => {
46
+ const specsPath = path.resolve(specs + '');
52
47
 
53
- export const runContractTests = startTestServer;
48
+ var cmd = `java -jar ${specmaticJarPath} test`;
49
+ if (specs) cmd += ` ${specsPath}`;
50
+ if (host) cmd += ` --host=${host}`;
51
+ if (port) cmd += ` --port=${port}`;
52
+ console.log(cmd);
54
53
 
55
- export const installContracts = () => {
56
- console.log('Installing contracts')
57
- execSh(
58
- `java -jar ${specmaticJarPath} install`
59
- , {}, (err: any) => {
60
- if (err) {
61
- console.log('Exit code: ', err.code);
62
- process.exit(err.code);
63
- }
64
- });
65
- }
54
+ console.log('Running specmatic tests');
66
55
 
67
- export const installSpecs = installContracts;
56
+ return new Promise((resolve, _reject) => {
57
+ execSh(cmd, {}, (err: any) => {
58
+ if (err) {
59
+ console.error('Specmatic test run failed with error', err);
60
+ }
61
+ resolve(err == null);
62
+ });
63
+ });
64
+ };
68
65
 
69
- export const loadDynamicStub = (stubPath: string, stubServerBaseUrl?: string) => {
70
- const stubResponse = require(path.resolve(stubPath));
66
+ const setExpectations = (stubPath: string, stubServerBaseUrl?: string) => {
67
+ const stubResponse = require(path.resolve(stubPath));
71
68
 
72
- console.log("setting expectations");
73
- fetch(`${stubServerBaseUrl ? stubServerBaseUrl : `http://localhost:9000/`}_specmatic/expectations`,
74
- {
75
- method: 'POST',
76
- body: JSON.stringify(stubResponse)
77
- })
78
- .then(res => res.json())
79
- .then(json => console.log(json));
69
+ console.log('Setting expectations');
70
+ fetch(`${stubServerBaseUrl ? stubServerBaseUrl : `http://localhost:9000/`}_specmatic/expectations`, {
71
+ method: 'POST',
72
+ body: JSON.stringify(stubResponse),
73
+ }).then(json => console.log(json));
80
74
  };
81
75
 
82
- export const setExpectations = loadDynamicStub;
83
-
84
- export const printSpecmaticJarVersion = () => {
85
- execSh(
86
- `java -jar ${specmaticJarPath} --version`
87
- , {}, (err: any) => {
88
- if (err) {
89
- console.log('Exit code: ', err.code);
90
- process.exit(err.code);
91
- }
76
+ const printJarVersion = () => {
77
+ execSh(`java -jar ${specmaticJarPath} --version`, {}, (err: any) => {
78
+ if (err) {
79
+ console.error('Could not print specmatic version', err);
80
+ }
92
81
  });
93
- }
82
+ };
83
+
84
+ export { startStub, stopStub, test, setExpectations, printJarVersion };