Add minimal testing structure

This commit is contained in:
Andrey Antukh 2025-05-19 09:08:43 +02:00
parent 29d23577d2
commit 778de6adaf
5 changed files with 100 additions and 15 deletions

View file

@ -125,7 +125,8 @@
[:path {:optional true} ::sm/text]]) [:path {:optional true} ::sm/text]])
(def ^:private check-add-component (def ^:private check-add-component
(sm/check-fn schema:add-component)) (sm/check-fn schema:add-component
:hint "invalid arguments passed for add-component"))
(def decode-add-component (def decode-add-component
(sm/decode-fn schema:add-component sm/json-transformer)) (sm/decode-fn schema:add-component sm/json-transformer))
@ -136,7 +137,8 @@
[:file-id {:optional true} ::sm/uuid]]) [:file-id {:optional true} ::sm/uuid]])
(def ^:private check-add-component-instance (def ^:private check-add-component-instance
(sm/check-fn schema:add-component-instance)) (sm/check-fn schema:add-component-instance
:hint "invalid arguments passed for add-component-instance"))
(def decode-add-component-instance (def decode-add-component-instance
(sm/decode-fn schema:add-component-instance sm/json-transformer)) (sm/decode-fn schema:add-component-instance sm/json-transformer))
@ -196,7 +198,8 @@
[state params] [state params]
(let [params (-> params (let [params (-> params
(assoc :features cfeat/default-features) (assoc :features cfeat/default-features)
(assoc :migrations fmig/available-migrations)) (assoc :migrations fmig/available-migrations)
(update :id default-uuid))
file (types.file/make-file params :create-page false)] file (types.file/make-file params :create-page false)]
(-> state (-> state
(update ::files assoc (:id file) file) (update ::files assoc (:id file) file)
@ -390,7 +393,8 @@
(defn add-component (defn add-component
[state params] [state params]
(let [{:keys [component-id file-id name path]} (let [{:keys [component-id file-id name path]}
(check-add-component params) (-> (check-add-component params)
(update :component-id default-uuid))
frame-id frame-id
(get state ::current-frame-id) (get state ::current-frame-id)
@ -398,9 +402,6 @@
page-id page-id
(get state ::current-page-id) (get state ::current-page-id)
component-id
(or component-id (uuid/next))
change1 change1
(d/without-nils (d/without-nils
{:type :add-component {:type :add-component
@ -485,7 +486,7 @@
[state guide] [state guide]
(let [guide (cond-> guide (let [guide (cond-> guide
(nil? (:id guide)) (nil? (:id guide))
(assoc :id (uuid/next))) (update :id default-uuid))
page-id (::current-page-id state)] page-id (::current-page-id state)]
(-> state (-> state
(commit-change (commit-change

View file

@ -13,15 +13,19 @@
"resolutions": { "resolutions": {
"@zip.js/zip.js@npm:^2.7.44": "patch:@zip.js/zip.js@npm%3A2.7.60#~/.yarn/patches/@zip.js-zip.js-npm-2.7.60-b6b814410b.patch" "@zip.js/zip.js@npm:^2.7.44": "patch:@zip.js/zip.js@npm%3A2.7.60#~/.yarn/patches/@zip.js-zip.js-npm-2.7.60-b6b814410b.patch"
}, },
"imports": {
"#self": {
"default": "./target/library/penpot.js"
}
},
"scripts": { "scripts": {
"clear:shadow-cache": "rm -rf .shadow-cljs", "clear:shadow-cache": "rm -rf .shadow-cljs",
"build": "yarn run clear:shadow-cache && clojure -M:dev:shadow-cljs release library", "build": "yarn run clear:shadow-cache && clojure -M:dev:shadow-cljs release library",
"fmt:clj": "cljfmt fix --parallel=true src/ test/", "fmt:clj": "cljfmt fix --parallel=true src/ test/",
"fmt:clj:check": "cljfmt check --parallel=false src/ test/", "fmt:clj:check": "cljfmt check --parallel=false src/ test/",
"lint:clj": "clj-kondo --parallel --lint src/", "lint:clj": "clj-kondo --parallel --lint src/",
"build:test": "clojure -M:dev:shadow-cljs compile test", "test": "node --test",
"test": "yarn run build:test && node target/tests/test.js", "watch:test": "node --test --watch",
"watch:test": "mkdir -p target/tests && concurrently \"clojure -M:dev:shadow-cljs watch test\" \"nodemon -C -d 2 -w target/tests --exec 'node target/tests/test.js'\"",
"watch": "yarn run clear:shadow-cache && clojure -M:dev:shadow-cljs watch library" "watch": "yarn run clear:shadow-cache && clojure -M:dev:shadow-cljs watch library"
}, },
"devDependencies": { "devDependencies": {

View file

@ -1,4 +1,4 @@
import * as penpot from "../target/library/penpot.js"; import * as penpot from "#self";
import { writeFile, readFile } from 'fs/promises'; import { writeFile, readFile } from 'fs/promises';
import { createWriteStream } from 'fs'; import { createWriteStream } from 'fs';
import { Writable } from "stream"; import { Writable } from "stream";

View file

@ -35,7 +35,7 @@
:enumerable true :enumerable true
:this false :this false
:get (fn [] cause)} :get (fn [] cause)}
{:name "data" {:name "explain"
:enumerable true :enumerable true
:this false :this false
:get (fn [] :get (fn []
@ -68,7 +68,7 @@
(defn- create-builder-api (defn- create-builder-api
[state] [state]
(obj/reify {:name "File"} (obj/reify {:name "BuildContext"}
:currentFileId :currentFileId
{:get #(dm/str (get @state ::fb/current-file-id))} {:get #(dm/str (get @state ::fb/current-file-id))}
@ -275,8 +275,11 @@
:genId :genId
(fn [] (fn []
(dm/str (uuid/next))))) (dm/str (uuid/next)))
:getInternalState
(fn []
(json/->js @state))))
(defn create-build-context (defn create-build-context
"Create an empty builder state context." "Create an empty builder state context."

View file

@ -0,0 +1,77 @@
import assert from "node:assert/strict";
import test from "node:test";
import * as penpot from "#self";
test("create empty context", () => {
const context = penpot.createBuildContext();
assert.ok(context);
});
test("create context with single file", () => {
const context = penpot.createBuildContext();
context.addFile({name: "sample"});
const internalState = context.getInternalState();
// console.log(internalState);
assert.ok(internalState.files);
assert.equal(typeof internalState.files, "object");
assert.equal(typeof internalState.currentFileId, "string");
const file = internalState.files[internalState.currentFileId];
assert.ok(file);
});
test("create context with two file", () => {
const context = penpot.createBuildContext();
const fileId_1 = context.addFile({name: "sample 1"});
const fileId_2 = context.addFile({name: "sample 2"});
const internalState = context.getInternalState();
// console.log(internalState.files[fileId_1])
assert.ok(internalState.files[fileId_1]);
assert.ok(internalState.files[fileId_2]);
assert.equal(internalState.files[fileId_1].name, "sample 1");
assert.equal(internalState.files[fileId_2].name, "sample 2");
const file = internalState.files[fileId_2];
assert.ok(file.data);
assert.ok(file.data.pages);
assert.ok(file.data.pagesIndex);
assert.equal(file.data.pages.length, 0)
});
test("create context with file and page", () => {
const context = penpot.createBuildContext();
const fileId = context.addFile({name: "file 1"});
const pageId = context.addPage({name: "page 1"});
const internalState = context.getInternalState();
const file = internalState.files[fileId];
assert.ok(file, "file should exist");
assert.ok(file.data);
assert.ok(file.data.pages);
assert.equal(file.data.pages.length, 1);
const page = file.data.pagesIndex[pageId];
assert.ok(page, "page should exist");
assert.ok(page.objects, "page objects should exist");
assert.equal(page.id, pageId);
const rootShape = page.objects["00000000-0000-0000-0000-000000000000"];
assert.ok(rootShape, "root shape should exist");
assert.equal(rootShape.id, "00000000-0000-0000-0000-000000000000");
});