@onlineapps/conn-orch-validator 2.0.6 → 2.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -1
- package/TESTING_STRATEGY.md +0 -0
- package/docs/DESIGN.md +0 -0
- package/examples/service-wrapper-usage.js +0 -0
- package/examples/three-tier-testing.js +0 -0
- package/jest.config.js +0 -0
- package/onlineapps-conn-e2e-testing-1.0.0.tgz +0 -0
- package/package.json +1 -1
- package/src/CookbookTestRunner.js +4 -4
- package/src/CookbookTestUtils.js +0 -0
- package/src/ServiceReadinessValidator.js +0 -0
- package/src/ServiceTestHarness.js +0 -0
- package/src/ServiceValidator.js +0 -0
- package/src/TestOrchestrator.js +0 -0
- package/src/ValidationOrchestrator.js +29 -22
- package/src/WorkflowTestRunner.js +0 -0
- package/src/helpers/README.md +0 -0
- package/src/helpers/createPreValidationTests.js +0 -0
- package/src/helpers/createServiceReadinessTests.js +0 -0
- package/src/index.js +0 -0
- package/src/mocks/MockMQClient.js +0 -0
- package/src/mocks/MockRegistry.js +0 -0
- package/src/mocks/MockStorage.js +0 -0
- package/src/validators/ServiceStructureValidator.js +0 -0
- package/src/validators/ValidationProofGenerator.js +0 -0
- package/test-mq-flow.js +0 -0
- package/tests/component/testing-framework-integration.test.js +0 -313
- package/tests/integration/ServiceReadiness.test.js +0 -265
- package/tests/monitoring-e2e.test.js +0 -315
- package/tests/run-example.js +0 -257
- package/tests/unit/CookbookTestRunner.test.js +0 -353
- package/tests/unit/MockMQClient.test.js +0 -190
- package/tests/unit/MockRegistry.test.js +0 -233
- package/tests/unit/MockStorage.test.js +0 -257
- package/tests/unit/ServiceValidator.test.js +0 -429
- package/tests/unit/WorkflowTestRunner.test.js +0 -546
package/tests/run-example.js
DELETED
|
@@ -1,257 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Simple test runner to demonstrate connector-testing functionality
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const { TestOrchestrator, ServiceTestHarness, ServiceReadinessValidator } = require('../src');
|
|
8
|
-
const express = require('express');
|
|
9
|
-
const path = require('path');
|
|
10
|
-
|
|
11
|
-
// Create a minimal test service
|
|
12
|
-
function createTestService() {
|
|
13
|
-
const app = express();
|
|
14
|
-
app.use(express.json());
|
|
15
|
-
|
|
16
|
-
app.get('/health', (req, res) => {
|
|
17
|
-
res.json({
|
|
18
|
-
status: 'healthy',
|
|
19
|
-
service: 'test-service',
|
|
20
|
-
timestamp: new Date().toISOString()
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
app.get('/good-day', (req, res) => {
|
|
25
|
-
const name = req.query.name || 'World';
|
|
26
|
-
res.json({
|
|
27
|
-
message: `Good day, ${name}!`,
|
|
28
|
-
timestamp: new Date().toISOString()
|
|
29
|
-
});
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
app.post('/process', (req, res) => {
|
|
33
|
-
res.json({
|
|
34
|
-
processed: true,
|
|
35
|
-
input: req.body,
|
|
36
|
-
output: { transformed: true }
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
return app;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Create OpenAPI spec
|
|
44
|
-
function createOpenApiSpec() {
|
|
45
|
-
return {
|
|
46
|
-
openapi: '3.0.0',
|
|
47
|
-
info: {
|
|
48
|
-
title: 'Test Service',
|
|
49
|
-
version: '1.0.0',
|
|
50
|
-
description: 'Service for testing connector-testing'
|
|
51
|
-
},
|
|
52
|
-
paths: {
|
|
53
|
-
'/health': {
|
|
54
|
-
get: {
|
|
55
|
-
operationId: 'healthCheck',
|
|
56
|
-
summary: 'Health check endpoint',
|
|
57
|
-
responses: {
|
|
58
|
-
'200': {
|
|
59
|
-
description: 'Service is healthy',
|
|
60
|
-
content: {
|
|
61
|
-
'application/json': {
|
|
62
|
-
schema: {
|
|
63
|
-
type: 'object',
|
|
64
|
-
properties: {
|
|
65
|
-
status: { type: 'string' },
|
|
66
|
-
service: { type: 'string' },
|
|
67
|
-
timestamp: { type: 'string' }
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
},
|
|
76
|
-
'/good-day': {
|
|
77
|
-
get: {
|
|
78
|
-
operationId: 'goodDay',
|
|
79
|
-
summary: 'Greeting endpoint',
|
|
80
|
-
parameters: [
|
|
81
|
-
{
|
|
82
|
-
name: 'name',
|
|
83
|
-
in: 'query',
|
|
84
|
-
required: false,
|
|
85
|
-
schema: { type: 'string' }
|
|
86
|
-
}
|
|
87
|
-
],
|
|
88
|
-
responses: {
|
|
89
|
-
'200': {
|
|
90
|
-
description: 'Greeting response',
|
|
91
|
-
content: {
|
|
92
|
-
'application/json': {
|
|
93
|
-
schema: {
|
|
94
|
-
type: 'object',
|
|
95
|
-
properties: {
|
|
96
|
-
message: { type: 'string' },
|
|
97
|
-
timestamp: { type: 'string' }
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
},
|
|
106
|
-
'/process': {
|
|
107
|
-
post: {
|
|
108
|
-
operationId: 'processData',
|
|
109
|
-
summary: 'Process data',
|
|
110
|
-
requestBody: {
|
|
111
|
-
content: {
|
|
112
|
-
'application/json': {
|
|
113
|
-
schema: {
|
|
114
|
-
type: 'object'
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
},
|
|
119
|
-
responses: {
|
|
120
|
-
'200': {
|
|
121
|
-
description: 'Processing result',
|
|
122
|
-
content: {
|
|
123
|
-
'application/json': {
|
|
124
|
-
schema: {
|
|
125
|
-
type: 'object',
|
|
126
|
-
properties: {
|
|
127
|
-
processed: { type: 'boolean' },
|
|
128
|
-
input: { type: 'object' },
|
|
129
|
-
output: { type: 'object' }
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
async function runTests() {
|
|
143
|
-
console.log('=== Connector-Testing Demo ===\n');
|
|
144
|
-
|
|
145
|
-
const app = createTestService();
|
|
146
|
-
const openApiSpec = createOpenApiSpec();
|
|
147
|
-
|
|
148
|
-
// Test 1: Service Test Harness
|
|
149
|
-
console.log('1. Testing with ServiceTestHarness (with mocks)...\n');
|
|
150
|
-
|
|
151
|
-
const harness = new ServiceTestHarness({
|
|
152
|
-
service: app,
|
|
153
|
-
serviceName: 'test-service',
|
|
154
|
-
openApiSpec,
|
|
155
|
-
mockInfrastructure: true
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
await harness.start();
|
|
159
|
-
console.log(` ✓ Service started at: ${harness.baseUrl}`);
|
|
160
|
-
|
|
161
|
-
// Test API calls
|
|
162
|
-
const healthResponse = await harness.callApi('GET', '/health');
|
|
163
|
-
console.log(` ✓ Health check: ${healthResponse.status}`);
|
|
164
|
-
|
|
165
|
-
const greetingResponse = await harness.callApi('GET', '/good-day', null, {});
|
|
166
|
-
console.log(` ✓ Greeting: ${greetingResponse.message}`);
|
|
167
|
-
|
|
168
|
-
// Test workflow simulation
|
|
169
|
-
const workflow = await harness.simulateWorkflow({
|
|
170
|
-
steps: [
|
|
171
|
-
{
|
|
172
|
-
id: 'step1',
|
|
173
|
-
type: 'task',
|
|
174
|
-
service: 'test-service',
|
|
175
|
-
operation: 'healthCheck'
|
|
176
|
-
},
|
|
177
|
-
{
|
|
178
|
-
id: 'step2',
|
|
179
|
-
type: 'task',
|
|
180
|
-
service: 'test-service',
|
|
181
|
-
operation: 'processData',
|
|
182
|
-
input: { test: 'data' }
|
|
183
|
-
}
|
|
184
|
-
]
|
|
185
|
-
});
|
|
186
|
-
console.log(` ✓ Workflow completed: ${workflow.completed}`);
|
|
187
|
-
|
|
188
|
-
// Check mock infrastructure
|
|
189
|
-
const messages = harness.getPublishedMessages();
|
|
190
|
-
console.log(` ✓ Messages published: ${messages.length}`);
|
|
191
|
-
|
|
192
|
-
const registration = harness.getServiceRegistration();
|
|
193
|
-
console.log(` ✓ Service registered: ${registration.name}`);
|
|
194
|
-
|
|
195
|
-
await harness.stop();
|
|
196
|
-
console.log(' ✓ Harness stopped\n');
|
|
197
|
-
|
|
198
|
-
// Test 2: Service Readiness Validator
|
|
199
|
-
console.log('2. Testing with ServiceReadinessValidator...\n');
|
|
200
|
-
|
|
201
|
-
// Start service for validation
|
|
202
|
-
const server = app.listen(4444);
|
|
203
|
-
|
|
204
|
-
const validator = new ServiceReadinessValidator();
|
|
205
|
-
const readiness = await validator.validateReadiness({
|
|
206
|
-
name: 'test-service',
|
|
207
|
-
url: 'http://localhost:4444',
|
|
208
|
-
openApiSpec,
|
|
209
|
-
healthEndpoint: '/health'
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
console.log(` ✓ Readiness score: ${readiness.score}/${readiness.maxScore}`);
|
|
213
|
-
console.log(` ✓ Service ready: ${readiness.ready}`);
|
|
214
|
-
console.log(` ✓ Recommendation: ${readiness.recommendation}`);
|
|
215
|
-
|
|
216
|
-
// Show check results
|
|
217
|
-
console.log('\n Check results:');
|
|
218
|
-
for (const [name, check] of Object.entries(readiness.checks)) {
|
|
219
|
-
const status = check.passed ? '✓' : '✗';
|
|
220
|
-
console.log(` ${status} ${name}: ${check.passed ? 'Passed' : 'Failed'}`);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
server.close();
|
|
224
|
-
console.log('\n ✓ Validator test completed\n');
|
|
225
|
-
|
|
226
|
-
// Test 3: Test Orchestrator (Three-tier testing)
|
|
227
|
-
console.log('3. Testing with TestOrchestrator (three-tier)...\n');
|
|
228
|
-
|
|
229
|
-
const orchestrator = new TestOrchestrator({
|
|
230
|
-
service: app,
|
|
231
|
-
serviceName: 'test-service',
|
|
232
|
-
openApiSpec
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
// Run only unit tests for speed
|
|
236
|
-
console.log(' Running unit tests with full mocks...');
|
|
237
|
-
const unitResults = await orchestrator.runUnitTests();
|
|
238
|
-
|
|
239
|
-
console.log(` ✓ Unit tests passed: ${unitResults.passed}`);
|
|
240
|
-
console.log(` ✓ Coverage: ${unitResults.coverage}%`);
|
|
241
|
-
console.log(` ✓ Tests run: ${unitResults.tests.length}`);
|
|
242
|
-
|
|
243
|
-
// Show individual test results
|
|
244
|
-
console.log('\n Test results:');
|
|
245
|
-
unitResults.tests.forEach(test => {
|
|
246
|
-
const status = test.passed ? '✓' : '✗';
|
|
247
|
-
console.log(` ${status} ${test.name}`);
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
console.log('\n=== All tests completed successfully! ===\n');
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
// Run the tests
|
|
254
|
-
runTests().catch(error => {
|
|
255
|
-
console.error('Test failed:', error);
|
|
256
|
-
process.exit(1);
|
|
257
|
-
});
|
|
@@ -1,353 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const CookbookTestRunner = require('../../src/CookbookTestRunner');
|
|
4
|
-
const fs = require('fs');
|
|
5
|
-
const path = require('path');
|
|
6
|
-
|
|
7
|
-
describe('CookbookTestRunner @unit', () => {
|
|
8
|
-
let runner;
|
|
9
|
-
const testServicePath = path.join(__dirname, '../fixtures/test-service');
|
|
10
|
-
|
|
11
|
-
beforeEach(() => {
|
|
12
|
-
runner = new CookbookTestRunner({
|
|
13
|
-
serviceName: 'test-service',
|
|
14
|
-
serviceUrl: 'http://localhost:3000',
|
|
15
|
-
servicePath: testServicePath,
|
|
16
|
-
mockInfrastructure: true
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
describe('constructor', () => {
|
|
21
|
-
test('should initialize with default options', () => {
|
|
22
|
-
const defaultRunner = new CookbookTestRunner({
|
|
23
|
-
serviceName: 'test'
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
expect(defaultRunner.serviceName).toBe('test');
|
|
27
|
-
expect(defaultRunner.serviceUrl).toBe('http://localhost:3000');
|
|
28
|
-
expect(defaultRunner.mockInfrastructure).toBe(true);
|
|
29
|
-
expect(defaultRunner.timeout).toBe(30000);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
test('should accept custom options', () => {
|
|
33
|
-
const customRunner = new CookbookTestRunner({
|
|
34
|
-
serviceName: 'custom',
|
|
35
|
-
serviceUrl: 'http://localhost:5000',
|
|
36
|
-
mockInfrastructure: false,
|
|
37
|
-
timeout: 60000
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
expect(customRunner.serviceName).toBe('custom');
|
|
41
|
-
expect(customRunner.serviceUrl).toBe('http://localhost:5000');
|
|
42
|
-
expect(customRunner.mockInfrastructure).toBe(false);
|
|
43
|
-
expect(customRunner.timeout).toBe(60000);
|
|
44
|
-
});
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
describe('validateCookbook()', () => {
|
|
48
|
-
test('should validate valid cookbook', () => {
|
|
49
|
-
const validCookbook = {
|
|
50
|
-
version: '1.0.0',
|
|
51
|
-
steps: [{
|
|
52
|
-
id: 'test-1',
|
|
53
|
-
service: 'test-service',
|
|
54
|
-
operation: 'test-op',
|
|
55
|
-
input: {}
|
|
56
|
-
}]
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
expect(() => runner.validateCookbook(validCookbook)).not.toThrow();
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
test('should reject cookbook without steps', () => {
|
|
63
|
-
const invalidCookbook = {
|
|
64
|
-
version: '1.0.0'
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
expect(() => runner.validateCookbook(invalidCookbook))
|
|
68
|
-
.toThrow('Cookbook must have steps array');
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
test('should reject cookbook with empty steps', () => {
|
|
72
|
-
const invalidCookbook = {
|
|
73
|
-
version: '1.0.0',
|
|
74
|
-
steps: []
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
expect(() => runner.validateCookbook(invalidCookbook))
|
|
78
|
-
.toThrow('Cookbook must have at least one step');
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
test('should reject step without service', () => {
|
|
82
|
-
const invalidCookbook = {
|
|
83
|
-
version: '1.0.0',
|
|
84
|
-
steps: [{
|
|
85
|
-
operation: 'test-op'
|
|
86
|
-
}]
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
expect(() => runner.validateCookbook(invalidCookbook))
|
|
90
|
-
.toThrow('Step must have service');
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
test('should reject step without operation', () => {
|
|
94
|
-
const invalidCookbook = {
|
|
95
|
-
version: '1.0.0',
|
|
96
|
-
steps: [{
|
|
97
|
-
service: 'test-service'
|
|
98
|
-
}]
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
expect(() => runner.validateCookbook(invalidCookbook))
|
|
102
|
-
.toThrow('Step must have operation');
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
describe('hasExpectClauses()', () => {
|
|
107
|
-
test('should detect cookbook with expect clauses', () => {
|
|
108
|
-
const cookbook = {
|
|
109
|
-
steps: [{
|
|
110
|
-
service: 'test',
|
|
111
|
-
operation: 'op',
|
|
112
|
-
expect: { status: 'success' }
|
|
113
|
-
}]
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
expect(runner.hasExpectClauses(cookbook)).toBe(true);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
test('should detect cookbook without expect clauses', () => {
|
|
120
|
-
const cookbook = {
|
|
121
|
-
steps: [{
|
|
122
|
-
service: 'test',
|
|
123
|
-
operation: 'op'
|
|
124
|
-
}]
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
expect(runner.hasExpectClauses(cookbook)).toBe(false);
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
describe('validateOutput()', () => {
|
|
132
|
-
test('should pass valid type check', () => {
|
|
133
|
-
const expected = {
|
|
134
|
-
message: { type: 'string' }
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
const actual = {
|
|
138
|
-
message: 'Hello'
|
|
139
|
-
};
|
|
140
|
-
|
|
141
|
-
const errors = runner.validateOutput(expected, actual);
|
|
142
|
-
|
|
143
|
-
expect(errors).toHaveLength(0);
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
test('should fail invalid type check', () => {
|
|
147
|
-
const expected = {
|
|
148
|
-
count: { type: 'number' }
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
const actual = {
|
|
152
|
-
count: 'not a number'
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
const errors = runner.validateOutput(expected, actual);
|
|
156
|
-
|
|
157
|
-
expect(errors.length).toBeGreaterThan(0);
|
|
158
|
-
expect(errors[0]).toContain('expected type number');
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
test('should pass contains check', () => {
|
|
162
|
-
const expected = {
|
|
163
|
-
message: { contains: 'Hello' }
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
const actual = {
|
|
167
|
-
message: 'Hello World'
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
const errors = runner.validateOutput(expected, actual);
|
|
171
|
-
|
|
172
|
-
expect(errors).toHaveLength(0);
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
test('should fail contains check', () => {
|
|
176
|
-
const expected = {
|
|
177
|
-
message: { contains: 'Goodbye' }
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
const actual = {
|
|
181
|
-
message: 'Hello World'
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
const errors = runner.validateOutput(expected, actual);
|
|
185
|
-
|
|
186
|
-
expect(errors.length).toBeGreaterThan(0);
|
|
187
|
-
expect(errors[0]).toContain('expected to contain');
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
test('should pass pattern check', () => {
|
|
191
|
-
const expected = {
|
|
192
|
-
timestamp: { pattern: '^\\d{4}-\\d{2}-\\d{2}T' }
|
|
193
|
-
};
|
|
194
|
-
|
|
195
|
-
const actual = {
|
|
196
|
-
timestamp: '2025-09-30T12:00:00Z'
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
const errors = runner.validateOutput(expected, actual);
|
|
200
|
-
|
|
201
|
-
expect(errors).toHaveLength(0);
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
test('should fail pattern check', () => {
|
|
205
|
-
const expected = {
|
|
206
|
-
code: { pattern: '^[A-Z]{3}$' }
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
const actual = {
|
|
210
|
-
code: 'invalid'
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
const errors = runner.validateOutput(expected, actual);
|
|
214
|
-
|
|
215
|
-
expect(errors.length).toBeGreaterThan(0);
|
|
216
|
-
expect(errors[0]).toContain('does not match pattern');
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
test('should pass equals check', () => {
|
|
220
|
-
const expected = {
|
|
221
|
-
status: { equals: 'active' }
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
const actual = {
|
|
225
|
-
status: 'active'
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
const errors = runner.validateOutput(expected, actual);
|
|
229
|
-
|
|
230
|
-
expect(errors).toHaveLength(0);
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
test('should fail equals check', () => {
|
|
234
|
-
const expected = {
|
|
235
|
-
status: { equals: 'active' }
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
const actual = {
|
|
239
|
-
status: 'inactive'
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
const errors = runner.validateOutput(expected, actual);
|
|
243
|
-
|
|
244
|
-
expect(errors.length).toBeGreaterThan(0);
|
|
245
|
-
expect(errors[0]).toContain('expected active');
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
test('should pass range check', () => {
|
|
249
|
-
const expected = {
|
|
250
|
-
count: { min: 0, max: 100 }
|
|
251
|
-
};
|
|
252
|
-
|
|
253
|
-
const actual = {
|
|
254
|
-
count: 50
|
|
255
|
-
};
|
|
256
|
-
|
|
257
|
-
const errors = runner.validateOutput(expected, actual);
|
|
258
|
-
|
|
259
|
-
expect(errors).toHaveLength(0);
|
|
260
|
-
});
|
|
261
|
-
|
|
262
|
-
test('should fail min check', () => {
|
|
263
|
-
const expected = {
|
|
264
|
-
count: { min: 10 }
|
|
265
|
-
};
|
|
266
|
-
|
|
267
|
-
const actual = {
|
|
268
|
-
count: 5
|
|
269
|
-
};
|
|
270
|
-
|
|
271
|
-
const errors = runner.validateOutput(expected, actual);
|
|
272
|
-
|
|
273
|
-
expect(errors.length).toBeGreaterThan(0);
|
|
274
|
-
expect(errors[0]).toContain('less than min');
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
test('should fail max check', () => {
|
|
278
|
-
const expected = {
|
|
279
|
-
count: { max: 100 }
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
const actual = {
|
|
283
|
-
count: 150
|
|
284
|
-
};
|
|
285
|
-
|
|
286
|
-
const errors = runner.validateOutput(expected, actual);
|
|
287
|
-
|
|
288
|
-
expect(errors.length).toBeGreaterThan(0);
|
|
289
|
-
expect(errors[0]).toContain('exceeds max');
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
test('should check field existence', () => {
|
|
293
|
-
const expected = {
|
|
294
|
-
optional: { exists: false },
|
|
295
|
-
required: { exists: true }
|
|
296
|
-
};
|
|
297
|
-
|
|
298
|
-
const actual = {
|
|
299
|
-
required: 'value'
|
|
300
|
-
};
|
|
301
|
-
|
|
302
|
-
const errors = runner.validateOutput(expected, actual);
|
|
303
|
-
|
|
304
|
-
expect(errors).toHaveLength(0);
|
|
305
|
-
});
|
|
306
|
-
|
|
307
|
-
test('should detect missing required field', () => {
|
|
308
|
-
const expected = {
|
|
309
|
-
required: { exists: true }
|
|
310
|
-
};
|
|
311
|
-
|
|
312
|
-
const actual = {};
|
|
313
|
-
|
|
314
|
-
const errors = runner.validateOutput(expected, actual);
|
|
315
|
-
|
|
316
|
-
expect(errors.length).toBeGreaterThan(0);
|
|
317
|
-
expect(errors[0]).toContain('expected to exist');
|
|
318
|
-
});
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
describe('getResults()', () => {
|
|
322
|
-
test('should return initialized results', () => {
|
|
323
|
-
const results = runner.getResults();
|
|
324
|
-
|
|
325
|
-
expect(results).toEqual({
|
|
326
|
-
total: 0,
|
|
327
|
-
passed: 0,
|
|
328
|
-
failed: 0,
|
|
329
|
-
duration: 0,
|
|
330
|
-
steps: []
|
|
331
|
-
});
|
|
332
|
-
});
|
|
333
|
-
});
|
|
334
|
-
|
|
335
|
-
describe('resetResults()', () => {
|
|
336
|
-
test('should reset results', () => {
|
|
337
|
-
// Simulate some test runs
|
|
338
|
-
runner.results.total = 5;
|
|
339
|
-
runner.results.passed = 3;
|
|
340
|
-
runner.results.failed = 2;
|
|
341
|
-
|
|
342
|
-
runner.resetResults();
|
|
343
|
-
|
|
344
|
-
expect(runner.results).toEqual({
|
|
345
|
-
total: 0,
|
|
346
|
-
passed: 0,
|
|
347
|
-
failed: 0,
|
|
348
|
-
duration: 0,
|
|
349
|
-
steps: []
|
|
350
|
-
});
|
|
351
|
-
});
|
|
352
|
-
});
|
|
353
|
-
});
|