@opra/testing 0.2.0 → 0.4.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 -46
- 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 +27 -26
- package/cjs/test-client.js +32 -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 -44
- 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 +26 -26
- package/esm/test-client.d.ts +18 -0
- package/esm/test-client.js +27 -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,77 +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
|
-
|
|
73
|
-
expect(item).toBeSortedBy(fields);
|
|
74
|
-
}
|
|
70
|
+
this._expect(this.response.data).toBeSortedBy(fields);
|
|
75
71
|
}
|
|
76
72
|
catch (e) {
|
|
77
73
|
Error.captureStackTrace(e, this.toBeSortedBy);
|
|
@@ -83,9 +79,9 @@ export class ApiExpectArray {
|
|
|
83
79
|
const f = convertFilter(filter);
|
|
84
80
|
if (f) {
|
|
85
81
|
const j = ruleJudgment(f);
|
|
86
|
-
const filtered = this.response.
|
|
82
|
+
const filtered = this.response.data.filter(j);
|
|
87
83
|
try {
|
|
88
|
-
|
|
84
|
+
this._expect(this.response.data).toStrictEqual(filtered);
|
|
89
85
|
}
|
|
90
86
|
catch (e) {
|
|
91
87
|
Error.captureStackTrace(e, this.toBeFilteredBy);
|
|
@@ -96,7 +92,7 @@ export class ApiExpectArray {
|
|
|
96
92
|
}
|
|
97
93
|
toHaveExactItems(expected) {
|
|
98
94
|
try {
|
|
99
|
-
|
|
95
|
+
this._expect(this.response.data).toHaveLength(expected);
|
|
100
96
|
}
|
|
101
97
|
catch (e) {
|
|
102
98
|
Error.captureStackTrace(e, this.toHaveExactItems);
|
|
@@ -106,7 +102,7 @@ export class ApiExpectArray {
|
|
|
106
102
|
}
|
|
107
103
|
toHaveMaxItems(expected) {
|
|
108
104
|
try {
|
|
109
|
-
|
|
105
|
+
this._expect(this.response.data.length).toBeLessThanOrEqual(expected);
|
|
110
106
|
}
|
|
111
107
|
catch (e) {
|
|
112
108
|
Error.captureStackTrace(e, this.toHaveMaxItems);
|
|
@@ -116,7 +112,7 @@ export class ApiExpectArray {
|
|
|
116
112
|
}
|
|
117
113
|
toHaveMinItems(expected) {
|
|
118
114
|
try {
|
|
119
|
-
|
|
115
|
+
this._expect(this.response.data.length).toBeGreaterThanOrEqual(expected);
|
|
120
116
|
}
|
|
121
117
|
catch (e) {
|
|
122
118
|
Error.captureStackTrace(e, this.toHaveMinItems);
|
|
@@ -124,6 +120,12 @@ export class ApiExpectArray {
|
|
|
124
120
|
}
|
|
125
121
|
return this;
|
|
126
122
|
}
|
|
123
|
+
_expect(expected) {
|
|
124
|
+
const out = expect(expected);
|
|
125
|
+
if (this._isNot)
|
|
126
|
+
return out.not;
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
127
129
|
}
|
|
128
130
|
export function convertFilter(str) {
|
|
129
131
|
const ast = typeof str === 'string' ? $parse(str) : str;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { OpraResponse } 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: OpraResponse;
|
|
5
|
+
constructor(response: OpraResponse);
|
|
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 { OpraResponse } from '@opra/client';
|
|
2
|
+
export declare class ApiExpectObject {
|
|
3
|
+
readonly response: OpraResponse;
|
|
4
|
+
protected _isNot: boolean;
|
|
5
|
+
constructor(response: OpraResponse, _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 { OpraResponse } from '@opra/client';
|
|
2
|
+
export declare class ApiExpectOperationResult {
|
|
3
|
+
readonly response: OpraResponse;
|
|
4
|
+
protected _isNot: boolean;
|
|
5
|
+
constructor(response: OpraResponse, _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 { OpraResponse } 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: OpraResponse;
|
|
8
|
+
protected _isNot: boolean;
|
|
9
|
+
constructor(response: OpraResponse, _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 opraTest(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 opraTest(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)) {
|
|
@@ -36,10 +36,10 @@ expect.extend({
|
|
|
36
36
|
};
|
|
37
37
|
},
|
|
38
38
|
toBeSorted(received, compareFn) {
|
|
39
|
-
let pass =
|
|
39
|
+
let pass = true;
|
|
40
40
|
let message;
|
|
41
41
|
if (pass) {
|
|
42
|
-
const sorted = [...received];
|
|
42
|
+
const sorted = [...(received || [])];
|
|
43
43
|
sorted.sort(compareFn);
|
|
44
44
|
try {
|
|
45
45
|
expect(received).toEqual(sorted);
|
|
@@ -65,10 +65,10 @@ expect.extend({
|
|
|
65
65
|
}
|
|
66
66
|
return v;
|
|
67
67
|
};
|
|
68
|
-
let pass =
|
|
68
|
+
let pass = true;
|
|
69
69
|
let message;
|
|
70
70
|
if (pass) {
|
|
71
|
-
const sorted = [...received];
|
|
71
|
+
const sorted = [...(received || [])];
|
|
72
72
|
sorted.sort((a, b) => {
|
|
73
73
|
for (const sortField of fieldsMap) {
|
|
74
74
|
const l = getValue(a, sortField);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { AxiosRequestConfig } from 'axios';
|
|
3
|
+
import { IncomingMessage, Server, ServerResponse } from 'http';
|
|
4
|
+
import { CollectionService, CommonRequestOptions, OpraClient, OpraClientOptions, OpraResponse } from '@opra/client';
|
|
5
|
+
import { SingletonService } from '@opra/client/src/services/singleton-service';
|
|
6
|
+
import { ApiExpect } from './api-expect/api-expect.js';
|
|
7
|
+
declare type RequestListener = (req: IncomingMessage, res: ServerResponse) => void;
|
|
8
|
+
declare type Handler = RequestListener | Server;
|
|
9
|
+
declare type OpraTestResponse<T = any> = OpraResponse<T> & {
|
|
10
|
+
expect: ApiExpect;
|
|
11
|
+
};
|
|
12
|
+
export declare class OpraTestClient extends OpraClient {
|
|
13
|
+
collection<T = any, TResponse extends OpraTestResponse<T> = OpraTestResponse<T>>(name: string): CollectionService<T, TResponse>;
|
|
14
|
+
singleton<T = any, TResponse extends OpraTestResponse<T> = OpraTestResponse<T>>(name: string): SingletonService<T, TResponse>;
|
|
15
|
+
protected _send(req: AxiosRequestConfig, options: CommonRequestOptions): Promise<OpraTestResponse>;
|
|
16
|
+
static create(app: Handler, options?: OpraClientOptions): Promise<OpraTestClient>;
|
|
17
|
+
}
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,27 @@
|
|
|
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
|
+
// @ts-ignore
|
|
6
|
+
collection(name) {
|
|
7
|
+
return super.collection(name);
|
|
8
|
+
}
|
|
9
|
+
// @ts-ignore
|
|
10
|
+
singleton(name) {
|
|
11
|
+
return super.singleton(name);
|
|
12
|
+
}
|
|
13
|
+
async _send(req, options) {
|
|
14
|
+
const resp = (await super._send(req, options));
|
|
15
|
+
resp.expect = new ApiExpect(resp);
|
|
16
|
+
return resp;
|
|
17
|
+
}
|
|
18
|
+
static async create(app, options) {
|
|
19
|
+
const instance = await super.create('/', {
|
|
20
|
+
validateStatus: false,
|
|
21
|
+
...options,
|
|
22
|
+
adapter: axiosist.createAdapter(app)
|
|
23
|
+
});
|
|
24
|
+
Object.setPrototypeOf(instance, OpraTestClient.prototype);
|
|
25
|
+
return instance;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
File without changes
|
|
File without changes
|