Back to Repositories

Testing HighlightedText Component Label Management in Gradio

This test suite validates the HighlightedText component functionality in Gradio, focusing on text rendering and label management. The tests ensure proper display of text tokens with their associated class labels and interactive label removal capabilities.

Test Coverage Overview

The test suite provides comprehensive coverage of the HighlightedText component’s core features.

Key areas tested include:
  • Text token rendering with associated class labels
  • Interactive label removal functionality
  • Event handling for label changes
  • Component state management
Edge cases covered include null class values and multiple instances of the same label class.

Implementation Analysis

The testing approach utilizes Vitest and custom rendering utilities to validate component behavior. The implementation follows component-driven testing patterns with specific focus on DOM interactions and event handling.

Framework-specific features include:
  • Svelte component testing utilities
  • Custom render functions
  • Event simulation via fireEvent
  • Assertion-based validation

Technical Details

Testing tools and configuration:
  • Vitest test runner
  • Custom @self/tootils testing utilities
  • DOM cleanup after each test
  • i18n setup for internationalization support
  • Mock LoadingStatus object for state management

Best Practices Demonstrated

The test suite exemplifies high-quality testing practices through clear test organization and comprehensive coverage.

Notable practices include:
  • Isolated test cases with proper cleanup
  • Descriptive test naming conventions
  • Proper component initialization
  • Event handler validation
  • Mock data structures for consistent testing

gradio-app/gradio

js/highlightedtext/highlightedtext.test.ts

            
import { test, describe, assert, afterEach } from "vitest";
import { cleanup, fireEvent, render } from "@self/tootils";
import { setupi18n } from "../core/src/i18n";

import HighlightedText from "./Index.svelte";
import type { LoadingStatus } from "@gradio/statustracker";

const loading_status: LoadingStatus = {
	eta: 0,
	queue_position: 1,
	queue_size: 1,
	status: "complete" as LoadingStatus["status"],
	scroll_to_output: false,
	visible: true,
	fn_index: 0,
	show_progress: "full"
};

describe("HighlightedText", () => {
	afterEach(() => cleanup());

	setupi18n();

	test("renders provided text and labels", async () => {
		const { getByText, getByTestId, getAllByText } = await render(
			HighlightedText,
			{
				interactive: false,
				loading_status,
				value: [
					{ token: "The", class_or_confidence: null },
					{ token: "quick", class_or_confidence: "adjective" },
					{ token: " sneaky", class_or_confidence: "adjective" },
					{ token: "fox", class_or_confidence: "subject" },
					{ token: " jumped ", class_or_confidence: "past tense verb" },
					{ token: "over the", class_or_confidence: null },
					{ token: "lazy dog", class_or_confidence: "object" }
				]
			}
		);

		const quick = getByText("quick");
		const adjectiveLabels = getAllByText("adjective");

		assert.exists(quick);
		assert.exists(adjectiveLabels);
		assert.equal(adjectiveLabels.length, 2);
	});

	test("renders labels with remove label buttons which trigger change", async () => {
		const { getAllByText, listen } = await render(HighlightedText, {
			interactive: true,
			loading_status,
			value: [
				{ token: "The", class_or_confidence: null },
				{ token: "quick", class_or_confidence: "adjective" },
				{ token: " sneaky", class_or_confidence: "adjective" },
				{ token: "fox", class_or_confidence: "subject" },
				{ token: " jumped ", class_or_confidence: "past tense  verb" },
				{ token: "over the", class_or_confidence: null },
				{ token: "lazy dog", class_or_confidence: "object" }
			]
		});

		const mock = listen("change");

		const removeButtons = getAllByText("×");

		assert.equal(removeButtons.length, 5);

		assert.equal(mock.callCount, 0);

		fireEvent.click(removeButtons[0]);

		assert.equal(mock.callCount, 1);
	});
});