update deps + fix tests (#4675)

* update deps + fix tests

* tweak

* fixes

* changes

* fix everything

* fix checks

* fix

* log

* remove logs

* try this
This commit is contained in:
pngwn 2023-06-28 22:40:53 +01:00 committed by GitHub
parent bf26b5f66d
commit 085ff0394d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 2527 additions and 5502 deletions

View File

@ -0,0 +1,11 @@
import type { TestingLibraryMatchers } from "@testing-library/jest-dom/matchers";
import matchers from "@testing-library/jest-dom/matchers";
import { expect } from "vitest";
declare module "vitest" {
interface Assertion<T = any>
extends jest.Matchers<void, T>,
TestingLibraryMatchers<T, void> {}
}
expect.extend(matchers);

View File

@ -6,9 +6,6 @@
"cssvar.extensions": ["js", "css", "html", "jsx", "tsx", "svelte"],
"python.analysis.extraPaths": ["./gradio/themes/utils"],
"prettier.useTabs": true,
"editor.codeActionsOnSave": {
"source.fixAll": true
},
"editor.formatOnSave": true,
"svelte.plugin.svelte.format.enable": true,
"svelte.plugin.svelte.diagnostics.enable": false,

View File

@ -24,6 +24,7 @@
- The `plot` parameter deprecation warnings should now only be emitted for `Image` components by [@freddyaboulton](https://github.com/freddyaboulton) in [PR 4709](https://github.com/gradio-app/gradio/pull/4709)
- Removed uncessessary `type` deprecation warning by [@freddyaboulton](https://github.com/freddyaboulton) in [PR 4709](https://github.com/gradio-app/gradio/pull/4709)
- Ensure Audio autoplays works when `autoplay=True` and the video source is dynamically updated [@pngwn](https://github.com/pngwn) in [PR 4705](https://github.com/gradio-app/gradio/pull/4705)
- Update depedencies by [@pngwn](https://github.com/pngwn) in [PR 4675](https://github.com/gradio-app/gradio/pull/4675)
- Fixes `gr.Dropdown` being cutoff at the bottom by [@abidlabs](https://github.com/abidlabs) in [PR 4691](https://github.com/gradio-app/gradio/pull/4691).
## Other Changes:

View File

@ -1,18 +0,0 @@
import { test, expect, Page } from "@playwright/test";
function mock_demo(page: Page, demo: string) {
return page.route("**/config", (route) => {
return route.fulfill({
headers: {
"Access-Control-Allow-Origin": "*"
},
path: `../../demo/${demo}/config.json`
});
});
}
test("blocks layout", async ({ page }) => {
await mock_demo(page, "blocks_layout");
await page.goto("http://localhost:9876");
await expect(page).toHaveScreenshot();
});

View File

@ -1,18 +0,0 @@
import { test, expect, Page } from "@playwright/test";
function mock_demo(page: Page, demo: string) {
return page.route("**/config", (route) => {
return route.fulfill({
headers: {
"Access-Control-Allow-Origin": "*"
},
path: `../../demo/${demo}/config.json`
});
});
}
test("blocks xray", async ({ page }) => {
await mock_demo(page, "blocks_xray");
await page.goto("http://localhost:9876");
await expect(page).toHaveScreenshot();
});

View File

@ -1,18 +0,0 @@
import { test, expect, Page } from "@playwright/test";
function mock_demo(page: Page, demo: string) {
return page.route("**/config", (route) => {
return route.fulfill({
headers: {
"Access-Control-Allow-Origin": "*"
},
path: `../../demo/${demo}/config.json`
});
});
}
test("kitchen sink", async ({ page }) => {
await mock_demo(page, "kitchen_sink");
await page.goto("http://localhost:9876");
await expect(page).toHaveScreenshot();
});

View File

@ -7,6 +7,8 @@
import {
create_loading_status_store,
app_state,
} from "./stores";
import type {
LoadingStatusCollection
} from "./stores";
@ -29,16 +31,16 @@
setupi18n();
export let root: string;
export let components: Array<ComponentMeta>;
export let components: ComponentMeta[];
export let layout: LayoutNode;
export let dependencies: Array<Dependency>;
export let dependencies: Dependency[];
export let title: string = "Gradio";
export let analytics_enabled: boolean = false;
export let title = "Gradio";
export let analytics_enabled = false;
export let target: HTMLElement;
export let autoscroll: boolean;
export let show_api: boolean = true;
export let show_footer: boolean = true;
export let show_api = true;
export let show_footer = true;
export let control_page_title = false;
export let app_mode: boolean;
export let theme_mode: ThemeMode;
@ -95,7 +97,7 @@
function is_dep(
id: number,
type: "inputs" | "outputs",
deps: Array<Dependency>
deps: Dependency[]
) {
for (const dep of deps) {
for (const dep_item of dep[type]) {
@ -134,7 +136,7 @@
type LoadedComponent = {
Component: ComponentMeta["component"];
modes?: Array<string>;
modes?: string[];
document?: (arg0: Record<string, unknown>) => Documentation;
};
@ -232,7 +234,7 @@
obj.props[prop] = val;
rootNode = rootNode;
}
let handled_dependencies: Array<number[]> = [];
let handled_dependencies: number[][] = [];
let messages: (ToastMessage & { fn_index: number })[] = [];
let _error_id = -1;
@ -413,7 +415,7 @@
.filter((v) => !!v && !!v[1])
.forEach(([id, { instance }]: [number, ComponentMeta]) => {
if (handled_dependencies[i]?.includes(id) || !instance) return;
instance?.$on(trigger, (event_data) => {
instance?.$on(trigger, (event_data: any) => {
trigger_api_call(i, event_data.detail);
});

View File

@ -60,7 +60,6 @@
<script lang="ts">
import { onMount, setContext } from "svelte";
import type { api_factory, SpaceStatus } from "@gradio/client";
import Embed from "./Embed.svelte";
import type { ThemeMode } from "./components/types";
import { Component as Loader } from "./components/StatusTracker";

View File

@ -4,7 +4,7 @@
import { Image } from "@gradio/icons";
import StatusTracker from "../StatusTracker/StatusTracker.svelte";
import type { LoadingStatus } from "../StatusTracker/types";
import { FileData, normalise_file } from "@gradio/upload";
import { type FileData, normalise_file } from "@gradio/upload";
import type { SelectData } from "@gradio/utils";
export let elem_id: string = "";

View File

@ -1,7 +1,7 @@
<script lang="ts">
import { Block } from "@gradio/atoms";
import { createEventDispatcher } from "svelte";
import type { SvelteComponentDev, ComponentType } from "svelte/internal";
import type { SvelteComponent, ComponentType } from "svelte";
import { component_map } from "./directory";
import type { SelectData } from "@gradio/utils";
@ -73,9 +73,7 @@
$: component_meta = selected_samples.map((sample_row) =>
sample_row.map((sample_cell, j) => ({
value: sample_cell,
component: component_map[
components[j]
] as ComponentType<SvelteComponentDev>
component: component_map[components[j]] as ComponentType<SvelteComponent>
}))
);
</script>

View File

@ -1,7 +1,8 @@
<script lang="ts">
import { createEventDispatcher, getContext } from "svelte";
import { File as FileComponent, FileUpload } from "@gradio/file";
import { blobToBase64, FileData } from "@gradio/upload";
import { blobToBase64 } from "@gradio/upload";
import type { FileData } from "@gradio/upload";
import { normalise_file } from "@gradio/upload";
import { Block } from "@gradio/atoms";
import UploadText from "../UploadText.svelte";

View File

@ -1,13 +1,13 @@
<script lang="ts">
import type { ComponentType } from "svelte";
import type { SvelteComponentDev } from "svelte/internal";
import type { SvelteComponent } from "svelte";
import { component_map } from "./directory";
export let component: keyof typeof component_map;
export let component_props: Record<string, any>;
export let value: any;
$: _component = component_map[component] as ComponentType<SvelteComponentDev>;
$: _component = component_map[component] as ComponentType<SvelteComponent>;
</script>
{#if value}

View File

@ -15,7 +15,7 @@
export let lines: number;
export let placeholder: string = "";
export let show_label: boolean;
export let max_lines: number | false;
export let max_lines: number;
export let type: "text" | "password" | "email" = "text";
export let container: boolean = false;
export let scale: number | null = null;

View File

@ -1,5 +1,5 @@
import type { ComponentType } from "svelte";
import type { SvelteComponentDev } from "svelte/internal";
import type { SvelteComponent } from "svelte";
import type { component_map } from "./directory";
@ -10,8 +10,8 @@ export interface ComponentMeta {
id: number;
has_modes: boolean;
props: Record<string, unknown>;
instance: SvelteComponentDev;
component: ComponentType<SvelteComponentDev>;
instance: SvelteComponent;
component: ComponentType<SvelteComponent>;
documentation?: Documentation;
children?: Array<ComponentMeta>;
value?: any;

View File

@ -32,8 +32,8 @@ test("Consecutive .success event is triggered successfully", async ({
(await url.headerValue("content-type")) === "application/json";
if (!is_json) return false;
const data = (await url.json()).data[0];
return data === "Consecutive Event Triggered";
const data = await url.json();
return data?.data?.[0] === "Consecutive Event Triggered";
}
await Promise.all([

View File

@ -1,5 +1,4 @@
import { test, expect } from "@gradio/tootils";
import { BASE64_PLOT_IMG } from "./media_data";
test("matplotlib", async ({ page }) => {
await page.getByLabel("Plot Type").click();

View File

@ -60,19 +60,19 @@
}
const dispatch = createEventDispatcher<{
change: AudioData;
change: AudioData | null;
stream: AudioData;
edit: AudioData;
play: undefined;
pause: undefined;
stop: undefined;
end: undefined;
edit: never;
play: never;
pause: never;
stop: never;
end: never;
drag: boolean;
error: string;
upload: FileData;
clear: undefined;
start_recording: undefined;
stop_recording: undefined;
clear: never;
start_recording: never;
stop_recording: never;
}>();
function blob_to_data_url(blob: Blob): Promise<string> {
@ -195,7 +195,7 @@
}
function clear(): void {
dispatch("change");
dispatch("change", null);
dispatch("clear");
mode = "";
value = null;

View File

@ -13,7 +13,7 @@
export let info: string | undefined = undefined;
export let disabled = false;
export let show_label: boolean = true;
export let max_lines: number | false;
export let max_lines: number;
export let type: "text" | "password" | "email" = "text";
export let show_copy_button: boolean = false;
@ -96,7 +96,7 @@
if (lines === max_lines) return;
let max =
max_lines === false
max_lines === undefined
? false
: max_lines === undefined // default
? 21 * 11

View File

@ -156,7 +156,8 @@
</div>
{/if}
<div class="textfield" data-testid="highlighted-text:textfield">
{#each value as [text, score]}
{#each value as [text, _score]}
{@const score = typeof _score === "string" ? parseInt(_score) : _score}
<span
class="textspan score-text"
style={"background-color: rgba(" +

6
js/jsx.d.ts vendored
View File

@ -1,7 +1,5 @@
declare namespace svelte.JSX {
interface DOMAttributes<T extends EventTarget> {
theme?: string;
"item-type"?: string;
declare namespace svelteHTML {
interface HTMLAttributes<T extends EventTarget> {
webkitdirectory?: boolean | string;
mozdirectory?: boolean | string;
}

View File

@ -1,8 +1,10 @@
import { test as base } from "@playwright/test";
import { basename } from "path";
import type { SvelteComponentTyped } from "svelte";
import { spy } from "tinyspy";
import type { SvelteComponent } from "svelte";
import type { SpyFn } from "tinyspy";
export function get_text<T extends HTMLElement>(el: T): string {
return el.innerText.trim();
}
@ -27,9 +29,9 @@ export const test = base.extend<{ setup: void }>({
});
export async function wait_for_event(
component: SvelteComponentTyped,
component: SvelteComponent,
event: string
) {
): Promise<SpyFn> {
const mock = spy();
return new Promise((res) => {
component.$on(event, () => {

View File

@ -1,27 +1,54 @@
import { getQueriesForElement, prettyDOM } from "@testing-library/dom";
import {
getQueriesForElement,
prettyDOM,
fireEvent as dtlFireEvent
} from "@testing-library/dom";
import { tick } from "svelte";
import type { SvelteComponentTyped } from "svelte";
import type { SvelteComponent } from "svelte";
import type {
queries,
Queries,
BoundFunction,
EventType,
FireObject
} from "@testing-library/dom";
const containerCache = new Map();
const componentCache = new Set();
type Component<T extends SvelteComponentTyped, Props> = new (args: {
type ComponentType<T extends SvelteComponent, Props> = new (args: {
target: any;
props?: Props;
}) => T;
async function render<
export type RenderResult<
C extends SvelteComponent,
Q extends Queries = typeof queries
> = {
container: HTMLElement;
component: C;
debug: (el?: HTMLElement | DocumentFragment) => void;
unmount: () => void;
} & { [P in keyof Q]: BoundFunction<Q[P]> };
export interface RenderOptions<Q extends Queries = typeof queries> {
container?: HTMLElement;
queries?: Q;
}
export async function render<
Events extends Record<string, any>,
Props extends Record<string, any>,
T extends SvelteComponentTyped<Props, Events>
T extends SvelteComponent<Props, Events>
>(
Component: Component<T, Props> | { default: Component<T, Props> },
Component: ComponentType<T, Props> | { default: ComponentType<T, Props> },
props?: Props
) {
): Promise<RenderResult<T>> {
const container = document.body;
const target = container.appendChild(document.createElement("div"));
const ComponentConstructor: Component<T, Props> =
const ComponentConstructor: ComponentType<T, Props> =
//@ts-ignore
Component.default || Component;
@ -42,15 +69,16 @@ async function render<
return {
container,
component,
debug: (el = container) => console.log(prettyDOM(el)),
unmount: () => {
//@ts-ignore
debug: (el = container): void => console.warn(prettyDOM(el)),
unmount: (): void => {
if (componentCache.has(component)) component.$destroy();
},
...getQueriesForElement(container)
};
}
const cleanupAtContainer = (container: HTMLElement) => {
const cleanupAtContainer = (container: HTMLElement): void => {
const { target, component } = containerCache.get(container);
if (componentCache.has(component)) component.$destroy();
@ -62,11 +90,28 @@ const cleanupAtContainer = (container: HTMLElement) => {
containerCache.delete(container);
};
const cleanup = () => {
export function cleanup(): void {
Array.from(containerCache.keys()).forEach(cleanupAtContainer);
};
}
export const fireEvent = Object.keys(dtlFireEvent).reduce((acc, key) => {
const _key = key as EventType;
return {
...acc,
[_key]: async (
element: Document | Element | Window,
options: object = {}
): Promise<boolean> => {
const event = dtlFireEvent[_key](element, options);
await tick();
return event;
}
};
}, {} as FireObject);
export type FireFunction = (
element: Document | Element | Window,
event: Event
) => Promise<boolean>;
export * from "@testing-library/dom";
export { render, cleanup };
export { fireEvent } from "@testing-library/svelte";

View File

@ -1,6 +1,4 @@
<script lang="ts">
import type { FileData } from "./types";
import { IconButton } from "@gradio/atoms";
import { Edit, Clear } from "@gradio/icons";
@ -9,7 +7,7 @@
export let editable: boolean = false;
export let absolute: boolean = true;
const dispatch = createEventDispatcher<{ edit: FileData; clear: null }>();
const dispatch = createEventDispatcher<{ edit: never; clear: never }>();
</script>
<div

View File

@ -36,14 +36,15 @@
"@changesets/cli": "^2.26.1",
"@csstools/postcss-global-data": "^1.0.3",
"@gradio/tootils": "workspace:^0.0.1",
"@playwright/test": "^1.35.1",
"@playwright/experimental-ct-svelte": "^1.35.1",
"@sveltejs/vite-plugin-svelte": "^2.0.0",
"@sveltejs/vite-plugin-svelte": "^2.4.2",
"@tailwindcss/forms": "^0.5.0",
"@testing-library/dom": "^9.0.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/svelte": "^3.1.0",
"@testing-library/user-event": "^14.0.0",
"@types/node": "^20.3.1",
"@types/testing-library__jest-dom": "^5.14.6",
"@typescript-eslint/eslint-plugin": "^5.60.0",
"@typescript-eslint/parser": "^5.60.0",
"autoprefixer": "^10.4.4",
@ -54,7 +55,7 @@
"globals": "^13.20.0",
"jsdom": "^22.1.0",
"kleur": "^4.1.5",
"msw": "^1.0.0",
"msw": "^1.2.2",
"node-html-parser": "^6.0.0",
"npm-run-all": "^4.1.5",
"plotly.js-dist-min": "^2.10.1",
@ -65,14 +66,14 @@
"postcss-nested": "^5.0.6",
"postcss-prefix-selector": "^1.16.0",
"prettier": "^2.6.2",
"prettier-plugin-css-order": "^1.3.0",
"prettier-plugin-svelte": "^2.10.0",
"prettier-plugin-css-order": "^1.3.1",
"prettier-plugin-svelte": "^2.10.1",
"sirv": "^2.0.2",
"sirv-cli": "^2.0.2",
"svelte": "^3.59.1",
"svelte-check": "^3.1.4",
"svelte": "^4.0.0",
"svelte-check": "^3.4.4",
"svelte-i18n": "^3.6.0",
"svelte-preprocess": "^5.0.3",
"svelte-preprocess": "^5.0.4",
"tailwindcss": "^3.1.6",
"tinyspy": "^2.0.0",
"typescript": "^5.0.0",

7763
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@
svelte-preprocess cannot figure out whether you have a value or a type, so tell TypeScript
to enforce using \`import type\` instead of \`import\` for Types.
*/
"importsNotUsedAsValues": "error",
"verbatimModuleSyntax": true,
"isolatedModules": true,
"resolveJsonModule": true,
"strict": true,
@ -22,7 +22,10 @@
"allowJs": true,
"checkJs": true,
"outDir": "dist",
"baseUrl": "."
"baseUrl": ".",
"paths": {
"./pure": ["./pure.js"]
}
},
"exclude": [
"**/dist/**/*",