@avimate/msfs-jest-utils 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +22 -0
- package/README.md +170 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +24 -0
- package/dist/mocks/CoherentMock.d.ts +74 -0
- package/dist/mocks/CoherentMock.js +148 -0
- package/dist/mocks/GarminSDKAdapter.d.ts +79 -0
- package/dist/mocks/GarminSDKAdapter.js +127 -0
- package/dist/mocks/MSFSGlobals.d.ts +6 -0
- package/dist/mocks/MSFSGlobals.js +514 -0
- package/dist/mocks/SDKAdapter.d.ts +126 -0
- package/dist/mocks/SDKAdapter.js +696 -0
- package/dist/mocks/SDKClasses.d.ts +32 -0
- package/dist/mocks/SDKClasses.js +118 -0
- package/dist/mocks/SimVarMock.d.ts +97 -0
- package/dist/mocks/SimVarMock.js +215 -0
- package/dist/mocks/index.d.ts +9 -0
- package/dist/mocks/index.js +25 -0
- package/dist/setupTests.d.ts +13 -0
- package/dist/setupTests.js +109 -0
- package/dist/test-utils/ComponentTestHelper.d.ts +73 -0
- package/dist/test-utils/ComponentTestHelper.js +558 -0
- package/dist/test-utils/ObservableTestHelper.d.ts +25 -0
- package/dist/test-utils/ObservableTestHelper.js +75 -0
- package/dist/test-utils/TestEnvironment.d.ts +76 -0
- package/dist/test-utils/TestEnvironment.js +227 -0
- package/dist/test-utils/index.d.ts +6 -0
- package/dist/test-utils/index.js +22 -0
- package/package.json +64 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test environment setup for MSFS instrument testing.
|
|
3
|
+
*
|
|
4
|
+
* Sets up jsdom, mocks SimVar and Coherent APIs, and provides utilities for testing.
|
|
5
|
+
*/
|
|
6
|
+
import { Subject } from '@microsoft/msfs-sdk';
|
|
7
|
+
export declare class TestEnvironment {
|
|
8
|
+
private dom;
|
|
9
|
+
private originalSimVar;
|
|
10
|
+
private originalCoherent;
|
|
11
|
+
private originalDocument;
|
|
12
|
+
private originalWindow;
|
|
13
|
+
/**
|
|
14
|
+
* Setup test environment with jsdom
|
|
15
|
+
*/
|
|
16
|
+
setup(): void;
|
|
17
|
+
/**
|
|
18
|
+
* Teardown test environment
|
|
19
|
+
*/
|
|
20
|
+
teardown(): void;
|
|
21
|
+
/**
|
|
22
|
+
* Reset environment (clear mocks but keep setup)
|
|
23
|
+
*/
|
|
24
|
+
reset(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Get the jsdom document
|
|
27
|
+
*/
|
|
28
|
+
getDocument(): Document;
|
|
29
|
+
/**
|
|
30
|
+
* Get the jsdom window
|
|
31
|
+
*/
|
|
32
|
+
getWindow(): any;
|
|
33
|
+
/**
|
|
34
|
+
* Set a SimVar value
|
|
35
|
+
*/
|
|
36
|
+
setSimVar(name: string, unit: string, value: any, dataSource?: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* Get a SimVar value
|
|
39
|
+
*/
|
|
40
|
+
getSimVar(name: string, unit: string, dataSource?: string): any;
|
|
41
|
+
/**
|
|
42
|
+
* Get SimVar access log
|
|
43
|
+
*/
|
|
44
|
+
getSimVarAccessLog(): import("../mocks/SimVarMock").SimVarAccessLog[];
|
|
45
|
+
/**
|
|
46
|
+
* Clear SimVar access log
|
|
47
|
+
*/
|
|
48
|
+
clearSimVarAccessLog(): void;
|
|
49
|
+
/**
|
|
50
|
+
* Get Coherent call history
|
|
51
|
+
*/
|
|
52
|
+
getCoherentCallHistory(): import("../mocks/CoherentMock").CoherentCall[];
|
|
53
|
+
/**
|
|
54
|
+
* Clear Coherent call history
|
|
55
|
+
*/
|
|
56
|
+
clearCoherentCallHistory(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Create a Subject that reads from SimVar and updates automatically
|
|
59
|
+
* Useful for testing reactive components
|
|
60
|
+
* Note: In real tests, you would typically poll SimVar in Update() method
|
|
61
|
+
* This is a helper for setting up test scenarios
|
|
62
|
+
*/
|
|
63
|
+
createSimVarSubject<T>(name: string, unit: string, dataSource?: string): Subject<T>;
|
|
64
|
+
/**
|
|
65
|
+
* Setup SimVar mock in global scope
|
|
66
|
+
*/
|
|
67
|
+
private setupSimVarMock;
|
|
68
|
+
/**
|
|
69
|
+
* Setup Coherent mock in global scope
|
|
70
|
+
*/
|
|
71
|
+
private setupCoherentMock;
|
|
72
|
+
/**
|
|
73
|
+
* Setup simvar global (used by SDK internally)
|
|
74
|
+
*/
|
|
75
|
+
private setupSimvarGlobal;
|
|
76
|
+
}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Test environment setup for MSFS instrument testing.
|
|
4
|
+
*
|
|
5
|
+
* Sets up jsdom, mocks SimVar and Coherent APIs, and provides utilities for testing.
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.TestEnvironment = void 0;
|
|
9
|
+
const jsdom_1 = require("jsdom");
|
|
10
|
+
const SimVarMock_1 = require("../mocks/SimVarMock");
|
|
11
|
+
const CoherentMock_1 = require("../mocks/CoherentMock");
|
|
12
|
+
const msfs_sdk_1 = require("@microsoft/msfs-sdk");
|
|
13
|
+
class TestEnvironment {
|
|
14
|
+
constructor() {
|
|
15
|
+
this.dom = null;
|
|
16
|
+
this.originalSimVar = null;
|
|
17
|
+
this.originalCoherent = null;
|
|
18
|
+
this.originalDocument = null;
|
|
19
|
+
this.originalWindow = null;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Setup test environment with jsdom
|
|
23
|
+
*/
|
|
24
|
+
setup() {
|
|
25
|
+
// Create jsdom environment
|
|
26
|
+
this.dom = new jsdom_1.JSDOM('<!DOCTYPE html><html><body></body></html>', {
|
|
27
|
+
url: 'http://localhost',
|
|
28
|
+
pretendToBeVisual: true,
|
|
29
|
+
resources: 'usable',
|
|
30
|
+
});
|
|
31
|
+
// Set global document and window
|
|
32
|
+
const globalObj = globalThis;
|
|
33
|
+
this.originalDocument = globalObj.document;
|
|
34
|
+
this.originalWindow = globalObj.window;
|
|
35
|
+
globalObj.document = this.dom.window.document;
|
|
36
|
+
globalObj.window = this.dom.window;
|
|
37
|
+
// Copy window properties to global
|
|
38
|
+
Object.defineProperty(globalObj, 'window', {
|
|
39
|
+
value: this.dom.window,
|
|
40
|
+
writable: true,
|
|
41
|
+
});
|
|
42
|
+
// Setup SimVar mock
|
|
43
|
+
this.setupSimVarMock();
|
|
44
|
+
// Setup Coherent mock
|
|
45
|
+
this.setupCoherentMock();
|
|
46
|
+
// Setup simvar global (used by SDK)
|
|
47
|
+
this.setupSimvarGlobal();
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Teardown test environment
|
|
51
|
+
*/
|
|
52
|
+
teardown() {
|
|
53
|
+
// Reset mocks
|
|
54
|
+
SimVarMock_1.simVarMock.reset();
|
|
55
|
+
CoherentMock_1.coherentMock.reset();
|
|
56
|
+
// Restore original globals
|
|
57
|
+
const globalObj = globalThis;
|
|
58
|
+
if (this.originalDocument) {
|
|
59
|
+
globalObj.document = this.originalDocument;
|
|
60
|
+
}
|
|
61
|
+
if (this.originalWindow) {
|
|
62
|
+
globalObj.window = this.originalWindow;
|
|
63
|
+
}
|
|
64
|
+
// Clean up
|
|
65
|
+
this.dom = null;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Reset environment (clear mocks but keep setup)
|
|
69
|
+
*/
|
|
70
|
+
reset() {
|
|
71
|
+
SimVarMock_1.simVarMock.reset();
|
|
72
|
+
CoherentMock_1.coherentMock.reset();
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Get the jsdom document
|
|
76
|
+
*/
|
|
77
|
+
getDocument() {
|
|
78
|
+
if (!this.dom) {
|
|
79
|
+
throw new Error('TestEnvironment not setup. Call setup() first.');
|
|
80
|
+
}
|
|
81
|
+
return this.dom.window.document;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Get the jsdom window
|
|
85
|
+
*/
|
|
86
|
+
getWindow() {
|
|
87
|
+
if (!this.dom) {
|
|
88
|
+
throw new Error('TestEnvironment not setup. Call setup() first.');
|
|
89
|
+
}
|
|
90
|
+
return this.dom.window;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Set a SimVar value
|
|
94
|
+
*/
|
|
95
|
+
setSimVar(name, unit, value, dataSource = '') {
|
|
96
|
+
SimVarMock_1.simVarMock.setSimVarValue(name, unit, value, dataSource);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get a SimVar value
|
|
100
|
+
*/
|
|
101
|
+
getSimVar(name, unit, dataSource = '') {
|
|
102
|
+
return SimVarMock_1.simVarMock.getSimVarValue(name, unit, dataSource);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get SimVar access log
|
|
106
|
+
*/
|
|
107
|
+
getSimVarAccessLog() {
|
|
108
|
+
return SimVarMock_1.simVarMock.getAccessLog();
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Clear SimVar access log
|
|
112
|
+
*/
|
|
113
|
+
clearSimVarAccessLog() {
|
|
114
|
+
SimVarMock_1.simVarMock.clearAccessLog();
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get Coherent call history
|
|
118
|
+
*/
|
|
119
|
+
getCoherentCallHistory() {
|
|
120
|
+
return CoherentMock_1.coherentMock.getCallHistory();
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Clear Coherent call history
|
|
124
|
+
*/
|
|
125
|
+
clearCoherentCallHistory() {
|
|
126
|
+
CoherentMock_1.coherentMock.clearHistory();
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Create a Subject that reads from SimVar and updates automatically
|
|
130
|
+
* Useful for testing reactive components
|
|
131
|
+
* Note: In real tests, you would typically poll SimVar in Update() method
|
|
132
|
+
* This is a helper for setting up test scenarios
|
|
133
|
+
*/
|
|
134
|
+
createSimVarSubject(name, unit, dataSource = '') {
|
|
135
|
+
const value = this.getSimVar(name, unit);
|
|
136
|
+
return msfs_sdk_1.Subject.create(value);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Setup SimVar mock in global scope
|
|
140
|
+
*/
|
|
141
|
+
setupSimVarMock() {
|
|
142
|
+
const globalObj = globalThis;
|
|
143
|
+
// Store original if exists
|
|
144
|
+
if (typeof globalObj.SimVar !== 'undefined') {
|
|
145
|
+
this.originalSimVar = globalObj.SimVar;
|
|
146
|
+
}
|
|
147
|
+
// Create mock SimVar object
|
|
148
|
+
globalObj.SimVar = {
|
|
149
|
+
GetSimVarValue: (name, unit, dataSource = '') => {
|
|
150
|
+
return SimVarMock_1.simVarMock.getSimVarValue(name, unit, dataSource);
|
|
151
|
+
},
|
|
152
|
+
SetSimVarValue: (name, unit, value, dataSource = '') => {
|
|
153
|
+
return Promise.resolve(SimVarMock_1.simVarMock.setSimVarValue(name, unit, value, dataSource));
|
|
154
|
+
},
|
|
155
|
+
GetRegisteredId: (name, unit, dataSource = '') => {
|
|
156
|
+
return SimVarMock_1.simVarMock.getRegisteredId(name, unit, dataSource);
|
|
157
|
+
},
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Setup Coherent mock in global scope
|
|
162
|
+
*/
|
|
163
|
+
setupCoherentMock() {
|
|
164
|
+
const globalObj = globalThis;
|
|
165
|
+
// Store original if exists
|
|
166
|
+
if (typeof globalObj.Coherent !== 'undefined') {
|
|
167
|
+
this.originalCoherent = globalObj.Coherent;
|
|
168
|
+
}
|
|
169
|
+
// Connect Coherent handlers to SimVar mock
|
|
170
|
+
CoherentMock_1.coherentMock.registerHandler('setValueReg_Number', (id, value) => {
|
|
171
|
+
SimVarMock_1.simVarMock.setValueReg(id, value);
|
|
172
|
+
return Promise.resolve();
|
|
173
|
+
});
|
|
174
|
+
CoherentMock_1.coherentMock.registerHandler('setValueReg_String', (id, value) => {
|
|
175
|
+
SimVarMock_1.simVarMock.setValueReg(id, value);
|
|
176
|
+
return Promise.resolve();
|
|
177
|
+
});
|
|
178
|
+
CoherentMock_1.coherentMock.registerHandler('setValueReg_Bool', (id, value) => {
|
|
179
|
+
SimVarMock_1.simVarMock.setValueReg(id, value ? 1 : 0);
|
|
180
|
+
return Promise.resolve();
|
|
181
|
+
});
|
|
182
|
+
// Create mock Coherent object
|
|
183
|
+
globalObj.Coherent = {
|
|
184
|
+
call: (method, ...args) => {
|
|
185
|
+
return CoherentMock_1.coherentMock.call(method, ...args);
|
|
186
|
+
},
|
|
187
|
+
on: (eventName, callback) => {
|
|
188
|
+
CoherentMock_1.coherentMock.on(eventName, callback);
|
|
189
|
+
},
|
|
190
|
+
off: (eventName, callback) => {
|
|
191
|
+
CoherentMock_1.coherentMock.off(eventName, callback);
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Setup simvar global (used by SDK internally)
|
|
197
|
+
*/
|
|
198
|
+
setupSimvarGlobal() {
|
|
199
|
+
const globalObj = globalThis;
|
|
200
|
+
// The SDK uses a global 'simvar' object for optimized access
|
|
201
|
+
globalObj.simvar = {
|
|
202
|
+
getValueReg: (id) => {
|
|
203
|
+
return SimVarMock_1.simVarMock.getValueReg(id);
|
|
204
|
+
},
|
|
205
|
+
getValueReg_String: (id) => {
|
|
206
|
+
return SimVarMock_1.simVarMock.getValueReg(id);
|
|
207
|
+
},
|
|
208
|
+
getValue_LatLongAlt: (name, dataSource) => {
|
|
209
|
+
// Mock implementation - return default structure
|
|
210
|
+
return { lat: 0, long: 0, alt: 0 };
|
|
211
|
+
},
|
|
212
|
+
getValue_LatLongAltPBH: (name, dataSource) => {
|
|
213
|
+
return { lat: 0, long: 0, alt: 0, pitch: 0, bank: 0, heading: 0 };
|
|
214
|
+
},
|
|
215
|
+
getValue_PBH: (name, dataSource) => {
|
|
216
|
+
return { pitch: 0, bank: 0, heading: 0 };
|
|
217
|
+
},
|
|
218
|
+
getValue_PID_STRUCT: (name, dataSource) => {
|
|
219
|
+
return { p: 0, i: 0, d: 0 };
|
|
220
|
+
},
|
|
221
|
+
getValue_XYZ: (name, dataSource) => {
|
|
222
|
+
return { x: 0, y: 0, z: 0 };
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
exports.TestEnvironment = TestEnvironment;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* MSFS Unit Test Framework - Test Utilities
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
__exportStar(require("./TestEnvironment"), exports);
|
|
21
|
+
__exportStar(require("./ComponentTestHelper"), exports);
|
|
22
|
+
__exportStar(require("./ObservableTestHelper"), exports);
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@avimate/msfs-jest-utils",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Unit testing framework for MSFS instruments with DOM support via jsdom",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./dist/index.js",
|
|
9
|
+
"./setupTests": "./dist/setupTests.js",
|
|
10
|
+
"./mocks/SDKAdapter": "./dist/mocks/SDKAdapter.js",
|
|
11
|
+
"./mocks/GarminSDKAdapter": "./dist/mocks/GarminSDKAdapter.js",
|
|
12
|
+
"./mocks/MSFSGlobals": "./dist/mocks/MSFSGlobals.js",
|
|
13
|
+
"./mocks/SimVarMock": "./dist/mocks/SimVarMock.js",
|
|
14
|
+
"./mocks/CoherentMock": "./dist/mocks/CoherentMock.js",
|
|
15
|
+
"./test-utils/ComponentTestHelper": "./dist/test-utils/ComponentTestHelper.js",
|
|
16
|
+
"./test-utils/TestEnvironment": "./dist/test-utils/TestEnvironment.js",
|
|
17
|
+
"./test-utils/ObservableTestHelper": "./dist/test-utils/ObservableTestHelper.js"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"test": "jest",
|
|
22
|
+
"test:watch": "jest --watch"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"msfs",
|
|
26
|
+
"testing",
|
|
27
|
+
"unit-test",
|
|
28
|
+
"jsdom",
|
|
29
|
+
"simvar",
|
|
30
|
+
"coherent"
|
|
31
|
+
],
|
|
32
|
+
"author": "",
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"repository": {
|
|
38
|
+
"type": "git",
|
|
39
|
+
"url": "git+https://github.com/ivan-slepchenko/msfs-unit-test-framework.git"
|
|
40
|
+
},
|
|
41
|
+
"bugs": {
|
|
42
|
+
"url": "https://github.com/ivan-slepchenko/msfs-unit-test-framework/issues"
|
|
43
|
+
},
|
|
44
|
+
"homepage": "https://github.com/ivan-slepchenko/msfs-unit-test-framework#readme",
|
|
45
|
+
"files": [
|
|
46
|
+
"dist",
|
|
47
|
+
"README.md",
|
|
48
|
+
"LICENSE"
|
|
49
|
+
],
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@microsoft/msfs-garminsdk": "^2.2.3",
|
|
52
|
+
"@microsoft/msfs-sdk": "^2.2.3",
|
|
53
|
+
"@microsoft/msfs-types": "^1.14.6"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@types/jest": "^29.5.0",
|
|
57
|
+
"@types/node": "^18.11.18",
|
|
58
|
+
"jest": "^29.5.0",
|
|
59
|
+
"jest-environment-jsdom": "^29.5.0",
|
|
60
|
+
"jsdom": "^23.0.0",
|
|
61
|
+
"ts-jest": "^29.1.0",
|
|
62
|
+
"typescript": "^5.8.3"
|
|
63
|
+
}
|
|
64
|
+
}
|