Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set output evaluation context for a single node #8440

Merged
merged 44 commits into from
Dec 15, 2023
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
ce332a1
`isMatch` function to match CST subtrees
somebody1234 Dec 1, 2023
391c526
(broken) Detect current Output Context enabled state
somebody1234 Dec 1, 2023
a23dddc
Implement `extractMatches` to extract CST subtrees
somebody1234 Dec 1, 2023
a079f66
Interactivity for output context override in Circular Menu; initial i…
somebody1234 Dec 1, 2023
f3fa62f
Basic tests for string escape
somebody1234 Dec 1, 2023
ae6f53d
Attempt to hide overridden output context expressions from `GraphNode`
somebody1234 Dec 4, 2023
9ea511b
Merge branch 'develop' into wip/sb/set-eval-ctx
somebody1234 Dec 4, 2023
b658ef6
Fix CSS for `CircularMenu`
somebody1234 Dec 4, 2023
32e7b28
Fix AST match extraction by using `parseLine` instead of `parse`
somebody1234 Dec 4, 2023
70425c2
Fix inserted text
somebody1234 Dec 4, 2023
c5bf8f6
Refactor to make it easier to fix node icons for overriden output con…
somebody1234 Dec 4, 2023
09dca91
Only allow a single output context override
somebody1234 Dec 5, 2023
48e9a55
Address review
somebody1234 Dec 5, 2023
fbc457e
Initial component test for `GraphNode` including execution mode override
somebody1234 Dec 5, 2023
882c23b
Get rid of `unhandledRejection` errors
somebody1234 Dec 5, 2023
d163b54
More consistent handling of `default`
kazcw Dec 5, 2023
ecfdbec
Inline function return signatures
kazcw Dec 5, 2023
ada03b6
GUI1
kazcw Dec 6, 2023
a46aee2
Merge branch 'develop' into wip/sb/set-eval-ctx
somebody1234 Dec 6, 2023
415fc47
Port AST matching to new API
somebody1234 Dec 6, 2023
9f0e95d
Add missing issue number
kazcw Dec 6, 2023
45ed77d
Tests
kazcw Dec 6, 2023
f07fa80
Fix tests and stuff
somebody1234 Dec 6, 2023
986d309
WIP: Checking and modifying prefixes of node content
somebody1234 Dec 7, 2023
745f049
Fix tests
somebody1234 Dec 7, 2023
f92385c
Fix bug
somebody1234 Dec 7, 2023
616c83e
Fix imports in E2E tests
somebody1234 Dec 7, 2023
795f836
Move `ast/string` to `ast/text`
somebody1234 Dec 7, 2023
55e97bc
Fix text escaping
somebody1234 Dec 7, 2023
5575023
Fix error that only occurs on built package
somebody1234 Dec 7, 2023
351eea7
Merge remote-tracking branch 'origin/wip/kw/parse-inline-signatures' …
kazcw Dec 8, 2023
7786b70
Merge remote-tracking branch 'origin/wip/sb/set-eval-ctx' into ast-edits
kazcw Dec 8, 2023
ba211b0
wip
kazcw Dec 11, 2023
2b038df
Merge remote-tracking branch 'origin/develop' into ast-edits
kazcw Dec 11, 2023
4362fc8
wip
kazcw Dec 11, 2023
9888941
Pass tests
kazcw Dec 12, 2023
41d4172
Merge commit '0974d5ff1e1729148e7b74c98c82e03a5ad8a751' into ast-edits
kazcw Dec 12, 2023
e71c60b
Merge commit '3d76459ba7079c6bd115bbfec2b0911881e527e5' into ast-edits
kazcw Dec 12, 2023
8aa3e0e
Merge commit 'be2ae3279cbfddf30007f2007b0aaa19cfa14891' into ast-edits
kazcw Dec 12, 2023
0ded00d
Merge remote-tracking branch 'origin/develop' into ast-edits
kazcw Dec 12, 2023
791c841
Clean up tests
kazcw Dec 13, 2023
bf63ea8
Rerun CI?
kazcw Dec 13, 2023
371ad48
Rerun CI?
kazcw Dec 13, 2023
19906cb
Merge branch 'develop' into wip/sb/set-eval-ctx
somebody1234 Dec 15, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions app/gui2/e2e/MockApp.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<script setup lang="ts">
import { computed } from 'vue'
import { getMainFile, setMainFile } from '../mock/engine'
import App from '../src/App.vue'
import MockProjectStoreWrapper from '../stories/MockProjectStoreWrapper.vue'
import { getMainFile, setMainFile } from './mockEngine'

const mainFile = computed({
get() {
Expand All @@ -15,7 +15,9 @@ const mainFile = computed({
</script>

<template>
<MockProjectStoreWrapper v-model="mainFile"><App :config="{}" /></MockProjectStoreWrapper>
<MockProjectStoreWrapper v-model="mainFile">
<App :config="{}" :metadata="{}" />
</MockProjectStoreWrapper>
</template>

<style scoped>
Expand Down
2 changes: 1 addition & 1 deletion app/gui2/e2e/main.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import 'enso-dashboard/src/tailwind.css'
import { createPinia } from 'pinia'
import { createApp, ref } from 'vue'
import { mockDataHandler, mockLSHandler } from '../mock/engine'
import '../src/assets/base.css'
import { provideGuiConfig } from '../src/providers/guiConfig'
import { provideVisualizationConfig } from '../src/providers/visualizationConfig'
import { MockTransport, MockWebSocket } from '../src/util/net'
import { Vec2 } from '../src/util/vec2'
import MockApp from './MockApp.vue'
import { mockDataHandler, mockLSHandler } from './mockEngine'

MockTransport.addMock('engine', mockLSHandler)
MockWebSocket.addMock('data', mockDataHandler)
Expand Down
2 changes: 1 addition & 1 deletion app/gui2/e2e/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
type ProjectId,
type ProjectName,
type UTCDateTime,
} from './mockProjectManager'
} from '../mock/projectManager'
import pmSpec from './pm-openrpc.json' assert { type: 'json' }

export default function setup() {
Expand Down
File renamed without changes.
92 changes: 92 additions & 0 deletions app/gui2/mock/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { provideGuiConfig } from '@/providers/guiConfig'
import { provideWidgetRegistry } from '@/providers/widgetRegistry'
import { useGraphStore } from '@/stores/graph'
import { GraphDb, mockNode } from '@/stores/graph/graphDatabase'
import { useProjectStore } from '@/stores/project'
import { ComputedValueRegistry } from '@/stores/project/computedValueRegistry'
import { MockTransport, MockWebSocket } from '@/util/net'
import * as random from 'lib0/random'
import { getActivePinia } from 'pinia'
import type { ExprId } from 'shared/yjsModel'
import { ref, type App } from 'vue'
import { mockDataHandler, mockLSHandler } from './engine'
export * as providers from './providers'
export * as vue from './vue'

export function languageServer() {
MockTransport.addMock('engine', mockLSHandler)
}

export function dataServer() {
MockWebSocket.addMock('data', mockDataHandler)
}

export function guiConfig(app: App) {
return provideGuiConfig._mock(
ref({
startup: {
project: 'Mock Project',
displayedProjectName: 'Mock Project',
},
engine: { rpcUrl: 'mock://engine', dataUrl: 'mock://data' },
}),
app,
)
}

export const computedValueRegistry = ComputedValueRegistry.Mock
export const graphDb = GraphDb.Mock

export function widgetRegistry(app: App) {
return widgetRegistry.withGraphDb(graphDb())(app)
}

widgetRegistry.withGraphDb = function widgetRegistryWithGraphDb(graphDb: GraphDb) {
return (app: App) => provideWidgetRegistry._mock([graphDb], app)
}

export function graphStore() {
return useGraphStore(getActivePinia())
}

type ProjectStore = ReturnType<typeof projectStore>

export function projectStore() {
const projectStore = useProjectStore(getActivePinia())
const mod = projectStore.projectModel.createNewModule('Main.enso')
mod.doc.ydoc.emit('load', [])
mod.doc.contents.insert(0, 'main =\n')
return projectStore
}

/** The stores should be initialized in this order, as `graphStore` depends on `projectStore`. */
export function projectStoreAndGraphStore() {
return [projectStore(), graphStore()] satisfies [] | unknown[]
}

export function newExprId() {
return random.uuidv4() as ExprId
}

/** This should only be used for supplying as initial props when testing.
* Please do {@link GraphDb.mockNode} with a `useGraphStore().db` after mount. */
export function node() {
return mockNode()
}

export function waitForMainModule(projectStore?: ProjectStore) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't find any usages of this function. Can it be removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was required previously when I used component tests for GraphNode

const definedProjectStore = projectStore ?? useProjectStore(getActivePinia())
return new Promise((resolve, reject) => {
const handle1 = window.setInterval(() => {
if (definedProjectStore.module != null) {
window.clearInterval(handle1)
window.clearTimeout(handle2)
resolve(definedProjectStore.module)
}
}, 10)
const handle2 = window.setTimeout(() => {
window.clearInterval(handle1)
reject()
}, 5_000)
})
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
declare const projectIdBrand: unique symbol
/** A name of a project. */
/** An ID of a project. */
export type ProjectId = string & { [projectIdBrand]: never }
declare const projectNameBrand: unique symbol
/** A name of a project. */
export type ProjectName = string & { [projectNameBrand]: never }
declare const utcDateTimeBrand: unique symbol
/** A name of a project. */
/** A UTC date and time. */
export type UTCDateTime = string & { [utcDateTimeBrand]: never }

/** A value specifying the hostname and port of a socket. */
Expand Down
55 changes: 55 additions & 0 deletions app/gui2/mock/providers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import type { GraphSelection } from '@/providers/graphSelection'
import type { GraphNavigator } from '../src/providers/graphNavigator'
import { Rect } from '../src/util/rect'
import { Vec2 } from '../src/util/vec2'

export const graphNavigator: GraphNavigator = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this have to be mocked? I feel like no providers should need any mocking, except for things related to network requests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

previously we had component tests for GraphNode... I guess the correct solution is maybe to use a wrapper component then?

but also, we're no longer doing component tests so it's not like these are currently used either.

events: {} as any,
clientToScenePos: () => Vec2.Zero,
clientToSceneRect: () => Rect.Zero,
panAndZoomTo: () => {},
transform: '',
prescaledTransform: '',
translate: Vec2.Zero,
scale: 1,
sceneMousePos: Vec2.Zero,
viewBox: '',
viewport: Rect.Zero,
}

export function graphNavigatorWith(modifications?: Partial<GraphNavigator>): GraphNavigator {
return Object.assign({}, graphNavigator, modifications)
}

export const graphSelection: GraphSelection = {
events: {} as any,
anchor: undefined,
deselectAll: () => {},
addHoveredPort: () => new Set(),
removeHoveredPort: () => false,
handleSelectionOf: () => {},
hoveredNode: undefined,
hoveredPort: undefined,
isSelected: () => false,
mouseHandler: () => false,
selectAll: () => {},
selected: new Set(),
}

export function graphSelectionWith(modifications?: Partial<GraphSelection>): GraphSelection {
return Object.assign({}, graphSelection, modifications)
}

export const all = {
'graph navigator': graphNavigator,
'graph selection': graphSelection,
}

export function allWith(
modifications: Partial<{ [K in keyof typeof all]: Partial<(typeof all)[K]> }>,
): typeof all {
return {
'graph navigator': graphNavigatorWith(modifications['graph navigator']),
'graph selection': graphSelectionWith(modifications['graph selection']),
}
}
19 changes: 19 additions & 0 deletions app/gui2/mock/vue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { type VueWrapper } from '@vue/test-utils'
import { nextTick } from 'vue'

// It is currently not feasible to use generics here, as the type of the component's emits
// is not exposed.
export function handleEmit(wrapper: VueWrapper<any>, event: string, fn: (...args: any[]) => void) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this used anywhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above, previously used for component tests. i figured it's fine to keep it if we may want to do component testing in the future, but i have no problems with removing all unused code because we are probably not planning to do that anytime soon anyway.

let previousLength = 0
return {
async run() {
const emitted = wrapper.emitted(event)
if (!emitted) return
for (let i = previousLength; i < emitted.length; i += 1) {
fn(...emitted[i]!)
}
previousLength = emitted.length
await nextTick()
},
}
}
6 changes: 6 additions & 0 deletions app/gui2/src/assets/icons.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 19 additions & 8 deletions app/gui2/src/components/CircularMenu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
import ToggleIcon from '@/components/ToggleIcon.vue'

const props = defineProps<{
isAutoEvaluationDisabled: boolean
isOutputContextEnabledGlobally: boolean
isOutputContextOverridden: boolean
isDocsVisible: boolean
isVisualizationVisible: boolean
}>()
const emit = defineEmits<{
'update:isAutoEvaluationDisabled': [isAutoEvaluationDisabled: boolean]
'update:isOutputContextOverridden': [isOutputContextOverridden: boolean]
'update:isDocsVisible': [isDocsVisible: boolean]
'update:isVisualizationVisible': [isVisualizationVisible: boolean]
}>()
Expand All @@ -16,11 +17,16 @@ const emit = defineEmits<{
<template>
<div class="CircularMenu">
<ToggleIcon
icon="no_auto_replay"
class="icon-container button no-auto-evaluate-button"
:alt="`${props.isAutoEvaluationDisabled ? 'Enable' : 'Disable'} auto-evaluation`"
:modelValue="props.isAutoEvaluationDisabled"
@update:modelValue="emit('update:isAutoEvaluationDisabled', $event)"
:icon="props.isOutputContextEnabledGlobally ? 'no_auto_replay' : 'auto_replay'"
class="icon-container button override-output-context-button"
:class="{ 'output-context-overridden': props.isOutputContextOverridden }"
:alt="`${
props.isOutputContextEnabledGlobally != props.isOutputContextOverridden
? 'Disable'
: 'Enable'
} output context`"
:modelValue="props.isOutputContextOverridden"
@update:modelValue="emit('update:isOutputContextOverridden', $event)"
/>
<ToggleIcon
icon="docs"
Expand Down Expand Up @@ -70,12 +76,17 @@ const emit = defineEmits<{
opacity: unset;
}

.no-auto-evaluate-button {
.override-output-context-button {
position: absolute;
left: 9px;
top: 8px;
}

.output-context-overridden {
opacity: 100%;
color: red;
}

.docs-button {
position: absolute;
left: 18.54px;
Expand Down
Loading