Merge branch 'master' into enhance/keymaps-manager-x

This commit is contained in:
charlie
2023-05-17 17:19:34 +08:00
8 changed files with 76 additions and 19 deletions

View File

@@ -139,7 +139,17 @@ By convention, a namespace's tests are found at a corresponding namespace
of the same name with an added `-test` suffix. For example, tests
for `frontend.db.model` are found in `frontend.db.model-test`.
There are a couple different ways to develop with tests:
There are a couple different ways to run tests:
* [Focus tests](#focus-tests) - Run one or more tests from the CLI
* [Autorun tests](#autorun-tests) - Autorun tests from the CLI
* [Repl tests](#repl-tests) - Run tests from REPL
There a couple types of tests and they can overlap with each other:
* [Database tests](#database-tests) - Tests that involve a datascript DB.
* [Performance tests](#performance-tests) - Tests that aim to measure and enforce a performance characteristic.
* [Async tests](#async-tests) - Tests that run async code and require some helpers.
#### Focus Tests
@@ -166,6 +176,15 @@ To run tests automatically on file save, run `clojure -M:test watch test
the `:ns-regexp` option e.g. `clojure -M:test watch test --config-merge
'{:autorun true :ns-regexp "frontend.util.page-property-test"}'`.
#### REPL tests
Most unit tests e.g. ones that are browser compatible and don't require node libraries, can be run from the REPL. To do so:
* Start a REPL for your editor. See [here for an example](https://github.com/logseq/logseq/blob/master/docs/develop-logseq.md#repl-setup).
* Load a test namespace.
* Run `(cljs.test/run-tests)` to run tests for the current test namespace.
#### Database tests
To write a test that uses a datascript db:
@@ -188,7 +207,7 @@ To write a performance test:
For examples of these tests, see `frontend.db.query-dsl-test` and `frontend.db.model-test`.
### Async Unit Testing
#### Async Tests
Async unit testing is well supported in ClojureScript.
https://clojurescript.org/tools/testing#async-testing is a good guide for how to

View File

@@ -159,6 +159,38 @@ test('undo the delete action', async ({ page }) => {
await expect(page.locator('.logseq-tldraw .tl-line-container')).toHaveCount(1)
})
test('convert the first rectangle to ellipse', async ({ page }) => {
await page.keyboard.press('Escape')
await page.waitForTimeout(1000)
await page.click('.logseq-tldraw .tl-box-container:first-of-type')
await page.mouse.move(0, 0) // move mouse to trigger a rerender of the context bar
await page.click('.tl-context-bar .tl-geometry-tools-pane-anchor')
await page.click('.tl-context-bar .tl-geometry-toolbar [data-tool=ellipse]')
await expect(page.locator('.logseq-tldraw .tl-ellipse-container')).toHaveCount(1)
await expect(page.locator('.logseq-tldraw .tl-box-container')).toHaveCount(1)
})
test('change the color of the ellipse', async ({ page }) => {
await page.click('.tl-context-bar .tl-color-bg')
await page.click('.tl-context-bar .tl-color-palette .bg-red-500')
await expect(page.locator('.logseq-tldraw .tl-ellipse-container ellipse:last-of-type')).toHaveAttribute('fill', 'var(--ls-wb-background-color-red)')
})
test('undo the color switch', async ({ page }) => {
await page.keyboard.press(modKey + '+z')
await expect(page.locator('.logseq-tldraw .tl-ellipse-container ellipse:last-of-type')).toHaveAttribute('fill', 'var(--ls-wb-background-color-default)')
})
test('undo the shape conversion', async ({ page }) => {
await page.keyboard.press(modKey + '+z')
await expect(page.locator('.logseq-tldraw .tl-box-container')).toHaveCount(2)
await expect(page.locator('.logseq-tldraw .tl-ellipse-container')).toHaveCount(0)
})
test('locked elements should not be removed', async ({ page }) => {
await page.keyboard.press('Escape')
await page.waitForTimeout(1000)

View File

@@ -667,14 +667,20 @@
[]
[:div.panel-wrap
[:div.text-sm.my-4
(ui/admonition
:tip
[:p "If you have Logseq Sync enabled, you can view a page's edit history directly. This section is for tech-savvy only."])
[:span.text-sm.opacity-50.my-4
"To view page's edit history, click the three horizontal dots in the top-right corner and select \"View page history\"."]
[:br][:br]
[:span.text-sm.opacity-50.my-4
"You can view a page's edit history by clicking the three horizontal dots "
"in the top-right corner and selecting \"View page history\". "
"Logseq uses "]
"For professional users, Logseq also supports using "]
[:a {:href "https://git-scm.com/" :target "_blank"}
"Git"]
[:span.text-sm.opacity-50.my-4
" for version control."]]
" for version control."]
[:span.text-sm.opacity-50.my-4
"Use Git at your own risk as general Git issues are not supported by the Logseq team"]]
[:br]
(switch-git-auto-commit-row t)
(git-auto-commit-seconds t)
@@ -827,9 +833,7 @@
[[:general "general" (t :settings-page/tab-general) (ui/icon "adjustments")]
[:editor "editor" (t :settings-page/tab-editor) (ui/icon "writing")]
(when (and
(util/electron?)
(not (file-sync-handler/synced-file-graph? current-repo)))
(when (util/electron?)
[:git "git" (t :settings-page/tab-version-control) (ui/icon "history")])
;; (when (util/electron?)

View File

@@ -100,7 +100,7 @@
:getBlockPageName #(:block/name (model/get-block-page (state/get-current-repo) (parse-uuid %)))
:exportToImage (fn [page-name options] (state/set-modal! #(export/export-blocks page-name (merge (js->clj options :keywordize-keys true) {:whiteboard? true}))))
:isWhiteboardPage model/whiteboard-page?
:isMobile (util/mobile?)
:isMobile util/mobile?
:saveAsset save-asset-handler
:makeAssetUrl editor-handler/make-asset-url
:copyToClipboard (fn [text, html] (util/copy-to-clipboard! text :html html))

View File

@@ -133,9 +133,7 @@ const LogseqPortalViewModeAction = observer(() => {
<div className="flex">
{collapsed ? 'Expand' : 'Collapse'}
<KeyboardShortcut
action={
collapsed ? 'editor/expand-block-children' : 'editor/collapse-block-children'
}
action={collapsed ? 'editor/expand-block-children' : 'editor/collapse-block-children'}
/>
</div>
)
@@ -253,7 +251,7 @@ const NoFillAction = observer(() => {
const app = useApp<Shape>()
const shapes = filterShapeByAction<BoxShape | PolygonShape | EllipseShape>('NoFill')
const handleChange = React.useCallback((v: boolean) => {
shapes.forEach(s => s.update({ noFill: v }))
app.selectedShapesArray.forEach(s => s.update({ noFill: v }))
app.persist()
}, [])
@@ -279,14 +277,14 @@ const SwatchAction = observer(() => {
>('Swatch')
const handleSetColor = React.useCallback((color: string) => {
shapes.forEach(s => {
app.selectedShapesArray.forEach(s => {
s.update({ fill: color, stroke: color })
})
app.persist()
}, [])
const handleSetOpacity = React.useCallback((opacity: number) => {
shapes.forEach(s => {
app.selectedShapesArray.forEach(s => {
s.update({ opacity: opacity })
})
app.persist()

View File

@@ -98,7 +98,11 @@ export class EllipseShape extends TLEllipseShape<EllipseShapeProps> {
)
return (
<div {...events} style={{ width: '100%', height: '100%', overflow: 'hidden' }}>
<div
{...events}
style={{ width: '100%', height: '100%', overflow: 'hidden' }}
className="tl-ellipse-container"
>
<TextLabel
font={font}
text={label}

View File

@@ -428,6 +428,7 @@ export class TLApi<S extends TLShape = TLShape, K extends TLEventMap = TLEventMa
return new ShapeClass({
...s.serialized,
type: type,
nonce: Date.now(),
})
})
this.app.currentPage.addShapes(...clones)

View File

@@ -17,11 +17,10 @@ export class ContextMenuState<
onEnter = (info: TLEventInfo<S>) => {
const {
selectedIds,
selectedShapes,
inputs: { shiftKey },
} = this.app
if (info.type === TLTargetType.Shape && !selectedShapes.has(info.shape)) {
if (info.type === TLTargetType.Shape && !selectedIds.has(info.shape.id)) {
const shape = this.app.getParentGroup(info.shape) ?? info.shape
if (shiftKey) {
this.app.setSelectedShapes([...Array.from(selectedIds.values()), shape.id])