@opra/testing 0.33.13 → 1.0.0-alpha.10
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/cjs/api-expect/api-expect-collection.js +32 -10
- package/cjs/api-expect/api-expect-error.js +2 -1
- package/cjs/api-expect/api-expect-object.js +14 -5
- package/cjs/api-expect/api-expect.js +22 -19
- package/cjs/jest-extend/common.extend.js +9 -8
- package/cjs/test-backend.js +12 -8
- package/cjs/utils/object-matches.util.js +2 -1
- package/esm/api-expect/api-expect-collection.js +32 -10
- package/esm/api-expect/api-expect-error.js +2 -1
- package/esm/api-expect/api-expect-object.js +14 -6
- package/esm/api-expect/api-expect.js +22 -19
- package/esm/jest-extend/common.extend.js +10 -9
- package/esm/test-backend.js +11 -8
- package/esm/utils/object-matches.util.js +2 -1
- package/package.json +10 -6
- package/types/api-expect/api-expect-error.d.ts +1 -1
- package/types/api-expect/api-expect.d.ts +1 -1
- package/types/test-backend.d.ts +3 -2
- package/types/test-client.d.ts +7 -3
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.convertFilter = exports.ApiExpectCollection = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
|
-
const
|
|
5
|
+
const type_is_1 = tslib_1.__importDefault(require("@browsery/type-is"));
|
|
6
6
|
const common_1 = require("@opra/common");
|
|
7
|
+
const rule_judgment_1 = tslib_1.__importDefault(require("rule-judgment"));
|
|
7
8
|
const api_expect_base_js_1 = require("./api-expect-base.js");
|
|
8
9
|
// @ts-ignore
|
|
9
10
|
const ruleJudgment = typeof rule_judgment_1.default === 'object' ? rule_judgment_1.default.default : rule_judgment_1.default;
|
|
@@ -19,8 +20,13 @@ class ApiExpectCollection extends api_expect_base_js_1.ApiExpectBase {
|
|
|
19
20
|
toReturnItems(min, max) {
|
|
20
21
|
let msg = '';
|
|
21
22
|
try {
|
|
23
|
+
const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
|
|
24
|
+
? this.response.body.payload
|
|
25
|
+
: this.response.body;
|
|
26
|
+
msg += `Payload should be array.`;
|
|
27
|
+
this._expect(Array.isArray(data)).toBeTruthy();
|
|
22
28
|
msg += `The length of payload array do not match. `;
|
|
23
|
-
const l =
|
|
29
|
+
const l = data.length;
|
|
24
30
|
this._expect(l).toBeGreaterThanOrEqual(min || 1);
|
|
25
31
|
if (max)
|
|
26
32
|
this._expect(l).toBeLessThanOrEqual(max);
|
|
@@ -57,7 +63,12 @@ class ApiExpectCollection extends api_expect_base_js_1.ApiExpectBase {
|
|
|
57
63
|
toMatch(expected) {
|
|
58
64
|
try {
|
|
59
65
|
expected = (0, common_1.omitNullish)(expected);
|
|
60
|
-
|
|
66
|
+
const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
|
|
67
|
+
? this.response.body.payload
|
|
68
|
+
: this.response.body;
|
|
69
|
+
for (const x of data) {
|
|
70
|
+
this._expect(x).toMatchObject(expected);
|
|
71
|
+
}
|
|
61
72
|
}
|
|
62
73
|
catch (e) {
|
|
63
74
|
Error.captureStackTrace(e, this.toMatch);
|
|
@@ -72,7 +83,10 @@ class ApiExpectCollection extends api_expect_base_js_1.ApiExpectBase {
|
|
|
72
83
|
toContainFields(fields) {
|
|
73
84
|
try {
|
|
74
85
|
fields = Array.isArray(fields) ? fields : [fields];
|
|
75
|
-
|
|
86
|
+
const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
|
|
87
|
+
? this.response.body.payload
|
|
88
|
+
: this.response.body;
|
|
89
|
+
for (const item of data) {
|
|
76
90
|
this._expect(Object.keys(item)).toEqual(expect.arrayContaining(fields));
|
|
77
91
|
}
|
|
78
92
|
}
|
|
@@ -89,7 +103,10 @@ class ApiExpectCollection extends api_expect_base_js_1.ApiExpectBase {
|
|
|
89
103
|
toContainAllFields(fields) {
|
|
90
104
|
try {
|
|
91
105
|
fields = Array.isArray(fields) ? fields : [fields];
|
|
92
|
-
|
|
106
|
+
const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
|
|
107
|
+
? this.response.body.payload
|
|
108
|
+
: this.response.body;
|
|
109
|
+
for (const item of data) {
|
|
93
110
|
this._expect(Object.keys(item)).toEqual(fields);
|
|
94
111
|
}
|
|
95
112
|
}
|
|
@@ -106,8 +123,10 @@ class ApiExpectCollection extends api_expect_base_js_1.ApiExpectBase {
|
|
|
106
123
|
toBeSortedBy(fields) {
|
|
107
124
|
try {
|
|
108
125
|
fields = Array.isArray(fields) ? fields : [fields];
|
|
109
|
-
|
|
110
|
-
.
|
|
126
|
+
const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
|
|
127
|
+
? this.response.body.payload
|
|
128
|
+
: this.response.body;
|
|
129
|
+
this._expect(data).opraCollectionToBeSortedBy(fields);
|
|
111
130
|
}
|
|
112
131
|
catch (e) {
|
|
113
132
|
Error.captureStackTrace(e, this.toBeSortedBy);
|
|
@@ -123,9 +142,12 @@ class ApiExpectCollection extends api_expect_base_js_1.ApiExpectBase {
|
|
|
123
142
|
const f = convertFilter(filter);
|
|
124
143
|
if (f) {
|
|
125
144
|
const j = ruleJudgment(f);
|
|
126
|
-
const
|
|
145
|
+
const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
|
|
146
|
+
? this.response.body.payload
|
|
147
|
+
: this.response.body;
|
|
148
|
+
const filtered = data.filter(j);
|
|
127
149
|
try {
|
|
128
|
-
this._expect(
|
|
150
|
+
this._expect(data).toStrictEqual(filtered);
|
|
129
151
|
}
|
|
130
152
|
catch (e) {
|
|
131
153
|
Error.captureStackTrace(e, this.toBeFilteredBy);
|
|
@@ -173,7 +195,7 @@ expect.extend({
|
|
|
173
195
|
return {
|
|
174
196
|
actual: received,
|
|
175
197
|
message,
|
|
176
|
-
pass
|
|
198
|
+
pass,
|
|
177
199
|
};
|
|
178
200
|
},
|
|
179
201
|
});
|
|
@@ -9,8 +9,9 @@ class ApiExpectError extends api_expect_base_js_1.ApiExpectBase {
|
|
|
9
9
|
try {
|
|
10
10
|
if (typeof expected === 'string')
|
|
11
11
|
expected = { message: expected };
|
|
12
|
-
else if (expected instanceof RegExp)
|
|
12
|
+
else if (expected instanceof RegExp) {
|
|
13
13
|
expected = { message: expect.stringMatching(expected) };
|
|
14
|
+
}
|
|
14
15
|
else
|
|
15
16
|
expected = (0, common_1.omitNullish)(expected);
|
|
16
17
|
this._expect(this.response.body.errors).toEqual(expect.arrayContaining([expect.objectContaining(expected)]));
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ApiExpectObject = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const type_is_1 = tslib_1.__importDefault(require("@browsery/type-is"));
|
|
4
6
|
const common_1 = require("@opra/common");
|
|
5
7
|
const api_expect_base_js_1 = require("./api-expect-base.js");
|
|
6
8
|
class ApiExpectObject extends api_expect_base_js_1.ApiExpectBase {
|
|
@@ -14,7 +16,10 @@ class ApiExpectObject extends api_expect_base_js_1.ApiExpectBase {
|
|
|
14
16
|
toMatch(expected) {
|
|
15
17
|
try {
|
|
16
18
|
expected = (0, common_1.omitNullish)(expected);
|
|
17
|
-
|
|
19
|
+
const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
|
|
20
|
+
? this.response.body.payload
|
|
21
|
+
: this.response.body;
|
|
22
|
+
this._expect(data).toEqual(expect.objectContaining(expected));
|
|
18
23
|
}
|
|
19
24
|
catch (e) {
|
|
20
25
|
Error.captureStackTrace(e, this.toMatch);
|
|
@@ -29,8 +34,10 @@ class ApiExpectObject extends api_expect_base_js_1.ApiExpectBase {
|
|
|
29
34
|
toContainFields(fields) {
|
|
30
35
|
try {
|
|
31
36
|
fields = Array.isArray(fields) ? fields : [fields];
|
|
32
|
-
|
|
33
|
-
.
|
|
37
|
+
const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
|
|
38
|
+
? this.response.body.payload
|
|
39
|
+
: this.response.body;
|
|
40
|
+
this._expect(Object.keys(data)).toEqual(expect.arrayContaining(fields));
|
|
34
41
|
}
|
|
35
42
|
catch (e) {
|
|
36
43
|
Error.captureStackTrace(e, this.toContainFields);
|
|
@@ -45,8 +52,10 @@ class ApiExpectObject extends api_expect_base_js_1.ApiExpectBase {
|
|
|
45
52
|
toContainAllFields(fields) {
|
|
46
53
|
try {
|
|
47
54
|
fields = Array.isArray(fields) ? fields : [fields];
|
|
48
|
-
|
|
49
|
-
.
|
|
55
|
+
const data = type_is_1.default.is(this.response.contentType, [common_1.MimeTypes.opra_response_json])
|
|
56
|
+
? this.response.body.payload
|
|
57
|
+
: this.response.body;
|
|
58
|
+
this._expect(Object.keys(data)).toEqual(fields);
|
|
50
59
|
}
|
|
51
60
|
catch (e) {
|
|
52
61
|
Error.captureStackTrace(e, this.toContainAllFields);
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ApiExpect = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
require("../jest-extend/index.js");
|
|
6
|
+
const common_1 = require("@opra/common");
|
|
6
7
|
const ansi_colors_1 = tslib_1.__importDefault(require("ansi-colors"));
|
|
7
8
|
const api_expect_base_js_1 = require("./api-expect-base.js");
|
|
8
9
|
const api_expect_collection_js_1 = require("./api-expect-collection.js");
|
|
@@ -27,16 +28,17 @@ class ApiExpect extends api_expect_base_js_1.ApiExpectBase {
|
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
catch (e) {
|
|
30
|
-
e.message =
|
|
31
|
+
e.message = "Request didn't succeeded as expected. " + msg + '\n\n' + e.message;
|
|
31
32
|
const issues = this.response.body?.errors;
|
|
32
33
|
if (issues) {
|
|
33
34
|
e.message += '\n\n';
|
|
34
35
|
issues.forEach((issue, i) => {
|
|
35
|
-
const stack = Array.isArray(issue.stack)
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
const stack = Array.isArray(issue.stack) ? issue.stack.join('\n') : issue.stack;
|
|
37
|
+
e.message +=
|
|
38
|
+
ansi_colors_1.default.yellow(issues.length > 1 ? `Error [${i}]: ` : 'Error: ') +
|
|
39
|
+
issue.message +
|
|
40
|
+
'\n' +
|
|
41
|
+
(stack ? ' ' + stack.substring(stack.indexOf('at ')) + '\n' : '');
|
|
40
42
|
});
|
|
41
43
|
}
|
|
42
44
|
Error.captureStackTrace(e, this.toSuccess);
|
|
@@ -61,16 +63,17 @@ class ApiExpect extends api_expect_base_js_1.ApiExpectBase {
|
|
|
61
63
|
}
|
|
62
64
|
}
|
|
63
65
|
catch (e) {
|
|
64
|
-
e.message =
|
|
66
|
+
e.message = "Request didn't failed as expected. " + msg + '\n\n' + e.message;
|
|
65
67
|
const issues = this.response.body?.errors;
|
|
66
68
|
if (issues) {
|
|
67
69
|
e.message += '\n\n';
|
|
68
70
|
issues.forEach((issue, i) => {
|
|
69
|
-
const stack = Array.isArray(issue.stack)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
const stack = Array.isArray(issue.stack) ? issue.stack.join('\n') : issue.stack;
|
|
72
|
+
e.message +=
|
|
73
|
+
ansi_colors_1.default.yellow(issues.length > 1 ? `Error [${i}]: ` : 'Error: ') +
|
|
74
|
+
issue.message +
|
|
75
|
+
'\n' +
|
|
76
|
+
(stack ? ' ' + stack.substring(stack.indexOf('at ')) + '\n' : '');
|
|
74
77
|
});
|
|
75
78
|
}
|
|
76
79
|
Error.captureStackTrace(e, this.toSuccess);
|
|
@@ -85,7 +88,7 @@ class ApiExpect extends api_expect_base_js_1.ApiExpectBase {
|
|
|
85
88
|
let msg = '';
|
|
86
89
|
try {
|
|
87
90
|
msg = 'Content-Type header value is not valid. ';
|
|
88
|
-
expect(this.response.contentType).toEqual('application/opra+json');
|
|
91
|
+
expect(this.response.contentType).toEqual('application/opra.response+json');
|
|
89
92
|
msg = 'Type of response "body" is not valid. ';
|
|
90
93
|
expect(typeof this.response.body).toEqual('object');
|
|
91
94
|
msg = 'Type of "payload" is not an Array. ';
|
|
@@ -93,7 +96,7 @@ class ApiExpect extends api_expect_base_js_1.ApiExpectBase {
|
|
|
93
96
|
expect(Array.isArray(payload) ? 'array' : typeof payload).toEqual('array');
|
|
94
97
|
}
|
|
95
98
|
catch (e) {
|
|
96
|
-
e.message =
|
|
99
|
+
e.message = "Api didn't returned a Collection. " + msg + '\n\n' + e.message;
|
|
97
100
|
if (msg)
|
|
98
101
|
e.message = msg + '\n\n' + e.message;
|
|
99
102
|
Error.captureStackTrace(e, this.toReturnCollection);
|
|
@@ -104,11 +107,11 @@ class ApiExpect extends api_expect_base_js_1.ApiExpectBase {
|
|
|
104
107
|
/**
|
|
105
108
|
* Tests if API returns an Object
|
|
106
109
|
*/
|
|
107
|
-
toReturnObject() {
|
|
110
|
+
toReturnObject(contentType) {
|
|
108
111
|
let msg = '';
|
|
109
112
|
try {
|
|
110
113
|
msg = 'Content-Type header value is not valid. ';
|
|
111
|
-
expect(this.response.contentType).toEqual(
|
|
114
|
+
expect(this.response.contentType).toEqual(contentType || common_1.MimeTypes.opra_response_json);
|
|
112
115
|
msg = 'Type of response "body" is not valid. ';
|
|
113
116
|
expect(typeof this.response.body).toEqual('object');
|
|
114
117
|
msg = 'Type of "payload" is not an Object. ';
|
|
@@ -116,7 +119,7 @@ class ApiExpect extends api_expect_base_js_1.ApiExpectBase {
|
|
|
116
119
|
expect(typeof payload).toEqual('object');
|
|
117
120
|
}
|
|
118
121
|
catch (e) {
|
|
119
|
-
e.message =
|
|
122
|
+
e.message = "Api didn't returned an Object. " + msg + '\n\n' + e.message;
|
|
120
123
|
if (msg)
|
|
121
124
|
e.message = msg + '\n\n' + e.message;
|
|
122
125
|
Error.captureStackTrace(e, this.toReturnCollection);
|
|
@@ -131,7 +134,7 @@ class ApiExpect extends api_expect_base_js_1.ApiExpectBase {
|
|
|
131
134
|
let msg = '';
|
|
132
135
|
try {
|
|
133
136
|
msg = 'Content-Type header value is not valid. ';
|
|
134
|
-
expect(this.response.contentType).toEqual(
|
|
137
|
+
expect(this.response.contentType).toEqual(common_1.MimeTypes.opra_response_json);
|
|
135
138
|
msg = 'Type of response "body" is not valid. ';
|
|
136
139
|
expect(typeof this.response.body).toEqual('object');
|
|
137
140
|
msg = 'The response has payload. ';
|
|
@@ -139,7 +142,7 @@ class ApiExpect extends api_expect_base_js_1.ApiExpectBase {
|
|
|
139
142
|
expect(typeof payload).toEqual('undefined');
|
|
140
143
|
}
|
|
141
144
|
catch (e) {
|
|
142
|
-
e.message =
|
|
145
|
+
e.message = "Api didn't returned a OperationResult. " + msg + '\n\n' + e.message;
|
|
143
146
|
if (msg)
|
|
144
147
|
e.message = msg + '\n\n' + e.message;
|
|
145
148
|
Error.captureStackTrace(e, this.toReturnCollection);
|
|
@@ -23,8 +23,9 @@ expect.extend({
|
|
|
23
23
|
const pass = !filteredKeys.length === !this.isNot;
|
|
24
24
|
if (!pass) {
|
|
25
25
|
const message = () => `${!this.isNot ? 'Do not expects' : 'Expects'} additional keys other than: ${ansi_colors_1.default.yellow('' + expectedKeys)}\n` +
|
|
26
|
-
(filteredKeys
|
|
27
|
-
|
|
26
|
+
(filteredKeys
|
|
27
|
+
? `Additional keys received: ${ansi_colors_1.default.yellow('' + filteredKeys)}\n`
|
|
28
|
+
: 'No additional keys received\n');
|
|
28
29
|
return { message, pass };
|
|
29
30
|
}
|
|
30
31
|
return { actual: received, pass: !this.isNot, message: () => '' };
|
|
@@ -35,33 +36,33 @@ expect.extend({
|
|
|
35
36
|
}
|
|
36
37
|
return {
|
|
37
38
|
pass: false,
|
|
38
|
-
message: () => 'Value is not an array'
|
|
39
|
+
message: () => 'Value is not an array',
|
|
39
40
|
};
|
|
40
41
|
},
|
|
41
42
|
toBeGreaterThanAny(received, expected) {
|
|
42
43
|
return compare('toBeGreaterThan', {
|
|
43
44
|
isNot: this.isNot,
|
|
44
|
-
promise: this.promise
|
|
45
|
+
promise: this.promise,
|
|
45
46
|
}, received, expected, '>', () => received > expected);
|
|
46
47
|
},
|
|
47
48
|
toBeGreaterThanOrEqualAny(received, expected) {
|
|
48
49
|
return compare('toBeGreaterThanOrEqual', {
|
|
49
50
|
isNot: this.isNot,
|
|
50
|
-
promise: this.promise
|
|
51
|
+
promise: this.promise,
|
|
51
52
|
}, received, expected, '>=', () => received >= expected);
|
|
52
53
|
},
|
|
53
54
|
toBeLessThanAny(received, expected) {
|
|
54
55
|
return compare('toBeLessThan', {
|
|
55
56
|
isNot: this.isNot,
|
|
56
|
-
promise: this.promise
|
|
57
|
+
promise: this.promise,
|
|
57
58
|
}, received, expected, '<', () => received < expected);
|
|
58
59
|
},
|
|
59
60
|
toBeLessThanOrEqualAny(received, expected) {
|
|
60
61
|
return compare('toBeLessThanOrEqual', {
|
|
61
62
|
isNot: this.isNot,
|
|
62
|
-
promise: this.promise
|
|
63
|
+
promise: this.promise,
|
|
63
64
|
}, received, expected, '<=', () => received <= expected);
|
|
64
|
-
}
|
|
65
|
+
},
|
|
65
66
|
});
|
|
66
67
|
function compare(matcherName, options, received, expected, operator, fn) {
|
|
67
68
|
const pass = fn(received, expected);
|
package/cjs/test-backend.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TestBackend = void 0;
|
|
4
|
-
const
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const path = tslib_1.__importStar(require("node:path"));
|
|
5
6
|
const client_1 = require("@opra/client");
|
|
6
|
-
const
|
|
7
|
+
const http_1 = require("http");
|
|
7
8
|
const api_expect_js_1 = require("./api-expect/api-expect.js");
|
|
8
9
|
/**
|
|
9
10
|
*
|
|
@@ -11,34 +12,37 @@ const api_expect_js_1 = require("./api-expect/api-expect.js");
|
|
|
11
12
|
*/
|
|
12
13
|
class TestBackend extends client_1.FetchBackend {
|
|
13
14
|
constructor(app, options) {
|
|
14
|
-
super('http://tempuri.org', options);
|
|
15
|
+
super(options?.basePath ? path.join('http://tempuri.org', options.basePath) : 'http://tempuri.org', options);
|
|
15
16
|
this._server = app instanceof http_1.Server ? app : (0, http_1.createServer)(app);
|
|
16
17
|
}
|
|
17
18
|
send(req) {
|
|
18
19
|
return new Promise((resolve, reject) => {
|
|
19
|
-
const url = new
|
|
20
|
+
const url = new URL(req.url);
|
|
20
21
|
// Set protocol to HTTP
|
|
21
22
|
url.protocol = 'http';
|
|
22
23
|
// Apply original host to request header
|
|
23
24
|
if (url.host !== 'opra.test' && req.headers.get('host') == null)
|
|
24
25
|
req.headers.set('host', url.host);
|
|
25
|
-
new Promise(
|
|
26
|
+
new Promise(subResolve => {
|
|
26
27
|
if (this._server.listening)
|
|
27
28
|
subResolve();
|
|
28
29
|
else
|
|
29
30
|
this._server.listen(0, '127.0.0.1', () => subResolve());
|
|
30
|
-
})
|
|
31
|
+
})
|
|
32
|
+
.then(() => {
|
|
31
33
|
const address = this._server.address();
|
|
32
34
|
url.host = '127.0.0.1';
|
|
33
35
|
url.port = address.port.toString();
|
|
34
36
|
return fetch(url.toString(), req);
|
|
35
|
-
})
|
|
37
|
+
})
|
|
38
|
+
.then(res => {
|
|
36
39
|
if (!this._server.listening)
|
|
37
40
|
return resolve(res);
|
|
38
41
|
this._server.once('close', () => resolve(res));
|
|
39
42
|
this._server.close();
|
|
40
43
|
this._server.unref();
|
|
41
|
-
})
|
|
44
|
+
})
|
|
45
|
+
.then()
|
|
42
46
|
.catch(error => {
|
|
43
47
|
if (!this._server.listening)
|
|
44
48
|
return reject(error);
|
|
@@ -23,12 +23,13 @@ function _objectMatches(received, expected, path) {
|
|
|
23
23
|
else if (ev && typeof ev === 'object') {
|
|
24
24
|
_objectMatches(rv, ev, path ? path + '.' + k : k);
|
|
25
25
|
}
|
|
26
|
-
else
|
|
26
|
+
else {
|
|
27
27
|
try {
|
|
28
28
|
expect(rv).toEqual(ev);
|
|
29
29
|
}
|
|
30
30
|
catch {
|
|
31
31
|
throw new Error(`Property "${k}" does not match`);
|
|
32
32
|
}
|
|
33
|
+
}
|
|
33
34
|
}
|
|
34
35
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import typeIs from '@browsery/type-is';
|
|
2
|
+
import { MimeTypes, omitNullish, OpraFilter } from '@opra/common';
|
|
1
3
|
import ruleJudgmentLib from 'rule-judgment';
|
|
2
|
-
import { omitNullish, OpraFilter } from '@opra/common';
|
|
3
4
|
import { ApiExpectBase } from './api-expect-base.js';
|
|
4
5
|
// @ts-ignore
|
|
5
6
|
const ruleJudgment = typeof ruleJudgmentLib === 'object' ? ruleJudgmentLib.default : ruleJudgmentLib;
|
|
@@ -15,8 +16,13 @@ export class ApiExpectCollection extends ApiExpectBase {
|
|
|
15
16
|
toReturnItems(min, max) {
|
|
16
17
|
let msg = '';
|
|
17
18
|
try {
|
|
19
|
+
const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
|
|
20
|
+
? this.response.body.payload
|
|
21
|
+
: this.response.body;
|
|
22
|
+
msg += `Payload should be array.`;
|
|
23
|
+
this._expect(Array.isArray(data)).toBeTruthy();
|
|
18
24
|
msg += `The length of payload array do not match. `;
|
|
19
|
-
const l =
|
|
25
|
+
const l = data.length;
|
|
20
26
|
this._expect(l).toBeGreaterThanOrEqual(min || 1);
|
|
21
27
|
if (max)
|
|
22
28
|
this._expect(l).toBeLessThanOrEqual(max);
|
|
@@ -53,7 +59,12 @@ export class ApiExpectCollection extends ApiExpectBase {
|
|
|
53
59
|
toMatch(expected) {
|
|
54
60
|
try {
|
|
55
61
|
expected = omitNullish(expected);
|
|
56
|
-
|
|
62
|
+
const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
|
|
63
|
+
? this.response.body.payload
|
|
64
|
+
: this.response.body;
|
|
65
|
+
for (const x of data) {
|
|
66
|
+
this._expect(x).toMatchObject(expected);
|
|
67
|
+
}
|
|
57
68
|
}
|
|
58
69
|
catch (e) {
|
|
59
70
|
Error.captureStackTrace(e, this.toMatch);
|
|
@@ -68,7 +79,10 @@ export class ApiExpectCollection extends ApiExpectBase {
|
|
|
68
79
|
toContainFields(fields) {
|
|
69
80
|
try {
|
|
70
81
|
fields = Array.isArray(fields) ? fields : [fields];
|
|
71
|
-
|
|
82
|
+
const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
|
|
83
|
+
? this.response.body.payload
|
|
84
|
+
: this.response.body;
|
|
85
|
+
for (const item of data) {
|
|
72
86
|
this._expect(Object.keys(item)).toEqual(expect.arrayContaining(fields));
|
|
73
87
|
}
|
|
74
88
|
}
|
|
@@ -85,7 +99,10 @@ export class ApiExpectCollection extends ApiExpectBase {
|
|
|
85
99
|
toContainAllFields(fields) {
|
|
86
100
|
try {
|
|
87
101
|
fields = Array.isArray(fields) ? fields : [fields];
|
|
88
|
-
|
|
102
|
+
const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
|
|
103
|
+
? this.response.body.payload
|
|
104
|
+
: this.response.body;
|
|
105
|
+
for (const item of data) {
|
|
89
106
|
this._expect(Object.keys(item)).toEqual(fields);
|
|
90
107
|
}
|
|
91
108
|
}
|
|
@@ -102,8 +119,10 @@ export class ApiExpectCollection extends ApiExpectBase {
|
|
|
102
119
|
toBeSortedBy(fields) {
|
|
103
120
|
try {
|
|
104
121
|
fields = Array.isArray(fields) ? fields : [fields];
|
|
105
|
-
|
|
106
|
-
.
|
|
122
|
+
const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
|
|
123
|
+
? this.response.body.payload
|
|
124
|
+
: this.response.body;
|
|
125
|
+
this._expect(data).opraCollectionToBeSortedBy(fields);
|
|
107
126
|
}
|
|
108
127
|
catch (e) {
|
|
109
128
|
Error.captureStackTrace(e, this.toBeSortedBy);
|
|
@@ -119,9 +138,12 @@ export class ApiExpectCollection extends ApiExpectBase {
|
|
|
119
138
|
const f = convertFilter(filter);
|
|
120
139
|
if (f) {
|
|
121
140
|
const j = ruleJudgment(f);
|
|
122
|
-
const
|
|
141
|
+
const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
|
|
142
|
+
? this.response.body.payload
|
|
143
|
+
: this.response.body;
|
|
144
|
+
const filtered = data.filter(j);
|
|
123
145
|
try {
|
|
124
|
-
this._expect(
|
|
146
|
+
this._expect(data).toStrictEqual(filtered);
|
|
125
147
|
}
|
|
126
148
|
catch (e) {
|
|
127
149
|
Error.captureStackTrace(e, this.toBeFilteredBy);
|
|
@@ -168,7 +190,7 @@ expect.extend({
|
|
|
168
190
|
return {
|
|
169
191
|
actual: received,
|
|
170
192
|
message,
|
|
171
|
-
pass
|
|
193
|
+
pass,
|
|
172
194
|
};
|
|
173
195
|
},
|
|
174
196
|
});
|
|
@@ -6,8 +6,9 @@ export class ApiExpectError extends ApiExpectBase {
|
|
|
6
6
|
try {
|
|
7
7
|
if (typeof expected === 'string')
|
|
8
8
|
expected = { message: expected };
|
|
9
|
-
else if (expected instanceof RegExp)
|
|
9
|
+
else if (expected instanceof RegExp) {
|
|
10
10
|
expected = { message: expect.stringMatching(expected) };
|
|
11
|
+
}
|
|
11
12
|
else
|
|
12
13
|
expected = omitNullish(expected);
|
|
13
14
|
this._expect(this.response.body.errors).toEqual(expect.arrayContaining([expect.objectContaining(expected)]));
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import typeIs from '@browsery/type-is';
|
|
2
|
+
import { MimeTypes, omitNullish } from '@opra/common';
|
|
2
3
|
import { ApiExpectBase } from './api-expect-base.js';
|
|
3
4
|
export class ApiExpectObject extends ApiExpectBase {
|
|
4
5
|
get not() {
|
|
@@ -11,7 +12,10 @@ export class ApiExpectObject extends ApiExpectBase {
|
|
|
11
12
|
toMatch(expected) {
|
|
12
13
|
try {
|
|
13
14
|
expected = omitNullish(expected);
|
|
14
|
-
|
|
15
|
+
const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
|
|
16
|
+
? this.response.body.payload
|
|
17
|
+
: this.response.body;
|
|
18
|
+
this._expect(data).toEqual(expect.objectContaining(expected));
|
|
15
19
|
}
|
|
16
20
|
catch (e) {
|
|
17
21
|
Error.captureStackTrace(e, this.toMatch);
|
|
@@ -26,8 +30,10 @@ export class ApiExpectObject extends ApiExpectBase {
|
|
|
26
30
|
toContainFields(fields) {
|
|
27
31
|
try {
|
|
28
32
|
fields = Array.isArray(fields) ? fields : [fields];
|
|
29
|
-
|
|
30
|
-
.
|
|
33
|
+
const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
|
|
34
|
+
? this.response.body.payload
|
|
35
|
+
: this.response.body;
|
|
36
|
+
this._expect(Object.keys(data)).toEqual(expect.arrayContaining(fields));
|
|
31
37
|
}
|
|
32
38
|
catch (e) {
|
|
33
39
|
Error.captureStackTrace(e, this.toContainFields);
|
|
@@ -42,8 +48,10 @@ export class ApiExpectObject extends ApiExpectBase {
|
|
|
42
48
|
toContainAllFields(fields) {
|
|
43
49
|
try {
|
|
44
50
|
fields = Array.isArray(fields) ? fields : [fields];
|
|
45
|
-
|
|
46
|
-
.
|
|
51
|
+
const data = typeIs.is(this.response.contentType, [MimeTypes.opra_response_json])
|
|
52
|
+
? this.response.body.payload
|
|
53
|
+
: this.response.body;
|
|
54
|
+
this._expect(Object.keys(data)).toEqual(fields);
|
|
47
55
|
}
|
|
48
56
|
catch (e) {
|
|
49
57
|
Error.captureStackTrace(e, this.toContainAllFields);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import '../jest-extend/index.js';
|
|
2
|
+
import { MimeTypes } from '@opra/common';
|
|
2
3
|
import colors from 'ansi-colors';
|
|
3
4
|
import { ApiExpectBase } from './api-expect-base.js';
|
|
4
5
|
import { ApiExpectCollection } from './api-expect-collection.js';
|
|
@@ -23,16 +24,17 @@ export class ApiExpect extends ApiExpectBase {
|
|
|
23
24
|
}
|
|
24
25
|
}
|
|
25
26
|
catch (e) {
|
|
26
|
-
e.message =
|
|
27
|
+
e.message = "Request didn't succeeded as expected. " + msg + '\n\n' + e.message;
|
|
27
28
|
const issues = this.response.body?.errors;
|
|
28
29
|
if (issues) {
|
|
29
30
|
e.message += '\n\n';
|
|
30
31
|
issues.forEach((issue, i) => {
|
|
31
|
-
const stack = Array.isArray(issue.stack)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
const stack = Array.isArray(issue.stack) ? issue.stack.join('\n') : issue.stack;
|
|
33
|
+
e.message +=
|
|
34
|
+
colors.yellow(issues.length > 1 ? `Error [${i}]: ` : 'Error: ') +
|
|
35
|
+
issue.message +
|
|
36
|
+
'\n' +
|
|
37
|
+
(stack ? ' ' + stack.substring(stack.indexOf('at ')) + '\n' : '');
|
|
36
38
|
});
|
|
37
39
|
}
|
|
38
40
|
Error.captureStackTrace(e, this.toSuccess);
|
|
@@ -57,16 +59,17 @@ export class ApiExpect extends ApiExpectBase {
|
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
61
|
catch (e) {
|
|
60
|
-
e.message =
|
|
62
|
+
e.message = "Request didn't failed as expected. " + msg + '\n\n' + e.message;
|
|
61
63
|
const issues = this.response.body?.errors;
|
|
62
64
|
if (issues) {
|
|
63
65
|
e.message += '\n\n';
|
|
64
66
|
issues.forEach((issue, i) => {
|
|
65
|
-
const stack = Array.isArray(issue.stack)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
const stack = Array.isArray(issue.stack) ? issue.stack.join('\n') : issue.stack;
|
|
68
|
+
e.message +=
|
|
69
|
+
colors.yellow(issues.length > 1 ? `Error [${i}]: ` : 'Error: ') +
|
|
70
|
+
issue.message +
|
|
71
|
+
'\n' +
|
|
72
|
+
(stack ? ' ' + stack.substring(stack.indexOf('at ')) + '\n' : '');
|
|
70
73
|
});
|
|
71
74
|
}
|
|
72
75
|
Error.captureStackTrace(e, this.toSuccess);
|
|
@@ -81,7 +84,7 @@ export class ApiExpect extends ApiExpectBase {
|
|
|
81
84
|
let msg = '';
|
|
82
85
|
try {
|
|
83
86
|
msg = 'Content-Type header value is not valid. ';
|
|
84
|
-
expect(this.response.contentType).toEqual('application/opra+json');
|
|
87
|
+
expect(this.response.contentType).toEqual('application/opra.response+json');
|
|
85
88
|
msg = 'Type of response "body" is not valid. ';
|
|
86
89
|
expect(typeof this.response.body).toEqual('object');
|
|
87
90
|
msg = 'Type of "payload" is not an Array. ';
|
|
@@ -89,7 +92,7 @@ export class ApiExpect extends ApiExpectBase {
|
|
|
89
92
|
expect(Array.isArray(payload) ? 'array' : typeof payload).toEqual('array');
|
|
90
93
|
}
|
|
91
94
|
catch (e) {
|
|
92
|
-
e.message =
|
|
95
|
+
e.message = "Api didn't returned a Collection. " + msg + '\n\n' + e.message;
|
|
93
96
|
if (msg)
|
|
94
97
|
e.message = msg + '\n\n' + e.message;
|
|
95
98
|
Error.captureStackTrace(e, this.toReturnCollection);
|
|
@@ -100,11 +103,11 @@ export class ApiExpect extends ApiExpectBase {
|
|
|
100
103
|
/**
|
|
101
104
|
* Tests if API returns an Object
|
|
102
105
|
*/
|
|
103
|
-
toReturnObject() {
|
|
106
|
+
toReturnObject(contentType) {
|
|
104
107
|
let msg = '';
|
|
105
108
|
try {
|
|
106
109
|
msg = 'Content-Type header value is not valid. ';
|
|
107
|
-
expect(this.response.contentType).toEqual(
|
|
110
|
+
expect(this.response.contentType).toEqual(contentType || MimeTypes.opra_response_json);
|
|
108
111
|
msg = 'Type of response "body" is not valid. ';
|
|
109
112
|
expect(typeof this.response.body).toEqual('object');
|
|
110
113
|
msg = 'Type of "payload" is not an Object. ';
|
|
@@ -112,7 +115,7 @@ export class ApiExpect extends ApiExpectBase {
|
|
|
112
115
|
expect(typeof payload).toEqual('object');
|
|
113
116
|
}
|
|
114
117
|
catch (e) {
|
|
115
|
-
e.message =
|
|
118
|
+
e.message = "Api didn't returned an Object. " + msg + '\n\n' + e.message;
|
|
116
119
|
if (msg)
|
|
117
120
|
e.message = msg + '\n\n' + e.message;
|
|
118
121
|
Error.captureStackTrace(e, this.toReturnCollection);
|
|
@@ -127,7 +130,7 @@ export class ApiExpect extends ApiExpectBase {
|
|
|
127
130
|
let msg = '';
|
|
128
131
|
try {
|
|
129
132
|
msg = 'Content-Type header value is not valid. ';
|
|
130
|
-
expect(this.response.contentType).toEqual(
|
|
133
|
+
expect(this.response.contentType).toEqual(MimeTypes.opra_response_json);
|
|
131
134
|
msg = 'Type of response "body" is not valid. ';
|
|
132
135
|
expect(typeof this.response.body).toEqual('object');
|
|
133
136
|
msg = 'The response has payload. ';
|
|
@@ -135,7 +138,7 @@ export class ApiExpect extends ApiExpectBase {
|
|
|
135
138
|
expect(typeof payload).toEqual('undefined');
|
|
136
139
|
}
|
|
137
140
|
catch (e) {
|
|
138
|
-
e.message =
|
|
141
|
+
e.message = "Api didn't returned a OperationResult. " + msg + '\n\n' + e.message;
|
|
139
142
|
if (msg)
|
|
140
143
|
e.message = msg + '\n\n' + e.message;
|
|
141
144
|
Error.captureStackTrace(e, this.toReturnCollection);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import colors from
|
|
1
|
+
import colors from 'ansi-colors';
|
|
2
2
|
import { matcherHint, printExpected, printReceived } from 'jest-matcher-utils';
|
|
3
3
|
expect.extend({
|
|
4
4
|
toHaveFields(received, expected) {
|
|
@@ -20,8 +20,9 @@ expect.extend({
|
|
|
20
20
|
const pass = !filteredKeys.length === !this.isNot;
|
|
21
21
|
if (!pass) {
|
|
22
22
|
const message = () => `${!this.isNot ? 'Do not expects' : 'Expects'} additional keys other than: ${colors.yellow('' + expectedKeys)}\n` +
|
|
23
|
-
(filteredKeys
|
|
24
|
-
|
|
23
|
+
(filteredKeys
|
|
24
|
+
? `Additional keys received: ${colors.yellow('' + filteredKeys)}\n`
|
|
25
|
+
: 'No additional keys received\n');
|
|
25
26
|
return { message, pass };
|
|
26
27
|
}
|
|
27
28
|
return { actual: received, pass: !this.isNot, message: () => '' };
|
|
@@ -32,33 +33,33 @@ expect.extend({
|
|
|
32
33
|
}
|
|
33
34
|
return {
|
|
34
35
|
pass: false,
|
|
35
|
-
message: () => 'Value is not an array'
|
|
36
|
+
message: () => 'Value is not an array',
|
|
36
37
|
};
|
|
37
38
|
},
|
|
38
39
|
toBeGreaterThanAny(received, expected) {
|
|
39
40
|
return compare('toBeGreaterThan', {
|
|
40
41
|
isNot: this.isNot,
|
|
41
|
-
promise: this.promise
|
|
42
|
+
promise: this.promise,
|
|
42
43
|
}, received, expected, '>', () => received > expected);
|
|
43
44
|
},
|
|
44
45
|
toBeGreaterThanOrEqualAny(received, expected) {
|
|
45
46
|
return compare('toBeGreaterThanOrEqual', {
|
|
46
47
|
isNot: this.isNot,
|
|
47
|
-
promise: this.promise
|
|
48
|
+
promise: this.promise,
|
|
48
49
|
}, received, expected, '>=', () => received >= expected);
|
|
49
50
|
},
|
|
50
51
|
toBeLessThanAny(received, expected) {
|
|
51
52
|
return compare('toBeLessThan', {
|
|
52
53
|
isNot: this.isNot,
|
|
53
|
-
promise: this.promise
|
|
54
|
+
promise: this.promise,
|
|
54
55
|
}, received, expected, '<', () => received < expected);
|
|
55
56
|
},
|
|
56
57
|
toBeLessThanOrEqualAny(received, expected) {
|
|
57
58
|
return compare('toBeLessThanOrEqual', {
|
|
58
59
|
isNot: this.isNot,
|
|
59
|
-
promise: this.promise
|
|
60
|
+
promise: this.promise,
|
|
60
61
|
}, received, expected, '<=', () => received <= expected);
|
|
61
|
-
}
|
|
62
|
+
},
|
|
62
63
|
});
|
|
63
64
|
function compare(matcherName, options, received, expected, operator, fn) {
|
|
64
65
|
const pass = fn(received, expected);
|
package/esm/test-backend.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as path from 'node:path';
|
|
2
2
|
import { FetchBackend, HttpResponse } from '@opra/client';
|
|
3
|
-
import {
|
|
3
|
+
import { createServer, Server } from 'http';
|
|
4
4
|
import { ApiExpect } from './api-expect/api-expect.js';
|
|
5
5
|
/**
|
|
6
6
|
*
|
|
@@ -8,34 +8,37 @@ import { ApiExpect } from './api-expect/api-expect.js';
|
|
|
8
8
|
*/
|
|
9
9
|
export class TestBackend extends FetchBackend {
|
|
10
10
|
constructor(app, options) {
|
|
11
|
-
super('http://tempuri.org', options);
|
|
11
|
+
super(options?.basePath ? path.join('http://tempuri.org', options.basePath) : 'http://tempuri.org', options);
|
|
12
12
|
this._server = app instanceof Server ? app : createServer(app);
|
|
13
13
|
}
|
|
14
14
|
send(req) {
|
|
15
15
|
return new Promise((resolve, reject) => {
|
|
16
|
-
const url = new
|
|
16
|
+
const url = new URL(req.url);
|
|
17
17
|
// Set protocol to HTTP
|
|
18
18
|
url.protocol = 'http';
|
|
19
19
|
// Apply original host to request header
|
|
20
20
|
if (url.host !== 'opra.test' && req.headers.get('host') == null)
|
|
21
21
|
req.headers.set('host', url.host);
|
|
22
|
-
new Promise(
|
|
22
|
+
new Promise(subResolve => {
|
|
23
23
|
if (this._server.listening)
|
|
24
24
|
subResolve();
|
|
25
25
|
else
|
|
26
26
|
this._server.listen(0, '127.0.0.1', () => subResolve());
|
|
27
|
-
})
|
|
27
|
+
})
|
|
28
|
+
.then(() => {
|
|
28
29
|
const address = this._server.address();
|
|
29
30
|
url.host = '127.0.0.1';
|
|
30
31
|
url.port = address.port.toString();
|
|
31
32
|
return fetch(url.toString(), req);
|
|
32
|
-
})
|
|
33
|
+
})
|
|
34
|
+
.then(res => {
|
|
33
35
|
if (!this._server.listening)
|
|
34
36
|
return resolve(res);
|
|
35
37
|
this._server.once('close', () => resolve(res));
|
|
36
38
|
this._server.close();
|
|
37
39
|
this._server.unref();
|
|
38
|
-
})
|
|
40
|
+
})
|
|
41
|
+
.then()
|
|
39
42
|
.catch(error => {
|
|
40
43
|
if (!this._server.listening)
|
|
41
44
|
return reject(error);
|
|
@@ -19,12 +19,13 @@ function _objectMatches(received, expected, path) {
|
|
|
19
19
|
else if (ev && typeof ev === 'object') {
|
|
20
20
|
_objectMatches(rv, ev, path ? path + '.' + k : k);
|
|
21
21
|
}
|
|
22
|
-
else
|
|
22
|
+
else {
|
|
23
23
|
try {
|
|
24
24
|
expect(rv).toEqual(ev);
|
|
25
25
|
}
|
|
26
26
|
catch {
|
|
27
27
|
throw new Error(`Property "${k}" does not match`);
|
|
28
28
|
}
|
|
29
|
+
}
|
|
29
30
|
}
|
|
30
31
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opra/testing",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0-alpha.10",
|
|
4
4
|
"description": "Opra testing package",
|
|
5
5
|
"author": "Panates",
|
|
6
6
|
"license": "MIT",
|
|
@@ -17,8 +17,10 @@
|
|
|
17
17
|
"build:esm": "tsc -b tsconfig-build-esm.json",
|
|
18
18
|
"postbuild": "cp README.md package.json ../../LICENSE ../../build/testing && cp ../../package.cjs.json ../../build/testing/cjs/package.json",
|
|
19
19
|
"lint": "eslint . --max-warnings=0",
|
|
20
|
-
"
|
|
21
|
-
"
|
|
20
|
+
"lint:fix": "eslint . --max-warnings=0 --fix",
|
|
21
|
+
"format": "prettier . --write --log-level=warn",
|
|
22
|
+
"test": "jest --passWithNoTests",
|
|
23
|
+
"cover": "jest --passWithNoTests --collect-coverage",
|
|
22
24
|
"clean": "npm run clean:src && npm run clean:test && npm run clean:dist && npm run clean:cover",
|
|
23
25
|
"clean:src": "ts-cleanup -s src --all",
|
|
24
26
|
"clean:test": "ts-cleanup -s test --all",
|
|
@@ -26,9 +28,11 @@
|
|
|
26
28
|
"clean:cover": "rimraf ../../coverage/testing"
|
|
27
29
|
},
|
|
28
30
|
"dependencies": {
|
|
29
|
-
"@
|
|
30
|
-
"@opra/
|
|
31
|
+
"@browsery/type-is": "^1.6.18-r3",
|
|
32
|
+
"@opra/client": "^1.0.0-alpha.10",
|
|
33
|
+
"@opra/common": "^1.0.0-alpha.10",
|
|
31
34
|
"ansi-colors": "^4.1.3",
|
|
35
|
+
"jest-matcher-utils": "^29.7.0",
|
|
32
36
|
"rule-judgment": "^1.1.5"
|
|
33
37
|
},
|
|
34
38
|
"type": "module",
|
|
@@ -51,4 +55,4 @@
|
|
|
51
55
|
"opra",
|
|
52
56
|
"testing"
|
|
53
57
|
]
|
|
54
|
-
}
|
|
58
|
+
}
|
|
@@ -10,5 +10,5 @@ export interface MatchingErrorIssue {
|
|
|
10
10
|
[index: string]: any;
|
|
11
11
|
}
|
|
12
12
|
export declare class ApiExpectError extends ApiExpectBase {
|
|
13
|
-
toMatch(expected:
|
|
13
|
+
toMatch(expected: string | RegExp | MatchingErrorIssue): this;
|
|
14
14
|
}
|
package/types/test-backend.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { IncomingMessage, Server, ServerResponse } from 'http';
|
|
3
2
|
import { FetchBackend, HttpResponse } from '@opra/client';
|
|
3
|
+
import { IncomingMessage, Server, ServerResponse } from 'http';
|
|
4
4
|
import { ApiExpect } from './api-expect/api-expect.js';
|
|
5
|
+
import type { OpraTestClient } from './test-client.js';
|
|
5
6
|
declare type RequestListener = (req: IncomingMessage, res: ServerResponse) => void;
|
|
6
7
|
export type ResponseExt = {
|
|
7
8
|
expect: ApiExpect;
|
|
@@ -12,7 +13,7 @@ export type ResponseExt = {
|
|
|
12
13
|
*/
|
|
13
14
|
export declare class TestBackend extends FetchBackend {
|
|
14
15
|
protected _server: Server;
|
|
15
|
-
constructor(app: Server | RequestListener, options?:
|
|
16
|
+
constructor(app: Server | RequestListener, options?: OpraTestClient.Options);
|
|
16
17
|
protected send(req: Request): Promise<Response>;
|
|
17
18
|
protected createResponse(init: HttpResponse.Initiator): HttpResponse<any> & ResponseExt;
|
|
18
19
|
}
|
package/types/test-client.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { IncomingMessage, Server, ServerResponse } from 'http';
|
|
3
2
|
import { FetchBackend, HttpClientBase, kBackend } from '@opra/client';
|
|
3
|
+
import { IncomingMessage, Server, ServerResponse } from 'http';
|
|
4
4
|
import { ApiExpect } from './api-expect/api-expect.js';
|
|
5
5
|
import { TestBackend } from './test-backend.js';
|
|
6
6
|
declare type RequestListener = (req: IncomingMessage, res: ServerResponse) => void;
|
|
@@ -8,9 +8,13 @@ export declare const kContext: unique symbol;
|
|
|
8
8
|
export type ResponseExt = {
|
|
9
9
|
expect: ApiExpect;
|
|
10
10
|
};
|
|
11
|
+
export declare namespace OpraTestClient {
|
|
12
|
+
interface Options extends FetchBackend.Options {
|
|
13
|
+
basePath?: string;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
11
16
|
export declare class OpraTestClient extends HttpClientBase<FetchBackend.RequestOptions, ResponseExt> {
|
|
12
|
-
protected _server: Server;
|
|
13
17
|
[kBackend]: TestBackend;
|
|
14
|
-
constructor(app: Server | RequestListener, options?:
|
|
18
|
+
constructor(app: Server | RequestListener, options?: OpraTestClient.Options);
|
|
15
19
|
}
|
|
16
20
|
export {};
|