Skip to content

Commit 87eb4c2

Browse files
committed
additional vite config for testing and chunking
1 parent f475f9e commit 87eb4c2

12 files changed

Lines changed: 1026 additions & 884 deletions

File tree

package-lock.json

Lines changed: 864 additions & 765 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
],
1919
"sideEffects": [
2020
"**/*.css",
21+
"src/register-components.ts",
22+
"src/components/source-provider/SourceProvider.ts",
23+
"src/components/sourceEditorCard/SourceEditorCard.ts",
2124
"dist/**/*.js"
2225
],
2326
"scripts": {

src/Header.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { ref } from 'lit/directives/ref.js'
33
import { NamedNode, LiveStore } from 'rdflib'
44
import { widgets, icons } from 'solid-ui'
55
import { SourcePaneState } from './types'
6-
import SourceEditorCard from './components/sourceEditorCard/SourceEditorCard'
6+
import type SourceEditorCard from './components/sourceEditorCard/SourceEditorCard'
77

88
/* This we will use in the header ticket, didn't want to lose the code */
99
export function canEditSource (subject: NamedNode, sourcePaneState: SourcePaneState) {

src/components/source-provider/SourceProvider.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { provide } from '@lit/context'
21
import { html } from 'lit'
2+
import { provide } from '@lit/context'
33
import { customElement, property } from 'lit/decorators.js'
44
import { NamedNode } from 'rdflib'
55
import { DataBrowserContext } from 'pane-registry'
@@ -87,9 +87,9 @@ export default class SourceProvider extends WebComponent {
8787
const { renderStatusSection } = getStatusSection()
8888

8989
return html`
90-
${renderHeader(store, subject, this.sourcePaneState)}
90+
${renderHeader(store as any, subject as any, this.sourcePaneState)}
9191
<solid-panes-source-editor-card></solid-panes-source-editor-card>
9292
${renderStatusSection()}
9393
`
9494
}
95-
}
95+
}

src/components/sourceEditorCard/SourceEditorCard.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ import { applyResponseHeaders, checkSyntax, fetchContentAndMetadata, getResponse
77
import styles from './SourceEditorCard.styles.css'
88
import { WebComponent } from 'solid-ui'
99
import { getStatusSection } from '../../StatusSection'
10-
import { SourceContext } from '../../primitives/context'
11-
import { sourceContext } from '../../primitives/context'
1210
import 'solid-ui/components/button'
1311
import { compactable } from '../../compactableFormats'
12+
import { SourceContext } from '../../primitives/context'
13+
import { sourceContext } from '../../primitives/context'
1414

1515
@customElement('solid-panes-source-editor-card')
1616
export default class SourceEditorCard extends WebComponent {
1717
static styles = styles
18+
1819
private _editor?: SourceEditor
1920
private _originalContent?: string
2021
private _dirtyState = false
@@ -84,7 +85,7 @@ export default class SourceEditorCard extends WebComponent {
8485
}
8586
try {
8687
const { SourceEditor } = await import('./SourceEditor')
87-
const { content, metadata } = await fetchContentAndMetadata(sourceContext.context.session.store, new NamedNode(sourceContext.subject), sourceContext.sourcePaneState)
88+
const { content, metadata } = await fetchContentAndMetadata(sourceContext.context.session.store as any, new NamedNode(sourceContext.subject), sourceContext.sourcePaneState as any)
8889
this._originalContent = content
8990
this._editor = new SourceEditor()
9091
await this._editor.initialize(sourcePaneEditor, content, metadata.contentType, 'dark', dirty => {
@@ -126,13 +127,13 @@ export default class SourceEditorCard extends WebComponent {
126127
private async saveBack () {
127128
const sourceContext = this._requireSourceContext()
128129

129-
const store = sourceContext.context.session.store
130+
const store = sourceContext.context.session.store as any
130131
const subject = new NamedNode(sourceContext.subject)
131132
const sourcePaneState = sourceContext.sourcePaneState
132133
const fetcher = store.fetcher
133134
const data = this.getEditor()?.getValue() ?? ''
134135
const { contentType, eTag } = sourceContext.sourcePaneState
135-
if (!checkSyntax(store, subject, data, contentType, subject)) {
136+
if (!checkSyntax(store, subject as any, data, contentType, subject as any)) {
136137
const { showError } = getStatusSection()
137138
showError('Syntax error: fix the document before saving.')
138139
return
@@ -147,7 +148,7 @@ export default class SourceEditorCard extends WebComponent {
147148
try {
148149
const response = await fetcher.webOperation('HEAD', subject.uri) // , defaultFetchHeaders())
149150
if (!happy(response, 'HEAD')) return
150-
applyResponseHeaders(sourcePaneState, getResponseHeaders(store, subject, response))
151+
applyResponseHeaders(sourcePaneState as any, getResponseHeaders(store, subject as any, response))
151152
this._resetEditorState()
152153
} catch (err) {
153154
throw err
@@ -164,7 +165,7 @@ export default class SourceEditorCard extends WebComponent {
164165
const { contentType } = sourceContext.sourcePaneState
165166
const compactContentType = contentType?.split(';')[0]
166167
const { showError } = getStatusSection()
167-
const store = sourceContext.context.session.store
168+
const store = sourceContext.context.session.store as any
168169
const subjectNode = new NamedNode(sourceContext.subject)
169170

170171
if (compactContentType && compactable[compactContentType]) {

src/register-components.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
void import('./components/source-provider/SourceProvider').then(() => undefined)
2+
void import('./components/sourceEditorCard/SourceEditorCard').then(() => undefined)

src/sourcePane.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,10 @@ import { DataBrowserContext, NewPaneOptions } from 'pane-registry'
99
import * as mime from 'mime-types'
1010
import { html, render as litRender } from 'lit'
1111
import { log } from './debug'
12-
import SourceEditorCard from './components/sourceEditorCard/SourceEditorCard'
13-
import SourceProvider from './components/source-provider/SourceProvider'
1412
import './sourcePane.css'
13+
import './register-components'
1514
import { SourcePaneState } from './types'
1615

17-
// Keep custom-element modules in the bundle; they are registered for side effects.
18-
void SourceEditorCard
19-
void SourceProvider
20-
2116
const pane = {
2217
icon: icons.iconBase + 'noun_109873.svg', // noun_109873_51A7F9.svg
2318

test/helpers.test.js

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,54 @@
1-
const { getResponseHeaders, fetchContentAndMetadata } = require('../src/helpers')
1+
import { beforeEach, describe, expect, it, vi } from 'vitest'
2+
3+
import { fetchContentAndMetadata, getResponseHeaders } from '../src/helpers.ts'
24

35
describe('helpers', () => {
46
beforeEach(() => {
5-
jest.clearAllMocks()
7+
vi.clearAllMocks()
68
})
79

810
it('reads response headers into metadata', () => {
911
const response = {
1012
headers: {
11-
get: jest.fn((name) => {
13+
get: vi.fn((name) => {
1214
if (name === 'content-type') return 'text/turtle; charset=utf-8'
1315
if (name === 'allow') return 'GET,PUT'
1416
if (name === 'etag') return '"abc"'
1517
return null
16-
}),
17-
},
18+
})
19+
}
1820
}
19-
const store = { each: jest.fn(), any: jest.fn(), anyValue: jest.fn(), sym: jest.fn() }
21+
const store = { each: vi.fn(), any: vi.fn(), anyValue: vi.fn(), sym: vi.fn() }
2022
const subject = { uri: 'https://example.org/profile/card' }
2123

2224
expect(getResponseHeaders(store, subject, response)).toEqual({
2325
contentType: 'text/turtle',
2426
allowed: 'GET,PUT',
25-
eTag: '"abc"',
27+
eTag: '"abc"'
2628
})
2729
})
2830

2931
it('fetches content and applies the returned metadata', async () => {
3032
const response = {
3133
ok: true,
3234
headers: {
33-
get: jest.fn((name) => {
35+
get: vi.fn((name) => {
3436
if (name === 'content-type') return 'text/turtle'
3537
if (name === 'allow') return 'GET,PUT'
3638
if (name === 'etag') return '"abc"'
3739
return null
38-
}),
40+
})
3941
},
40-
responseText: '<> a <#Thing>.',
42+
responseText: '<> a <#Thing>.'
4143
}
4244
const store = {
4345
fetcher: {
44-
webOperation: jest.fn().mockResolvedValue(response),
46+
webOperation: vi.fn().mockResolvedValue(response)
4547
},
46-
each: jest.fn(),
47-
any: jest.fn(),
48-
anyValue: jest.fn(),
49-
sym: jest.fn(),
48+
each: vi.fn(),
49+
any: vi.fn(),
50+
anyValue: vi.fn(),
51+
sym: vi.fn()
5052
}
5153
const subject = { uri: 'https://example.org/profile/card' }
5254
const sourcePaneState = { broken: false, contentType: undefined, allowed: undefined, eTag: undefined }
@@ -58,14 +60,14 @@ describe('helpers', () => {
5860
metadata: {
5961
contentType: 'text/turtle',
6062
allowed: 'GET,PUT',
61-
eTag: '"abc"',
62-
},
63+
eTag: '"abc"'
64+
}
6365
})
6466
expect(sourcePaneState).toEqual({
6567
broken: false,
6668
contentType: 'text/turtle',
6769
allowed: 'GET,PUT',
68-
eTag: '"abc"',
70+
eTag: '"abc"'
6971
})
7072
})
7173
})

test/helpers/fetch-mock.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { vi } from 'vitest'
2+
3+
type FetchHandler = (request: Request) => Response | Promise<Response> | Record<string, unknown> | Promise<Record<string, unknown>>
4+
5+
type FetchMockEntry = {
6+
pattern: RegExp
7+
handler: FetchHandler
8+
}
9+
10+
const handlers: FetchMockEntry[] = []
11+
12+
function toHeaders (headers: Headers | Record<string, string> | undefined) {
13+
if (headers instanceof Headers) return headers
14+
return new Headers(headers)
15+
}
16+
17+
function toResponse (result: Response | Promise<Response> | Record<string, unknown>): Response | Promise<Response> {
18+
if (result instanceof Response || result instanceof Promise) {
19+
return result
20+
}
21+
22+
const status = typeof result.status === 'number' ? result.status : 200
23+
const body = typeof result.body === 'string' ? result.body : ''
24+
const headers = toHeaders(result.headers as Record<string, string> | undefined)
25+
26+
return new Response(body, { status, headers })
27+
}
28+
29+
export function mockFetchIf (pattern: RegExp, handler: FetchHandler): void {
30+
handlers.push({ pattern, handler })
31+
}
32+
33+
export function enableFetchMocks (): void {
34+
vi.stubGlobal('fetch', vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => {
35+
const request = input instanceof Request ? input : new Request(input, init)
36+
37+
for (const { pattern, handler } of handlers) {
38+
if (pattern.test(request.url)) {
39+
return toResponse(await handler(request))
40+
}
41+
}
42+
43+
return new Response('Not Found', { status: 404 })
44+
}))
45+
}
46+
47+
export function resetFetchMocks (): void {
48+
handlers.length = 0
49+
vi.unstubAllGlobals()
50+
}

0 commit comments

Comments
 (0)