Back to Repositories

Testing Component Stack Trace Implementation in PreactJS

This test suite examines component stack trace functionality in Preact’s debug mode, specifically focusing on warning generation when key JSX source plugins are missing. It validates the behavior when components attempt state updates during construction and verifies proper error reporting mechanisms.

Test Coverage Overview

The test coverage focuses on Preact’s component stack trace functionality in debug mode.

  • Tests warning generation for missing @babel/plugin-transform-react-jsx-source
  • Validates component error handling during construction
  • Verifies console warning interception

Implementation Analysis

The testing approach uses Jest’s describe/it pattern with setup and teardown hooks to manage test environment.

Key implementation features include:
  • Console error/warning interception using Sinon stubs
  • Component lifecycle testing during construction phase
  • JSX transformation validation

Technical Details

  • Testing Framework: Jest
  • Mocking Library: Sinon
  • Test Utilities: Custom setupScratch and teardown helpers
  • Component Types: Functional and Class Components
  • Error Handling: Console error/warning capture

Best Practices Demonstrated

The test suite demonstrates several testing best practices for component debugging.

  • Proper test isolation through beforeEach/afterEach hooks
  • Controlled error handling and assertion
  • Clean test environment management
  • Specific test case focus with clear expectations

preactjs/preact

debug/test/browser/component-stack-2.test.js

            
import { createElement, render, Component } from 'preact';
import 'preact/debug';
import { setupScratch, teardown } from '../../../test/_util/helpers';

/** @jsx createElement */

// This test is not part of component-stack.test.js to avoid it being
// transpiled with '@babel/plugin-transform-react-jsx-source' enabled.

describe('component stack', () => {
	/** @type {HTMLDivElement} */
	let scratch;

	let errors = [];
	let warnings = [];

	beforeEach(() => {
		scratch = setupScratch();

		errors = [];
		warnings = [];
		sinon.stub(console, 'error').callsFake(e => errors.push(e));
		sinon.stub(console, 'warn').callsFake(w => warnings.push(w));
	});

	afterEach(() => {
		console.error.restore();
		console.warn.restore();
		teardown(scratch);
	});

	it('should print a warning when "@babel/plugin-transform-react-jsx-source" is not installed', () => {
		function Foo() {
			return <Thrower />;
		}

		class Thrower extends Component {
			constructor(props) {
				super(props);
				this.setState({ foo: 1 });
			}

			render() {
				return <div>foo</div>;
			}
		}

		render(<Foo />, scratch);

		expect(
			warnings[0].indexOf('@babel/plugin-transform-react-jsx-source') > -1
		).to.equal(true);
	});
});