Skip to content

Commit

Permalink
Support play-editor tests
Browse files Browse the repository at this point in the history
niedzielski committed Feb 28, 2024
1 parent f76916b commit f7a71ad
Showing 11 changed files with 59 additions and 22 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -4,3 +4,4 @@ tsconfig.tsbuildinfo

/dist/
/src/bundler/tsd.json
/src/typescript/typescript.js
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/dist/
/src/bundler/tsd.json
/src/typescript/typescript.js
2 changes: 1 addition & 1 deletion src/bundler/compiler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as tsvfs from '@typescript/vfs'
import * as ts from 'typescript'
import ts from '../typescript/typescript.js'
import tsd from './tsd.json' assert {type: 'json'}

export const appEntrypointFilename = '/src/main.tsx'
2 changes: 1 addition & 1 deletion src/elements/play-console.ts
Original file line number Diff line number Diff line change
@@ -8,8 +8,8 @@ import {
type TemplateResult
} from 'lit'
import {customElement, property} from 'lit/decorators.js'
import * as ts from 'typescript'
import type {Diagnostics} from '../types/diagnostics.js'
import ts from '../typescript/typescript.js'
import {Bubble} from '../utils/bubble.js'

declare global {
2 changes: 1 addition & 1 deletion src/elements/play-editor-tip.ts
Original file line number Diff line number Diff line change
@@ -7,8 +7,8 @@ import {
type TemplateResult
} from 'lit'
import {customElement, property} from 'lit/decorators.js'
import * as ts from 'typescript'
import type {Diagnostics} from '../types/diagnostics.js'
import ts from '../typescript/typescript.js'

declare global {
interface HTMLElementTagNameMap {
2 changes: 1 addition & 1 deletion src/elements/play-editor/editor-state.ts
Original file line number Diff line number Diff line change
@@ -35,8 +35,8 @@ import {
} from '@codemirror/view'
import type {VirtualTypeScriptEnvironment} from '@typescript/vfs'
import {EditorView} from 'codemirror'
import * as ts from 'typescript'
import {appEntrypointFilename} from '../../bundler/compiler.js'
import ts from '../../typescript/typescript.js'
import {PlayEditorTip} from '../play-editor-tip.js'
import {editorThemeExtension} from './editor-theme.js'

22 changes: 22 additions & 0 deletions src/elements/play-editor/play-editor.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {assert, expect} from '@esm-bundle/chai'
import {html, render} from 'lit'
import {newTSEnv} from '../../bundler/compiler.js'
import {PlayEditor} from './play-editor.js'

test('tag is defined', () => {
@@ -25,3 +26,24 @@ test('a slotted template emits an edit-template event', async () => {
})
expect(edit.detail).equal("console.log('Hello World!')")
})

test('setSrc() replaces a template', async () => {
render(
html`
<play-editor .env=${newTSEnv()}>
<script lang="tsx" type="application/devvit">
'abc'
</script>
</play-editor>
`,
document.body
)
const el = document.querySelector<PlayEditor>('play-editor')!
await new Promise(resolve => requestAnimationFrame(resolve))
const edit = await new Promise<CustomEvent<string>>(resolve => {
el.addEventListener('edit', resolve)
el.setSrc("'def'")
})

expect(edit.detail).equal("'def'")
})
20 changes: 11 additions & 9 deletions src/elements/play-editor/play-editor.ts
Original file line number Diff line number Diff line change
@@ -13,8 +13,8 @@ import {
customElement,
eventOptions,
property,
query,
queryAssignedElements
queryAssignedElements,
queryAsync
} from 'lit/decorators.js'
import {Bubble} from '../../utils/bubble.js'
import {unindent} from '../../utils/unindent.js'
@@ -45,9 +45,9 @@ export class PlayEditor extends LitElement {
`

@property({attribute: false}) env?: VirtualTypeScriptEnvironment
@property() src: string | undefined
@property() src: string = ''

@query('div') private _root!: HTMLDivElement
@queryAsync('.editor') private _editorEl!: Promise<HTMLDivElement>

@queryAssignedElements({
flatten: true,
@@ -76,19 +76,21 @@ export class PlayEditor extends LitElement {
})
}

protected override firstUpdated(_props: PropertyValues<this>): void {
if (this.env) {
const init = newEditorState(this.env, this.src ?? '')
protected override async willUpdate(
props: PropertyValues<this>
): Promise<void> {
if (props.has('env') && this.env && !this.#editor) {
const el = await this._editorEl
const init = newEditorState(this.env, this.src)
this.#editor = new EditorView({
dispatch: transaction => {
this.#editor!.update([transaction])

if (transaction.docChanged) {
const src = transaction.state.doc.sliceString(0)
this.dispatchEvent(Bubble<string>('edit', src))
}
},
parent: this._root,
parent: el,
state: init
})
}
4 changes: 2 additions & 2 deletions src/types/diagnostics.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type {DevvitUIError} from '@devvit/ui-renderer/client/devvit-custom-post.js'
import type {Diagnostic} from 'typescript'
import ts from '../typescript/typescript.js'

export type Diagnostics = {
// to-do: unhandled promise rejections.
/** Uncaught errors thrown when executing the pen program. */
previewErrs: DevvitUIError[]
tsErrs: Diagnostic[]
tsErrs: ts.Diagnostic[]
}
2 changes: 2 additions & 0 deletions src/typescript/typescript.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import ts from 'typescript'
export default ts
23 changes: 16 additions & 7 deletions tools/build
Original file line number Diff line number Diff line change
@@ -80,10 +80,19 @@ async function pluginOnEnd(result) {
)
}

await fs.writeFile(
path.join('src', 'bundler', 'tsd.json'),
JSON.stringify(await readTSDs(), null, 2)
)
await Promise.all([
fs.writeFile(
'src/bundler/tsd.json', // move?
JSON.stringify(await readTSDs(), null, 2)
),
esbuild.build({
bundle: true,
entryPoints: ['node_modules/typescript/lib/typescript.js'],
external: ['fs', 'inspector', 'os'],
format: 'esm',
outfile: 'src/typescript/typescript.js'
})
])

/** @type {esbuild.BuildOptions} */
const opts = {
@@ -112,12 +121,12 @@ if (watch) {
esbuild.build(appOpts),
esbuild.build({
...opts,
entryPoints: [path.join('src', 'index.ts')],
outfile: path.join('dist', 'play.js')
entryPoints: ['src/index.ts'],
outfile: 'dist/play.js'
}),
esbuild.build({
...opts,
entryPoints: [path.join('src', 'elements', 'play-pen', 'play-pen.ts')],
entryPoints: ['src/elements/play-pen/play-pen.ts'],
outdir: 'dist'
})
])

0 comments on commit f7a71ad

Please sign in to comment.