@geometra/renderer-canvas 1.1.2 → 1.2.1

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.
@@ -1,4 +1,5 @@
1
- import { describe, it, expect } from 'vitest';
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { box } from '@geometra/core';
2
3
  import { CanvasRenderer } from '../renderer.js';
3
4
  class FakeCtx {
4
5
  fillStyle = '';
@@ -22,6 +23,23 @@ class FakeCtx {
22
23
  }
23
24
  }
24
25
  describe('CanvasRenderer.setFrameTimings', () => {
26
+ it('treats omitted or non-finite layoutMs as 0', () => {
27
+ Object.defineProperty(globalThis, 'window', {
28
+ value: { devicePixelRatio: 1 },
29
+ configurable: true,
30
+ writable: true,
31
+ });
32
+ const ctx = new FakeCtx();
33
+ const canvas = {
34
+ style: {},
35
+ getContext: () => ctx,
36
+ };
37
+ const renderer = new CanvasRenderer({ canvas });
38
+ renderer.setFrameTimings({});
39
+ expect(renderer.lastLayoutWallMs).toBe(0);
40
+ renderer.setFrameTimings({ layoutMs: undefined });
41
+ expect(renderer.lastLayoutWallMs).toBe(0);
42
+ });
25
43
  it('clamps non-finite or negative layoutMs to 0', () => {
26
44
  Object.defineProperty(globalThis, 'window', {
27
45
  value: { devicePixelRatio: 1 },
@@ -43,5 +61,68 @@ describe('CanvasRenderer.setFrameTimings', () => {
43
61
  renderer.setFrameTimings({ layoutMs: 4.25 });
44
62
  expect(renderer.lastLayoutWallMs).toBe(4.25);
45
63
  });
64
+ it('treats non-number layoutMs (bigint, string, boolean) as 0 without throwing', () => {
65
+ Object.defineProperty(globalThis, 'window', {
66
+ value: { devicePixelRatio: 1 },
67
+ configurable: true,
68
+ writable: true,
69
+ });
70
+ const ctx = new FakeCtx();
71
+ const canvas = {
72
+ style: {},
73
+ getContext: () => ctx,
74
+ };
75
+ const renderer = new CanvasRenderer({ canvas });
76
+ expect(() => renderer.setFrameTimings({ layoutMs: 99n })).not.toThrow();
77
+ expect(renderer.lastLayoutWallMs).toBe(0);
78
+ expect(() => renderer.setFrameTimings({ layoutMs: '12' })).not.toThrow();
79
+ expect(renderer.lastLayoutWallMs).toBe(0);
80
+ expect(() => renderer.setFrameTimings({ layoutMs: true })).not.toThrow();
81
+ expect(renderer.lastLayoutWallMs).toBe(0);
82
+ });
83
+ });
84
+ describe('CanvasRenderer.render wall time', () => {
85
+ it('sets lastRenderWallMs to the elapsed performance.now() delta for the frame', () => {
86
+ Object.defineProperty(globalThis, 'window', {
87
+ value: { devicePixelRatio: 1 },
88
+ configurable: true,
89
+ writable: true,
90
+ });
91
+ const ctx = new FakeCtx();
92
+ const canvas = {
93
+ style: {},
94
+ getContext: () => ctx,
95
+ };
96
+ // render() samples performance.now() at frame start and again when computing lastRenderWallMs
97
+ // (inspector HUD is off by default, so there is no third sample).
98
+ const stamps = [100, 103.5];
99
+ let i = 0;
100
+ const spy = vi.spyOn(performance, 'now').mockImplementation(() => stamps[i++] ?? stamps[stamps.length - 1]);
101
+ const renderer = new CanvasRenderer({ canvas });
102
+ const tree = box({ width: 10, height: 10 });
103
+ const layout = { x: 0, y: 0, width: 10, height: 10, children: [] };
104
+ renderer.render(layout, tree);
105
+ expect(renderer.lastRenderWallMs).toBeCloseTo(3.5, 5);
106
+ spy.mockRestore();
107
+ });
108
+ it('records 0 lastRenderWallMs when performance.now does not advance (stable clock)', () => {
109
+ Object.defineProperty(globalThis, 'window', {
110
+ value: { devicePixelRatio: 1 },
111
+ configurable: true,
112
+ writable: true,
113
+ });
114
+ const ctx = new FakeCtx();
115
+ const canvas = {
116
+ style: {},
117
+ getContext: () => ctx,
118
+ };
119
+ const spy = vi.spyOn(performance, 'now').mockImplementation(() => 42);
120
+ const renderer = new CanvasRenderer({ canvas });
121
+ const tree = box({ width: 10, height: 10 });
122
+ const layout = { x: 0, y: 0, width: 10, height: 10, children: [] };
123
+ renderer.render(layout, tree);
124
+ expect(renderer.lastRenderWallMs).toBe(0);
125
+ spy.mockRestore();
126
+ });
46
127
  });
47
128
  //# sourceMappingURL=renderer-timing.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"renderer-timing.test.js","sourceRoot":"","sources":["../../src/__tests__/renderer-timing.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAE/C,MAAM,OAAO;IACX,SAAS,GAAG,EAAE,CAAA;IACd,WAAW,GAAG,EAAE,CAAA;IAChB,SAAS,GAAG,CAAC,CAAA;IACb,IAAI,GAAG,iBAAiB,CAAA;IACxB,YAAY,GAAG,KAA2B,CAAA;IAC1C,WAAW,GAAG,CAAC,CAAA;IACf,KAAK,KAAU,CAAC;IAChB,YAAY,KAAU,CAAC;IACvB,QAAQ,KAAU,CAAC;IACnB,SAAS,KAAU,CAAC;IACpB,IAAI,KAAU,CAAC;IACf,IAAI,KAAU,CAAC;IACf,IAAI,KAAU,CAAC;IACf,OAAO,KAAU,CAAC;IAClB,UAAU,KAAU,CAAC;IACrB,QAAQ,KAAU,CAAC;IACnB,WAAW,CAAC,CAAS;QACnB,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAA;IAChC,CAAC;CACF;AAED,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,EAAE;YAC1C,KAAK,EAAE,EAAE,gBAAgB,EAAE,CAAC,EAAE;YAC9B,YAAY,EAAE,IAAI;YAClB,QAAQ,EAAE,IAAI;SACf,CAAC,CAAA;QACF,MAAM,GAAG,GAAG,IAAI,OAAO,EAAE,CAAA;QACzB,MAAM,MAAM,GAAG;YACb,KAAK,EAAE,EAA4B;YACnC,UAAU,EAAE,GAAG,EAAE,CAAC,GAAG;SACU,CAAA;QAEjC,MAAM,QAAQ,GAAG,IAAI,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC,CAAA;QAC/C,QAAQ,CAAC,eAAe,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAA;QAClD,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACzC,QAAQ,CAAC,eAAe,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,iBAAiB,EAAE,CAAC,CAAA;QAChE,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACzC,QAAQ,CAAC,eAAe,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC,CAAA;QAC1C,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACzC,QAAQ,CAAC,eAAe,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;QAC5C,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC9C,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"renderer-timing.test.js","sourceRoot":"","sources":["../../src/__tests__/renderer-timing.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geometra/renderer-canvas",
3
- "version": "1.1.2",
3
+ "version": "1.2.1",
4
4
  "description": "Canvas2D renderer for Geometra — the singularity frontend framework",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -35,6 +35,6 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@geometra/client": "file:../client",
38
- "@geometra/core": "^1.1.2"
38
+ "@geometra/core": "^1.2.1"
39
39
  }
40
40
  }