mirror of
https://github.com/penpot/penpot.git
synced 2026-07-22 22:17:58 +00:00
🐛 Add more test for reported bugs (#10765)
This commit is contained in:
parent
2de08f00e8
commit
6c5d01283a
@ -1043,7 +1043,12 @@
|
||||
ids (into #{} (map #(obj/get % "$id")) shapes)]
|
||||
(st/emit! (-> (dwl/add-component id-ref ids)
|
||||
(se/add-event plugin-id)))
|
||||
(lib-component-proxy plugin-id file-id @id-ref))))
|
||||
;; add-component only sets id-ref when it actually creates a
|
||||
;; component; an empty selection or shapes that can't form one
|
||||
;; leave it nil, so reject instead of returning a broken proxy.
|
||||
(if-let [id @id-ref]
|
||||
(lib-component-proxy plugin-id file-id id)
|
||||
(u/not-valid plugin-id :createComponent "Cannot create a component from the given shapes")))))
|
||||
|
||||
;; Plugin data
|
||||
:getPluginData
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
|
||||
### 🩹 Fixes
|
||||
|
||||
- **plugins-runtime**: `Library.createComponent()` now rejects invalid input (an empty shape list, or a shape inside a component copy) with a validation error instead of returning a component proxy pointing at nothing.
|
||||
- **plugins-runtime**: Setting an individual padding/margin side (`leftPadding`, `topMargin`, …) now re-derives the padding/margin type, switching to `multiple` when the four sides stop being symmetric (so the value is actually painted) and back to `simple` once top/bottom and left/right are mirrored again.
|
||||
|
||||
## 1.5.0 (2026-07-08)
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { expect } from '../framework/expect';
|
||||
import { describe, test } from '../framework/registry';
|
||||
import type { Text } from '@penpot/plugin-types';
|
||||
import type { Board, Text } from '@penpot/plugin-types';
|
||||
import type { TestContext } from '../framework/types';
|
||||
import { PNG_1X1 } from './fixtures';
|
||||
|
||||
@ -310,5 +310,59 @@ describe('Library', () => {
|
||||
expect(instance).toBeDefined();
|
||||
expect(typeof instance.id).toBe('string');
|
||||
});
|
||||
|
||||
// Reported (via MCP): create a page-root shape (rectangle / ellipse / text),
|
||||
// save it as a component, then use it from Assets — the component root was
|
||||
// said to be a plain shape instead of a board/component. This does not
|
||||
// reproduce: a lone page-root shape is wrapped in a board and that board
|
||||
// becomes the component (main-instance) root. Pin the invariant for the
|
||||
// exact repro.
|
||||
test('createComponent wraps a page-root shape in a board component root', (ctx) => {
|
||||
// A genuine page-root shape: created but NOT placed inside any board.
|
||||
const rect = ctx.penpot.createRectangle();
|
||||
const comp = ctx.penpot.library.local.createComponent([rect]);
|
||||
|
||||
const main = comp.mainInstance() as Board;
|
||||
expect(main.type).toBe('board');
|
||||
expect(main.isComponentRoot()).toBeTruthy();
|
||||
expect(main.isComponentMainInstance()).toBeTruthy();
|
||||
expect(main.children.some((c) => c.id === rect.id)).toBe(true);
|
||||
|
||||
const errors = ctx.penpot.currentFile?.validate() ?? [];
|
||||
expect(errors.map((e) => e.code)).toEqual([]);
|
||||
|
||||
// The generated main instance lands at the page root (outside ctx.board);
|
||||
// tuck it under the scratch board so teardown removes it.
|
||||
ctx.board.appendChild(main);
|
||||
});
|
||||
|
||||
// createComponent must reject inputs that cannot form a component rather
|
||||
// than succeeding silently or crashing. Both cases below currently surface
|
||||
// an INTERNAL assertion ("Assert failed: (uuid? id)"): the operation is a
|
||||
// no-op, so the returned LibraryComponent proxy is built from a nil id. It
|
||||
// should be a clean rejection (or a null return) instead — and in a release
|
||||
// build, where the assertion is elided, the caller gets a broken component
|
||||
// proxy pointing at nothing. The file must stay valid regardless.
|
||||
test('createComponent with no shapes is rejected', (ctx) => {
|
||||
expect(() => ctx.penpot.library.local.createComponent([])).toThrow();
|
||||
const errors = ctx.penpot.currentFile?.validate() ?? [];
|
||||
expect(errors.map((e) => e.code)).toEqual([]);
|
||||
});
|
||||
|
||||
test('createComponent from a shape inside a component copy is rejected', (ctx) => {
|
||||
const rect = ctx.penpot.createRectangle();
|
||||
ctx.board.appendChild(rect);
|
||||
const source = ctx.penpot.library.local.createComponent([rect]);
|
||||
const copy = source.instance() as Board;
|
||||
ctx.board.appendChild(copy);
|
||||
const copyChild = copy.children[0];
|
||||
expect(copyChild).toBeDefined();
|
||||
|
||||
expect(() =>
|
||||
ctx.penpot.library.local.createComponent([copyChild]),
|
||||
).toThrow();
|
||||
const errors = ctx.penpot.currentFile?.validate() ?? [];
|
||||
expect(errors.map((e) => e.code)).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user