@opra/testing 0.3.0 → 0.5.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/cjs/{expect/api-expect-array.js → api-expect/api-expect-collection.js} +48 -44
- package/cjs/{expect → api-expect}/api-expect-error.js +3 -4
- package/cjs/api-expect/api-expect-object.js +54 -0
- package/cjs/{expect → api-expect}/api-expect-operation-result.js +14 -6
- package/cjs/{expect → api-expect}/api-expect.js +30 -23
- package/cjs/constants.js +4 -0
- package/cjs/index.js +3 -22
- package/cjs/{expect/jest-extend → jest-extend}/common.extend.js +23 -22
- package/cjs/test-client.js +34 -0
- package/cjs/{expect/utils → utils}/object-matches.util.js +0 -0
- package/esm/api-expect/api-expect-collection.d.ts +19 -0
- package/esm/{expect/api-expect-array.js → api-expect/api-expect-collection.js} +46 -42
- package/esm/{expect → api-expect}/api-expect-error.d.ts +3 -3
- package/esm/{expect → api-expect}/api-expect-error.js +3 -4
- package/esm/api-expect/api-expect-object.d.ts +11 -0
- package/esm/api-expect/api-expect-object.js +49 -0
- package/esm/api-expect/api-expect-operation-result.d.ts +11 -0
- package/esm/{expect → api-expect}/api-expect-operation-result.js +14 -6
- package/esm/{expect → api-expect}/api-expect.d.ts +8 -7
- package/esm/{expect → api-expect}/api-expect.js +30 -23
- package/esm/constants.d.ts +1 -0
- package/esm/constants.js +1 -0
- package/esm/index.d.ts +2 -6
- package/esm/index.js +2 -19
- package/esm/{expect/jest-extend → jest-extend}/common.extend.d.ts +2 -2
- package/esm/{expect/jest-extend → jest-extend}/common.extend.js +22 -22
- package/esm/test-client.d.ts +22 -0
- package/esm/test-client.js +29 -0
- package/esm/{expect/utils → utils}/object-matches.util.d.ts +0 -0
- package/esm/{expect/utils → utils}/object-matches.util.js +0 -0
- package/package.json +6 -4
- package/cjs/api-response.js +0 -22
- package/cjs/expect/api-expect-object.js +0 -76
- package/cjs/expect/utils/print-errors.util.js +0 -15
- package/cjs/testers/base-operation-tester.js +0 -24
- package/cjs/testers/base-tester.js +0 -23
- package/cjs/testers/entity-create-tester.js +0 -43
- package/cjs/testers/entity-delete-many-tester.js +0 -27
- package/cjs/testers/entity-delete-tester.js +0 -24
- package/cjs/testers/entity-get-tester.js +0 -46
- package/cjs/testers/entity-search-tester.js +0 -75
- package/cjs/testers/entity-tester.js +0 -72
- package/cjs/testers/entity-update-many-tester.js +0 -31
- package/cjs/testers/entity-update-tester.js +0 -46
- package/esm/api-response.d.ts +0 -12
- package/esm/api-response.js +0 -18
- package/esm/expect/api-expect-array.d.ts +0 -17
- package/esm/expect/api-expect-object.d.ts +0 -12
- package/esm/expect/api-expect-object.js +0 -71
- package/esm/expect/api-expect-operation-result.d.ts +0 -9
- package/esm/expect/utils/print-errors.util.d.ts +0 -1
- package/esm/expect/utils/print-errors.util.js +0 -11
- package/esm/testers/base-operation-tester.d.ts +0 -8
- package/esm/testers/base-operation-tester.js +0 -20
- package/esm/testers/base-tester.d.ts +0 -13
- package/esm/testers/base-tester.js +0 -19
- package/esm/testers/entity-create-tester.d.ts +0 -17
- package/esm/testers/entity-create-tester.js +0 -38
- package/esm/testers/entity-delete-many-tester.d.ts +0 -14
- package/esm/testers/entity-delete-many-tester.js +0 -22
- package/esm/testers/entity-delete-tester.d.ts +0 -14
- package/esm/testers/entity-delete-tester.js +0 -19
- package/esm/testers/entity-get-tester.d.ts +0 -18
- package/esm/testers/entity-get-tester.js +0 -41
- package/esm/testers/entity-search-tester.d.ts +0 -22
- package/esm/testers/entity-search-tester.js +0 -70
- package/esm/testers/entity-tester.d.ts +0 -24
- package/esm/testers/entity-tester.js +0 -68
- package/esm/testers/entity-update-many-tester.d.ts +0 -16
- package/esm/testers/entity-update-many-tester.js +0 -26
- package/esm/testers/entity-update-tester.d.ts +0 -19
- package/esm/testers/entity-update-tester.js +0 -41
|
@@ -1,75 +1,73 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
import ruleJudgment from 'rule-judgment';
|
|
3
3
|
import { $parse, ArrayExpression, BooleanLiteral, ComparisonExpression, DateLiteral, LogicalExpression, NullLiteral, NumberLiteral, ParenthesesExpression, QualifiedIdentifier, StringLiteral, TimeLiteral } from '@opra/url';
|
|
4
|
-
export class
|
|
4
|
+
export class ApiExpectCollection {
|
|
5
5
|
response;
|
|
6
|
-
|
|
6
|
+
_isNot;
|
|
7
|
+
constructor(response, _isNot = false) {
|
|
7
8
|
this.response = response;
|
|
9
|
+
this._isNot = _isNot;
|
|
8
10
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const v = _.omitBy(expected, _.isNil);
|
|
12
|
-
for (const item of this.response.body) {
|
|
13
|
-
expect(item).toMatchObject(v);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
catch (e) {
|
|
17
|
-
Error.captureStackTrace(e, this.toMatch);
|
|
18
|
-
throw e;
|
|
19
|
-
}
|
|
20
|
-
return this;
|
|
11
|
+
get not() {
|
|
12
|
+
return new ApiExpectCollection(this.response, !this._isNot);
|
|
21
13
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
for (const item of this.response.body) {
|
|
25
|
-
expect(item).toContainAllKeys(keys);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
catch (e) {
|
|
29
|
-
Error.captureStackTrace(e, this.toContainAllKeys);
|
|
30
|
-
throw e;
|
|
31
|
-
}
|
|
14
|
+
forEach(callbackfn) {
|
|
15
|
+
this.response.data.forEach(callbackfn);
|
|
32
16
|
return this;
|
|
33
17
|
}
|
|
34
|
-
|
|
18
|
+
toMatch(expected) {
|
|
35
19
|
try {
|
|
36
|
-
|
|
37
|
-
|
|
20
|
+
const v = _.omitBy(expected, _.isNil);
|
|
21
|
+
for (const item of this.response.data) {
|
|
22
|
+
this._expect(item).toMatchObject(v);
|
|
38
23
|
}
|
|
39
24
|
}
|
|
40
25
|
catch (e) {
|
|
41
|
-
Error.captureStackTrace(e, this.
|
|
26
|
+
Error.captureStackTrace(e, this.toMatch);
|
|
42
27
|
throw e;
|
|
43
28
|
}
|
|
44
29
|
return this;
|
|
45
30
|
}
|
|
46
|
-
|
|
31
|
+
toHaveFields(keys) {
|
|
47
32
|
try {
|
|
48
|
-
for (const item of this.response.
|
|
49
|
-
|
|
33
|
+
for (const item of this.response.data) {
|
|
34
|
+
this._expect(item).toHaveFields(keys);
|
|
50
35
|
}
|
|
51
36
|
}
|
|
52
37
|
catch (e) {
|
|
53
|
-
Error.captureStackTrace(e, this.
|
|
38
|
+
Error.captureStackTrace(e, this.toHaveFields);
|
|
54
39
|
throw e;
|
|
55
40
|
}
|
|
56
41
|
return this;
|
|
57
42
|
}
|
|
58
|
-
|
|
43
|
+
toHaveFieldsOnly(keys) {
|
|
59
44
|
try {
|
|
60
|
-
for (const item of this.response.
|
|
61
|
-
|
|
45
|
+
for (const item of this.response.data) {
|
|
46
|
+
this._expect(item).toHaveFieldsOnly(keys);
|
|
62
47
|
}
|
|
63
48
|
}
|
|
64
49
|
catch (e) {
|
|
65
|
-
Error.captureStackTrace(e, this.
|
|
50
|
+
Error.captureStackTrace(e, this.toHaveFieldsOnly);
|
|
66
51
|
throw e;
|
|
67
52
|
}
|
|
68
53
|
return this;
|
|
69
54
|
}
|
|
55
|
+
//
|
|
56
|
+
// toHaveProperty(keyPath, value?): this {
|
|
57
|
+
// try {
|
|
58
|
+
// for (const item of this.response.data) {
|
|
59
|
+
// this._expect(item).toHaveProperty(keyPath, value);
|
|
60
|
+
// }
|
|
61
|
+
//
|
|
62
|
+
// } catch (e: any) {
|
|
63
|
+
// Error.captureStackTrace(e, this.toHaveProperty);
|
|
64
|
+
// throw e;
|
|
65
|
+
// }
|
|
66
|
+
// return this;
|
|
67
|
+
// }
|
|
70
68
|
toBeSortedBy(...fields) {
|
|
71
69
|
try {
|
|
72
|
-
|
|
70
|
+
this._expect(this.response.data).toBeSortedBy(fields);
|
|
73
71
|
}
|
|
74
72
|
catch (e) {
|
|
75
73
|
Error.captureStackTrace(e, this.toBeSortedBy);
|
|
@@ -81,9 +79,9 @@ export class ApiExpectArray {
|
|
|
81
79
|
const f = convertFilter(filter);
|
|
82
80
|
if (f) {
|
|
83
81
|
const j = ruleJudgment(f);
|
|
84
|
-
const filtered = this.response.
|
|
82
|
+
const filtered = this.response.data.filter(j);
|
|
85
83
|
try {
|
|
86
|
-
|
|
84
|
+
this._expect(this.response.data).toStrictEqual(filtered);
|
|
87
85
|
}
|
|
88
86
|
catch (e) {
|
|
89
87
|
Error.captureStackTrace(e, this.toBeFilteredBy);
|
|
@@ -94,7 +92,7 @@ export class ApiExpectArray {
|
|
|
94
92
|
}
|
|
95
93
|
toHaveExactItems(expected) {
|
|
96
94
|
try {
|
|
97
|
-
|
|
95
|
+
this._expect(this.response.data).toHaveLength(expected);
|
|
98
96
|
}
|
|
99
97
|
catch (e) {
|
|
100
98
|
Error.captureStackTrace(e, this.toHaveExactItems);
|
|
@@ -104,7 +102,7 @@ export class ApiExpectArray {
|
|
|
104
102
|
}
|
|
105
103
|
toHaveMaxItems(expected) {
|
|
106
104
|
try {
|
|
107
|
-
|
|
105
|
+
this._expect(this.response.data.length).toBeLessThanOrEqual(expected);
|
|
108
106
|
}
|
|
109
107
|
catch (e) {
|
|
110
108
|
Error.captureStackTrace(e, this.toHaveMaxItems);
|
|
@@ -114,7 +112,7 @@ export class ApiExpectArray {
|
|
|
114
112
|
}
|
|
115
113
|
toHaveMinItems(expected) {
|
|
116
114
|
try {
|
|
117
|
-
|
|
115
|
+
this._expect(this.response.data.length).toBeGreaterThanOrEqual(expected);
|
|
118
116
|
}
|
|
119
117
|
catch (e) {
|
|
120
118
|
Error.captureStackTrace(e, this.toHaveMinItems);
|
|
@@ -122,6 +120,12 @@ export class ApiExpectArray {
|
|
|
122
120
|
}
|
|
123
121
|
return this;
|
|
124
122
|
}
|
|
123
|
+
_expect(expected) {
|
|
124
|
+
const out = expect(expected);
|
|
125
|
+
if (this._isNot)
|
|
126
|
+
return out.not;
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
125
129
|
}
|
|
126
130
|
export function convertFilter(str) {
|
|
127
131
|
const ast = typeof str === 'string' ? $parse(str) : str;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ClientResponse } from '@opra/client';
|
|
2
2
|
import { ApiExpectObject } from './api-expect-object.js';
|
|
3
3
|
export declare class ApiExpectError extends ApiExpectObject {
|
|
4
|
-
readonly response:
|
|
5
|
-
constructor(response:
|
|
4
|
+
readonly response: ClientResponse;
|
|
5
|
+
constructor(response: ClientResponse);
|
|
6
6
|
toContainDetail(...matching: any[]): void;
|
|
7
7
|
}
|
|
8
8
|
declare global {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import matcherUtils from 'jest-matcher-utils';
|
|
2
|
+
import { objectMatches } from '../utils/object-matches.util.js';
|
|
2
3
|
import { ApiExpectObject } from './api-expect-object.js';
|
|
3
|
-
import { objectMatches } from './utils/object-matches.util.js';
|
|
4
4
|
export class ApiExpectError extends ApiExpectObject {
|
|
5
5
|
response;
|
|
6
6
|
constructor(response) {
|
|
@@ -9,9 +9,8 @@ export class ApiExpectError extends ApiExpectObject {
|
|
|
9
9
|
}
|
|
10
10
|
toContainDetail(...matching) {
|
|
11
11
|
try {
|
|
12
|
-
expect(this.response.
|
|
13
|
-
expect(this.response.
|
|
14
|
-
expect(this.response.body.issues).apiErrorDetailToContain(matching);
|
|
12
|
+
expect(this.response.data.issues).toBeDefined();
|
|
13
|
+
expect(this.response.data.issues).apiErrorDetailToContain(matching);
|
|
15
14
|
}
|
|
16
15
|
catch (e) {
|
|
17
16
|
Error.captureStackTrace(e, this.toContainDetail);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ClientResponse } from '@opra/client';
|
|
2
|
+
export declare class ApiExpectObject {
|
|
3
|
+
readonly response: ClientResponse;
|
|
4
|
+
protected _isNot: boolean;
|
|
5
|
+
constructor(response: ClientResponse, _isNot?: boolean);
|
|
6
|
+
get not(): ApiExpectObject;
|
|
7
|
+
toMatch<T extends {}>(expected: T): this;
|
|
8
|
+
toHaveFields(fields: string[]): this;
|
|
9
|
+
toHaveFieldsOnly(fields: string[]): this;
|
|
10
|
+
protected _expect(expected: any): jest.Matchers<any>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
export class ApiExpectObject {
|
|
3
|
+
response;
|
|
4
|
+
_isNot;
|
|
5
|
+
constructor(response, _isNot = false) {
|
|
6
|
+
this.response = response;
|
|
7
|
+
this._isNot = _isNot;
|
|
8
|
+
}
|
|
9
|
+
get not() {
|
|
10
|
+
return new ApiExpectObject(this.response, !this._isNot);
|
|
11
|
+
}
|
|
12
|
+
toMatch(expected) {
|
|
13
|
+
try {
|
|
14
|
+
const v = _.omitBy(expected, _.isNil);
|
|
15
|
+
this._expect(this.response.data).toMatchObject(v);
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
Error.captureStackTrace(e, this.toMatch);
|
|
19
|
+
throw e;
|
|
20
|
+
}
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
toHaveFields(fields) {
|
|
24
|
+
try {
|
|
25
|
+
this._expect(this.response.data).toHaveFields(fields);
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
Error.captureStackTrace(e, this.toHaveFields);
|
|
29
|
+
throw e;
|
|
30
|
+
}
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
toHaveFieldsOnly(fields) {
|
|
34
|
+
try {
|
|
35
|
+
this._expect(this.response.data).toHaveFieldsOnly(fields);
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
Error.captureStackTrace(e, this.toHaveFieldsOnly);
|
|
39
|
+
throw e;
|
|
40
|
+
}
|
|
41
|
+
return this;
|
|
42
|
+
}
|
|
43
|
+
_expect(expected) {
|
|
44
|
+
const out = expect(expected);
|
|
45
|
+
if (this._isNot)
|
|
46
|
+
return out.not;
|
|
47
|
+
return out;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ClientResponse } from '@opra/client';
|
|
2
|
+
export declare class ApiExpectOperationResult {
|
|
3
|
+
readonly response: ClientResponse;
|
|
4
|
+
protected _isNot: boolean;
|
|
5
|
+
constructor(response: ClientResponse, _isNot?: boolean);
|
|
6
|
+
get not(): ApiExpectOperationResult;
|
|
7
|
+
toBeAffectedExact(expected: number): this;
|
|
8
|
+
toBeAffectedMin(expected: number): this;
|
|
9
|
+
toBeAffectedMax(expected: number): this;
|
|
10
|
+
protected _expect(expected: any): jest.Matchers<any>;
|
|
11
|
+
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
export class ApiExpectOperationResult {
|
|
2
2
|
response;
|
|
3
|
-
|
|
3
|
+
_isNot;
|
|
4
|
+
constructor(response, _isNot = false) {
|
|
4
5
|
this.response = response;
|
|
6
|
+
this._isNot = _isNot;
|
|
5
7
|
}
|
|
6
|
-
get
|
|
7
|
-
return this.response.
|
|
8
|
+
get not() {
|
|
9
|
+
return new ApiExpectOperationResult(this.response, !this._isNot);
|
|
8
10
|
}
|
|
9
11
|
toBeAffectedExact(expected) {
|
|
10
12
|
try {
|
|
11
|
-
|
|
13
|
+
this._expect(this.response.data.affected).toStrictEqual(expected);
|
|
12
14
|
}
|
|
13
15
|
catch (e) {
|
|
14
16
|
Error.captureStackTrace(e, this.toBeAffectedExact);
|
|
@@ -18,7 +20,7 @@ export class ApiExpectOperationResult {
|
|
|
18
20
|
}
|
|
19
21
|
toBeAffectedMin(expected) {
|
|
20
22
|
try {
|
|
21
|
-
|
|
23
|
+
this._expect(this.response.data.affected).toBeGreaterThanOrEqual(expected);
|
|
22
24
|
}
|
|
23
25
|
catch (e) {
|
|
24
26
|
Error.captureStackTrace(e, this.toBeAffectedMin);
|
|
@@ -28,7 +30,7 @@ export class ApiExpectOperationResult {
|
|
|
28
30
|
}
|
|
29
31
|
toBeAffectedMax(expected) {
|
|
30
32
|
try {
|
|
31
|
-
|
|
33
|
+
this._expect(this.response.data.affected).toBeLessThanOrEqual(expected);
|
|
32
34
|
}
|
|
33
35
|
catch (e) {
|
|
34
36
|
Error.captureStackTrace(e, this.toBeAffectedMax);
|
|
@@ -36,4 +38,10 @@ export class ApiExpectOperationResult {
|
|
|
36
38
|
}
|
|
37
39
|
return this;
|
|
38
40
|
}
|
|
41
|
+
_expect(expected) {
|
|
42
|
+
const out = expect(expected);
|
|
43
|
+
if (this._isNot)
|
|
44
|
+
return out.not;
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
39
47
|
}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import '
|
|
2
|
-
import
|
|
3
|
-
import { ApiExpectArray } from './api-expect-array.js';
|
|
1
|
+
import { ClientResponse } from '@opra/client';
|
|
2
|
+
import { ApiExpectCollection } from './api-expect-collection.js';
|
|
4
3
|
import { ApiExpectError } from './api-expect-error.js';
|
|
5
4
|
import { ApiExpectObject } from './api-expect-object.js';
|
|
6
5
|
import { ApiExpectOperationResult } from './api-expect-operation-result.js';
|
|
7
6
|
export declare class ApiExpect {
|
|
8
|
-
readonly response:
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
readonly response: ClientResponse;
|
|
8
|
+
protected _isNot: boolean;
|
|
9
|
+
constructor(response: ClientResponse, _isNot?: boolean);
|
|
10
|
+
get not(): ApiExpect;
|
|
11
11
|
toSuccess(status?: number): this;
|
|
12
12
|
toFail(status?: number): ApiExpectError;
|
|
13
13
|
toReturnOperationResult(): ApiExpectOperationResult;
|
|
14
14
|
toReturnObject(): ApiExpectObject;
|
|
15
|
-
|
|
15
|
+
toReturnCollection(): ApiExpectCollection;
|
|
16
|
+
protected _expect(expected: any): jest.Matchers<any>;
|
|
16
17
|
}
|
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
import './
|
|
2
|
-
import { ApiExpectArray } from './api-expect-array.js';
|
|
1
|
+
import { ApiExpectCollection } from './api-expect-collection.js';
|
|
3
2
|
import { ApiExpectError } from './api-expect-error.js';
|
|
4
3
|
import { ApiExpectObject } from './api-expect-object.js';
|
|
5
4
|
import { ApiExpectOperationResult } from './api-expect-operation-result.js';
|
|
6
5
|
export class ApiExpect {
|
|
7
6
|
response;
|
|
8
|
-
|
|
7
|
+
_isNot;
|
|
8
|
+
constructor(response, _isNot = false) {
|
|
9
9
|
this.response = response;
|
|
10
|
+
this._isNot = _isNot;
|
|
10
11
|
}
|
|
11
|
-
get
|
|
12
|
-
return this.response.
|
|
12
|
+
get not() {
|
|
13
|
+
return new ApiExpect(this.response, !this._isNot);
|
|
13
14
|
}
|
|
14
15
|
toSuccess(status = 200) {
|
|
15
|
-
let msg = '
|
|
16
|
+
let msg = '';
|
|
16
17
|
try {
|
|
17
|
-
msg = '
|
|
18
|
-
|
|
18
|
+
msg = 'Unexpected "status" returned';
|
|
19
|
+
this._expect(this.response.status).toStrictEqual(status);
|
|
19
20
|
}
|
|
20
21
|
catch (e) {
|
|
21
22
|
if (msg)
|
|
@@ -26,7 +27,7 @@ export class ApiExpect {
|
|
|
26
27
|
return this;
|
|
27
28
|
}
|
|
28
29
|
toFail(status = 400) {
|
|
29
|
-
let msg = '
|
|
30
|
+
let msg = '';
|
|
30
31
|
try {
|
|
31
32
|
msg = 'Response "status" does not match';
|
|
32
33
|
if (status) {
|
|
@@ -37,8 +38,8 @@ export class ApiExpect {
|
|
|
37
38
|
expect(this.response.status).toBeLessThanOrEqual(599);
|
|
38
39
|
}
|
|
39
40
|
msg = 'Api did not returned "errors"';
|
|
40
|
-
expect(this.response.
|
|
41
|
-
expect(this.response.
|
|
41
|
+
expect(this.response.data.errors).toBeArray();
|
|
42
|
+
expect(this.response.data.errors.length).toBeGreaterThan(0);
|
|
42
43
|
}
|
|
43
44
|
catch (e) {
|
|
44
45
|
if (msg)
|
|
@@ -49,26 +50,26 @@ export class ApiExpect {
|
|
|
49
50
|
return new ApiExpectError(this.response);
|
|
50
51
|
}
|
|
51
52
|
toReturnOperationResult() {
|
|
52
|
-
let msg = '
|
|
53
|
+
let msg = '';
|
|
53
54
|
try {
|
|
54
55
|
msg = '"body" is empty';
|
|
55
|
-
expect(this.response.
|
|
56
|
+
expect(this.response.data).toBeDefined();
|
|
56
57
|
msg = '"operation" property is empty';
|
|
57
|
-
expect(this.response.
|
|
58
|
+
expect(this.response.data.operation).toBeDefined();
|
|
58
59
|
}
|
|
59
60
|
catch (e) {
|
|
60
61
|
if (msg)
|
|
61
62
|
e.message = msg + '\n\n' + e.message;
|
|
62
|
-
Error.captureStackTrace(e, this.
|
|
63
|
+
Error.captureStackTrace(e, this.toReturnOperationResult);
|
|
63
64
|
throw e;
|
|
64
65
|
}
|
|
65
66
|
return new ApiExpectOperationResult(this.response);
|
|
66
67
|
}
|
|
67
68
|
toReturnObject() {
|
|
68
|
-
let msg = '
|
|
69
|
+
let msg = '';
|
|
69
70
|
try {
|
|
70
71
|
msg = '"body" is empty';
|
|
71
|
-
expect(this.response.
|
|
72
|
+
expect(this.response.data).toBeDefined();
|
|
72
73
|
}
|
|
73
74
|
catch (e) {
|
|
74
75
|
if (msg)
|
|
@@ -78,20 +79,26 @@ export class ApiExpect {
|
|
|
78
79
|
}
|
|
79
80
|
return new ApiExpectObject(this.response);
|
|
80
81
|
}
|
|
81
|
-
|
|
82
|
-
let msg = '
|
|
82
|
+
toReturnCollection() {
|
|
83
|
+
let msg = '';
|
|
83
84
|
try {
|
|
84
85
|
msg = '"body" is empty';
|
|
85
|
-
expect(this.response.
|
|
86
|
+
expect(this.response.data).toBeDefined();
|
|
86
87
|
msg = '"body" is not an array';
|
|
87
|
-
expect(this.response.
|
|
88
|
+
expect(this.response.data).toBeArray();
|
|
88
89
|
}
|
|
89
90
|
catch (e) {
|
|
90
91
|
if (msg)
|
|
91
92
|
e.message = msg + '\n\n' + e.message;
|
|
92
|
-
Error.captureStackTrace(e, this.
|
|
93
|
+
Error.captureStackTrace(e, this.toReturnCollection);
|
|
93
94
|
throw e;
|
|
94
95
|
}
|
|
95
|
-
return new
|
|
96
|
+
return new ApiExpectCollection(this.response);
|
|
97
|
+
}
|
|
98
|
+
_expect(expected) {
|
|
99
|
+
const out = expect(expected);
|
|
100
|
+
if (this._isNot)
|
|
101
|
+
return out.not;
|
|
102
|
+
return out;
|
|
96
103
|
}
|
|
97
104
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const expectSymbolTag: unique symbol;
|
package/esm/constants.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const expectSymbolTag = Symbol('opra.test.expect');
|
package/esm/index.d.ts
CHANGED
|
@@ -1,6 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
export declare function opraTestClient(app: any, options?: Partial<Omit<OpraTesterParams, 'app'>>): OpraTester;
|
|
4
|
-
export declare class OpraTester extends BaseTester {
|
|
5
|
-
entity(path: string): OpraEntityTester;
|
|
6
|
-
}
|
|
1
|
+
import './jest-extend/common.extend.js';
|
|
2
|
+
export * from './test-client.js';
|
package/esm/index.js
CHANGED
|
@@ -1,19 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
export function opraTestClient(app, options) {
|
|
4
|
-
return new OpraTester({
|
|
5
|
-
app,
|
|
6
|
-
...options,
|
|
7
|
-
prefix: options?.prefix || '',
|
|
8
|
-
headers: options?.headers || {}
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
export class OpraTester extends BaseTester {
|
|
12
|
-
entity(path) {
|
|
13
|
-
return new OpraEntityTester({
|
|
14
|
-
...this._params,
|
|
15
|
-
headers: { ...this._params.headers },
|
|
16
|
-
path
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
}
|
|
1
|
+
import './jest-extend/common.extend.js';
|
|
2
|
+
export * from './test-client.js';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
declare global {
|
|
2
2
|
namespace jest {
|
|
3
3
|
interface Matchers<R> {
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
toHaveFields(expected: string[]): any;
|
|
5
|
+
toHaveFieldsOnly(expected: string[]): any;
|
|
6
6
|
toBeArray(): any;
|
|
7
7
|
toBeSorted(compareFn?: (a: any, b: any) => number): any;
|
|
8
8
|
toBeSortedBy(properties: string[]): any;
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
+
import colors from "ansi-colors";
|
|
1
2
|
import { matcherHint, printExpected, printReceived } from 'jest-matcher-utils';
|
|
2
3
|
expect.extend({
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
4
|
+
toHaveFields(received, expected) {
|
|
5
|
+
const expectedKeys = (Array.isArray(expected) ? expected : Object.keys(expected)).map(x => x.toLowerCase());
|
|
6
|
+
const objectKeys = Object.keys(received).map(x => x.toLowerCase());
|
|
7
|
+
const filteredKeys = expectedKeys.filter(x => !objectKeys.includes(x));
|
|
8
|
+
const pass = !filteredKeys.length === !this.isNot;
|
|
9
|
+
if (!pass) {
|
|
10
|
+
const message = () => `Expects keys to${this.isNot ? ' not' : ''} contain: ${colors.yellow('' + expectedKeys)}\n` +
|
|
11
|
+
`${this.isNot ? 'Unsolicited' : 'Missing'} fields: ${colors.yellow('' + filteredKeys)}\n`;
|
|
12
|
+
return { message, pass: !!this.isNot };
|
|
13
13
|
}
|
|
14
|
-
return { actual: received, pass:
|
|
14
|
+
return { actual: received, pass: !this.isNot, message: () => '' };
|
|
15
15
|
},
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
16
|
+
toHaveFieldsOnly(received, expected) {
|
|
17
|
+
const expectedKeys = (Array.isArray(expected) ? expected : Object.keys(expected)).map(x => x.toLowerCase());
|
|
18
|
+
const objectKeys = Object.keys(received).map(x => x.toLowerCase());
|
|
19
|
+
const filteredKeys = objectKeys.filter(x => !expectedKeys.includes(x));
|
|
20
|
+
const pass = !filteredKeys.length === !this.isNot;
|
|
21
|
+
if (!pass) {
|
|
22
|
+
const message = () => `${!this.isNot ? 'Do not expects' : 'Expects'} additional keys other than: ${colors.yellow('' + expectedKeys)}\n` +
|
|
23
|
+
(filteredKeys ? `Additional keys received: ${colors.yellow('' + filteredKeys)}\n` :
|
|
24
|
+
'No additional keys received\n');
|
|
25
|
+
return { message, pass };
|
|
26
26
|
}
|
|
27
|
-
return { actual: received, pass:
|
|
27
|
+
return { actual: received, pass: !this.isNot, message: () => '' };
|
|
28
28
|
},
|
|
29
29
|
toBeArray(received) {
|
|
30
30
|
if (Array.isArray(received)) {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { AxiosRequestConfig } from 'axios';
|
|
3
|
+
import { IncomingMessage, Server, ServerResponse } from 'http';
|
|
4
|
+
import { Type } from 'ts-gems';
|
|
5
|
+
import { ClientResponse, CollectionNode, OpraClient, OpraClientOptions } from '@opra/client';
|
|
6
|
+
import { SingletonNode } from '@opra/client/src/services/singleton-node';
|
|
7
|
+
import { OpraDocument } from '@opra/schema/src/index';
|
|
8
|
+
import { ApiExpect } from './api-expect/api-expect.js';
|
|
9
|
+
declare type RequestListener = (req: IncomingMessage, res: ServerResponse) => void;
|
|
10
|
+
declare type Handler = RequestListener | Server;
|
|
11
|
+
declare type OpraTestResponse<T = any> = ClientResponse<T> & {
|
|
12
|
+
expect: ApiExpect;
|
|
13
|
+
};
|
|
14
|
+
export declare class OpraTestClient extends OpraClient {
|
|
15
|
+
constructor(app: Handler, options?: OpraClientOptions);
|
|
16
|
+
constructor(app: Handler, metadata: OpraDocument, options?: OpraClientOptions);
|
|
17
|
+
collection<T = any, TResponse extends OpraTestResponse<T> = OpraTestResponse<T>>(name: string): CollectionNode<T, TResponse>;
|
|
18
|
+
singleton<T = any, TResponse extends OpraTestResponse<T> = OpraTestResponse<T>>(name: string): SingletonNode<T, TResponse>;
|
|
19
|
+
protected _send<TResponse extends OpraTestResponse>(req: AxiosRequestConfig): Promise<TResponse>;
|
|
20
|
+
static create<T extends OpraTestClient>(this: Type<T>, app: Handler, options?: OpraClientOptions): Promise<T>;
|
|
21
|
+
}
|
|
22
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as axiosist from 'axiosist';
|
|
2
|
+
import { OpraClient } from '@opra/client';
|
|
3
|
+
import { ApiExpect } from './api-expect/api-expect.js';
|
|
4
|
+
export class OpraTestClient extends OpraClient {
|
|
5
|
+
constructor(app, arg1, arg2) {
|
|
6
|
+
super('/', arg1, arg2);
|
|
7
|
+
this._axios.defaults.adapter = axiosist.createAdapter(app);
|
|
8
|
+
this._axios.defaults.validateStatus = () => true;
|
|
9
|
+
}
|
|
10
|
+
// @ts-ignore
|
|
11
|
+
collection(name) {
|
|
12
|
+
return super.collection(name);
|
|
13
|
+
}
|
|
14
|
+
// @ts-ignore
|
|
15
|
+
singleton(name) {
|
|
16
|
+
return super.singleton(name);
|
|
17
|
+
}
|
|
18
|
+
// @ts-ignore
|
|
19
|
+
async _send(req) {
|
|
20
|
+
const resp = (await super._send(req));
|
|
21
|
+
resp.expect = new ApiExpect(resp);
|
|
22
|
+
return resp;
|
|
23
|
+
}
|
|
24
|
+
static async create(app, options) {
|
|
25
|
+
const client = new this(app, options);
|
|
26
|
+
await client.init();
|
|
27
|
+
return client;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
File without changes
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opra/testing",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Opra testing package",
|
|
5
5
|
"author": "Panates",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,11 +25,13 @@
|
|
|
25
25
|
"clean:cover": "rimraf ../../coverage/testing"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@opra/schema": "^0.
|
|
29
|
-
"@opra/url": "^0.
|
|
28
|
+
"@opra/schema": "^0.5.0",
|
|
29
|
+
"@opra/url": "^0.5.0",
|
|
30
|
+
"@opra/client": "^0.5.0",
|
|
31
|
+
"ansi-colors": "^4.1.3",
|
|
30
32
|
"lodash": "^4.17.21",
|
|
31
33
|
"rule-judgment": "^1.1.5",
|
|
32
|
-
"supertest": "^6.
|
|
34
|
+
"supertest": "^6.3.0"
|
|
33
35
|
},
|
|
34
36
|
"devDependencies": {
|
|
35
37
|
"@types/supertest": "^2.0.12"
|