@lynx-js/testing-environment 0.1.5 → 0.1.7

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/CHANGELOG.md ADDED
@@ -0,0 +1,72 @@
1
+ # @lynx-js/testing-environment
2
+
3
+ ## 0.1.7
4
+
5
+ ### Patch Changes
6
+
7
+ - Support `lynx.createSelectorQuery().select()` and `setNativeProps` API ([#1570](https://github.com/lynx-family/lynx-stack/pull/1570))
8
+
9
+ ## 0.1.6
10
+
11
+ ### Patch Changes
12
+
13
+ - Fix that `lynxTestingEnv.jsdom` cannot be initialized correctly when `global.jsdom` is not defined. ([#1422](https://github.com/lynx-family/lynx-stack/pull/1422))
14
+
15
+ ## 0.1.5
16
+
17
+ ### Patch Changes
18
+
19
+ - Fix `GlobalEventEmitter` type definition, the `emit(eventName: string, data: unknown)` function should recevie an array typed `data` and pass as param list of listeners. ([#1479](https://github.com/lynx-family/lynx-stack/pull/1479))
20
+
21
+ ## 0.1.4
22
+
23
+ ### Patch Changes
24
+
25
+ - Fix the thread switching bug in `lynx.getCoreContext` and `lynx.getJSContext`. ([#1244](https://github.com/lynx-family/lynx-stack/pull/1244))
26
+
27
+ ## 0.1.3
28
+
29
+ ### Patch Changes
30
+
31
+ - Support alog of component rendering on production for better error reporting. Enable it by using `REACT_ALOG=true rspeedy dev/build` or defining `__ALOG__` to `true` in `lynx.config.js`: ([#1164](https://github.com/lynx-family/lynx-stack/pull/1164))
32
+
33
+ ```js
34
+ export default defineConfig({
35
+ // ...
36
+ source: {
37
+ define: {
38
+ __ALOG__: true,
39
+ },
40
+ },
41
+ });
42
+ ```
43
+
44
+ - Supports `console.alog` and use different `console` object in main thread and background thread. ([#1164](https://github.com/lynx-family/lynx-stack/pull/1164))
45
+
46
+ ## 0.1.2
47
+
48
+ ### Patch Changes
49
+
50
+ - Fix the infinite loop in the `__RemoveElement` element PAPI. ([#1263](https://github.com/lynx-family/lynx-stack/pull/1263))
51
+
52
+ ## 0.1.1
53
+
54
+ ### Patch Changes
55
+
56
+ - Fix `getJSContext` or `getCoreContext` is not a function. ([#1122](https://github.com/lynx-family/lynx-stack/pull/1122))
57
+
58
+ ## 0.1.0
59
+
60
+ ### Minor Changes
61
+
62
+ - Switch to ESM package format by setting `"type": "module"`. ([#703](https://github.com/lynx-family/lynx-stack/pull/703))
63
+
64
+ ### Patch Changes
65
+
66
+ - rename @lynx-js/test-environment to @lynx-js/testing-environment ([#704](https://github.com/lynx-family/lynx-stack/pull/704))
67
+
68
+ ## 0.0.1
69
+
70
+ ### Patch Changes
71
+
72
+ - Add testing library for ReactLynx ([#74](https://github.com/lynx-family/lynx-stack/pull/74))
package/README.md CHANGED
@@ -8,8 +8,9 @@ The Element PAPI implementation is based on jsdom, for example `__CreateElement`
8
8
 
9
9
  ```js
10
10
  import { LynxTestingEnv } from '@lynx-js/testing-environment';
11
+ import { JSDOM } from 'jsdom';
11
12
 
12
- const lynxTestingEnv = new LynxTestingEnv();
13
+ const lynxTestingEnv = new LynxTestingEnv(new JSDOM());
13
14
  ```
14
15
 
15
16
  To use `@lynx-js/testing-environment`, you will primarily use the `LynxTestingEnv` constructor, which is a named export of the package. You will get back a `LynxTestingEnv` instance, which has a number of methods of useful properties, notably `switchToMainThread` and `switchToBackgroundThread`, which allow you to switch between the main thread and background thread.
@@ -34,8 +34,7 @@ const env = {
34
34
  async setup (global) {
35
35
  const fakeGlobal = {};
36
36
  await environments_namespaceObject.builtinEnvironments.jsdom.setup(fakeGlobal, {});
37
- global.jsdom = fakeGlobal.jsdom;
38
- const lynxTestingEnv = new testing_environment_namespaceObject.LynxTestingEnv();
37
+ const lynxTestingEnv = new testing_environment_namespaceObject.LynxTestingEnv(fakeGlobal.jsdom);
39
38
  global.lynxTestingEnv = lynxTestingEnv;
40
39
  return {
41
40
  teardown (global) {
@@ -6,8 +6,7 @@ const env = {
6
6
  async setup (global) {
7
7
  const fakeGlobal = {};
8
8
  await builtinEnvironments.jsdom.setup(fakeGlobal, {});
9
- global.jsdom = fakeGlobal.jsdom;
10
- const lynxTestingEnv = new LynxTestingEnv();
9
+ const lynxTestingEnv = new LynxTestingEnv(fakeGlobal.jsdom);
11
10
  global.lynxTestingEnv = lynxTestingEnv;
12
11
  return {
13
12
  teardown (global) {
package/dist/index.cjs CHANGED
@@ -53,10 +53,10 @@ function _define_property(obj, key, value) {
53
53
  return obj;
54
54
  }
55
55
  function __injectElementApi(target) {
56
- const elementTree = (0, ElementPAPI_cjs_namespaceObject.initElementTree)();
57
- target.elementTree = elementTree;
56
+ const elementTree1 = (0, ElementPAPI_cjs_namespaceObject.initElementTree)();
57
+ target.elementTree = elementTree1;
58
58
  if (void 0 === target) target = globalThis;
59
- for (const k of Object.getOwnPropertyNames(elementTree.constructor.prototype))if (k.startsWith('__')) target[k] = elementTree[k].bind(elementTree);
59
+ for (const k of Object.getOwnPropertyNames(elementTree1.constructor.prototype))if (k.startsWith('__')) target[k] = elementTree1[k].bind(elementTree1);
60
60
  target.$kTemplateAssembler = {};
61
61
  target.registerDataProcessor = ()=>{
62
62
  console.error('registerDataProcessor is not implemented');
@@ -202,8 +202,14 @@ class NodesRef {
202
202
  fields() {
203
203
  throw new Error('not implemented');
204
204
  }
205
- setNativeProps() {
206
- throw new Error('not implemented');
205
+ setNativeProps(props) {
206
+ return {
207
+ exec: ()=>{
208
+ const element = elementTree.uniqueId2Element.get(Number(this._nodeSelectToken.identifier));
209
+ if (!element) throw new Error(`[NodesRef.setNativeProps] Element not found for identifier=${this._nodeSelectToken.identifier}`);
210
+ if (element) for(const key in props)element.setAttributeNS(null, key, props[key]);
211
+ }
212
+ };
207
213
  }
208
214
  constructor(selectorQuery, nodeSelectToken){
209
215
  _define_property(this, "_nodeSelectToken", void 0);
@@ -242,6 +248,14 @@ function injectBackgroundThreadGlobals(target, polyfills) {
242
248
  type: 2,
243
249
  identifier: uniqueId.toString()
244
250
  });
251
+ },
252
+ select: function(selector) {
253
+ const el = lynxTestingEnv.jsdom.window.document.querySelector(selector);
254
+ if (!el) throw new Error(`[createSelectorQuery.select] No element matches selector: ${selector}`);
255
+ return new NodesRef({}, {
256
+ type: 0,
257
+ identifier: el.$$uiSign.toString()
258
+ });
245
259
  }
246
260
  }),
247
261
  getCoreContext: ()=>CoreContext,
@@ -310,11 +324,13 @@ class LynxTestingEnv {
310
324
  this.switchToBackgroundThread();
311
325
  null == (_globalThis_onResetLynxTestingEnv = (_globalThis = globalThis).onResetLynxTestingEnv) || _globalThis_onResetLynxTestingEnv.call(_globalThis);
312
326
  }
313
- constructor(){
327
+ constructor(jsdom){
314
328
  _define_property(this, "originals", new Map());
315
329
  _define_property(this, "backgroundThread", void 0);
316
330
  _define_property(this, "mainThread", void 0);
317
- _define_property(this, "jsdom", global.jsdom);
331
+ _define_property(this, "jsdom", void 0);
332
+ this.jsdom = jsdom ?? global.jsdom;
333
+ if (!this.jsdom) throw new Error("LynxTestingEnv requires a JSDOM instance. Pass one to the constructor, or ensure your test runner sets global.jsdom (e.g., via a setup file).");
318
334
  this.backgroundThread = (0, GlobalThis_cjs_namespaceObject.createGlobalThis)();
319
335
  this.mainThread = (0, GlobalThis_cjs_namespaceObject.createGlobalThis)();
320
336
  const globalPolyfills = {
package/dist/index.d.ts CHANGED
@@ -56,7 +56,7 @@ declare global {
56
56
  * ```ts
57
57
  * import { LynxTestingEnv } from '@lynx-js/testing-environment';
58
58
  *
59
- * const lynxTestingEnv = new LynxTestingEnv();
59
+ * const lynxTestingEnv = new LynxTestingEnv(new JSDOM());
60
60
  *
61
61
  * lynxTestingEnv.switchToMainThread();
62
62
  * // use the main thread Element PAPI
@@ -78,7 +78,7 @@ export declare class LynxTestingEnv {
78
78
  * ```ts
79
79
  * import { LynxTestingEnv } from '@lynx-js/testing-environment';
80
80
  *
81
- * const lynxTestingEnv = new LynxTestingEnv();
81
+ * const lynxTestingEnv = new LynxTestingEnv(new JSDOM());
82
82
  *
83
83
  * lynxTestingEnv.switchToBackgroundThread();
84
84
  * // use the background thread global object
@@ -94,7 +94,7 @@ export declare class LynxTestingEnv {
94
94
  * ```ts
95
95
  * import { LynxTestingEnv } from '@lynx-js/testing-environment';
96
96
  *
97
- * const lynxTestingEnv = new LynxTestingEnv();
97
+ * const lynxTestingEnv = new LynxTestingEnv(new JSDOM());
98
98
  *
99
99
  * lynxTestingEnv.switchToMainThread();
100
100
  * // use the main thread global object
@@ -105,7 +105,7 @@ export declare class LynxTestingEnv {
105
105
  */
106
106
  mainThread: LynxGlobalThis & ElementTreeGlobals;
107
107
  jsdom: JSDOM;
108
- constructor();
108
+ constructor(jsdom?: JSDOM);
109
109
  injectGlobals(): void;
110
110
  switchToBackgroundThread(): void;
111
111
  switchToMainThread(): void;
package/dist/index.js CHANGED
@@ -14,10 +14,10 @@ function _define_property(obj, key, value) {
14
14
  return obj;
15
15
  }
16
16
  function __injectElementApi(target) {
17
- const elementTree = initElementTree();
18
- target.elementTree = elementTree;
17
+ const elementTree1 = initElementTree();
18
+ target.elementTree = elementTree1;
19
19
  if (void 0 === target) target = globalThis;
20
- for (const k of Object.getOwnPropertyNames(elementTree.constructor.prototype))if (k.startsWith('__')) target[k] = elementTree[k].bind(elementTree);
20
+ for (const k of Object.getOwnPropertyNames(elementTree1.constructor.prototype))if (k.startsWith('__')) target[k] = elementTree1[k].bind(elementTree1);
21
21
  target.$kTemplateAssembler = {};
22
22
  target.registerDataProcessor = ()=>{
23
23
  console.error('registerDataProcessor is not implemented');
@@ -163,8 +163,14 @@ class NodesRef {
163
163
  fields() {
164
164
  throw new Error('not implemented');
165
165
  }
166
- setNativeProps() {
167
- throw new Error('not implemented');
166
+ setNativeProps(props) {
167
+ return {
168
+ exec: ()=>{
169
+ const element = elementTree.uniqueId2Element.get(Number(this._nodeSelectToken.identifier));
170
+ if (!element) throw new Error(`[NodesRef.setNativeProps] Element not found for identifier=${this._nodeSelectToken.identifier}`);
171
+ if (element) for(const key in props)element.setAttributeNS(null, key, props[key]);
172
+ }
173
+ };
168
174
  }
169
175
  constructor(selectorQuery, nodeSelectToken){
170
176
  _define_property(this, "_nodeSelectToken", void 0);
@@ -203,6 +209,14 @@ function injectBackgroundThreadGlobals(target, polyfills) {
203
209
  type: 2,
204
210
  identifier: uniqueId.toString()
205
211
  });
212
+ },
213
+ select: function(selector) {
214
+ const el = lynxTestingEnv.jsdom.window.document.querySelector(selector);
215
+ if (!el) throw new Error(`[createSelectorQuery.select] No element matches selector: ${selector}`);
216
+ return new NodesRef({}, {
217
+ type: 0,
218
+ identifier: el.$$uiSign.toString()
219
+ });
206
220
  }
207
221
  }),
208
222
  getCoreContext: ()=>CoreContext,
@@ -271,11 +285,13 @@ class LynxTestingEnv {
271
285
  this.switchToBackgroundThread();
272
286
  null == (_globalThis_onResetLynxTestingEnv = (_globalThis = globalThis).onResetLynxTestingEnv) || _globalThis_onResetLynxTestingEnv.call(_globalThis);
273
287
  }
274
- constructor(){
288
+ constructor(jsdom){
275
289
  _define_property(this, "originals", new Map());
276
290
  _define_property(this, "backgroundThread", void 0);
277
291
  _define_property(this, "mainThread", void 0);
278
- _define_property(this, "jsdom", global.jsdom);
292
+ _define_property(this, "jsdom", void 0);
293
+ this.jsdom = jsdom ?? global.jsdom;
294
+ if (!this.jsdom) throw new Error("LynxTestingEnv requires a JSDOM instance. Pass one to the constructor, or ensure your test runner sets global.jsdom (e.g., via a setup file).");
279
295
  this.backgroundThread = createGlobalThis();
280
296
  this.mainThread = createGlobalThis();
281
297
  const globalPolyfills = {
@@ -38,11 +38,10 @@ function _define_property(obj, key, value) {
38
38
  }
39
39
  const initElementTree = ()=>{
40
40
  let uiSignNext = 0;
41
- const uniqueId2Element = new Map();
42
41
  return new class {
43
42
  countElement(element, parentComponentUniqueId) {
44
43
  element.$$uiSign = uiSignNext++;
45
- uniqueId2Element.set(element.$$uiSign, element);
44
+ this.uniqueId2Element.set(element.$$uiSign, element);
46
45
  element.parentComponentUniqueId = parentComponentUniqueId;
47
46
  }
48
47
  __CreatePage(_tag, parentComponentUniqueId) {
@@ -251,9 +250,10 @@ const initElementTree = ()=>{
251
250
  return this.toTree();
252
251
  }
253
252
  __GetElementByUniqueId(uniqueId) {
254
- return uniqueId2Element.get(uniqueId);
253
+ return this.uniqueId2Element.get(uniqueId);
255
254
  }
256
255
  constructor(){
256
+ _define_property(this, "uniqueId2Element", new Map());
257
257
  _define_property(this, "root", void 0);
258
258
  }
259
259
  }();
@@ -45,6 +45,7 @@ export interface LynxElement extends HTMLElement {
45
45
  * @public
46
46
  */
47
47
  export declare const initElementTree: () => {
48
+ uniqueId2Element: Map<number, LynxElement>;
48
49
  root: LynxElement | undefined;
49
50
  countElement(element: LynxElement, parentComponentUniqueId: number): void;
50
51
  __CreatePage(_tag: string, parentComponentUniqueId: number): LynxElement;
@@ -10,11 +10,10 @@ function _define_property(obj, key, value) {
10
10
  }
11
11
  const initElementTree = ()=>{
12
12
  let uiSignNext = 0;
13
- const uniqueId2Element = new Map();
14
13
  return new class {
15
14
  countElement(element, parentComponentUniqueId) {
16
15
  element.$$uiSign = uiSignNext++;
17
- uniqueId2Element.set(element.$$uiSign, element);
16
+ this.uniqueId2Element.set(element.$$uiSign, element);
18
17
  element.parentComponentUniqueId = parentComponentUniqueId;
19
18
  }
20
19
  __CreatePage(_tag, parentComponentUniqueId) {
@@ -223,9 +222,10 @@ const initElementTree = ()=>{
223
222
  return this.toTree();
224
223
  }
225
224
  __GetElementByUniqueId(uniqueId) {
226
- return uniqueId2Element.get(uniqueId);
225
+ return this.uniqueId2Element.get(uniqueId);
227
226
  }
228
227
  constructor(){
228
+ _define_property(this, "uniqueId2Element", new Map());
229
229
  _define_property(this, "root", void 0);
230
230
  }
231
231
  }();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lynx-js/testing-environment",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "A subset of a Lynx environment to be useful for testing",
5
5
  "keywords": [
6
6
  "Lynx",
@@ -43,12 +43,13 @@
43
43
  }
44
44
  },
45
45
  "files": [
46
- "dist"
46
+ "dist",
47
+ "CHANGELOG.md"
47
48
  ],
48
49
  "devDependencies": {
49
- "@testing-library/jest-dom": "^6.6.4",
50
+ "@testing-library/jest-dom": "^6.8.0",
50
51
  "@types/jsdom": "^21.1.7",
51
- "rsbuild-plugin-publint": "0.3.2"
52
+ "rsbuild-plugin-publint": "0.3.3"
52
53
  },
53
54
  "scripts": {
54
55
  "api-extractor": "api-extractor run --verbose",